filtre convolution

Pour discuter de l'assembleur
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

filtre convolution

Message par manababel »

Bonjour

ci-dessous trois programmes qui font la même chose
1- Filter_ConvolV1_Pb filtre standard sans optimisation en purebasic ( le plus simple mais le plus lent)
2- Filter_ConvolV2_Pb filtre standard optimisé en purebasic ( presque 2 fois plus rapide que la Ver. 1 )
3-Filters_ConvolV2_ASM la conversion du filtre 'Filter_ConvolV2_Pb' en ASM ( 3 fois plus rapide que la Ver. 2 )

il existe deux autres façons de faire un filtre de convolution 2d plus optimisé.
1- le Fft ( Fast Fourier transform)
2- mixés 2 convolutions 1d
pour le moment je ne sais faire ni l'un ni l'autre.

toute la dernière partie du programme "data section" est une copie d'un programme sur le site ci-dessous
https://www.purebasic.fr/english/viewto ... 12&t=68204

Code : Tout sélectionner

EnableExplicit

Global Dim Reg_memory.q(4*344)

; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
  Protected source_p , cible_p , s.q
  Protected lg.q , ht.q , taille.q , depth.q

  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
   
  StartDrawing(ImageOutput(nom))
  source_p = DrawingBuffer()
  ht = ImageHeight(nom)
  lg = ImageWidth(nom)
  Depth=OutputDepth()
  StopDrawing()

  If Depth=24
    taille=lg*ht
    cible_p=AllocateMemory(taille*4)
    Dim save.q(4)
    s=@save()
    EnableASM
      !mov rax,[p.v_s]
      !mov [rax],rcx
      !mov [rax+8],rdx
      !mov [rax+16],r8
      !mov rcx,[p.v_source_p]
      !mov rdx,[p.v_cible_p]
      !mov r8,[p.v_taille]
      !sub r8,1 ; <---------------- ????
      !copy_boucle24:
        !mov eax,[rcx]     
        !mov [rdx],eax
        !add rcx,3
        !add rdx,4
        !dec r8
       !jnz copy_boucle24
      !mov rax,[p.v_s]
      !mov rcx,[rax]
      !mov rdx, [rax+8]
      !mov r8,[rax+16]
    DisableASM
    FreeArray(save())
   
    FreeImage(nom) ; supprime l'image 24bits
    CreateImage(nom,lg,ht,32)
    StartDrawing(ImageOutput(nom))
    source_p = DrawingBuffer()
    StopDrawing()
    CopyMemory( cible_p , source_p , taille*4 )
    FreeMemory(cible_p)
  EndIf
 
  ProcedureReturn 1
EndProcedure




; partie du programme à modifier pour adapter se programme au votre
; convertie les "IDs" des images en pointer d'adresse
; test si les images sont en 32bits et de la meme taille
;-------------------------------------------------------------------

Macro sp(source,cible)
  Protected Depth.q , lg.q , ht.q , lg1.q , ht1.q , taille.q
  Protected cible_p.q , source_p.q

  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht1 = ImageHeight(cible)
  lg1 = ImageWidth(cible)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf

  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht = ImageHeight(source)
  lg = ImageWidth(source)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf

  If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf

  taille = lg * ht
EndMacro

Macro clampRGB(r,g,b)
  If r<0:r=0:EndIf
  If g<0:g=0:EndIf
  If b<0:b=0:EndIf
  If r>255:r=255:EndIf
  If g>255:g=255:EndIf
  If b>255:b=255:EndIf
EndMacro

Macro returnRGB(pixel,r,g,b)
    r=(pixel & $ff0000)>>16
    g=(pixel & $ff00)>>8
    b=(pixel & $ff)
  EndMacro

