Image encrypter

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Image encrypter

Post by BasicallyPure »

An image viewer with the option to encrypt / decrypt images.
A password is required to encrypt or decrypt an image.
Right mouse click gives popup menu with keyboard shortcuts.
Navigation is easy with keyboard arrow keys.
Right/left arrows load next/previous images.
Once password has been set, up arrow to encrypt, down arrow to decrypt.
Password is used to create a seed for the random number generator.
All pixels are XOR'd with a different random number.
Encrypted images must be saved in a lossless format, .bmp or .png (default).
An encryption mark is inserted into an encrypted image in the upper left corner.
An 8 x 8 area (64 pixels) of the LSB blue pixel component holds the encryption mark.
This as a permanent change to the original image but is not visible to the eye.
This encryption mark contains no information about the password.
This mark is used to prevent double encryption of an image or trying to decrypt an unencrypted image.

Code: Select all

; Encrypter.pb
; by BasicallyPure
; date    : 02.19.2019
; License : free and risky
; Compiler: Windows PB 5.62(x64)
; Compiler: Linux   PB 5.61(x64)

EnableExplicit

#version = "1.00"

UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()

Declare.i CENTER_IMAGE_IN_WINDOW(image)
Declare.i CHECK_IF_ENCRYPTED()
Declare.i COPY_IMAGE(image.i)
Declare.i DECRYPT_IMAGE()
Declare.i DRAG_WINDOW()
Declare.i ENCRYPT_IMAGE()
Declare.i EVENT_LOOP()
Declare.i EXPAND_WINDOW(image)
Declare.i FILL_DIR_LIST(path$)
Declare.i FIT_IMAGE_TO_WINDOW(image)
Declare.i FIT_WINDOW_TO_IMAGE(image)
Declare.i INIT_GUI()
Declare.i LOAD_IMAGE()
Declare.i LOAD_NEXT()
Declare.i LOAD_PREVIOUS()
Declare.i MAXIMIZE_WINDOW()
Declare.i SAVE_IMAGE(image.i)
Declare.i TOGGLE_INFO()
Declare.i TOGGLE_STRETCH()
Declare.i UPDATE_CANVAS()
Declare.i PASSWORD_REQUESTER()
Declare.i PASTE_IMAGE(image.i)
Declare.i SIZE_IMAGE_TO_MAXIMUM(image)

Global File$ 
Global password.s  = #Null$
Global KeyMark.q = $51F5825A22A0F7D9 ; never change this
Global seed.q
Global quit.i = #False
Global TBH.i ; tool bar height
Global maxCanvas_X, maxCanvas_Y
Global stretch = #False
Global maximize = #False
Global encrypted.i = #False
Global info.i = #False ; display image information
Global minW.i ; minimum window width
Global NewList dirList.s()

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
   File$ = GetHomeDirectory() + "Pictures/"
   minW = 560
CompilerElse
   minW = 470
CompilerEndIf

File$ + "Image Encrypter" + #version

If ExamineDesktops() < 1 : End : EndIf

Global DW = DesktopWidth(0)
Global DH = DesktopHeight(0)
Global minH = minW * DH/DW

#MainWin     = 0
#Menu        = 0
#MenuPopUp   = 1
#ImgMain     = 0
#ImgTemp     = 1
#Canvas      = 0
#WindowColor = $081B4C

Enumeration ; menu items
   #Menu_load  : #Menu_save     : #Menu_next    : #Menu_previous : #Menu_copy
   #Menu_paste : #Menu_password : #Menu_encrypt : #Menu_decrypt  : #Menu_minimize
   #Menu_quit  : #Menu_stretch  : #Menu_maximize: #Menu_info
EndEnumeration


If INIT_GUI()
   EVENT_LOOP()
EndIf

End

