mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-19 06:38:07 +02:00
[api-minor] Use an icc profile for converting CMYK to RGB
This commit is contained in:
parent
1bc98dfbd9
commit
7280540901
14 changed files with 224 additions and 274 deletions
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 {
|
||||
static _module = null;
|
||||
|
||||
static _mustAddAlpha = false;
|
||||
|
||||
static _destBuffer = null;
|
||||
}
|
||||
|
||||
|
@ -23,16 +25,25 @@ function copy_result(ptr, len) {
|
|||
// 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
|
||||
// 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);
|
||||
if (result.length === _destBuffer.length) {
|
||||
_destBuffer.set(result);
|
||||
return;
|
||||
}
|
||||
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];
|
||||
if (_mustAddAlpha) {
|
||||
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];
|
||||
_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() {
|
||||
return gulp.src(
|
||||
[
|
||||
|
@ -1091,6 +1098,7 @@ function buildGeneric(defines, dir) {
|
|||
})
|
||||
.pipe(gulp.dest(dir + "web")),
|
||||
createCMapBundle().pipe(gulp.dest(dir + "web/cmaps")),
|
||||
createICCBundle().pipe(gulp.dest(dir + "web/iccs")),
|
||||
createStandardFontBundle().pipe(gulp.dest(dir + "web/standard_fonts")),
|
||||
createWasmBundle().pipe(gulp.dest(dir + "web/wasm")),
|
||||
|
||||
|
@ -1420,6 +1428,7 @@ gulp.task(
|
|||
createCMapBundle().pipe(
|
||||
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/cmaps")
|
||||
),
|
||||
createICCBundle().pipe(gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/iccs")),
|
||||
createStandardFontBundle().pipe(
|
||||
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/standard_fonts")
|
||||
),
|
||||
|
@ -1525,6 +1534,9 @@ gulp.task(
|
|||
createCMapBundle().pipe(
|
||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/cmaps")
|
||||
),
|
||||
createICCBundle().pipe(
|
||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/iccs")
|
||||
),
|
||||
createStandardFontBundle().pipe(
|
||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/standard_fonts")
|
||||
),
|
||||
|
@ -2364,6 +2376,12 @@ gulp.task(
|
|||
encoding: false,
|
||||
})
|
||||
.pipe(gulp.dest(DIST_DIR)),
|
||||
gulp
|
||||
.src(GENERIC_DIR + "web/iccs/**/*", {
|
||||
base: GENERIC_DIR + "web",
|
||||
encoding: false,
|
||||
})
|
||||
.pipe(gulp.dest(DIST_DIR)),
|
||||
gulp
|
||||
.src(GENERIC_DIR + "web/standard_fonts/**/*", {
|
||||
base: GENERIC_DIR + "web",
|
||||
|
|
|
@ -25,9 +25,9 @@ import {
|
|||
LabCS,
|
||||
PatternCS,
|
||||
} from "./colorspace.js";
|
||||
import { CmykICCBasedCS, IccColorSpace } from "./icc_colorspace.js";
|
||||
import { Dict, Name, Ref } from "./primitives.js";
|
||||
import { MathClamp, shadow, unreachable, warn } from "../shared/util.js";
|
||||
import { IccColorSpace } from "./icc_colorspace.js";
|
||||
import { MissingDataException } from "./core_utils.js";
|
||||
|
||||
class ColorSpaceUtils {
|
||||
|
@ -205,7 +205,11 @@ class ColorSpaceUtils {
|
|||
|
||||
if (IccColorSpace.isUsable) {
|
||||
try {
|
||||
const iccCS = new IccColorSpace(stream.getBytes(), numComps);
|
||||
const iccCS = new IccColorSpace(
|
||||
stream.getBytes(),
|
||||
"ICCBased",
|
||||
numComps
|
||||
);
|
||||
if (isRef) {
|
||||
globalColorSpaceCache.set(/* name = */ null, cs[1], iccCS);
|
||||
}
|
||||
|
@ -285,6 +289,13 @@ class ColorSpaceUtils {
|
|||
}
|
||||
|
||||
static get cmyk() {
|
||||
if (IccColorSpace.isUsable) {
|
||||
try {
|
||||
return shadow(this, "cmyk", new CmykICCBasedCS());
|
||||
} catch {
|
||||
warn("CMYK fallback: DeviceCMYK");
|
||||
}
|
||||
}
|
||||
return shadow(this, "cmyk", new DeviceCmykCS());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ const DefaultPartialEvaluatorOptions = Object.freeze({
|
|||
useWasm: true,
|
||||
useWorkerFetch: true,
|
||||
cMapUrl: null,
|
||||
iccUrl: null,
|
||||
standardFontDataUrl: null,
|
||||
wasmUrl: null,
|
||||
});
|
||||
|
|
|
@ -41,12 +41,12 @@ class IccColorSpace extends ColorSpace {
|
|||
qcms_drop_transformer(transformer);
|
||||
});
|
||||
|
||||
constructor(iccProfile, numComps) {
|
||||
constructor(iccProfile, name, numComps) {
|
||||
if (!IccColorSpace.isUsable) {
|
||||
throw new Error("No ICC color space support");
|
||||
}
|
||||
|
||||
super("ICCBased", numComps);
|
||||
super(name, numComps);
|
||||
|
||||
let inType;
|
||||
switch (numComps) {
|
||||
|
@ -104,11 +104,13 @@ class IccColorSpace extends ColorSpace {
|
|||
src[i] *= scale;
|
||||
}
|
||||
}
|
||||
QCMS._mustAddAlpha = alpha01 && dest.buffer === src.buffer;
|
||||
QCMS._destBuffer = dest.subarray(
|
||||
destOffset,
|
||||
destOffset + count * (3 + alpha01)
|
||||
);
|
||||
qcms_convert_array(this.#transformer, src);
|
||||
QCMS._mustAddAlpha = false;
|
||||
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 { ColorSpaceUtils } from "./colorspace_utils.js";
|
||||
import { grayToRGBA } from "../shared/image_utils.js";
|
||||
import { readUint16 } from "./core_utils.js";
|
||||
|
||||
|
@ -1317,141 +1318,13 @@ class JpegImage {
|
|||
}
|
||||
|
||||
_convertYcckToRgb(data) {
|
||||
let Y, Cb, Cr, k;
|
||||
let offset = 0;
|
||||
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);
|
||||
this._convertYcckToCmyk(data);
|
||||
return this._convertCmykToRgb(data);
|
||||
}
|
||||
|
||||
_convertYcckToRgba(data) {
|
||||
for (let i = 0, length = data.length; i < length; i += 4) {
|
||||
const Y = data[i];
|
||||
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;
|
||||
this._convertYcckToCmyk(data);
|
||||
return this._convertCmykToRgba(data);
|
||||
}
|
||||
|
||||
_convertYcckToCmyk(data) {
|
||||
|
@ -1469,140 +1342,13 @@ class JpegImage {
|
|||
}
|
||||
|
||||
_convertCmykToRgb(data) {
|
||||
let c, m, y, k;
|
||||
let offset = 0;
|
||||
for (let i = 0, length = data.length; i < length; i += 4) {
|
||||
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);
|
||||
const count = data.length / 4;
|
||||
ColorSpaceUtils.cmyk.getRgbBuffer(data, 0, count, data, 0, 8, 0);
|
||||
return data.subarray(0, count * 3);
|
||||
}
|
||||
|
||||
_convertCmykToRgba(data) {
|
||||
for (let i = 0, length = data.length; i < length; i += 4) {
|
||||
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;
|
||||
}
|
||||
ColorSpaceUtils.cmyk.getRgbBuffer(data, 0, data.length / 4, data, 0, 8, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CmykICCBasedCS, IccColorSpace } from "./icc_colorspace.js";
|
||||
import {
|
||||
createValidAbsoluteUrl,
|
||||
FeatureTest,
|
||||
|
@ -20,7 +21,6 @@ import {
|
|||
warn,
|
||||
} from "../shared/util.js";
|
||||
import { ChunkedStreamManager } from "./chunked_stream.js";
|
||||
import { IccColorSpace } from "./icc_colorspace.js";
|
||||
import { ImageResizer } from "./image_resizer.js";
|
||||
import { JpegStream } from "./jpeg_stream.js";
|
||||
import { JpxImage } from "./jpx.js";
|
||||
|
@ -78,6 +78,7 @@ class BasePdfManager {
|
|||
const options = { ...evaluatorOptions, handler };
|
||||
JpxImage.setOptions(options);
|
||||
IccColorSpace.setOptions(options);
|
||||
CmykICCBasedCS.setOptions(options);
|
||||
}
|
||||
|
||||
get docId() {
|
||||
|
|
|
@ -125,6 +125,8 @@ const RENDERING_CANCELLED_TIMEOUT = 100; // ms
|
|||
* @property {Object} [CMapReaderFactory] - The factory that will be used when
|
||||
* reading built-in CMap files.
|
||||
* 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
|
||||
* embedded in the PDF document will fallback to a system font.
|
||||
* 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
|
||||
? NodeCMapReaderFactory
|
||||
: DOMCMapReaderFactory);
|
||||
const iccUrl = getFactoryUrlProp(src.iccUrl);
|
||||
const standardFontDataUrl = getFactoryUrlProp(src.standardFontDataUrl);
|
||||
const StandardFontDataFactory =
|
||||
src.StandardFontDataFactory ||
|
||||
|
@ -418,6 +421,7 @@ function getDocument(src = {}) {
|
|||
useWasm,
|
||||
useWorkerFetch,
|
||||
cMapUrl,
|
||||
iccUrl,
|
||||
standardFontDataUrl,
|
||||
wasmUrl,
|
||||
},
|
||||
|
|
|
@ -30,6 +30,7 @@ const { GenericL10n, parseQueryString, SimpleLinkService } = pdfjsViewer;
|
|||
|
||||
const WAITING_TIME = 100; // ms
|
||||
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 WASM_URL = "/build/generic/web/wasm/";
|
||||
const IMAGE_RESOURCES_PATH = "/web/images/";
|
||||
|
@ -637,6 +638,7 @@ class Driver {
|
|||
url: new URL(task.file, window.location),
|
||||
password: task.password,
|
||||
cMapUrl: CMAP_URL,
|
||||
iccUrl: ICC_URL,
|
||||
standardFontDataUrl: STANDARD_FONT_DATA_URL,
|
||||
wasmUrl: WASM_URL,
|
||||
disableAutoFetch: !task.enableAutoFetch,
|
||||
|
|
|
@ -406,6 +406,17 @@ const defaultOptions = {
|
|||
value: false,
|
||||
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: {
|
||||
/** @type {boolean} */
|
||||
value: true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue