%!PS % PIXEL INTERPOLATION TABLE LOOKUP GENERATOR % ========================================== % by Don Lancaster % Copyright c 2002 by Don Lancaster & Synergetics, Box 809, Thatcher, AZ, 85552 % (928) 428-4073 Email: don@tinaja.com Website: http://www.tinaja.com % Consulting services available http://www.tinaja.com/info01.html % All commercial rights and all electronic media rights ~fully~ reserved. % Linking usually welcome. Reposting expressly forbidden. Version 1.5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% This demo code shows how to generate the cubic spline hires basis functions %% needed for image pixel interpolation as a fast table lookup. %% Additional details are found at http://www.tinaja.com/glib/basis.pdf and %% http://members.bellatlantic.net/~vze2vrva/design.html %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % IMPORTANT NOTE: Don Lancaster's file gonzo.ps is required for this program. % After obvious location mods, uncomment ONE of the following two lines: (C:\\Documents and Settings\\don\\Desktop\\gonzo\\gonzo.ps) run % use internal gonzo % (A:\\gonzo.ps) run % use external gonzo % NOTE THAT ALL PS FILENAME STRINGS !!!DEMAND!!! DOUBLE REVERSE SLASHES. % GONZO20A Guru Gonzo PostScript power tools (Interim release) % Includes gonzo justification and layout utilities. % Copyright c 1990, 1996, 2001 by Don Lancaster and Synergetics, Box 809, % Thatcher Arizona, 5552 (928) 428-4073 don@tinaja.com support % via http://www.tinaja.com All commercial rights and all electronic % media rights **FULLY** reserved. Reposting is expressly forbidden. %% Another useful paper is Parker, J. A., R. V. Kenyon, and Troxel, D. E., %% "Comparison of Interpolating Methods for Image Resampling," _IEEE Transations %% on Medical Imaging_, Vol. MI-2, No. 1, March, 1983, pp. 31-39. %% Data format is as an array of arrays: %% [[B0_0.0 B1_0.0 B2_0.0 B3_0.0 Tx_0.0] ... [[B0_1.0 B1_1.0 23_1.0 B3_1.0 Tx_1.0]] %% aa and xx may optionally be tacked into each array end as reminders. %% Interpolated y values are then simply found by y0B0 + y1B1 + y2B2 + y3B3. %% Process is done once for pixel rows, and then repeated for four pixel columns. /resolution 100 store % one less than the total increment from x=0 to x=1 /aa -1.0 store % edge enhancement -1 for people -0.5 for machines % tofx finds t(x)for a given x. This intermediate step is needed to relate y to x. % t(x) = 2(2a+1)x^3 -3(2a+1)x^2 + 2 (a+1)x /findtofx {gsave /xxx exch store % save xxx value xxx dup dup mul mul % find t(x) term by term aa 2 mul 1 add mul 2 mul xxx dup mul aa 2 mul 1 add mul 3 mul sub xxx aa 1 add mul 2 mul add grestore } store % Basis functions do the actual cubic calculations, then become fixed lookup values. % b0(t) = at^3 - 2at^2 + at /B0yoft { tofx dup dup mul mul aa mul tofx dup mul 2 mul aa mul sub tofx aa mul add } store % b1(t) = (a+2)t3 -(a+3)t^2 + 1 /B1yoft { tofx dup dup mul mul aa 2 add mul tofx dup mul aa 3 add mul sub 1 add } store % b2(t) = -(a+2)t^3 + (2a+3)t^2 -at /B2yoft { tofx dup dup mul mul aa 2 add mul neg tofx dup mul aa 2 mul 3 add mul add tofx aa mul sub } store % b3(t) = -at^3 + at^2 /B3yoft { tofx dup dup mul mul aa mul neg tofx dup mul aa mul add } store % generatebasistable creates the table lookup array /generatebasistable {gsave mark % start main array 0 1 resolution div 1.0001 { /xx exch store % current increment xx findtofx /tofx exch store % find t(x) for x mark % start subarray B0yoft % enter data values B1yoft B2yoft B3yoft tofx aa % optional reminder xx resolution mul round resolution div % optional reminder ] % end subarray } for ] % end main array grestore} def % This actually does it... generatebasistable /basistab exch store % basistab == { %% checkplot 100 300 10 setgrid 20 20 showgrid 0 0 moveto 0 0.01 1 {/xx exch store xx 20 mul xx 100 mul round cvi basistab exch get 4 get 20 mul lineto } for 1 0 0 setrgbcolor line1 stroke 0 0 moveto 0 0.01 1 {/xx exch store xx 20 mul xx 100 mul round cvi basistab exch get 0 get 20 mul lineto } for 1 1 0 setrgbcolor line1 stroke 0 0 moveto 0 0.01 1 {/xx exch store xx 20 mul xx 100 mul round cvi basistab exch get 1 get 20 mul lineto } for 0 1 0 setrgbcolor line1 stroke 0 0 moveto 0 0.01 1 {/xx exch store xx 20 mul xx 100 mul round cvi basistab exch get 2 get 20 mul lineto } for 0 1 1 setrgbcolor line1 stroke 0 0 moveto 0 0.01 1 {/xx exch store xx 20 mul xx 100 mul round cvi basistab exch get 3 get 20 mul lineto } for 0 0 1 setrgbcolor line1 stroke showpage } pop %% Note that the B3 and B4 are redundant, as they can be read backwards %% by using symmetry. Tx is included for completeness, but would not normally be used. %% Here's what should get returned with reminders in place for aa = -1.0: %% (this has been slightly pretty printed)... : /basistab [ [ 0.00000000 1.000000 0.00000000 0.000000000 0.000000 -1.0 0.00] [-0.00029782 1.000000 0.00029808 -8.87775e-08 0.000298 -1.0 0.01] [-0.00118120 0.999997 0.00118540 -1.40020e-06 0.001184 -1.0 0.02] [-0.00263202 0.999986 0.00265298 -6.98279e-06 0.002646 -1.0 0.03] [-0.00462845 0.999956 0.00469373 -2.17256e-05 0.004672 -1.0 0.04] [-0.00714526 0.9998950 0.0073022 -5.21814e-05 0.007250 -1.0 0.05] [-0.01015410 0.9997860 0.0104744 -0.000106381 0.010368 -1.0 0.06] [-0.01362400 0.9996100 0.0142076 -0.000193640 0.014014 -1.0 0.07] [-0.01752130 0.9993450 0.0185004 -0.000324362 0.018176 -1.0 0.08] [-0.02181040 0.9989680 0.0233518 -0.000509839 0.022842 -1.0 0.09] [-0.02645390 0.9984540 0.0287620 -0.000762048 0.028000 -1.0 0.10] [-0.03141300 0.9977750 0.0347314 -0.001093450 0.033638 -1.0 0.11] [-0.03664760 0.9969040 0.0412608 -0.001516810 0.039744 -1.0 0.12] [-0.04211680 0.9958110 0.0483509 -0.002044950 0.046306 -1.0 0.13] [-0.04777920 0.9944670 0.0560026 -0.002690650 0.053312 -1.0 0.14] [-0.05359310 0.9928430 0.0642164 -0.003466360 0.060750 -1.0 0.15] [-0.05951680 0.9909090 0.0729921 -0.004384110 0.068608 -1.0 0.16] [-0.06550910 0.9886350 0.0823293 -0.005455320 0.076874 -1.0 0.17] [-0.07152900 0.9859930 0.0922266 -0.006690590 0.085536 -1.0 0.18] [-0.07753660 0.9829550 0.1026820 -0.008099650 0.094582 -1.0 0.19] [-0.08349290 0.9794930 0.1136910 -0.009691140 0.104000 -1.0 0.20] [-0.08936000 0.9755820 0.1252510 -0.011472500 0.113778 -1.0 0.21] [-0.09510180 0.9711980 0.1373540 -0.013450000 0.123904 -1.0 0.22] [-0.10068300 0.9663170 0.1499940 -0.015628400 0.134366 -1.0 0.23] [-0.10607200 0.9609200 0.1631630 -0.018010900 0.145152 -1.0 0.24] [-0.11123700 0.9549870 0.1768490 -0.020599400 0.156250 -1.0 0.25] [-0.11614800 0.9485000 0.1910420 -0.023394000 0.167648 -1.0 0.26] [-0.12078000 0.9414460 0.2057270 -0.026393200 0.179334 -1.0 0.27] [-0.12510800 0.9338120 0.2208900 -0.029593800 0.191296 -1.0 0.28] [-0.12911000 0.9255880 0.2365130 -0.032991100 0.203522 -1.0 0.29] [-0.13276600 0.9167660 0.2525780 -0.036578300 0.216000 -1.0 0.30] [-0.13605900 0.9073410 0.2690650 -0.040347200 0.228718 -1.0 0.31] [-0.13897500 0.8973110 0.2859520 -0.044287900 0.241664 -1.0 0.32] [-0.14150100 0.8866750 0.3032150 -0.048388800 0.254826 -1.0 0.33] [-0.14362800 0.8754360 0.3208290 -0.052636700 0.268192 -1.0 0.34] [-0.14535000 0.8636000 0.3387670 -0.057016900 0.281750 -1.0 0.35] [-0.14666200 0.8511740 0.3570010 -0.061513100 0.295488 -1.0 0.36] [-0.14756100 0.8381670 0.3755020 -0.066108000 0.309394 -1.0 0.37] [-0.14805000 0.8245940 0.3942380 -0.070782500 0.323456 -1.0 0.38] [-0.14812900 0.8104680 0.4131790 -0.075516800 0.337662 -1.0 0.39] [-0.14780600 0.7958060 0.4322900 -0.080289700 0.352000 -1.0 0.40] [-0.14708700 0.7806290 0.4515370 -0.085079200 0.366458 -1.0 0.41] [-0.14598200 0.7649580 0.4708860 -0.089862400 0.381024 -1.0 0.42] [-0.14450300 0.7488170 0.4903020 -0.094615800 0.395686 -1.0 0.43] [-0.14266200 0.7322310 0.5097470 -0.099315300 0.410432 -1.0 0.44] [-0.14047600 0.7152260 0.5291860 -0.103936000 0.425250 -1.0 0.45] [-0.13796100 0.6978330 0.5485820 -0.108454000 0.440128 -1.0 0.46] [-0.13513600 0.6800820 0.5678980 -0.112844000 0.455054 -1.0 0.47] [-0.13202000 0.6620040 0.5870970 -0.117081000 0.470016 -1.0 0.48] [-0.12863400 0.6436320 0.6061430 -0.121141000 0.485002 -1.0 0.49] [-0.12500000 0.6250000 0.6250000 -0.125000000 0.500000 -1.0 0.50] [-0.12114100 0.6061440 0.6436310 -0.128634000 0.514998 -1.0 0.51] [-0.11708200 0.5870980 0.6620030 -0.132019000 0.529984 -1.0 0.52] [-0.11284400 0.5678990 0.6800810 -0.135136000 0.544946 -1.0 0.53] [-0.10845400 0.5485830 0.6978330 -0.137961000 0.559872 -1.0 0.54] [-0.10393700 0.5291870 0.7152260 -0.140476000 0.574750 -1.0 0.55] [-0.09931550 0.5097480 0.7322300 -0.142662000 0.589568 -1.0 0.56] [-0.09461600 0.4903002 0.7488160 -0.144503000 0.604314 -1.0 0.57] [-0.08986260 0.4708870 0.7649580 -0.145982000 0.618976 -1.0 0.58] [-0.08507940 0.4515380 0.7806290 -0.147087000 0.633542 -1.0 0.59] [-0.08028990 0.4322900 0.7958060 -0.147806000 0.648000 -1.0 0.60] [-0.07551700 0.4131790 0.8104670 -0.148129000 0.662338 -1.0 0.61] [-0.07078270 0.3942390 0.8245930 -0.148050000 0.676544 -1.0 0.62] [-0.06610820 0.3755030 0.8381670 -0.147561000 0.690606 -1.0 0.63] [-0.06151330 0.3570020 0.8511730 -0.146662000 0.704512 -1.0 0.64] [-0.05701700 0.3387670 0.8636000 -0.145350000 0.718250 -1.0 0.65] [-0.05263690 0.3208290 0.8754360 -0.143628000 0.731808 -1.0 0.66] [-0.04838900 0.3032150 0.8866750 -0.141501000 0.745174 -1.0 0.67] [-0.04428810 0.2859530 0.8973100 -0.138975000 0.758336 -1.0 0.68] [-0.04034740 0.2690660 0.9073410 -0.136059000 0.771282 -1.0 0.69] [-0.03657840 0.2525790 0.9167650 -0.132766000 0.783999 -1.0 0.7] [-0.03299120 0.2365140 0.9255870 -0.129110000 0.796478 -1.0 0.71] [-0.02959400 0.2208910 0.9338120 -0.125108000 0.808703 -1.0 0.72] [-0.02639330 0.2057280 0.9414460 -0.120780000 0.820666 -1.0 0.73] [-0.02339410 0.1910430 0.9485000 -0.116148000 0.832352 -1.0 0.74] [-0.02059950 0.1768500 0.9549860 -0.111237000 0.843534 -1.0 0.75] [-0.01801100 0.1631630 0.9609200 -0.106072000 0.854848 -1.0 0.76] [-0.01562840 0.1499950 0.9663170 -0.100684000 0.865634 -1.0 0.77] [-0.01345010 0.1373550 0.9711980 -0.095102100 0.876096 -1.0 0.78] [-0.01147260 0.1252510 0.9755820 -0.089360300 0.886222 -1.0 0.79] [-0.00969124 0.1136920 0.9794930 -0.0834931 0.896000 -1.0 0.80] [-0.00809973 0.1026820 0.9829540 -0.0775369 0.905418 -1.0 0.81] [-0.00669068 0.0922272 0.9859930 -0.0715293 0.914464 -1.0 0.82] [-0.00545537 0.0823298 0.9886350 -0.0655093 0.923126 -1.0 0.83] [-0.00438416 0.0729926 0.9909090 -0.0595171 0.931392 -1.0 0.84] [-0.00346643 0.0642168 0.9928430 -0.0535933 0.939250 -1.0 0.85] [-0.00269067 0.0560032 0.9944670 -0.0477796 0.946687 -1.0 0.86] [-0.00204504 0.0483515 0.9958110 -0.0421172 0.953694 -1.0 0.87] [-0.00151682 0.0412612 0.9969040 -0.0366479 0.960256 -1.0 0.88] [-0.00109351 0.0347319 0.9977750 -0.0314133 0.966362 -1.0 0.89] [-0.00076204 0.0287624 0.9984540 -0.0264543 0.972000 -1.0 0.90] [-0.00050985 0.0233523 0.9989680 -0.0218108 0.977158 -1.0 0.91] [-0.00032436 0.0185004 0.9993450 -0.0175213 0.981824 -1.0 0.92] [-0.00019365 0.0142079 0.9996100 -0.0136242 0.985986 -1.0 0.93] [-0.00010633 0.0104744 0.9997860 -0.0101542 0.989632 -1.0 0.94] [-5.2154e-05 0.0073022 0.9998950 -0.0071453 0.992750 -1.0 0.95] [-2.1755e-05 0.0046940 0.9999560 -0.0046287 0.995328 -1.0 0.96] [-7.0333e-06 0.0026532 0.9999860 -0.0026322 0.997354 -1.0 0.97] [-1.3709e-06 0.0011853 0.9999970 -0.0011811 0.998816 -1.0 0.98] [-1.1920e-07 0.0002981 0.9999998 -0.0002978 0.999702 -1.0 0.99] [-0.00000000 0.0000000 1.0000000 -0.0000000 1.000000 -1.0 1.00] ] store %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % generate an xy interpolation table /nnn 16 store % table resolution /aa -1.0 store % magic a value /xybasistlu00 { /xyb00 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B0yoft xxxx findtofx /tofx exch store B0yoft mul } for ] } for ] store } store /xybasistlu01 { /xyb01 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B0yoft xxxx findtofx /tofx exch store B1yoft mul } for ] } for ] store } store /xybasistlu02 { /xyb02 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B0yoft xxxx findtofx /tofx exch store B2yoft mul } for ] } for ] store } store /xybasistlu03 { /xyb03 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B0yoft xxxx findtofx /tofx exch store B3yoft mul } for ] } for ] store } store /xybasistlu10 { /xyb10 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B1yoft xxxx findtofx /tofx exch store B0yoft mul } for ] } for ] store } store /xybasistlu11 { /xyb11 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B1yoft xxxx findtofx /tofx exch store B1yoft mul } for ] } for ] store } store /xybasistlu12 { /xyb12 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B1yoft xxxx findtofx /tofx exch store B2yoft mul } for ] } for ] store } store /xybasistlu13 { /xyb13 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B1yoft xxxx findtofx /tofx exch store B3yoft mul } for ] } for ] store } store /xybasistlu20 { /xyb20 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B2yoft xxxx findtofx /tofx exch store B0yoft mul } for ] } for ] store } store /xybasistlu21 { /xyb21 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B2yoft xxxx findtofx /tofx exch store B1yoft mul } for ] } for ] store } store /xybasistlu22 { /xyb22 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B2yoft xxxx findtofx /tofx exch store B2yoft mul } for ] } for ] store } store /xybasistlu23 { /xyb23 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B2yoft xxxx findtofx /tofx exch store B3yoft mul } for ] } for ] store } store /xybasistlu30 { /xyb30 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B3yoft xxxx findtofx /tofx exch store B0yoft mul } for ] } for ] store } store /xybasistlu31 { /xyb31 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B3yoft xxxx findtofx /tofx exch store B1yoft mul } for ] } for ] store } store /xybasistlu32 { /xyb32 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B3yoft xxxx findtofx /tofx exch store B2yoft mul } for ] } for ] store } store /xybasistlu33 { /xyb33 mark % start array 0 1 nnn div 1 { /yyyy exch store mark 0 1 nnn div 1 { /xxxx exch store yyyy findtofx /tofx exch store B3yoft xxxx findtofx /tofx exch store B3yoft mul } for ] } for ] store } store stopwatchon xybasistlu00 xybasistlu01 xybasistlu02 xybasistlu03 xybasistlu10 xybasistlu11 xybasistlu12 xybasistlu13 xybasistlu20 xybasistlu21 xybasistlu22 xybasistlu23 xybasistlu30 xybasistlu31 xybasistlu32 xybasistlu33 stopwatchoff (\n\n\n\n) print flush xyb00 == (\n\n\n\n) print flush xyb01 == (\n\n\n\n) print flush xyb02 == (\n\n\n\n) print flush xyb03 == (\n\n\n\n) print flush xyb10 == (\n\n\n\n) print flush xyb11 == (\n\n\n\n) print flush xyb12 == (\n\n\n\n) print flush xyb13 == (\n\n\n\n) print flush xyb20 == (\n\n\n\n) print flush xyb21 == (\n\n\n\n) print flush xyb22 == (\n\n\n\n) print flush xyb23 == (\n\n\n\n) print flush xyb30 == (\n\n\n\n) print flush xyb31 == (\n\n\n\n) print flush xyb32 == (\n\n\n\n) print flush xyb33 == % EOF