Attribute VB_Name = "fixBlooms"
Option Explicit
Public myDoc As Object
Public deBloomValid
Public errMsg, x
Public boolSaveSettings As Boolean
Public msgForm As Object
Public myStarArray() As Single
Public myStarArray2() As Single, myOriginX, myOriginY
Public myStarArray3() As Single
Public myStarArray4() As Single
Public myStarArray5() As Single
Public myBloomArray2() As Single
Public showRotateDialog, doRotate, OKRotate, scriptingOn, hasBlooms, bloomCounter
Public myArray, myRefArray, myBloomArray() As Single, myAdjust, starFactor, xOffset, yOffset, Distance, newLimit, halfLimit, ulimitX, uLimitY
Public myXCenter, myYCenter, myXCount, myYCount, myStarDoc, starX, starY, showingStars, rotateDisplay, hideStar, showBloom, loadRotateForm
Public bloomLimit, bloomSlope, starSize, starLimit, iter, noiseFactor, starAggressiveness, fillDistance, increment
Public progressBarLength, progressBarIncrement, myBackgroundAvg, isTextChange
Public rotateZoom, showDialogs

Public Const SWP_NOSIZE            As Long = &H1
Public Const SWP_NOMOVE            As Long = &H2
Public Const SWP_NOZORDER          As Long = &H4
Public Const SWP_NOREDRAW          As Long = &H8
Public Const SWP_NOACTIVATE        As Long = &H10
Public Const SWP_FRAMECHANGED      As Long = &H20
Public Const SWP_SHOWWINDOW        As Long = &H40
Public Const SWP_HIDEWINDOW        As Long = &H80
Public Const SWP_NOCOPYBITS        As Long = &H100
Public Const SWP_NOOWNERZORDER     As Long = &H200
Public Const SWP_NOSENDCHANGING    As Long = &H400

Public Const SWP_DRAWFRAME         As Long = SWP_FRAMECHANGED
Public Const SWP_NOREPOSITION      As Long = SWP_NOOWNERZORDER

Public Const HWND_TOP              As Long = 0
Public Const HWND_BOTTOM           As Long = 1
Public Const HWND_TOPMOST          As Long = -1
Public Const HWND_NOTOPMOST        As Long = -2
Public Const SW_SHOWNORMAL         As Long = 1

Public autoRegister As Boolean

Public Declare Function SetWindowPos Lib "user32.dll" ( _
                ByVal hWnd As Long, _
                ByVal hWndInsertAfter As Long, _
                ByVal x As Long, _
                ByVal Y As Long, _
                ByVal CX As Long, _
                ByVal CY As Long, _
                ByVal uFLags As Long) As Long


Public Declare Function ShellExecute Lib "shell32" Alias "ShellExecuteA" ( _
                ByVal hWnd As Long, _
                ByVal lpOperation As String, _
                ByVal lpFile As String, _
                ByVal lpParameters As String, _
                ByVal lpDirectory As String, _
                ByVal nShowCmd As Long) As Long

