rem Picture Editor (ASM version) ............. Rev 3.2 rem A J Tooth // May 2009 rem ==================================================================== rem Implements a suite of basic Photo Editor functions. rem ==================================================================== rem Preamble================================== on error if (err=17) then quit *FLOAT 64 himem=lomem + 200000000 install @lib$+"MyUtils.bbc" install @lib$+"BMP_Utils.bbc" rem Preamble================================== rem Set up initial screen proc_setup repeat rem Select a menu item Ch&=fn_select case Ch& of when 1: cls : proc_initial : if Z%=0 then proc_setup2 : Z%=1 when 2: NoCh&=0 : Rev&=1 : proc_action(1) when 3: NoCh&=0 : Rev&=1 : proc_action(2) when 4: NoCh&=0 : Rev&=1 : proc_action(3) when 5: NoCh&=0 : Rev&=1 : proc_action(4) when 6: NoCh&=0 : Rev&=1 : proc_action(5) when 7: NoCh&=0 : Rev&=1 : proc_action(6) when 8: NoCh&=0 : Rev&=1 : proc_action(7) when 9: NoCh&=0 : Rev&=1 : proc_action(8) when 10: proc_revert when 11: proc_original when 12: proc_save(Name$,"N",picworkold%,clgth%,Newpic$) when 13: rem Exit loop and QUIT endcase until Ch&=Buts& quit rem End of Program ============================================= rem ============================================================ rem Set up initial screen def proc_setup local a&,b& rem Maximise screen proc_maxim(xscreen%,yscreen%) : colour 132,0,50,50 : colour 132: cls rem Change the Windows Title title$ = " PHOTO EDITOR" sys "SetWindowText", @hwnd%, title$ Flg&=1 : rem 1=use original 2=work on revised Buts&=13 : rem Number of buttons Frst&=1 : rem Frst&=1 indicates no base picture yet selected NoCh&=1 : rem NoCh&=1 indicates no processing yet taken place Rev&=0 : rem No Revert NoCut&=1 : rem NoCut&=1 indicates no cut has taken place MaxL%=3024*4032*3 + 54 : rem Maxmimum length of bitmap data rem Standard grey-scale weightings wr=0.299 : wg=0.587 : wb=0.114 dim conv(2,2), cinv(2,2), rgb(2), yuv(2), cum(2) rem Read in RGB/YUV conversion data restore for a&=0 to 2 for b&=0 to 2 read conv(a&,b&) next b& next a& conv()*=1.0 for a&=0 to 2 for b&=0 to 2 read cinv(a&,b&) next b& next a& cinv()*=1.0 rem Set up THREE maximum size mirror bitmaps according proc_BMP_Set(4032,3024,picorig%,ntused%,ntused%) proc_BMP_Set(4032,3024,picworkold%,ntused%,ntused%) proc_BMP_Set(4032,3024,picworknew%,ntused%,ntused%) endproc rem ============================================================ rem RGB / YUV Conversion factors data 0.299,0.587,0.114,-0.14713,-0.28886,0.436,0.615,-0.51499,-0.10001 data 1.0,0.0,1.13983,1.0,-0.39465,-0.58060,1.0,2.03211,0.0 rem ============================================================ rem ASM setup def proc_setup2 local pass& dim cut% 1000, desaturate% 1000, saturate% 1000, contrast% 2000, blur% 1500, itmp% 3 dim Despeck% 1000, median% 500, grid% 26, stat% 26, grey% 1000 rem Various constants i4%=4 i5%=5 i255%=255 f2=1.75 f05=0.5 f11=1.1 i24%=24 i8%=8 i9%=9 rem Dual-pass assembly, in case of labels for pass&=0 to 2 step 2 proc_Desat(pass&) proc_Satur(pass&) proc_Contra(pass&) proc_Blur(pass&) proc_Cut(pass&) proc_Despeck(pass&) proc_Median(pass&) proc_Grey(pass&) next pass& endproc rem ============================================================ rem Select an action def fn_select local a& msg$="\3MENU OF EDITOR FUNCTIONS" proc_msg("Georgia",12,"B",50,fn_adapt(1,1500),msg$) msg$="\2======================================" proc_msg("Georgia",12,"",50,fn_adapt(1,1450),msg$) if Flg&=1 then dim butt{ch$(Buts&),state&(Buts&)} rem Button messages butt.ch$(1)="\3Select \2NEW \3picture" butt.ch$(2)="\3Crop" butt.ch$(3)="\3Contrast" butt.ch$(4)="\3Desaturate" butt.ch$(5)="\3Saturate" butt.ch$(6)="\3Sharpen" butt.ch$(7)="\3Smooth" butt.ch$(8)="\3Despeckle" butt.ch$(9)="\3GreyScale" butt.ch$(10)="\3Undo" butt.ch$(11)="\3Original" butt.ch$(12)="\2SAVE \3current picture" butt.ch$(13)="\1EXIT" rem Disallow functions before picture selected if Frst&=1 then butt.state&(1)=1 butt.state&(2)=0 butt.state&(3)=0 butt.state&(4)=0 butt.state&(5)=0 butt.state&(6)=0 butt.state&(7)=0 butt.state&(8)=0 butt.state&(9)=0 butt.state&(10)=0 butt.state&(11)=0 butt.state&(12)=0 butt.state&(13)=1 else for a&=1 to Buts& butt.state&(a&)=1 next a& if NoCh&=1 then butt.state&(10)=0 : butt.state&(11)=0 : butt.state&(12)=0 if NoCut&=0 then butt.state&(2)=0 butt.state&(10)=Rev& endif else rem Reset all other functions to be allowed for a&=1 to Buts& butt.state&(a&)=1 next a& butt.state(10)=Rev& endif cc&=0 repeat rem Get reference for a pressed button cc&=fn_getbut("Georgia",12,"",butt{},50,fn_adapt(1,1300),100,Buts&) sys "Sleep",10 until cc&<>0 =cc& rem ================================================================== rem Select the initial picture def proc_initial local pic% OK&=2 rem Choose a picture to work with, and convert to .bmp proc_pichoose(OK&,Name$,FulName$,Pre$,wdth%,hght%,lgth%) case OK& of when 1: rem Revise current parameters proc_pars(wdth%,hght%,lgth%) rem Display it "as is" proc_scale(3*xscreen%/4,3*yscreen%/4,wdth%,hght%,xbo%,ybo%,xwo%,yho%) xso%=xscreen%/4+xbo% : yso%=yscreen%/8+ybo% xs%=xso% : ys%=yso% xw%=xwo% : yh%=yho% proc_BMP_Disp(xw%,yh%,picorig%,xs%,ys%) rem Copy a fixed number of bytes to another location proc_recopy(picorig%,picworkold%,lgth%) proc_recopy(picorig%,picworknew%,lgth%) Temp$=Pre$+"Temp.bmp" Frst&=0 : NoCut&=1 : NoCh&=1 : Rev&=0 when 0: sys "MessageBox", @hwnd%, "Image too large!! Pick another.", "ERROR!!", 48 endcase endproc rem ================================================================== rem Revise current parameters def proc_pars(w%,h%,l%) local st% st%=(w%*3+3)and-4 clgth%=l% : cwdth%=w% : chght%=h% : Clim%=st% endproc rem ================================================================== rem Original picture def proc_original *REFRESH OFF colour 10,0,50,50 : gcol 10 : rectangle fill xscreen%/2-5,yscreen%/4-5,3*xscreen%/2+10,3*yscreen%/2+10 rem Copy a fixed number of bytes to another location proc_recopy(picorig%,picworkold%,lgth%) proc_recopy(picorig%,picworknew%,lgth%) rem Display original picture xs%=xso% : ys%=yso% xw%=xwo% : yh%=yho% proc_BMP_Disp(xw%,yh%,picworkold%,xs%,ys%) *REFRESH *REFRESH ON rem Revise current parameters proc_pars(wdth%,hght%,lgth%) Rev&=0 : NoCh&=1 : NoCut&=1 endproc rem ================================================================== rem Previous picture def proc_revert local wd%,hg%,lh%,lim% *REFRESH OFF Newpic$="temp.bmp" command$=" LOAD "+chr$(34) + Newpic$ +chr$(34) +str$~picworkold%+" +"+str$~(lgth%) oscli command$ colour 10,0,50,50 : gcol 10 : rectangle fill xscreen%/2-5,yscreen%/4-5,3*xscreen%/2+10,3*yscreen%/2+10 rem Display previous picture wd%=!(picworkold% + 18) hg%=!(picworkold% + 22) lh%=!(picworkold% + 2) lim%=((wd%*3+3)and-4) rem Redo scaling proc_scale(3*xscreen%/4,3*yscreen%/4,wd%,hg%,xb%,yb%,xw%,yh%) xs%=xscreen%/4+xb% : ys%=yscreen%/8+yb% rem Display previous picture proc_BMP_Disp(xw%,yh%,picworkold%,xs%,ys%) *REFRESH *REFRESH ON rem Ensure picworknew has reverted header proc_recopy(picworkold%,picworknew%,lh%) rem Revise current parameters proc_pars(wd%,hg%,lh%) Rev&=0 endproc rem ================================================================== rem Actions def proc_action(Ctr&) rem Save old picture temporarily to disc proc_tempsave(picworkold%,lgth%) rem Perform chosen action case Ctr& of when 1 : proc_crop(clgth%) when 2 : call contrast% when 3 : call desaturate% when 4 : call saturate% when 5 : shrp&=1 : call blur% when 6 : shrp&=0 : call blur% when 7 : call Despeck% when 8 : call grey% endcase rem Show new picture proc_show(clgth%) endproc rem ================================================================== rem Crop the image def proc_crop(return lgcut%) rem Select crop region proc_zoom(xs%,ys%,xw%,yh%,lx%,ly%,ux%,uy%) rem Convert to units to access the source bmp sx%=int((lx%-2*xs%)*wdth%/(2*xw%)) : sy%=int((ly%-2*ys%)*hght%/(2*yh%)) ex%=int((ux%-2*xs%)*wdth%/(2*xw%)) : ey%=int((uy%-2*ys%)*hght%/(2*yh%)) rem Provide working bitmap with a revised header wdcut%=ex%-sx% : hgcut%=ey%-sy% proc_bmpheader(wdcut%,hgcut%,picworknew%,Wcut%,lgcut%) call cut% rem Revise current parameters proc_pars(wdcut%,hgcut%,lgcut%) NoCut&=0 rem Redo scaling proc_scale(3*xscreen%/4,3*yscreen%/4,wdcut%,hgcut%,xb%,yb%,xw%,yh%) xs%=xscreen%/4+xb% : ys%=yscreen%/8+yb% endproc rem ======================================================================== rem Enables user to zoom into a particular area def proc_zoom(Xs%,Ys%,Xw%,Yh%, return lx%, return ly%, return ux%, return uy%) local w%,h%,b&,ax%,cx%,ay%,cy% mouse on 3 : gcol 3 mouse rectangle 2*Xs%,2*Ys%,2*Xw%,2*Yh% *REFRESH OFF rem Select first corner of rectangular zoom area repeat mouse w%,h%,b& sys "Sleep",10 until b&=4 ax%=w% : ay%=h% rem Print a "+" at the first corner move ax%-10,ay% : draw ax%+10,ay% move ax%,ay%-10 : draw ax%,ay%+10 rem Select opposite corner of zoom area cx%=-1 : cy%=-1 : rem Initialise opposite corner points repeat mouse w%,h%,b& sys "Sleep",10 if (cx%<>w% or cy%<>h%) then cx%=w% : cy%=h% cls : proc_BMP_Disp(Xw%,Yh%,picworkold%,Xs%,Ys%) move ax%,ay% : draw cx%,ay% : draw cx%,cy% draw ax%,cy% : draw ax%,ay% *REFRESH endif until b&=1 *REFRESH rem Re-assign corner points in ascending order if ax%0 then fullname$ = $$fm% else quit rn%=len(fullname$) g%=0 : pic$="" repeat n$=mid$(fullname$,rn%-g%,1) if n$<>"\" then pic$=n$+pic$ : g%+=1 until n$="\" Pre$=left$(fullname$,rn%-g%) rem Change the current Directory command$="CD "+chr$(34)+Pre$+chr$(34) oscli command$ Name$=pic$ : FulName$=Pre$+Name$ rem Read in a picture as a bitmap proc_read_as_bmp(OK&,FulName$,wdth%,hght%,lgth%) endproc rem--------------------------------------------------------------------- rem Reads a picture as a BMP def proc_read_as_bmp(return OK&,fil$, return Ww%, return Hh%, return lgth%) local bm%, G% dim temp% 255, bm% 86 bm% = (bm% + 3) and -4 : rem Ensures bm% is a multiple of FOUR sys "MultiByteToWideChar", 0, 0, fil$, len(fil$), temp%, 256 sys "LoadLibrary", "OLEAUT32.DLL" to oleaut32% sys "GetProcAddress", oleaut32%, "OleLoadPicturePath" to olpp% I% = &7BF80980 : rem. 128-bit iid J% = &101ABF32 K% = &AA00BB8B L% = &AB0C3000 sys olpp%, temp%, 0, 0, 0, ^I%, ^G% : rem. OleLoadPicturePath if G% = 0 error 0, "Cannot load file """+fil$+"""" sys !(!G%+12), G%, ^hbm% : rem. IPicture::get_Handle sys "GetObject", hbm%, 84, bm% Ww% = bm%!4 Hh% = bm%!8 lgth% = 54+Hh%*((Ww%*3+3)and-4) if lgth%<=MaxL% then P% = picorig% [OPT 0 DB "BM" ; Signature DD lgth% ; Total file bytes DD 0 ; Set t0 zero DD 54 ; Header bytes DD 40 ; Offset t0 Data DD Ww% ; Image Width DD Hh% ; Image Height DW 1 ; Bit planes DW 24 ; Colour depth in bits DD 0 ; Compression type=0=none DD lgth%-54 ; Image size net 0f header DD 0 ; Set t0 zero DD 0 ; Set t0 zero DD 0 ; Set t0 zero DD 0 ; Set t0 zero ] sys "GetDIBits", @memhdc%, hbm%, 0, Hh%, picorig%+54, picorig%+14, 0 OK&=1 else OK&=0 endif sys !(!G%+8), G% : rem. IPicture::Release endproc rem =============================================================== rem Desaturate Routine def proc_Desat(opt&) P%=desaturate% [opt opt& mov edx,0 mov [^y%],edx .dyloop mov eax,[^y%] imul eax,[^Clim%] add eax,54 mov edx,0 mov [^x%],edx .dxloop mov [^ref%],eax mov ebx,0 mov bl,picworkold%[eax] mov [^b&],bl mov [itmp%],ebx fild dword [itmp%] fld qword [^wb] fmulp st1,st0 mov bl,picworkold%[eax+1] mov [^g&],bl mov [itmp%],ebx fild dword [itmp%] fld qword [^wg] fmulp st1,st0 mov bl,picworkold%[eax+2] mov [^r&],bl mov [itmp%],ebx fild dword [itmp%] fld qword [^wr] fmulp st1,st0 faddp st1,st0 faddp st1,st0 fstp qword [^v] mov bl,[^b&] mov [itmp%],ebx fild dword [itmp%] fild dword [^i4%] fmulp st1,st0 fld qword [^v] faddp st1,st0 fild dword [^i5%] fdivp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] mov picworknew%[eax],bl mov bl,[^g&] mov [itmp%],ebx fild dword [itmp%] fild dword [^i4%] fmulp st1,st0 fld qword [^v] faddp st1,st0 fild dword [^i5%] fdivp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] mov picworknew%[eax+1],bl mov bl,[^r&] mov [itmp%],ebx fild dword [itmp%] fild dword [^i4%] fmulp st1,st0 fld qword [^v] faddp st1,st0 fild dword [^i5%] fdivp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] mov picworknew%[eax+2],bl add eax,3 inc dword [^x%] mov edx,[^x%] cmp edx,[^cwdth%] jb near dxloop inc dword [^y%] mov edx,[^y%] cmp edx,[^chght%] jb near dyloop ret ] endproc rem ====================================================================== rem Coded into ASM def proc_dump_Desat for y%=0 to hght%-1 for x%=0 to wdth%-1 ref%=y%*Wlim% + 3*x% + 54 b&=?(picworkold% + ref%) g&=?(picworkold% + ref% + 1) r&=?(picworkold% + ref% + 2) v=wr*r& + wg*g& + wb*b& b&=int((4*b&+v)/5) g&=int((4*g&+v)/5) r&=int((4*r&+v)/5) ?(picworknew% + ref%) = b& ?(picworknew% + ref% + 1) = g& ?(picworknew% + ref% + 2) = r& next x% next y% endproc rem ====================================================================== rem Desaturate Routine def proc_Satur(opt&) P%=saturate% [opt opt& mov edx,0 mov [^y%],edx .syloop mov eax,[^y%] imul eax,[^Clim%] add eax,54 mov edx,0 mov [^x%],edx .sxloop mov [^ref%],eax mov ebx,0 mov bl,picworkold%[eax] mov [itmp%],ebx fild dword [itmp%] fld qword [^wb] fmulp st1,st0 mov bl,picworkold%[eax+1] mov [itmp%],ebx fild dword [itmp%] fld qword [^wg] fmulp st1,st0 mov bl,picworkold%[eax+2] mov [itmp%],ebx fild dword [itmp%] fld qword [^wr] fmulp st1,st0 faddp st1,st0 faddp st1,st0 fstp qword [^v] mov ebx,0 mov bl,picworkold%[eax] mov [itmp%],ebx fild dword [itmp%] fild dword [^i5%] fmulp st1,st0 fld qword [^v] fsubp st1,st0 fild dword [^i4%] fdivp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] cmp ebx,255 jle bhok mov ebx,255 jmp blok .bhok cmp ebx,0 jge blok mov ebx,0 .blok mov picworknew%[eax],bl mov ebx,0 mov bl,picworkold%[eax+1] mov [itmp%],ebx fild dword [itmp%] fild dword [^i5%] fmulp st1,st0 fld qword [^v] fsubp st1,st0 fild dword [^i4%] fdivp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] cmp ebx,255 jle ghok mov ebx,255 jmp glok .ghok cmp ebx,0 jge glok mov ebx,0 .glok mov picworknew%[eax+1],bl mov ebx,0 mov bl,picworkold%[eax+2] mov [itmp%],ebx fild dword [itmp%] fild dword [^i5%] fmulp st1,st0 fld qword [^v] fsubp st1,st0 fild dword [^i4%] fdivp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] cmp ebx,255 jle rhok mov ebx,255 jmp rlok .rhok cmp ebx,0 jge rlok mov ebx,0 .rlok mov picworknew%[eax+2],bl add eax,3 inc dword [^x%] mov edx,[^x%] cmp edx,[^cwdth%] jb near sxloop inc dword [^y%] mov edx,[^y%] cmp edx,[^chght%] jb near syloop ret ] endproc rem ====================================================================== rem Coded into ASM def proc_dump_Satur for y%=0 to hght%-1 for x%=0 to wdth%-1 ref%=y%*Wlim% + 3*x% + 54 b&=?(picworkold% + ref%) g&=?(picworkold% + ref% + 1) r&=?(picworkold% + ref% + 2) v=wr*r& + wg*g& + wb*b& b%=int((5*b&-v)/4) g%=int((5*g&-v)/4) r%=int((5*r&-v)/4) if b%>255 then b%=255 if g%>255 then g%=255 if r%>255 then r%=255 if b%<0 then b%=0 if g%<0 then g%=0 if r%<0 then r%=0 b&=b% : g&=g% : r&=r% ?(picworknew% + ref%) = b& ?(picworknew% + ref% + 1) = g& ?(picworknew% + ref% + 2) = r& next x% next y% endproc rem ====================================================================== rem Contrast Routine def proc_Contra(opt&) P%=contrast% [opt opt& mov edx,0 mov [^y%],edx .cyloop mov eax,[^y%] imul eax,[^Clim%] add eax,54 mov edx,0 mov [^x%],edx .cxloop mov [^ref%],eax finit mov ebx,0 mov bl,picworkold%[eax] mov [itmp%],ebx fild dword [itmp%] fild dword [^i255%] fdivp st1,st0 fstp qword [^rgb(2)] mov bl,picworkold%[eax+1] mov [itmp%],ebx fild dword [itmp%] fild dword [^i255%] fdivp st1,st0 fstp qword [^rgb(1)] mov bl,picworkold%[eax+2] mov [itmp%],ebx fild dword [itmp%] fild dword [^i255%] fdivp st1,st0 fstp qword [^rgb(0)] fldz fst qword [^yuv(0)] fst qword [^yuv(1)] fstp qword [^yuv(2)] mov dl,0 mov [^aa&],dl .aaloop mov dl,0 mov [^bb&],dl .bbloop mov eax,0 mov al,[^aa&] imul eax,24 mov ebx,0 mov bl,[^bb&] shl ebx,3 add eax,ebx fld qword (^conv(0,0))[eax] mov ebx,0 mov bl,[^bb&] shl bl,3 fld qword (^rgb(0))[ebx] fmulp st1,st0 mov eax,0 mov al,[^aa&] shl al,3 fld qword (^yuv(0))[eax] faddp st1,st0 fstp qword (^yuv(0))[eax] inc byte [^bb&] mov dl,[^bb&] cmp dl,2 jbe near bbloop inc byte [^aa&] mov dl,[^aa&] cmp dl,2 jbe near aaloop fld qword [^yuv(0)] fld qword [^f05] fsubp st1,st0 fld qword [^f11] fmulp st1,st0 fld qword [^f05] faddp st1,st0 fstp qword [^yuv(0)] fldz fst qword [^rgb(0)] fst qword [^rgb(1)] fstp qword [^rgb(2)] mov dl,0 mov [^a&],dl .aloop mov dl,0 mov [^b&],dl .bloop mov eax,0 mov al,[^a&] imul eax,24 mov ebx,0 mov bl,[^b&] shl ebx,3 add eax,ebx fld qword (^cinv(0,0))[eax] mov ebx,0 mov bl,[^b&] shl bl,3 fld qword (^yuv(0))[ebx] fmulp st1,st0 mov eax,0 mov al,[^a&] shl al,3 fld qword (^rgb(0))[eax] faddp st1,st0 fstp qword (^rgb(0))[eax] inc byte [^b&] mov dl,[^b&] cmp dl,2 jbe near bloop inc byte [^a&] mov dl,[^a&] cmp dl,2 jbe near aloop mov eax,[^ref%] fld qword [^rgb(2)] fild dword [^i255%] fmulp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] cmp ebx,255 jle bbhok mov ebx,255 jmp bblok .bbhok cmp ebx,0 jge bblok mov ebx,0 .bblok mov picworknew%[eax],bl fld qword [^rgb(1)] fild dword [^i255%] fmulp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] cmp ebx,255 jle gghok mov ebx,255 jmp gglok .gghok cmp ebx,0 jge gglok mov ebx,0 .gglok mov picworknew%[eax+1],bl fld qword [^rgb(0)] fild dword [^i255%] fmulp st1,st0 fistp dword [itmp%] mov ebx,[itmp%] cmp ebx,255 jle rrhok mov ebx,255 jmp rrlok .rrhok cmp ebx,0 jge rrlok mov ebx,0 .rrlok mov picworknew%[eax+2],bl add eax,3 inc dword [^x%] mov edx,[^x%] cmp edx,[^cwdth%] jb near cxloop inc dword [^y%] mov edx,[^y%] cmp edx,[^chght%] jb near cyloop ret ] endproc rem ====================================================================== rem Coded into ASM def proc_dump_Contra for y%=0 to hght%-1 for x%=0 to wdth%-1 ref%=y%*Wlim% + 3*x% + 54 rgb(2)=(?(picworkold% + ref%))/255 rgb(1)=(?(picworkold% + ref% + 1))/255 rgb(0)=(?(picworkold% + ref% + 2))/255 yuv()=0.0 for a&=0 to 2 for b&=0 to 2 yuv(a&)+=conv(a&,b&)*rgb(b&) next b& next a& y=yuv(0) : rem DONE y=0.5 + (y-0.5)*1.1 : rem DONE if y>1.0 then y=1.0 : rem DONE if y<0.0 then y=0.0 : rem DONE yuv(0)=y : rem DONE rgb()=0.0 : rem DONE for a&=0 to 2 : rem DONE for b&=0 to 2 : rem DONE rgb(a&)+=cinv(a&,b&)*yuv(b&) : rem DONE next b& next a& b%=int(rgb(2)*255) : rem DONE g%=int(rgb(1)*255) : rem DONE r%=int(rgb(0)*255) : rem DONE if b%>255 then b%=255 : rem DONE if g%>255 then g%=255 : rem DONE if r%>255 then r%=255 : rem DONE if b%<0 then b%=0 : rem DONE if g%<0 then g%=0 : rem DONE if r%<0 then r%=0 : rem DONE b&=b% : g&=g% : r&=r% : rem DONE ?(picworknew% + ref%) = b& : rem DONE ?(picworknew% + ref% + 1) = g& : rem DONE ?(picworknew% + ref% + 2) = r& : rem DONE next x% next y% endproc rem ====================================================================== rem Blur OR Sharpen Routine def proc_Blur(opt&) P%=blur% [opt opt& mov edx,1 mov [^y%],edx .blyloop mov edx,1 mov [^x%],edx .blxloop mov eax,[^y%] imul eax,[^Clim%] add eax,[^x%] add eax,[^x%] add eax,[^x%] add eax,54 mov [^ref%],eax finit fldz fst qword [^cum(0)] fst qword [^cum(1)] fstp qword [^cum(2)] mov edx,-1 mov [^a%],edx .laloop mov edx,-1 mov [^b%],edx .lbloop mov eax,[^b%] imul eax,[^Clim%] add eax,[^a%] add eax,[^a%] add eax,[^a%] add eax,[^ref%] mov ecx,0 mov cl,picworkold%[eax] mov [itmp%],ecx fild dword [itmp%] fld qword [^cum(0)] faddp st1,st0 fstp qword [^cum(0)] mov cl,picworkold%[eax+1] mov [itmp%],ecx fild dword [itmp%] fld qword [^cum(1)] faddp st1,st0 fstp qword [^cum(1)] mov cl,picworkold%[eax+2] mov [itmp%],ecx fild dword [itmp%] fld qword [^cum(2)] faddp st1,st0 fstp qword [^cum(2)] inc dword [^b%] mov edx,[^b%] cmp edx,1 jle near lbloop inc dword [^a%] mov edx,[^a%] cmp edx,1 jle near laloop fild dword [^i9%] fld qword [^cum(0)] fdiv st0,st1 fistp dword [^bb%] fld qword [^cum(1)] fdiv st0,st1 fistp dword [^gg%] fld qword [^cum(2)] fdivrp st1,st0 fistp dword [^rr%] mov al,[^shrp&] cmp al,1 jne smooth mov eax,[^ref%] mov ecx,0 mov cl,picworkold%[eax] shl ecx,1 sub ecx,[^bb%] mov [^bb%],ecx mov ecx,0 mov cl,picworkold%[eax+1] shl ecx,1 sub ecx,[^gg%] mov [^gg%],ecx mov ecx,0 mov cl,picworkold%[eax+2] shl ecx,1 sub ecx,[^rr%] mov [^rr%],ecx .smooth mov ebx,[^bb%] cmp ebx,255 jle pphok mov ebx,255 jmp pplok .pphok cmp ebx,0 jge pplok mov ebx,0 .pplok mov [^bb&],bl mov ebx,[^gg%] cmp ebx,255 jle qqhok mov ebx,255 jmp qqlok .qqhok cmp ebx,0 jge qqlok mov ebx,0 .qqlok mov [^gg&],bl mov ebx,[^rr%] cmp ebx,255 jle sshok mov ebx,255 jmp sslok .sshok cmp ebx,0 jge sslok mov ebx,0 .sslok mov [^rr&],bl mov eax,[^ref%] mov cl,[^bb&] mov picworknew%[eax],cl mov cl,[^gg&] mov picworknew%[eax+1],cl mov cl,[^rr&] mov picworknew%[eax+2],cl inc dword [^x%] mov edx,[^x%] mov ecx,[^cwdth%] dec ecx cmp edx,ecx jb near blxloop inc dword [^y%] mov edx,[^y%] mov ecx,[^chght%] dec ecx cmp edx,ecx jb near blyloop ret ] endproc rem ====================================================================== rem Coded into ASM def proc_dump_Blur for y%=1 to hght%-2 : rem DONE for x%=1 to wdth%-2 : rem DONE cum()=0.0 : rem DONE for a%=-1 to 1 : rem DONE for b%=-1 to 1 : rem DONE dref%=ref% + b%*Clim% + 3*a% : rem DONE bb&=?(picworkold%+dref%) : rem DONE cum(0)+=bb& : rem DONE gg&=?(picworkold%+dref%+1) : rem DONE cum(1)+=gg& : rem DONE rr&=?(picworkold%+dref%+2) : rem DONE cum(2)+=rr& : rem DONE next b% next a% cum()/=9 : rem DONE bb%=int(cum(0)) : rem DONE gg%=int(cum(1)) : rem DONE rr%=int(cum(2)) : rem DONE if bb%>255 then bb%=255 : rem DONE if gg%>255 then gg%=255 : rem DONE if gg%>255 then gg%=255 : rem DONE if bb%<0 then bb%=0 : rem DONE if gg%<0 then gg%=0 : rem DONE if rr%<0 then rr%=0 : rem DONE bb&=bb% : gg&=gg% : rr&=rr% : rem DONE ref%=y%*Clim% + 3*x% + 54 : rem DONE ?(picworknew% + ref%) = bb& : rem DONE ?(picworknew% + ref% + 1) = gg& : rem DONE ?(picworknew% + ref% + 2) = rr& : rem DONE next x% next y% endproc rem ====================================================================== rem BMP Cut Routine def proc_Cut(opt&) P%=cut% [opt opt& mov edx,0 mov [^yy%],edx .yloop mov edx,0 mov [^xx%],edx .xloop mov eax,[^yy%] add eax,[^sy%] imul eax,[^Clim%] add eax,[^xx%] add eax,[^sx%] add eax,[^xx%] add eax,[^sx%] add eax,[^xx%] add eax,[^sx%] add eax,54 mov ebx,eax mov eax,[^yy%] imul eax,[^Wcut%] add eax,[^xx%] add eax,[^xx%] add eax,[^xx%] add eax,54 mov cl,picworkold%[ebx] mov picworknew%[eax],cl mov cl,picworkold%[ebx+1] mov picworknew%[eax+1],cl mov cl,picworkold%[ebx+2] mov picworknew%[eax+2],cl inc dword [^xx%] ;x loop control mov edx,[^xx%] mov ebx,[^wdcut%] cmp edx,ebx jl near xloop inc dword [^yy%] mov edx,[^yy%] ;y loop control mov ebx,[^hgcut%] cmp edx,ebx jl near yloop ret ] endproc rem ====================================================================== rem Copy the cut-out area to a sub-bmp def proc_dump hgcut%=ey%-sy% : wdcut%=ex%-sx% for yy%=0 to hgcut% for xx%=0 to wdcut% refs%=54 + (sy% + yy%)*Wlim% + 3*(sx% + xx%) refd%=54 + yy%*Wcut% + 3*xx% for n&=0 to 2 ?(cutpic% + refd% + n&) =?(pf% + refs% + n&) next n& next xx% next yy% endproc rem ====================================================================== rem BMP Update Routine def proc_Despeck(opt&) P%=Despeck% [opt opt& mov edx,0 mov [^y%],edx .qyloop mov edx,0 mov [^x%],edx .qxloop mov edx,0 mov [^k%],edx mov edx,0 mov [^i&],dl mov eax,0 mov cl,0 .iloop1 ;Initialise status array mov al,[^i&] mov stat%[eax],cl inc byte [^i&] mov dl,[^i&] cmp dl,26 jbe near iloop1 ;Initialise status array .kloop mov edx,0 mov [^j%],edx .jloop mov eax,[^y%] add eax,[^k%] imul eax,[^Clim%] mov ebx,[^x%] add ebx,[^j%] add eax,ebx add eax,ebx add eax,ebx add eax,54 mov ebx,eax mov eax,[^k%] imul eax,9 add eax,[^j%] add eax,[^j%] add eax,[^j%] mov cl,picworkold%[ebx] mov grid%[eax],cl mov cl,picworkold%[ebx+1] mov grid%[eax+1],cl mov cl,picworkold%[ebx+2] mov grid%[eax+2],cl inc dword [^j%] mov edx,[^j%] cmp edx,2 jle near jloop inc dword [^k%] mov edx,[^k%] cmp edx,2 jle near kloop ;SECTION TWO mov dl,0 mov [^i&],dl .iloop2 mov cl,255 mov [^medb&],cl mov [^medg&],cl mov [^medr&],cl call median% inc byte [^i&] mov dl,[^i&] cmp dl,5 jbe near iloop2 mov eax,[^y%] imul eax,[^Clim%] add eax,[^x%] add eax,[^x%] add eax,[^x%] add eax,54 mov bl,[^medb&] mov picworknew%[eax],bl mov bl,[^medg&] mov picworknew%[eax+1],bl mov bl,[^medr&] mov picworknew%[eax+2],bl inc dword [^x%] ;x loop control mov edx,[^x%] mov ebx,[^cwdth%] dec ebx dec ebx cmp edx,ebx jl near qxloop inc dword [^y%] mov edx,[^y%] ;y loop control mov ebx,[^chght%] dec ebx dec ebx cmp edx,ebx jl near qyloop ret ] endproc rem ====================================================================== rem Median function def proc_Median(opt&) P%=median% [opt opt& mov dl,0 mov [^m&],dl mov eax,0 .mloop mov al,[^m&] imul eax,3 mov bl,stat%[eax] cmp bl,0 jne miss0 mov cl,grid%[eax] cmp cl,[^medb&] ja miss0 mov [^medb&],cl mov [^indb&],al .miss0 mov bl,stat%[eax+1] cmp bl,0 jne miss1 mov cl,grid%[eax+1] cmp cl,[^medg&] ja miss1 mov [^medg&],cl mov [^indg&],al .miss1 mov bl,stat%[eax+2] cmp bl,0 jne miss2 mov cl,grid%[eax+2] cmp cl,[^medr&] ja miss2 mov [^medr&],cl mov [^indr&],al .miss2 inc byte [^m&] mov dl,[^m&] cmp dl,8 jbe near mloop mov ebx,0 mov cl,1 mov bl,[^indb&] mov stat%[ebx],cl mov bl,[^indg&] mov stat%[ebx+1],cl mov bl,[^indr&] mov stat%[ebx+2],cl ret ] endproc rem ====================================================================== rem Greyscale Conversion - Assembly Routine def proc_Grey(opt&) P%=grey% [opt opt& mov edx,0 mov [^j%],edx .qjloop mov edx,0 mov [^k%],edx .qkloop mov eax,[^j%] imul eax,[^Clim%] add eax,[^k%] add eax,[^k%] add eax,[^k%] add eax,54 finit mov ecx,0 mov cl,picworkold%[eax] mov [itmp%],ecx fild dword [itmp%] fld qword [^wb] fmulp st1,st0 mov cl,picworkold%[eax+1] mov [itmp%],ecx fild dword [itmp%] fld qword [^wg] fmulp st1,st0 faddp st1,st0 mov cl,picworkold%[eax+2] mov [itmp%],ecx fild dword [itmp%] fld qword [^wr] fmulp st1,st0 faddp st1,st0 fistp dword [^avg%] ;Use standard rgb weights f0r greyscale conversion mov ebx,[^avg%] cmp ebx,255 jle vok mov ebx,255 mov [^avg%],ebx .vok mov cl,[^avg%] mov picworknew%[eax],cl mov picworknew%[eax+1],cl mov picworknew%[eax+2],cl inc dword [^k%] mov edx,[^k%] cmp edx,[^cwdth%] jl near qkloop inc dword [^j%] mov edx,[^j%] cmp edx,[^chght%] jl near qjloop ret ] endproc rem =========================================================================================================