Page 1 of 1

Base64 encoding

Posted: Mon Feb 14, 2022 12:20 am
by Jagermeister
I adapted this from: viewtopic.php?t=25152

It works but should I be using Base64EncoderBuffer, [size = FileSize(filename$) * 1.35], or some other allocation to avoid overflows? I'm not yet adept at using memory functions :oops:

Also, am I using StringByteLength in the right place (line 55) or should it be used in the encoding procedure?

Code: Select all

UseTIFFImageDecoder()
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseTGAImageDecoder()


Procedure.s base64encodefile(filename$) ; Encode a file to a base64 string.
  
  file = ReadFile(#PB_Any, filename$)
  
  Select file
    Case 0
    Default
      size = FileSize(filename$); * 1.35 ; FileSize and Lof produce the same result
      
      *filebuff = AllocateMemory(size) ; Allocate a memory block the size of the file
      ReadData(file, *filebuff, size) ; Read the file into the memory block
      
      buffer$ = Base64Encoder(*filebuff, size) ; Base64 encode the buffer into the variable
      FreeMemory(*filebuff)
      CloseFile(file)
  EndSelect
  
  Debug buffer$
  
  ProcedureReturn buffer$ 
  
EndProcedure


Procedure base64catchimage(buffer$ , buffersize) ; Create a new image from a base64 string.
  
  *output = AllocateMemory(buffersize) ; Allocate a memory block the size of the string (buffer$)
  
  Base64Decoder(buffer$, *output , buffersize) ; Decode the string (buffer$) into memory (*output) with the size provided
  
  image = CatchImage(#PB_Any, *output) ; Output an ImageID from Base64 decoded memory
  
  FreeMemory(*output)
  
  ProcedureReturn image
  
EndProcedure


filename$ = OpenFileRequester("" , "" , "" , 0)

Select Len(filename$) ; End if filename is blank
  Case 0
  Default
    
    buffer$ = base64encodefile(filename$)
    image = base64catchimage(buffer$ , StringByteLength(buffer$))
    
    OpenWindow(0 , 0 , 0 , 0 , 0 , "" , #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    ImageGadget(0 , 0 , 0 , 0 , 0 , ImageID(image))
    
    ResizeWindow(0 , #PB_Ignore , #PB_Ignore , ImageWidth(image) , ImageHeight(image))
    
    Repeat
      event = WaitWindowEvent()
      Select event
        Case #PB_Event_CloseWindow
          shutdown = #True
      EndSelect
    Until shutdown = #True
EndSelect

Re: Base64 encoding

Posted: Sat Feb 19, 2022 10:02 am
by STARGĂ…TE
In case of your base64encodefile procedure, the code is right.
The buffer do not need to be larger (*1.35) because it is automatically handled by Base64Encoder.

In case of your base64catchimage procedure, you do not really need a buffersize argument.
The buffer during decoding should be at least 64 bytes and can be 30% smaller than the string length.
StringByteLength() is the wrong function here, because it gives the internal byte length of the string.
In case of unicode applications, it is 2 byte per character, but 4 characters are only 3 encoded bytes.
Your procedure can rewrite like:

Code: Select all

Procedure base64catchimage(buffer$) ; Create a new image from a base64 string.
  
  Protected buffersize = 64
  
  If Len(buffer$) > buffersize
  	buffersize = Len(buffer$) * 0.7 ; buffer can by smaller.
  EndIf
  
  *output = AllocateMemory(buffersize) ; Allocate a memory block the size of the string (buffer$)
  
  buffersize = Base64Decoder(buffer$, *output , buffersize) ; Decode the string (buffer$) into memory (*output) with the size provided
  ; buffersize is now the real size of the decoded string, useful in CatchImage.
  
  image = CatchImage(#PB_Any, *output, buffersize) ; Output an ImageID from Base64 decoded memory
  
  FreeMemory(*output)
  
  ProcedureReturn image
  
EndProcedure

Re: Base64 encoding

Posted: Sun Feb 20, 2022 6:24 am
by Jagermeister
Ahhhh. So cool. Thank you, Stargate!

Re: Base64 encoding

Posted: Tue Oct 25, 2022 6:20 am
by loulou2522
Hi all
I have a problem with the following code

Code: Select all

UseTIFFImageDecoder()
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseTGAImageDecoder()


Procedure.s base64encodefile(filename$) ; Encode a file to a base64 string.
  
  file = ReadFile(#PB_Any, filename$)
  
  Select file
    Case 0
    Default
      size = FileSize(filename$); * 1.35 ; FileSize and Lof produce the same result
      
      *filebuff = AllocateMemory(size) ; Allocate a memory block the size of the file
      ReadData(file, *filebuff, size) ; Read the file into the memory block
      
      buffer$ = Base64Encoder(*filebuff, size) ; Base64 encode the buffer into the variable
      FreeMemory(*filebuff)
      CloseFile(file)
  EndSelect
  
  Debug buffer$
  
  ProcedureReturn buffer$ 
  
EndProcedure


Procedure base64catchimage(buffer$ , buffersize) ; Create a new image from a base64 string.
  
  *output = AllocateMemory(buffersize) ; Allocate a memory block the size of the string (buffer$)

  buffersize= Base64Decoder(buffer$, *output , buffersize) ; Decode the string (buffer$) into memory (*output) with the size provided
    Debug buffersize
   
 image= CatchImage(#PB_Any, *output,buffersize) ; Output an ImageID from Base64 decoded memory
  
  Debug image 
  
  
  FreeMemory(*output)
  
  ProcedureReturn image
  
EndProcedure


filename$ = OpenFileRequester("" , "" , "" , 0)

Select Len(filename$) ; End if filename is blank
  Case 0
  Default
    
    buffer$ = base64encodefile(filename$)
    image = base64catchimage(buffer$ , StringByteLength(buffer$))
    
    OpenWindow(0 , 0 , 0 , 0 , 0 , "" , #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    ImageGadget(0 , 0 , 0 , 0 , 0 , ImageID(image))
    
    ResizeWindow(0 , #PB_Ignore , #PB_Ignore , ImageWidth(image) , ImageHeight(image))
    
    Repeat
      event = WaitWindowEvent()
      Select event
        Case #PB_Event_CloseWindow
          shutdown = #True
      EndSelect
    Until shutdown = #True
EndSelect


filename$ = OpenFileRequester("" , "" , "" , 0)

Select Len(filename$) ; End if filename is blank
  Case 0
  Default
    
    buffer$ = base64encodefile(filename$)
    image = base64catchimage(buffer$ , StringByteLength(buffer$))
    
    OpenWindow(0 , 0 , 0 , 0 , 0 , "" , #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    ImageGadget(0 , 0 , 0 , 0 , 0 , ImageID(image))
    
    ResizeWindow(0 , #PB_Ignore , #PB_Ignore , ImageWidth(image) , ImageHeight(image))
    
    Repeat
      event = WaitWindowEvent()
      Select event
        Case #PB_Event_CloseWindow
          shutdown = #True
      EndSelect
    Until shutdown = #True
EndSelect
CatchImage allways return 0 (means an error) can someone help me ?
Thanks

Re: Base64 encoding

Posted: Tue Oct 25, 2022 3:28 pm
by jacdelad
Use LoadImage to load images from files and CatchImage to load images that are already in memory. You try to load the filename from memory.

Also, I would replace the Select with a simple "If Filename$<>""", if there are no other cases planned.

Re: Base64 encoding

Posted: Tue Oct 25, 2022 4:05 pm
by loulou2522
jacdelad wrote: Tue Oct 25, 2022 3:28 pm Use LoadImage to load images from files and CatchImage to load images that are already in memory. You try to load the filename from memory.

Also, I would replace the Select with a simple "If Filename$<>""", if there are no other cases planned.
Jacqekad,
Thanks for your answering
but I don't have the level to understand your explanations. Would it be possible for you to modify the part of the program so that I can understand the mistake I made.
Thanks in advance

Re: Base64 encoding

Posted: Tue Oct 25, 2022 9:28 pm
by jacdelad
I'm sorry, I read it on my phone and misinterpreted the call. You are using the right call. Also, your code works here. I don't see a problem. Again, sorry (I should avoid visiting this forum on my phone). :oops: