1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-22 16:18:08 +02:00

Merge pull request #9729 from Snuffleupagus/gulp-image_decoders

Add a `gulp image_decoders` command to package the image decoders (i.e. jpg.js, jpx.js, jbig2.js) separately, and publish them in pdfjs-dist
This commit is contained in:
Tim van der Meij 2018-06-26 23:27:32 +02:00 committed by GitHub
commit 14b69a4c1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 288 additions and 14 deletions

View file

@ -1192,6 +1192,47 @@ var Jbig2Image = (function Jbig2ImageClosure() {
return visitor.buffer;
}
function parseJbig2(data) {
let position = 0, end = data.length;
if (data[position] !== 0x97 || data[position + 1] !== 0x4A ||
data[position + 2] !== 0x42 || data[position + 3] !== 0x32 ||
data[position + 4] !== 0x0D || data[position + 5] !== 0x0A ||
data[position + 6] !== 0x1A || data[position + 7] !== 0x0A) {
throw new Jbig2Error('parseJbig2 - invalid header.');
}
let header = Object.create(null);
position += 8;
const flags = data[position++];
header.randomAccess = !(flags & 1);
if (!(flags & 2)) {
header.numberOfPages = readUint32(data, position);
position += 4;
}
let segments = readSegments(header, data, position, end);
let visitor = new SimpleSegmentVisitor();
processSegments(segments, visitor);
const { width, height, } = visitor.currentPageInfo;
const bitPacked = visitor.buffer;
let imgData = new Uint8ClampedArray(width * height);
let q = 0, k = 0;
for (let i = 0; i < height; i++) {
let mask = 0, buffer;
for (let j = 0; j < width; j++) {
if (!mask) {
mask = 128; buffer = bitPacked[k++];
}
imgData[q++] = (buffer & mask) ? 0 : 255;
mask >>= 1;
}
}
return { imgData, width, height, };
}
function SimpleSegmentVisitor() {}
SimpleSegmentVisitor.prototype = {
@ -2095,9 +2136,16 @@ var Jbig2Image = (function Jbig2ImageClosure() {
function Jbig2Image() {}
Jbig2Image.prototype = {
parseChunks: function Jbig2Image_parseChunks(chunks) {
parseChunks(chunks) {
return parseJbig2Chunks(chunks);
},
parse(data) {
const { imgData, width, height, } = parseJbig2(data);
this.width = width;
this.height = height;
return imgData;
},
};
return Jbig2Image;

View file

@ -63,7 +63,10 @@ let JpegStream = (function JpegStreamClosure() {
if (this.eof) {
return;
}
let jpegImage = new JpegImage();
let jpegOptions = {
decodeTransform: undefined,
colorTransform: undefined,
};
// Checking if values need to be transformed before conversion.
let decodeArr = this.dict.getArray('Decode', 'D');
@ -81,16 +84,17 @@ let JpegStream = (function JpegStreamClosure() {
}
}
if (transformNeeded) {
jpegImage.decodeTransform = transform;
jpegOptions.decodeTransform = transform;
}
}
// Fetching the 'ColorTransform' entry, if it exists.
if (isDict(this.params)) {
let colorTransform = this.params.get('ColorTransform');
if (Number.isInteger(colorTransform)) {
jpegImage.colorTransform = colorTransform;
jpegOptions.colorTransform = colorTransform;
}
}
const jpegImage = new JpegImage(jpegOptions);
jpegImage.parse(this.bytes);
let data = jpegImage.getData(this.drawWidth, this.drawHeight,

View file

@ -94,9 +94,9 @@ var JpegImage = (function JpegImageClosure() {
var dctSqrt2 = 5793; // sqrt(2)
var dctSqrt1d2 = 2896; // sqrt(2) / 2
function JpegImage() {
this.decodeTransform = null;
this.colorTransform = -1;
function JpegImage({ decodeTransform = null, colorTransform = -1, } = {}) {
this._decodeTransform = decodeTransform;
this._colorTransform = colorTransform;
}
function buildHuffmanTable(codeLengths, values) {
@ -1013,7 +1013,7 @@ var JpegImage = (function JpegImageClosure() {
}
// decodeTransform contains pairs of multiplier (-256..256) and additive
var transform = this.decodeTransform;
const transform = this._decodeTransform;
if (transform) {
for (i = 0; i < dataLength;) {
for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
@ -1030,7 +1030,7 @@ var JpegImage = (function JpegImageClosure() {
return !!this.adobe.transformCode;
}
if (this.numComponents === 3) {
if (this.colorTransform === 0) {
if (this._colorTransform === 0) {
// If the Adobe transform marker is not present and the image
// dictionary has a 'ColorTransform' entry, explicitly set to `0`,
// then the colours should *not* be transformed.
@ -1039,7 +1039,7 @@ var JpegImage = (function JpegImageClosure() {
return true;
}
// `this.numComponents !== 3`
if (this.colorTransform === 1) {
if (this._colorTransform === 1) {
// If the Adobe transform marker is not present and the image
// dictionary has a 'ColorTransform' entry, explicitly set to `1`,
// then the colours should be transformed.

45
src/pdf.image_decoders.js Normal file
View file

@ -0,0 +1,45 @@
/* Copyright 2018 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable no-unused-vars */
import { getVerbosityLevel, setVerbosityLevel } from './shared/util';
import { Jbig2mage } from './core/jbig2';
import { JpegImage } from './core/jpg';
import { JpxImage } from './core/jpx';
// To ensure that the standalone PDF.js image decoders have the same
// browser/environment compatibility as the regular PDF.js library,
// the standard set of polyfills are thus included in this build as well.
//
// Given that the (current) image decoders don't use all of the features
// of the complete PDF.js library, e.g. they are completely synchronous,
// some of the larger polyfills are thus unnecessary.
//
// In an attempt to reduce the size of the standalone PDF.js image decoders,
// the following polyfills are currently being excluded:
// - ReadableStream
// - Promise
// - URL
const pdfjsVersion = PDFJSDev.eval('BUNDLE_VERSION');
const pdfjsBuild = PDFJSDev.eval('BUNDLE_BUILD');
export {
Jbig2mage,
JpegImage,
JpxImage,
getVerbosityLevel,
setVerbosityLevel,
};

View file

@ -147,6 +147,11 @@ const hasDOM = typeof window === 'object' && typeof document === 'object';
// Support: IE, Safari<8, Chrome<32
(function checkPromise() {
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
// The current image decoders are synchronous, hence `Promise` shouldn't
// need to be polyfilled for the IMAGE_DECODERS build target.
return;
}
if (globalScope.Promise) {
return;
}
@ -166,6 +171,11 @@ const hasDOM = typeof window === 'object' && typeof document === 'object';
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
(function checkURLConstructor() {
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
// The current image decoders doesn't utilize the `URL` constructor, hence
// it shouldn't need to be polyfilled for the IMAGE_DECODERS build target.
return;
}
// feature detect for URL constructor
var hasWorkingUrl = false;
try {

View file

@ -31,6 +31,17 @@ if (typeof ReadableStream !== 'undefined') {
if (isReadableStreamSupported) {
exports.ReadableStream = ReadableStream;
} else {
exports.ReadableStream =
require('../../external/streams/streams-lib').ReadableStream;
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
class DummyReadableStream {
constructor() {
throw new Error('The current image decoders are synchronous, ' +
'hence `ReadableStream` shouldn\'t need to be ' +
'polyfilled for the IMAGE_DECODERS build target.');
}
}
exports.ReadableStream = DummyReadableStream;
} else {
exports.ReadableStream =
require('../../external/streams/streams-lib').ReadableStream;
}
}