rem Spline Resize V ......... Rev 8.0 rem Assembler Enhanced Version rem A J Tooth // July 2005 rem Modified to work on both jpg and bmp January 2006 rem Largely rewritten March 2007 rem Preamble================================== rem on error if (err=17) then quit *FLOAT 64 himem=lomem + 250000000 install @lib$+"MyUtils.bbc" install @lib$+"BMP_Utils.bbc" rem Preamble================================== rem Setup proc_setup rem Choose a suitable small picture to enlarge proc_pichoose(Name$,FulName$,Pr$,wdth%,hght%,lgth%,pf%) rem Transfer to Fullscreen mode proc_fullscreen(xscreen%,yscreen%) rem Set the scaling proc_scale(wdth%,hght%,xsb%,ysb%,xsc%,ysc%,yset%,xset%) rem Display the original image proc_BMP_Disp(xsc%,ysc%,pf%,xsb%,ysb%) colour 3 print tab(5,5);"Width = ";wdth%;" resizing to: ";Xlim% print tab(5,7);"Height = ";hght%;" resizing to: ";Ylim% print tab(5,11);"Press any key, or left-click, to continue." proc_event(a$,b&) rem Y-Splines proc_YSplines rem Compile Assembly Routines proc_comp rem X-Splines proc_XSplines rem Re-Set the scaling proc_scale(Xlim%,Ylim%,xsb%,ysb%,xsc%,ysc%,yset%,xset%) rem Display the resulting enlarged image cls : proc_BMP_Disp(xsc%,ysc%,pfdest%,xsb%,ysb%) proc_event(a$,b&) if a$="s" then proc_save(a$,b&) if a$=" " or b&=4 then run else quit quit rem End of Program =================================================== rem ================================================================== rem Setup def proc_setup local x%,y%,b& dim ftmp% 7, itmp% 3, CR% 3 rem Maximise the Window sys "ShowWindow", @hwnd%, 3 vdu 26 off : colour 132,0,0,50 : colour 4,0,0,50 : colour 132:cls rem Change the Windows Title title$ = " Spline Resize V" sys "SetWindowText", @hwnd%, title$ Font$="Georgia" : Sz&=12 : Styl$="" Msg$="\11 \3Click on a button to choose the default size for resizing in pixels." proc_msg(Font$,Sz&,Styl$,100,1300,Msg$) Msg$="\12 \3Rotate the mouse wheel to fine-tune pixels, if desired." proc_msg(Font$,Sz&,Styl$,100,1250,Msg$) Msg$="\13 \3Left-click on \2OK \3to confirm the setting." proc_msg(Font$,Sz&,Styl$,100,1200,Msg$) Msg$="\3Alternative default settings" proc_msg(Font$,Sz&,Styl$,200,1100,Msg$) Xlim%=1024 : Ylim%=768 : rem Default values rem Defaults proc_defaults(Xlim%,Ylim%) Msg$="\2New Width : " proc_msg(Font$,Sz&,Styl$,200,500,Msg$) Msg$="\2New Height: " proc_msg(Font$,Sz&,Styl$,200,450,Msg$) Msg$="\2OK" proc_msg(Font$,Sz&,Styl$,200,350,Msg$) Msg$="\1"+str$(Xlim%) proc_msg(Font$,Sz&,Styl$,400,500,Msg$) Msg$="\1"+str$(Ylim%) proc_msg(Font$,Sz&,Styl$,400,450,Msg$) b&=0 repeat mouse x%,y%,b& sys "Sleep",5 cs&=0 if x%>400 and x%<500 and y%<500 and y%>450 then cs&=1 if x%>400 and x%<500 and y%<450 and y%>400 then cs&=2 if x%>200 and x%<250 and y%<350 and y%>300 then cs&=3 case cs& of when 0: mouse on 136 when 1: mouse on 137 Xval%=fn_islct(256,Xlim%,3264) if abs(Xlim%-Xval%)>0 then Msg$="\4"+str$(Xlim%) proc_msg(Font$,Sz&,Styl$,400,500,Msg$) Xlim%=Xval% Msg$="\1"+str$(Xlim%) proc_msg(Font$,Sz&,Styl$,400,500,Msg$) endif when 2: mouse on 137 Yval%=fn_islct(256,Ylim%,2448) if abs(Ylim%-Yval%)>0 then Msg$="\4"+str$(Ylim%) proc_msg(Font$,Sz&,Styl$,400,450,Msg$) Ylim%=Yval% Msg$="\1"+str$(Ylim%) proc_msg(Font$,Sz&,Styl$,400,450,Msg$) endif when 3: mouse on 137 endcase until b&>0 and cs&=3 Msg$="\3OK" proc_msg(Font$,Sz&,Styl$,200,350,Msg$) a$=inkey$(50) : cls : mouse off Tlgth%=Xlim%*Ylim%*3 + 54 rem Standard bmp header proc_BMP_Set(Xlim%,Ylim%,pfdest%,Dlim%,Tlgth%) endproc rem ================================================================== rem Set the scaling def proc_scale(Wd%,Hh%,return xb%, return yb%, return xc%, return yc%, return yst%, return xst%) if Hh%<0.75*Wd% then yc%=int(xscreen%*Hh%/Wd%) : yb%=int((yscreen%-yc%)/2) xc%=xscreen% : xb%=0 else yc%=yscreen% : yb%=0 xc%=int(yscreen%*Wd%/Hh%) : xb%=int((xscreen%-xc%)/2) endif yst%=yscreen%-yc% : xst%=xscreen%-xc% endproc rem ======================================================================= rem Select a default size def proc_defaults(return Xl%,return Yl%) local a&,d&,x%,y%,b&,s& dim butt{ch$(5),state&(5)} rem Button messages butt.ch$(1)="\11024 \2x \1768" butt.ch$(2)="\12048 \2x \11536" butt.ch$(3)="\13264 \2x \12448" butt.ch$(4)="\1768 \2x \11024" butt.ch$(5)="\11024 \2x \1256" for a&=1 to 5 butt.state&(a&)=1 next a& rem Gete reference for a pressed button cc&=fn_getbut(Font$,Sz&,Styl$,butt{},200,1000,100,5) rem Adjust filter values case cc& of when 1 : Xl%=1024 : Yl%=768 when 2 : Xl%=2048 : Yl%=1536 when 3 : Xl%=3264 : Yl%=2448 when 4 : Xl%=768 : Yl%=1024 when 5 : Xl%=1024 : Yl%=256 endcase endproc rem ================================================================== rem Parameter selection function - integers def fn_islct(Mn%,Typ%,Mx%) : local x%, y%, b&, cur%, in& cur%=Typ% rem Raise / lower parameter if mouse wheel rotated in&=inkey(2) case in& of when 141 : if cur%>Mn% then cur%-=1 when 138 : if cur%>Mn%+100 then cur%-=100 when 140 : if cur%=(!wid%-1) ? mov ecx,[^wdth%] dec ecx cmp eax,ecx jge near nocal2 ;If so, set m2=0.0 mov eax,[^y1%] imul eax,[^Wlim%] mov ebx,[^x1%] add ebx,[^x1%] add ebx,[^x1%] mov ebx,0 mov bl,[^a&] add eax,ebx add eax,54 ;Calculate ref2 mov [^ref2%],eax add eax,3 ;Add 3 gives ref1 mov [^ref1%],eax mov ebx,0 ;Calculate m2 mov bl,pf%[eax] mov ecx,ebx mov eax,[^ref2%] mov bl,pf%[eax] sub ecx,ebx mov [itmp%],ecx fild dword [itmp%] fld qword [^StpX] fld st0 faddp st1,st0 fdivp st1,st0 fstp qword [^m2] jmp cont2 .nocal2 fldz fstp qword [^m2] ;Calculate m2 .cont2 fild dword [^b%] ;Calculate D1 fld qword [^StpX] fild dword [^x1%] fmulp st1,st0 fsubp st1,st0 fst qword [^d1] ;D1 left 0n stack fld qword [^StpX] ;Calculate D2=D1-StpX% fsubp st1,st0 fst qword [^d2] ;D2 left 0n stack fld qword [^m1] ;Calculate D1*D2*(M1*D2 + M2*D1) fmulp st1,st0 fld qword [^m2] fld qword [^d1] fmulp st1,st0 faddp st1,st0 fld qword [^d1] fld qword [^d2] fmulp st1,st0 fmulp st1,st0 fstp qword [ftmp%] ;Store in ftmp% temporarily fld qword [^d1] ;Calculate P1*D2*D2*(1+((2*D1)/|StpX%)) fadd st0,st0 fld qword [^StpX] fdivp st1,st0 fld1 faddp st1,st0 fld qword [^p1] fmulp st1,st0 fld qword [^d2] fmul st0,st0 fmulp st1,st0 fld qword [ftmp%] faddp st1,st0 fstp qword [ftmp%] ;Store cumulative result in ftmp% temporarily fld qword [^d2] ;Calculate P2*D1*D1*(1-((2*D2)/|StpX%)) fadd st0,st0 fld qword [^StpX] fdivp st1,st0 fld1 fsubrp st1,st0 fld qword [^p2] fmulp st1,st0 fld qword [^d1] fmul st0,st0 fmulp st1,st0 fld qword [ftmp%] faddp st1,st0 fld qword [^StpX] fmul st0,st0 fdivp st1,st0 fistp dword [^u%] ;Normalise clr t0 lie in range 0-255 mov ecx,[^u%] cmp ecx,0 jle low cmp ecx,255 jge high mov [^cv&],cl jmp miss .low mov cl,0 mov [^cv&],cl jmp miss .high mov cl,255 mov [^cv&],cl ;Normalise clr t0 lie in range 0-255 .miss mov eax,[^c%] ;Calculate array reference p0int imul eax,[^Dlim%] add eax,[^b%] add eax,[^b%] add eax,[^b%] mov ecx,0 mov cl,[^a&] add eax,ecx add eax,54 mov bl,[^cv&] ;Transfer clr vlue t0 bmp array mov pfdest%[eax],bl inc byte [^a&] ;Minor loop control mov dl,[^a&] cmp dl,2 jle near mloop fstcw [CR%] ;Reset rounding control t0 Default mov ax,[CR%] and ax,&F3FF ;Clears bits 10-11 in FP Cntrl Register mov [CR%],ax fldcw [CR%] ;Reset rounding control t0 Default inc dword [^b%] ;Major loop control mov edx,[^b%] mov ecx,[^Xlim%] dec ecx dec ecx cmp edx,ecx jle near bloop inc dword [^c%] ;External loop control mov edx,[^c%] mov ecx,[^Ylim%] dec ecx dec ecx cmp edx,ecx jle near eloop ret ] endproc rem ======================================================================= rem Lagrange Polynomial Coefficients Assembly Routine def proc_coeff(opt&) P%=coeff% [opt opt& finit mov eax,[^hght%] ;Calculate reference f0r my1 imul eax,[^y1%] mov dl,[^Flg&] cmp dl,2 je scnda add eax,[^x1%] add eax,[^x1%] add eax,[^x1%] jmp ntscnda .scnda add eax,[^x2%] add eax,[^x2%] add eax,[^x2%] .ntscnda mov ebx,0 mov bl,[^a&] add eax,ebx shl eax,3 fld qword Yspl%[eax] fstp qword [^my1] ;Fetch my1 mov eax,[^hght%] ;Calculate reference f0r my2 imul eax,[^y2%] mov dl,[^Flg&] cmp dl,2 je scndaa add eax,[^x1%] add eax,[^x1%] add eax,[^x1%] jmp ntscndaa .scndaa add eax,[^x2%] add eax,[^x2%] add eax,[^x2%] .ntscndaa mov ebx,0 mov bl,[^a&] add eax,ebx shl eax,3 fld qword Yspl%[eax] fstp qword [^my2] ;Fetch my2 fild dword [^c%] ;Calculate d1 fild dword [^y1%] fld qword [^Stpy] fmulp st1,st0 fsubp st1,st0 fstp qword [^d1] ;Calculate d1 fild dword [^c%] ;Calculate d2 fild dword [^y2%] fld qword [^Stpy] fmulp st1,st0 fsubp st1,st0 fst qword [^d2] ;Calculate d2 fld qword [^my1] ;Calculate D1*D2*(My1*D2 + My2*D1) fmulp st1,st0 fld qword [^d1] fld qword [^my2] fmulp st1,st0 faddp st1,st0 ;Here is (My1*D2 + My2*D1) fld qword [^d1] fld qword [^d2] fmulp st1,st0 fmulp st1,st0 fstp qword [ftmp%] ;Store result temporarily in ftmp% mov eax,[^y1%] ;Calculate 54 + (3*!wid% + ?rs%)*Y1% + 3*X2% + ?a% imul eax,[^Wlim%] mov dl,[^Flg&] cmp dl,2 je scnd add eax,[^x1%] add eax,[^x1%] add eax,[^x1%] jmp ntscnd .scnd add eax,[^x2%] add eax,[^x2%] add eax,[^x2%] .ntscnd mov ebx,0 mov bl,[^a&] add eax,ebx add eax,54 ;Calculate 54 + (3*!wid% + ?rs%)*Y1% + 3*X2% + ?a% fld qword [^d1] ;Calculate ?(pf% + !ref%)*D2*D2*(1+((2*D1)/Stpy)) fadd st0,st0 fld qword [^Stpy] fdivp st1,st0 fld1 faddp st1,st0 fld qword [^d2] fmul st0,st0 fmulp st1,st0 mov ecx,0 mov cl,pf%[eax] mov [itmp%],ecx fild dword [itmp%] fmulp st1,st0 fld qword [ftmp%] faddp st1,st0 fstp qword [ftmp%] ;Store cumulative result in ftmp% mov eax,[^y2%] ;Calculate 54 + (3*!wid% + ?rs%)*Y2% + 3*X2% + ?a% imul eax,[^Wlim%] mov dl,[^Flg&] cmp dl,2 je scndb add eax,[^x1%] add eax,[^x1%] add eax,[^x1%] jmp ntscndb .scndb add eax,[^x2%] add eax,[^x2%] add eax,[^x2%] .ntscndb mov ebx,0 mov bl,[^a&] add eax,ebx add eax,54 ;Calculate 54 + (3*!wid% + ?rs%)*Y2% + 3*X2% + ?a% fld qword [^d2] ;Calculate ?(pf% + !ref%)*D1*D1*(1-((2*D2)/Stpy)) fadd st0,st0 fld qword [^Stpy] fdivp st1,st0 fld1 fsubrp st1,st0 fld qword [^d1] fmul st0,st0 fmulp st1,st0 mov ecx,0 mov cl,pf%[eax] mov [itmp%],ecx fild dword [itmp%] fmulp st1,st0 fld qword [ftmp%] faddp st1,st0 fld qword [^Stpy] fmul st0,st0 fdivp st1,st0 mov dl,[^Flg&] cmp dl,2 je ptwo fstp qword [^p1] ;Result is p1% jmp ntwo .ptwo fstp qword [^p2] ;Result is p2% .ntwo ret ] endproc rem ======================================================================= rem Y-Splines Assembly Routine def proc_ysplin(opt&) P%=ysplin% [opt opt& mov edx,0 mov [^j%],edx ;Initialise outer loop counter .outloop mov edx,0 mov [^k%],edx ;Initialise middle loop counter .midloop mov dl,0 mov [^a&],dl ;Initialise minor loop counter .iloop finit mov eax,[^k%] ;Calculate references cmp eax,0 je near ncal mov eax,[^k%] imul eax,[^Wlim%] add eax,[^j%] add eax,[^j%] add eax,[^j%] mov ebx,0 mov bl,[^a&] add eax,ebx add eax,54 mov [^ref1%],eax sub eax,[^Wlim%] mov [^ref2%],eax ;Calculate references mov ebx,0 ;Calculate m mov ecx,0 mov [itmp%],ebx mov eax,[^ref1%] mov cl,pf%[eax] mov eax,[^ref2%] mov bl,pf%[eax] sub ecx,ebx mov [itmp%],ecx fild dword [itmp%] fld qword [^Stpy] fadd st0,st0 fdivp st1,st0 fstp qword [^m] ;m=(?(pf% + !ref1%) - ?(pf% + !ref2%))/(2*Stpy) jmp cont0 .ncal fldz fstp qword [^m] ;m set t0 0.0 1f k%=0 .cont0 mov eax,[^hght%] imul eax,[^k%] add eax,[^j%] add eax,[^j%] add eax,[^j%] mov ebx,0 mov bl,[^a&] add eax,ebx shl eax,3 fld qword Yspl%[eax] fstp qword [^m] inc byte [^a&] ;Minor loop control mov dl,[^a&] cmp dl,2 jle near iloop inc dword [^k%] ;Middle loop control mov edx,[^k%] mov ecx,[^hght%] cmp edx,ecx jl near midloop inc dword [^j%] ;Outer loop control mov edx,[^j%] mov ecx,[^wdth%] cmp edx,ecx jl near outloop ret ] endproc rem =======================================================================