Use Uint8ClampedArray
, when returning data, and remove manual clamping in src/core/jpg.js
(issue 4901)
This patch removes the `clamp0to255` helper function, as well as manual clamping code in `src/core/jpg.js`. The adjusted constants in `_convertCmykToRgb` were taken from CMYK to RGB conversion code found in `src/core/colorspace.js`. *Please note:* There will be some very slight movement in a number of existing test-cases, since `Uint8ClampedArray` appears to use `Math.round` (or equivalent) and the old code used (basically) `Math.floor`.
This commit is contained in:
parent
be36c60e0f
commit
d6cd5355f0
@ -600,10 +600,6 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
return component.blockData;
|
return component.blockData;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clamp0to255(a) {
|
|
||||||
return a <= 0 ? 0 : a >= 255 ? 255 : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findNextFileMarker(data, currentPos, startPos) {
|
function findNextFileMarker(data, currentPos, startPos) {
|
||||||
function peekUint16(pos) {
|
function peekUint16(pos) {
|
||||||
return (data[pos] << 8) | data[pos + 1];
|
return (data[pos] << 8) | data[pos + 1];
|
||||||
@ -919,7 +915,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
var output;
|
var output;
|
||||||
var numComponents = this.components.length;
|
var numComponents = this.components.length;
|
||||||
var dataLength = width * height * numComponents;
|
var dataLength = width * height * numComponents;
|
||||||
var data = new Uint8Array(dataLength);
|
var data = new Uint8ClampedArray(dataLength);
|
||||||
var xScaleBlockOffset = new Uint32Array(width);
|
var xScaleBlockOffset = new Uint32Array(width);
|
||||||
var mask3LSB = 0xfffffff8; // used to clear the 3 LSBs
|
var mask3LSB = 0xfffffff8; // used to clear the 3 LSBs
|
||||||
|
|
||||||
@ -985,12 +981,12 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
_convertYccToRgb: function convertYccToRgb(data) {
|
_convertYccToRgb: function convertYccToRgb(data) {
|
||||||
var Y, Cb, Cr;
|
var Y, Cb, Cr;
|
||||||
for (var i = 0, length = data.length; i < length; i += 3) {
|
for (var i = 0, length = data.length; i < length; i += 3) {
|
||||||
Y = data[i ];
|
Y = data[i];
|
||||||
Cb = data[i + 1];
|
Cb = data[i + 1];
|
||||||
Cr = data[i + 2];
|
Cr = data[i + 2];
|
||||||
data[i ] = clamp0to255(Y - 179.456 + 1.402 * Cr);
|
data[i] = Y - 179.456 + 1.402 * Cr;
|
||||||
data[i + 1] = clamp0to255(Y + 135.459 - 0.344 * Cb - 0.714 * Cr);
|
data[i + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr;
|
||||||
data[i + 2] = clamp0to255(Y - 226.816 + 1.772 * Cb);
|
data[i + 2] = Y - 226.816 + 1.772 * Cb;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@ -999,12 +995,12 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
var Y, Cb, Cr, k;
|
var Y, Cb, Cr, k;
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
for (var i = 0, length = data.length; i < length; i += 4) {
|
for (var i = 0, length = data.length; i < length; i += 4) {
|
||||||
Y = data[i];
|
Y = data[i];
|
||||||
Cb = data[i + 1];
|
Cb = data[i + 1];
|
||||||
Cr = data[i + 2];
|
Cr = data[i + 2];
|
||||||
k = data[i + 3];
|
k = data[i + 3];
|
||||||
|
|
||||||
var r = -122.67195406894 +
|
data[offset++] = -122.67195406894 +
|
||||||
Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr -
|
Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr -
|
||||||
5.4080610064599e-5 * Y + 0.00048449797120281 * k -
|
5.4080610064599e-5 * Y + 0.00048449797120281 * k -
|
||||||
0.154362151871126) +
|
0.154362151871126) +
|
||||||
@ -1014,7 +1010,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
0.48357088451265) +
|
0.48357088451265) +
|
||||||
k * (-0.000336197177618394 * k + 0.484791561490776);
|
k * (-0.000336197177618394 * k + 0.484791561490776);
|
||||||
|
|
||||||
var g = 107.268039397724 +
|
data[offset++] = 107.268039397724 +
|
||||||
Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr +
|
Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr +
|
||||||
0.000659397001245577 * Y + 0.000426105652938837 * k -
|
0.000659397001245577 * Y + 0.000426105652938837 * k -
|
||||||
0.176491792462875) +
|
0.176491792462875) +
|
||||||
@ -1024,7 +1020,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
0.25802910206845) +
|
0.25802910206845) +
|
||||||
k * (-0.000318913117588328 * k - 0.213742400323665);
|
k * (-0.000318913117588328 * k - 0.213742400323665);
|
||||||
|
|
||||||
var b = -20.810012546947 +
|
data[offset++] = -20.810012546947 +
|
||||||
Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr +
|
Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr +
|
||||||
0.0020741088115012 * Y - 0.00288260236853442 * k +
|
0.0020741088115012 * Y - 0.00288260236853442 * k +
|
||||||
0.814272968359295) +
|
0.814272968359295) +
|
||||||
@ -1033,10 +1029,6 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
Y * (0.00174418132927582 * Y - 0.00255243321439347 * k +
|
Y * (0.00174418132927582 * Y - 0.00255243321439347 * k +
|
||||||
0.116935020465145) +
|
0.116935020465145) +
|
||||||
k * (-0.000343531996510555 * k + 0.24165260232407);
|
k * (-0.000343531996510555 * k + 0.24165260232407);
|
||||||
|
|
||||||
data[offset++] = clamp0to255(r);
|
|
||||||
data[offset++] = clamp0to255(g);
|
|
||||||
data[offset++] = clamp0to255(b);
|
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@ -1044,12 +1036,12 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
_convertYcckToCmyk: function convertYcckToCmyk(data) {
|
_convertYcckToCmyk: function convertYcckToCmyk(data) {
|
||||||
var Y, Cb, Cr;
|
var Y, Cb, Cr;
|
||||||
for (var i = 0, length = data.length; i < length; i += 4) {
|
for (var i = 0, length = data.length; i < length; i += 4) {
|
||||||
Y = data[i];
|
Y = data[i];
|
||||||
Cb = data[i + 1];
|
Cb = data[i + 1];
|
||||||
Cr = data[i + 2];
|
Cr = data[i + 2];
|
||||||
data[i ] = clamp0to255(434.456 - Y - 1.402 * Cr);
|
data[i] = 434.456 - Y - 1.402 * Cr;
|
||||||
data[i + 1] = clamp0to255(119.541 - Y + 0.344 * Cb + 0.714 * Cr);
|
data[i + 1] = 119.541 - Y + 0.344 * Cb + 0.714 * Cr;
|
||||||
data[i + 2] = clamp0to255(481.816 - Y - 1.772 * Cb);
|
data[i + 2] = 481.816 - Y - 1.772 * Cb;
|
||||||
// K in data[i + 3] is unchanged
|
// K in data[i + 3] is unchanged
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
@ -1058,45 +1050,42 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
_convertCmykToRgb: function convertCmykToRgb(data) {
|
_convertCmykToRgb: function convertCmykToRgb(data) {
|
||||||
var c, m, y, k;
|
var c, m, y, k;
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
var min = -255 * 255 * 255;
|
var scale = 1 / 255;
|
||||||
var scale = 1 / 255 / 255;
|
|
||||||
for (var i = 0, length = data.length; i < length; i += 4) {
|
for (var i = 0, length = data.length; i < length; i += 4) {
|
||||||
c = data[i];
|
c = data[i] * scale;
|
||||||
m = data[i + 1];
|
m = data[i + 1] * scale;
|
||||||
y = data[i + 2];
|
y = data[i + 2] * scale;
|
||||||
k = data[i + 3];
|
k = data[i + 3] * scale;
|
||||||
|
|
||||||
var r =
|
data[offset++] = 255 +
|
||||||
c * (-4.387332384609988 * c + 54.48615194189176 * m +
|
c * (-4.387332384609988 * c + 54.48615194189176 * m +
|
||||||
18.82290502165302 * y + 212.25662451639585 * k -
|
18.82290502165302 * y + 212.25662451639585 * k -
|
||||||
72734.4411664936) +
|
285.2331026137004) +
|
||||||
m * (1.7149763477362134 * m - 5.6096736904047315 * y -
|
m * (1.7149763477362134 * m - 5.6096736904047315 * y -
|
||||||
17.873870861415444 * k - 1401.7366389350734) +
|
17.873870861415444 * k - 5.497006427196366) +
|
||||||
y * (-2.5217340131683033 * y - 21.248923337353073 * k +
|
y * (-2.5217340131683033 * y - 21.248923337353073 * k +
|
||||||
4465.541406466231) -
|
17.5119270841813) -
|
||||||
k * (21.86122147463605 * k + 48317.86113160301);
|
k * (21.86122147463605 * k + 189.48180835922747);
|
||||||
var g =
|
|
||||||
|
data[offset++] = 255 +
|
||||||
c * (8.841041422036149 * c + 60.118027045597366 * m +
|
c * (8.841041422036149 * c + 60.118027045597366 * m +
|
||||||
6.871425592049007 * y + 31.159100130055922 * k -
|
6.871425592049007 * y + 31.159100130055922 * k -
|
||||||
20220.756542821975) +
|
79.2970844816548) +
|
||||||
m * (-15.310361306967817 * m + 17.575251261109482 * y +
|
m * (-15.310361306967817 * m + 17.575251261109482 * y +
|
||||||
131.35250912493976 * k - 48691.05921601825) +
|
131.35250912493976 * k - 190.9453302588951) +
|
||||||
y * (4.444339102852739 * y + 9.8632861493405 * k -
|
y * (4.444339102852739 * y + 9.8632861493405 * k -
|
||||||
6341.191035517494) -
|
24.86741582555878) -
|
||||||
k * (20.737325471181034 * k + 47890.15695978492);
|
k * (20.737325471181034 * k + 187.80453709719578);
|
||||||
var b =
|
|
||||||
|
data[offset++] = 255 +
|
||||||
c * (0.8842522430003296 * c + 8.078677503112928 * m +
|
c * (0.8842522430003296 * c + 8.078677503112928 * m +
|
||||||
30.89978309703729 * y - 0.23883238689178934 * k -
|
30.89978309703729 * y - 0.23883238689178934 * k -
|
||||||
3616.812083916688) +
|
14.183576799673286) +
|
||||||
m * (10.49593273432072 * m + 63.02378494754052 * y +
|
m * (10.49593273432072 * m + 63.02378494754052 * y +
|
||||||
50.606957656360734 * k - 28620.90484698408) +
|
50.606957656360734 * k - 112.23884253719248) +
|
||||||
y * (0.03296041114873217 * y + 115.60384449646641 * k -
|
y * (0.03296041114873217 * y + 115.60384449646641 * k -
|
||||||
49363.43385999684) -
|
193.58209356861505) -
|
||||||
k * (22.33816807309886 * k + 45932.16563550634);
|
k * (22.33816807309886 * k + 180.12613974708367);
|
||||||
|
|
||||||
data[offset++] = r >= 0 ? 255 : r <= min ? 0 : 255 + r * scale | 0;
|
|
||||||
data[offset++] = g >= 0 ? 255 : g <= min ? 0 : 255 + g * scale | 0;
|
|
||||||
data[offset++] = b >= 0 ? 255 : b <= min ? 0 : 255 + b * scale | 0;
|
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@ -1110,7 +1099,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
|
|
||||||
if (this.numComponents === 1 && forceRGBoutput) {
|
if (this.numComponents === 1 && forceRGBoutput) {
|
||||||
var dataLength = data.length;
|
var dataLength = data.length;
|
||||||
var rgbData = new Uint8Array(dataLength * 3);
|
var rgbData = new Uint8ClampedArray(dataLength * 3);
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
for (var i = 0; i < dataLength; i++) {
|
for (var i = 0; i < dataLength; i++) {
|
||||||
var grayColor = data[i];
|
var grayColor = data[i];
|
||||||
|
Loading…
Reference in New Issue
Block a user