Base64 encoding

Just starting out? Need help? Post your questions and find answers here.
Jagermeister
Enthusiast
Enthusiast
Posts: 137
Joined: Thu Nov 15, 2012 11:38 pm
Location: Los Angeles

Base64 encoding

Post 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
User avatar
STARGÅTE
Addict
Addict
Posts: 2234
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Base64 encoding

Post 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
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Jagermeister
Enthusiast
Enthusiast
Posts: 137
Joined: Thu Nov 15, 2012 11:38 pm
Location: Los Angeles

Re: Base64 encoding

Post by Jagermeister »

Ahhhh. So cool. Thank you, Stargate!
loulou2522
Enthusiast
Enthusiast
Posts: 551
Joined: Tue Oct 14, 2014 12:09 pm

Re: Base64 encoding

Post 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
User avatar
jacdelad
Addict
Addict
Posts: 2010
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Base64 encoding

Post 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.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
loulou2522
Enthusiast
Enthusiast
Posts: 551
Joined: Tue Oct 14, 2014 12:09 pm

Re: Base64 encoding

Post 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
User avatar
jacdelad
Addict
Addict
Posts: 2010
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Base64 encoding

Post 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:
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Post Reply