;-------------------------------------------------------------------
; sauvegarde de registres
Macro Save_reg()
  s=@reg_memory()
  EnableASM
  !mov rax,[p.v_s]
  !mov [rax+000],rbx
  !mov [rax+008],rcx ;
  !mov [rax+016],rdx ;
  !mov [rax+024],rsi
  !mov [rax+032],rdi
  !mov [rax+040],r8 ;
  !mov [rax+048],r9 ;
  !mov [rax+056],r10
  !mov [rax+064],r11
  !mov [rax+072],r12
  !mov [rax+080],r13
  !mov [rax+088],r14
  !mov [rax+096],r15

  !movdqu [rax+104],xmm0 ;
  !movdqu [rax+120],xmm1 ;
  !movdqu [rax+136],xmm2 ;
  !movdqu [rax+152],xmm3 ;
  !movdqu [rax+168],xmm4
  !movdqu [rax+184],xmm5
  !movdqu [rax+200],xmm6
  !movdqu [rax+216],xmm7
  !movdqu [rax+232],xmm8
  !movdqu [rax+248],xmm9
  !movdqu [rax+264],xmm10
  !movdqu [rax+280],xmm11
  !movdqu [rax+296],xmm12
  !movdqu [rax+312],xmm13
  !movdqu [rax+328],xmm14
  !movdqu [rax+344],xmm15
  DisableASM
EndMacro

Macro Rest_Reg()
; restore les registres
  s=@reg_memory()
  EnableASM
  !mov rax,[p.v_s]
  !mov rbx,[rax+000]
  !mov rcx,[rax+008]
  !mov rdx,[rax+016]
  !mov rsi,[rax+024]
  !mov rdi,[rax+032]
  !mov r8,[rax+040]
  !mov r9,[rax+048]
  !mov r10,[rax+056]
  !mov r11,[rax+064]
  !mov r12,[rax+072]
  !mov r13,[rax+080]
  !mov r14,[rax+088]
  !mov r15,[rax+096]

  !movdqu xmm0,[rax+104] ;
  !movdqu xmm1,[rax+120] ;
  !movdqu xmm2,[rax+136] ;
  !movdqu xmm3,[rax+152] ;
  !movdqu xmm4,[rax+168]
  !movdqu xmm5,[rax+184]
  !movdqu xmm6,[rax+200]
  !movdqu xmm7,[rax+216]
  !movdqu xmm8,[rax+232]
  !movdqu xmm9,[rax+248]
  !movdqu xmm10,[rax+264]
  !movdqu xmm11,[rax+280]
  !movdqu xmm12,[rax+296]
  !movdqu xmm13,[rax+312]
  !movdqu xmm14,[rax+328]
  !movdqu xmm15,[rax+344]
  DisableASM

EndMacro

;-------------------------------------------------------------------
Global Dim convol.f(11)
;-------------------------------------------------------------------

Procedure select_convol(opt)
  Protected i.q
  Select opt
    Case 0
      Restore K3x3_GAUSSIANBLUR_2
    Case 1
      Restore K3x3_GAUSSIANBLUR_3
    Case 2     
      Restore K3x3_GAUSSIANBLUR_4
    Case 3      
      Restore K3x3_GAUSSIANBLUR_6
    Case 4     
      Restore K3x3_GAUSSIANBLUR_8
    Case 5   
      Restore K3x3_GAUSSIANBLUR_10
    Case 6     
      Restore K3x3_MOTIONBLUR
    Case 7     
      Restore K3x3_MOTIONBLUR_RIGHT 
    Case 8     
      Restore K3x3_MOTIONBLUR_LEFT
    Case 9     
      Restore K3x3_SMOOTH_1
    Case 10     
      Restore K3x3_SMOOTH_2
    Case 11
      Restore K3x3_SMOOTH_3
    Case 12
      Restore K3x3_SMOOTH_4
    Case 13     
      Restore K3x3_MEANSMOOTH
    Case 14
      Restore K3x3_SHARPEN_15
    Case 15
      Restore K3x3_SHARPEN_20
    Case 16
      Restore K3x3_SHARPEN_30
    Case 17
      Restore K3x3_SHARPEN_50
    Case 18
      Restore K3x3_SHARPEN_MEANREMOVAL
    Case 19
      Restore K3x3_EMBOSS_v1
    Case 20
      Restore K3x3_EMBOSS_v2
    Case 21
      Restore K3x3_EMBOSS_v3
    Case 22
      Restore K3x3_EMBOSS_v4
    Case 23
      Restore K3x3_RAISED
    Case 24
      Restore K3x3_EDGEDETECT_HV
    Case 25
      Restore K3x3_EDGEDETECT_H
    Case 26
      Restore K3x3_EDGEDETECT_V
    Case 27
      Restore K3x3_EDGEDETECT_DIFFERENTIAL
    Case 28
      Restore K3x3_EDGEENHANCE_H
    Case 29
      Restore K3x3_EDGEENHANCE_V
    Case 30
      Restore K3x3_PREWITT_H
    Case 31
      Restore K3x3_PREWITT_V
    Case 32
      Restore K3x3_SOBEL_H
    Case 33
      Restore K3x3_SOBEL_V
    Case 34
      Restore K3x3_SOBELFELDMAN_H
    Case 35
      Restore K3x3_SOBELFELDMAN_V
    Case 36
      Restore K3x3_LAPLACE
    Case 37
      Restore K3x3_LAPLACE_INV 
    Case 38
      Restore K3x3_LAPLACE_DIAGONAL
    Case 39
      Restore K3x3_SCHARR_H
    Case 40
      Restore K3x3_SCHARR_V
    Case 41
      Restore K3x3_EDGE360_KEYA 
    Case 42
      Restore K3x3_GRADIENTDETECT_V
    Case 43
      Restore K3x3_GRADIENTDETECT_H
  EndSelect

  For i=0 To 10
    Read.f convol(i)
  Next
  If convol(9) = 0 : convol(9) = 1 :EndIf  ; pour eviter une division par 0
