1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-21 15:48:06 +02:00

Remove manual clamping/rounding from ColorSpace and PDFImage, by having their methods use Uint8ClampedArrays

The built-in image decoders are already using `Uint8ClampedArray` when returning data, and this patch simply extends that to the rest of the image/colorspace code.

As far as I can tell, the only reason for using manual clamping/rounding in the first place was because TypedArrays used to be polyfilled (using regular arrays). And trying to polyfill the native clamping/rounding would probably have been had too much overhead, but given that TypedArray support is required in PDF.js version `2.0` that's no longer a concern.

*Please note:* Because of different rounding behaviour, basically `Math.round` in `Uint8ClampedArray` respectively `Math.floor` in the old code, there will be very slight movement in quite a few existing test-cases. However, the changes should be imperceivable to the naked eye, given that the absolute difference is *at most* `1` for each RGB component when comparing `master` and this patch (see also the updated expectation values in the unit-tests).
This commit is contained in:
Jonas Jenwald 2018-06-11 17:25:40 +02:00
parent 55199aa281
commit 731f2e6dfc
9 changed files with 150 additions and 157 deletions

View file

@ -166,7 +166,7 @@ describe('annotation', function() {
var annotation = new Annotation({ dict, ref, });
annotation.setColor('red');
expect(annotation.color).toEqual(new Uint8Array([0, 0, 0]));
expect(annotation.color).toEqual(new Uint8ClampedArray([0, 0, 0]));
});
it('should set and get a transparent color', function() {
@ -180,28 +180,28 @@ describe('annotation', function() {
var annotation = new Annotation({ dict, ref, });
annotation.setColor([0.4]);
expect(annotation.color).toEqual(new Uint8Array([102, 102, 102]));
expect(annotation.color).toEqual(new Uint8ClampedArray([102, 102, 102]));
});
it('should set and get an RGB color', function() {
var annotation = new Annotation({ dict, ref, });
annotation.setColor([0, 0, 1]);
expect(annotation.color).toEqual(new Uint8Array([0, 0, 255]));
expect(annotation.color).toEqual(new Uint8ClampedArray([0, 0, 255]));
});
it('should set and get a CMYK color', function() {
var annotation = new Annotation({ dict, ref, });
annotation.setColor([0.1, 0.92, 0.84, 0.02]);
expect(annotation.color).toEqual(new Uint8Array([233, 59, 47]));
expect(annotation.color).toEqual(new Uint8ClampedArray([234, 59, 48]));
});
it('should not set and get an invalid color', function() {
var annotation = new Annotation({ dict, ref, });
annotation.setColor([0.4, 0.6]);
expect(annotation.color).toEqual(new Uint8Array([0, 0, 0]));
expect(annotation.color).toEqual(new Uint8ClampedArray([0, 0, 0]));
});
});

View file

