Excessive delay in base64 encoding of jpg file

I am having trouble resolving an issue with sending an email with a jpg file via smtp2go using code posted by SurferTim in this thread by donfrankrice.

I have adjusted the code to my specific hardware and local settings and am able to successfully email a jpg file, however there is an issue with the length of time for encoding the image file. I have tried sending a 640x480 image totaling about 47k as well as a 320x240 image totaling about 11k. In each case the time to encode and send the email has been between 6 and 8 minutes.

I have tried commenting out/in various lines without success. I have added serial.print lines at the major events in the code, and it is definitely the encode or rather encodeblock portion of the code where the delay is occurring.

I am using an arduino mega 2560 and an adafruit winc1500 wifi shield. I've gone over the original code and my own sketch repeatedly and cannot find any discrepancies, but I'm obviously missing something. Any tips would be appreciated.

/*
Portions of this code adapted from code created by the following:
 SuferTim
  Email client sketch for IDE v1.0.5 and w5100/w5200
   Posted   07 May 2015
   modified 23 Oct 2019
 Tom Igoe
  Connects to WiFi network, then print MAC address, IP address, and
  network details.
   created 13 July 2010
   by dlf (Metodo2 srl)
   modified 31 May 2012
   modified 23 Oct 2019
 Eric Ayars
  Test/demo of read routines for a DS3231 RTC.
   created 00 Apr 2011
 Public Domain
  This is a basic snapshot sketch using the VC0706 library.
   On start, the Arduino will find the camera and SD card and
   then snap a photo, saving it to the SD card.
BARRAGAN <http://barraganstudio.com>
  Servo control
   modified 08 Nov 2013 by Scott Fitzgerald

   
*/

#include <Wire.h>
#include <WiFi101.h>
#include <SPI.h>
#include <SD.h>
#include "arduino_secrets.h"  //enter login data in the Secret tab/arduino_secrets.h

char ssid[] = SECRET_SSID;    // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;  // the WiFi radio's status


// this must be unique
byte mac[] = { 0xF8, 0xF0, 0x05, 0x90, 0x1E, 0x09 };  
// change network settings to yours
IPAddress ip( 192, 168, 43, 164 );    
IPAddress gateway( 192, 168, 0, 1 );
IPAddress subnet( 255, 255, 255, 0 );
 
char server[] = "mail.smtp2go.com";    // change server to your email server domain
int port = 2525;
 
WiFiClient client;
File myFile;

char b64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char tBuf[64];
char b64Buf[128];
byte bufCount;

void setup()
{
 Serial.begin(115200);
  //pinMode(10,OUTPUT);                  //   WiFi Shield pin
  //digitalWrite(10,HIGH);                 
  pinMode(4,OUTPUT);                     //   SD card pin
  
  // attempt to connect to WiFi network:
  while ( status != WL_CONNECTED) 
   {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);      // Connect to WPA/WPA2 network:
    delay(10000);                         // wait 10 seconds for connection:
   }

  if(!SD.begin(4)) 
  Serial.println(F("SD failed"));
  
 Serial.println(F("Ready. Press 'e' to send."));  // <<<<<<<<<<< !!!need to change/remove this!!!!  <<<<<<<<<<<<<<
}

void loop()
{
  byte inChar;
 
  inChar = Serial.read();
 
  if(inChar == 'e')
  {
      if(sendEmail()) Serial.println(F("Email sent")); // infinite loop - need to change this somehow
      else Serial.println(F("Email failed"));
  }
}
 
