[api-minor] Use an icc profile for converting CMYK to RGB
This commit is contained in:
parent
1bc98dfbd9
commit
7280540901
BIN
external/iccs/CGATS001Compat-v2-micro.icc
vendored
Executable file
BIN
external/iccs/CGATS001Compat-v2-micro.icc
vendored
Executable file
Binary file not shown.
116
external/iccs/LICENSE
vendored
Normal file
116
external/iccs/LICENSE
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
CC0 1.0 Universal
|
||||||
|
|
||||||
|
Statement of Purpose
|
||||||
|
|
||||||
|
The laws of most jurisdictions throughout the world automatically confer
|
||||||
|
exclusive Copyright and Related Rights (defined below) upon the creator and
|
||||||
|
subsequent owner(s) (each and all, an "owner") of an original work of
|
||||||
|
authorship and/or a database (each, a "Work").
|
||||||
|
|
||||||
|
Certain owners wish to permanently relinquish those rights to a Work for the
|
||||||
|
purpose of contributing to a commons of creative, cultural and scientific
|
||||||
|
works ("Commons") that the public can reliably and without fear of later
|
||||||
|
claims of infringement build upon, modify, incorporate in other works, reuse
|
||||||
|
and redistribute as freely as possible in any form whatsoever and for any
|
||||||
|
purposes, including without limitation commercial purposes. These owners may
|
||||||
|
contribute to the Commons to promote the ideal of a free culture and the
|
||||||
|
further production of creative, cultural and scientific works, or to gain
|
||||||
|
reputation or greater distribution for their Work in part through the use and
|
||||||
|
efforts of others.
|
||||||
|
|
||||||
|
For these and/or other purposes and motivations, and without any expectation
|
||||||
|
of additional consideration or compensation, the person associating CC0 with a
|
||||||
|
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
|
||||||
|
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
|
||||||
|
and publicly distribute the Work under its terms, with knowledge of his or her
|
||||||
|
Copyright and Related Rights in the Work and the meaning and intended legal
|
||||||
|
effect of CC0 on those rights.
|
||||||
|
|
||||||
|
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||||
|
protected by copyright and related or neighboring rights ("Copyright and
|
||||||
|
Related Rights"). Copyright and Related Rights include, but are not limited
|
||||||
|
to, the following:
|
||||||
|
|
||||||
|
i. the right to reproduce, adapt, distribute, perform, display, communicate,
|
||||||
|
and translate a Work;
|
||||||
|
|
||||||
|
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||||
|
|
||||||
|
iii. publicity and privacy rights pertaining to a person's image or likeness
|
||||||
|
depicted in a Work;
|
||||||
|
|
||||||
|
iv. rights protecting against unfair competition in regards to a Work,
|
||||||
|
subject to the limitations in paragraph 4(a), below;
|
||||||
|
|
||||||
|
v. rights protecting the extraction, dissemination, use and reuse of data in
|
||||||
|
a Work;
|
||||||
|
|
||||||
|
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||||
|
European Parliament and of the Council of 11 March 1996 on the legal
|
||||||
|
protection of databases, and under any national implementation thereof,
|
||||||
|
including any amended or successor version of such directive); and
|
||||||
|
|
||||||
|
vii. other similar, equivalent or corresponding rights throughout the world
|
||||||
|
based on applicable law or treaty, and any national implementations thereof.
|
||||||
|
|
||||||
|
2. Waiver. To the greatest extent permitted by, but not in contravention of,
|
||||||
|
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
|
||||||
|
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
|
||||||
|
and Related Rights and associated claims and causes of action, whether now
|
||||||
|
known or unknown (including existing as well as future claims and causes of
|
||||||
|
action), in the Work (i) in all territories worldwide, (ii) for the maximum
|
||||||
|
duration provided by applicable law or treaty (including future time
|
||||||
|
extensions), (iii) in any current or future medium and for any number of
|
||||||
|
copies, and (iv) for any purpose whatsoever, including without limitation
|
||||||
|
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
|
||||||
|
the Waiver for the benefit of each member of the public at large and to the
|
||||||
|
detriment of Affirmer's heirs and successors, fully intending that such Waiver
|
||||||
|
shall not be subject to revocation, rescission, cancellation, termination, or
|
||||||
|
any other legal or equitable action to disrupt the quiet enjoyment of the Work
|
||||||
|
by the public as contemplated by Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
3. Public License Fallback. Should any part of the Waiver for any reason be
|
||||||
|
judged legally invalid or ineffective under applicable law, then the Waiver
|
||||||
|
shall be preserved to the maximum extent permitted taking into account
|
||||||
|
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
|
||||||
|
is so judged Affirmer hereby grants to each affected person a royalty-free,
|
||||||
|
non transferable, non sublicensable, non exclusive, irrevocable and
|
||||||
|
unconditional license to exercise Affirmer's Copyright and Related Rights in
|
||||||
|
the Work (i) in all territories worldwide, (ii) for the maximum duration
|
||||||
|
provided by applicable law or treaty (including future time extensions), (iii)
|
||||||
|
in any current or future medium and for any number of copies, and (iv) for any
|
||||||
|
purpose whatsoever, including without limitation commercial, advertising or
|
||||||
|
promotional purposes (the "License"). The License shall be deemed effective as
|
||||||
|
of the date CC0 was applied by Affirmer to the Work. Should any part of the
|
||||||
|
License for any reason be judged legally invalid or ineffective under
|
||||||
|
applicable law, such partial invalidity or ineffectiveness shall not
|
||||||
|
invalidate the remainder of the License, and in such case Affirmer hereby
|
||||||
|
affirms that he or she will not (i) exercise any of his or her remaining
|
||||||
|
Copyright and Related Rights in the Work or (ii) assert any associated claims
|
||||||
|
and causes of action with respect to the Work, in either case contrary to
|
||||||
|
Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
4. Limitations and Disclaimers.
|
||||||
|
|
||||||
|
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||||
|
surrendered, licensed or otherwise affected by this document.
|
||||||
|
|
||||||
|
b. Affirmer offers the Work as-is and makes no representations or warranties
|
||||||
|
of any kind concerning the Work, express, implied, statutory or otherwise,
|
||||||
|
including without limitation warranties of title, merchantability, fitness
|
||||||
|
for a particular purpose, non infringement, or the absence of latent or
|
||||||
|
other defects, accuracy, or the present or absence of errors, whether or not
|
||||||
|
discoverable, all to the greatest extent permissible under applicable law.
|
||||||
|
|
||||||
|
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||||
|
that may apply to the Work or any use thereof, including without limitation
|
||||||
|
any person's Copyright and Related Rights in the Work. Further, Affirmer
|
||||||
|
disclaims responsibility for obtaining any necessary consents, permissions
|
||||||
|
or other rights required for any use of the Work.
|
||||||
|
|
||||||
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
|
party to this document and has no duty or obligation with respect to this
|
||||||
|
CC0 or use of the Work.
|
||||||
|
|
||||||
|
For more information, please see
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
10
external/iccs/README.md
vendored
Normal file
10
external/iccs/README.md
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
## ICC
|
||||||
|
|
||||||
|
The file CGATS001Compat-v2-micro.icc used to convert colors from CMYK to RGB comes from:
|
||||||
|
https://github.com/saucecontrol/Compact-ICC-Profiles
|
||||||
|
|
||||||
|
at revision bdd84663061bc4ae95ca70decff54f581e27f702.
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
[CGATS001Compat-v2-micro.icc](https://github.com/saucecontrol/Compact-ICC-Profiles/blob/master/profiles/CGATS001Compat-v2-micro.icc) is under [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||||
BIN
external/qcms/qcms_bg.wasm
vendored
BIN
external/qcms/qcms_bg.wasm
vendored
Binary file not shown.
21
external/qcms/qcms_utils.js
vendored
21
external/qcms/qcms_utils.js
vendored
@ -16,6 +16,8 @@
|
|||||||
class QCMS {
|
class QCMS {
|
||||||
static _module = null;
|
static _module = null;
|
||||||
|
|
||||||
|
static _mustAddAlpha = false;
|
||||||
|
|
||||||
static _destBuffer = null;
|
static _destBuffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,16 +25,25 @@ function copy_result(ptr, len) {
|
|||||||
// This function is called from the wasm module (it's an external
|
// This function is called from the wasm module (it's an external
|
||||||
// "C" function). Its goal is to copy the result from the wasm memory
|
// "C" function). Its goal is to copy the result from the wasm memory
|
||||||
// to the destination buffer without any intermediate copies.
|
// to the destination buffer without any intermediate copies.
|
||||||
const { _module, _destBuffer } = QCMS;
|
const { _module, _mustAddAlpha, _destBuffer } = QCMS;
|
||||||
const result = new Uint8Array(_module.memory.buffer, ptr, len);
|
const result = new Uint8Array(_module.memory.buffer, ptr, len);
|
||||||
if (result.length === _destBuffer.length) {
|
if (result.length === _destBuffer.length) {
|
||||||
_destBuffer.set(result);
|
_destBuffer.set(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (let i = 0, j = 0, ii = result.length; i < ii; i += 3, j += 4) {
|
if (_mustAddAlpha) {
|
||||||
_destBuffer[j] = result[i];
|
for (let i = 0, j = 0, ii = result.length; i < ii; i += 3, j += 4) {
|
||||||
_destBuffer[j + 1] = result[i + 1];
|
_destBuffer[j] = result[i];
|
||||||
_destBuffer[j + 2] = result[i + 2];
|
_destBuffer[j + 1] = result[i + 1];
|
||||||
|
_destBuffer[j + 2] = result[i + 2];
|
||||||
|
_destBuffer[j + 3] = 255;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (let i = 0, j = 0, ii = result.length; i < ii; i += 3, j += 4) {
|
||||||
|
_destBuffer[j] = result[i];
|
||||||
|
_destBuffer[j + 1] = result[i + 1];
|
||||||
|
_destBuffer[j + 2] = result[i + 2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
gulpfile.mjs
18
gulpfile.mjs
@ -636,6 +636,13 @@ function createCMapBundle() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createICCBundle() {
|
||||||
|
return gulp.src(["external/iccs/*.icc", "external/iccs/LICENSE"], {
|
||||||
|
base: "external/iccs",
|
||||||
|
encoding: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function createStandardFontBundle() {
|
function createStandardFontBundle() {
|
||||||
return gulp.src(
|
return gulp.src(
|
||||||
[
|
[
|
||||||
@ -1091,6 +1098,7 @@ function buildGeneric(defines, dir) {
|
|||||||
})
|
})
|
||||||
.pipe(gulp.dest(dir + "web")),
|
.pipe(gulp.dest(dir + "web")),
|
||||||
createCMapBundle().pipe(gulp.dest(dir + "web/cmaps")),
|
createCMapBundle().pipe(gulp.dest(dir + "web/cmaps")),
|
||||||
|
createICCBundle().pipe(gulp.dest(dir + "web/iccs")),
|
||||||
createStandardFontBundle().pipe(gulp.dest(dir + "web/standard_fonts")),
|
createStandardFontBundle().pipe(gulp.dest(dir + "web/standard_fonts")),
|
||||||
createWasmBundle().pipe(gulp.dest(dir + "web/wasm")),
|
createWasmBundle().pipe(gulp.dest(dir + "web/wasm")),
|
||||||
|
|
||||||
@ -1420,6 +1428,7 @@ gulp.task(
|
|||||||
createCMapBundle().pipe(
|
createCMapBundle().pipe(
|
||||||
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/cmaps")
|
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/cmaps")
|
||||||
),
|
),
|
||||||
|
createICCBundle().pipe(gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/iccs")),
|
||||||
createStandardFontBundle().pipe(
|
createStandardFontBundle().pipe(
|
||||||
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/standard_fonts")
|
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/standard_fonts")
|
||||||
),
|
),
|
||||||
@ -1525,6 +1534,9 @@ gulp.task(
|
|||||||
createCMapBundle().pipe(
|
createCMapBundle().pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/cmaps")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/cmaps")
|
||||||
),
|
),
|
||||||
|
createICCBundle().pipe(
|
||||||
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/iccs")
|
||||||
|
),
|
||||||
createStandardFontBundle().pipe(
|
createStandardFontBundle().pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/standard_fonts")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/standard_fonts")
|
||||||
),
|
),
|
||||||
@ -2364,6 +2376,12 @@ gulp.task(
|
|||||||
encoding: false,
|
encoding: false,
|
||||||
})
|
})
|
||||||
.pipe(gulp.dest(DIST_DIR)),
|
.pipe(gulp.dest(DIST_DIR)),
|
||||||
|
gulp
|
||||||
|
.src(GENERIC_DIR + "web/iccs/**/*", {
|
||||||
|
base: GENERIC_DIR + "web",
|
||||||
|
encoding: false,
|
||||||
|
})
|
||||||
|
.pipe(gulp.dest(DIST_DIR)),
|
||||||
gulp
|
gulp
|
||||||
.src(GENERIC_DIR + "web/standard_fonts/**/*", {
|
.src(GENERIC_DIR + "web/standard_fonts/**/*", {
|
||||||
base: GENERIC_DIR + "web",
|
base: GENERIC_DIR + "web",
|
||||||
|
|||||||
@ -25,9 +25,9 @@ import {
|
|||||||
LabCS,
|
LabCS,
|
||||||
PatternCS,
|
PatternCS,
|
||||||
} from "./colorspace.js";
|
} from "./colorspace.js";
|
||||||
|
import { CmykICCBasedCS, IccColorSpace } from "./icc_colorspace.js";
|
||||||
import { Dict, Name, Ref } from "./primitives.js";
|
import { Dict, Name, Ref } from "./primitives.js";
|
||||||
import { MathClamp, shadow, unreachable, warn } from "../shared/util.js";
|
import { MathClamp, shadow, unreachable, warn } from "../shared/util.js";
|
||||||
import { IccColorSpace } from "./icc_colorspace.js";
|
|
||||||
import { MissingDataException } from "./core_utils.js";
|
import { MissingDataException } from "./core_utils.js";
|
||||||
|
|
||||||
class ColorSpaceUtils {
|
class ColorSpaceUtils {
|
||||||
@ -205,7 +205,11 @@ class ColorSpaceUtils {
|
|||||||
|
|
||||||
if (IccColorSpace.isUsable) {
|
if (IccColorSpace.isUsable) {
|
||||||
try {
|
try {
|
||||||
const iccCS = new IccColorSpace(stream.getBytes(), numComps);
|
const iccCS = new IccColorSpace(
|
||||||
|
stream.getBytes(),
|
||||||
|
"ICCBased",
|
||||||
|
numComps
|
||||||
|
);
|
||||||
if (isRef) {
|
if (isRef) {
|
||||||
globalColorSpaceCache.set(/* name = */ null, cs[1], iccCS);
|
globalColorSpaceCache.set(/* name = */ null, cs[1], iccCS);
|
||||||
}
|
}
|
||||||
@ -285,6 +289,13 @@ class ColorSpaceUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get cmyk() {
|
static get cmyk() {
|
||||||
|
if (IccColorSpace.isUsable) {
|
||||||
|
try {
|
||||||
|
return shadow(this, "cmyk", new CmykICCBasedCS());
|
||||||
|
} catch {
|
||||||
|
warn("CMYK fallback: DeviceCMYK");
|
||||||
|
}
|
||||||
|
}
|
||||||
return shadow(this, "cmyk", new DeviceCmykCS());
|
return shadow(this, "cmyk", new DeviceCmykCS());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,6 +94,7 @@ const DefaultPartialEvaluatorOptions = Object.freeze({
|
|||||||
useWasm: true,
|
useWasm: true,
|
||||||
useWorkerFetch: true,
|
useWorkerFetch: true,
|
||||||
cMapUrl: null,
|
cMapUrl: null,
|
||||||
|
iccUrl: null,
|
||||||
standardFontDataUrl: null,
|
standardFontDataUrl: null,
|
||||||
wasmUrl: null,
|
wasmUrl: null,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -41,12 +41,12 @@ class IccColorSpace extends ColorSpace {
|
|||||||
qcms_drop_transformer(transformer);
|
qcms_drop_transformer(transformer);
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(iccProfile, numComps) {
|
constructor(iccProfile, name, numComps) {
|
||||||
if (!IccColorSpace.isUsable) {
|
if (!IccColorSpace.isUsable) {
|
||||||
throw new Error("No ICC color space support");
|
throw new Error("No ICC color space support");
|
||||||
}
|
}
|
||||||
|
|
||||||
super("ICCBased", numComps);
|
super(name, numComps);
|
||||||
|
|
||||||
let inType;
|
let inType;
|
||||||
switch (numComps) {
|
switch (numComps) {
|
||||||
@ -104,11 +104,13 @@ class IccColorSpace extends ColorSpace {
|
|||||||
src[i] *= scale;
|
src[i] *= scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QCMS._mustAddAlpha = alpha01 && dest.buffer === src.buffer;
|
||||||
QCMS._destBuffer = dest.subarray(
|
QCMS._destBuffer = dest.subarray(
|
||||||
destOffset,
|
destOffset,
|
||||||
destOffset + count * (3 + alpha01)
|
destOffset + count * (3 + alpha01)
|
||||||
);
|
);
|
||||||
qcms_convert_array(this.#transformer, src);
|
qcms_convert_array(this.#transformer, src);
|
||||||
|
QCMS._mustAddAlpha = false;
|
||||||
QCMS._destBuffer = null;
|
QCMS._destBuffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,4 +154,21 @@ class IccColorSpace extends ColorSpace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { IccColorSpace };
|
class CmykICCBasedCS extends IccColorSpace {
|
||||||
|
static #iccUrl;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
const filename = "CGATS001Compat-v2-micro.icc";
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", `${CmykICCBasedCS.#iccUrl}${filename}`, false);
|
||||||
|
xhr.responseType = "arraybuffer";
|
||||||
|
xhr.send(null);
|
||||||
|
super(new Uint8Array(xhr.response), "DeviceCMYK", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static setOptions({ iccUrl }) {
|
||||||
|
this.#iccUrl = iccUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CmykICCBasedCS, IccColorSpace };
|
||||||
|
|||||||
272
src/core/jpg.js
272
src/core/jpg.js
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert, BaseException, warn } from "../shared/util.js";
|
import { assert, BaseException, warn } from "../shared/util.js";
|
||||||
|
import { ColorSpaceUtils } from "./colorspace_utils.js";
|
||||||
import { grayToRGBA } from "../shared/image_utils.js";
|
import { grayToRGBA } from "../shared/image_utils.js";
|
||||||
import { readUint16 } from "./core_utils.js";
|
import { readUint16 } from "./core_utils.js";
|
||||||
|
|
||||||
@ -1317,141 +1318,13 @@ class JpegImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_convertYcckToRgb(data) {
|
_convertYcckToRgb(data) {
|
||||||
let Y, Cb, Cr, k;
|
this._convertYcckToCmyk(data);
|
||||||
let offset = 0;
|
return this._convertCmykToRgb(data);
|
||||||
for (let i = 0, length = data.length; i < length; i += 4) {
|
|
||||||
Y = data[i];
|
|
||||||
Cb = data[i + 1];
|
|
||||||
Cr = data[i + 2];
|
|
||||||
k = data[i + 3];
|
|
||||||
|
|
||||||
data[offset++] =
|
|
||||||
-122.67195406894 +
|
|
||||||
Cb *
|
|
||||||
(-6.60635669420364e-5 * Cb +
|
|
||||||
0.000437130475926232 * Cr -
|
|
||||||
5.4080610064599e-5 * Y +
|
|
||||||
0.00048449797120281 * k -
|
|
||||||
0.154362151871126) +
|
|
||||||
Cr *
|
|
||||||
(-0.000957964378445773 * Cr +
|
|
||||||
0.000817076911346625 * Y -
|
|
||||||
0.00477271405408747 * k +
|
|
||||||
1.53380253221734) +
|
|
||||||
Y *
|
|
||||||
(0.000961250184130688 * Y -
|
|
||||||
0.00266257332283933 * k +
|
|
||||||
0.48357088451265) +
|
|
||||||
k * (-0.000336197177618394 * k + 0.484791561490776);
|
|
||||||
|
|
||||||
data[offset++] =
|
|
||||||
107.268039397724 +
|
|
||||||
Cb *
|
|
||||||
(2.19927104525741e-5 * Cb -
|
|
||||||
0.000640992018297945 * Cr +
|
|
||||||
0.000659397001245577 * Y +
|
|
||||||
0.000426105652938837 * k -
|
|
||||||
0.176491792462875) +
|
|
||||||
Cr *
|
|
||||||
(-0.000778269941513683 * Cr +
|
|
||||||
0.00130872261408275 * Y +
|
|
||||||
0.000770482631801132 * k -
|
|
||||||
0.151051492775562) +
|
|
||||||
Y *
|
|
||||||
(0.00126935368114843 * Y -
|
|
||||||
0.00265090189010898 * k +
|
|
||||||
0.25802910206845) +
|
|
||||||
k * (-0.000318913117588328 * k - 0.213742400323665);
|
|
||||||
|
|
||||||
data[offset++] =
|
|
||||||
-20.810012546947 +
|
|
||||||
Cb *
|
|
||||||
(-0.000570115196973677 * Cb -
|
|
||||||
2.63409051004589e-5 * Cr +
|
|
||||||
0.0020741088115012 * Y -
|
|
||||||
0.00288260236853442 * k +
|
|
||||||
0.814272968359295) +
|
|
||||||
Cr *
|
|
||||||
(-1.53496057440975e-5 * Cr -
|
|
||||||
0.000132689043961446 * Y +
|
|
||||||
0.000560833691242812 * k -
|
|
||||||
0.195152027534049) +
|
|
||||||
Y *
|
|
||||||
(0.00174418132927582 * Y -
|
|
||||||
0.00255243321439347 * k +
|
|
||||||
0.116935020465145) +
|
|
||||||
k * (-0.000343531996510555 * k + 0.24165260232407);
|
|
||||||
}
|
|
||||||
// Ensure that only the converted RGB data is returned.
|
|
||||||
return data.subarray(0, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_convertYcckToRgba(data) {
|
_convertYcckToRgba(data) {
|
||||||
for (let i = 0, length = data.length; i < length; i += 4) {
|
this._convertYcckToCmyk(data);
|
||||||
const Y = data[i];
|
return this._convertCmykToRgba(data);
|
||||||
const Cb = data[i + 1];
|
|
||||||
const Cr = data[i + 2];
|
|
||||||
const k = data[i + 3];
|
|
||||||
|
|
||||||
data[i] =
|
|
||||||
-122.67195406894 +
|
|
||||||
Cb *
|
|
||||||
(-6.60635669420364e-5 * Cb +
|
|
||||||
0.000437130475926232 * Cr -
|
|
||||||
5.4080610064599e-5 * Y +
|
|
||||||
0.00048449797120281 * k -
|
|
||||||
0.154362151871126) +
|
|
||||||
Cr *
|
|
||||||
(-0.000957964378445773 * Cr +
|
|
||||||
0.000817076911346625 * Y -
|
|
||||||
0.00477271405408747 * k +
|
|
||||||
1.53380253221734) +
|
|
||||||
Y *
|
|
||||||
(0.000961250184130688 * Y -
|
|
||||||
0.00266257332283933 * k +
|
|
||||||
0.48357088451265) +
|
|
||||||
k * (-0.000336197177618394 * k + 0.484791561490776);
|
|
||||||
|
|
||||||
data[i + 1] =
|
|
||||||
107.268039397724 +
|
|
||||||
Cb *
|
|
||||||
(2.19927104525741e-5 * Cb -
|
|
||||||
0.000640992018297945 * Cr +
|
|
||||||
0.000659397001245577 * Y +
|
|
||||||
0.000426105652938837 * k -
|
|
||||||
0.176491792462875) +
|
|
||||||
Cr *
|
|
||||||
(-0.000778269941513683 * Cr +
|
|
||||||
0.00130872261408275 * Y +
|
|
||||||
0.000770482631801132 * k -
|
|
||||||
0.151051492775562) +
|
|
||||||
Y *
|
|
||||||
(0.00126935368114843 * Y -
|
|
||||||
0.00265090189010898 * k +
|
|
||||||
0.25802910206845) +
|
|
||||||
k * (-0.000318913117588328 * k - 0.213742400323665);
|
|
||||||
|
|
||||||
data[i + 2] =
|
|
||||||
-20.810012546947 +
|
|
||||||
Cb *
|
|
||||||
(-0.000570115196973677 * Cb -
|
|
||||||
2.63409051004589e-5 * Cr +
|
|
||||||
0.0020741088115012 * Y -
|
|
||||||
0.00288260236853442 * k +
|
|
||||||
0.814272968359295) +
|
|
||||||
Cr *
|
|
||||||
(-1.53496057440975e-5 * Cr -
|
|
||||||
0.000132689043961446 * Y +
|
|
||||||
0.000560833691242812 * k -
|
|
||||||
0.195152027534049) +
|
|
||||||
Y *
|
|
||||||
(0.00174418132927582 * Y -
|
|
||||||
0.00255243321439347 * k +
|
|
||||||
0.116935020465145) +
|
|
||||||
k * (-0.000343531996510555 * k + 0.24165260232407);
|
|
||||||
data[i + 3] = 255;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_convertYcckToCmyk(data) {
|
_convertYcckToCmyk(data) {
|
||||||
@ -1469,140 +1342,13 @@ class JpegImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_convertCmykToRgb(data) {
|
_convertCmykToRgb(data) {
|
||||||
let c, m, y, k;
|
const count = data.length / 4;
|
||||||
let offset = 0;
|
ColorSpaceUtils.cmyk.getRgbBuffer(data, 0, count, data, 0, 8, 0);
|
||||||
for (let i = 0, length = data.length; i < length; i += 4) {
|
return data.subarray(0, count * 3);
|
||||||
c = data[i];
|
|
||||||
m = data[i + 1];
|
|
||||||
y = data[i + 2];
|
|
||||||
k = data[i + 3];
|
|
||||||
|
|
||||||
data[offset++] =
|
|
||||||
255 +
|
|
||||||
c *
|
|
||||||
(-0.00006747147073602441 * c +
|
|
||||||
0.0008379262121013727 * m +
|
|
||||||
0.0002894718188643294 * y +
|
|
||||||
0.003264231057537806 * k -
|
|
||||||
1.1185611867203937) +
|
|
||||||
m *
|
|
||||||
(0.000026374107616089405 * m -
|
|
||||||
0.00008626949158638572 * y -
|
|
||||||
0.0002748769067499491 * k -
|
|
||||||
0.02155688794978967) +
|
|
||||||
y *
|
|
||||||
(-0.00003878099212869363 * y -
|
|
||||||
0.0003267808279485286 * k +
|
|
||||||
0.0686742238595345) -
|
|
||||||
k * (0.0003361971776183937 * k + 0.7430659151342254);
|
|
||||||
|
|
||||||
data[offset++] =
|
|
||||||
255 +
|
|
||||||
c *
|
|
||||||
(0.00013596372813588848 * c +
|
|
||||||
0.000924537132573585 * m +
|
|
||||||
0.00010567359618683593 * y +
|
|
||||||
0.0004791864687436512 * k -
|
|
||||||
0.3109689587515875) +
|
|
||||||
m *
|
|
||||||
(-0.00023545346108370344 * m +
|
|
||||||
0.0002702845253534714 * y +
|
|
||||||
0.0020200308977307156 * k -
|
|
||||||
0.7488052167015494) +
|
|
||||||
y *
|
|
||||||
(0.00006834815998235662 * y +
|
|
||||||
0.00015168452363460973 * k -
|
|
||||||
0.09751927774728933) -
|
|
||||||
k * (0.0003189131175883281 * k + 0.7364883807733168);
|
|
||||||
|
|
||||||
data[offset++] =
|
|
||||||
255 +
|
|
||||||
c *
|
|
||||||
(0.000013598650411385307 * c +
|
|
||||||
0.00012423956175490851 * m +
|
|
||||||
0.0004751985097583589 * y -
|
|
||||||
0.0000036729317476630422 * k -
|
|
||||||
0.05562186980264034) +
|
|
||||||
m *
|
|
||||||
(0.00016141380598724676 * m +
|
|
||||||
0.0009692239130725186 * y +
|
|
||||||
0.0007782692450036253 * k -
|
|
||||||
0.44015232367526463) +
|
|
||||||
y *
|
|
||||||
(5.068882914068769e-7 * y +
|
|
||||||
0.0017778369011375071 * k -
|
|
||||||
0.7591454649749609) -
|
|
||||||
k * (0.0003435319965105553 * k + 0.7063770186160144);
|
|
||||||
}
|
|
||||||
// Ensure that only the converted RGB data is returned.
|
|
||||||
return data.subarray(0, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_convertCmykToRgba(data) {
|
_convertCmykToRgba(data) {
|
||||||
for (let i = 0, length = data.length; i < length; i += 4) {
|
ColorSpaceUtils.cmyk.getRgbBuffer(data, 0, data.length / 4, data, 0, 8, 1);
|
||||||
const c = data[i];
|
|
||||||
const m = data[i + 1];
|
|
||||||
const y = data[i + 2];
|
|
||||||
const k = data[i + 3];
|
|
||||||
|
|
||||||
data[i] =
|
|
||||||
255 +
|
|
||||||
c *
|
|
||||||
(-0.00006747147073602441 * c +
|
|
||||||
0.0008379262121013727 * m +
|
|
||||||
0.0002894718188643294 * y +
|
|
||||||
0.003264231057537806 * k -
|
|
||||||
1.1185611867203937) +
|
|
||||||
m *
|
|
||||||
(0.000026374107616089405 * m -
|
|
||||||
0.00008626949158638572 * y -
|
|
||||||
0.0002748769067499491 * k -
|
|
||||||
0.02155688794978967) +
|
|
||||||
y *
|
|
||||||
(-0.00003878099212869363 * y -
|
|
||||||
0.0003267808279485286 * k +
|
|
||||||
0.0686742238595345) -
|
|
||||||
k * (0.0003361971776183937 * k + 0.7430659151342254);
|
|
||||||
|
|
||||||
data[i + 1] =
|
|
||||||
255 +
|
|
||||||
c *
|
|
||||||
(0.00013596372813588848 * c +
|
|
||||||
0.000924537132573585 * m +
|
|
||||||
0.00010567359618683593 * y +
|
|
||||||
0.0004791864687436512 * k -
|
|
||||||
0.3109689587515875) +
|
|
||||||
m *
|
|
||||||
(-0.00023545346108370344 * m +
|
|
||||||
0.0002702845253534714 * y +
|
|
||||||
0.0020200308977307156 * k -
|
|
||||||
0.7488052167015494) +
|
|
||||||
y *
|
|
||||||
(0.00006834815998235662 * y +
|
|
||||||
0.00015168452363460973 * k -
|
|
||||||
0.09751927774728933) -
|
|
||||||
k * (0.0003189131175883281 * k + 0.7364883807733168);
|
|
||||||
|
|
||||||
data[i + 2] =
|
|
||||||
255 +
|
|
||||||
c *
|
|
||||||
(0.000013598650411385307 * c +
|
|
||||||
0.00012423956175490851 * m +
|
|
||||||
0.0004751985097583589 * y -
|
|
||||||
0.0000036729317476630422 * k -
|
|
||||||
0.05562186980264034) +
|
|
||||||
m *
|
|
||||||
(0.00016141380598724676 * m +
|
|
||||||
0.0009692239130725186 * y +
|
|
||||||
0.0007782692450036253 * k -
|
|
||||||
0.44015232367526463) +
|
|
||||||
y *
|
|
||||||
(5.068882914068769e-7 * y +
|
|
||||||
0.0017778369011375071 * k -
|
|
||||||
0.7591454649749609) -
|
|
||||||
k * (0.0003435319965105553 * k + 0.7063770186160144);
|
|
||||||
data[i + 3] = 255;
|
|
||||||
}
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { CmykICCBasedCS, IccColorSpace } from "./icc_colorspace.js";
|
||||||
import {
|
import {
|
||||||
createValidAbsoluteUrl,
|
createValidAbsoluteUrl,
|
||||||
FeatureTest,
|
FeatureTest,
|
||||||
@ -20,7 +21,6 @@ import {
|
|||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { ChunkedStreamManager } from "./chunked_stream.js";
|
import { ChunkedStreamManager } from "./chunked_stream.js";
|
||||||
import { IccColorSpace } from "./icc_colorspace.js";
|
|
||||||
import { ImageResizer } from "./image_resizer.js";
|
import { ImageResizer } from "./image_resizer.js";
|
||||||
import { JpegStream } from "./jpeg_stream.js";
|
import { JpegStream } from "./jpeg_stream.js";
|
||||||
import { JpxImage } from "./jpx.js";
|
import { JpxImage } from "./jpx.js";
|
||||||
@ -78,6 +78,7 @@ class BasePdfManager {
|
|||||||
const options = { ...evaluatorOptions, handler };
|
const options = { ...evaluatorOptions, handler };
|
||||||
JpxImage.setOptions(options);
|
JpxImage.setOptions(options);
|
||||||
IccColorSpace.setOptions(options);
|
IccColorSpace.setOptions(options);
|
||||||
|
CmykICCBasedCS.setOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
get docId() {
|
get docId() {
|
||||||
|
|||||||
@ -125,6 +125,8 @@ const RENDERING_CANCELLED_TIMEOUT = 100; // ms
|
|||||||
* @property {Object} [CMapReaderFactory] - The factory that will be used when
|
* @property {Object} [CMapReaderFactory] - The factory that will be used when
|
||||||
* reading built-in CMap files.
|
* reading built-in CMap files.
|
||||||
* The default value is {DOMCMapReaderFactory}.
|
* The default value is {DOMCMapReaderFactory}.
|
||||||
|
* @property {string} [iccUrl] - The URL where the predefined ICC profiles are
|
||||||
|
* located. Include the trailing slash.
|
||||||
* @property {boolean} [useSystemFonts] - When `true`, fonts that aren't
|
* @property {boolean} [useSystemFonts] - When `true`, fonts that aren't
|
||||||
* embedded in the PDF document will fallback to a system font.
|
* embedded in the PDF document will fallback to a system font.
|
||||||
* The default value is `true` in web environments and `false` in Node.js;
|
* The default value is `true` in web environments and `false` in Node.js;
|
||||||
@ -269,6 +271,7 @@ function getDocument(src = {}) {
|
|||||||
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC") && isNodeJS
|
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC") && isNodeJS
|
||||||
? NodeCMapReaderFactory
|
? NodeCMapReaderFactory
|
||||||
: DOMCMapReaderFactory);
|
: DOMCMapReaderFactory);
|
||||||
|
const iccUrl = getFactoryUrlProp(src.iccUrl);
|
||||||
const standardFontDataUrl = getFactoryUrlProp(src.standardFontDataUrl);
|
const standardFontDataUrl = getFactoryUrlProp(src.standardFontDataUrl);
|
||||||
const StandardFontDataFactory =
|
const StandardFontDataFactory =
|
||||||
src.StandardFontDataFactory ||
|
src.StandardFontDataFactory ||
|
||||||
@ -418,6 +421,7 @@ function getDocument(src = {}) {
|
|||||||
useWasm,
|
useWasm,
|
||||||
useWorkerFetch,
|
useWorkerFetch,
|
||||||
cMapUrl,
|
cMapUrl,
|
||||||
|
iccUrl,
|
||||||
standardFontDataUrl,
|
standardFontDataUrl,
|
||||||
wasmUrl,
|
wasmUrl,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -30,6 +30,7 @@ const { GenericL10n, parseQueryString, SimpleLinkService } = pdfjsViewer;
|
|||||||
|
|
||||||
const WAITING_TIME = 100; // ms
|
const WAITING_TIME = 100; // ms
|
||||||
const CMAP_URL = "/build/generic/web/cmaps/";
|
const CMAP_URL = "/build/generic/web/cmaps/";
|
||||||
|
const ICC_URL = "/build/generic/web/iccs/";
|
||||||
const STANDARD_FONT_DATA_URL = "/build/generic/web/standard_fonts/";
|
const STANDARD_FONT_DATA_URL = "/build/generic/web/standard_fonts/";
|
||||||
const WASM_URL = "/build/generic/web/wasm/";
|
const WASM_URL = "/build/generic/web/wasm/";
|
||||||
const IMAGE_RESOURCES_PATH = "/web/images/";
|
const IMAGE_RESOURCES_PATH = "/web/images/";
|
||||||
@ -637,6 +638,7 @@ class Driver {
|
|||||||
url: new URL(task.file, window.location),
|
url: new URL(task.file, window.location),
|
||||||
password: task.password,
|
password: task.password,
|
||||||
cMapUrl: CMAP_URL,
|
cMapUrl: CMAP_URL,
|
||||||
|
iccUrl: ICC_URL,
|
||||||
standardFontDataUrl: STANDARD_FONT_DATA_URL,
|
standardFontDataUrl: STANDARD_FONT_DATA_URL,
|
||||||
wasmUrl: WASM_URL,
|
wasmUrl: WASM_URL,
|
||||||
disableAutoFetch: !task.enableAutoFetch,
|
disableAutoFetch: !task.enableAutoFetch,
|
||||||
|
|||||||
@ -406,6 +406,17 @@ const defaultOptions = {
|
|||||||
value: false,
|
value: false,
|
||||||
kind: OptionKind.API,
|
kind: OptionKind.API,
|
||||||
},
|
},
|
||||||
|
iccUrl: {
|
||||||
|
/** @type {string} */
|
||||||
|
value:
|
||||||
|
// eslint-disable-next-line no-nested-ternary
|
||||||
|
typeof PDFJSDev === "undefined"
|
||||||
|
? "../external/iccs/"
|
||||||
|
: PDFJSDev.test("MOZCENTRAL")
|
||||||
|
? "resource://pdf.js/web/iccs/"
|
||||||
|
: "../web/iccs/",
|
||||||
|
kind: OptionKind.API,
|
||||||
|
},
|
||||||
isEvalSupported: {
|
isEvalSupported: {
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
value: true,
|
value: true,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user