@ -764,7 +764,7 @@ describe('api', function() {
expect(outlineItem.bold).toEqual(true);
expect(outlineItem.italic).toEqual(false);
expect(outlineItem.color).toEqual(new Uint8Array([0, 64, 128]));
expect(outlineItem.color).toEqual(new Uint8ClampedArray([0, 64, 128]));
expect(outlineItem.items.length).toEqual(1);
expect(outlineItem.items[0].title).toEqual('Paragraph 1.1');
@ -791,7 +791,8 @@ describe('api', function() {
var outlineItemOne = outline[1];
expect(outlineItemOne.bold).toEqual(false);
expect(outlineItemOne.italic).toEqual(true);
expect(outlineItemOne.color).toEqual(new Uint8Array([0, 0, 0]));
expect(outlineItemOne.color).toEqual(
new Uint8ClampedArray([0, 0, 0]));
loadingTask.destroy().then(done);
});

View file

@ -61,8 +61,8 @@ describe('colorspace', function () {
let colorSpace = ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
let testSrc = new Uint8Array([27, 125, 250, 131]);
let testDest = new Uint8Array(4 * 4 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(4 * 4 * 3);
let expectedDest = new Uint8ClampedArray([
27, 27, 27,
27, 27, 27,
125, 125, 125,
@ -83,7 +83,7 @@ describe('colorspace', function () {
colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([0.1]), 0))
.toEqual(new Uint8Array([25, 25, 25]));
.toEqual(new Uint8ClampedArray([26, 26, 26]));
expect(colorSpace.getOutputLength(2, 0)).toEqual(6);
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(testDest).toEqual(expectedDest);
@ -102,8 +102,8 @@ describe('colorspace', function () {
let colorSpace = ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
let testSrc = new Uint8Array([27, 125, 250, 131]);
let testDest = new Uint8Array(3 * 3 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(3 * 3 * 3);
let expectedDest = new Uint8ClampedArray([
27, 27, 27,
27, 27, 27,
125, 125, 125,
@ -117,7 +117,7 @@ describe('colorspace', function () {
colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([0.2]), 0))
.toEqual(new Uint8Array([51, 51, 51]));
.toEqual(new Uint8ClampedArray([51, 51, 51]));
expect(colorSpace.getOutputLength(3, 1)).toEqual(12);
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(testDest).toEqual(expectedDest);
@ -144,8 +144,8 @@ describe('colorspace', function () {
111, 25, 198,
21, 147, 255
]);
let testDest = new Uint8Array(4 * 4 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(4 * 4 * 3);
let expectedDest = new Uint8ClampedArray([
27, 125, 250,
27, 125, 250,
131, 139, 140,
@ -166,7 +166,7 @@ describe('colorspace', function () {
colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0))
.toEqual(new Uint8Array([25, 51, 76]));
.toEqual(new Uint8ClampedArray([26, 51, 77]));
expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
expect(colorSpace.isPassthrough(8)).toBeTruthy();
expect(testDest).toEqual(expectedDest);
@ -190,8 +190,8 @@ describe('colorspace', function () {
111, 25, 198,
21, 147, 255
]);
let testDest = new Uint8Array(3 * 3 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(3 * 3 * 3);
let expectedDest = new Uint8ClampedArray([
27, 125, 250,
27, 125, 250,
131, 139, 140,
@ -205,7 +205,7 @@ describe('colorspace', function () {
colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0))
.toEqual(new Uint8Array([25, 51, 76]));
.toEqual(new Uint8ClampedArray([26, 51, 77]));
expect(colorSpace.getOutputLength(4, 1)).toEqual(5);
expect(colorSpace.isPassthrough(8)).toBeTruthy();
expect(testDest).toEqual(expectedDest);
@ -232,29 +232,29 @@ describe('colorspace', function () {
111, 25, 198, 78,
21, 147, 255, 69
]);
let testDest = new Uint8Array(4 * 4 * 3);
let expectedDest = new Uint8Array([
135, 80, 18,
135, 80, 18,
113, 102, 97,
113, 102, 97,
135, 80, 18,
135, 80, 18,
113, 102, 97,
113, 102, 97,
112, 143, 75,
112, 143, 75,
let testDest = new Uint8ClampedArray(4 * 4 * 3);
let expectedDest = new Uint8ClampedArray([
135, 81, 18,
135, 81, 18,
114, 102, 97,
114, 102, 97,
135, 81, 18,
135, 81, 18,
114, 102, 97,
114, 102, 97,
112, 144, 75,
112, 144, 75,
188, 98, 27,
188, 98, 27,
112, 143, 75,
112, 143, 75,
112, 144, 75,
112, 144, 75,
188, 98, 27,
188, 98, 27
]);
colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]),
0)).toEqual(new Uint8Array([31, 27, 20]));
0)).toEqual(new Uint8ClampedArray([32, 28, 21]));
expect(colorSpace.getOutputLength(4, 0)).toEqual(3);
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(testDest).toEqual(expectedDest);
@ -278,22 +278,22 @@ describe('colorspace', function () {
111, 25, 198, 78,
21, 147, 255, 69
]);
let testDest = new Uint8Array(3 * 3 * 3);
let expectedDest = new Uint8Array([
135, 80, 18,
135, 80, 18,
113, 102, 97,
135, 80, 18,
135, 80, 18,
113, 102, 97,
112, 143, 75,
112, 143, 75,
let testDest = new Uint8ClampedArray(3 * 3 * 3);
let expectedDest = new Uint8ClampedArray([
135, 81, 18,
135, 81, 18,
114, 102, 97,
135, 81, 18,
135, 81, 18,
114, 102, 97,
112, 144, 75,
112, 144, 75,
188, 98, 27
]);
colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]), 0))
.toEqual(new Uint8Array([31, 27, 20]));
.toEqual(new Uint8ClampedArray([32, 28, 21]));
expect(colorSpace.getOutputLength(4, 1)).toEqual(4);
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(testDest).toEqual(expectedDest);
@ -323,8 +323,8 @@ describe('colorspace', function () {
let colorSpace = ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
let testSrc = new Uint8Array([27, 125, 250, 131]);
let testDest = new Uint8Array(4 * 4 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(4 * 4 * 3);
let expectedDest = new Uint8ClampedArray([
25, 25, 25,
25, 25, 25,
143, 143, 143,
@ -335,17 +335,17 @@ describe('colorspace', function () {
143, 143, 143,
251, 251, 251,
251, 251, 251,
148, 148, 148,
148, 148, 148,
149, 149, 149,
149, 149, 149,
251, 251, 251,
251, 251, 251,
148, 148, 148,
148, 148, 148
149, 149, 149,
149, 149, 149
]);
colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([1.0]), 0))
.toEqual(new Uint8Array([255, 255, 255]));
.toEqual(new Uint8ClampedArray([255, 255, 255]));
expect(colorSpace.getOutputLength(4, 0)).toEqual(12);
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(testDest).toEqual(expectedDest);
@ -381,8 +381,8 @@ describe('colorspace', function () {
111, 25, 198,
21, 147, 255
]);
let testDest = new Uint8Array(3 * 3 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(3 * 3 * 3);
let expectedDest = new Uint8ClampedArray([
0, 238, 255,
0, 238, 255,
185, 196, 195,
@ -396,7 +396,7 @@ describe('colorspace', function () {
colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0))
.toEqual(new Uint8Array([0, 147, 151]));
.toEqual(new Uint8ClampedArray([0, 147, 151]));
expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(testDest).toEqual(expectedDest);
@ -431,22 +431,22 @@ describe('colorspace', function () {
11, 25, 98,
21, 47, 55
]);
let testDest = new Uint8Array(3 * 3 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(3 * 3 * 3);
let expectedDest = new Uint8ClampedArray([
0, 49, 101,
0, 49, 101,
0, 53, 116,
0, 53, 117,
0, 49, 101,
0, 49, 101,
0, 53, 116,
0, 40, 39,
0, 40, 39,
0, 53, 117,
0, 41, 40,
0, 41, 40,
0, 43, 90
]);
colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
expect(colorSpace.getRgb([55, 25, 35], 0))
.toEqual(new Uint8Array([188, 99, 61]));
.toEqual(new Uint8ClampedArray([188, 100, 61]));
expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
@ -479,8 +479,8 @@ describe('colorspace', function () {
let colorSpace = ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
let testSrc = new Uint8Array([2, 2, 0, 1]);
let testDest = new Uint8Array(3 * 3 * 3);
let expectedDest = new Uint8Array([
let testDest = new Uint8ClampedArray(3 * 3 * 3);
let expectedDest = new Uint8ClampedArray([
255, 109, 70,
255, 109, 70,
255, 109, 70,
@ -493,7 +493,8 @@ describe('colorspace', function () {
]);
colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
expect(colorSpace.getRgb([2], 0)).toEqual(new Uint8Array([255, 109, 70]));
expect(colorSpace.getRgb([2], 0)).toEqual(
new Uint8ClampedArray([255, 109, 70]));
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
expect(testDest).toEqual(expectedDest);
@ -534,22 +535,22 @@ describe('colorspace', function () {
let colorSpace = ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
let testSrc = new Uint8Array([27, 25, 50, 31]);
let testDest = new Uint8Array(3 * 3 * 3);
let expectedDest = new Uint8Array([
227, 243, 242,
227, 243, 242,
228, 243, 242,
227, 243, 242,
227, 243, 242,
228, 243, 242,
203, 233, 229,
203, 233, 229,
222, 241, 239
let testDest = new Uint8ClampedArray(3 * 3 * 3);
let expectedDest = new Uint8ClampedArray([
226, 242, 241,
226, 242, 241,
229, 244, 242,
226, 242, 241,
226, 242, 241,
229, 244, 242,
203, 232, 229,
203, 232, 229,
222, 241, 238
]);
colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
expect(colorSpace.getRgb([0.1], 0))
.toEqual(new Uint8Array([228, 243, 241]));
.toEqual(new Uint8ClampedArray([228, 243, 242]));
expect(colorSpace.isPassthrough(8)).toBeFalsy();
expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
expect(testDest).toEqual(expectedDest);