EndProcedure
;-------------------------------------------------------------------



Procedure Filter_convolV2_asm(source.q,cible.q)
  
  Protected d.f , y.q , Ncible.q , Nsource.q , s.q , var.l
  sp(source,cible)
  
  var=@convol() 
  
  d.f = 1.0 / convol(9)

  For y=0 To ht-3
    Ncible = cible_p + (((y+1)*lg+1)*4)
    Nsource = source_p + ( y * lg * 4)

    Save_Reg()
    EnableASM
    !mov rax,[p.v_var]
    !pxor xmm0,xmm0
    !VBROADCASTSS xmm14,[p.v_d];[p.v_var+36]
    !VBROADCASTSS xmm15,[rax+40]
    !mov rdx,[p.v_lg]
    !shl rdx,2

    !mov rdi,[p.v_Ncible] ; cible
    !mov rsi,[p.v_Nsource]; source
       
    !mov rbx,[p.v_lg] ; for x = 0 to lg - 2
    !sub rbx,2
    
      ;*** ligne 1
      !movd xmm1,[rsi+00] ; xmm1 =  ARGB (4 x 8 bits)       ;      rgb=PeekL(p)
      !punpcklbw xmm1,xmm0 ; xmm1 =  0A0R0G0B (4 x 16 bits)
      !punpcklwd xmm1,xmm0 ; xmm1 = 000a000r000g000b (4 x 32 bits)
      !movd xmm2,[rsi+04] 
      !punpcklbw xmm2,xmm0 
      !punpcklwd xmm2,xmm0
      !cvtdq2ps xmm1,xmm1 ;  conversion interger vers float
      !cvtdq2ps xmm2,xmm2
      
      ;*** ligne 2
      !add rsi,rdx  ; y + 1
      !movd xmm4,[rsi+00] 
      !punpcklbw xmm4,xmm0 
      !punpcklwd xmm4,xmm0
      !movd xmm5,[rsi+04] 
      !punpcklbw xmm5,xmm0 
      !punpcklwd xmm5,xmm0
      !cvtdq2ps xmm4,xmm4
      !cvtdq2ps xmm5,xmm5
      
      ;***ligne 3 
      !add rsi,rdx ; y + 1   
      !movd xmm7,[rsi+00] 
      !punpcklbw xmm7,xmm0 
      !punpcklwd xmm7,xmm0
      !movd xmm8,[rsi+04] 
      !punpcklbw xmm8,xmm0 
      !punpcklwd xmm8,xmm0
      !cvtdq2ps xmm7,xmm7
      !cvtdq2ps xmm8,xmm8
      
      !sub rsi,rdx ; y - 1 
      !sub rsi,rdx; y - 1
       
    !convolx02:

      ;*** ligne 1
      !movd xmm3,[rsi+08] 
      !punpcklbw xmm3,xmm0 
      !punpcklwd xmm3,xmm0
      !cvtdq2ps xmm3,xmm3  

      ;*** ligne 2
      !add rsi,rdx ; y + 1 
      !movd xmm6,[rsi+08] 
      !punpcklbw xmm6,xmm0 
      !punpcklwd xmm6,xmm0
      !cvtdq2ps xmm6,xmm6
      
      ;***ligne 3
      !add rsi,rdx ; y + 1 
      !movd xmm9,[rsi+08] 
      !punpcklbw xmm9,xmm0 
      !punpcklwd xmm9,xmm0
      !cvtdq2ps xmm9,xmm9
           
      !sub rsi,rdx ; y - 1 
      !sub rsi,rdx; y - 1 
      
      !movups xmm11,xmm1 ; ; r=r1*convol(0)+r2*convol(1)+r3*convol(2)+r4*convol(3)+r5*convol(4)+r6*convol(5)+r7*convol(6)+r8*convol(7)+r9*convol(8)
      !VBROADCASTSS xmm10,[rax+00]
      !mulps xmm11,xmm10     
      !movups xmm12,xmm2
      !VBROADCASTSS xmm10,[rax+04]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12      
      !movups xmm12,xmm3
      !VBROADCASTSS xmm10,[rax+08]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12     
      !movups xmm12,xmm4
      !VBROADCASTSS xmm10,[rax+12]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12      
      !movups xmm12,xmm5
      !VBROADCASTSS xmm10,[rax+16]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12
      !movups xmm12,xmm5
      !VBROADCASTSS xmm10,[rax+20]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12
      !movups xmm12,xmm7
      !VBROADCASTSS xmm10,[rax+24]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12
      !movups xmm12,xmm8
      !VBROADCASTSS xmm10,[rax+28]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12
      !movups xmm12,xmm8
      !VBROADCASTSS xmm10,[rax+32]
      !mulps xmm12,xmm10
      !addps xmm11,xmm12
      
      !mulps xmm11,xmm14 ; r= r * dif + convol(10)
      !addps xmm11,xmm15
      
      !CVTPS2DQ xmm11,xmm11 ; conversion float vers interger
      
      !packusdw xmm11,xmm0 ; 000a000r000g000b (4 x 32 bits)  => 0A0R0G0B (4 x 16 bits)
      !packuswb xmm11,xmm0 ; 0A0R0G0B (4 x 16 bits) => ARGB
      
      !movd [rdi],xmm11
      
      !add rsi,4
      !add rdi,4
      
      !movups xmm1,xmm2 ; r1=r2:r2=r3:r4=r5:r5=r6:r7=r8:r8=r9
      !movups xmm2,xmm3
      !movups xmm4,xmm5
      !movups xmm5,xmm6
      !movups xmm7,xmm8
      !movups xmm8,xmm9
    !dec rbx
    !jnz convolx02

  DisableASM
  Rest_Reg()
  