Public Sub fixAllBlooms()
  Dim myKeeper, TheApp As Object, AllDocs As Maxim.Documents
  Dim tmpArray, newDoc, numStarPixels, myLowerLimit, leftAdjust, rightAdjust
  Dim ii, jj, i, j, k, l, m, Y, z, myOffset, numImages, myStarSize
  Dim leftPixel1, leftPixel2, leftPixel3, myCtr
  Dim rightPixel1, rightPixel2, rightPixel3
  Dim leftMedian, rightMedian, myTest, myStart, myIncrease, uLimit, myRnd
  Dim startValue, upperbound, lowerbound, starDepth, hasStarTop, hasStarBottom, maxCheck
  Dim myBackgroundTotal, myBackgroundCtr
  Dim iOffset, jOffset, LeftEdge, RightEdge, starWidth
  Dim orig_value, new_value, diff_value, myStart1, myStart2
  Dim myVerticalValue, myHorizontalValue, dragRect
  Dim myRectArrayDim, myRectWidth, myRectHeight, fudgeFactorIncrease, fudgeFactorDecrease
  Dim myRectArray(), myResponse, myDocBogus, retValue, myDistance, tmpString

  On Error GoTo errHandler
  'On Error GoTo 0
  dragRect = False
  OKRotate = True
  showingStars = True
  rotateDisplay = True
  If frmOptions.chkNoStars.Value = 0 Then
    showRotateDialog = True
  Else
    showRotateDialog = False
  End If
  errMsg = "Setting variables."
  If Not deBloomValid Then
    Exit Sub
  End If
  starFactor = CDbl(frmOptions.txtStarFactor.Text)
  frmBloomRemoval.Command1.Enabled = False
  frmBloomRemoval.Command4.Enabled = False
  bloomLimit = CDbl(frmBloomRemoval.txtBloomLimit)
  If bloomLimit < 1500 Then
    myResponse = MsgBox("Bloom limit is set too low; cannot proceed. Minimum bloom limit is 1500." & vbCrLf & "Set Bloom limit to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtBloomLimit = 1500
        bloomLimit = CDbl(frmBloomRemoval.txtBloomLimit)
    Else
        Exit Sub
    End If
  End If
  starLimit = CDbl(frmBloomRemoval.txtStarLimit)
  If starLimit < 500 Then
    myResponse = MsgBox("Star limit is set too low; cannot proceed. Minimum star limit is 500." & vbCrLf & "Set star limit to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtStarLimit = 500
        starLimit = CDbl(frmBloomRemoval.txtStarLimit)
    Else
        Exit Sub
    End If
  End If
  If bloomLimit < starLimit + 1000 Then
    myResponse = MsgBox("Bloom limit is less than Star limit; cannot proceed. Bloom limit must be at least 1000 greater than star limit." & vbCrLf & "Set bloom limit to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtBloomLimit = starLimit + 1000
        bloomLimit = CDbl(frmBloomRemoval.txtBloomLimit)
    Else
        Exit Sub
    End If
  End If
  fillDistance = CDbl(frmBloomRemoval.txtFillDistance)
  If fillDistance > 25 Then
    myResponse = MsgBox("Fuzzy distance is too large; cannot proceed. Maximum fuzzy distance is 25." & vbCrLf & "Set Fuzzy distance to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtFillDistance = 25
        fillDistance = CDbl(frmBloomRemoval.txtFillDistance)
    Else
        Exit Sub
    End If
  End If
  starSize = CDbl(frmOptions.txtStarSize)
  If starSize > 25 Then
    myResponse = MsgBox("Scan length is set too high; cannot proceed. Maximum scan length is 25." & vbCrLf & "Set Scan length to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmOptions.txtStarSize = 25
        starSize = CDbl(frmOptions.txtStarSize)
    Else
        Exit Sub
    End If
  End If
  If starSize < 3 Then
    myResponse = MsgBox("Scan length is set too low; cannot proceed. Minimum scan length is 3." & vbCrLf & "Set Scan length to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmOptions.txtStarSize = 3
        starSize = CDbl(frmOptions.txtStarSize)
    Else
        Exit Sub
    End If
  End If
  iter = CDbl(frmBloomRemoval.txtBloomIterations)
  If iter > 10 Then
    myResponse = MsgBox("Number of iterations is set too high; cannot proceed. Maximum number of iterations is 10." & vbCrLf & "Set Number of iterations to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtBloomIterations = 10
        iter = CDbl(frmBloomRemoval.txtBloomIterations)
    Else
        Exit Sub
    End If
  End If
  If iter < 1 Then
    myResponse = MsgBox("Number of iterations is set too low; cannot proceed. Minimum number of iterations is 1." & vbCrLf & "Set Number of iterations to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtBloomIterations = 1
        iter = CDbl(frmBloomRemoval.txtBloomIterations)
    Else
        Exit Sub
    End If
  End If
  noiseFactor = CDbl(frmBloomRemoval.txtNoiseFactor) / 250
  If CDbl(frmBloomRemoval.txtNoiseFactor) < 1 Then
    myResponse = MsgBox("Noise factor is set too low; cannot proceed. Minimum noise factor is 1." & vbCrLf & "Set Noise factor to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtNoiseFactor = 1
        noiseFactor = CDbl(frmBloomRemoval.txtNoiseFactor) / 250
    Else
        Exit Sub
    End If
  End If
  If CDbl(frmBloomRemoval.txtNoiseFactor) > 1000 Then
    myResponse = MsgBox("Noise factor is set too high; cannot proceed. Maximum noise factor is 1000." & vbCrLf & "Set Noise factor to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmBloomRemoval.txtNoiseFactor = 1000
        noiseFactor = CDbl(frmBloomRemoval.txtNoiseFactor) / 250
    Else
        Exit Sub
    End If
  End If
  starAggressiveness = CDbl(frmOptions.txtStarAggressiveness) / 100
  If CDbl(frmOptions.txtStarAggressiveness) > 250 Then
    myResponse = MsgBox("Scan booster is set too high; cannot proceed. Maximum scan booster value is 250." & vbCrLf & "Set Scan booster to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmOptions.txtStarAggressiveness = 250
        starAggressiveness = CDbl(frmOptions.txtStarAggressiveness) / 100
    Else
        Exit Sub
    End If
  End If
  If CDbl(frmOptions.txtStarAggressiveness) < 5 Then
    myResponse = MsgBox("Scan booster is set too low; cannot proceed. Minimum scan booster value is 5." & vbCrLf & "Set Scan booster to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmOptions.txtStarAggressiveness = 5
        starAggressiveness = CDbl(frmOptions.txtStarAggressiveness) / 100
    Else
        Exit Sub
    End If
  End If
  increment = CDbl(frmOptions.txtBloomIncrement.Text)
  If increment > 1000 Then
    myResponse = MsgBox("Auto increment is set too high; cannot proceed. Maximum auto increment value is 1000." & vbCrLf & "Set Auto increment to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmOptions.txtBloomIncrement = 1000
        increment = CDbl(frmOptions.txtBloomIncrement.Text)
    Else
        Exit Sub
    End If
  End If
  If increment < 10 Then
    myResponse = MsgBox("Auto increment is set too low; cannot proceed. Minimum auto increment value is 10." & vbCrLf & "Set Auto increment to this value and continue?", vbYesNo + vbCritical + vbDefaultButton2)
    If myResponse = vbYes Then
        frmOptions.txtBloomIncrement = 10
        increment = CDbl(frmOptions.txtBloomIncrement.Text)
    Else
        Exit Sub
    End If
  End If
  If frmOptions.chkRotate.Value = 1 Then
    doRotate = True
  Else
    doRotate = False
  End If
  
  progressBarLength = 4900 - 160
  
  dragRect = True
  If frmBloomRemoval.chkDoAll.Value = 1 Then
    On Error GoTo dragRectHandler
    myRectArrayDim = myDoc.DragRectangle
    On Error GoTo errHandler
    'On Error GoTo 0
    If dragRect Then
        retValue = MsgBox("Warning: You created a drag rectangle and 'Apply to all images' is checked." & vbCrLf & "Drag rectangles cannot apply to multiple documents," & vbCrLf & "so the drag rectangle will be ignored if you continue." & vbCrLf & vbCrLf & "Click Yes to continue, No to abort.", vbYesNo + vbCritical + vbDefaultButton2)
        If retValue = vbNo Then
            Exit Sub
        End If
    End If
    ' Get number of images.
    Set TheApp = New Maxim.Application
    Set AllDocs = TheApp.Documents
    numImages = AllDocs.Count
    dragRect = False
  Else
    numImages = 1
    On Error GoTo dragRectHandler
    myRectArrayDim = myDoc.DragRectangle
    myRectWidth = Abs(myRectArrayDim(2) - myRectArrayDim(0))
    myRectHeight = Abs(myRectArrayDim(3) - myRectArrayDim(1))
    If myRectWidth < 10 Or myRectHeight < 10 Then
        dragRect = False
    End If
    On Error GoTo errHandler
    'On Error GoTo 0
  End If
  If Not deBloomValid Then
    Exit Sub
  End If
  msgForm.txtMsg.Text = ""
  For z = 1 To numImages
    deBloomValid = True
    If numImages > 1 Then
        ' Get next document.
        Set myDoc = AllDocs(z)
        myArray = myDoc.ImageArray
        myRefArray = myDoc.ImageArray
        msgForm.txtMsg.Text = msgForm.txtMsg.Text & "Image #" & z & vbCrLf
        msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
    Else
        If dragRect Then
            errMsg = "Getting drag rectangle data."
           ' Work only with the portion of the image in the drag rectangle.
            tmpArray = myDoc.ImageArray
            
            myRectWidth = Abs(myRectArrayDim(2) - myRectArrayDim(0))
            myRectHeight = Abs(myRectArrayDim(3) - myRectArrayDim(1))
            If myRectArrayDim(2) < myRectArrayDim(0) Then
                myStart1 = myRectArrayDim(2)
            Else
                myStart1 = myRectArrayDim(0)
            End If
            If myRectArrayDim(3) < myRectArrayDim(1) Then
                myStart2 = myRectArrayDim(3)
            Else
                myStart2 = myRectArrayDim(1)
            End If
            ReDim myRectArray(myRectWidth, myRectHeight)
            For i = 0 To myRectWidth
                For j = 0 To myRectHeight
                    myRectArray(i, j) = tmpArray(myStart1 + i, myStart2 + j)
                Next j
            Next i
            errMsg = "Storing image data in local array."
            myArray = myRectArray
            myRefArray = myRectArray
        Else
            errMsg = "Storing image data in local array."
            myArray = myDoc.ImageArray
            myRefArray = myDoc.ImageArray
        End If
    End If
    msgForm.txtMsg.Text = msgForm.txtMsg.Text & "Setting up bloom removal..." & vbCrLf & "Image: " & myDoc.DisplayName
    msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
    msgForm.progressBar.X2 = msgForm.progressBar.X1
    DoEvents
    ulimitX = UBound(myArray, 1)
    uLimitY = UBound(myArray, 2)
    hasBlooms = False
    DoEvents
    ReDim myBloomArray(ulimitX, uLimitY)
    If deBloomValid Then
    For x = 1 To iter
      If frmBloomRemoval.chkAuto.Value = 1 Then
        If frmBloomRemoval.chkAuto.Value = 1 Then
            msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Calculating bloom and star limits..."
            msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
            DoEvents
            frmBloomRemoval.Label14_Click
            If Not deBloomValid Then
                Exit For
            End If
            frmBloomRemoval.Label17_Click
        End If
        If Not deBloomValid Then
            Exit For
        End If
        bloomLimit = CDbl(frmBloomRemoval.txtBloomLimit)
        starLimit = CDbl(frmBloomRemoval.txtStarLimit)
      End If
      errMsg = "Setting bloom array values to 0."
      progressBarIncrement = (progressBarLength / ulimitX) / 4
      msgForm.progressBar.Visible = True
      For i = 0 To ulimitX
        For j = 0 To uLimitY
            myBloomArray(i, j) = 0
        Next j
        msgForm.progressBar.X2 = progressBarIncrement * i
        DoEvents
      Next i
    
      msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Pass " & x
      msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
      DoEvents
      ' Find bloomed pixels.
      '=======================================================================================================
      If deBloomValid Then
        findBloomedPixels
      Else
        Exit For
      End If

      ' Locate stars.
      '=======================================================================================================
      If deBloomValid Then
        locateStars
      Else
        Exit For
      End If
    
      msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Marking star centers..."
      msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
      DoEvents
      'Find and mark star centers.
      '=======================================================================================================
      If deBloomValid Then
        markStarCenters
      Else
        Exit For
      End If
    
    
      If frmOptions.chkBloomMap.Value = 0 Then
        msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Fixing bloomed areas..."
        msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
        DoEvents
        ' Fill in bloomed area with average values.
        If deBloomValid Then
            fillBlooms
        Else
            Exit For
        End If
      End If ' creating bloom map
    
      If frmOptions.chkRotate.Value = 1 Then
        msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Applying rotated star images..."
        msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
        DoEvents
        ' Find star centers.
        '=======================================================================================================
        If deBloomValid Then
            findStarCenters
        Else
            Exit For
        End If
        
      End If ' Not creating bloom map.
    Next x
    End If
    If hasBlooms And deBloomValid Then
        If frmOptions.chkBloomMap.Value = 1 Then
            msgForm.txtMsg.Text = msgForm.txtMsg.Text & "Creating map..." & vbCrLf
            msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
            DoEvents
            myDocBogus = myDoc.DirectMono
            If dragRect Then
                ' Work only with the portion of the image in the drag rectangle.
                For i = 0 To myRectWidth
                    For j = 0 To myRectHeight
                        tmpArray(myStart1 + i, myStart2 + j) = myBloomArray(i, j)
                    Next j
                Next i
                If deBloomValid Then
                    myDoc.ImageArray = tmpArray
                End If
            Else
                If deBloomValid Then
                    myDoc.ImageArray = myBloomArray
                End If
            End If
            myDoc.DisplayName = "Map of bloomed pixels - set min to 8000 and max to 12500 to see details"
            myDoc.Modified = True
            'myDoc.StretchMin = 8000
            'myDoc.StretchMax = 12500
        Else
            errMsg = "Storing fixes to image in MaxIm DL."
            msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Setting image..."
            msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
            DoEvents
            ' Fix blooms.
            myDocBogus = myDoc.DirectMono
            If dragRect Then
                ' Work only with the portion of the image in the drag rectangle.
                For i = 0 To myRectWidth
                    For j = 0 To myRectHeight
                        tmpArray(myStart1 + i, myStart2 + j) = myArray(i, j)
                    Next j
                Next i
                If deBloomValid Then
                    myDoc.ImageArray = tmpArray
                End If
            Else
                If deBloomValid Then
                    myDoc.ImageArray = myArray
                End If
            End If
            myDoc.Modified = True
        End If
    End If
  Next z
  msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Done."
  msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
  ' Copy results of operation to clipboard for review.
  If frmOptions.chkClip.Value = 1 Then
    Clipboard.Clear
    Clipboard.SetText reportSettings() & msgForm.txtMsg.Text
  End If
  SetWindowPos msgForm.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, (SWP_SHOWWINDOW + SWP_NOMOVE + SWP_NOSIZE)
  
  'If msgForm.Caption = "DeBloomer Status" Then
  '  frmMsg.Timer1.Enabled = True
  'End If
  On Error GoTo 0
  Exit Sub

errHandler:
  errMsg = "Fatal error #" & Err.Number & ": " & Err.Description & vbCrLf & "Additional information: " & errMsg
  MsgBox errMsg
  Exit Sub

dragRectHandler:
  dragRect = False
  Resume Next
End Sub

Public Function reportSettings()
    Dim myStr
    myStr = "Apply to all images: " & frmBloomRemoval.chkDoAll & vbCrLf
    myStr = myStr & "Star rounding active: " & frmBloomRemoval.chkFixTopBottom & vbCrLf
    myStr = myStr & "Fuzzy fill active: " & frmBloomRemoval.chkFuzzy & vbCrLf
    myStr = myStr & "Automatic limits: " & frmBloomRemoval.chkAuto & vbCrLf
    myStr = myStr & "Blooming limit: " & frmBloomRemoval.txtBloomLimit & vbCrLf
    myStr = myStr & "Star limit: " & frmBloomRemoval.txtStarLimit & vbCrLf
    myStr = myStr & "Fuzzy distance: " & frmBloomRemoval.txtFillDistance & vbCrLf
    myStr = myStr & "Iterations: " & frmBloomRemoval.txtBloomIterations & vbCrLf
    myStr = myStr & "Noise factor: " & frmBloomRemoval.txtNoiseFactor & vbCrLf
    myStr = myStr & "Scan length: " & frmOptions.txtStarSize & vbCrLf
    myStr = myStr & "Scan booster: " & frmOptions.txtStarAggressiveness & vbCrLf
    myStr = myStr & "Auto increment: " & frmOptions.txtBloomIncrement & vbCrLf
    myStr = myStr & "Star limit adjust: " & frmOptions.txtStarAdjust & vbCrLf
    myStr = myStr & "Left adjustment: " & frmOptions.txtLeftAdjust & vbCrLf
    myStr = myStr & "Right adjustment: " & frmOptions.txtRightAdjust & vbCrLf
    myStr = myStr & "Create bloom map: " & frmOptions.chkBloomMap & vbCrLf
    myStr = myStr & "Fix stars by rotation: " & frmOptions.chkRotate & vbCrLf
    myStr = myStr & "Rotate without showing stars first: " & frmOptions.chkNoStars & vbCrLf
    myStr = myStr & "Offset fill source by fuzzy fill distance: " & frmOptions.chkOffsetFill & vbCrLf
    myStr = myStr & "Copy results to clipboard: " & frmOptions.chkClip & vbCrLf
    myStr = myStr & "Min. star size: " & frmOptions.txtMinStarSize & vbCrLf
    myStr = myStr & "Star factor: " & frmOptions.txtStarFactor & vbCrLf & vbCrLf
    reportSettings = myStr
End Function

Public Sub saveSettings()
    SaveSetting "New Astro DeBloomer", "Resume", "txtBloomLimit", frmBloomRemoval.txtBloomLimit
    SaveSetting "New Astro DeBloomer", "Resume", "txtBloomSlope", CStr(bloomSlope)
    SaveSetting "New Astro DeBloomer", "Resume", "txtFillDistance", frmBloomRemoval.txtFillDistance
    SaveSetting "New Astro DeBloomer", "Resume", "txtStarLimit", frmBloomRemoval.txtStarLimit
    SaveSetting "New Astro DeBloomer", "Resume", "txtBloomIterations", frmBloomRemoval.txtBloomIterations
    SaveSetting "New Astro DeBloomer", "Resume", "txtNoiseFactor", frmBloomRemoval.txtNoiseFactor
    SaveSetting "New Astro DeBloomer", "Resume", "chkDoAll", frmBloomRemoval.chkDoAll.Value
    SaveSetting "New Astro DeBloomer", "Resume", "chkFixTopBottom", frmBloomRemoval.chkFixTopBottom.Value
    SaveSetting "New Astro DeBloomer", "Resume", "chkFuzzy", frmBloomRemoval.chkFuzzy.Value
    SaveSetting "New Astro DeBloomer", "Resume", "chkAuto", frmBloomRemoval.chkAuto.Value
    
    SaveSetting "New Astro DeBloomer", "Resume", "txtStarSize", frmOptions.txtStarSize
    SaveSetting "New Astro DeBloomer", "Resume", "txtBloomIncrement", frmOptions.txtBloomIncrement
    SaveSetting "New Astro DeBloomer", "Resume", "txtStarAggressiveness", frmOptions.txtStarAggressiveness
    SaveSetting "New Astro DeBloomer", "Resume", "txtStarAdjust", frmOptions.txtStarAdjust
    SaveSetting "New Astro DeBloomer", "Resume", "chkBloomMap", frmOptions.chkBloomMap.Value
    SaveSetting "New Astro DeBloomer", "Resume", "chkRotate", frmOptions.chkRotate.Value
    SaveSetting "New Astro DeBloomer", "Resume", "chkNoStars", frmOptions.chkNoStars.Value
    SaveSetting "New Astro DeBloomer", "Resume", "txtStarFactor", frmOptions.txtStarFactor.Text
    SaveSetting "New Astro DeBloomer", "Resume", "chkNoRotateMinStars", frmOptions.chkNoRotateMinStars.Value
    
    SaveSetting "New Astro DeBloomer", "Resume", "txtMinStarSize", frmOptions.txtMinStarSize.Text
    SaveSetting "New Astro DeBloomer", "Resume", "chkCrossHairs", frmRotate.options_hairs.Checked
    
    SaveSetting "New Astro DeBloomer", "Resume", "chkShowBloom", frmRotate.chkShowBloom.Value
    SaveSetting "New Astro DeBloomer", "Resume", "optShowFullBloom", frmRotate.optShowFullBloom.Checked
    SaveSetting "New Astro DeBloomer", "Resume", "chkOffsetFill", frmOptions.chkOffsetFill.Value
    
    'If frmRotate.cmdBigger.Caption = ">>" Then
    '    SaveSetting "New Astro DeBloomer", "Resume", "RotateWidth", "5355"
    'Else
    '    SaveSetting "New Astro DeBloomer", "Resume", "RotateWidth", "8310"
    'End If
    
    savePositions
End Sub

Public Sub savePositions()
    SaveSetting "New Astro DeBloomer", "Resume", "frmBloomLeft", frmBloomRemoval.Left
    SaveSetting "New Astro DeBloomer", "Resume", "frmBloomTop", frmBloomRemoval.Top
    SaveSetting "New Astro DeBloomer", "Resume", "frmOptionsLeft", frmOptions.Left
    SaveSetting "New Astro DeBloomer", "Resume", "frmOptionsTop", frmOptions.Top
End Sub

Public Sub getSettings()
    Dim loginData, loginData2, loginData3, myExpectedPassword, myNow, myThen, myRotateWidth
    
    frmRotate.options_remember.Checked = False
    frmBloomRemoval.txtBloomLimit = GetSetting("New Astro DeBloomer", "Resume", "txtBloomLimit", "50000")
    On Error GoTo blankBloomSlope
    bloomSlope = CDbl(GetSetting("New Astro DeBloomer", "Resume", "txtBloomSlope", "1000"))
    On Error GoTo 0
    If bloomSlope < 1000 Then
        bloomSlope = 1000
    End If
    frmBloomRemoval.txtFillDistance = GetSetting("New Astro DeBloomer", "Resume", "txtFillDistance", "6")
    frmBloomRemoval.txtStarLimit = GetSetting("New Astro DeBloomer", "Resume", "txtStarLimit", "3000")
    frmBloomRemoval.txtBloomIterations = GetSetting("New Astro DeBloomer", "Resume", "txtBloomIterations", "1")
    frmBloomRemoval.txtNoiseFactor = GetSetting("New Astro DeBloomer", "Resume", "txtNoiseFactor", "20")
    frmBloomRemoval.chkDoAll.Value = GetSetting("New Astro DeBloomer", "Resume", "chkDoAll", "0")
    frmBloomRemoval.chkFixTopBottom.Value = GetSetting("New Astro DeBloomer", "Resume", "chkFixTopBottom", "1")
    frmBloomRemoval.chkFuzzy.Value = GetSetting("New Astro DeBloomer", "Resume", "chkFuzzy", "1")
    frmBloomRemoval.chkAuto.Value = GetSetting("New Astro DeBloomer", "Resume", "chkAuto", "1")
    
    frmOptions.txtStarSize = GetSetting("New Astro DeBloomer", "Resume", "txtStarSize", "5")
    frmOptions.txtStarAggressiveness = GetSetting("New Astro DeBloomer", "Resume", "txtStarAggressiveness", "75")
    frmOptions.txtBloomIncrement = GetSetting("New Astro DeBloomer", "Resume", "txtBloomIncrement", "50")
    frmOptions.chkBloomMap.Value = GetSetting("New Astro DeBloomer", "Resume", "chkBloomMap", "0")
    frmOptions.chkRotate.Value = GetSetting("New Astro DeBloomer", "Resume", "chkRotate", "1")
    frmOptions.chkNoStars.Value = GetSetting("New Astro DeBloomer", "Resume", "chkNoStars", "0")
    frmOptions.txtStarAdjust = GetSetting("New Astro DeBloomer", "Resume", "txtStarAdjust", "3200")
    frmOptions.txtStarFactor = GetSetting("New Astro DeBloomer", "Resume", "txtStarFactor", "15")
    frmOptions.chkNoRotateMinStars.Value = GetSetting("New Astro DeBloomer", "Resume", "chkNoRotateMinStars", "0")
    
    loadRotateForm = False
    frmOptions.txtMinStarSize = GetSetting("New Astro DeBloomer", "Resume", "txtMinStarSize", "3")
    frmRotate.txtMinStarSize.Text = frmOptions.txtMinStarSize.Text
    frmRotate.options_hairs.Checked = GetSetting("New Astro DeBloomer", "Resume", "chkCrossHairs", "1")
    xOffset = 0
    frmBloomRemoval.Left = GetSetting("New Astro DeBloomer", "Resume", "frmBloomLeft", "300")
    frmBloomRemoval.Top = GetSetting("New Astro DeBloomer", "Resume", "frmBloomTop", "5300")
    frmOptions.Left = GetSetting("New Astro DeBloomer", "Resume", "frmOptionsLeft", "500")
    frmOptions.Top = GetSetting("New Astro DeBloomer", "Resume", "frmOptionsTop", "5500")
    
    frmRotate.chkShowBloom.Value = GetSetting("New Astro DeBloomer", "Resume", "chkShowBloom", "0")
    frmRotate.optShowFullBloom.Checked = GetSetting("New Astro DeBloomer", "Resume", "optShowFullBloom", "0")
    frmOptions.chkOffsetFill.Value = GetSetting("New Astro DeBloomer", "Resume", "chkOffsetFill", "0")
    
    'myRotateWidth = GetSetting("New Astro DeBloomer", "Resume", "RotateWidth", "5510")
    'frmRotate.Width = myRotateWidth
    
    ' Check for registration.
    loginData = GetSetting("New Astro DeBloomer", "Init", "ls_CRD", "x")
    loginData2 = GetSetting("New Astro DeBloomer", "Init", "ls_CJH", "xyz123 fgh")
    loginData3 = GetSetting("New Astro DeBloomer", "Init", "ls_CRR", "1234")
    myNow = CLng(Now)
    myThen = GetSetting("New Astro DeBloomer", "Init", "txtRotateBool", "0")
    If myThen = "0" Then ' First use.
        ' Save date of first use.
        SaveSetting "New Astro DeBloomer", "Init", "txtRotateBool", CStr(myNow)
        SaveSetting "New Astro DeBloomer", "Init", "initialUse", CStr(Now)
        SaveSetting "New Astro DeBloomer", "Init", "txtOffsetAmt", CStr(myNow / 45)
        myThen = myNow
    End If
    frmBloomRemoval.chkAuto_Click
    Exit Sub
    
blankBloomSlope:
    bloomSlope = 1000
    Resume Next
End Sub

Public Function getPassword(myInput)
    Dim myTemp, myASC, myNewASC, i
    myTemp = ""
    If Len(myInput) < 16 Then
        myInput = myInput & Left("81726354AHBGCFDE", 16 - Len(myInput))
    End If
    myInput = Left(myInput, 16)
    For i = 1 To 16
        myASC = Asc(Mid(myInput, i, 1)) + i
        myNewASC = (((myASC + 27863) / 11) * 4837) Mod 26
        myTemp = myTemp & Chr(myNewASC + 65)
        If i Mod 4 = 0 And i <> 16 Then
            myTemp = myTemp & "-"
        End If
    Next i
    getPassword = myTemp
End Function

Public Sub adjustRotation()
    Dim l, m, myRnd, myDistance, theArray
    If Not loadRotateForm Or Not deBloomValid Then
        Exit Sub
    End If
    frmRotate.Caption = "Rotation   [Paste x: " & xOffset & " y: "
    frmRotate.Caption = frmRotate.Caption & yOffset
    frmRotate.Caption = frmRotate.Caption & "] [Source x: " & myOriginX & " y: "
    frmRotate.Caption = frmRotate.Caption & myOriginX
    frmRotate.Caption = frmRotate.Caption & " size: " & starFactor & "]"
    ' Refresh display array with original star image.
    ' Shfit origin in source array?
    For l = 0 To newLimit
        For m = 0 To newLimit
            If l + myOriginY >= 0 And l + myOriginY <= newLimit And m + myOriginX >= 0 And m + myOriginX <= newLimit Then
                myStarArray5(l, m) = myStarArray2(l + myOriginY, m + myOriginX)
            End If
        Next m
    Next l
    'myStarArray2 = myStarArray5
    If hideStar Then
        For l = 0 To newLimit
            For m = 0 To newLimit
                myStarArray(l, m) = 0
            Next m
        Next l
    Else
        myStarArray = myStarArray2
    End If
    If rotateDisplay Then
        For l = 0 To newLimit
            For m = 0 To newLimit
                errMsg = "Adjusting rotation at " & l & ", " & m & "."
                myDistance = Sqr((l - halfLimit - 1) ^ 2 + (m - halfLimit - 1) ^ 2)
                If frmRotate.options_hairs.Checked And (l = newLimit / 2 + 0.5 Or m = newLimit / 2 + 0.5) And m + xOffset - 1 > 0 And m + xOffset - 1 < newLimit And l - yOffset - 1 > 0 And l - yOffset - 1 < newLimit Then
                    myStarArray(m + xOffset - 1, l - yOffset - 1) = 0
                Else
                    If myDistance < (myXCount / 2) * (starFactor / 10) And myStarArray3(l, m) <> 0 Then
                        If m + xOffset - 1 < newLimit And l - yOffset - 1 < newLimit And l - yOffset - 1 > 0 And m + xOffset - 1 > 0 And l + (starX - halfLimit) - 1 < ulimitX And m + (starY - halfLimit) - 1 < uLimitY And (l + (starX - halfLimit) - 1) > 0 And (m + (starY - halfLimit) - 1) > 0 Then
                            myStarArray(m + xOffset - 1, l - yOffset - 1) = myArray(l + (starX - halfLimit) - 1 + myOriginY, m + (starY - halfLimit) - 1 + myOriginX)
                        End If
                    End If
                End If
            Next m
        Next l
    End If
    On Error GoTo 0
    If showBloom Then
        For l = 0 To newLimit
            For m = 0 To newLimit
                errMsg = "Showing Bloom at " & l & ", " & m & "."
                myDistance = Sqr((l - halfLimit - 1) ^ 2 + (m - halfLimit - 1) ^ 2)
                If frmRotate.options_hairs.Checked And (l = newLimit / 2 + 0.5 Or m = newLimit / 2 + 0.5) And m + xOffset - 1 > 0 And m + xOffset - 1 < newLimit And l - yOffset - 1 > 0 And l - yOffset - 1 < newLimit Then
                    myBloomArray2(m + xOffset - 1, l - yOffset - 1) = 0
                Else
                    If m + xOffset - 1 < newLimit And l - yOffset - 1 < newLimit And l - yOffset - 1 > 0 And m + xOffset - 1 > 0 And l + (starY - halfLimit) - 1 < uLimitY And m + (starX - halfLimit) - 1 < ulimitX And (l + (starY - halfLimit) - 1) > 0 And (m + (starX - halfLimit) - 1) > 0 Then
                        If (l Mod 2 = 0 Or m Mod 2 = 0) Or frmRotate.optShowFullBloom.Checked Then
                            myBloomArray2(m + xOffset - 1, l - yOffset - 1) = myRefArray(m + (starX - halfLimit) - 1 + myOriginY, l + (starY - halfLimit) - 1 + myOriginX)
                        End If
                    End If
                End If
            Next m
        Next l
    End If
    ' repaint picture box on rotation form.
    paintPictureBox
    If showBloom Then
        paintPictureBoxBloom
    End If
End Sub

Public Sub findBloomedPixels()
    Dim myStart, myEnd, myOffset
    Dim i, j, k
    
    bloomCounter = 0
    progressBarIncrement = (progressBarLength / ulimitX) / 4
    For i = 0 To ulimitX
        errMsg = "Scanning column " & i & " of image."
        For j = 0 To uLimitY
            If myArray(i, j) >= bloomLimit Then
                ' Find length of bloom in this column.
                myOffset = 0
                While myArray(i, j + myOffset) > bloomLimit And j + myOffset < uLimitY - 1
                    myOffset = myOffset + 1
                Wend
                ' Check other edge of bloom.
                If myOffset > (starSize * 0.7) Then
                    ' OK, this is really a bloom.
                    'errMsg = "Storing bloom locations in myBloomArray."
                    hasBlooms = True
                    If j = 0 Then
                        myStart = j
                    Else
                        myStart = j - 1
                    End If
                    If j + myOffset > uLimitY - 1 Then
                        myEnd = uLimitY - 1
                    Else
                        myEnd = j + myOffset
                    End If
                    For k = myStart To myEnd
                        myBloomArray(i, k) = 65000
                    Next k
                    j = k - 1
                    bloomCounter = bloomCounter + 1
                End If
            End If
        Next j
        msgForm.progressBar.X2 = (progressBarLength / 4) + (progressBarIncrement * i)
        DoEvents
    Next i
    msgForm.txtMsg.Text = msgForm.txtMsg.Text & vbCrLf & "Found " & bloomCounter & " columns with blooms." & vbCrLf
    If bloomCounter <= 0 Then
        msgForm.txtMsg.Text = msgForm.txtMsg.Text & "No bloomed pixels; aborting."
        msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
        deBloomValid = False
        If Not scriptingOn Then
            If showDialogs Then
                MsgBox "No bloomed pixels were found.", vbExclamation
            End If
        End If
    End If
    msgForm.txtMsg.Text = msgForm.txtMsg.Text & "Finding stars..."
    msgForm.txtMsg.SelStart = Len(msgForm.txtMsg.Text)
    DoEvents
End Sub

Public Sub locateStars()
    Dim i, j, ii, jj, k
    Dim numStarPixels, myTest, myOffset, starSearching
    
    progressBarIncrement = (progressBarLength / uLimitY) / 4
    For i = 0 To uLimitY
        errMsg = "Scanning row " & i & " looking for stars."
        For j = 0 To ulimitX
            numStarPixels = 0
            If (myArray(j, i) >= starLimit + (increment * 100) And myArray(j, i) < bloomLimit) Then
                ' Brightness level says this is a star.
                ' Are there adjoining pixels that are at star brightness?
                For ii = -1 To 1
                    For jj = 0 To 2
                        If i + ii >= 0 And i + ii < uLimitY And j + jj < ulimitX Then
                            myTest = myArray(j + jj, i + ii)
                            If (myTest >= starLimit And myTest < bloomLimit) Then
                                numStarPixels = numStarPixels + 1
                            End If
                        End If
                    Next jj
                Next ii
                If numStarPixels > 1 Then
                    myOffset = 0
                    'errMsg = "Found a pixel that is in a star:" & i & ", " & j
                    starSearching = True
                    While starSearching
                        If j + myOffset < ulimitX - 1 Then
                            If myArray(j + myOffset, i) >= starLimit + (increment * 100) Then
                                myOffset = myOffset + 1
                            Else
                                starSearching = False
                            End If
                        Else
                            starSearching = False
                        End If
                    Wend
                    If myOffset >= (starSize * starAggressiveness) + (((x - 1) * increment / 50) * (x - 1)) And myOffset > 3 Then
                        For k = j + 1 To j + myOffset - 1
                            If k < ulimitX Then
                                myBloomArray(k, i) = 10000
                            End If
                        Next k
                        j = k - 1
                    End If
                End If
            End If
        Next j
        DoEvents
        msgForm.progressBar.X2 = (progressBarLength / 2) + (progressBarIncrement * i)
    Next i
End Sub

Public Sub markStarCenters()
    Dim i, j, edgeSearching
    
    For i = 0 To uLimitY - 1
        errMsg = "Scanning column " & i & " while marking stars."
        For j = 1 To ulimitX - 1
            ' Is this a left edge?
            If myBloomArray(j, i) = 10000 And myBloomArray(j - 1, i) < 10000 Then
                ' Mark left edge.
                myBloomArray(j, i) = 20000
                myXCount = 1
                ' Find right edge.
                edgeSearching = True
                While edgeSearching
                    If j + myXCount <= ulimitX - 1 Then
                        If myBloomArray(j + myXCount, i) = 10000 Then
                            myXCount = myXCount + 1
                        Else
                            edgeSearching = False
                        End If
                    Else
                        edgeSearching = False
                    End If
                Wend
                ' Mark right edge.
                myBloomArray(j + myXCount - 1, i) = 30000
                ' Mark center.
                myBloomArray(j + Round((myXCount - 1) / 2), i) = 40000
            End If
        Next j
        DoEvents
    Next i
End Sub

Public Sub fillBlooms()
    Dim iFillDistance, jFillDistance, kFillDistance
    Dim i, ii, j, k, m, Y
    Dim myOffset, bloomSearching, leftPixel1, rightPixel1, leftPixel2, rightPixel2, leftPixel3, rightPixel3, leftMedian, rightMedian
    Dim leftAdjust, rightAdjust, myIncrease, starDepth
    Dim myCtr, star_slope, myHorizontalValue, myVerticalValue, startValue, upperbound, lowerbound, myRnd
    Dim myRightBright, myLeftBright
    
    If myBackgroundAvg = -1 Then
        myBackgroundAvg = CDbl(frmBloomRemoval.txtStarLimit.Text) - CDbl(frmOptions.txtStarAdjust.Text)
    End If
    progressBarIncrement = (progressBarLength / uLimitY) / 4
    For i = 0 To uLimitY
        errMsg = "Scanning row " & i & " looking for bloomed pixels to fix up."
        If i + fillDistance >= uLimitY Then
            iFillDistance = uLimitY - i
        Else
            iFillDistance = fillDistance
        End If
        For j = 0 To ulimitX
            If myBloomArray(j, i) = 65000 Then
                If j + fillDistance > ulimitX Then
                    jFillDistance = ulimitX - j
                Else
                    jFillDistance = fillDistance
                End If
                If frmOptions.chkOffsetFill.Value = 0 Then
                    ' Eliminate variable fill distance.
                    jFillDistance = 1
                    iFillDistance = 1
                End If
                If j < fillDistance Then
                    jFillDistance = j
                End If
                If i < fillDistance Then
                    iFillDistance = i
                End If
                'errMsg = "Found a bloomed pixel to fix up."
                myOffset = 0
                ' How wide is this group of bloomed pixels?
                bloomSearching = True
                While bloomSearching
                    If j + myOffset <= ulimitX Then
                        If myBloomArray(j + myOffset, i) > 60000 Then
                            myOffset = myOffset + 1
                        Else
                            bloomSearching = False
                        End If
                    Else
                        bloomSearching = False
                    End If
                Wend
                
                ' Get values on either side of bloom.
                'errMsg = "Getting values outside left edge of bloom: pixel 1. i=" & i & " j=" & j
                If j - jFillDistance > 0 Then
                    leftPixel1 = myArray(j - jFillDistance, i)
                    Y = 1
                    While leftPixel1 > bloomLimit And Y + jFillDistance <= j
                        leftPixel1 = myArray(j - (Y + jFillDistance), i)
                        Y = Y + 1
                        If Y > 25 Then
                            leftPixel1 = myBackgroundAvg
                        End If
                    Wend
                    If i > 0 Then
                        'errMsg = "Getting values outside left edge of bloom: pixel 2. i=" & i & " j=" & j
                        leftPixel2 = myArray(j - jFillDistance, i - iFillDistance)
                        Y = 1
                        While leftPixel2 > bloomLimit And Y + jFillDistance <= j And Y + iFillDistance <= i
                            leftPixel2 = myArray(j - (Y + jFillDistance), i - Y + iFillDistance)
                            Y = Y + 1
                            If Y > 25 Then
                                leftPixel2 = myBackgroundAvg
                            End If
                        Wend
                    Else
                        leftPixel2 = leftPixel1
                    End If
                    If i < uLimitY Then
                        'errMsg = "Getting values outside left edge of bloom: pixel 3. i=" & i & " j=" & j
                        leftPixel3 = myArray(j - jFillDistance, i + iFillDistance)
                        Y = 1
                        While leftPixel3 > bloomLimit And Y + jFillDistance <= j And (Y + iFillDistance + i) <= uLimitY
                            leftPixel3 = myArray(j - (Y + jFillDistance), i + Y + iFillDistance)
                            Y = Y + 1
                            If Y > 25 Then
                                leftPixel3 = myBackgroundAvg
                            End If
                        Wend
                    Else
                        leftPixel3 = leftPixel1
                    End If
                Else
                    ' Edge pixel. set to value of right pixel later.
                    leftPixel1 = -1
                End If
                'On Error GoTo errHandler
                
                'errMsg = "Getting values outside right edge of bloom: pixel 1. i=" & i & " j=" & j
                If j + myOffset + jFillDistance < ulimitX Then
                    rightPixel1 = myArray(j + myOffset + jFillDistance, i)
                    Y = 1
                    While rightPixel1 > bloomLimit And (Y + jFillDistance) <= ulimitX - (j + myOffset)
                        rightPixel1 = myArray(j + myOffset + (Y + jFillDistance), i)
                        Y = Y + 1
                        If Y > 25 Then
                            rightPixel1 = bloomLimit - 1000
                        End If
                    Wend
                    If i > 0 Then
                        'errMsg = "Getting values outside right edge of bloom: pixel 2. i=" & i & " j=" & j
                        rightPixel2 = myArray(j + myOffset + jFillDistance, i - iFillDistance)
                        Y = 1
                        While rightPixel2 > bloomLimit And (Y + jFillDistance) <= ulimitX - (j + myOffset) And (Y + iFillDistance) <= i
                            rightPixel2 = myArray(j + myOffset + (Y + jFillDistance), i - (Y + iFillDistance))
                            Y = Y + 1
                            If Y > 25 Then
                                rightPixel2 = bloomLimit - 1000
                            End If
                        Wend
                    Else
                        rightPixel2 = rightPixel1
                    End If
                
                    If i < uLimitY Then
                        'errMsg = "Getting values outside right edge of bloom: pixel 3. i=" & i & " j=" & j
                        rightPixel3 = myArray(j + myOffset + jFillDistance, i + iFillDistance)
                        Y = 1
                        While rightPixel3 > bloomLimit And (Y + jFillDistance) <= ulimitX - (j + myOffset) And (Y + iFillDistance) + i <= uLimitY
                            rightPixel3 = myArray(j + myOffset + (Y + jFillDistance), i + (Y + iFillDistance))
                            Y = Y + 1
                            If Y > 25 Then
                                rightPixel3 = bloomLimit - 1000
                            End If
                        Wend
                    Else
                        rightPixel3 = rightPixel1
                    End If
                Else
                    ' Edge pixel. Use default value.
                    rightPixel1 = leftPixel1
                    rightPixel2 = rightPixel1
                    rightPixel3 = rightPixel1
                End If
                
                If leftPixel1 = -1 Then
                    leftPixel1 = rightPixel1
                    leftPixel2 = rightPixel1
                    leftPixel3 = rightPixel1
                End If
                
                'errMsg = "Finding median of left pixels."
                If leftPixel1 < leftPixel2 Then
                    If leftPixel2 < leftPixel3 Then
                        leftMedian = leftPixel2
                    Else
                        If leftPixel1 < leftPixel3 Then
                            leftMedian = leftPixel3
                        Else
                            leftMedian = leftPixel1
                        End If
                    End If
                Else
                    If leftPixel1 < leftPixel3 Then
                        leftMedian = leftPixel1
                    Else
                        If leftPixel2 < leftPixel3 Then
                            leftMedian = leftPixel3
                        Else
                            leftMedian = leftPixel2
                        End If
                    End If
                End If
                
                'errMsg = "Finding median of right pixels."
                If rightPixel1 < rightPixel2 Then
                    If rightPixel2 < rightPixel3 Then
                        rightMedian = rightPixel2
                    Else
                        If rightPixel1 < rightPixel3 Then
                            rightMedian = rightPixel3
                        Else
                            rightMedian = rightPixel1
                        End If
                    End If
                Else
                    If rightPixel1 < rightPixel3 Then
                        rightMedian = rightPixel1
                    Else
                        If rightPixel2 < rightPixel3 Then
                            rightMedian = rightPixel3
                        Else
                            rightMedian = rightPixel2
                        End If
                    End If
                End If
                If frmBloomRemoval.chkFuzzy.Value = 0 Then
                    'Fuzzy fill is inactive.
                    rightMedian = rightPixel1
                    leftMedian = leftPixel1
                End If
                
                errMsg = "Entering alternative code for keeping stars round."
                If starLimit > 0 Then
                    If leftMedian > starLimit And frmBloomRemoval.chkFixTopBottom.Value = 1 Then
                        leftMedian = leftMedian * Sqr(Sqr((leftMedian / starLimit)))
                    End If
                    If rightMedian > starLimit And frmBloomRemoval.chkFixTopBottom.Value = 1 Then
                        rightMedian = rightMedian * Sqr(Sqr((rightMedian / starLimit)))
                    End If
                End If
                
                ' Adjust left/right values by specific amounts if required.
                leftAdjust = frmOptions.txtLeftAdjust
                rightAdjust = frmOptions.txtRightAdjust
                leftMedian = leftMedian + leftAdjust
                rightMedian = rightMedian + rightAdjust
                If leftMedian < 0 Then
                    leftMedian = 0
                End If
                If rightMedian < 0 Then
                    rightMedian = 0
                End If
                
                errMsg = "Filling bloomed pixels."
                Dim startForFill, endForFill
                startForFill = j
                If frmOptions.chkOffsetFill.Value = 1 Then
                    startForFill = startForFill - 1
                    If startForFill < 0 Then startForFill = 0
                End If
                endForFill = Round(j + myOffset)
                If frmOptions.chkOffsetFill.Value = 1 Then
                    endForFill = endForFill + 1
                    If endForFill > ulimitX Then endForFill = ulimitX
                End If
                For k = startForFill To endForFill
                    myIncrease = 0
                    starDepth = 0
                    
                    myCtr = k - startForFill
                    If myOffset = 0 Then
                        startValue = (leftMedian + rightMedian) / 2
                    Else
                        startValue = Round((rightMedian * (k - startForFill) + leftMedian * (myOffset - (k - startForFill))) / (myOffset))
                    End If
                    If starLimit = 0 Then
                        Err.Raise 2, "fixAllBlooms", "Star Limit = 0; cannot proceed."
                    End If
                    upperbound = starSize * noiseFactor * 100 * (startValue / starLimit) * 2
                    lowerbound = 1
                    myRnd = Round(CDbl((upperbound - lowerbound + 1) * Rnd + lowerbound))
                    If k < ulimitX And k >= 0 Then
                        myArray(k, i) = startValue + Round(CDbl(myRnd - (upperbound / 2))) + myIncrease
                        If myArray(k, i) > bloomLimit Then myArray(k, i) = bloomLimit
                    End If
                Next k
                If frmBloomRemoval.chkFuzzy.Value = 1 Then
                    'errMsg = "Adding noise to surrounding pixels (fuzzy fill)."
                    ' Apply noise to surrounding pixels.
                    If j < fillDistance Then
                        jFillDistance = j
                    Else
                        jFillDistance = fillDistance
                    End If
                    If k + fillDistance > ulimitX Then
                        kFillDistance = ulimitX - k
                    Else
                        kFillDistance = fillDistance
                    End If
                    If starLimit = 0 Then
                        Err.Raise 2, "fixAllBlooms", "Star Limit = 0; cannot proceed."
                    End If
                    For m = 1 To jFillDistance
                        lowerbound = 0
                        If m <= jFillDistance Then
                            upperbound = (starSize * noiseFactor * 100) * ((myArray(j - m, i) / starLimit) * 2)
                            myRnd = Round(CDbl((upperbound - lowerbound + 1) * Rnd + lowerbound))
                            myArray(j - m, i) = myArray(j - m, i) + Round(CDbl(myRnd - (upperbound * 15 / 25)))
                        End If
                        If m <= kFillDistance Then
                            upperbound = (starSize * noiseFactor * 100) * ((myArray(k + m, i) / starLimit)) * 2
                            myRnd = Round(CDbl((upperbound - lowerbound + 1) * Rnd + lowerbound))
                            myArray(k + m, i) = myArray(k + m, i) + Round(CDbl(myRnd - (upperbound * 15 / 25)))
                        End If
                    Next m
                End If
                j = k - 1
            End If
        Next j
        DoEvents
        msgForm.progressBar.X2 = ((progressBarLength * 3) / 4) + (progressBarIncrement * i)
        DoEvents
    Next i
End Sub

Public Sub findStarCenters()
    Dim i, j, l, m
    Dim myDistance, lowerbound, upperbound, myRnd, myMax
    
    If frmOptions.chkNoStars.Value = 0 Then
        'Set myStarDoc = CreateObject("MaxIm.Document")
    End If
    SetWindowPos msgForm.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, (SWP_HIDEWINDOW + SWP_NOMOVE + SWP_NOSIZE)
    
    On Error GoTo errHandler
    myMax = CStr(Round(myDoc.StretchMax - myDoc.StretchMin))
    If myMax > 32000 Then myMax = 32000
    frmRotate.txtMax = myMax
    On Error GoTo 0

    For i = 0 To uLimitY
        errMsg = "Scanning in column " & i & " while looking for star centers."
        For j = 3 To ulimitX - 3
            'errMsg = "Scanning pixel " & i & ", " & j & " looking for star centers."
            myXCenter = 0
            myYCenter = 0
            myXCount = 0
            myYCount = 0
            If myBloomArray(j, i) = 40000 And showingStars Then
                ' First star center in this star.
                ' Count length and clean up star centers.
                While myBloomArray(j - 3, i + myYCount) = 40000 Or myBloomArray(j - 2, i + myYCount) = 40000 Or myBloomArray(j - 1, i + myYCount) = 40000 Or myBloomArray(j, i + myYCount) = 40000 Or myBloomArray(j + 1, i + myYCount) = 40000 Or myBloomArray(j + 2, i + myYCount) = 40000 Or myBloomArray(j + 3, i + myYCount) = 40000
                    'errMsg = "Found star center at pixel " & i & ", " & j & " with current Ycount at " & myYCount & "."
                    myYCenter = myYCenter + (i + myYCount)
                    If myBloomArray(j - 3, i + myYCount) = 40000 Then
                        myBloomArray(j - 3, i + myYCount) = 40001
                        myXCenter = myXCenter + (j - 3)
                    End If
                    If myBloomArray(j - 2, i + myYCount) = 40000 Then
                        myBloomArray(j - 2, i + myYCount) = 40001
                        myXCenter = myXCenter + (j - 2)
                    End If
                    If myBloomArray(j - 1, i + myYCount) = 40000 Then
                        myBloomArray(j - 1, i + myYCount) = 40001
                        myXCenter = myXCenter + (j - 1)
                    End If
                    If myBloomArray(j, i + myYCount) = 40000 Then
                        myBloomArray(j, i + myYCount) = 40001
                        myXCenter = myXCenter + (j)
                    End If
                    If myBloomArray(j + 1, i + myYCount) = 40000 Then
                        myBloomArray(j + 1, i + myYCount) = 40001
                        myXCenter = myXCenter + (j + 1)
                    End If
                    If myBloomArray(j + 2, i + myYCount) = 40000 Then
                        myBloomArray(j + 2, i + myYCount) = 40001
                        myXCenter = myXCenter + (j + 2)
                    End If
                    If myBloomArray(j + 3, i + myYCount) = 40000 Then
                        myBloomArray(j + 3, i + myYCount) = 40001
                        myXCenter = myXCenter + (j + 3)
                    End If
                    myYCount = myYCount + 1
                Wend
                ' Find star center.
                If myYCount <= 0 Then
                    Err.Raise 1, "fixAllBlooms", "Vertical star size (YCount) <= 0"
                Else
                    starX = Round(myXCenter / myYCount)
                    starY = Round(myYCenter / myYCount)
                End If
                errMsg = "Found star center at " & starX & ", " & starY & "."
                'myBloomArray(starX, starY) = 50000
                'errMsg = "Preparing the check for bloom map request at pixel " & i & ", " & j & "."
              If frmOptions.chkBloomMap.Value = 0 Then
                ' Load an array with the star image.
                errMsg = "No bloom map; at pixel " & i & ", " & j & "."
                myXCount = myYCount
                ' Initialize array.
                newLimit = 61
                errMsg = "Verifying that image is large enough to the current sample size at pixel " & i & ", " & j & "."
                If ulimitX < uLimitY Then
                    If ulimitX < 60 Then
                        newLimit = ulimitX - 1
                    End If
                Else
                    If uLimitY < 60 Then
                        newLimit = uLimitY - 1
                    End If
                End If
                errMsg = "Veryifying that 'newLimit' is an odd number, at pixel " & i & ", " & j & "."
                If newLimit Mod 2 = 0 Then newLimit = newLimit - 1
                errMsg = "Setting 'halfLimit' at pixel " & i & ", " & j & "."
                halfLimit = (newLimit - 1) / 2
                errMsg = "ReDim of temporary arrays at pixel " & i & ", " & j & "."
                If newLimit <> 60 Then
                    ReDim myStarArray(newLimit, newLimit)
                    ReDim myStarArray2(newLimit, newLimit)
                    ReDim myStarArray3(newLimit, newLimit)
                    ReDim myStarArray4(newLimit, newLimit)
                    ReDim myStarArray5(newLimit, newLimit)
                    ReDim myBloomArray2(newLimit + 1, newLimit + 1)
                End If
                errMsg = "Initializing temporary arrays at pixel " & i & ", " & j & "."
                For l = 0 To newLimit
                    For m = 0 To newLimit
                        myStarArray(l, m) = 66000
                        myStarArray2(l, m) = 0
                        myStarArray3(l, m) = 0
                    Next m
                Next l
                errMsg = "Ready to set starFactor value at pixel " & i & ", " & j & "."
                If Not frmRotate.options_remember.Checked Then
                    starFactor = CDbl(frmOptions.txtStarFactor.Text)
                    'errMsg = "Set star factor to " & starFactor & " at pixel " & i & ", " & j & "."
                    If starFactor >= halfLimit Then
                        starFactor = halfLimit - 1
                        'errMsg = "Reset star factor to " & starFactor & " at pixel " & i & ", " & j & "."
                    End If
                End If
                If myXCount < newLimit Then
                    errMsg = "Putting star into small  array because XCount (" & myXCount & ") < " & newLimit & " at pixel " & i & ", " & j & "."
                    ' Put the star into the small array.
                    For l = 0 To newLimit
                        For m = 0 To newLimit
                            If l + (starX - halfLimit) > 0 And m + (starY - halfLimit) > 0 And l + (starX - halfLimit) < ulimitX And m + (starY - halfLimit) < uLimitY Then
                                myStarArray(l, m) = myArray(l + (starX - halfLimit), m + (starY - halfLimit))
                            End If
                        Next m
                    Next l
                    myStarArray2 = myStarArray
                    If doRotate Then
                        errMsg = "Building mask at pixel " & i & ", " & j & "."
                        ' Build a mask so we are only applying to top and bottom quadrants of the star.
                        For l = 0 To newLimit
                            For m = 0 To newLimit
                                If (l < m And l < (newLimit - m)) Or (l > m And l > (newLimit - m)) Then
                                    myStarArray3(l, m) = 65000
                                Else
                                    myStarArray3(l, m) = 0
                                End If
                            Next m
                        Next l
                        errMsg = "Rotating pattern at pixel " & i & ", " & j & "."
                        ' Rotate pattern 90 degrees into a new array, for later blending of edges.
                        For l = 0 To newLimit
                            For m = 0 To newLimit
                                myStarArray4(l, m) = myStarArray3(m, newLimit - l)
                            Next m
                        Next l
                        ' Optionally, display the star in a small document in MaxIm DL.
                        loadRotateForm = False
                        hideStar = False
                        'frmRotate.optShowAll.Value = True
                        If frmOptions.chkNoStars.Value = 0 And showRotateDialog And myXCount > CDbl(frmRotate.txtMinStarSize.Text) Then
                            errMsg = "Showing rotate dialog at " & i & ", " & j & "."
                            myAdjust = "x"
                            'myStarDoc.XSize = UBound(myStarArray2, 1) + 1
                            'myStarDoc.YSize = UBound(myStarArray2, 2) + 1
                            'myStarDoc.StretchMin = myDoc.StretchMin
                            'myStarDoc.StretchMax = myDoc.StretchMax
                            If Not frmRotate.options_remember.Checked Then
                                xOffset = 0
                                yOffset = 0
                                myOriginX = 0
                                myOriginY = 0
                            End If
                            loadRotateForm = True
                            'myStarDoc.ImageArray = myStarArray
                            If frmRotate.chkShowBloom.Value = 1 Then
                                showBloom = True
                            Else
                                If frmRotate.chkShowPaste.Value = 1 Then
                                    rotateDisplay = True
                                Else
                                    rotateDisplay = False
                                End If
                                If frmRotate.chkShowStar.Value = 1 Then
                                    hideStar = False
                                Else
                                    hideStar = True
                                End If
                                showBloom = False
                            End If
                            adjustRotation
                            While myAdjust <> ""
                                frmRotate.Show 1
                                If frmRotate.options_remember.Checked Then
                                    ' Save new star factor to registry.
                                    frmOptions.txtStarFactor.Text = starFactor
                                    SaveSetting "New Astro DeBloomer", "Resume", "txtStarFactor", starFactor
                                End If
                            Wend
                            
                        End If
                        If Not loadRotateForm And Not frmRotate.options_remember.Checked Then
                            xOffset = 0
                            yOffset = 0
                        End If
                        If myXCount < CDbl(frmRotate.txtMinStarSize.Text) And frmOptions.chkNoRotateMinStars.Value = 1 Then
                            OKRotate = False
                        End If
                        If OKRotate Then
                            ' Rotate 90 degrees and apply to image.
                            If starLimit = 0 Then
                                Err.Raise 2, "fixAllBlooms", "Star Limit = 0; cannot proceed."
                            End If
    ' Shfit origin in source array?
    For l = 0 To newLimit
        For m = 0 To newLimit
            If l + myOriginY >= 0 And l + myOriginY <= newLimit And m + myOriginX >= 0 And m + myOriginX <= newLimit Then
                myStarArray5(l, m) = myStarArray2(l + myOriginY, m + myOriginX)
            End If
        Next m
    Next l
    myStarArray2 = myStarArray5
                            For l = 3 To newLimit - 3
                                For m = 3 To newLimit - 3
                                    ' Accept the dimmer value.
                                    myDistance = Sqr((l - halfLimit - 1) ^ 2 + (m - halfLimit - 1) ^ 2)
                                    If myDistance < (myXCount / 2) * (starFactor / 10) And myStarArray3(l, m) = 0 Then
                                        ' Copying only into the area at top and bottom of star.
                                        If l + (starX - halfLimit) + xOffset - 1 > 0 And m + (starY - halfLimit) - yOffset - 1 > 0 And l + (starX - halfLimit) + xOffset - 1 < ulimitX And m + (starY - halfLimit) - yOffset - 1 < uLimitY Then
                                            lowerbound = 0
                                            If m > 0 And l > 0 Then
                                                upperbound = (starSize * noiseFactor * 100) * ((myStarArray2(m - 1, l - 1) / starLimit) * 2)
                                                myRnd = Round(CDbl((upperbound - lowerbound + 1) * Rnd + lowerbound))
                                                If (myStarArray4(m, l) = 0 And myStarArray4(m, l - 1) = 65000) Or (myStarArray4(m, l) = 0 And myStarArray4(m, l + 1) = 65000) Then
                                                    myArray(l + (starX - halfLimit) + xOffset - 1, m + (starY - halfLimit) - yOffset - 1) = 0.1 * (myStarArray2(m - 1, l - 1)) + 0.9 * (myArray(l + (starX - halfLimit) + xOffset - 1, m + (starY - halfLimit) - yOffset - 1))
                                                Else
                                                    If (myStarArray4(m, l) = 0 And myStarArray4(m, l - 2) = 65000) Or (myStarArray4(m, l) = 0 And myStarArray4(m, l + 2) = 65000) Then
                                                        myArray(l + (starX - halfLimit) + xOffset - 1, m + (starY - halfLimit) - yOffset - 1) = 0.3 * (myStarArray2(m - 1, l - 1)) + 0.7 * (myArray(l + (starX - halfLimit) + xOffset - 1, m + (starY - halfLimit) - yOffset - 1))
                                                    Else
                                                        If (myStarArray4(m, l) = 0 And myStarArray4(m, l - 3) = 65000) Or (myStarArray4(m, l) = 0 And myStarArray4(m, l + 3) = 65000) Then
                                                            myArray(l + (starX - halfLimit) + xOffset - 1, m + (starY - halfLimit) - yOffset - 1) = 0.7 * (myStarArray2(m - 1, l - 1)) + 0.3 * (myArray(l + (starX - halfLimit) + xOffset - 1, m + (starY - halfLimit) - yOffset - 1))
                                                        Else
                                                            myArray(l + (starX - halfLimit) + xOffset - 1, m + (starY - halfLimit) - yOffset - 1) = myStarArray2(m - 1, l - 1) + Round(CDbl(myRnd - (upperbound * 15 / 25)))
                                                        End If
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                Next m
                            Next l
                            'myDoc.ImageArray = myArray
                        Else
                        End If
                    End If
                Else
                End If
              End If ' Creating blooming map.
              errMsg = "End of loop, end of bloom map IF block, at pixel " & i & ", " & j & "."
            End If
        Next j
        If Not deBloomValid Then
            'Set myStarDoc = Nothing
            Exit Sub
        End If
    Next i
    If frmOptions.chkNoStars.Value = 0 Then
        'Set myStarDoc = Nothing
    End If
    SetWindowPos msgForm.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, (SWP_SHOWWINDOW + SWP_NOMOVE + SWP_NOSIZE)
    frmBloomRemoval.MousePointer = 0

errHandler:
    frmRotate.txtMax = "500"
    Exit Sub
End Sub

Public Sub ShowWebpage(path As String)
    Dim z As Long

    z = ShellExecute(0, "Open", path, 0, 0, SW_SHOWNORMAL)
    If (z > 0) And (z <= 32) Then
        MsgBox _
            "It doesn't appear that you have a web browser installed " & _
            "on your system.", (vbOKOnly + vbExclamation + vbMsgBoxSetForeground), "DeBloomer"
        Exit Sub
    End If

End Sub

Public Sub paintPictureBox()
    Dim l, m, n, x, CX, CY, Msg, XPos, YPos   ' Declare variables.
    Dim myMin, myScale
    On Error GoTo errHandler
    myMin = myDoc.StretchMin
    errMsg = "Testing Range of " & frmRotate.txtMax & " against minimum/maximum values."
    If CDbl(frmRotate.txtMax) < 100 Or Not IsNumeric(frmRotate.txtMax) Then
        frmRotate.txtMax = "100"
    End If
    If CDbl(frmRotate.txtMax) > 32000 Then frmRotate.txtMax = "32000"
    myScale = Round(CDbl(frmRotate.txtMax))
    If myScale <= 0 Then
        ' Cannot have a  scale of zero.
        frmRotate.txtMax = "100"
    End If
   
    frmRotate.Picture1.ScaleMode = 3   ' Set ScaleMode to pixels.
    frmRotate.Picture1.DrawWidth = rotateZoom + 1 ' Set DrawWidth.
    frmRotate.Picture1.Cls   ' Clear form.
    frmRotate.Picture1.Visible = False
   
    errMsg = "FOR loop - painting pixels."
    For l = 0 To newLimit
        For m = 0 To newLimit
            'errMsg = "Painting bloomed pixels at l=" & l & ", m=" & m & ". newLimit=" & newLimit
            ' Paint picture box.
            If (myStarArray(m, l) - myMin) < myScale Then
                n = Round(((myStarArray(m, l) - myMin) / myScale) * 256)
                If n < 0 Then n = 0
            Else
                n = 256
            End If
            frmRotate.Picture1.PSet (rotateZoom * m, rotateZoom * l), RGB(n, n, n)
            DoEvents
        Next m
    Next l
    frmRotate.Picture1.Visible = True
    On Error GoTo 0
    Exit Sub
errHandler:
    errMsg = "Error painting bloomed pixels #" & Err.Number & ": " & Err.Description & vbCrLf & "Additional information: " & errMsg
    MsgBox errMsg
    Exit Sub
End Sub

Public Sub paintPictureBoxBloom()
    Dim l, m, n, x, CX, CY, Msg, XPos, YPos   ' Declare variables.
    Dim myMin, myScale
    On Error GoTo errHandler
    myMin = myDoc.StretchMin
    If CDbl(frmRotate.txtMax) < 100 Or Not IsNumeric(frmRotate.txtMax) Then
        frmRotate.txtMax = CStr(100)
    End If
    If CDbl(frmRotate.txtMax) > 32000 Then frmRotate.txtMax = "32000"
    myScale = Round(CDbl(frmRotate.txtMax))
   
    frmRotate.Picture1.ScaleMode = 3   ' Set ScaleMode to pixels.
    If hideStar And Not rotateDisplay Then
        frmRotate.Picture1.DrawWidth = rotateZoom / 2 ' Set DrawWidth.
    Else
        If frmRotate.optShowFullBloom.Checked Then
            frmRotate.Picture1.DrawWidth = rotateZoom + 1 ' Set DrawWidth.
        Else
            frmRotate.Picture1.DrawWidth = rotateZoom / 2 ' Set DrawWidth.
        End If
    End If
    frmRotate.Picture1.Visible = False
   
    For l = 0 To newLimit
        For m = 0 To newLimit
            'errMsg = "Painting bloomed pixels at l=" & l & ", m=" & m & ". newLimit=" & newLimit
            ' Paint picture box.
            If (myBloomArray2(m, l) - myMin) < myScale Then
                n = Round(((myBloomArray2(m, l) - myMin) / myScale) * 256)
                If n < 0 Then n = 0
            Else
                n = 256
            End If
            If myBloomArray2(m, l) >= bloomLimit Then
                frmRotate.Picture1.PSet (rotateZoom * m, rotateZoom * l), RGB(n, 0, 0)
            End If
            DoEvents
        Next m
    Next l
    frmRotate.Picture1.Visible = True
    On Error GoTo 0
    Exit Sub
errHandler:
    errMsg = "Error painting bloomed pixels #" & Err.Number & ": " & Err.Description & vbCrLf & "Additional information: " & errMsg
    MsgBox errMsg
    Exit Sub
End Sub

