From a5bf02573d8b7df6047e24dc537cca9f6f408daa Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Thu, 25 Apr 2013 22:26:42 +0300 Subject: [PATCH] Implement initial CalGray support Gamma and Whitepoint are supported in this patch for CalGray. Blackpoint is not supported. --- src/shared/colorspace.js | 118 ++++++++- test/pdfs/calgray.pdf | 553 +++++++++++++++++++++++++++++++++++++++ test/test_manifest.json | 6 + 3 files changed, 675 insertions(+), 2 deletions(-) create mode 100644 test/pdfs/calgray.pdf diff --git a/src/shared/colorspace.js b/src/shared/colorspace.js index ddf0f8cb6..62f7a4d4f 100644 --- a/src/shared/colorspace.js +++ b/src/shared/colorspace.js @@ -15,7 +15,7 @@ * limitations under the License. */ /* globals error, info, isArray, isDict, isName, isStream, isString, - PDFFunction, warn, shadow */ + PDFFunction, warn, shadow, TODO */ 'use strict'; @@ -132,6 +132,11 @@ var ColorSpace = (function ColorSpaceClosure() { return this.singletons.rgb; case 'DeviceCmykCS': return this.singletons.cmyk; + case 'CalGrayCS': + var whitePoint = IR[1].WhitePoint; + var blackPoint = IR[1].BlackPoint; + var gamma = IR[1].Gamma; + return new CalGrayCS(whitePoint, blackPoint, gamma); case 'PatternCS': var basePatternCS = IR[1]; if (basePatternCS) @@ -207,7 +212,8 @@ var ColorSpace = (function ColorSpaceClosure() { case 'CMYK': return 'DeviceCmykCS'; case 'CalGray': - return 'DeviceGrayCS'; + var params = cs[1].getAll(); + return ['CalGrayCS', params]; case 'CalRGB': return 'DeviceRgbCS'; case 'ICCBased': @@ -627,6 +633,113 @@ var DeviceCmykCS = (function DeviceCmykCSClosure() { return DeviceCmykCS; })(); +// +// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245 +// +var CalGrayCS = (function CalGrayCSClosure() { + function CalGrayCS(whitePoint, blackPoint, gamma) { + this.name = 'CalGray'; + this.numComps = 3; + this.defaultColor = new Float32Array([0, 0, 0]); + + if (!whitePoint) { + error('WhitePoint missing - required for color space CalGray'); + } + blackPoint = blackPoint || [0, 0, 0]; + gamma = gamma || 1; + + // Translate arguments to spec variables. + this.XW = whitePoint[0]; + this.YW = whitePoint[1]; + this.ZW = whitePoint[2]; + + this.XB = blackPoint[0]; + this.YB = blackPoint[1]; + this.ZB = blackPoint[2]; + + this.G = gamma; + + // Validate variables as per spec. + if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { + error('Invalid WhitePoint components for ' + this.name + + ', no fallback available'); + } + + if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { + info('Invalid BlackPoint for ' + this.name + ', falling back to default'); + this.XB = this.YB = this.ZB = 0; + } + + if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) { + TODO(this.name + ', BlackPoint: XB: ' + this.XB + ', YB: ' + this.YB + + ', ZB: ' + this.ZB + ', only default values are supported.'); + } + + if (this.G < 1) { + info('Invalid Gamma: ' + this.G + ' for ' + this.name + + ', falling back to default'); + this.G = 1; + } + } + + CalGrayCS.prototype = { + getRgb: function CalGrayCS_getRgb(src, srcOffset) { + var rgb = new Uint8Array(3); + this.getRgbItem(src, srcOffset, rgb, 0); + return rgb; + }, + getRgbItem: function CalGrayCS_getRgbItem(src, srcOffset, + dest, destOffset) { + // A represents a gray component of a calibrated gray space. + // A <---> AG in the spec + var A = src[srcOffset]; + var AG = Math.pow(A, this.G); + + // Computes intermediate variables M, L, N as per spec. + // Except if other than default BlackPoint values are used. + var M = this.XW * AG; + var L = this.YW * AG; + var N = this.ZW * AG; + + // Decode XYZ, as per spec. + var X = M; + var Y = L; + var Z = N; + + // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4. + // This yields values in range [0, 100]. + var Lstar = Math.max(116 * Math.pow(Y, 1 / 3) - 16, 0); + + // Convert values to rgb range [0, 255]. + dest[destOffset] = Lstar * 255 / 100; + dest[destOffset + 1] = Lstar * 255 / 100; + dest[destOffset + 2] = Lstar * 255 / 100; + }, + getRgbBuffer: function CalGrayCS_getRgbBuffer(src, srcOffset, count, + dest, destOffset, bits) { + // TODO: This part is copied from DeviceGray. Make this utility function. + var scale = 255 / ((1 << bits) - 1); + var j = srcOffset, q = destOffset; + for (var i = 0; i < count; ++i) { + var c = (scale * src[j++]) | 0; + dest[q++] = c; + dest[q++] = c; + dest[q++] = c; + } + }, + getOutputLength: function CalGrayCS_getOutputLength(inputLength) { + return inputLength * 3; + }, + isPassthrough: ColorSpace.prototype.isPassthrough, + createRgbBuffer: ColorSpace.prototype.createRgbBuffer, + isDefaultDecode: function CalGrayCS_isDefaultDecode(decodeMap) { + return ColorSpace.isDefaultDecode(decodeMap, this.numComps); + }, + usesZeroToOneRange: true + }; + return CalGrayCS; +})(); + // // LabCS: Based on "PDF Reference, Sixth Ed", p.250 // @@ -767,3 +880,4 @@ var LabCS = (function LabCSClosure() { }; return LabCS; })(); + diff --git a/test/pdfs/calgray.pdf b/test/pdfs/calgray.pdf new file mode 100644 index 000000000..89e97e3f0 --- /dev/null +++ b/test/pdfs/calgray.pdf @@ -0,0 +1,553 @@ +%PDF-1.7 +% filler % +% filler % + +1 0 obj % entry point % +<< % + /Type /Catalog % + /Pages 2 0 R % +>> % +% filler % +endobj + +2 0 obj % +<< /Type /Pages % + /MediaBox [ 0 0 850 1100 ] % + /Count 3 % + /Kids [ 3 0 R % + 8 0 R % + 12 0 R % + ] % +>> % +% filler % +endobj + +3 0 obj % Page object % +<< /Type /Page % + /Parent 2 0 R % + /Resources 4 0 R % + /Contents 7 0 R % + /CropBox [ 0 0 850 1100 ] % +>> % +% filler % +endobj + +4 0 obj % Resource dictionary for page % +<< % + /ColorSpace << /Cs5 5 0 R >> % + /Font << /F1 6 0 R >> % +>> % +% filler % +endobj + +5 0 obj % Colorspace definition % +[ /CalGray % +<< /WhitePoint [ 1.00000 1.0 1.00000 ] % + /BlackPoint [ 0.0 0.0 0.0 ] % + /Gamma 1.0 % +>> % +] % +% filler % +endobj + +6 0 obj % Font definition % +<< /Type /Font % + /Subtype /Type1 % + /BaseFont /Times-Roman % +>> % +% filler % +endobj + +7 0 obj % Contents of page % +<< /Length 3300 >> +stream + + /Cs5 cs % + 0.00 sc % + 25 25 200 200 re% + f % + /Cs5 cs % + 0.01 sc % + 225 25 200 200 re% + f % + /Cs5 cs % + 0.05 sc % + 425 25 200 200 re% + f % + /Cs5 cs % + 0.10 sc % + 625 25 200 200 re% + f % + /Cs5 cs % + 0.15 sc % + 25 225 200 200 re% + f % + /Cs5 cs % + 0.20 sc % + 225 225 200 200 re% + f % + /Cs5 cs % + 0.25 sc % + 425 225 200 200 re% + f % + /Cs5 cs % + 0.30 sc % + 625 225 200 200 re% + f % + /Cs5 cs % + 0.35 sc % + 25 425 200 200 re% + f % + /Cs5 cs % + 0.40 sc % + 225 425 200 200 re% + f % + /Cs5 cs % + 0.45 sc % + 425 425 200 200 re% + f % + /Cs5 cs % + 0.50 sc % + 625 425 200 200 re% + f % + /Cs5 cs % + 0.55 sc % + 25 625 200 200 re% + f % + /Cs5 cs % + 0.60 sc % + 225 625 200 200 re% + f % + /Cs5 cs % + 0.65 sc % + 425 625 200 200 re% + f % + /Cs5 cs % + 0.70 sc % + 625 625 200 200 re% + f % + /Cs5 cs % + 0.75 sc % + 25 825 200 200 re% + f % + /Cs5 cs % + 0.80 sc % + 225 825 200 200 re% + f % + /Cs5 cs % + 0.90 sc % + 425 825 200 200 re% + f % + /Cs5 cs % + 1.00 sc % + 625 825 200 200 re% + f % + BT % + /F1 16 Tf % + 50 50 Td % + (A = 0.00) Tj % + 200 0 Td % + (A = 0.01) Tj % + 200 0 Td % + (A = 0.05) Tj % + 200 0 Td % + (A = 0.10) Tj % + -600 200 Td % + (A = 0.15) Tj % + 200 0 Td % + (A = 0.20) Tj % + 200 0 Td % + (A = 0.25) Tj % + 200 0 Td % + (A = 0.30) Tj % + -600 200 Td % + (A = 0.35) Tj % + 200 0 Td % + (A = 0.40) Tj % + 200 0 Td % + (A = 0.45) Tj % + 200 0 Td % + (A = 0.50) Tj % + -600 200 Td % + (A = 0.55) Tj % + 200 0 Td % + (A = 0.60) Tj % + 200 0 Td % + (A = 0.65) Tj % + 200 0 Td % + (A = 0.70) Tj % + -600 200 Td 0.0 g % + (A = 0.75) Tj % + 200 0 Td % + (A = 0.80) Tj % + 200 0 Td % + (A = 0.90) Tj % + 200 0 Td % + (A = 1.00) Tj % + -600 200 Td % + (WhitePoint [ 1.0 1.0 1.0 ]) Tj % + 200 0 Td % + (BlackPoint [ 0.0 0.0 0.0 ]) Tj % + 200 0 Td % + (Gamma 1.0) Tj % + ET % +endstream +% % +endobj + +8 0 obj % Page object % +<< /Type /Page % + /Parent 2 0 R % + /Resources 9 0 R % + /Contents 11 0 R % + /CropBox [ 0 0 850 1100 ] % +>> % +% filler % +endobj + +9 0 obj % Resource dictionary for page % +<< % + /ColorSpace << /Cs10 10 0 R >> % + /Font << /F1 6 0 R >> % +>> % +% filler % +endobj + +10 0 obj % Colorspace definition % +[ /CalGray % +<< /WhitePoint [ 1.00000 1.0 1.00000 ] % + /BlackPoint [ 0.0 0.0 0.0 ] % + /Gamma 5.0 % +>> % +] % +% filler % +endobj + +11 0 obj % Contents of page % +<< /Length 3300 >> +stream + + /Cs10 cs % + 0.0 sc % + 25 25 200 200 re% + f % + /Cs10 cs % + 0.01 sc % + 225 25 200 200 re% + f % + /Cs10 cs % + 0.05 sc % + 425 25 200 200 re% + f % + /Cs10 cs % + 0.1 sc % + 625 25 200 200 re% + f % + /Cs10 cs % + 0.15 sc % + 25 225 200 200 re% + f % + /Cs10 cs % + 0.2 sc % + 225 225 200 200 re% + f % + /Cs10 cs % + 0.25 sc % + 425 225 200 200 re% + f % + /Cs10 cs % + 0.3 sc % + 625 225 200 200 re% + f % + /Cs10 cs % + 0.35 sc % + 25 425 200 200 re% + f % + /Cs10 cs % + 0.4 sc % + 225 425 200 200 re% + f % + /Cs10 cs % + 0.45 sc % + 425 425 200 200 re% + f % + /Cs10 cs % + 0.5 sc % + 625 425 200 200 re% + f % + /Cs10 cs % + 0.55 sc % + 25 625 200 200 re% + f % + /Cs10 cs % + 0.6 sc % + 225 625 200 200 re% + f % + /Cs10 cs % + 0.65 sc % + 425 625 200 200 re% + f % + /Cs10 cs % + 0.7 sc % + 625 625 200 200 re% + f % + /Cs10 cs % + 0.75 sc % + 25 825 200 200 re% + f % + /Cs10 cs % + 0.8 sc % + 225 825 200 200 re% + f % + /Cs10 cs % + 0.9 sc % + 425 825 200 200 re% + f % + /Cs10 cs % + 1.0 sc % + 625 825 200 200 re% + f % + BT % + /F1 16 Tf % + 50 50 Td % + (A = 0.00) Tj % + 200 0 Td % + (A = 0.01) Tj % + 200 0 Td % + (A = 0.05) Tj % + 200 0 Td % + (A = 0.10) Tj % + -600 200 Td % + (A = 0.15) Tj % + 200 0 Td % + (A = 0.20) Tj % + 200 0 Td % + (A = 0.25) Tj % + 200 0 Td % + (A = 0.30) Tj % + -600 200 Td % + (A = 0.35) Tj % + 200 0 Td % + (A = 0.40) Tj % + 200 0 Td % + (A = 0.45) Tj % + 200 0 Td % + (A = 0.50) Tj % + -600 200 Td % + (A = 0.55) Tj % + 200 0 Td % + (A = 0.60) Tj % + 200 0 Td % + (A = 0.65) Tj % + 200 0 Td % + (A = 0.70) Tj % + -600 200 Td 0.0 g % + (A = 0.75) Tj % + 200 0 Td % + (A = 0.80) Tj % + 200 0 Td % + (A = 0.90) Tj % + 200 0 Td % + (A = 1.00) Tj % + -600 200 Td % + (WhitePoint [ 1.0 1.0 1.0 ]) Tj % + 200 0 Td % + (BlackPoint [ 0.0 0.0 0.0 ]) Tj % + 200 0 Td % + (Gamma 5.0) Tj % + ET % +endstream +% % +endobj + +12 0 obj % Page object % +<< /Type /Page % + /Parent 2 0 R % + /Resources 13 0 R % + /Contents 15 0 R % + /CropBox [ 0 0 850 1100 ] % +>> % +% filler % +endobj + +13 0 obj % Resource dictionary for page % +<< % + /ColorSpace << /Cs14 14 0 R >> % + /Font << /F1 6 0 R >> % +>> % +% filler % +endobj + +14 0 obj % Colorspace definition % +[ /CalGray % +<< /WhitePoint [ 1.00000 1.0 1.00000 ] % + /BlackPoint [ 0.7 0.7 0.7 ] % + /Gamma 1.0 % +>> % +] % +% filler % +endobj + +15 0 obj % Contents of page % +<< /Length 3300 >> +stream + + /Cs14 cs % + 0.0 sc % + 25 25 200 200 re% + f % + /Cs14 cs % + 0.01 sc % + 225 25 200 200 re% + f % + /Cs14 cs % + 0.05 sc % + 425 25 200 200 re% + f % + /Cs14 cs % + 0.1 sc % + 625 25 200 200 re% + f % + /Cs14 cs % + 0.15 sc % + 25 225 200 200 re% + f % + /Cs14 cs % + 0.2 sc % + 225 225 200 200 re% + f % + /Cs14 cs % + 0.25 sc % + 425 225 200 200 re% + f % + /Cs14 cs % + 0.3 sc % + 625 225 200 200 re% + f % + /Cs14 cs % + 0.35 sc % + 25 425 200 200 re% + f % + /Cs14 cs % + 0.4 sc % + 225 425 200 200 re% + f % + /Cs14 cs % + 0.45 sc % + 425 425 200 200 re% + f % + /Cs14 cs % + 0.5 sc % + 625 425 200 200 re% + f % + /Cs14 cs % + 0.55 sc % + 25 625 200 200 re% + f % + /Cs14 cs % + 0.6 sc % + 225 625 200 200 re% + f % + /Cs14 cs % + 0.65 sc % + 425 625 200 200 re% + f % + /Cs14 cs % + 0.7 sc % + 625 625 200 200 re% + f % + /Cs14 cs % + 0.75 sc % + 25 825 200 200 re% + f % + /Cs14 cs % + 0.8 sc % + 225 825 200 200 re% + f % + /Cs14 cs % + 0.9 sc % + 425 825 200 200 re% + f % + /Cs14 cs % + 1.0 sc % + 625 825 200 200 re% + f % + BT % + /F1 16 Tf % + 50 50 Td % + (A = 0.00) Tj % + 200 0 Td % + (A = 0.01) Tj % + 200 0 Td % + (A = 0.05) Tj % + 200 0 Td % + (A = 0.10) Tj % + -600 200 Td % + (A = 0.15) Tj % + 200 0 Td % + (A = 0.20) Tj % + 200 0 Td % + (A = 0.25) Tj % + 200 0 Td % + (A = 0.30) Tj % + -600 200 Td % + (A = 0.35) Tj % + 200 0 Td % + (A = 0.40) Tj % + 200 0 Td % + (A = 0.45) Tj % + 200 0 Td % + (A = 0.50) Tj % + -600 200 Td % + (A = 0.55) Tj % + 200 0 Td % + (A = 0.60) Tj % + 200 0 Td % + (A = 0.65) Tj % + 200 0 Td % + (A = 0.70) Tj % + -600 200 Td 0.0 g % + (A = 0.75) Tj % + 200 0 Td % + (A = 0.80) Tj % + 200 0 Td % + (A = 0.90) Tj % + 200 0 Td % + (A = 1.00) Tj % + -600 200 Td % + (WhitePoint [ 1.0 1.0 1.0 ]) Tj % + 200 0 Td % + (BlackPoint [ 0.7 0.7 0.7 ]) Tj % + 200 0 Td % + (Gamma 1.0) Tj % + ET % +endstream +% % +endobj + +xref +0 16 +0000000000 65535 f +0000000100 00000 n +0000000400 00000 n +0000000900 00000 n +0000001300 00000 n +0000001600 00000 n +0000002000 00000 n +0000002300 00000 n +0000005700 00000 n +0000006100 00000 n +0000006400 00000 n +0000006800 00000 n +0000010200 00000 n +0000010600 00000 n +0000010900 00000 n +0000011300 00000 n +trailer +<< + /Size 16 + /Root 1 0 R +>> +startxref +14700 +%%EOF diff --git a/test/test_manifest.json b/test/test_manifest.json index 15602609e..ce8c7d6c2 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -1363,6 +1363,12 @@ "lastPage": 1, "type": "eq" }, + { "id": "calgray", + "file": "pdfs/calgray.pdf", + "md5": "ee784999bfa1ed373f55cdabbb580df1", + "rounds": 1, + "type": "eq" + }, { "id": "issue2853", "file": "pdfs/issue2853.pdf", "md5": "9f0ad95ef0b243ee8813c4eca0f7a042",