byte sendEmail()
{
  byte thisByte = 0;
  byte respCode;
//  char tBuf[64];
 
  if(client.connect(server,port) == 1) {
    Serial.println(F("connected"));
  } else {
    Serial.println(F("connection failed"));
    return 0;
  }

  if(!eRcv()) return 0;

  Serial.println(F("Sending hello"));
  strcpy_P(tBuf,PSTR("EHLO\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;

  Serial.println(F("Sending auth login"));
  strcpy_P(tBuf,PSTR("auth login\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;

  Serial.println(F("Sending User"));
  strcpy_P(tBuf,PSTR("xxxxxxxxxxxxxxxxx\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;

  Serial.println(F("Sending Password"));
  strcpy_P(tBuf,PSTR("xxxxxxxxxxxxxxxxxxxx\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;

// change to your email address (sender)
  Serial.println(F("Sending From"));
  strcpy_P(tBuf,PSTR("MAIL From: <xxxxxxx@xxxxx.xxxx>\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;

// change to recipient address
  Serial.println(F("Sending To"));
  strcpy_P(tBuf,PSTR("RCPT To: <xxxxxxxxxx@xxxx.com>\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;

  Serial.println(F("Sending DATA"));
  strcpy_P(tBuf,PSTR("DATA\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;

  Serial.println(F("Sending email"));
  

//                                      change to recipient address
  strcpy_P(tBuf,PSTR("To: You <xxxxxxxxx@gmail.com>\r\n")); 
  client.write(tBuf);
//                                      change to your address
  strcpy_P(tBuf,PSTR("From: Fish <xxxxxxxx@xxxxxxxxxxx.xyz>\r\n")); 
  client.write(tBuf);
  client.println("Subject: Arduino email image");
  client.write("MIME-Version: 1.0\r\n");
  client.write("Content-Type: Multipart/mixed; boundary=frontier\r\n\r\n");
  client.write("--frontier\r\n");
  client.write("Content-Type: text/plain\r\n\r\n");
  client.write("This is an image from my Arduino!\r\n");
  client.write("--frontier\r\n");
  client.write("Content-Type: image/jpeg\r\n");
  client.write("Content-Disposition: attachment; filename=IMAGE01.JPG\r\n");
  client.print("Content-Transfer-Encoding: base64\r\n\r\n");
  

// this is where you would send your file
   int clientCount = 0;

// change this to a valid jpg image file name
   myFile = SD.open("IMAGE01.JPG",FILE_READ);
   if(myFile) {
    encode();
    myFile.close();                 
  }
  else {
    Serial.println(F("File open failed"));
  }
 
  client.write("--frontier--\r\n");
  client.println(".");
  if(!eRcv()) return 0;

  Serial.println(F("Sending QUIT"));
  strcpy_P(tBuf,PSTR("QUIT\r\n")); 
  client.write(tBuf);
  if(!eRcv()) return 0;
  client.stop();

  Serial.println(F("disconnected"));
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;
  int loopCount = 0;

  while(!client.available()) {
    delay(1);
    loopCount++;

    // if nothing received for 10 seconds, timeout
    if(loopCount > 10000) {
      client.stop();
      Serial.println(F("\r\nTimeout"));
      return 0;
    }
  }

  respCode = client.peek();

  while(client.available())
  { 
    thisByte = client.read();   
    Serial.write(thisByte);
  }

  if(respCode >= '4')
  {
    efail();
    return 0; 
  }

  return 1;
}


void efail()
{
  byte thisByte = 0;
  int loopCount = 0;

  client.println("QUIT");

  while(!client.available()) {
    delay(1);
    loopCount++;

    // if nothing received for 10 seconds, timeout
    if(loopCount > 10000) {
      client.stop();
      Serial.println(F("\r\nTimeout"));
      return;
    }
  }

  while(client.available())
  { 
    thisByte = client.read();   
    Serial.write(thisByte);
  }

  client.stop();

  Serial.println(F("disconnected"));
}

void encode()
{
  unsigned char in[3],out[4];
  int i,len,blocksout=0;
  while (myFile.available()!=0) {
    len=0;
    for (i=0;i<3;i++){
      in[i]=(unsigned char) myFile.read();
      if (myFile.available()!=0) len++;
      else in[i]=0;
    }
    if (len){
      encodeblock(in,out,len);
      for(i=0;i<4;i++) client.write(out[i]);
        blocksout++;
    }
    if (blocksout>=19||myFile.available()==0){
      if (blocksout) client.print("\r\n");  blocksout=0;
    }
  }
}

void encodeblock( byte *in, byte *out, int len )
{
    out[0] = (byte) b64Chars[ (in[0] >> 2) ];
    out[1] = (byte) b64Chars[ (in[0] & 0x03) << 4 | (in[1] & 0xf0) >> 4 ];
    out[2] = (byte) (len > 1 ? b64Chars[ (in[1] & 0x0f) << 2 | (in[2] & 0xc0) >> 6 ] : '=');
    out[3] = (byte) (len > 2 ? b64Chars[ (in[2] & 0x3f) ] : '=');
}

What is your upload speed?

If this is on your home network, then your ISP may likely be throttling your upload speeds.

My upload speed is 23 Mbps.

When I place
serial.println("encodeblock");
right after the open bracket in the void encodeblock() function - this is where the sketch sticks for 6-8 minutes on the serial monitor. The rest of the code flies by in milliseconds.
Other people using the same code report encode/email times of less than 1 minute for ~50kb files.

Here is what the serial monitor displays:

Attempting to connect to WPA SSID: xxxxxx
connected
220 mail.smtp2go.com ESMTP Exim 4.92-S2G Sun, 03 Nov 2019 22:59:47 +0000
Sending hello
250-mail.smtp2go.com Hello  [70.114.115.112]
250-SIZE 52428800
250-8BITMIME
250-DSN
250-PIPELINING
250-AUTH CRAM-MD5 PLAIN LOGIN
250-CHUNKING
250-STARTTLS
250-PRDR
250 HELP
Sending auth login
334 (b64 xxxxxx)
Sending User
334 (b64 xxxxxx)
Sending Password
235 Authentication succeeded
Sending From
250 OK
Sending To
250 Accepted <xxxxxx@gmail.com>
Sending DATA
354 Enter message, ending with "." on a line by itself
Sending email
250 OK id=1iROqc-IbZsgM-H1
Sending QUIT
221 mail.smtp2go.com closing connection
disconnected
Email sent

Everything seems to work fine, except there is a 6-8 minute pause at Sending email.
When I insert the serial.println(); code in the encodeblock funtction, the serial monitor displays "encodeblock" over and over for 6-8 minutes and then the rest of the code runs. I didn't include all 50,000 "encodeblock" lines.

Found another old thread regarding this issue with wifi. I'm think it is related to the wifishield upload speed, but I can't find any information on how to determine my wifi shield's upload speed. Can anyone point me in the right direction?