[Pkg-javascript-commits] [pdf.js] 38/141: Read color info from JPX stream
David Prévot
taffit at moszumanska.debian.org
Sat Apr 19 22:40:28 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 1ccc8a64b7beeb79f5dc4aee1a03ef04f23997ee
Author: fkaelberer <o_0_o at gmx.de>
Date: Sat Apr 5 17:27:18 2014 +0200
Read color info from JPX stream
Fix colors problem #4540 + minor cleanup
fix lint warnings
---
src/core/image.js | 38 ++++++++++++++++-------
src/core/jpx.js | 91 +++++++++++++++++++++++++++++++++++++------------------
2 files changed, 89 insertions(+), 40 deletions(-)
diff --git a/src/core/image.js b/src/core/image.js
index 8dc7b6d..17ea6b6 100644
--- a/src/core/image.js
+++ b/src/core/image.js
@@ -14,8 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/* globals ColorSpace, DecodeStream, error, isArray, ImageKind, isStream,
- JpegStream, Name, Promise, Stream, warn, LegacyPromise */
+/* globals ColorSpace, DecodeStream, error, info, isArray, ImageKind, isStream,
+ JpegStream, JpxImage, Name, Promise, Stream, warn, LegacyPromise */
'use strict';
@@ -51,16 +51,21 @@ var PDFImage = (function PDFImageClosure() {
}
function PDFImage(xref, res, image, inline, smask, mask, isMask) {
this.image = image;
- if (image.getParams) {
- // JPX/JPEG2000 streams directly contain bits per component
- // and color space mode information.
- warn('get params from actual stream');
- // var bits = ...
- // var colorspace = ...
+ var dict = image.dict;
+ if (dict.get('Filter').name === 'JPXDecode') {
+ info('get image params from JPX stream');
+ var jpxImage = new JpxImage();
+ var data = image.stream.bytes;
+ jpxImage.parseImageProperties(data, 0, data.length);
+ image.bitsPerComponent = jpxImage.bitsPerComponent;
+ image.numComps = jpxImage.componentsCount;
+ }
+ if (dict.get('Filter').name === 'JBIG2Decode') {
+ image.bitsPerComponent = 1;
+ image.numComps = 1;
}
// TODO cache rendered images?
- var dict = image.dict;
this.width = dict.get('Width', 'W');
this.height = dict.get('Height', 'H');
@@ -89,8 +94,19 @@ var PDFImage = (function PDFImageClosure() {
if (!this.imageMask) {
var colorSpace = dict.get('ColorSpace', 'CS');
if (!colorSpace) {
- warn('JPX images (which do not require color spaces)');
- colorSpace = Name.get('DeviceRGB');
+ info('JPX images (which do not require color spaces)');
+ switch (image.numComps) {
+ case 1:
+ colorSpace = Name.get('DeviceGray');
+ break;
+ case 3:
+ colorSpace = Name.get('DeviceRGB');
+ break;
+ default:
+ // TODO: Find out how four color channels are handled. CMYK? Alpha?
+ error('JPX images with ' + this.numComps +
+ ' color components not supported.');
+ }
}
this.colorSpace = ColorSpace.parse(colorSpace, xref, res);
this.numComps = this.colorSpace.numComps;
diff --git a/src/core/jpx.js b/src/core/jpx.js
index 55d4078..de8cc90 100644
--- a/src/core/jpx.js
+++ b/src/core/jpx.js
@@ -26,10 +26,6 @@ var JpxImage = (function JpxImageClosure() {
'HL': 1,
'HH': 2
};
- var TransformType = {
- IRREVERSIBLE: 0,
- REVERSIBLE: 1
- };
function JpxImage() {
this.failOnCorruptedImage = false;
}
@@ -102,6 +98,37 @@ var JpxImage = (function JpxImageClosure() {
}
}
},
+ parseImageProperties: function JpxImage_parseImageProperties(data, start,
+ end) {
+ try {
+ var position = start;
+ while (position + 40 < end) {
+ var code = readUint16(data, position);
+ // Image and tile size (SIZ)
+ if (code == 0xFF51) {
+ var Xsiz = readUint32(data, position + 6);
+ var Ysiz = readUint32(data, position + 10);
+ var XOsiz = readUint32(data, position + 14);
+ var YOsiz = readUint32(data, position + 18);
+ var Csiz = readUint16(data, position + 38);
+ this.width = Xsiz - XOsiz;
+ this.height = Ysiz - YOsiz;
+ this.componentsCount = Csiz;
+ // Results are always returned as UInt8Arrays
+ this.bitsPerComponent = 8;
+ return;
+ }
+ position += 1;
+ }
+ throw 'No size marker found in JPX stream';
+ } catch (e) {
+ if (this.failOnCorruptedImage) {
+ error('JPX error: ' + e);
+ } else {
+ warn('JPX error: ' + e + '. Trying to recover');
+ }
+ }
+ },
parseCodestream: function JpxImage_parseCodestream(data, start, end) {
var context = {};
try {
@@ -270,7 +297,7 @@ var JpxImage = (function JpxImageClosure() {
cod.verticalyStripe = !!(blockStyle & 8);
cod.predictableTermination = !!(blockStyle & 16);
cod.segmentationSymbolUsed = !!(blockStyle & 32);
- cod.transformation = data[j++];
+ cod.reversibleTransformation = data[j++];
if (cod.entropyCoderWithCustomPrecincts) {
var precinctsSizes = [];
while (j < length + position) {
@@ -333,6 +360,8 @@ var JpxImage = (function JpxImageClosure() {
length = readUint16(data, position);
// skipping content
break;
+ case 0xFF53: // Coding style component (COC)
+ throw 'Codestream code 0xFF53 (COC) is not implemented';
default:
throw 'Unknown codestream code: ' + code.toString(16);
}
@@ -878,7 +907,7 @@ var JpxImage = (function JpxImageClosure() {
return position;
}
function copyCoefficients(coefficients, x0, y0, width, height,
- delta, mb, codeblocks, transformation,
+ delta, mb, codeblocks, reversible,
segmentationSymbolUsed) {
for (var i = 0, ii = codeblocks.length; i < ii; ++i) {
var codeblock = codeblocks[i];
@@ -934,16 +963,22 @@ var JpxImage = (function JpxImageClosure() {
var offset = (codeblock.tbx0_ - x0) + (codeblock.tby0_ - y0) * width;
var n, nb, correction, position = 0;
- var irreversible = (transformation === TransformType.IRREVERSIBLE);
+ var irreversible = !reversible;
var sign = bitModel.coefficentsSign;
var magnitude = bitModel.coefficentsMagnitude;
var bitsDecoded = bitModel.bitsDecoded;
+ var magnitudeCorrection = reversible ? 0 : 0.5;
for (var j = 0; j < blockHeight; j++) {
for (var k = 0; k < blockWidth; k++) {
- n = (sign[position] ? -1 : 1) * magnitude[position];
- nb = bitsDecoded[position];
- correction = (irreversible || mb > nb) ? 1 << (mb - nb) : 1;
- coefficients[offset++] = n * correction * delta;
+ var mag = magnitude[position];
+ if (mag !== 0) {
+ n = sign[position] ? -(mag + magnitudeCorrection) :
+ (mag + magnitudeCorrection);
+ nb = bitsDecoded[position];
+ correction = (irreversible || mb > nb) ? 1 << (mb - nb) : 1;
+ coefficients[offset] = n * correction * delta;
+ }
+ offset++;
position++;
}
offset += width - blockWidth;
@@ -959,16 +994,15 @@ var JpxImage = (function JpxImageClosure() {
var spqcds = quantizationParameters.SPqcds;
var scalarExpounded = quantizationParameters.scalarExpounded;
var guardBits = quantizationParameters.guardBits;
- var transformation = codingStyleParameters.transformation;
var segmentationSymbolUsed = codingStyleParameters.segmentationSymbolUsed;
var precision = context.components[c].precision;
- var transformation = codingStyleParameters.transformation;
- var transform = (transformation === TransformType.IRREVERSIBLE ?
- new IrreversibleTransform() : new ReversibleTransform());
+ var reversible = codingStyleParameters.reversibleTransformation;
+ var transform = (reversible ? new ReversibleTransform() :
+ new IrreversibleTransform());
var subbandCoefficients = [];
- var k = 0, b = 0;
+ var b = 0;
for (var i = 0; i <= decompositionLevelsCount; i++) {
var resolution = component.resolutions[i];
@@ -989,13 +1023,13 @@ var JpxImage = (function JpxImageClosure() {
var gainLog2 = SubbandsGainLog2[subband.type];
// calulate quantization coefficient (Section E.1.1.1)
- var delta = (transformation === TransformType.IRREVERSIBLE ?
- Math.pow(2, precision + gainLog2 - epsilon) * (1 + mu / 2048) : 1);
+ var delta = (reversible ? 1 :
+ Math.pow(2, precision + gainLog2 - epsilon) * (1 + mu / 2048));
var mb = (guardBits + epsilon - 1);
var coefficients = new Float32Array(width * height);
copyCoefficients(coefficients, subband.tbx0, subband.tby0,
- width, height, delta, mb, subband.codeblocks, transformation,
+ width, height, delta, mb, subband.codeblocks, reversible,
segmentationSymbolUsed);
subbandCoefficients.push({
@@ -1034,8 +1068,7 @@ var JpxImage = (function JpxImageClosure() {
// Section G.2.2 Inverse multi component transform
if (tile.codingStyleDefaultParameters.multipleComponentTransform) {
var component0 = tile.components[0];
- var transformation = component0.codingStyleParameters.transformation;
- if (transformation === TransformType.IRREVERSIBLE) {
+ if (!component0.codingStyleParameters.reversibleTransformation) {
// inverse irreversible multiple component transform
var y0items = result[0].items;
var y1items = result[1].items;
@@ -1628,26 +1661,26 @@ var JpxImage = (function JpxImageClosure() {
var items = new Float32Array(width * height);
var i, j, k, l;
- for (i = 0; i < llHeight; i++) {
- var k = i * llWidth, l = i * 2 * width;
+ for (i = 0, k = 0; i < llHeight; i++) {
+ l = i * 2 * width;
for (var j = 0; j < llWidth; j++, k++, l += 2) {
items[l] = llItems[k];
}
}
- for (i = 0; i < hlHeight; i++) {
- k = i * hlWidth; l = i * 2 * width + 1;
+ for (i = 0, k = 0; i < hlHeight; i++) {
+ l = i * 2 * width + 1;
for (j = 0; j < hlWidth; j++, k++, l += 2) {
items[l] = hlItems[k];
}
}
- for (i = 0; i < lhHeight; i++) {
- k = i * lhWidth; l = (i * 2 + 1) * width;
+ for (i = 0, k = 0; i < lhHeight; i++) {
+ l = (i * 2 + 1) * width;
for (j = 0; j < lhWidth; j++, k++, l += 2) {
items[l] = lhItems[k];
}
}
- for (i = 0; i < hhHeight; i++) {
- k = i * hhWidth; l = (i * 2 + 1) * width + 1;
+ for (i = 0, k = 0; i < hhHeight; i++) {
+ l = (i * 2 + 1) * width + 1;
for (j = 0; j < hhWidth; j++, k++, l += 2) {
items[l] = hhItems[k];
}
--
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