colorspace_spec.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2020 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * Javascript code in this page
  21. */
  22. "use strict";
  23. var _primitives = require("../../core/primitives.js");
  24. var _stream = require("../../core/stream.js");
  25. var _colorspace = require("../../core/colorspace.js");
  26. var _function = require("../../core/function.js");
  27. var _test_utils = require("./test_utils.js");
  28. describe("colorspace", function () {
  29. describe("ColorSpace", function () {
  30. it("should be true if decode is not an array", function () {
  31. expect(_colorspace.ColorSpace.isDefaultDecode("string", 0)).toBeTruthy();
  32. });
  33. it("should be true if length of decode array is not correct", function () {
  34. expect(_colorspace.ColorSpace.isDefaultDecode([0], 1)).toBeTruthy();
  35. expect(_colorspace.ColorSpace.isDefaultDecode([0, 1, 0], 1)).toBeTruthy();
  36. });
  37. it("should be true if decode map matches the default decode map", function () {
  38. expect(_colorspace.ColorSpace.isDefaultDecode([], 0)).toBeTruthy();
  39. expect(_colorspace.ColorSpace.isDefaultDecode([0, 0], 1)).toBeFalsy();
  40. expect(_colorspace.ColorSpace.isDefaultDecode([0, 1], 1)).toBeTruthy();
  41. expect(_colorspace.ColorSpace.isDefaultDecode([0, 1, 0, 1, 0, 1], 3)).toBeTruthy();
  42. expect(_colorspace.ColorSpace.isDefaultDecode([0, 1, 0, 1, 1, 1], 3)).toBeFalsy();
  43. expect(_colorspace.ColorSpace.isDefaultDecode([0, 1, 0, 1, 0, 1, 0, 1], 4)).toBeTruthy();
  44. expect(_colorspace.ColorSpace.isDefaultDecode([1, 0, 0, 1, 0, 1, 0, 1], 4)).toBeFalsy();
  45. });
  46. });
  47. describe("DeviceGrayCS", function () {
  48. it("should handle the case when cs is a Name object", function () {
  49. const cs = _primitives.Name.get("DeviceGray");
  50. const xref = new _test_utils.XRefMock([{
  51. ref: _primitives.Ref.get(10, 0),
  52. data: new _primitives.Dict()
  53. }]);
  54. const res = new _primitives.Dict();
  55. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  56. xref
  57. });
  58. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  59. const testSrc = new Uint8Array([27, 125, 250, 131]);
  60. const testDest = new Uint8ClampedArray(4 * 4 * 3);
  61. const expectedDest = new Uint8ClampedArray([27, 27, 27, 27, 27, 27, 125, 125, 125, 125, 125, 125, 27, 27, 27, 27, 27, 27, 125, 125, 125, 125, 125, 125, 250, 250, 250, 250, 250, 250, 131, 131, 131, 131, 131, 131, 250, 250, 250, 250, 250, 250, 131, 131, 131, 131, 131, 131]);
  62. colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
  63. expect(colorSpace.getRgb(new Float32Array([0.1]), 0)).toEqual(new Uint8ClampedArray([26, 26, 26]));
  64. expect(colorSpace.getOutputLength(2, 0)).toEqual(6);
  65. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  66. expect(testDest).toEqual(expectedDest);
  67. });
  68. it("should handle the case when cs is an indirect object", function () {
  69. const cs = _primitives.Ref.get(10, 0);
  70. const xref = new _test_utils.XRefMock([{
  71. ref: cs,
  72. data: _primitives.Name.get("DeviceGray")
  73. }]);
  74. const res = new _primitives.Dict();
  75. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  76. xref
  77. });
  78. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  79. const testSrc = new Uint8Array([27, 125, 250, 131]);
  80. const testDest = new Uint8ClampedArray(3 * 3 * 3);
  81. const expectedDest = new Uint8ClampedArray([27, 27, 27, 27, 27, 27, 125, 125, 125, 27, 27, 27, 27, 27, 27, 125, 125, 125, 250, 250, 250, 250, 250, 250, 131, 131, 131]);
  82. colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
  83. expect(colorSpace.getRgb(new Float32Array([0.2]), 0)).toEqual(new Uint8ClampedArray([51, 51, 51]));
  84. expect(colorSpace.getOutputLength(3, 1)).toEqual(12);
  85. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  86. expect(testDest).toEqual(expectedDest);
  87. });
  88. });
  89. describe("DeviceRgbCS", function () {
  90. it("should handle the case when cs is a Name object", function () {
  91. const cs = _primitives.Name.get("DeviceRGB");
  92. const xref = new _test_utils.XRefMock([{
  93. ref: _primitives.Ref.get(10, 0),
  94. data: new _primitives.Dict()
  95. }]);
  96. const res = new _primitives.Dict();
  97. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  98. xref
  99. });
  100. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  101. const testSrc = new Uint8Array([27, 125, 250, 131, 139, 140, 111, 25, 198, 21, 147, 255]);
  102. const testDest = new Uint8ClampedArray(4 * 4 * 3);
  103. const expectedDest = new Uint8ClampedArray([27, 125, 250, 27, 125, 250, 131, 139, 140, 131, 139, 140, 27, 125, 250, 27, 125, 250, 131, 139, 140, 131, 139, 140, 111, 25, 198, 111, 25, 198, 21, 147, 255, 21, 147, 255, 111, 25, 198, 111, 25, 198, 21, 147, 255, 21, 147, 255]);
  104. colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
  105. expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8ClampedArray([26, 51, 77]));
  106. expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
  107. expect(colorSpace.isPassthrough(8)).toBeTruthy();
  108. expect(testDest).toEqual(expectedDest);
  109. });
  110. it("should handle the case when cs is an indirect object", function () {
  111. const cs = _primitives.Ref.get(10, 0);
  112. const xref = new _test_utils.XRefMock([{
  113. ref: cs,
  114. data: _primitives.Name.get("DeviceRGB")
  115. }]);
  116. const res = new _primitives.Dict();
  117. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  118. xref
  119. });
  120. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  121. const testSrc = new Uint8Array([27, 125, 250, 131, 139, 140, 111, 25, 198, 21, 147, 255]);
  122. const testDest = new Uint8ClampedArray(3 * 3 * 3);
  123. const expectedDest = new Uint8ClampedArray([27, 125, 250, 27, 125, 250, 131, 139, 140, 27, 125, 250, 27, 125, 250, 131, 139, 140, 111, 25, 198, 111, 25, 198, 21, 147, 255]);
  124. colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
  125. expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8ClampedArray([26, 51, 77]));
  126. expect(colorSpace.getOutputLength(4, 1)).toEqual(5);
  127. expect(colorSpace.isPassthrough(8)).toBeTruthy();
  128. expect(testDest).toEqual(expectedDest);
  129. });
  130. });
  131. describe("DeviceCmykCS", function () {
  132. it("should handle the case when cs is a Name object", function () {
  133. const cs = _primitives.Name.get("DeviceCMYK");
  134. const xref = new _test_utils.XRefMock([{
  135. ref: _primitives.Ref.get(10, 0),
  136. data: new _primitives.Dict()
  137. }]);
  138. const res = new _primitives.Dict();
  139. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  140. xref
  141. });
  142. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  143. const testSrc = new Uint8Array([27, 125, 250, 128, 131, 139, 140, 45, 111, 25, 198, 78, 21, 147, 255, 69]);
  144. const testDest = new Uint8ClampedArray(4 * 4 * 3);
  145. const 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, 144, 75, 112, 144, 75, 188, 98, 27, 188, 98, 27]);
  146. colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
  147. expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]), 0)).toEqual(new Uint8ClampedArray([32, 28, 21]));
  148. expect(colorSpace.getOutputLength(4, 0)).toEqual(3);
  149. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  150. expect(testDest).toEqual(expectedDest);
  151. });
  152. it("should handle the case when cs is an indirect object", function () {
  153. const cs = _primitives.Ref.get(10, 0);
  154. const xref = new _test_utils.XRefMock([{
  155. ref: cs,
  156. data: _primitives.Name.get("DeviceCMYK")
  157. }]);
  158. const res = new _primitives.Dict();
  159. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  160. xref
  161. });
  162. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  163. const testSrc = new Uint8Array([27, 125, 250, 128, 131, 139, 140, 45, 111, 25, 198, 78, 21, 147, 255, 69]);
  164. const testDest = new Uint8ClampedArray(3 * 3 * 3);
  165. const 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]);
  166. colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
  167. expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]), 0)).toEqual(new Uint8ClampedArray([32, 28, 21]));
  168. expect(colorSpace.getOutputLength(4, 1)).toEqual(4);
  169. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  170. expect(testDest).toEqual(expectedDest);
  171. });
  172. });
  173. describe("CalGrayCS", function () {
  174. it("should handle the case when cs is an array", function () {
  175. const params = new _primitives.Dict();
  176. params.set("WhitePoint", [1, 1, 1]);
  177. params.set("BlackPoint", [0, 0, 0]);
  178. params.set("Gamma", 2.0);
  179. const cs = [_primitives.Name.get("CalGray"), params];
  180. const xref = new _test_utils.XRefMock([{
  181. ref: _primitives.Ref.get(10, 0),
  182. data: new _primitives.Dict()
  183. }]);
  184. const res = new _primitives.Dict();
  185. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  186. xref
  187. });
  188. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  189. const testSrc = new Uint8Array([27, 125, 250, 131]);
  190. const testDest = new Uint8ClampedArray(4 * 4 * 3);
  191. const expectedDest = new Uint8ClampedArray([25, 25, 25, 25, 25, 25, 143, 143, 143, 143, 143, 143, 25, 25, 25, 25, 25, 25, 143, 143, 143, 143, 143, 143, 251, 251, 251, 251, 251, 251, 149, 149, 149, 149, 149, 149, 251, 251, 251, 251, 251, 251, 149, 149, 149, 149, 149, 149]);
  192. colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
  193. expect(colorSpace.getRgb(new Float32Array([1.0]), 0)).toEqual(new Uint8ClampedArray([255, 255, 255]));
  194. expect(colorSpace.getOutputLength(4, 0)).toEqual(12);
  195. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  196. expect(testDest).toEqual(expectedDest);
  197. });
  198. });
  199. describe("CalRGBCS", function () {
  200. it("should handle the case when cs is an array", function () {
  201. const params = new _primitives.Dict();
  202. params.set("WhitePoint", [1, 1, 1]);
  203. params.set("BlackPoint", [0, 0, 0]);
  204. params.set("Gamma", [1, 1, 1]);
  205. params.set("Matrix", [1, 0, 0, 0, 1, 0, 0, 0, 1]);
  206. const cs = [_primitives.Name.get("CalRGB"), params];
  207. const xref = new _test_utils.XRefMock([{
  208. ref: _primitives.Ref.get(10, 0),
  209. data: new _primitives.Dict()
  210. }]);
  211. const res = new _primitives.Dict();
  212. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  213. xref
  214. });
  215. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  216. const testSrc = new Uint8Array([27, 125, 250, 131, 139, 140, 111, 25, 198, 21, 147, 255]);
  217. const testDest = new Uint8ClampedArray(3 * 3 * 3);
  218. const expectedDest = new Uint8ClampedArray([0, 238, 255, 0, 238, 255, 185, 196, 195, 0, 238, 255, 0, 238, 255, 185, 196, 195, 235, 0, 243, 235, 0, 243, 0, 255, 255]);
  219. colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
  220. expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8ClampedArray([0, 147, 151]));
  221. expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
  222. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  223. expect(testDest).toEqual(expectedDest);
  224. });
  225. });
  226. describe("LabCS", function () {
  227. it("should handle the case when cs is an array", function () {
  228. const params = new _primitives.Dict();
  229. params.set("WhitePoint", [1, 1, 1]);
  230. params.set("BlackPoint", [0, 0, 0]);
  231. params.set("Range", [-100, 100, -100, 100]);
  232. const cs = [_primitives.Name.get("Lab"), params];
  233. const xref = new _test_utils.XRefMock([{
  234. ref: _primitives.Ref.get(10, 0),
  235. data: new _primitives.Dict()
  236. }]);
  237. const res = new _primitives.Dict();
  238. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  239. xref
  240. });
  241. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  242. const testSrc = new Uint8Array([27, 25, 50, 31, 19, 40, 11, 25, 98, 21, 47, 55]);
  243. const testDest = new Uint8ClampedArray(3 * 3 * 3);
  244. const expectedDest = new Uint8ClampedArray([0, 49, 101, 0, 49, 101, 0, 53, 117, 0, 49, 101, 0, 49, 101, 0, 53, 117, 0, 41, 40, 0, 41, 40, 0, 43, 90]);
  245. colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
  246. expect(colorSpace.getRgb([55, 25, 35], 0)).toEqual(new Uint8ClampedArray([188, 100, 61]));
  247. expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
  248. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  249. expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
  250. expect(testDest).toEqual(expectedDest);
  251. });
  252. });
  253. describe("IndexedCS", function () {
  254. it("should handle the case when cs is an array", function () {
  255. const lookup = new Uint8Array([23, 155, 35, 147, 69, 93, 255, 109, 70]);
  256. const cs = [_primitives.Name.get("Indexed"), _primitives.Name.get("DeviceRGB"), 2, lookup];
  257. const xref = new _test_utils.XRefMock([{
  258. ref: _primitives.Ref.get(10, 0),
  259. data: new _primitives.Dict()
  260. }]);
  261. const res = new _primitives.Dict();
  262. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  263. xref
  264. });
  265. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  266. const testSrc = new Uint8Array([2, 2, 0, 1]);
  267. const testDest = new Uint8ClampedArray(3 * 3 * 3);
  268. const expectedDest = new Uint8ClampedArray([255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 23, 155, 35, 23, 155, 35, 147, 69, 93]);
  269. colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
  270. expect(colorSpace.getRgb([2], 0)).toEqual(new Uint8ClampedArray([255, 109, 70]));
  271. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  272. expect(colorSpace.isDefaultDecode([0, 1], 1)).toBeTruthy();
  273. expect(testDest).toEqual(expectedDest);
  274. });
  275. });
  276. describe("AlternateCS", function () {
  277. it("should handle the case when cs is an array", function () {
  278. const fnDict = new _primitives.Dict();
  279. fnDict.set("FunctionType", 4);
  280. fnDict.set("Domain", [0.0, 1.0]);
  281. fnDict.set("Range", [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]);
  282. fnDict.set("Length", 58);
  283. let fn = new _stream.StringStream("{ dup 0.84 mul " + "exch 0.00 exch " + "dup 0.44 mul " + "exch 0.21 mul }");
  284. fn = new _stream.Stream(fn.bytes, 0, 58, fnDict);
  285. const fnRef = _primitives.Ref.get(10, 0);
  286. const cs = [_primitives.Name.get("Separation"), _primitives.Name.get("LogoGreen"), _primitives.Name.get("DeviceCMYK"), fnRef];
  287. const xref = new _test_utils.XRefMock([{
  288. ref: fnRef,
  289. data: fn
  290. }]);
  291. const res = new _primitives.Dict();
  292. const pdfFunctionFactory = new _function.PDFFunctionFactory({
  293. xref
  294. });
  295. const colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
  296. const testSrc = new Uint8Array([27, 25, 50, 31]);
  297. const testDest = new Uint8ClampedArray(3 * 3 * 3);
  298. const 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]);
  299. colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
  300. expect(colorSpace.getRgb([0.1], 0)).toEqual(new Uint8ClampedArray([228, 243, 242]));
  301. expect(colorSpace.isPassthrough(8)).toBeFalsy();
  302. expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
  303. expect(testDest).toEqual(expectedDest);
  304. });
  305. });
  306. });