Next

EndProcedure
;-------------------------------------------------------------------

Procedure Filter_convolV2_pb(source.q,cible.q)
  Protected x.q , y.q , p.q , rgb.q
  Protected r.q , r1.q , r2.q , r3.q , r4.q , r5.q , r6.q , r7.q , r8.q , r9.q
  Protected g.q , g1.q , g2.q , g3.q , g4.q , g5.q , g6.q , g7.q , g8.q , g9.q
  Protected b.q , b1.q , b2.q , b3.q , b4.q , b5.q , b6.q , b7.q , b8.q , b9.q
  Protected dif.f
  sp(source,cible)
  
  dif.f = 1 / convol(9)
  For y=1 To ht-2
    x=0
    p=source_p+((y-1)*lg*4)+((x-0)*4)
    rgb=PeekL(p)
    returnRGB(rgb,r1,g1,b1)
    p=source_p+((y-1)*lg*4)+((x+1)*4)
    rgb=PeekL(p)
    returnRGB(rgb,r2,g2,b2)
  
    p=source_p+((y-0)*lg*4)+((x-0)*4)
    rgb=PeekL(p)
    returnRGB(rgb,r4,g4,b4)   
    p=source_p+((y-0)*lg*4)+((x+1)*4)
    rgb=PeekL(p)
    returnRGB(rgb,r5,g5,b5)
          
    p=source_p+((y+1)*lg*4)+((x-0)*4)
    rgb=PeekL(p)
    returnRGB(rgb,r7,g7,b7)          
    p=source_p+((y+1)*lg*4)+((x+1)*4)
    rgb=PeekL(p)
    returnRGB(rgb,r8,g8,b8)          
    
    For x=2 To lg-1
      p=source_p+((((y-1)*lg)+x)<<2)
      rgb=PeekL(p)
      returnRGB(rgb,r3,g3,b3) 
      p=source_p+((((y-0)*lg)+x)<<2)
      rgb=PeekL(p)
      returnRGB(rgb,r6,g6,b6)      
      p=source_p+((((y+1)*lg)+x)<<2)
      rgb=PeekL(p)
      returnRGB(rgb,r9,g9,b9)
      
      r=r1*convol(0)+r2*convol(1)+r3*convol(2)+r4*convol(3)+r5*convol(4)+r6*convol(5)+r7*convol(6)+r8*convol(7)+r9*convol(8)
      g=g1*convol(0)+g2*convol(1)+g3*convol(2)+g4*convol(3)+g5*convol(4)+g6*convol(5)+g7*convol(6)+g8*convol(7)+g9*convol(8)
      b=b1*convol(0)+b2*convol(1)+b3*convol(2)+b4*convol(3)+b5*convol(4)+b6*convol(5)+b7*convol(6)+b8*convol(7)+b9*convol(8)
      
      r= r * dif + convol(10)
      g= g * dif + convol(10)
      b= b * dif + convol(10)
      
      ClampRGB(r,g,b)
      PokeL(cible_p+(y*lg*4)+(x-1)*4,(r<<16+g<<8+b))
      
      r1=r2:r2=r3:r4=r5:r5=r6:r7=r8:r8=r9
      g1=g2:g2=g3:g4=g5:g5=g6:g7=g8:g8=g9
      b1=b2:b2=b3:b4=b5:b5=b6:b7=b8:b8=b9
    Next
  Next
