Attribute VB_Name = "ModFilters"

' ModFilters.bas

' Some filters modified, adapted from various refs:

' Manuel Santos         PSC CodeId=26303  (Several)
' Stephane Swertvaegher PSC CodeId=28441  (Blinds, Mozaic & Stephan)
'      NB Uses On Error Resume Next to avoid array boundary
'      check but will fail in EXE if Advanced Options checked.
' Tanner Helland  PSC CodeId=66955 ('Real Brightness') but cut down version.
'                 PSC CodeId=25819 (Contrast)
' APaint8   PSC CodeID=53558
' etc, etc


' Note: Input:  Public FullW & FullH, image width & height
'               Public PicDataORG(0 To 3, 0 To FullW - 1, 0 To FullH - 1)
'               the original image data.
'       Output: Public PicData(0 To 3, 0 To FullW - 1, 0 To FullH - 1)
'               which is DISPLAYED in frmFilters.

Option Explicit

Private Type RECT
    Left As Long
    TOp As Long
    Right As Long
    Bottom As Long
End Type

Private REC As RECT

Private Declare Function PtInRect Lib "USER32" _
   (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long

Private Declare Function SetRect Lib "USER32" _
(lpRect As RECT, ByVal x1 As Long, ByVal y1 As Long, _
  ByVal x2 As Long, ByVal y2 As Long) As Long


'Dim r As RECT
'SetRect REC, 0, 0, FullW - 1, FullH - 1
'If PtInRect(REC, XX, YY) <> 0 Then ' Quad1



Public FilterIndex As Integer
Public aniDone As Boolean
' NB Double first letter to avoid
' duplicating command button captions
Public Enum EFilterIndex
   [BBlackWhite] = 0
   [BBrightness] = 1
   [CContrast] = 2
   [DDiffuseH] = 3
   [DDiffuseV] = 4
   [DDiffuseHV] = 5
   [EEngraveEmboss] = 6
   [FFog] = 7
   [FMozaic] = 8
   [LLitho] = 9
   [MMelt] = 10
   [OOil] = 11
   
   [XHLIGHT] = 12
   [OLaplace] = 13
   [AddSubEdge] = 14
   
   [PPixelize] = 15
   [XPosterize] = 16
   [RRelief] = 17
   [EErode] = 18
   [TTiltPixels] = 19

   [SSharpSmooth] = 20
   [SSolarize] = 21
   [VVaryRed] = 22
   [VVaryGreen] = 23
   [VVaryBlue] = 24
   [TannerB] = 25
   [XWhiten] = 26
   [XSnow] = 27
   
   
   [FInvert] = 28
   [FGrey] = 29
   [FSepia] = 30
   [FSwapBG] = 31
   [FSwapBR] = 32
   [FswapGR] = 33
   [FSolidColor] = 34
   [FSolidGrey] = 35

   [FMask] = 36
End Enum

Private Cul As Long
Private ix As Long, iy As Long     ' Image data array scanning
Private ixx As Long, iyy As Long   ' Mask coords for Public MaskArray()
' MaskArray() set @ CalcSelectCoords
' or CalcSelectCoordsFromMinxmax on Form1
Private i As Long, j As Long
Private k As Long
Private B As Long, g As Long, r As Long

Private picData2() As Byte
' Outlines
Private q(-1 To 1, -1 To 1)

' For Tanner Brightness
Private Const MAXGAMMA As Double = 1.8460498941512
Private Const MIDGAMMA As Double = 0.68377223398334
Private Const ROOT10 As Double = 3.16227766

' TEST
'Private Max As Double
'Private Min As Double

'<<<< Progress bar >>>>>>>>>>
Private xd As Single, xp As Single

' Select rectangle coords
'Public LOX As Long, HIX As Long
'Public LOY As Long, HIY As Long
' set by CalcSelectCoords (Main form)
' at picDRAW_MouseUp
' scrZoom, scrHorz & scrVert

Public Sub Invert()
   picDATA() = picDATAORG()
      
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then InvertCALC
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then InvertCALC
            End If
         Else
            If aExternal Then InvertCALC
         End If
      Else  ' Selection OFF
         InvertCALC
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub InvertCALC()
   picDATA(0, ix, iy) = Not picDATAORG(0, ix, iy)
   picDATA(1, ix, iy) = Not picDATAORG(1, ix, iy)
   picDATA(2, ix, iy) = Not picDATAORG(2, ix, iy)
End Sub

Public Sub Grey()
Dim S As Long
   picDATA() = picDATAORG()
      
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then GreyCALC S
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then GreyCALC S
            End If
         Else
            If aExternal Then GreyCALC S
         End If
      Else  ' Selection OFF
         GreyCALC S
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub GreyCALC(S As Long)
      B = picDATAORG(0, ix, iy)
      g = picDATAORG(1, ix, iy)
      r = picDATAORG(2, ix, iy)
      S = (0.3 * r + 0.6 * g + 0.1 * B)  ' Good enough !?
      picDATA(0, ix, iy) = S
      picDATA(1, ix, iy) = S
      picDATA(2, ix, iy) = S
End Sub

Public Sub Sepia()
   picDATA() = picDATAORG()
      
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then SepiaCALC
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then SepiaCALC
            End If
         Else
            If aExternal Then SepiaCALC
         End If
      Else  ' Selection OFF
         SepiaCALC
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub SepiaCALC()
      B = picDATAORG(0, ix, iy) * 0.114
      g = picDATAORG(1, ix, iy) * 0.587
      r = picDATAORG(2, ix, iy) * 0.299
      k = B + g + r
      B = k
      g = k
      r = k
      picDATA(1, ix, iy) = g
      If r < 63 Then
         r = r * 1.1
         B = B * 0.9
      End If
      If r > 62 And r < 192 Then
         r = r * 1.15
         B = B * 0.85
      End If
      If r > 191 Then
         r = r * 1.08
         If r > 255 Then
            r = 255
         End If
         B = B * 0.93
      End If
      picDATA(0, ix, iy) = B
      picDATA(2, ix, iy) = r
End Sub

Public Sub Brightness(Frac As Single)
' Frac 0.3 -> 5.0
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then BrightnessCALC Frac
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then BrightnessCALC Frac
            End If
         Else
            If aExternal Then BrightnessCALC Frac
         End If
      Else  ' Selection OFF
         BrightnessCALC Frac
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub BrightnessCALC(Frac As Single)
' Frac 0.3 -> 5.0
      For k = 0 To 3
         Cul = 1& * picDATAORG(k, ix, iy) * Frac
         If Cul > 255 Then Cul = 255
         picDATA(k, ix, iy) = Cul
      Next k
End Sub

Public Sub TannerBrightness(LIM As Long)
' Lim 0 to 255
' Based on Tanner Helland but cut down
Dim gvalues(0 To 255) As Double
Dim gstep As Double
Dim bRatio As Byte
Dim gLevels(0 To 255) As Byte
Dim tmpGamma As Double
Dim NewLevels(0 To 255) As Byte

   gstep = (MAXGAMMA + MIDGAMMA) / 127
   For ix = 0 To 127
      gvalues(ix) = (CDbl(ix) / 127) * MIDGAMMA
   Next ix
   For ix = 128 To 255
      gvalues(ix) = MIDGAMMA + (CDbl(ix - 127) * gstep)
   Next ix
   For ix = 0 To 255
      gvalues(ix) = 1 / ((gvalues(ix) + 1 / ROOT10) ^ 2)
   Next ix
   bRatio = CByte(LIM)
   For ix = 0 To 255
      tmpGamma = CDbl(ix) / 255
      tmpGamma = tmpGamma ^ (1 / gvalues(bRatio))
      tmpGamma = tmpGamma * 255
      If tmpGamma > 255 Then tmpGamma = 255
      If tmpGamma < 0 Then tmpGamma = 0
      gLevels(ix) = tmpGamma
   Next ix
   For ix = 0 To 255
      NewLevels(ix) = gLevels(ix)
   Next ix
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then TannerBrightnessCALC NewLevels()
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then TannerBrightnessCALC NewLevels()
            End If
         Else
            If aExternal Then TannerBrightnessCALC NewLevels()
         End If
      Else  ' Selection OFF
         TannerBrightnessCALC NewLevels()
      End If
   Next ix
   DrawProgress
   Next iy
   

   frmFilters.picPB.Cls
End Sub

Private Sub TannerBrightnessCALC(NewLevels() As Byte)
      B = picDATAORG(0, ix, iy)
      g = picDATAORG(1, ix, iy)
      r = picDATAORG(2, ix, iy)
      picDATA(0, ix, iy) = NewLevels(B)
      picDATA(1, ix, iy) = NewLevels(g)
      picDATA(2, ix, iy) = NewLevels(r)
End Sub

Public Sub BlackWhite(BWLim As Long)
' BWLim  20 -> 200

   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then BlackWhiteCALC BWLim
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then BlackWhiteCALC BWLim
            End If
         Else
            If aExternal Then BlackWhiteCALC BWLim
         End If
      Else  ' Selection OFF
         BlackWhiteCALC BWLim
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub BlackWhiteCALC(BWLim As Long)
' BWLim = 50 - 200
' Private ix As Long, iy As Long
      
      Cul = (1& * picDATAORG(0, ix, iy) + _
                  picDATAORG(1, ix, iy) + _
                  picDATAORG(2, ix, iy)) \ 3
      If Cul < BWLim Then
         picDATA(0, ix, iy) = 0
         picDATA(1, ix, iy) = 0
         picDATA(2, ix, iy) = 0
      Else
         picDATA(0, ix, iy) = 255
         picDATA(1, ix, iy) = 255
         picDATA(2, ix, iy) = 255
      End If
End Sub



Public Sub Contrast(ContrastVal As Long)
' ContrastVal -66 -> 66
' Based on Tanner Helland
   
   StartProgress (HIY)
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then ContrastCALC ContrastVal
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then ContrastCALC ContrastVal
            End If
         Else
            If aExternal Then ContrastCALC ContrastVal
         End If
      Else  ' Selection OFF
         ContrastCALC ContrastVal
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub ContrastCALC(ContrastVal As Long)
   B = picDATAORG(0, ix, iy)
   g = picDATAORG(1, ix, iy)
   r = picDATAORG(2, ix, iy)
   r = r + (((r - 127) * ContrastVal) \ 100)
   g = g + (((g - 127) * ContrastVal) \ 100)
   B = B + (((B - 127) * ContrastVal) \ 100)
   If B < 0 Then B = 0 Else If B > 255 Then B = 255
   If g < 0 Then g = 0 Else If g > 255 Then g = 255
   If r < 0 Then r = 0 Else If r > 255 Then r = 255
   picDATA(0, ix, iy) = B
   picDATA(1, ix, iy) = g
   picDATA(2, ix, iy) = r
End Sub

Public Sub DiffuseHorz(PDIFFUSE As Long)
' PDIFFUSE  1 -> 16

   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then DiffuseHorzCALC PDIFFUSE
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then DiffuseHorzCALC PDIFFUSE
            End If
         Else
            If aExternal Then DiffuseHorzCALC PDIFFUSE
         End If
      Else  ' Selection OFF
         DiffuseHorzCALC PDIFFUSE
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub DiffuseHorzCALC(PDIFFUSE As Long)
   i = Rnd * PDIFFUSE - PDIFFUSE \ 2
   If ix + i < 0 Then i = 0
   If ix + i > FullW - 1 Then i = 0
   
   
   picDATA(0, ix, iy) = picDATAORG(0, ix + i, iy)
   picDATA(1, ix, iy) = picDATAORG(1, ix + i, iy)
   picDATA(2, ix, iy) = picDATAORG(2, ix + i, iy)
End Sub

Public Sub DiffuseVert(PDIFFUSE As Long)
' PDIFFUSE  1 -> 16
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then DiffuseVertCALC PDIFFUSE
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then DiffuseVertCALC PDIFFUSE
            End If
         Else
            If aExternal Then DiffuseVertCALC PDIFFUSE
         End If
      Else  ' Selection OFF
         DiffuseVertCALC PDIFFUSE
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub DiffuseVertCALC(PDIFFUSE As Long)
   j = Rnd * PDIFFUSE - PDIFFUSE \ 2
   If iy + j < 0 Then j = 0
   If iy + j > FullH - 1 Then j = 0
   picDATA(0, ix, iy) = picDATAORG(0, ix, iy + j)
   picDATA(1, ix, iy) = picDATAORG(1, ix, iy + j)
   picDATA(2, ix, iy) = picDATAORG(2, ix, iy + j)
End Sub

Public Sub Diffuse(PDIFFUSE As Long)   ' Horz & Vert
' PDIFFUSE  1 -> 16
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then DiffuseHVCALC PDIFFUSE
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then DiffuseHVCALC PDIFFUSE
            End If
         Else
            If aExternal Then DiffuseHVCALC PDIFFUSE
         End If
      Else  ' Selection OFF
         DiffuseHVCALC PDIFFUSE
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub DiffuseHVCALC(PDIFFUSE As Long)
   j = Rnd * PDIFFUSE - PDIFFUSE \ 2
   i = Rnd * PDIFFUSE - PDIFFUSE \ 2
   If ix + i < 0 Then i = 0 Else If ix + i > FullW - 1 Then i = 0
   If iy + j < 0 Then j = 0 Else If iy + j > FullH - 1 Then j = 0
   picDATA(0, ix, iy) = picDATAORG(0, ix + i, iy + j)
   picDATA(1, ix, iy) = picDATAORG(1, ix + i, iy + j)
   picDATA(2, ix, iy) = picDATAORG(2, ix + i, iy + j)
End Sub

Public Sub Fog(PFOG As Long)
'PFOG   -100 -> +100
Dim n As Long
Dim Nf As Long
   
   picDATA() = picDATAORG()
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then FogCALC PFOG
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then FogCALC PFOG
            End If
         Else
            If aExternal Then FogCALC PFOG
         End If
      Else  ' Selection OFF
         FogCALC PFOG
      End If
   Next ix
   DrawProgress
   Next iy
   
   StartProgress HIY
   
   Nf = 144
   
   For iy = 1 To FullH - 2
   n = Nf + 2 * Rnd
   For ix = 1 To FullW - 2
      If aSelectAccepted Then ' Selection ON
         If (ix > LOX And ix < HIX) And (iy > LOY And iy < HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then FogCALC2 PFOG, n
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then FogCALC2 PFOG, n
            End If
         Else
            If aExternal Then FogCALC2 PFOG, n
         End If
      Else  ' Selection OFF
         FogCALC2 PFOG, n
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub FogCALC(PFOG As Long)
Dim LR As Long, LG As Long, LB As Long
Dim FogLim As Long

   FogLim = 160
   LB = picDATAORG(0, ix, iy)
   LG = picDATAORG(1, ix, iy)
   LR = picDATAORG(2, ix, iy)
   
   If LB > FogLim Then
      LB = LB - PFOG
      If LB < FogLim Then LB = FogLim
   Else
      LB = LB + PFOG
      If LB > FogLim Then LB = FogLim
   End If
   If LG > FogLim Then
      LG = LG - PFOG
      If LG < FogLim Then LG = FogLim
   Else
      LG = LG + PFOG
      If LG > FogLim Then LG = FogLim
   End If
   If LR > FogLim Then
      LR = LR - PFOG
      If LR < FogLim Then LR = FogLim
   Else
      LR = LR + PFOG
      If LR > FogLim Then LR = FogLim ' FogLim
   End If
   'If LB < 0 Then LB = 0 Else If LB > 255 Then LB = 255
   'If LG < 0 Then LG = 0 Else If LG > 255 Then LG = 255
   'If LR < 0 Then LR = 0 Else If LR > 255 Then LR = 255
   picDATA(0, ix, iy) = LB
   picDATA(1, ix, iy) = LG
   picDATA(2, ix, iy) = LR
End Sub

Private Sub FogCALC2(PFOG As Long, n As Long)
Dim LR As Long, LG As Long, LB As Long

   LB = picDATAORG(0, ix, iy)
   LG = picDATAORG(1, ix, iy)
   LR = picDATAORG(2, ix, iy)
   n = n + 8 * (Rnd - 0.5)
   If LR > n Then LR = LR - PFOG
   If LR < n Then LR = n
   If LG > n Then LG = LG - PFOG
   If LG < n Then LG = n
   If LB > n Then LB = LB - PFOG
   If LB < n Then LB = n
   If LB < 0 Then LB = 0
   If LG < 0 Then LG = 0
   If LR < 0 Then LR = 0
   
   LB = LB + picDATA(0, ix, iy - 1) _
           + picDATA(0, ix, iy + 1) _
           + picDATA(0, ix - 1, iy) _
           + picDATA(0, ix + 1, iy)
   LB = LB \ 5
   LG = LG + picDATA(1, ix, iy - 1) _
           + picDATA(1, ix, iy + 1) _
           + picDATA(1, ix - 1, iy) _
           + picDATA(1, ix + 1, iy)
   LG = LG \ 5
   LR = LR + picDATA(2, ix, iy - 1) _
           + picDATA(2, ix, iy + 1) _
           + picDATA(2, ix - 1, iy) _
           + picDATA(2, ix + 1, iy)
   LR = LR \ 5
   If LB < 0 Then LB = 0 Else If LB > 255 Then LB = 255
   If LG < 0 Then LG = 0 Else If LG > 255 Then LG = 255
   If LR < 0 Then LR = 0 Else If LR > 255 Then LR = 255
   picDATA(0, ix, iy) = LB
   picDATA(1, ix, iy) = LG
   picDATA(2, ix, iy) = LR

End Sub

Public Sub Mozaic(ByVal SQU As Long)
' SQU 8 - 50
Dim HalfY As Long, HalfX As Long
Dim CH As Long, CW As Long
   
   HalfY = SQU \ 2
   HalfX = HalfY
   
   If aSelectAccepted Then
      CH = HIY - LOY
      CW = HIX - LOX
      If HalfX >= CW Then Exit Sub
      If HalfY >= CH Then Exit Sub
      If SQU > HIY Then SQU = HIY
   Else
      CH = FullH - 1
      CW = FullW - 1
      If HalfX >= CW Then Exit Sub
      If HalfY >= CH Then Exit Sub
      If SQU > CH Then SQU = CH
   End If
   
   StartProgress HIY \ SQU
   
   For iy = 0 To FullH - 1 Step SQU
      If iy + HalfY > FullH - 1 Then
         iy = FullH - 1 - HalfY
      End If
         For ix = 0 To FullW - 1 Step SQU
            MozaicCAL SQU, HalfX, HalfY
         Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub MozaicCAL(ByVal SQU As Long, HalfX As Long, HalfY As Long)
Dim iix As Long, iiy As Long
Dim ix1 As Long, iy1 As Long
Dim LR As Long, LG As Long, LB As Long
Dim SR As Long, SG As Long, sb As Long
   ix1 = ix
   If ix1 + HalfX > FullW - 1 Then
      ix1 = FullW - 1 - HalfX
   End If
   iy1 = iy
   If iy1 + HalfY > FullH - 1 Then
      iy1 = FullH - 1 - HalfY
   End If
   
   LB = picDATAORG(0, ix1 + HalfX, iy1 + HalfY)
   LG = picDATAORG(1, ix1 + HalfX, iy1 + HalfY)
   LR = picDATAORG(2, ix1 + HalfX, iy1 + HalfY)
      
   For iiy = iy1 To iy1 + SQU - 1
      If (iiy <= FullH - 1) And (iiy >= 0) Then
         For iix = ix1 To ix1 + SQU - 1
            If (iix <= FullW - 1) And (iix >= 0) Then
               
               If iix = ix1 Or iiy = iy Or _
                  iix = ix1 + SQU - 1 Or iiy = iy + SQU - 1 Then
                     If aSelectAccepted Then
                     
                        If (iix >= LOX And iix <= HIX) And (iiy >= LOY And iiy <= HIY) Then
                           If Not aExternal Then   ' Internal
                              If MaskArray(iix - LOX, iiy - LOY) = 0 Then MozaicSubCALC iix, iiy
                           Else  'External
                              If MaskArray(iix - LOX, iiy - LOY) <> 0 Then MozaicSubCALC iix, iiy
                           End If
                        Else
                           If aExternal Then MozaicSubCALC iix, iiy
                        End If
                     Else
                        MozaicSubCALC iix, iiy
                     End If
               Else
                     If aSelectAccepted Then
                     
                        If (iix >= LOX And iix <= HIX) And (iiy >= LOY And iiy <= HIY) Then
                           If Not aExternal Then   ' Internal
                              If MaskArray(iix - LOX, iiy - LOY) = 0 Then MozaicSubCALC2 iix, iiy, LB, LG, LR
                           Else  'External
                              If MaskArray(iix - LOX, iiy - LOY) <> 0 Then MozaicSubCALC2 iix, iiy, LB, LG, LR
                           End If
                        Else
                           If aExternal Then MozaicSubCALC2 iix, iiy, LB, LG, LR
                        End If
                     Else
                        MozaicSubCALC2 iix, iiy, LB, LG, LR
                     End If
               End If
            End If
         Next iix
      End If
   Next iiy
End Sub

Private Sub MozaicSubCALC(iix As Long, iiy As Long)
Dim SR As Long, SG As Long, sb As Long
      sb = picDATAORG(0, iix, iiy) - (10 * Rnd - 5)
      SG = picDATAORG(1, iix, iiy) - (10 * Rnd - 5)
      SR = picDATAORG(2, iix, iiy) - (10 * Rnd - 5)
      If sb < 0 Then sb = 0 Else If sb > 255 Then sb = 255
      If SG < 0 Then SG = 0 Else If SG > 255 Then SG = 255
      If SR < 0 Then SR = 0 Else If SR > 255 Then SR = 255
      picDATA(0, iix, iiy) = sb
      picDATA(1, iix, iiy) = SG
      picDATA(2, iix, iiy) = SR
End Sub
Private Sub MozaicSubCALC2(iix As Long, iiy As Long, LB As Long, LG As Long, LR As Long)
   picDATA(0, iix, iiy) = LB
   picDATA(1, iix, iiy) = LG
   picDATA(2, iix, iiy) = LR
End Sub

Public Sub Oil(POIL As Long)
' POIL  1 -> 3  SLOW
Dim HH As Long, WW As Long
   'ReDim IndexK(0 To 85)
   HH = (POIL + 1) \ 2
   If HH < 1 Then HH = 1
   WW = HH
   
   
   StartProgress HIY
   For iy = 0 + HH To FullH - 1
   For ix = 0 + WW To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then OilCALC POIL, HH, WW
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then OilCALC POIL, HH, WW
            End If
         Else
            If aExternal Then OilCALC POIL, HH, WW
         End If
      Else  ' Selection OFF
         OilCALC POIL, HH, WW
      End If
   Next ix
   DrawProgress
   If aniDone Then Exit For
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub OilCALC(POIL As Long, HH As Long, WW As Long)
' Private ix As Long, iy As Long     ' Image data array scanning
Dim SGrey As Long
Dim NN As Long
Dim LR As Long, LG As Long, LB As Long
'Dim LRMAX As Long, LGMAX As Long, LBMAX As Long
Dim ii As Long, jj As Long
Dim IndexCul(0 To 2, 0 To 85) As Long
         
ReDim Hist(0 To 85)  ' 255\3=85
         
         For jj = iy - POIL To iy + POIL
            'If jj > LOY + HH Then
            'If jj <= HIY Then
               
            If jj > HH Then
            If jj <= FullH - 1 Then
               
               
               For ii = ix - POIL To ix + POIL
                  'If ii > LOX + WW Then
                  'If ii <= HIX Then
                     
                  If ii > WW Then
                  If ii <= FullW - 1 Then
                     
                     LB = picDATAORG(0, ii, jj)
                     LG = picDATAORG(1, ii, jj)
                     LR = picDATAORG(2, ii, jj)
                     SGrey = (0.3 * LG + 0.6 * LG + 0.1 * LB) \ 3
                     ' Make grey histogram
                     Hist(SGrey) = Hist(SGrey) + 1
                     
                     IndexCul(0, SGrey) = LB
                     IndexCul(1, SGrey) = LG
                     IndexCul(2, SGrey) = LR
                  End If
                  End If
               Next ii
            End If
            End If
         Next jj
         NN = 0
         ' Find color with max grey @ ix,iy - could do binary search?
         For k = 0 To 85
            If Hist(k) > NN Then
               NN = Hist(k)
               LB = IndexCul(0, k)
               LG = IndexCul(1, k)
               LR = IndexCul(2, k)
            End If
         Next k
         picDATA(0, ix, iy) = LB
         picDATA(1, ix, iy) = LG
         picDATA(2, ix, iy) = LR
End Sub

Public Sub HighLighting(HL As Long)
' Adapted from Niranjan Paudyal (2002)
' not on PSC anymore

' HighLight  HL = 0 to 7

Dim QB(0 To 255) As Long
Dim QG(0 To 255) As Long
Dim QR(0 To 255) As Long
Dim dx As Long, DY As Long
Dim HB As Long, HG As Long, HR As Long
Dim XYB As Long, xyG As Long, XYR As Long
Dim Offset As Long
Dim ixx As Long, iyy As Long

For dx = 0 To 255
   QB(dx) = 2 * dx
   QG(dx) = 2 * dx
   QR(dx) = 2 * dx
Next dx

Offset = 3

Select Case HL
Case 0: dx = -Offset: DY = 0    ' R
Case 1: dx = -Offset: DY = -Offset   ' TR
Case 2: dx = 0: DY = -Offset    ' T
Case 3: dx = Offset: DY = -Offset    ' TL
Case 4: dx = Offset: DY = 0     ' L
Case 5: dx = Offset: DY = Offset     ' BL
Case 6: dx = 0: DY = Offset     ' B
Case 7: dx = -Offset: DY = Offset    ' BR
End Select

   StartProgress (HIY - Offset)
   picDATA() = picDATAORG()
   For iy = 0 + Offset To FullH - 1 - Offset
   For ix = 0 + Offset To FullW - 1 - Offset
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then HighLightingCALC QB(), QG(), QR(), dx, DY
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then HighLightingCALC QB(), QG(), QR(), dx, DY
            End If
         Else
            If aExternal Then HighLightingCALC QB(), QG(), QR(), dx, DY
         End If
      Else  ' Selection OFF
         HighLightingCALC QB(), QG(), QR(), dx, DY
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub HighLightingCALC(QB() As Long, QG() As Long, QR() As Long, _
                             dx As Long, DY As Long)
Dim HB As Long, HG As Long, HR As Long
Dim XYB As Long, xyG As Long, XYR As Long
      
      XYB = picDATAORG(0, ix, iy)
      xyG = picDATAORG(1, ix, iy)
      XYR = picDATAORG(2, ix, iy)
      HB = Abs(QB(XYB) - picDATAORG(0, ix + dx, iy + DY))
      HG = Abs(QG(xyG) - picDATAORG(1, ix + dx, iy + DY))
      HR = Abs(QR(XYR) - picDATAORG(2, ix + dx, iy + DY))
      
      If HB < 0 Then HB = 0 Else If HB > 255 Then HB = 255
      If HG < 0 Then HG = 0 Else If HG > 255 Then HG = 255
      If HR < 0 Then HR = 0 Else If HR > 255 Then HR = 255
      picDATA(0, ix, iy) = HB
      picDATA(1, ix, iy) = HG
      picDATA(2, ix, iy) = HR
End Sub

Public Sub LaplaceQ(ByVal LaplaceVal As Long)
' LaplaceVal 0 -> 2
'Private q(-1 To 1, -1 To 1)

'  0  -1  0    -1  -1  -1     -1  -2  -1
' -1   4 -1    -1   8  -1     -2  12  -2
'  0  -1  0    -1  -1  -1     -1  -2  -1

Dim LR As Byte, LG As Byte, LB As Byte
Dim i As Long, j As Long
Dim RR As Byte, RG As Byte, RB As Byte


LngToRGB RightColor, RR, RG, RB
LngToRGB LeftColor, LR, LG, LB
   
   picDATA() = picDATAORG()
   Select Case LaplaceVal
   Case 0, 3  ' Laplace 0 Weak
      q(-1, -1) = 0: q(0, -1) = -1: q(1, -1) = 0
      q(-1, 0) = -1:  q(0, 0) = 4:  q(1, 0) = -1
      q(-1, 1) = 0:  q(0, 1) = -1:  q(1, 1) = 0
   Case 1, 4  ' Laplace 1 Med
      q(-1, -1) = -1: q(0, -1) = -1: q(1, -1) = -1
      q(-1, 0) = -1:  q(0, 0) = 8:  q(1, 0) = -1
      q(-1, 1) = -1:  q(0, 1) = -1:  q(1, 1) = -1
   Case 2, 5 ' Laplace 2 Strong
      q(-1, -1) = -1: q(0, -1) = -2: q(1, -1) = -1
      q(-1, 0) = -2:  q(0, 0) = 12:  q(1, 0) = -2
      q(-1, 1) = -1:  q(0, 1) = -2:  q(1, 1) = -1
   End Select
   
   B = 0: g = 0: r = 0
   
   StartProgress (HIY - 1)
   For iy = 1 To FullH - 2 'Step 2
   For ix = 1 To FullW - 2 'Step 2
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then LaplaceCALCQ LaplaceVal
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then LaplaceCALCQ LaplaceVal
            End If
         Else
            If aExternal Then LaplaceCALCQ LaplaceVal
         End If
      Else  ' Selection OFF
         LaplaceCALCQ LaplaceVal
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub LaplaceCALCQ(OVALU As Long)
' Private q(-1 To 1, -1 To 1)
Dim RR As Byte, RG As Byte, RB As Byte
Dim GAV As Long
      LngToRGB RightColor, RR, RG, RB

      B = 0: g = 0: r = 0
      For j = -1 To 1
      For i = -1 To 1
         B = B + q(i, j) * picDATAORG(0, ix + i, iy + j)
         g = g + q(i, j) * picDATAORG(1, ix + i, iy + j)
         r = r + q(i, j) * picDATAORG(2, ix + i, iy + j)
      Next i
      Next j

      B = B + RB
      g = g + RG
      r = r + RR
   
   If OVALU <= 2 Then
      ' Colored
      If B < 0 Then B = 0 Else If B > 255 Then B = 255
      If g < 0 Then g = 0 Else If g > 255 Then g = 255
      If r < 0 Then r = 0 Else If r > 255 Then r = 255
      picDATA(0, ix, iy) = B
      picDATA(1, ix, iy) = g
      picDATA(2, ix, iy) = r
   
   Else
      ' B/W
      GAV = (B + g + r) / 3
      If GAV < 0 Then GAV = 0 Else If GAV > 255 Then GAV = 255
      If GAV > 128 Then GAV = 255 Else GAV = 0
      picDATA(0, ix, iy) = GAV
      picDATA(1, ix, iy) = GAV
      picDATA(2, ix, iy) = GAV
   End If
End Sub



Public Sub Pixelize(ByVal PSquare As Long)
'PSQUARE 1 to 16
' NB averages over block rather than take a spot color
   
   picDATA() = picDATAORG()
   
   ' Aspect ?? PSQY PSQX
   If PSquare = 0 Then PSquare = 1
   
   StartProgress (HIY - 1)
   picData2() = picDATA()
   For iy = 0 To FullH - 1 Step PSquare
   For ix = 0 To FullW - 1 Step PSquare
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then PixelizeCALC PSquare
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then PixelizeCALC PSquare
            End If
         Else
            If aExternal Then PixelizeCALC PSquare
         End If
      Else  ' Selection OFF
         PixelizeCALC PSquare
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub PixelizeCALC(PSQ As Long)
' Private ix as Long, iy As Long

'Public Sub BresBoxFill( ByVal ix1 As Long, ByVal iy1 As Long, ByVal ix2 As Long, ByVal iy2 As Long, _
'   Cul As Long, Optional ByVal psize As Long = 1, Optional ByVal Convert As Long = 0)
Dim cx As Long, cy As Long
Dim Cul As Long
   cx = ix
   cy = iy
      Cul = RGB(picDATAORG(2, cx, cy), picDATAORG(1, cx, cy), picDATAORG(0, cx, cy))
      BresBoxFill cx - PSQ / 2, cy - PSQ / 2, cx + PSQ / 2, cy + PSQ / 2, Cul
End Sub

Public Sub Posterize(Poster As Long)
' POSTER 32 -> 224
'255*(1 + (R1 - 128)/abs(R1 - 128))/2
'255*(1 + (G1 - 128)/abs(G1 - 128))/2
'255*(1 + (B1 - 128)/abs(B1 - 128))/2
Dim RR As Byte, RG As Byte, RB As Byte
   LngToRGB RightColor, RR, RG, RB
   
   
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then PosterizeCALC Poster, RB, RG, RR
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then PosterizeCALC Poster, RB, RG, RR
            End If
         Else
            If aExternal Then PosterizeCALC Poster, RB, RG, RR
         End If
      Else  ' Selection OFF
         PosterizeCALC Poster, RB, RG, RR
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub PosterizeCALC(Poster As Long, RB As Byte, RG As Byte, RR As Byte)
'255*(1 + (R1 - 128)/abs(R1 - 128))/2
'255*(1 + (G1 - 128)/abs(G1 - 128))/2
'255*(1 + (B1 - 128)/abs(B1 - 128))/2
Dim LR As Long, LG As Long, LB As Long
Dim pR As Long, pG As Long, pB As Long
      'Backcolor = RightColor
      pB = (picDATAORG(1, ix, iy) - Poster)
      If pB = 0 Then
         LB = RB
      Else
         LB = RB * (1 + pB / Abs(pB)) / 2
      End If
      pG = (picDATAORG(1, ix, iy) - Poster)
      If pG = 0 Then
         LG = RG
      Else
         LG = RG * (1 + pG / Abs(pG)) / 2
      End If
      pR = (picDATAORG(2, ix, iy) - Poster)
      If pR = 0 Then
         LR = RR
      Else
         LR = RR * (1 + pR / Abs(pR)) / 2
      End If
      
      If LB < 0 Then LB = 0 Else If LB > 255 Then LB = 255
      If LG < 0 Then LG = 0 Else If LG > 255 Then LG = 255
      If LR < 0 Then LR = 0 Else If LR > 255 Then LR = 255
      picDATA(0, ix, iy) = LB
      picDATA(1, ix, iy) = LG
      picDATA(2, ix, iy) = LR
End Sub

Public Sub Relief(PRelief As Long)
'PRELIEF As Long        ' 1,2,3
'+2 +1  0
'+1  0 -1
'0  -1 -2
Dim n  As Long
Dim RR As Byte, RG As Byte, RB As Byte
   LngToRGB RightColor, RR, RG, RB
   
   picDATA() = picDATAORG()
   
   StartProgress (PRelief * FullH - 1)
   For n = 1 To PRelief
      ReDim picData2(0 To 3, 0 To FullW - 1, 0 To FullH - 1)
      picData2() = picDATA()
   
      For iy = 1 To FullH - 2
      For ix = 1 To FullW - 2
         If aSelectAccepted Then ' Selection ON
            If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
               If Not aExternal Then   ' Internal
                  If MaskArray(ix - LOX, iy - LOY) = 0 Then ReliefCALC RB, RG, RR
               Else  'External
                  If MaskArray(ix - LOX, iy - LOY) <> 0 Then ReliefCALC RB, RG, RR
               End If
            Else
               If aExternal Then ReliefCALC RB, RG, RR
            End If
         Else  ' Selection OFF
            ReliefCALC RB, RG, RR
         End If
      Next ix
      DrawProgress
      Next iy
   
      picDATA() = picData2()
   Next n
   
   frmFilters.picPB.Cls
   frmFilters.Refresh
End Sub

Private Sub ReliefCALC(RB As Byte, RG As Byte, RR As Byte)
' RB,RG,RR = Backcolor
Dim LR As Long, LG As Long, LB As Long
'+2 +1  0
'+1  0 -1
'0  -1 -2
         LR = 0: LG = 0: LB = 0
         LB = LB + 2& * picDATA(0, ix - 1, iy + 1)
         LG = LG + 2& * picDATA(1, ix - 1, iy + 1)
         LR = LR + 2& * picDATA(2, ix - 1, iy + 1)
         
         LB = LB + picDATA(0, ix, iy + 1)
         LG = LG + picDATA(1, ix, iy + 1)
         LR = LR + picDATA(2, ix, iy + 1)
         
         LB = LB + picDATA(0, ix - 1, iy)
         LG = LG + picDATA(1, ix - 1, iy)
         LR = LR + picDATA(2, ix - 1, iy)
         
         LB = LB - 2& * picDATA(0, ix + 1, iy - 1)
         LG = LG - 2& * picDATA(1, ix + 1, iy - 1)
         LR = LR - 2& * picDATA(2, ix + 1, iy - 1)
         
         LB = LB - picDATA(0, ix, iy - 1)
         LG = LG - picDATA(1, ix, iy - 1)
         LR = LR - picDATA(2, ix, iy - 1)
         
         LB = LB - picDATA(0, ix + 1, iy)
         LG = LG - picDATA(1, ix + 1, iy)
         LR = LR - picDATA(2, ix + 1, iy)
         
         'Backcolor = RightColor
         LB = (LB + picDATA(0, ix, iy) + RB) \ 3
         LG = (LG + picDATA(1, ix, iy) + RG) \ 3
         LR = (LR + picDATA(2, ix, iy) + RR) \ 3
         
         If LB < 0 Then LB = 0 Else If LB > 255 Then LB = 255
         If LG < 0 Then LG = 0 Else If LG > 255 Then LG = 255
         If LR < 0 Then LR = 0 Else If LR > 255 Then LR = 255
         picData2(0, ix, iy) = LB
         picData2(1, ix, iy) = LG
         picData2(2, ix, iy) = LR
End Sub

Public Sub Erode(PAR As Long)
' PAR 1 - 16
Dim Par8 As Long
   Par8 = PAR * 8
   picDATA() = picDATAORG()
   
   StartProgress HIY / 8
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then ErodeCALC Par8 ', ix, iy
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then ErodeCALC Par8 ', ix, iy
            End If
         Else
            If aExternal Then ErodeCALC Par8 ', ix, iy
         End If
      Else  ' Selection OFF
         ErodeCALC Par8 ', ix, iy
      End If
   Next ix
   DrawProgress
   Next iy

   frmFilters.picPB.Cls
End Sub

Private Sub ErodeCALC(Par8 As Long) ', ix As Long, iy As Long)
' Par8 = 8 to 48
' Erode.................
   B = picDATAORG(0, ix, iy)
   g = picDATAORG(1, ix, iy)
   r = picDATAORG(2, ix, iy)
   B = Abs(B Xor Par8)
   g = Abs(g Xor Par8)
   r = Abs(r Xor Par8)
   picDATA(0, ix, iy) = B
   picDATA(1, ix, iy) = g
   picDATA(2, ix, iy) = r
   picDATA(0, ix, iy) = B
   picDATA(1, ix, iy) = g
   picDATA(2, ix, iy) = r
      
End Sub

Public Sub Solarize(PSOLAR As Long)
'PSOLAR  32 -> 224
Dim RR As Byte, RG As Byte, RB As Byte
   
   LngToRGB RightColor, RR, RG, RB
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then SolarizeCALC PSOLAR, RB, RG, RR
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then SolarizeCALC PSOLAR, RB, RG, RR
            End If
         Else
            If aExternal Then SolarizeCALC PSOLAR, RB, RG, RR
         End If
      Else  ' Selection OFF
         SolarizeCALC PSOLAR, RB, RG, RR
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
   frmFilters.Refresh
End Sub

Private Sub SolarizeCALC(PSOLAR As Long, RB As Byte, RG As Byte, RR As Byte)
Dim LR As Long, LG As Long, LB As Long
      LB = picDATAORG(0, ix, iy)
      LG = picDATAORG(1, ix, iy)
      LR = picDATAORG(2, ix, iy)
      If LB < PSOLAR Then LB = 255 - LB
      If LG < PSOLAR Then LG = 255 - LG
      If LR < PSOLAR Then LR = 255 - LR
      
      LB = (LB + RB) \ 2
      LG = (LG + RG) \ 2
      LR = (LR + RR) \ 2
      
      If LB < 0 Then LB = 0 Else If LB > 255 Then LB = 255
      If LG < 0 Then LG = 0 Else If LG > 255 Then LG = 255
      If LR < 0 Then LR = 0 Else If LR > 255 Then LR = 255
      picDATA(0, ix, iy) = LB
      picDATA(1, ix, iy) = LG
      picDATA(2, ix, iy) = LR
End Sub

Public Sub SharpSmooth(SSNum As Long)
'SSNum 1 to 9
Dim mf As Long, df As Long

' SSNum          1234 - 5678
'                Sharp- Smooth
   If SSNum <= 4 Then ' SHARP
      ' SHARP
      '-2 -2 -2
      '-2 mf -2
      '-2 -2 -2 / df
      mf = 24 + SSNum ^ 2.5
      df = 8 + SSNum ^ 2.5
      
      picDATA() = picDATAORG()
      
      StartProgress HIY
      For iy = 1 To FullH - 2
      For ix = 1 To FullW - 2
         If aSelectAccepted Then ' Selection ON
            If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
               If Not aExternal Then   ' Internal
                  If MaskArray(ix - LOX, iy - LOY) = 0 Then SharpCALC mf, df
               Else  'External
                  If MaskArray(ix - LOX, iy - LOY) <> 0 Then SharpCALC mf, df
               End If
            Else
               If aExternal Then SharpCALC mf, df
            End If
         Else  ' Selection OFF
            SharpCALC mf, df
         End If
      Next ix
      DrawProgress
      Next iy
      
   Else  ' SMOOTH
         
         ' SSNum          1234 - 5678        9
         '                Sharp- Smooth    Gausian Very similar to 4
         '  1      2      3        4          5
         '                     1 1 1 1 1   2  4  5  4  2
         '0 0 0  0 1 0  1 1 1  1 1 1 1 1   4  9 12  9  4
         '1 4 1  1 6 1  1 1 1  1 1 1 1 1   5 12 15 12  5
         '0 0 0  0 1 0  1 1 1  1 1 1 1 1   4  9 12  9  4
         '                     1 1 1 1 1   2  4  5  4  2 / 159
         ' Smooths add in (ix,iy)
         
         ' New 1
         ' HB blur   4 1
         '           1
         
      SSNum = SSNum - 4 ' 1,2,3,4 So top of scroll bar is most blurred
      Select Case SSNum
      Case 1   ' HB blur
         
         StartProgress HIY
         For iy = 1 To FullH - 2
         For ix = 1 To FullW - 2
            If aSelectAccepted Then ' Selection ON
               If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
                  If Not aExternal Then   ' Internal
                     If MaskArray(ix - LOX, iy - LOY) = 0 Then SmoothCALC1
                  Else  'External
                     If MaskArray(ix - LOX, iy - LOY) <> 0 Then SmoothCALC1
                  End If
               Else
                  If aExternal Then SmoothCALC1
               End If
            Else  ' Selection OFF
               SmoothCALC1
            End If
         Next ix
         DrawProgress
         Next iy
         
      Case 2   ' Cross blur
            
         StartProgress HIY
         For iy = 1 To FullH - 2
         For ix = 1 To FullW - 2
            If aSelectAccepted Then ' Selection ON
               If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
                  If Not aExternal Then   ' Internal
                     If MaskArray(ix - LOX, iy - LOY) = 0 Then SmoothCALC2
                  Else  'External
                     If MaskArray(ix - LOX, iy - LOY) <> 0 Then SmoothCALC2
                  End If
               Else
                  If aExternal Then SmoothCALC2
               End If
            Else  ' Selection OFF
               SmoothCALC2
            End If
         Next ix
         DrawProgress
         Next iy
         
      Case 3   ' Surr blur 1
            
         StartProgress HIY
         For iy = 1 To FullH - 2
         For ix = 1 To FullW - 2
            If aSelectAccepted Then ' Selection ON
               If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
                  If Not aExternal Then   ' Internal
                     If MaskArray(ix - LOX, iy - LOY) = 0 Then SmoothCALC3
                  Else  'External
                     If MaskArray(ix - LOX, iy - LOY) <> 0 Then SmoothCALC3
                  End If
               Else
                  If aExternal Then SmoothCALC3
               End If
            Else  ' Selection OFF
               SmoothCALC3
            End If
         Next ix
         DrawProgress
         Next iy
         
      Case 4   ' Surr blur 2
            
         StartProgress HIY
         For iy = 2 To FullH - 3
         For ix = 2 To FullW - 3
            If aSelectAccepted Then ' Selection ON
               If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
                  If Not aExternal Then   ' Internal
                     If MaskArray(ix - LOX, iy - LOY) = 0 Then SmoothCALC4
                  Else  'External
                     If MaskArray(ix - LOX, iy - LOY) <> 0 Then SmoothCALC4
                  End If
               Else
                  If aExternal Then SmoothCALC4
               End If
            Else  ' Selection OFF
               SmoothCALC4
            End If
         Next ix
         DrawProgress
         Next iy
         
      Case 5   ' Gaussian
            
         StartProgress HIY
         For iy = 2 To FullH - 3
         For ix = 2 To FullW - 3
            If aSelectAccepted Then ' Selection ON
               If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
                  If Not aExternal Then   ' Internal
                     If MaskArray(ix - LOX, iy - LOY) = 0 Then SmoothCALC5
                  Else  'External
                     If MaskArray(ix - LOX, iy - LOY) <> 0 Then SmoothCALC5
                  End If
               Else
                  If aExternal Then SmoothCALC5
               End If
            Else  ' Selection OFF
               SmoothCALC5
            End If
         Next ix
         DrawProgress
         Next iy
            
      End Select
         
      If Not aSelectAccepted Then
         For iy = LOY + 1 To HIY - 1
            SmoothVertEdges
         Next iy
         For ix = LOX + 1 To HIX - 1
            SmoothHorzEdges
         Next ix
      End If
         
         ' Corners ?
         
   End If   ' Sharp Smooth

   frmFilters.picPB.Cls
End Sub

Private Sub SharpCALC(mf As Long, df As Long)
            B = 0: g = 0: r = 0
            For j = iy - 1 To iy + 1
            For i = ix - 1 To ix + 1
               If (j <> iy Or i <> ix) Then
                  B = B - 2 * picDATA(0, i, j)
                  g = g - 2 * picDATA(1, i, j)
                  r = r - 2 * picDATA(2, i, j)
               Else
                  B = B + mf * picDATA(0, i, j)
                  g = g + mf * picDATA(1, i, j)
                  r = r + mf * picDATA(2, i, j)
               End If
            Next i
            Next j
            B = B \ df
            r = r \ df
            g = g \ df
            If B < 0 Then B = 0 Else If B > 255 Then B = 255
            If g < 0 Then g = 0 Else If g > 255 Then g = 255
            If r < 0 Then r = 0 Else If r > 255 Then r = 255
            picDATA(0, ix, iy) = B
            picDATA(1, ix, iy) = g
            picDATA(2, ix, iy) = r
End Sub

Private Sub SmoothCALC1()
' HB blur   4 1
'           1
'
         B = 0: g = 0: r = 0
         
         B = B + 4 * picDATAORG(0, ix, iy)
         g = g + 4 * picDATAORG(1, ix, iy)
         r = r + 4 * picDATAORG(2, ix, iy)
         
         B = B + picDATAORG(0, ix, iy + 1)
         g = g + picDATAORG(1, ix, iy + 1)
         r = r + picDATAORG(2, ix, iy + 1)
         
         B = B + picDATAORG(0, ix + 1, iy)
         g = g + picDATAORG(1, ix + 1, iy)
         r = r + picDATAORG(2, ix + 1, iy)
         
         B = B \ 6
         g = g \ 6
         r = r \ 6
         picDATA(0, ix, iy) = B
         picDATA(1, ix, iy) = g
         picDATA(2, ix, iy) = r
End Sub

Private Sub SmoothCALC2()
' Cross blurr +
         B = 0: g = 0: r = 0
         
         B = B + 6 * picDATAORG(0, ix, iy)
         g = g + 6 * picDATAORG(1, ix, iy)
         r = r + 6 * picDATAORG(2, ix, iy)
         
         B = B + picDATAORG(0, ix, iy - 1)
         g = g + picDATAORG(1, ix, iy - 1)
         r = r + picDATAORG(2, ix, iy - 1)
         
         B = B + picDATAORG(0, ix, iy + 1)
         g = g + picDATAORG(1, ix, iy + 1)
         r = r + picDATAORG(2, ix, iy + 1)
         
         B = B + picDATAORG(0, ix - 1, iy)
         g = g + picDATAORG(1, ix - 1, iy)
         r = r + picDATAORG(2, ix - 1, iy)
         
         B = B + picDATAORG(0, ix + 1, iy)
         g = g + picDATAORG(1, ix + 1, iy)
         r = r + picDATAORG(2, ix + 1, iy)
         
         B = B \ 10 '5
         g = g \ 10 '5
         r = r \ 10 '5
         picDATA(0, ix, iy) = B
         picDATA(1, ix, iy) = g
         picDATA(2, ix, iy) = r
End Sub

Private Sub SmoothCALC3()
' Surr blur 1
         B = 0: g = 0: r = 0
         For j = iy - 1 To iy + 1
         For i = ix - 1 To ix + 1
            B = B + picDATAORG(0, i, j)
            g = g + picDATAORG(1, i, j)
            r = r + picDATAORG(2, i, j)
         Next i
         Next j
         B = B \ 9
         g = g \ 9
         r = r \ 9
         picDATA(0, ix, iy) = B
         picDATA(1, ix, iy) = g
         picDATA(2, ix, iy) = r
End Sub

Private Sub SmoothCALC4()
' Surr blur 2
         B = 0: g = 0: r = 0
         For j = iy - 2 To iy + 2
         For i = ix - 2 To ix + 2
            B = B + picDATAORG(0, i, j)
            g = g + picDATAORG(1, i, j)
            r = r + picDATAORG(2, i, j)
         Next i
         Next j
         B = B \ 25
         g = g \ 25
         r = r \ 25
         picDATA(0, ix, iy) = B
         picDATA(1, ix, iy) = g
         picDATA(2, ix, iy) = r
End Sub

Private Sub SmoothCALC5()
' Gaussian

'        5
'  2  4  5  4  2
'  4  9 12  9  4
'  5 12 15 12  5
'  4  9 12  9  4
'  2  4  5  4  2 / 159
Dim ii As Long, jj As Long
Dim m(-2 To 2, -2 To 2) As Long

m(-2, -2) = 1: m(-2, -1) = 4: m(-2, 0) = 7: m(-2, 1) = 4: m(-2, 2) = 1
m(-1, -2) = 4: m(-1, -1) = 16: m(-1, 0) = 26: m(-1, 1) = 16: m(-1, 2) = 4
m(0, -2) = 7: m(0, -1) = 26: m(0, 0) = 41: m(0, 1) = 26: m(0, 2) = 7
m(1, -2) = 4: m(1, -1) = 16: m(1, 0) = 26: m(1, 1) = 16: m(1, 2) = 4
m(2, -2) = 1: m(2, -1) = 4: m(2, 0) = 7: m(2, 1) = 4: m(2, 2) = 1

      B = 0: g = 0: r = 0
      For j = iy - 2 To iy + 2
      jj = j - iy
      For i = ix - 2 To ix + 2
         ii = i - ix
         B = B + m(ii, jj) * picDATAORG(0, i, j)
         g = g + m(ii, jj) * picDATAORG(1, i, j)
         r = r + m(ii, jj) * picDATAORG(2, i, j)
      Next i
      Next j
      B = B \ 273 '159
      g = g \ 273 '159
      r = r \ 273 '159
      picDATA(0, ix, iy) = B
      picDATA(1, ix, iy) = g
      picDATA(2, ix, iy) = r

End Sub

Private Sub SmoothVertEdges()
      B = 0: g = 0: r = 0  ' Left
      B = B + picDATAORG(0, 0, iy - 1)
      B = B + picDATAORG(0, 0, iy)
      B = B + picDATAORG(0, 0, iy + 1)
      
      g = g + picDATAORG(1, 0, iy - 1)
      g = g + picDATAORG(1, 0, iy)
      g = g + picDATAORG(1, 0, iy + 1)
      
      r = r + picDATAORG(2, 0, iy - 1)
      r = r + picDATAORG(2, 0, iy)
      r = r + picDATAORG(2, 0, iy + 1)
      
      B = B \ 3
      g = g \ 3
      r = r \ 3
      picDATA(0, 0, iy) = B
      picDATA(1, 0, iy) = g
      picDATA(2, 0, iy) = r
      
      B = 0: g = 0: r = 0  ' Right
      B = B + picDATAORG(0, FullW - 1, iy - 1)
      B = B + picDATAORG(0, FullW - 1, iy)
      B = B + picDATAORG(0, FullW - 1, iy + 1)
      
      g = g + picDATAORG(1, FullW - 1, iy - 1)
      g = g + picDATAORG(1, FullW - 1, iy)
      g = g + picDATAORG(1, FullW - 1, iy + 1)
      
      r = r + picDATAORG(2, FullW - 1, iy - 1)
      r = r + picDATAORG(2, FullW - 1, iy)
      r = r + picDATAORG(2, FullW - 1, iy + 1)
      
      B = B \ 3
      g = g \ 3
      r = r \ 3
      picDATA(0, FullW - 1, iy) = B
      picDATA(1, FullW - 1, iy) = g
      picDATA(2, FullW - 1, iy) = r
End Sub

Private Sub SmoothHorzEdges()
      B = 0: g = 0: r = 0  ' Bottom
      B = B + picDATAORG(0, ix - 1, 0)
      B = B + picDATAORG(0, ix, 0)
      B = B + picDATAORG(0, ix + 1, 0)
      
      g = g + picDATAORG(1, ix - 1, 0)
      g = g + picDATAORG(1, ix, 0)
      g = g + picDATAORG(1, ix + 1, 0)
      
      r = r + picDATAORG(2, ix - 1, 0)
      r = r + picDATAORG(2, ix, 0)
      r = r + picDATAORG(2, ix + 1, 0)
      
      B = B \ 3
      g = g \ 3
      r = r \ 3
      picDATA(0, ix, 0) = B
      picDATA(1, ix, 0) = g
      picDATA(2, ix, 0) = r
      
      B = 0: g = 0: r = 0  ' Top
      B = B + picDATAORG(0, ix - 1, FullH - 1)
      B = B + picDATAORG(0, ix, FullH - 1)
      B = B + picDATAORG(0, ix + 1, FullH - 1)
      
      g = g + picDATAORG(1, ix - 1, FullH - 1)
      g = g + picDATAORG(1, ix, FullH - 1)
      g = g + picDATAORG(1, ix + 1, FullH - 1)
      
      r = r + picDATAORG(2, ix - 1, FullH - 1)
      r = r + picDATAORG(2, ix, FullH - 1)
      r = r + picDATAORG(2, ix + 1, FullH - 1)
      
      B = B \ 3
      g = g \ 3
      r = r \ 3
      picDATA(0, ix, iy) = B
      picDATA(1, ix, iy) = g
      picDATA(2, ix, iy) = r
End Sub

Public Sub EngraveEmboss(EEPAR As Long)
' EEPAR  -3 -> 3
'+1 0 -1    -1  0  +1
'+1 0 -1    -1  0  +1
'+1 0 -1    -1  0  +1
Dim zEEPAR As Single
Dim RR As Byte, RG As Byte, RB As Byte
   
   LngToRGB RightColor, RR, RG, RB
   
   zEEPAR = EEPAR
   If EEPAR = 0 Then zEEPAR = 0.5 'EEPAR = 1 else all grey
   
   StartProgress HIY
   For iy = 1 To FullH - 2
   For ix = 1 To FullW - 2
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then EngraveEmbossCALC zEEPAR, RB, RG, RR
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then EngraveEmbossCALC zEEPAR, RB, RG, RR
            End If
         Else
            If aExternal Then EngraveEmbossCALC zEEPAR, RB, RG, RR
         End If
      Else  ' Selection OFF
         EngraveEmbossCALC zEEPAR, RB, RG, RR
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub EngraveEmbossCALC(zEEPAR As Single, RB As Byte, RG As Byte, RR As Byte)
'+1 0 -1    -1  0  +1
'+1 0 -1    -1  0  +1
'+1 0 -1    -1  0  +1
      B = 0: g = 0: r = 0
      For j = iy - 1 To iy + 1
      For i = ix - 1 To ix + 1
         If i <> ix Then
            If i = ix + 1 Then
               B = B - zEEPAR * picDATAORG(0, i, j)
               g = g - zEEPAR * picDATAORG(1, i, j)
               r = r - zEEPAR * picDATAORG(2, i, j)
            Else  ' i=ix-1
               B = B + zEEPAR * picDATAORG(0, i, j)
               g = g + zEEPAR * picDATAORG(1, i, j)
               r = r + zEEPAR * picDATAORG(2, i, j)
            End If
         End If
      Next i
      Next j
      'Backcolor = RightColor
      B = B + RB
      g = g + RG
      r = r + RR
      If B < 0 Then B = 0 Else If B > 255 Then B = 255
      If g < 0 Then g = 0 Else If g > 255 Then g = 255
      If r < 0 Then r = 0 Else If r > 255 Then r = 255
      picDATA(0, ix, iy) = B
      picDATA(1, ix, iy) = g
      picDATA(2, ix, iy) = r
End Sub

Public Sub Litho(PLITHO As Long)
' PLITHO 92 -> 100

'-1  -1  -1  -1 -1
'-1 -10 -10 -10 -1
'-1 -10  96 -10 -1
'-1 -10 -10 -10 -1
'-1  -1  -1  -1 -1
   
   StartProgress HIY
   For iy = 2 To FullH - 3
   For ix = 2 To FullW - 3
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then LithoCALC PLITHO
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then LithoCALC PLITHO
            End If
         Else
            If aExternal Then LithoCALC PLITHO
         End If
      Else  ' Selection OFF
         LithoCALC PLITHO
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub LithoCALC(PLITHO As Long)
'-1  -1  -1  -1 -1
'-1 -10 -10 -10 -1
'-1 -10  96 -10 -1
'-1 -10 -10 -10 -1
'-1  -1  -1  -1 -1
Dim LR As Long, LG As Long, LB As Long
     LR = 0: LG = 0: LB = 0
      For j = iy - 2 To iy + 2
      For i = ix - 2 To ix + 2
      
         If (j <> iy Or i <> ix) Then
            If j = iy - 2 Or j = iy + 2 Then
               LB = LB - picDATAORG(0, i, j)
               LG = LG - picDATAORG(1, i, j)
               LR = LR - picDATAORG(2, i, j)
            ElseIf i = ix - 2 Or i = ix + 2 Then
               LB = LB - picDATAORG(0, i, j)
               LG = LG - picDATAORG(1, i, j)
               LR = LR - picDATAORG(2, i, j)
            Else
               LB = LB - 10 * picDATAORG(0, i, j)
               LG = LG - 10 * picDATAORG(1, i, j)
               LR = LR - 10 * picDATAORG(2, i, j)
            End If
         Else
            LB = LB + PLITHO * picDATAORG(0, i, j)
            LG = LG + PLITHO * picDATAORG(1, i, j)
            LR = LR + PLITHO * picDATAORG(2, i, j)
         End If
      Next i
      Next j
      If LB < 0 Then LB = 0 Else If LB > 255 Then LB = 255
      If LG < 0 Then LG = 0 Else If LG > 255 Then LG = 255
      If LR < 0 Then LR = 0 Else If LR > 255 Then LR = 255
      picDATA(0, ix, iy) = LB
      picDATA(1, ix, iy) = LG
      picDATA(2, ix, iy) = LR
End Sub

Public Sub Melt(PMELT As Long)
' PMELT  ' -8 -> 8
Dim n  As Long
Dim NN As Long
Dim iylo As Long, iyhi As Long
Dim ss As Long

   If PMELT = 0 Then Exit Sub
   picDATA() = picDATAORG()
   StartProgress (Abs(PMELT) * (HIY))
   
   For n = 1 To Abs(PMELT)
      
      If PMELT > 0 Then ' Melt down
         NN = n   ' 1 to PMELT
         iylo = 0: iyhi = FullH - 1 - NN
         ss = 1
      Else  ' Melt up
         NN = -n  ' -PMELT to -1
         iyhi = 0 + Abs(NN): iylo = FullH - 1
         ss = -1
      End If
      
      For iy = iylo To iyhi Step ss
      For ix = 0 To FullW - 1
         
         If aSelectAccepted Then ' Selection ON
            If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
               If Not aExternal Then   ' Internal
                  If MaskArray(ix - LOX, iy - LOY) = 0 Then MeltCALC NN
               Else  'External
                  If MaskArray(ix - LOX, iy - LOY) <> 0 Then MeltCALC NN
               End If
            Else
               If aExternal Then MeltCALC NN
            End If
         Else  ' Selection OFF
            MeltCALC NN
         End If
      Next ix
      DrawProgress
      Next iy
   
   Next n
   
   frmFilters.picPB.Cls
End Sub

Private Sub MeltCALC(NN As Long)
      B = picDATA(0, ix, iy)
      g = picDATA(1, ix, iy)
      r = picDATA(2, ix, iy)
      B = B - picDATA(0, ix, iy + NN)
      g = g - picDATA(1, ix, iy + NN)
      r = r - picDATA(2, ix, iy + NN)
      r = B + g + r
      If r < 0 Then
         picDATA(0, ix, iy) = picDATA(0, ix, iy + NN)
         picDATA(1, ix, iy) = picDATA(1, ix, iy + NN)
         picDATA(2, ix, iy) = picDATA(2, ix, iy + NN)
      Else
         picDATA(0, ix, iy) = picDATA(0, ix, iy)
         picDATA(1, ix, iy) = picDATA(1, ix, iy)
         picDATA(2, ix, iy) = picDATA(2, ix, iy)
      End If
End Sub


Public Sub Swaps(Index As Integer)
' Index = 3,4,5  - > BG, BR, GR
   picDATA() = picDATAORG()
      
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then SwapCALC Index
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then SwapCALC Index
            End If
         Else
            If aExternal Then SwapCALC Index
         End If
      Else  ' Selection OFF
         SwapCALC Index
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub

Private Sub SwapCALC(Index As Integer)
   Select Case Index
   Case 3 ' Swap BG
      picDATA(0, ix, iy) = picDATAORG(1, ix, iy)
      picDATA(1, ix, iy) = picDATAORG(0, ix, iy)
   Case 4 ' Swap BR
      picDATA(0, ix, iy) = picDATAORG(2, ix, iy)
      picDATA(2, ix, iy) = picDATAORG(0, ix, iy)
   Case 5 ' Swap GR
      picDATA(1, ix, iy) = picDATAORG(2, ix, iy)
      picDATA(2, ix, iy) = picDATAORG(1, ix, iy)
   End Select
End Sub



Public Sub VaryRGB(Index As Integer, Frac As Single)
' Index 0,1,2 - B,G,R   ' Frac 0.0 -> 10.0
   picDATA() = picDATAORG()
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then VaryRGBCALC Index, Frac
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then VaryRGBCALC Index, Frac
            End If
         Else
            If aExternal Then VaryRGBCALC Index, Frac
         End If
      Else  ' Selection OFF
         VaryRGBCALC Index, Frac
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub VaryRGBCALC(Index As Integer, Frac As Single)
' Private Cul As Long
      Cul = 1& * picDATAORG(Index, ix, iy) * Frac
      If Cul > 255 Then Cul = 255
      picDATA(Index, ix, iy) = Cul
End Sub

Public Sub mask()
' Black non-white areas
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then MaskCALC
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then MaskCALC
            End If
         Else
            If aExternal Then MaskCALC
         End If
      Else  ' Selection OFF
         MaskCALC
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub MaskCALC()
   If picDATAORG(0, ix, iy) <> 255 Or _
      picDATAORG(1, ix, iy) <> 255 Or _
      picDATAORG(2, ix, iy) <> 255 Then
      picDATA(0, ix, iy) = 0
      picDATA(1, ix, iy) = 0
      picDATA(2, ix, iy) = 0
   End If
End Sub


Public Sub Whiten(ByVal PAR As Long)
' Nearly white = white  Par 0 to 30
' Can sometimes be useful for making
' a mask from a jpeg, since jpegs may
' tone down white eg RGB 255 to 252
   picDATA() = picDATAORG()
   
   PAR = 255 - PAR
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then WhitenCALC PAR
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then WhitenCALC PAR
            End If
         Else
            If aExternal Then WhitenCALC PAR
         End If
      Else  ' Selection OFF
         WhitenCALC PAR
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub WhitenCALC(ByVal PAR As Long)
   If picDATAORG(0, ix, iy) > PAR Then
   If picDATAORG(1, ix, iy) > PAR Then
   If picDATAORG(2, ix, iy) > PAR Then
      picDATA(0, ix, iy) = 255
      picDATA(1, ix, iy) = 255
      picDATA(2, ix, iy) = 255
   End If
   End If
   End If
End Sub


Public Sub TiltPixels(PAR As Long)
' Par 4 - 16
   picDATA() = picDATAORG()
   
   
   StartProgress HIY / PAR
   For iy = 0 To FullH - 1 Step PAR
   For ix = 0 To FullW - 1 Step PAR
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then TiltPixelsCALC PAR
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then TiltPixelsCALC PAR
            End If
         Else
            If aExternal Then TiltPixelsCALC PAR
         End If
      Else  ' Selection OFF
         TiltPixelsCALC PAR
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub TiltPixelsCALC(PRAD As Long)
' Private ix as Long, iy As Long
Dim cx As Long, cy As Long
Dim Cul As Long
   cx = ix
   cy = iy
      Cul = RGB(picDATAORG(2, cx, cy), picDATAORG(1, cx, cy), picDATAORG(0, cx, cy))
      BresEllipse cx + PRAD / 2, cy + PRAD / 2, PRAD, PRAD, Cul, 1 ' 1 = Fill
End Sub

Public Sub FilterSnow(CulAdd As Long)
' Adapted from DreamVB PSC CodeId=71962
' CulAdd 30 to 200
' CulAdd determines how many pixels are forced over 255
' and hence to white

Dim sstep As Single
Dim AddCul As Long
Dim mR As Long, mG As Long, mB As Long

   picDATA() = picDATAORG()
   
   StartProgress (HIY)
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      AddCul = Int(Rnd * CulAdd)
      mB = picDATAORG(0, ix, iy) + AddCul
      mG = picDATAORG(1, ix, iy) + AddCul
      mR = picDATAORG(2, ix, iy) + AddCul
      If mB > 255 Then mB = 255
      If mG > 255 Then mG = 255
      If mR > 255 Then mR = 255
      If mB < 0 Then mB = 0
      If mG < 0 Then mG = 0
      If mR < 0 Then mR = 0
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then FilterSnowCALC mB, mG, mR
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then FilterSnowCALC mB, mG, mR
            End If
         Else
            If aExternal Then FilterSnowCALC mB, mG, mR
         End If
      Else  ' Selection OFF
          FilterSnowCALC mB, mG, mR
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub FilterSnowCALC(mB As Long, mG As Long, mR As Long)
   picDATA(0, ix, iy) = mB
   picDATA(1, ix, iy) = mG
   picDATA(2, ix, iy) = mR
End Sub

Public Sub EdgeAddSubTract(PAR As Long)
' Par = 0(ADD),1(SUBTRACT,2(SUBTRACT & INVERT

Dim i As Long, j As Long


Select Case PAR

Case 0
'' Grease
'' 0  0  0  0  0
'' 0  1  1  1  0
'' 0  1 -7  1  0
'' 0  1  1  1  0
'' 0  0  0  0  0

   StartProgress (HIY - 2)
   For iy = 1 To FullH - 2
   For ix = 1 To FullW - 2
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then AddEdgeCALC
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then AddEdgeCALC
            End If
         Else
            If aExternal Then AddEdgeCALC
         End If
      Else  ' Selection OFF
         AddEdgeCALC
      End If
   Next ix
   DrawProgress
   Next iy

Case 1, 2

   StartProgress HIY
   For iy = 1 To FullH - 2
   For ix = 1 To FullW - 2
      B = 0
      g = 0
      r = 0
      
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then EdgeSubTractCALC B, g, r, PAR
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then EdgeSubTractCALC B, g, r, PAR
            End If
         Else
            If aExternal Then EdgeSubTractCALC B, g, r, PAR
         End If
      Else  ' Selection OFF
         EdgeSubTractCALC B, g, r, PAR
      End If
      
   Next ix
   DrawProgress
   Next iy

End Select
   
   frmFilters.picPB.Cls
End Sub

Private Sub AddEdgeCALC()
' (This filter template taken from TannerHelland.com)
' Private ix As Long, iy As Long     ' Image data array scanning
' Private i As Long, j As Long
' Private k As Long

Dim LR As Long, LG As Long, LB As Long
Dim AV As Long

' Grease
' o  0  0  0  0
' 0  1  1  1  0
' 0  1 -7  1  0
' 0  1  1  1  0
' 0  0  0  0  0

   LR = 0: LG = 0: LB = 0
   
      For j = iy - 1 To iy + 1
      For i = ix - 1 To ix + 1
         If i = ix And j = iy Then
            LB = LB - 7 * picDATAORG(0, ix, iy)
            LG = LG - 7 * picDATAORG(1, ix, iy)
            LR = LR - 7 * picDATAORG(2, ix, iy)
         Else
            LB = LB + picDATAORG(0, i, j)
            LG = LG + picDATAORG(1, i, j)
            LR = LR + picDATAORG(2, i, j)
         End If
      Next i
      Next j
      
      If LB < 0 Then LB = 0 Else If LB > 255 Then LB = 255
      If LG < 0 Then LG = 0 Else If LG > 255 Then LG = 255
      If LR < 0 Then LR = 0 Else If LR > 255 Then LR = 255
      
      picDATA(0, ix, iy) = LB
      picDATA(1, ix, iy) = LG
      picDATA(2, ix, iy) = LR


End Sub

Private Sub EdgeSubTractCALC(B As Long, g As Long, r As Long, PAR)
Dim i As Long, j As Long
      For j = -1 To 1
      For i = -1 To 1
      
      B = B + Abs(1& * picDATAORG(0, ix, iy) - picDATAORG(0, ix + i, iy + j))
      g = g + Abs(1& * picDATAORG(1, ix, iy) - picDATAORG(1, ix + i, iy + j))
      r = r + Abs(1& * picDATAORG(2, ix, iy) - picDATAORG(2, ix + i, iy + j))
      If B < 0 Then B = 0 Else If B > 255 Then B = 255
      If g < 0 Then g = 0 Else If g > 255 Then g = 255
      If r < 0 Then r = 0 Else If r > 255 Then r = 255
      picDATA(0, ix, iy) = B
      picDATA(1, ix, iy) = g
      picDATA(2, ix, iy) = r
      
      Next i
      Next j
      
      If PAR = 2 Then
         ' And Invert
         picDATA(0, ix, iy) = Not picDATA(0, ix, iy)
         picDATA(1, ix, iy) = Not picDATA(1, ix, iy)
         picDATA(2, ix, iy) = Not picDATA(2, ix, iy)
      End If

End Sub


' Single
Public Sub SolidColor()
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then SolidColorCALC
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then SolidColorCALC
            End If
         Else
            If aExternal Then SolidColorCALC
         End If
      Else  ' Selection OFF
         SolidColorCALC
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub SolidColorCALC()
Dim CR As Long, CG As Long, CB As Long
   CR = picDATAORG(2, ix, iy)
   CG = picDATAORG(1, ix, iy)
   CB = picDATAORG(0, ix, iy)
   SolidPixels CR
   SolidPixels CG
   SolidPixels CB
   picDATA(2, ix, iy) = CR
   picDATA(1, ix, iy) = CG
   picDATA(0, ix, iy) = CB
End Sub

Public Sub SolidGrey()
   
   StartProgress HIY
   For iy = 0 To FullH - 1
   For ix = 0 To FullW - 1
      If aSelectAccepted Then ' Selection ON
         If (ix >= LOX And ix <= HIX) And (iy >= LOY And iy <= HIY) Then
            If Not aExternal Then   ' Internal
               If MaskArray(ix - LOX, iy - LOY) = 0 Then SolidGreyCALC
            Else  'External
               If MaskArray(ix - LOX, iy - LOY) <> 0 Then SolidGreyCALC
            End If
         Else
            If aExternal Then SolidGreyCALC
         End If
      Else  ' Selection OFF
         SolidGreyCALC
      End If
   Next ix
   DrawProgress
   Next iy
   
   frmFilters.picPB.Cls
End Sub
Private Sub SolidGreyCALC()
Dim CR As Long, CG As Long, CB As Long
Dim MeanRGB As Long
   CR = picDATAORG(2, ix, iy)
   CG = picDATAORG(1, ix, iy)
   CB = picDATAORG(0, ix, iy)
   MeanRGB = (CR + CG + CB) / 3
   SolidPixels MeanRGB
   picDATA(2, ix, iy) = MeanRGB
   picDATA(1, ix, iy) = MeanRGB
   picDATA(0, ix, iy) = MeanRGB
End Sub

Private Sub SolidPixels(c As Long)
Dim k As Long
Dim SCul As Long
   SCul = 256
   For k = 1 To 8
      SCul = SCul - k * 32
      If c >= SCul Then
         c = SCul + 32
         Exit For
      End If
   Next k
   If c < 0 Then c = 0
   If c > 255 Then c = 255
End Sub

Private Sub StartProgress(PAR As Long)
' Private xd As Single, xp As Single
' EG: Par = PRELIEF * FullH
   frmFilters.picPB.DrawWidth = 3
   frmFilters.picPB.Cls
   xp = 0
   xd = frmFilters.picPB.Width / PAR
   frmFilters.picPB.PSet (xp, 2), vbRed
End Sub

Private Sub DrawProgress()
Dim FW As Long
' Private xd As Single, xp As Single
   frmFilters.picPB.Line -(xp, 2), vbRed
   frmFilters.picPB.Refresh
   xp = xp + xd
   FW = frmFilters.picPB.Width
'   If FullW > 1500 And FullH > 1500 Then
'      If xp > 0.2 * frmFilters.picPB.Width And xp < 0.3 * FW Then
'         frmFilters.Refresh
'      ElseIf xp > 0.45 * frmFilters.picPB.Width And xp < 0.55 * FW Then
'         frmFilters.Refresh
'      ElseIf xp > 0.7 * frmFilters.picPB.Width And xp < 0.8 * FW Then
'         frmFilters.Refresh
'      End If
'   End If
End Sub
       