Procedure CENTER_IMAGE_IN_WINDOW(image)
   Protected ww = WindowWidth(#MainWin), wh = WindowHeight(#MainWin)-ToolBarHeight(#Menu)
   Protected iw = ImageWidth(image), ih = ImageHeight(image)
   
   ResizeGadget(#Canvas,(ww-iw)/2,(wh-ih)/2+TBH,iw,ih)
EndProcedure

Procedure CHECK_IF_ENCRYPTED()
   ;search for the encryption mark in an image
   ;encryption mark is stored in the blue component LSB of 63 pixels
   ;in an 8 x 8 block in the upper left corner of the image
   
   Protected Xmax, Ymax, x, y, result
   Protected mark.q
   
   StartDrawing(ImageOutput(#ImgMain))
      For y = 0 To 7
         For x = 0 To 7
            If x & y = %0111 : Break 2 : EndIf
            mark << 1
            mark | (Blue(Point(x,y)) & 1)
         Next x
      Next y
   StopDrawing()
   
   If mark = KeyMark
      encrypted = #True
   Else
      encrypted = #False
   EndIf
   
   ProcedureReturn encrypted
EndProcedure

Procedure COPY_IMAGE(image.i)
   Protected result = #False
   
   If IsImage(image)
      SetClipboardImage(image)
      result  = #True
   Else
      MessageRequester("","No image to copy!")
   EndIf
   
   ProcedureReturn result
EndProcedure

Procedure DECRYPT_IMAGE()
   ;  correct 'seed' must be set by PASSWORD_REQUESTER()
   
   Protected x, y, Xmax, Ymax
   
   If IsImage(#ImgMain) = #False
      MessageRequester("","Load an image first!")
      ProcedureReturn
   EndIf
   
   If CHECK_IF_ENCRYPTED() = #False
      MessageRequester("","This image is not recognezed as 'encrypted'")
      ProcedureReturn
   EndIf
   
   If password = #Null$
      MessageRequester("","Password is not set!")
      PASSWORD_REQUESTER()
      ProcedureReturn
   EndIf
   
   If IsImage(#ImgMain)
      RandomSeed(seed)
      
      Xmax = ImageWidth(#ImgMain)  - 1
      Ymax = ImageHeight(#ImgMain) - 1
      
      StartDrawing(ImageOutput(#ImgMain))
         For y = 0 To Ymax
            For x = 0 To Xmax
               Plot(x,y, Point(x,y) ! Random($FFFFFF))
            Next x
         Next y
      StopDrawing()
      
      encrypted = #False
      
      UPDATE_CANVAS()
   EndIf
EndProcedure

Procedure DRAG_WINDOW()
   Protected dragActive = #True
   Protected windowX = WindowX(#MainWin), windowY = WindowY(#MainWin)
   Protected ww = WindowWidth(#MainWin)
   Protected wh = WindowHeight(#MainWin)
   Protected Xref = GetGadgetAttribute(#Canvas,#PB_Canvas_MouseX)
   Protected Yref = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseY)
   Protected dX, dY
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_Gadget
            If EventGadget() = #Canvas
               
               Select EventType()
                  Case #PB_EventType_LeftButtonUp : dragActive = #False
                  Case #PB_EventType_MouseMove
                     dX = Xref - GetGadgetAttribute(#Canvas,#PB_Canvas_MouseX)
                     dY = Yref - GetGadgetAttribute(#Canvas, #PB_Canvas_MouseY)
                     windowX-dX : windowY - dY
                     
                     If windowX < 0 : windowX = 0 : EndIf
                     If windowY < 0 : windowY = 0 : EndIf
                     If windowX + ww > DW : windowX = DW - ww : EndIf
                     If windowY + wh > DH : windowY = DH - wh : EndIf
                     
                     ResizeWindow(#MainWin,windowX,windowY,#PB_Ignore,#PB_Ignore)
               EndSelect
            EndIf
            
      EndSelect
   Until dragActive = #False
   
EndProcedure

Procedure ENCRYPT_IMAGE()
   Protected Xmax, Ymax, x, y, result
   Protected m.q = $4000000000000000
   
   If IsImage(#ImgMain) = #False
      MessageRequester("","Load an image first!")
      ProcedureReturn
   EndIf
   
   If CHECK_IF_ENCRYPTED() = #True
      MessageRequester("","This image is already encrypted.")
      ProcedureReturn
   EndIf
   
   If password = #Null$
      MessageRequester("Error","Password is not set!")
      PASSWORD_REQUESTER()
      ProcedureReturn
   EndIf
   
   If ImageWidth(#ImgMain) < 8 Or ImageHeight(#ImgMain) < 8
      MessageRequester("Error","Image must be at least 8 x 8 pixels!")
      ProcedureReturn
   EndIf
   
   Xmax = ImageWidth(#ImgMain) - 1
   Ymax = ImageHeight(#ImgMain) - 1
   
   RandomSeed(seed)
   
   StartDrawing(ImageOutput(#ImgMain))
      For y = 0 To Ymax
         For x = 0 To Xmax
            Plot(x,y, Point(x,y) ! Random($FFFFFF))
         Next x
      Next y
      
      ; insert encryption mark in 63 Blue LSB of
      ; 8 x 8 pixels in upper left corner of image
      For y = 0 To 7
         For x = 0 To 7
            If x & y = %0111 : Break 2 : EndIf
            Plot(x,y, (Point(x,y) & $FEFFFF) | (Bool(KeyMark & m)<<16))
            m >> 1
         Next x
      Next y
   StopDrawing()
   
   encrypted = #True
   
   UPDATE_CANVAS()
   
EndProcedure

Procedure EVENT_LOOP()
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow : quit = #True
            
         CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            Case #WM_RBUTTONUP : DisplayPopupMenu(#MenuPopUp,WindowID(#MainWin))
         CompilerEndIf
               
         Case #PB_Event_Gadget
            If EventGadget() = #Canvas
               Select EventType()
                  Case #PB_EventType_LeftButtonDown : DRAG_WINDOW()
                     
                  CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
                     Case #PB_EventType_RightButtonUp  : DisplayPopupMenu(#MenuPopUp,WindowID(#MainWin))
                  CompilerEndIf
                     
               EndSelect
            EndIf
            
         Case #PB_Event_Menu
            Select EventMenu()
               Case #Menu_load     : LOAD_IMAGE()          ; load image
               Case #Menu_previous : LOAD_PREVIOUS()       ; load previous image
               Case #Menu_next     : LOAD_NEXT()           ; load next image
               Case #Menu_save     : SAVE_IMAGE(#ImgMain)  ; save image
               Case #Menu_copy     : COPY_IMAGE(#ImgMain)  ; Copy to clipboard
               Case #Menu_paste    : PASTE_IMAGE(#ImgMain) ; Paste from clipboard
               Case #Menu_password : PASSWORD_REQUESTER()  ; set the password
               Case #Menu_encrypt  : ENCRYPT_IMAGE()       ; encrypt image
               Case #Menu_decrypt  : DECRYPT_IMAGE()       ; decrypt the image
               Case #Menu_minimize : SetWindowState(#MainWin,#PB_Window_Minimize)
               Case #Menu_stretch  : TOGGLE_STRETCH()      ; toggle stretch image
               Case #Menu_info     : TOGGLE_INFO()         ; toggle image information display
               Case #Menu_maximize : MAXIMIZE_WINDOW()     ; toggle full screen
               Case #Menu_quit     : quit = #True          ; end the program
            EndSelect
      EndSelect
   Until quit
EndProcedure

Procedure EXPAND_WINDOW(image)
   ; expand window to maximum width or height as required
   
   Protected iw = ImageWidth(image), ih = ImageHeight(image)
   Protected imageAspect.d = iw/ih
   Protected windowAspect.d = maxCanvas_X / maxCanvas_Y
   Protected ww, wh
   
   If imageAspect > windowAspect ; expand to x
      ww = maxCanvas_X
      wh = ww / imageAspect
   Else ; expand to y
      wh = maxCanvas_Y
      ww = wh * imageAspect
   EndIf
   
   ResizeWindow(#MainWin,(DW-ww)/2, (DH-wh-TBH)/2,ww,wh+ToolBarHeight(#Menu))
   
EndProcedure

Procedure FILL_DIR_LIST(path$)
   Protected name$, ext$, dirIndex
   
   If ExamineDirectory(0,path$,"*.*")
      ClearList(dirList())
      
      While NextDirectoryEntry(0)
         If DirectoryEntryType(0) = #PB_DirectoryEntry_File
            name$ = DirectoryEntryName(0)
            ext$ = LCase(GetExtensionPart(name$))
            
            If ext$ = "jpg" Or ext$ = "png" Or ext$ = "bmp"
               AddElement(dirList())
               dirList() = name$
            EndIf
            
         EndIf
      Wend
      
      FinishDirectory(0)
      
      SortList(dirList(),#PB_Sort_Ascending|#PB_Sort_NoCase)
   EndIf
   
EndProcedure

Procedure FIT_IMAGE_TO_WINDOW(image)
   Protected resizeX, resizeY
   Protected iw = ImageWidth(image)    , ih = ImageHeight(image)
   Protected ww = WindowWidth(#MainWin), wh = WindowHeight(#MainWin) - ToolBarHeight(#Menu)
   Protected imageAspect.d = iw/ih     , windowAspect.d = ww/wh
   
   If iw = ww And ih = wh : ProcedureReturn image : EndIf
   
   CopyImage(image, #ImgTemp)
   image = #ImgTemp
   
   If iw <> ww : resizeX = #True : EndIf
   If ih <> wh : resizeY = #True : EndIf
   
   If resizeX Or resizeY
      If imageAspect > windowAspect ; stretch to fit x
         iw = ww                    ; new image width
         ih = iw / imageAspect      ; new image height
      Else                          ; stretch to fit y
         ih = wh                    ; new image height
         iw = ih * imageAspect      ; new image width
      EndIf
   EndIf
   
   ResizeImage(#ImgTemp,iw,ih)
   
   If maximize = #True
      CENTER_IMAGE_IN_WINDOW(image)
   Else
      ResizeGadget(#Canvas,0,TBH,iw,ih)
   EndIf
   
   ProcedureReturn image

EndProcedure

Procedure FIT_WINDOW_TO_IMAGE(image)
   Protected resizeX, resizeY, center
   Protected iw = ImageWidth(image)    , ih = ImageHeight(image)
   Protected ww = WindowWidth(#MainWin), wh = WindowHeight(#MainWin) - TBH
   Protected imageAspect.f = iw/ih     , windowAspect.f = ww/wh
   
   If iw > maxCanvas_X Or ih > maxCanvas_Y : ProcedureReturn #False : EndIf
   If ww = iw         And wh = ih          : ProcedureReturn #False : EndIf
   
   If ww <> iw : resizeX = #True : EndIf
   If wh <> ih : resizeY = #True : EndIf

   If resizeX Or resizeY
      If windowAspect > imageAspect ; stretch to fit x
         ww = iw                    ; new window width
         wh = ww / imageAspect      ; new window height
      Else                          ; stretch to fit y
         wh = ih                    ; new window height
         ww = wh * imageAspect      ; new window width
      EndIf
   EndIf
   
   If ww < minW : ww = minW : center = #True : EndIf
   If wh < minH : wh = minH : center = #True : EndIf
   
   ResizeWindow(#MainWin,(DW-ww)/2,(DH-wh-ToolBarHeight(#Menu))/2,ww,wh+ToolBarHeight(#Menu))
   
   CompilerIf #PB_Compiler_OS = #PB_OS_Linux
      While WindowEvent() : Wend
      ResizeWindow(#MainWin,(DW-ww)/2,(DH-wh-ToolBarHeight(#Menu))/2,ww,wh+ToolBarHeight(#Menu))
   CompilerEndIf
   
   If center = #True
      CENTER_IMAGE_IN_WINDOW(image)
   Else
      ResizeGadget(#Canvas,0,0+TBH,iw,ih)
   EndIf
   
   ProcedureReturn #True
EndProcedure

Procedure INIT_GUI()
   Protected windowBorder_X, windowBorder_Y
   Protected result.i = #True, x, y
   Protected ww = minW, wh = minH
   Protected flags.i = #PB_Window_ScreenCentered|#PB_Window_BorderLess
   
   Macro Inv(img)
      StartDrawing(ImageOutput(img))
         For y = 0 To ImageWidth(img)-1
            For x = 0 To ImageHeight(img)-1
               Plot(x,y,Point(x,y) ! $FFFFFF)
            Next x
         Next y
      StopDrawing()
   EndMacro
   
   If OpenWindow(#MainWin,0,0,ww,wh,"Image encrypter | v 1.0",flags)
      SetWindowColor(#MainWin,#WindowColor)
      WindowBounds(#MainWin,minW,minH,#PB_Ignore,#PB_Ignore)
      
      windowBorder_X = WindowWidth(#MainWin,#PB_Window_FrameCoordinate) - WindowWidth(#MainWin,#PB_Window_InnerCoordinate)
      windowBorder_Y = WindowHeight(#MainWin,#PB_Window_FrameCoordinate) - WindowHeight(#MainWin,#PB_Window_InnerCoordinate)
      
      maxCanvas_X = DW - windowBorder_X
      maxCanvas_Y = DH - windowBorder_Y
      
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_L, #Menu_load)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_S, #Menu_save)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_C, #Menu_copy)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_V, #Menu_paste)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_P, #Menu_password)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Right , #Menu_next)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Left  , #Menu_previous)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Up    , #Menu_encrypt)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Down  , #Menu_decrypt)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Add   , #Menu_stretch)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_F10, #Menu_minimize)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_F11, #Menu_maximize)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_I  , #menu_info)
      AddKeyboardShortcut(#MainWin, #PB_Shortcut_Escape, #Menu_quit)
      
      CompilerIf #PB_Compiler_OS = #PB_OS_Linux 
         If CreatePopupMenu(#MenuPopUp)
            MenuItem(#Menu_load,"Load ______________________ Ctrl+L")
            MenuItem(#Menu_next,"Load next _________________ Arrow right")
            MenuItem(#Menu_previous,"Load previous ____________ Arrow left")
            MenuItem(#Menu_save,"Save image _______________ Ctrl+S")
         MenuBar()
            MenuItem(#Menu_copy,"Copy to clipboard _________ Ctrl+C")
            MenuItem(#Menu_paste,"Paste from clipboard _____ Ctrl+V")
         MenuBar()
            MenuItem(#Menu_stretch,"stretch image _____________ ( + )")
            MenuItem(#menu_info,"show image info ____________ ( i )")
            SetMenuItemState(#MenuPopUp,#Menu_info,info)
         MenuBar()
            MenuItem(#Menu_password,"Set password ___________ Ctrl+P")
            MenuItem(#Menu_encrypt,"Encrypt image __________ Arrow up")
            MenuItem(#Menu_decrypt,"Decrypt image __________ Arrow down")
         MenuBar()
            MenuItem(#Menu_minimize,"minimize window _________ (F10)")
            MenuItem(#Menu_maximize,"maximize window _________ (F11)")
            MenuItem(#Menu_quit,"Quit ________________________ (Esc)")
         EndIf
      CompilerElse
         If CreatePopupMenu(#MenuPopUp)
               MenuItem(#Menu_load,"Load"+Chr(9)+"Ctrl+L")
               MenuItem(#Menu_next,"Load next"+Chr(9)+"Arrow R")
               MenuItem(#Menu_previous,"Load previous"+Chr(9)+"Arrow L")
               MenuItem(#Menu_save,"Save image"+Chr(9)+"Ctrl+S")
            MenuBar()
               MenuItem(#Menu_copy,"Copy to clipboard"+Chr(9)+"Ctrl+C")
               MenuItem(#Menu_paste,"Paste from clipboard"+Chr(9)+"Ctrl+V")
            MenuBar()
               MenuItem(#Menu_stretch,"stretch image"+Chr(9)+"+")
               MenuItem(#menu_info,"show image info" +Chr(9)+"i")
            SetMenuItemState(#MenuPopUp,#Menu_info,info)
            MenuBar()
               MenuItem(#Menu_password,"Set password"+Chr(9)+"Ctrl+P")
               MenuItem(#Menu_encrypt,"Encrypt image"+Chr(9)+"Arrow U")
               MenuItem(#Menu_decrypt,"Decrypt image"+Chr(9)+"Arrow D")
            MenuBar()
               MenuItem(#Menu_minimize,"minimize window"+Chr(9)+"F10")
               MenuItem(#Menu_maximize,"maximize window"+Chr(9)+"F11")
               MenuItem(#Menu_quit,"Quit"+Chr(9)+"Esc")
         EndIf
      CompilerEndIf
      
      CreateToolBar(#Menu,WindowID(#MainWin),#PB_ToolBar_Large)
      CatchImage(#ImgTemp,?Open_png)
      ToolBarImageButton(#Menu_load, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_load, "Load")
      
      CatchImage(#ImgTemp,?leftarrow_png)
      CompilerIf #PB_Compiler_OS = #PB_OS_Linux : Inv(#ImgTemp) : CompilerEndIf
      ToolBarImageButton(#Menu_previous, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_previous, "Load previous")
      
      CatchImage(#ImgTemp,?rightarrow_png)
      CompilerIf #PB_Compiler_OS = #PB_OS_Linux : Inv(#ImgTemp) : CompilerEndIf
      ToolBarImageButton(#Menu_next, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_next, "Load next")
      
      CatchImage(#ImgTemp,?Save_png_start)
      ToolBarImageButton(#Menu_save, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_save, "Save")
      
      ToolBarSeparator()
      CatchImage(#ImgTemp,?Copy_png)
      ToolBarImageButton(#Menu_copy, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_copy, "Copy")
      
      CatchImage(#ImgTemp,?Paste_png)
      ToolBarImageButton(#Menu_paste, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_paste, "Paste")
      
      ToolBarSeparator()
      CatchImage(#ImgTemp,?expand_png)
      ToolBarImageButton(#Menu_stretch, ImageID(#ImgTemp),#PB_ToolBar_Toggle)
      ToolBarToolTip(#Menu, #Menu_stretch, "stretch image")
      
      CatchImage(#ImgTemp,?info_png)
      ToolBarImageButton(#Menu_info, ImageID(#ImgTemp),#PB_ToolBar_Toggle)
      ToolBarToolTip(#Menu, #Menu_info, "show image info")
      SetToolBarButtonState(#Menu,#Menu_info,info)
      
      ToolBarSeparator()
      CatchImage(#ImgTemp,?secure_png)
      CompilerIf #PB_Compiler_OS = #PB_OS_Linux : Inv(#ImgTemp) : CompilerEndIf
      ToolBarImageButton(#Menu_password, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_password, "set password")
      
      CatchImage(#ImgTemp,?orange_fruit_png)
      ToolBarImageButton(#Menu_encrypt, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_encrypt, "encrypt")
      
      CatchImage(#ImgTemp,?watch_png)
      ToolBarImageButton(#Menu_decrypt, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_decrypt, "decrypt")
      
      ToolBarSeparator()
      CatchImage(#ImgTemp,?minimize_png)
      ToolBarImageButton(#Menu_minimize, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_minimize, "minimize window")
      
      CatchImage(#ImgTemp,?maximize_png)
      ToolBarImageButton(#Menu_maximize, ImageID(#ImgTemp),#PB_ToolBar_Toggle)
      ToolBarToolTip(#Menu, #Menu_maximize, "maximize window")
      
      CatchImage(#ImgTemp,?stop3_png)
      ToolBarImageButton(#Menu_quit, ImageID(#ImgTemp))
      ToolBarToolTip(#Menu, #Menu_quit, "Quit")
      
      CompilerIf #PB_Compiler_OS = #PB_OS_Linux
         TBH = 0
      CompilerElse
         TBH = ToolBarHeight(#Menu)
      CompilerEndIf
      
      CanvasGadget(#Canvas, 0, TBH, ww, wh)
      SetGadgetAttribute(#Canvas,#PB_Canvas_Cursor ,#PB_Cursor_Arrows)
      
      StartDrawing(CanvasOutput(#Canvas))
         Box(0, 0, ww, wh, #Black)
         DrawText(5, 5, "Image Encrypter " + #version)
      StopDrawing()
      
      maxCanvas_Y - ToolBarHeight(#Menu)
   Else
      result = #False
   EndIf
   
   ProcedureReturn result
EndProcedure

Procedure LOAD_IMAGE()
   Static Pattern$ = "*.jpg|*.jpg|*.png|*.png|*.bmp|*.bmp|*.jpg, *.png, *.bmp|*.jpg;*.png;*.bmp|*.*|*.*"
   Static Pattern = 3
   Static path$, lastPath$
   Protected result, F$ = File$, name$
   
   File$ = OpenFileRequester("Select an image", File$, Pattern$, Pattern)
   If File$
      Pattern = SelectedFilePattern()
      If LoadImage(#ImgMain, File$)
         result = #True
         encrypted = CHECK_IF_ENCRYPTED()
         
         path$ = GetPathPart(File$)
         name$ = GetFilePart(File$)
         
         If path$ <> lastPath$
            lastPath$ = path$
            FILL_DIR_LIST(path$)
         EndIf
         
         ForEach dirList() ; adjust the ListIndex
            If dirList() = name$
               Break
            EndIf
         Next
         
         UPDATE_CANVAS()
      EndIf
      
   Else
      File$ = F$
   EndIf
   
   ProcedureReturn result
EndProcedure

Procedure LOAD_NEXT()
   Protected F$ = GetPathPart(File$)
   
   If NextElement(dirList())
      If LoadImage(#ImgMain, F$ + dirList())
         File$ = F$ + dirList()
         encrypted = CHECK_IF_ENCRYPTED()
         
         UPDATE_CANVAS()
      Else
         DeleteElement(dirList())
         PostEvent(#PB_Event_Menu,#MainWin,#Menu_next)
      EndIf
      
   EndIf
   
EndProcedure

Procedure LOAD_PREVIOUS()
   Protected F$ = GetPathPart(File$)
   
   If PreviousElement(dirList())
      If LoadImage(#ImgMain, F$ + dirList())
         File$ = F$ + dirList()
         encrypted = CHECK_IF_ENCRYPTED()
         
         UPDATE_CANVAS()
      Else
         DeleteElement(dirList())
         PostEvent(#PB_Event_Menu,#MainWin,#Menu_previous)
      EndIf
      
   EndIf
   
EndProcedure

Procedure MAXIMIZE_WINDOW()
   maximize ! 1
   
   If maximize = #True
      ResizeWindow(#MainWin,0,0,DW,DH)
   Else
      If IsImage(#ImgMain)
         FIT_WINDOW_TO_IMAGE(#ImgMain)
      Else
         CreateImage(#ImgTemp,minW,minH,24,0)
         FIT_WINDOW_TO_IMAGE(#ImgTemp)
      EndIf
   EndIf
   
   UPDATE_CANVAS()
   
   SetMenuItemState(#MenuPopUp,#Menu_maximize, maximize)
   SetToolBarButtonState(#Menu,#Menu_maximize, maximize)
EndProcedure

Procedure SAVE_IMAGE(image.i)
   Static YesNo = #PB_MessageRequester_YesNo, Yes = #PB_MessageRequester_Yes
   Static pattern = 0
   Static savePath$
   Protected F$, p, result = #False, cancel = #False
   Protected Pattern$, path$
   
   If IsImage(#ImgMain) = #False
      MessageRequester("","No image to save!")
      ProcedureReturn
   EndIf
   
   If savePath$ = #Null$
      savePath$ = GetPathPart(File$)
   EndIf
   
   
   If encrypted = #True
      Pattern$ = "image.png|*.png|image.bmp|*.bmp"
      pattern = 0
   Else
      Pattern$ = "image.png|*.png|image.bmp|*.bmp|image.jpg|*.jpg"
      
      Select LCase(GetExtensionPart(File$))
         Case "png" : pattern = 0
         Case "bmp" : pattern = 1
         Case "jpg" : pattern = 2
      EndSelect
   
   EndIf
   
   F$ = SaveFileRequester("Save image", savePath$ + GetFilePart(File$, #PB_FileSystem_NoExtension), Pattern$, pattern)
   
   If F$
      pattern = SelectedFilePattern()
      savePath$ = GetPathPart(F$)
      
      ; remove any existing file extension
      p = FindString(ReverseString(F$),".")
      If p
         F$ = Left(F$,Len(F$)-p)
      EndIf
      
      Select SelectedFilePattern()
         Case 0 : F$ + ".png"
         Case 1 : F$ + ".bmp"
         Case 2 : F$ + ".jpg"
      EndSelect
      
      If FileSize(F$) <> -1 ; file exists
         If MessageRequester("File Exists!", "Do you wish to overwrite?", YesNo) <> Yes
            cancel = #True
         EndIf
      Else
         AddElement(dirList())
         dirList() = GetFilePart(F$)
      EndIf
      
      If cancel = #False
         Select SelectedFilePattern()
            Case 0 : result = SaveImage(#ImgMain, F$, #PB_ImagePlugin_PNG)
            Case 1 : result = SaveImage(#ImgMain, F$, #PB_ImagePlugin_BMP)
            Case 2 : result = SaveImage(#ImgMain, F$, #PB_ImagePlugin_JPEG,9)
         EndSelect
         
         If result = #False : MessageRequester("Error!","problem saving image.")
         ElseIf ListSize(dirList()) = 0
            FILL_DIR_LIST(GetPathPart(F$))
         EndIf
      EndIf
   EndIf
   
   If result
      StartDrawing(CanvasOutput(#Canvas))
         DrawText(5,5,GetFilePart(File$),0,0)
         File$ = F$
         DrawText(5,5,GetFilePart(File$))
      StopDrawing()
   EndIf
   
   ProcedureReturn result
EndProcedure

Procedure TOGGLE_INFO()
   ; toggle image information display on/off
   info ! 1
   SetMenuItemState(#MenuPopUp, #Menu_info, info)
   SetToolBarButtonState(#Menu,#Menu_info, info)
   UPDATE_CANVAS()
EndProcedure


Procedure TOGGLE_STRETCH()
   stretch ! 1
   UPDATE_CANVAS()
   SetMenuItemState(#MenuPopUp,#Menu_stretch, stretch)
   SetToolBarButtonState(#Menu,#Menu_stretch, stretch)
EndProcedure

Procedure UPDATE_CANVAS()
   If IsImage(#ImgMain) = #False : ProcedureReturn #False : EndIf
   
   Protected WW, WH, image = #ImgMain, zoom.f
   Protected iw = ImageWidth(image), ih = ImageHeight(image)
   
   
   If maximize = #True ; window is fullscreen
      
      If iw > maxCanvas_X Or ih > maxCanvas_Y
         image = FIT_IMAGE_TO_WINDOW(image)
      ElseIf stretch = #True
         image = FIT_IMAGE_TO_WINDOW(image)
      Else
         CENTER_IMAGE_IN_WINDOW(image)
      EndIf
      
   Else
      If iw > maxCanvas_X Or ih > maxCanvas_Y
         image = SIZE_IMAGE_TO_MAXIMUM(image)
         FIT_WINDOW_TO_IMAGE(image)
      Else
         If stretch = #True
            If (iw > maxCanvas_X) Or (ih > maxCanvas_Y)
               image = SIZE_IMAGE_TO_MAXIMUM(image)
               FIT_WINDOW_TO_IMAGE(image)
            Else
               EXPAND_WINDOW(image)
               image = Fit_IMAGE_TO_WINDOW(image)
            EndIf
         Else
            Fit_WINDOW_TO_IMAGE(image)
         EndIf
      EndIf
   EndIf
   
   If 1.0 < (iw / ih)
      zoom = ImageWidth(image) / ImageWidth(#ImgMain)
   Else
      zoom = ImageHeight(image) / ImageHeight(#ImgMain)
   EndIf
   
   StartDrawing(CanvasOutput(#Canvas))
      DrawImage(ImageID(image),0,0)
      If info = #True
         DrawText(5,5,GetFilePart(File$))
         DrawText(5,8+TextHeight("A"), Str(ImageWidth(#ImgMain)) + "x  /  " + Str(ImageHeight(#ImgMain)) +
                                       "y  = "+StrF(ImageWidth(#ImgMain) / ImageHeight(#ImgMain),3))
         DrawText(5,11 + 2*TextHeight("A"), "scale = " +StrF(zoom*100,1)+"%")
      EndIf
   StopDrawing()
   
   ww = WindowWidth(#MainWin,#PB_Window_FrameCoordinate)
   WH = WindowHeight(#MainWin,#PB_Window_FrameCoordinate)
   
   If WW < DW And WH < DH
      SetGadgetAttribute(#Canvas,#PB_Canvas_Cursor ,#PB_Cursor_Arrows)
   ElseIf WW < DW
      SetGadgetAttribute(#Canvas,#PB_Canvas_Cursor ,#PB_Cursor_LeftRight)
   ElseIf WH < DH
      SetGadgetAttribute(#Canvas,#PB_Canvas_Cursor ,#PB_Cursor_UpDown)
   Else
      SetGadgetAttribute(#Canvas,#PB_Canvas_Cursor ,#PB_Cursor_Default)
   EndIf
   
EndProcedure

Procedure PASSWORD_REQUESTER()
   Protected  idx.i, p.s = password
   
   password = InputRequester("Password Requester", "enter your password", password)
   
   If password <> #Null$
      seed = 0
      
      For idx = 1 To Len(password)
         seed = seed<<1 ! Asc(Mid(password,idx))
      Next
      
      If seed < 1e7 : seed * 132546 : EndIf
   Else
      password = p
   EndIf
   
   ProcedureReturn seed
EndProcedure

Procedure PASTE_IMAGE(image.i)
   If GetClipboardImage(#ImgTemp)
      CopyImage(#ImgTemp, #ImgMain)
      File$ = GetPathPart(File$) + "NewImage"

      CHECK_IF_ENCRYPTED()
      UPDATE_CANVAS()
   Else
      MessageRequester("","No image to paste!")
   EndIf
   
EndProcedure

Procedure SIZE_IMAGE_TO_MAXIMUM(image)
   ; shrink extra-large images down to maximum display size
   
   Protected resizeX, resizeY
   Protected iw = ImageWidth(image), ih = ImageHeight(image)
   Protected ww = maxCanvas_X, wh = maxCanvas_Y
   Protected imageAspect.d = iw/ih
   Protected windowAspect.d = ww/wh
   
   If iw <= ww And ih <= wh : ProcedureReturn image : EndIf
   
   CopyImage(image, #ImgTemp) : image = #ImgTemp
   
   If iw > ww : resizeX = #True : EndIf
   If ih > wh : resizeY = #True : EndIf
   
   If resizeX Or resizeY
      If imageAspect > windowAspect ; fit to x
         iw = ww                    ; new image width
         ih = iw / imageAspect      ; new image height
         
      Else                          ; fit to y
         ih = wh                    ; new image height
         iw = ih * imageAspect      ; new image width
      EndIf
   EndIf
   
   ResizeImage(#ImgTemp,iw,ih)
   
   ProcedureReturn image
   
EndProcedure

;{ tool images
DataSection
  Copy_png:
    ; size : 663 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$4D41670400000061
    Data.q $8A0537C8AF000041,$58457419000000E9,$72617774666F5374,$2065626F64410065,$6165526567616D49
    Data.q $00003C65C9717964,$CB38544144492902,$86144154683DD375,$6EB26CDDCCCCF7E1,$49304292827F1576
    Data.q $148B51188B415625,$5A28A530411B4A9A,$6097B0B1A09DA089,$1312274EB4AC0421,$92698865A80C1251
    Data.q $EE77FFB8C6B82488,$4CD3DD9282BB8B1C,$76323333CE63E733,$18CC747CDECBC3EF,$AF0D2A8820268A8A
    Data.q $7A54B379F36A9D95,$E5C943A75E353F36,$6DCE1FDD5E9F8B47,$012712A820158396,$8DC5A59B617A6167
    Data.q $BD3DCF6E37D7DF37,$A94F488C60176D50,$B023FAF94B6576AA,$974F663D79F099BC,$B9FF48E8C8A86463
    Data.q $0A30274EDDC2FEDC,$58C856320EB20562,$DA18D76E6C319B21,$5CF5F7F40B27130B,$A0B2204400E014ED
    Data.q $FF2ECC33AC856A0A,$07C703EF1EF0DA3E,$CA82454BFA6B710F,$345FD5ADAFAFDD4E,$A735E353F327A54B
    Data.q $084A2A5A63582080,$5B30F67EB98E234A,$19B2D3D7D36A40E5,$31B8B4B07ED85E98,$9085538AE6637A3C
    Data.q $9219C640AC042276,$6314B6565559F944,$83339E6A7607D894,$C5CC65C9150C8CDD,$C011554EC7E5D799
    Data.q $4940560A08623019,$26D7FD14674BACD7,$375D73B302C1C4E2,$2DC77F6F82486A0D,$E125AB365AE0271B
    Data.q $067225355F836ADD,$7FE28197C36D6A27,$AC1188B2E86C9DCD,$9912A366E2E028B5,$822305518D90AE7C
    Data.q $41095446CED09A48,$5DBF44F9C1541110,$D68029E9A078FC9B,$8FA7132C17CEED20,$03B740C80131B2EC
    Data.q $376B1A9E4CCDC555,$6BBC12714B87A5FF,$4C1043D4155D953D,$ABED36A5D6A24FC7,$A86D3AE23048CBE1
    Data.q $B2EDF7E4C8A5EAD6,$A6FA825E9AD21D21,$BFDE77F380DB6AA8,$FE5681F4C00646B5,$E42E52682558B4DA
    Data.q $291BFF97173FEEA2,$49000000007AA4ED
    Data.b $45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
  leftarrow_png:
    ; size : 344 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$4144491F010000F8
    Data.q $6031A06463DA7854,$6060100FFC163C1C,$9FFF98162681F0DC,$319871C6C0C6C157,$D0DFFE7816EA81A6
    Data.q $696180B05FE0C21F,$CA11C5EFF82D7523,$C40139C183DD3450,$5A19D3C34005AEA5,$A884C07A18319BD6
    Data.q $EC26192B32300167,$8EA6164037906157,$B6BA19EA1463FF05,$C0BC2BA06A4831CB,$D93DB68301A0F570
    Data.q $06016830CFFE3016,$14853602B083048B,$E80BA2CF3FFEC059,$C90A5C0176061E72,$E5C807957FF840B6
    Data.q $6D9214F81C8C0C6C,$A10C51ED55FFF381,$FF86441452148415,$CCD3F7A430E41467,$C15093DFFD501002
    Data.q $BE008016669F3C50,$452B8020058AA0F8,$259009E500A8B551,$0C00B13412BC0C42,$32C0645815BAB980
    Data.q $9728825B002DF51E,$C4605C92D4016368,$8016369070B8605F,$F8B2D065E0E2F12D,$005016368073D8CC
    Data.q $E97EA1DD00016E68,$0000000005726FC6,$826042AE444E4549
EndDataSection

DataSection
  minimize_png:
    ; size : 229 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$414449AC000000F8
    Data.q $5E02006063C74854,$4AFDA90CA904DE13,$09664181A9FF4ADD,$96A70CC030540A38,$4181B04DD058E8C1
    Data.q $68502CAD3CE650A6,$EDD2C28C40CF7852,$8913A3C4C1D1FFA5,$2D460B5182D464B2,$5E5CD60B1280B518
    Data.q $0F964B5200589FF3,$110544E19F04B188,$601C744E19084B3E,$DD00B689C31884B3,$259802C9270D6212
    Data.q $EE4AAE40B60E18A4,$EFC576C54CAAAD3E,$40B2B4FDC27EC20C,$230B2303396C5A2C,$2E1B6A7CE8B86887
    Data.q $004993899DB12291,$EE21D9A5D10CC200,$4E45490000000097
    Data.b $44,$AE,$42,$60,$82
EndDataSection

DataSection
  Open_png:
    ; size : 688 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$4D41670400000061
    Data.q $8A0537C8AF000041,$58457419000000E9,$72617774666F5374,$2065626F64410065,$6165526567616D49
    Data.q $00003C65C9717964,$1918544144494202,$001865558B41C105,$61DCEF77CEFDE7E0,$D98D4B51894DD468
    Data.q $368B5569B846508B,$3689FD155A42D041,$84FD0564DD3EE091,$9B5042516444595C,$A8E24E23A169B108
    Data.q $7BE73DCF7BDCCCE3,$ED7000004CC89E7B,$E06861830E5CC3E6,$8BFB1968A3A3CEF6,$BDFA6F8BBBDDDEE1
    Data.q $991E7B7D5D3FCBBD,$3F3F70FCAE000009,$32D02683C3CA70BC,$13DBFD7C76A6C6AD,$9DBDC1F6F9DADFBF
    Data.q $C7A638C000002AF7,$0D5A4A54C3CEE947,$E775E9C6F07CFECD,$FF5D6F2D31B71CCF,$E890000002B3E0EE
    Data.q $66176985DA655982,$704E677327BFE2D3,$0B8FB5D31B31DCF1,$41A8E93044000000,$E6E17BDB16ACC2ED
    Data.q $DEA2D49A79D3D2F6,$56D6E6D98FF67EBE,$2BA10A9F4A400144,$1289D6B25AD48805,$9795E591A893AEBA
    Data.q $0892120889397FCE,$4C174D0840D7DC6E,$9321110B5A99116B,$5C1F2DAFD685C86A,$7E73C453651DF631
    Data.q $16A8BFAF8BB2F5BC,$6530D282E92D144A,$BD6C9455AA9992BD,$F67FB70E96CA9FB1,$17EECE3A5D3FEFF4
    Data.q $1F68661D0E811204,$730DACE4550B42FC,$D5B476F6AC77DBFB,$D91F5BABEFB389C2,$14A4CA401664E8DC
    Data.q $5A2070E59CFCF9FE,$BC9DE7F5D4556A89,$F07A39A94C8D0970,$148416642919FE95,$1CB5365A606BE6EA
    Data.q $7BBF42E399956AFA,$B03F45E70E68090D,$5F307E8B461AB15C,$9FBBC558F0BF8EF6,$2D5EB2636C7BBAFC
    Data.q $656D1A264081B665,$ED05C72974C56D73,$D4ECD4F0E5F71B50,$849EAFCB8DC5FE9B,$F648E499230CCFAA
    Data.q $1E3973990B692DB2,$867C72FB0E40F1C9,$8F470EADF66A0006,$A13993B2164261B4,$44F664AE41B6C9AD
    Data.q $B9A800058B8C194F,$12D39DF57DB5FE58,$B4F7C44800000001,$293C21693FF00DBC,$00000000D6A829D5
    Data.q $826042AE444E4549
EndDataSection

DataSection
  orange_fruit_png:
    ; size : 886 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$4144493D030000F8
    Data.q $134C4B56C5C74854,$B29B89931B7D1451,$B2170430B0371031,$05C1251244170432,$92120EC859121886
    Data.q $21B50BA22602424A,$98A28D955C49591A,$91889507E0C06A20,$524101A6B5A9F208,$B694B4E32C5B6244
    Data.q $768741E73AE569D3,$7CE979270BA8A53A,$0DF7B9EE7BDCE73A,$E6BCB133C8F3FF63,$B14B957EE5FCD64A
    Data.q $BDF35FD4B5E4A45D,$FE0AC7D82F6856BD,$B519E0D0B8E1BC0A,$9377EC396EAB4AAC,$52E6CF7CF24434BC
    Data.q $B6317E028BA2C3CF,$FCBA6D3A5D29D932,$5DEE3259BBBF5147,$AEBF8A762B23FBB4,$E19E8D8AF8C7BA22
    Data.q $C8A12F3D7FAE27D1,$9DE775AEDCF908F2,$B82B28ACFDA2D98A,$EC522142862CD877,$48223303415EA216
    Data.q $79226B4285AA652C,$919E5641F962ACA6,$0D2CA2FE3C039100,$833678088DF70B04,$7AB3F2D0F7EC2887
    Data.q $16439A860987B08F,$7D1B044EC001B91E,$8B7CFE49C7B88A26,$D2BB739AB3189202,$3D165EB9A14141A4
    Data.q $9F3FBC153EAC6C41,$5D96BF0D4DEC5EF0,$5807A5480E75E403,$C75111C1BB0046A9,$5A8133BB9878DA35
    Data.q $FC723CC527964D07,$B7203D79728F846A,$D11F4876C34F0046,$5D22AAFE29BBE744,$17973C020935D567
    Data.q $690B21FFFA3CB807,$1430E597B39EB2C2,$DBDBB9E4C4B36C24,$7CAEFC19390B8F40,$5272CBE8381970B4
    Data.q $6323A9F4DD36DBA6,$8EE24876779570A6,$B8EA306B768A2742,$C1A1807D350EEC6E,$9E00CE16693F4142
    Data.q $987D5FDC6177B3B0,$C81DD1CF87343355,$9D456380445A92FA,$6A07B57CAC12B237,$3A1F829D065AB08F
    Data.q $2D93CA7335ACE8E4,$9B20450358CAE784,$1362E3932E972AE3,$0E6B7811C225B767,$3A816B51E5EA8B73
    Data.q $851CD4ECEA273B24,$D903043DFEBC2867,$A900FF96D7D841B5,$25505B9A88998A27,$D2C3915B04197949
    Data.q $23862FEA364A5270,$039A053453669366,$5E9032580620024E,$C57DEA305AD47D2E,$9D35ACCDBE568176
    Data.q $FCB9EEF9BA529A10,$652DAF112A24BF1E,$6F794CFA9B35A682,$B26D466F8891EC36,$459B4F6655DD349F
    Data.q $31BA1C342A0C07E8,$5B3508686B6C0113,$EAA36C719A898164,$24C615C3E2483EA8,$CB1FD640337A405B
    Data.q $EE3B6D4CA7F3C133,$EE3E0C3A85477509,$25C70051A3523577,$A793C15905EF27EE,$11B99EA7C295E0EB
    Data.q $726B0DBC11008E09,$B6F8BAF7AAF42E7B,$2A3A333772ECF3E9,$D21A787C3625598B,$4738D1EC215C7AAD
    Data.q $FF5A149EB64863F7,$1E34FA830D02EBF9,$236EF9C0CAF88D63,$CDECE09804310DFE,$45490000000047C7
    Data.b $4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
  Paste_png:
    ; size : 703 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$4D41670400000061
    Data.q $8A0537C8AF000041,$58457419000000E9,$72617774666F5374,$2065626F64410065,$6165526567616D49
    Data.q $00003C65C9717964,$1918544144495102,$001C65968831C105,$9C9E7DEFBEF3DFF0,$5E6095A457411DA6
    Data.q $B4360D68B64520A1,$0D191414D2D0435C,$2D056D8D84110E4E,$D50D290510450E0A,$04441041815852D2
    Data.q $9DF29E59E156DE15,$FBF7FFF3CFBDF7D7,$11F07E5FE704CC95,$AC2EA79B800002FC,$7A5EE728000005EF
    Data.q $77CB5DB585BC51E0,$00FFAEB6B38DE17B,$DBAFB3C3E63AEE96,$0BA9D2E11F05BADE,$5E67A5C0600117EB
    Data.q $F3FD7B9EF96FB339,$CC816D9B5332FBD5,$CA4F474B3EC8E274,$2E2CF7BFCECFB5CC,$B3EE5797FB80C002
    Data.q $C9FEB6DE3115FBF9,$B4A51FCF5D22643B,$06ED8F579677F3F1,$751D45CEB2018000,$DB8FA665568B0FFB
    Data.q $2DB7F37004432D69,$BCF3F77D5ED3F8E5,$1EBFF5CFF5F95B31,$A368807B6D6E7CBB,$A43FECDA6718A3A8
    Data.q $0D31B55B9F378436,$F88FE8616C699105,$3EAFE97DC3E6CAE0,$133A88070717DAF9,$CEBBE93214A192AD
    Data.q $6975D48D8FE9DB8D,$3B43D4F576D6E1AC,$F95BA4D2D7B43F1D,$3A8B9D441D4FDB36,$FA06D44DA8B9C6D7
    Data.q $B17D262FA4C0E2C2,$4EE876DCDB5CE938,$0181E63A8F627C5E,$B1886B2E71C99C62,$C9E85852A62DA991
    Data.q $37FD5CE87162FB24,$0B0EFF7C799EFF4D,$189B5173A8806743,$7D1454C8A441A89B,$A57A3B24452501D7
    Data.q $26C7201897BEFA2B,$0080236A26D44DE7,$4C94E864C2FA1145,$B1D4032645294511,$4491B189AD13636A
    Data.q $F4913A574743054B,$1A6640E761302E85,$6B26B64D8C55E720,$00000062A2D048C8,$4E9EDE5C06289591
    Data.q $B5136B2AB7DAEC4F,$0017B14EACC18991,$780CAE8954EACC00,$00A38DDD3F2FEBFB,$F603BA16F3F0ED70
    Data.q $500A514AE9328E2C,$9992F3AC887777D0,$E9BFEF99E4E00000,$20A2DC856E9072BB,$5A59EE9B644A5141
    Data.q $38134935AF3FF9D8,$490000000085FD33
    Data.b $45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
  rightarrow_png:
    ; size : 342 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$4144491D010000F8
    Data.q $6031A06463DA7854,$F8712FFEF016941C,$1FB6E30304ED70CC,$030692FFF6C0B134,$0C81350CC9FB0306
    Data.q $860482C4D03E1B8C,$33B42F0F0C3BFAE8,$400B2284B3E23814,$2D83541F6F0C17EC,$3BC080162680F259
    Data.q $FF3CCA18CA2FCF86,$E0400B1340B8CE33,$327E4B200FCFC30B,$FFFFDCC162813A4E,$07AB8605C16A93FF
    Data.q $317FC5D1EDB4180D,$8CB7F88C0351FFFC,$30740C0162683B6D,$3340592C66DE26F4,$F3C2CCC30A60400B
    Data.q $2C0801666813198C,$F1600B3341DD5863,$2DD51453900B1341,$827961CB903C6500,$11A37E78623C16AA
    Data.q $868CB54D5CE472E8,$CE18A7058AA25CAB,$6F8B31592E0998EF,$6AC177B0C1D82D8A,$164503755C4CBE86
    Data.q $40633B6138D861AC,$E18BF05B64B53E21,$D4841D498C938FD7,$5420100FFF275792,$16E6800901665193
    Data.q $931060B8E5F20000,$45490000000005F0
    Data.b $4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
  Save_png_start:
    ; size : 620 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$4D41670400000061
    Data.q $8A0537C8AF000041,$58457419000000E9,$72617774666F5374,$2065626F64410065,$6165526567616D49
    Data.q $00003C65C9717964,$191854414449FE01,$0618555D8B3DC105,$9282433BECCFB5D0,$560A0344448460A8
    Data.q $827F15A3F1206501,$A522D0422A916885,$A16308A222565636,$2295616282760AD8,$12B442C54EC11616
    Data.q $1F7EF67B99DE0CC5,$1E16F77C6F876AD7,$268E91F70278F3C3,$2A94934B2CD2DEC0,$DF5D3DBCFC6FECFF
    Data.q $7D3C765FCBF1F3BB,$1E2EA79A75DAEB74,$DECB5BB11BB15208,$B6F1C6B458399CD2,$7C79FEBF73CC9F1C
    Data.q $C6F0E4F97E6FF3E5,$E7757C20BC16E7D7,$AA0FE1F9B892155F,$37669659BD366B42,$D7F4B4DA5196BB62
    Data.q $8FFD8399D0FCBA5E,$3ACA3AC554123C16,$5537A6C7BE8AD602,$77F7C4847595DDB1,$FD8E9ED9ECDFD9EF
    Data.q $2C0AEED882A3B38E,$6B2734D17D3611AD,$8FE2542A25469ED9,$12267D275A484EBF,$E9B15FAFDBC0474E
    Data.q $8CB4EFF8CEB0BE8B,$A4A63ACAA444552A,$8FD9FBBC489AB474,$461A2FA6C6966B5A,$41FE7F38002518C5
    Data.q $9AA94A85D123D8EB,$510213469170BE1E,$35A2AA895124AAA1,$D0092730E9483AEB,$448244124551A012
    Data.q $1874A49B5D65244B,$A4491234D11010B3,$9CA22A535512444A,$E77842B313A521AE,$D6E0000000004B95
    Data.q $35A5F4A488C64FD1,$0075F6E0F84888B3,$873991EAF3700000,$700D1551AE8908DD,$6A00000000ABD2ED
    Data.q $34ACC927A506B996,$00000005FEFF6E02,$33AD39CD17D1F678,$F8F51BB6FC57A492,$FB9F378D6ACF9733
    Data.q $CBFB85C000000014,$DF6F8DE1DBBF819C,$9280792AB924F24F,$89148A4948A49484,$3FFBB96D3DC84824
    Data.q $A2B0106D8B6E7C21,$444E454900000000
    Data.b $AE,$42,$60,$82
EndDataSection

DataSection
  secure_png:
    ; size : 537 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$59487009000000F8
    Data.q $2E0000232E000073,$0000763FA5780123,$DA7854414449CB01,$9D185144284D55D5,$1B4B1DA5A5A5A5A5
    Data.q $69696965652C6CA5,$9A91344A46C76969,$8444289059F908A2,$89A888935144A514,$38F399BDE67EF3BA
    Data.q $F4D33F79DDBA6F8B,$DFBDDF799ABE2C2C,$041337BBE77CF739,$940585EEA32FE641,$7F2F6176E4E1F6DB
    Data.q $F7C51E601D48EFC0,$B7F00DE01F06943B,$04BC64006A534A87,$827CDEC36FFE46EB,$DF84F8C04E7FF7D7
    Data.q $2BC1D603777B05BE,$EB728DF07BD4AEFC,$3A9DDF8178C05414,$FF57A8014EFC1BC0,$B0D28D7196C800BA
    Data.q $BD49EF971DC29C00,$58A8D148B74E2D88,$91DC15C030DE7585,$707A54D938438024,$EA1BA2728A547701
    Data.q $B0DEBC3CC99C31C1,$40D46BB4002A6485,$6E059C1EC02846B2,$9B984CE04FF2869E,$3323AC3AC0090779
    Data.q $7E61CA0667BF0CFF,$23202E80155AF607,$C9516017AFEA5B53,$97FA9E39EBCC50E5,$E88BAB1917EFA798
    Data.q $2CFC922EF06738ED,$BF679234A79997D4,$3C0596695072246A,$433AD6402F57272A,$4620FA027415473D
    Data.q $B7285425367534B2,$648E4E98EE0CEE48,$1B83146902E80143,$DE398807C009A185,$E76286945BF7FAB0
    Data.q $01310E83F4BBF740,$DF661E939BF5E11E,$8591231DD5B2001A,$541CE5D605709452,$96CBAF78A22FCCC1
    Data.q $D05C572EA9B4C938,$194F43E25E975141,$A8D279C128B34B68,$64F8FDA1C1E86FC9,$0B1D141F89EB834A
    Data.q $000000B72ED59205,$6042AE444E454900
    Data.b $82
EndDataSection

DataSection
  stop3_png:
    ; size : 467 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$4144499A010000F8
    Data.q $04482F96ADC74854,$C3860C497FC51841,$18346D31060B9264,$125D31060C4974C4,$3517082F174C4183
    Data.q $2C98AF264C0E1169,$9E4CE581C20D041A,$F59106C882E18326,$DCECEDFAEB1EC2DE,$BE6F7D9996DE0F9F
    Data.q $0071B02B605033BF,$6B9A0D469370C7A7,$69FA6B0CD30535B0,$0B910B77A0AFF613,$5E4A066340EE10D7
    Data.q $E2229D0E78B0F3E4,$E1C30B560098742C,$B93DCD502A176A73,$144F3FC13C871DDC,$D7093C824EE80BF3
    Data.q $E36B5094040DCC2C,$D12E41063D16AD4B,$DAE61A35BD1CB943,$B5E6856F4E0D1C1E,$22299EBDDF648F5E
    Data.q $9B37BCF78DDBB0F2,$6B65AA3285DF48A6,$14D0C27E8952A9F1,$605355AB9ECB9349,$896042F261A86A1B
    Data.q $2571F4486A0B92F8,$F070A82E4BE22B2C,$2E02792F88B49EA9,$89792C365368BDE1,$BCF2187EE04E0537
    Data.q $2F968439E1D05BC4,$A0CE2CAEAAE2C2B9,$7094FB92FAEC3ACD,$8FC5ADA5A8B29A1A,$BB67C8B4D099CB56
    Data.q $56CDDC72C12C0A6D,$6AAE8FF14A95DC2F,$F66B7B13A757C891,$C134935262F26240,$18C8DE6A267F0402
    Data.q $9719494CB088F105,$D464F26ADE76E15C,$ECBDF7BAB2AFF570,$B1F785ACD42C8FEA,$A011EB0E2E944A65
    Data.q $A82FF1114CE7A619,$00C5F3CC9E9B9F71,$AE444E4549000000
    Data.b $42,$60,$82
EndDataSection

DataSection
  watch_png:
    ; size : 606 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$41444925020000F8
    Data.q $A305186063C74854,$1B8801D880240800,$2CCAF070E625B9D8,$280588003881B100,$2F38E04040403831
    Data.q $0A5FB3054977FF2F,$EB869CB191FF0526,$D735405FAE0E0E1F,$CE9A800C0D1196A1,$F75BEE687E3A3A3B
    Data.q $87CCC77FD1EF3DDF,$B520FFEECF6D7138,$9AF17A40F7FCFCFC,$FAAAAAAA1ACACACC,$FF3E1FFFFDFEFF66
    Data.q $DBF5793E1870D045,$05E907FFCFE7F3FF,$CE4E4E70D58A919A,$7FBFDFB7BB3B3B4A,$0C512FFD85020FFF
    Data.q $0165202FF9EC74D1,$E5C172283DE1AEC6,$483FEFF5FCFFFE4F,$4C086007E060606F,$F050FFF0C83970C0
    Data.q $C0CA81C30C5FDBF9,$25693560EDF6FB78,$A603F7BD5CD45173,$A5A4144FB2096C1D,$E0AE1EFF7FBD5FA5
    Data.q $B444799A28EFCDFC,$C6AC1CBE5F2C16E0,$1FBDEACD4519D6DA,$7B9393913E41FAE1,$84030303077C8B0B
    Data.q $CD1457C2F87040E9,$98998600B709A4C0,$D901F1DD2CD451D9,$E03A3838382FB008,$DBC2770494949FE1
    Data.q $6325EACB34507F8F,$E406A287E2A62058,$212FD56AB5581828,$282820F12883A121,$514C1BEDADADA3B8
    Data.q $5BB4FB66B853CD64,$C90B86E1423425FF,$07970CBA4DB7FC39,$C6E36040A39036A5,$D5018FC5C5C53F8D
    Data.q $BE3E3E0E2427A071,$D3DEC7C506C8A0B9,$0B60BC20A24A885F,$32E3BFEBEBEA7824,$BBBBBD228145251C
    Data.q $CF0D04BBE4F577FB,$FF759AF57FF17AEE,$4F7373723EA4A4A5,$9E2A005012386BC2,$7E7C2C8DEFCF4C05
    Data.q $895FF437FDB63968,$86DA9BFF5AECD582,$DE2E600FDFC604FE,$2A04794E41A3D407,$080AD644F87822CC
    Data.q $C60E79551013DECB,$03D6C5F8780F7222,$30C146F02D2812E5,$FBDB7A0C0B3B0000,$4549000000005039
    Data.b $4E,$44,$AE,$42,$60,$82
 EndDataSection
 
DataSection
  expand_png:
    ; size : 426 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$41444971010000F8
    Data.q $6031A06463DA7854,$19181B1419FF1104,$F509960CD8C037EE,$D717C91A0BE3D960,$C0B10256B86461EA
    Data.q $6A467AF1E33FF1B2,$8F030267033FF8B8,$4CC80893AE833759,$13E81158360059AA,$30266BE386050909
    Data.q $220A402C20148658,$305EEF7781060C8A,$0058A0C0C9A89CDC,$030C1863576C9332,$009EBC323214A7C7
    Data.q $0D06067FC16592E3,$1A72720CF5E4E906,$FD0D022BD7101228,$44B4044139016281,$AEAE833364278180
    Data.q $37034081F5F5C20D,$E02D832476499B20,$061BE3FDF0CF5C0C,$302E773B8610FB4B,$499A8797086C5EBE
    Data.q $38183BE419FF0596,$C8C9BA9FBE19CC8D,$03067F033FE334F0,$EC18F3C3230D9703,$56E386E844109016
    Data.q $3D189CBAE4441487,$6441A0FAB10B0764,$CADC03C5E18180B9,$5E19DCCD441838D8,$88A918E1AC493BEF
    Data.q $9C3232669BE38EA0,$05B088A918E5DA25,$0F03380B74929288,$9402D553D8181830,$0C0164A9D32E4220
    Data.q $23CD11079A02C9D0,$034E34672016E699,$E19070B85D707807,$C58AC02D100385FB,$018D7C32DD1E23D2
    Data.q $6A7B000162346A8A,$0000A3F4A6BC19F3,$42AE444E45490000
    Data.b $60,$82
EndDataSection

DataSection
  info_png:
    ; size : 538 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$414449E1010000F8
    Data.q $02483195CDDA7854,$83428382FFC71851,$C343834383418341,$43420D0541060D05,$60D0A41060D0D53A
    Data.q $4D1043510EA6D0D0,$3914379356E9043A,$D410DD4DA08394DA,$D0E0E0D0D0E0E410,$4D3AEEF9F508EFFD
    Data.q $DFBDEF3DDE1C3FA1,$CC6173DFFEFBEFBB,$DB981054C003FD72,$503A8DE3BDCB0202,$203E3C0143BF982F
    Data.q $94BC0DFB31280E7C,$98000C6AF8077500,$3DDFC2602B91030D,$69A1B8F1E0F8081A,$D03A5027D6FDE14D
    Data.q $EFB7C5C000EF28BF,$33DB56A3F14551C5,$D926AAA81BD1A3EE,$0C006CE6A8026DD8,$09122A73B8B3FECB
    Data.q $3B8913EE34DC58A2,$7202DDA0095572E4,$D62C3000B35340F3,$7CF9442314C58F31,$0AF7ADE2DB56AD1D
    Data.q $5E2015F80128B970,$CCDD2628019C8D83,$B23A5804ED601747,$E054D23F442CE29A,$9099811F76002A3A
    Data.q $6994A9057A7494D5,$00DB2E7F41E64C85,$0AF92002D367B258,$025C331801A302F8,$3004233D5643F0E0
    Data.q $E9DE340028F44CC1,$6F00C1D12FB000A4,$F077200155F99FFA,$C002D2BF46728070,$006EA61E492B31ED
    Data.q $44158BF6B96532C5,$271732704FCD9B37,$66C80BE3C55EB084,$1EF5E68DD6513BD7,$A494C0FA7FAC004B
    Data.q $60E8AF5D346CD1D9,$70C9E142A951D802,$8B23B8BA5EE8AF74,$BB38B8B96AEF6D76,$66AE8A00AFDE1B29
    Data.q $BB924B13B344F165,$422E628021C584EE,$547846DFD1B82049,$0E669D585CAB34F2,$39EADF01D8D77F00
    Data.q $0000E51FB9C619B5,$42AE444E45490000
    Data.b $60,$82
EndDataSection

 DataSection
  maximize_png:
    ; size : 1048 bytes
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1800000018000000,$3D77E00000000608,$414449DF030000F8
    Data.q $5B4F4B55ADC74854,$AA9112A63F3E1057,$4DDA89B2AD08BB2C,$20452B6AA2EAAAAA,$A910A28AAB2D4DB9
    Data.q $4A56AAACDA95B66A,$51E6217507DC822B,$EBEBED7C015E6D83,$7E307123F1863607,$F588790848182E62
    Data.q $11A8488439C77CE4,$9BE77B8B33A7C5D0,$70E9D3846F999DF3,$716844C994992D2D,$2A506D3A50612C31
    Data.q $E7264A798585A215,$E2567C78A3989128,$143359643362C52E,$524E69914C4B4E8D,$904484F0E1493224
    Data.q $E7E68050A140230C,$F9204B85F5D5D4FD,$D9F9B73F9F8B7EFE,$93C9F9B53E9F9B33,$FC6B01EDEF268975
    Data.q $B51E8FCEA24371F8,$3B3BCAA24D61F0F1,$DCAB12CBB7B78540,$E1589259B9B1B56A,$37C91CA81231D9D9
    Data.q $DD803ADA2879D7B7,$4476B49D5DDDE35A,$6183C1B9636276D2,$E483F5C65B0C079B,$200923333C2B1B1B
    Data.q $D477471FD2472A0B,$37CDCD7B0EC8C3F9,$EEBF97F32ADADF26,$F2758ABAC603E4AA,$830207C092078D8D
    Data.q $AF86FCE1DCAE8B20,$F4FC3F8210B16CFD,$CFA3F8A92F8F762B,$3C7BB157FEEFF32E,$FBFD7C5C17B3E2A3
    Data.q $254A82296FBB765E,$D3C8BB6D815AB5CF,$5D734283C092FFD3,$7DEFC839C0FA7E39,$6378D6FE3F3A93FE
    Data.q $13E1773E2EDDE67C,$B9351A38254A9045,$740928D4D4F1CE5C,$BE592A6950B41E0B,$0CBF171F3F559DBB
    Data.q $52254B91608FF917,$484727279652A524,$CB2141FA2DD115A0,$7A4DC7256381ABC5,$4669B0F1E3D87A7A
    Data.q $81261824BD8C9938,$1D12D507EA2B473E,$77CA767675120087,$B9C41BCBCC61B370,$0C0910C4C4F1CD5A
    Data.q $24F21E0B775CFA11,$264C8229F5F5F512,$1C0A346E7DE6CDCE,$BA44314260497A0C,$72E5C8912721D115
    Data.q $14F76B6BC0F08929,$3A7B52EE08A02041,$100370895A7E7DDB,$BC0487704979EBD4,$95A7F7D0887A0405
    Data.q $07FBF639EBD7D508,$FFD09E8F20B8C049,$1F1E59AB54102243,$FC7A3C845701201F,$B18203C94C512F4F
    Data.q $0B7B479045304531,$8A5A2E2D1234E02C,$E7E0243FC10152A0,$9CB7875188AE0790,$6F6AF87B2FF7A244
    Data.q $B10124E5AB544943,$B5EA81658121E7CF,$25A8FC6D70896AE5,$69D302844B58AFF8,$FA3A3CCBCB94114B
    Data.q $B96D0B2C226C0937,$EB7E65FD7B80FDB6,$77ABA870E1D877ED,$F191F77777707474,$1420800C54B74BF9
    Data.q $82692D2A5C93539A,$40FAA6ACF90B6120,$EE5EBD7B1EEFB6E3,$E762A3824057EFEF,$25178620FF075B6F
    Data.q $E9191E690A171612,$CFC1CD787A1D8127,$1C5A7959ABAB86E1,$9B36728B16398489,$B0A9A79714402754
    Data.q $0E1C3932CB631CBC,$42BB30C4A88B934B,$82C0917FC3C3C521,$287A9C952AE6BC3E,$E982DE175C43E090
    Data.q $F402BCA41ED016D4,$F3FF89C72A2DF006,$B60493FA1A1E05F9,$D5AB044D8735E1FF,$1C7AA7349EBE2B80
    Data.q $2B2BA0F05BA22B40,$3162F2472A3D5519,$B626E7A371B826D5,$361CD6287634163F,$570B961CFC059611
    Data.q $5098FE305BC17184,$04C788AD1CFA110C,$95CAE062416439A0,$3B9B6C2D00BE6FAF,$0000000050BA9EB6
    Data.q $826042AE444E4549
 EndDataSection : ;}
Last edited by BasicallyPure on Fri Mar 01, 2019 9:01 pm, edited 1 time in total.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Image encrypter

Post by Kwai chang caine »

Works perfectly, encrypted i have a lot of pixel color :D
I have try with a bad password and that works too
Thanks for sharing 8)

PS: EndDataSection missing :wink:
ImageThe happiness is a road...
Not a destination
User avatar
NicTheQuick
Addict
Addict
Posts: 1227
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Image encrypter

Post by NicTheQuick »

But remember that a simple Xor from a deterministic random number generator is not secure. If someone wants to he surely can decrypt the image again without a password. And because most pictures have not enough entropy in the neighbouhood of each individual pixel someone could also guess a small number sequence from the RNG and try to backfind this sequence and the initial random seed. Also a random seed only consists of 32 bit (if I remember correctly) so a longer password does not result in a stronger encryption. So bruteforce could also be a possible solution to decrypt the image again.

To safely ecnrypt something use the encryption functions Purebasic offers natively.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Image encrypter

Post by BasicallyPure »

Kwai chang caine wrote:PS: EndDataSection missing
Nice catch, fixed.

@NicTheQuick,
Thanks for the comments Nic.
I'm not claiming to be any kind of expert in cryptology so your thoughts on this subject are welcome.
NicTheQuick wrote:But remember that a simple Xor from a deterministic random number generator is not secure.
Isn't every form of encryption/decryption deterministic?
NicTheQuick wrote:guess a small number sequence from the RNG and try to backfind this sequence and the initial random seed.
I wonder how one could 'guess' the seed from a small number sequence, not saying it couldn't be done but I have no idea how.
NicTheQuick wrote:To safely ecnrypt something use the encryption functions Purebasic offers natively.
I have no argument against that.

I think for my purposes the method I used is good enough, others may need a higher level of security.
To anyone using my encrypter please take NicTheQuick's comments into consideration.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Image encrypter

Post by RSBasic »

Very good, thank you.
Image
Image
Post Reply