EndProcedure

  
;-------------------------------------------------------------------  
  
  
Procedure Filter_convolV1_pb(source.q,cible.q)
  Protected x.q , y.q , x1.q , y1.q , i.q , pos.q , var.q
  Protected r.q , g.q , b.q , r1.q , g1.q , b1.q
  Protected dif.f 

  sp(source,cible)
  
  dif.f = 1 / convol(9)
  For y = 1 To ht - 2
    For x = 1 To lg - 2
      r = 0 : g = 0 : b = 0 : i = -1
      For x1 = -1 To 1
        For y1 = -1 To 1
          i = i + 1
          pos=(((y+y1)*lg)+(x+x1))*4
          var=PeekL(source_p+pos)
          returnRGB(var,r1,g1,b1)
          r = r + r1 * convol(i)
          g = g + g1 * convol(i)
          b = b + b1 * convol(i)
        Next
      Next
      r = r * dif + convol(10)
      g = g * dif + convol(10)
      b = b * dif + convol(10)
      ClampRGB(r,g,b)
      PokeL(cible_p+pos,(r<<16+g<<8+b))
    Next
  Next

EndProcedure


;-------------------------------------------------------------------


;------------------------------------------------------------------
;-- programme
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1200
Global imgy=800


If OpenWindow(0, 0, 0, imgx, imgy, "balance", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.q , cible.q , t.q , file$ , i , var , tx$
  
  ComboBoxGadget(1, imgx/4, 1, imgx/2, 24)
  Restore DATA_NOM
  tx$=""
  While tx$<>"***END***"
    Read.s tx$
    If tx$<>"***END***"
      AddGadgetItem(1, -1, tx$)
    EndIf
  Wend
  

   file$ = OpenFileRequester("Image","","",0)
   source=10
   cible=20
   
   If Load_Image(source,file$) = 0 ; <- commande differente de "LOADIMAGE"
     MessageRequester("erreur", "image non chargeé" ,#PB_MessageRequester_Ok )
     End
   EndIf
   
   ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
   
   CreateImage(cible,imgx,imgy,32) ; l'image doit entre en mode 32bits
      
   Repeat
     Select WaitWindowEvent()

        Case  #PB_Event_CloseWindow
          End
        Case  #PB_Event_Gadget
         
          Select EventGadget()
             
            Case 1
              var=GetGadgetState(1)
              t=ElapsedMilliseconds()
              select_convol(var)
              Filter_convolV1_pb(source,cible)   ;  <=   changer de version ici
              ;Filter_convolV2_pb(source,cible)  ;  <=
              ;Filter_convolV2_ASM(source,cible) ;  <=
              t=ElapsedMilliseconds()-t

             
          EndSelect
      EndSelect
       
       StartDrawing(WindowOutput(0))
       DrawImage(ImageID(cible),0,50)
       DrawText(5,50,"temps : "+Str(t))
       DrawText(5,5,Str(GetGadgetState(1))+"     ")
       StopDrawing()
   
    ForEver
  EndIf
  
  
 ;------------------------------------------------------------------- 
 ;-data convolution
 ;-- https://www.purebasic.fr/english/viewtopic.php?f=12&t=68204
DataSection
  K3x3_GAUSSIANBLUR_2:
   Data.f 1, 2, 1
   Data.f 2, 2, 2
   Data.f 1, 2, 1
   Data.f 14
   Data.f 0
   
  K3x3_GAUSSIANBLUR_3:
   Data.f 1, 2, 1
   Data.f 2, 3, 2
   Data.f 1, 2, 1
   Data.f 15
   Data.f 0
   
  K3x3_GAUSSIANBLUR_4: 
   Data.f 1, 2, 1
   Data.f 2, 4, 2
   Data.f 1, 2, 1
   Data.f 16
   Data.f 0
   
  K3x3_GAUSSIANBLUR_6:
   Data.f 1, 2, 1
   Data.f 2, 6, 2
   Data.f 1, 2, 1
   Data.f 18
   Data.f 0
   
  K3x3_GAUSSIANBLUR_8:
   Data.f 1, 2, 1
   Data.f 2, 8, 2
   Data.f 1, 2, 1
   Data.f 20
   Data.f 0
   
  K3x3_GAUSSIANBLUR_10:
   Data.f 1, 2,  1
   Data.f 2, 10, 2
   Data.f 1, 2,  1
   Data.f 22
   Data.f 0   
 
  K3x3_MOTIONBLUR_RIGHT:
  Data.f 0, 0, 1
  Data.f 0, 0, 0
  Data.f 1, 0, 0
  Data.f 2
  Data.f 0
 
  K3x3_MOTIONBLUR_LEFT:
  Data.f 1, 0, 0
  Data.f 0, 0, 0
  Data.f 0, 0, 1
  Data.f 2
  Data.f 0
 
  K3x3_MOTIONBLUR:
  Data.f 1, 0, 0
  Data.f 0, 1, 0
  Data.f 0, 0, 1
  Data.f 3
  Data.f 0
 
  K3x3_SMOOTH_1:
  Data.f 1,   1,    1
  Data.f 1,   5,    1
  Data.f 1,   1,    1
  Data.f 13
  Data.f 0
 
  K3x3_SMOOTH_2:
  Data.f 1,   1,    1
  Data.f 1,   4,    1
  Data.f 1,   1,    1
  Data.f 12
  Data.f 0 
   
  K3x3_SMOOTH_3:
  Data.f 1,   1,    1
  Data.f 1,   3,    1
  Data.f 1,   1,    1
  Data.f 11
  Data.f 0 
 
  K3x3_SMOOTH_4:
  Data.f 1,   1,    1
  Data.f 1,   2,    1
  Data.f 1,   1,    1
  Data.f 10
  Data.f 0
 
  K3x3_MEANSMOOTH:
  Data.f 1,   1,    1
  Data.f 1,   1,    1
  Data.f 1,   1,    1
  Data.f 9.0
  Data.f 0
 
  K3x3_SHARPEN_15:
  Data.f  0,   -1,   0
  Data.f -1,  5,    -1
  Data.f  0,   -1,   0
  Data.f 1
  Data.f 0
 
  K3x3_SHARPEN_20:
  Data.f  0,   1,   0
  Data.f 1,   -3   ,1
  Data.f  0,   1,   0
  Data.f 1
  Data.f 0
 
  K3x3_SHARPEN_30:
  Data.f  -1,  -1,   -1
  Data.f -1,   9,  -1
  Data.f  -1,  -1,   -1
  Data.f 1
  Data.f 0 
 
  K3x3_SHARPEN_50:
  Data.f  1,  -2,   1
  Data.f -2,   5,  -2
  Data.f  1,  -2,   1
  Data.f 1
  Data.f 0
 
  K3x3_SHARPEN_MEANREMOVAL:     
  Data.f -1,  -1, -1
  Data.f -1,   9, -1
  Data.f -1,  -1, -1
  Data.f 1
  Data.f 0 
   
 
  K3x3_EXTRUDE:
  Data.f 1,   1,    1
  Data.f 1,   -7,    1
  Data.f 1,   1,    1
  Data.f 1
  Data.f 0   
 
  K3x3_EMBOSS_v1:
  Data.f -1,  -1,  0
  Data.f -1,   0,  1
  Data.f  0,   1,  1
  Data.f 9
  Data.f 128
 
  K3x3_EMBOSS_v2:
  Data.f  0, 0, 0
  Data.f -1, 0, 1
  Data.f  0, 0, 0
  Data.f 9
  Data.f 128
 
  K3x3_EMBOSS_v3:
  Data.f 1, 1,  0
  Data.f 1,  0,  -1
  Data.f  0,  -1,  -1
  Data.f 9
  Data.f 128
 
  K3x3_EMBOSS_v4:
  Data.f -2, -1,  0
  Data.f -1,  1,  1
  Data.f 0,  1,  2
  Data.f 9
  Data.f 128   
 
  K3x3_RAISED:
  Data.f 0, 0, -2
  Data.f 0, 2, 0
  Data.f 1, 0, 0
  Data.f 1
  Data.f 0
   
 
  K3x3_EDGEDETECT_HV:     
  Data.f 0,  1,  0
  Data.f 1, -4,  1
  Data.f 0,  1,  0
  Data.f 1
  Data.f 0
 
  K3x3_EDGEDETECT_H:
  Data.f  0,  0,  0
  Data.f -1,  2, -1
  Data.f 0,  0,  0
  Data.f 1
  Data.f 0
 
  K3x3_EDGEDETECT_V:
  Data.f 0, -1, 0
  Data.f 0,  2, 0
  Data.f 0, -1, 0
  Data.f 1
  Data.f 0
 
  K3x3_EDGEDETECT_DIFFERENTIAL:
  Data.f -1, 0,  1
  Data.f 0,  0,  0
  Data.f 1, 0, 1
  Data.f 1
  Data.f 0
 
  K3x3_EDGEENHANCE_H:
  Data.f  0, 0, 0
  Data.f -1, 1, 0
  Data.f  0, 0, 0
  Data.f 1
  Data.f 0
 
  K3x3_EDGEENHANCE_V:
  Data.f  0,-1, 0
  Data.f  0, 1, 0
  Data.f  0, 0, 0
  Data.f 1
  Data.f 0
 
  K3x3_PREWITT_H:
  Data.f 1, 0, -1
  Data.f 1, 0, -1
  Data.f 1, 0, -1
  Data.f 1
  Data.f 0
 
  K3x3_PREWITT_V:
  Data.f  1,  1,  1
  Data.f  0,  0,  0
  Data.f -1, -1, -1
  Data.f 1
  Data.f 0
 
  K3x3_SOBEL_H:
  Data.f -1, 0, 1
  Data.f -2, 0, 2
  Data.f -1, 0, 1
  Data.f 1
  Data.f 0
 
  K3x3_SOBEL_V:
  Data.f  1,  2,  1
  Data.f  0,  0,  0
  Data.f -1, -2, -1
  Data.f 1
  Data.f 0
 
  K3x3_SOBELFELDMAN_H:
  Data.f 3,  0,  -3
  Data.f 10, 0, -10
  Data.f  3, 0,  -3
  Data.f 1
  Data.f 0
 
  K3x3_SOBELFELDMAN_V:
  Data.f  3,  10,  3
  Data.f  0,  0,   0
  Data.f -3, -10, -3
  Data.f 1
  Data.f 0
 
  K3x3_LAPLACE:
  Data.f 0,  1, 0
  Data.f 1, -4, 1
  Data.f 0,  1, 0
  Data.f 1
  Data.f 0 
 
  K3x3_LAPLACE_INV:
  Data.f  0, -1,  0
  Data.f -1,  4, -1
  Data.f  0, -1,  0
  Data.f 1
  Data.f 0
 
  K3x3_LAPLACE_DIAGONAL:
  Data.f 1,   2, 1
  Data.f 2, -12, 2
  Data.f 1,   2, 1
  Data.f 1
  Data.f 0
 
  K3x3_SCHARR_H:
  Data.f  3.0,  10.0,  3.0
  Data.f  0.0,   0.0,  0.0
  Data.f -3.0, -10.0, -3.0
  Data.f 1
  Data.f 0
 
  K3x3_SCHARR_V:
  Data.f -3.0, -10.0, -3.0
  Data.f  0.0,   0.0,  0.0
  Data.f  3.0,  10.0,  3.0
  Data.f 1
  Data.f 0
 
  K3x3_EDGE360_KEYA:
  Data.f -1, -1, -1
  Data.f -1,  8, -1
  Data.f -1, -1, -1
  Data.f 1
  Data.f 0 
 
  K3x3_GRADIENTDETECT_V:
  Data.f -1, -1, -1
  Data.f  0,  0,  0
  Data.f  1,  1,  1
  Data.f 1
  Data.f 0
 
  K3x3_GRADIENTDETECT_H:
  Data.f -1, 0, 1
  Data.f -1, 0, 1
  Data.f -1, 0, 1
  Data.f 1
  Data.f 0
 
  DATA_NOM:
  Data.s "GAUSSIANBLUR_2" 
  Data.s "GAUSSIANBLUR_3"    
  Data.s "GAUSSIANBLUR_4"       
  Data.s "GAUSSIANBLUR_6"    
  Data.s "GAUSSIANBLUR_8"   
  Data.s "GAUSSIANBLUR_10"      
  Data.s "MOTIONBLUR"      
  Data.s "MOTIONBLUR_RIGHT"    
  Data.s "MOTIONBLUR_LEFT"      
  Data.s "SMOOTH_1"     
  Data.s "SMOOTH_2"
  Data.s "SMOOTH_3" 
  Data.s "SMOOTH_4"     
  Data.s "MEANSMOOTH"
  Data.s "SHARPEN_15"
  Data.s "SHARPEN_20"
  Data.s "SHARPEN_30"
  Data.s "SHARPEN_50"
  Data.s "SHARPEN_MEANREMOVAL"
  Data.s "EMBOSS_v1"
  Data.s "EMBOSS_v2"
  Data.s "EMBOSS_v3"
  Data.s "EMBOSS_v4"
  Data.s "RAISED"
  Data.s "EDGEDETECT_HV"
  Data.s "EDGEDETECT_H"
  Data.s "EDGEDETECT_V"
  Data.s "DGEDETECT_DIFFERENTIAL"
  Data.s "REDGEENHANCE_H"
  Data.s "EDGEENHANCE_V"
  Data.s "PREWITT_H"
  Data.s "PREWITT_V" 
  Data.s "SOBEL_H"
  Data.s "SOBELV"
  Data.s "SOBELFELDMAN_H"
  Data.s "SOBELFELDMAN_V" 
  Data.s "LAPLACE"
  Data.s "LAPLACE_INV"
  Data.s "LAPLACE_DIAGONAL"
  Data.s "SCHARR_H"
  Data.s "SCHARR_V"
  Data.s "EDGE360_KEYA"
  Data.s "GRADIENTDETECT_V"
  Data.s "GRADIENTDETECT_H"
  Data.s "***END***"
EndDataSection