You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
7.3 KiB

1 month ago
  1. % Copyright (C) 2001-2023 Artifex Software, Inc.
  2. % All Rights Reserved.
  3. %
  4. % This software is provided AS-IS with no warranty, either express or
  5. % implied.
  6. %
  7. % This software is distributed under license and may not be copied,
  8. % modified or distributed except as expressly authorized under the terms
  9. % of the license contained in the file LICENSE in this distribution.
  10. %
  11. % Refer to licensing information at http://www.artifex.com or contact
  12. % Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  13. % CA 94129, USA, for further information.
  14. %
  15. % docie.ps
  16. % Emulate CIE algorithms in PostScript.
  17. % ---------------- Auxiliary procedures ---------------- %
  18. /r1default [0 1] def
  19. /r3default [0 1 0 1 0 1] def
  20. /apply3 % <u> <v> <w> [<pu> <pv> <pw>] apply3 <u'> <v'> <w'>
  21. { { 4 -1 roll exch exec } forall
  22. } bind def
  23. /restrict % <u> <min> <max> restrict <u'>
  24. { 3 1 roll .max .min
  25. } bind def
  26. /restrict3 % <u> <v> <w> [<minu> ... <maxw>] restrict3 <u'> <v'> <w'>
  27. { aload pop
  28. 7 -1 roll 3 1 roll restrict 7 1 roll
  29. 5 -1 roll 3 1 roll restrict 5 1 roll
  30. restrict 3 1 roll
  31. } bind def
  32. /rescale % <u> <min> <max> rescale <u'>
  33. { 1 index sub 3 1 roll sub exch div 0 .max 1 .min
  34. } bind def
  35. /rescale3 % <u> <v> <w> [<minu> ... <maxw>] rescale3 <u'> <v'> <w'>
  36. { aload pop
  37. 7 -1 roll 3 1 roll rescale 7 1 roll
  38. 5 -1 roll 3 1 roll rescale 5 1 roll
  39. rescale 3 1 roll
  40. } bind def
  41. /mmult3 % <u> <v> <w> [<uu> <uv> ... <wv> <ww>] mmult3
  42. % <u'> <v'> <w'>
  43. { 4 -1 roll dup dup 6 -1 roll dup dup 8 -1 roll dup dup
  44. 10 -1 roll { 10 -1 roll mul } forall
  45. % Stack: u1 v1 w1 u2 v2 w2 u3 v3 w3
  46. 4 -1 roll add 6 -1 roll add
  47. % Stack: u1 v1 u2 v2 u3 v3 w'
  48. 7 1 roll 3 -1 roll add 4 -1 roll add
  49. % Stack: w' u1 u2 u3 v'
  50. 5 1 roll add add 3 1 roll
  51. } bind def
  52. /minvert3 % [<uu> <uv> ... <wv> <ww>] minvert3
  53. % [<uu'> <uv'> ... <wv'> <ww'>]
  54. { 16 dict begin
  55. aload pop { I H G F E D C B A } { exch def } forall
  56. /coa E I mul F H mul sub def
  57. /cob F G mul D I mul sub def
  58. /coc D H mul E G mul sub def
  59. /det A coa mul B cob mul add C coc mul add def
  60. [ coa det div
  61. C H mul B I mul sub det div
  62. B F mul C E mul sub det div
  63. cob det div
  64. A I mul C G mul sub det div
  65. C D mul A F mul sub det div
  66. coc det div
  67. B G mul A H mul sub det div
  68. A E mul B D mul sub det div
  69. ]
  70. end
  71. } bind def
  72. /print1
  73. { print dup ==
  74. } bind def
  75. /print3
  76. { print 3 array astore dup == aload pop
  77. } bind def
  78. % ---------------- Mapping to XYZ ---------------- %
  79. /csmap % <csdict> <l> <m> <n> csmap <csdict> <x> <y> <z>
  80. { 3 index /RangeLMN .knownget not { r3default } if restrict3
  81. DOCIEDEBUG { (After RangeLMN Decode: ) print3 } if
  82. 3 index /DecodeLMN .knownget { apply3 } if
  83. DOCIEDEBUG { (After DecodeLMN Decode: ) print3 } if
  84. 3 index /MatrixLMN .knownget { mmult3 } if
  85. DOCIEDEBUG { (After MatrixLMN Decode: ) print3 } if
  86. } bind def
  87. /csciea % <csdict> <a> csciea <csdict> <x> <y> <z>
  88. { 1 index /RangeA .knownget not { r1default aload pop } if restrict
  89. DOCIEDEBUG { (After RangeA Decode: ) print1 } if
  90. 1 index /DecodeA .knownget { exec } if
  91. DOCIEDEBUG { (After DecodeA Decode: ) print1 } if
  92. 1 index /MatrixA .knownget
  93. { { 1 index mul exch } forall pop }
  94. { dup dup }
  95. ifelse
  96. DOCIEDEBUG { (After MatrixA Decode: ) print3 } if
  97. csmap
  98. } bind def
  99. /cscieabc % <csdict> <a> <b> <c> cscieabc <csdict> <x> <y> <z>
  100. { 3 index /RangeABC .knownget not { r3default } if restrict3
  101. DOCIEDEBUG { (After RangeABC Decode: ) print3 } if
  102. 3 index /DecodeABC .knownget { apply3 } if
  103. DOCIEDEBUG { (After DecodeABC Decode: ) print3 } if
  104. 3 index /MatrixABC .knownget { mmult3 } if
  105. DOCIEDEBUG { (After MatrixABC Decode: ) print3 } if
  106. csmap
  107. } bind def
  108. % ---------------- Rendering from XYZ ---------------- %
  109. /lookup3 % <rtable> <a[0..1]> <b[0..1]> <c[0..1]> lookup3
  110. % <rtable> <bytes>
  111. { 3 -1 roll 3 index 0 get 1 sub mul
  112. 3 -1 roll 3 index 1 get 1 sub mul
  113. 3 -1 roll 3 index 2 get 1 sub mul
  114. % Stack: rtable ia ib ic
  115. DOCIEDEBUG { (RenderTable indices: ) print3 mark 5 1 roll } if
  116. 3 -1 roll round cvi 3 index 3 get exch get
  117. % Stack: rtable ib ic string
  118. 3 -1 roll round cvi 3 index 2 get mul
  119. % Stack: rtable ic string ib*nc
  120. 3 -1 roll round cvi add 2 index 4 get mul
  121. % Stack: rtable string index
  122. 2 index 4 get getinterval
  123. % Stack: rtable bytes
  124. DOCIEDEBUG { (RenderTable values: ) print (<) print (%stdout) (w) file 1 index writehexstring (>) = } if
  125. } bind def
  126. /bpdefault [0 0 0] def
  127. /crmap % <csdict> <crdict> <x> <y> <z> crmap <v1> ...
  128. {
  129. DOCIEDEBUG { (CIE XYZ = ) print3 } if
  130. 3 index /MatrixPQR .knownget { mmult3 } if
  131. DOCIEDEBUG { (After MatrixPQR: ) print3 } if
  132. 4 index /WhitePoint get
  133. 5 index /BlackPoint .knownget not { bpdefault } if
  134. 5 index /WhitePoint get
  135. 6 index /BlackPoint .knownget not { bpdefault } if
  136. 4
  137. { 4 -1 roll aload pop
  138. % Stack: csdict crdict x y z pt pt pt px py pz
  139. 3 copy 12 index /MatrixPQR .knownget { mmult3 } if 6 array astore
  140. }
  141. repeat
  142. % Stack: csdict crdict x y z wps+ bps+ wpd+ bpd+
  143. 9 -1 roll pop % get rid of csdict
  144. 7 4 roll
  145. 7 index /TransformPQR get
  146. { % Stack: crdict wps+ bps+ wpd+ bpd+ u v w proc
  147. 8 copy exch pop exch pop
  148. exec exch pop 4 -1 roll pop
  149. }
  150. forall
  151. 7 3 roll pop pop pop pop % get rid of White/BlackPoints
  152. DOCIEDEBUG { (After TransformPQR: ) print3 } if
  153. 3 index /MatrixPQR .knownget { minvert3 mmult3 } if
  154. DOCIEDEBUG { (After MatrixPQR': ) print3 } if
  155. 3 index /MatrixLMN .knownget { mmult3 } if
  156. DOCIEDEBUG { (After MatrixLMN Encode: ) print3 } if
  157. 3 index /EncodeLMN .knownget { apply3 } if
  158. DOCIEDEBUG { (After EncodeLMN Encode: ) print3 } if
  159. 3 index /RangeLMN .knownget not { r3default } if restrict3
  160. DOCIEDEBUG { (After RangeLMN Encode: ) print3 } if
  161. 3 index /MatrixABC .knownget { mmult3 } if
  162. DOCIEDEBUG { (After MatrixABC Encode: ) print3 } if
  163. 3 index /EncodeABC .knownget { apply3 } if
  164. DOCIEDEBUG { (After EncodeABC Encode: ) print3 } if
  165. 3 index /RangeABC .knownget not { r3default } if
  166. 5 -1 roll /RenderTable .knownget
  167. { % Stack: u v w ranges rtable
  168. 5 1 roll rescale3
  169. DOCIEDEBUG { (Rescaled ABC: ) print3 } if
  170. % Stack: rtable a b c
  171. lookup3
  172. % Stack: rtable bytes
  173. 0 1 3 index 4 get 1 sub
  174. { % Stack: values rtable bytes c
  175. 2 copy get 255 div
  176. % Stack: values rtable bytes c v
  177. 3 index 3 -1 roll 5 add get exec 3 1 roll
  178. }
  179. for pop pop
  180. DOCIEDEBUG { (After RenderTableT: ) print ] dup == aload pop } if
  181. }
  182. { restrict3
  183. DOCIEDEBUG { (After RangeABC Encode: ) print3 } if
  184. }
  185. ifelse
  186. } bind def
  187. % ---------------- Top level control ---------------- %
  188. /mapdict mark
  189. /CIEBasedA { 1 get exch csciea currentcolorrendering 4 1 roll crmap } bind
  190. /DeviceGray { pop /DefaultGray /ColorSpace findresource 1 get exch csciea currentcolorrendering 4 1 roll crmap } bind
  191. /CIEBasedABC { 1 get 4 1 roll cscieabc currentcolorrendering 4 1 roll crmap } bind
  192. /DeviceRGB { pop /DefaultRGB /ColorSpace findresource 1 get 4 1 roll cscieabc currentcolorrendering 4 1 roll crmap } bind
  193. .dicttomark def
  194. /mapcie % <a> mapcie <v1> ...
  195. % <a> <b> <c> mapcie <v1> ...
  196. { currentcolorspace dup 0 get //mapdict exch get exec
  197. } bind def