diff --git a/Makefile b/Makefile
index b66cfcc..e6f82d7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 CC = gcc
-CFLAGS = -Og -Wall -Wextra -Werror
+CFLAGS = -Og -g -Wall -Wextra -Werror
 
 objects = main.o input.o output.o encode.o
 
diff --git a/encode.c b/encode.c
index cee611f..861bae9 100644
--- a/encode.c
+++ b/encode.c
@@ -7,80 +7,83 @@ unsigned char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
                       "0123456789" \
                       "+/";
 
-unsigned char b64u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
-                       "abcdefghijklmnopqrstuvwxyz" \
-                       "0123456789" \
-                       "-_";
+unsigned char b64url[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+                         "abcdefghijklmnopqrstuvwxyz" \
+                         "0123456789" \
+                         "-_";
 
 int
 encode(unsigned char *op, int olen, unsigned char *sp, int url)
 {
-    int n;
-    unsigned char *sb, *enc;
+    int tmp;
+    unsigned char *table;
+    unsigned char *sbeg;
+    unsigned char *tend;
 
-    sb = sp;
-    enc = (!url) ? b64 : b64u;
-    switch (olen) {
-        case 3:
-            *sp++ = enc[(*op & ~3) >> 2];
-            n = (*op++ & 3) << 4;
-            *sp++ = enc[n + ((*op & ~15) >> 4)];
-            n = (*op++ & 15) << 2;
-            *sp++ = enc[n + ((*op & 192) >> 6)];
-            *sp = enc[*op & ~192];
-            break;
+    table = (!url) ? b64 : b64url;
+
+    sbeg = sp;
+    tend = op + olen - (olen % 3);
+    while (op < tend) {
+        *sp++ = table[(*op & ~3) >> 2];
+        tmp = (*op++ & 3) << 4;
+        *sp++ = table[tmp + ((*op & ~15) >> 4)];
+        tmp = (*op++ & 15) << 2;
+        *sp++ = table[tmp + ((*op & 192) >> 6)];
+        *sp++ = table[*op++ & ~192];
+    }
+    switch (olen % 3) {
         case 2:
-            *sp++ = enc[(*op & ~3) >> 2];
-            n = (*op++ & 3) << 4;
-            *sp++ = enc[n + ((*op & ~15) >> 4)];
-            *sp++ = enc[(*op & 15) << 2];
-            *sp = PADDING;
+            *sp++ = table[(*op & ~3) >> 2];
+            tmp = (*op++ & 3) << 4;
+            *sp++ = table[tmp + ((*op & ~15) >> 4)];
+            *sp++ = table[(*op & 15) << 2];
+            *sp++ = PADDING;
             break;
         case 1:
-            *sp++ = enc[(*op & ~3) >> 2];
-            *sp++ = enc[(*op & 3) << 4];
+            *sp++ = table[(*op & ~3) >> 2];
+            *sp++ = table[(*op & 3) << 4];
+            *sp++ = PADDING;
             *sp++ = PADDING;
-            *sp = PADDING;
             break;
     }
 
-    return sp-sb+1;
+    return sp-sbeg;
 }
 
 int
 decode(unsigned char *sp, int slen, unsigned char *op, int url)
 {
-    int n, b, atob(int c, int url);
-    unsigned char *ob;
+    int tmp, b, atob(int c, int url);
+    unsigned char *obeg;
+    unsigned char *qend;
 
-    ob = op;
-    switch (slen) {
-        case 4:
-            n = atob(*sp++, url) << 2;
-            b = atob(*sp++, url);
-            *op++ = n + ((b & ~15) >> 4);
-
-            n = (b & 15) << 4;
-            b = atob(*sp++, url);
-            *op++ = n + ((b & ~3) >> 2);
-
-            *op = ((b & 3) << 6) + atob(*sp, url);
-            break;
+    obeg = op;
+    qend = sp + slen - (slen % 4);
+    while (sp < qend) {
+        tmp = atob(*sp++, url) << 2;
+        b = atob(*sp++, url);
+        *op++ = tmp + ((b & ~15) >> 4);
+        tmp = (b & 15) << 4;
+        b = atob(*sp++, url);
+        *op++ = tmp + ((b & ~3) >> 2);
+        *op++ = ((b & 3) << 6) + atob(*sp++, url);
+    }
+    switch (slen % 4) {
         case 3:
-            n = atob(*sp++, url) << 2;
+            tmp = atob(*sp++, url) << 2;
             b = atob(*sp++, url);
-            *op++ = n + ((b & ~15) >> 4);
-
-            n = (b & 15) << 4;
-            *op = n + ((atob(*sp, url) & ~3) >> 2);
+            *op++ = tmp + ((b & ~15) >> 4);
+            tmp = (b & 15) << 4;
+            *op++ = tmp + ((atob(*sp++, url) & ~3) >> 2);
             break;
         case 2:
-            n = atob(*sp++, url) << 2;
-            *op = n + ((atob(*sp, url) & ~15) >> 4);
+            tmp = atob(*sp++, url) << 2;
+            *op++ = tmp + ((atob(*sp++, url) & ~15) >> 4);
             break;
     }
 
-    return op-ob+1;
+    return op-obeg;
 }
 
 int atob(int c, int url)
diff --git a/input.c b/input.c
index 517522b..aef154f 100644
--- a/input.c
+++ b/input.c
@@ -1,21 +1,8 @@
 #include "input.h"
 
 #define PADDING  '='
-#define OCTETBUF  3
 #define SXTETBUF  4
 
-int
-getocts(FILE *fp, unsigned char *o)
-{
-    int c, n;
-
-    n = 0;
-    while (n < OCTETBUF && (c = fgetc(fp)) != EOF)
-        o[n++] = c;
-
-    return n;
-}
-
 int
 getsxts(FILE *fp, unsigned char *s)
 {
diff --git a/input.h b/input.h
index 2238695..ca98ef2 100644
--- a/input.h
+++ b/input.h
@@ -3,9 +3,6 @@
 
 #include <stdio.h>
 
-int
-getocts(FILE *fp, unsigned char *o);
-
 int
 getsxts(FILE *fp, unsigned char *s);
 
diff --git a/main.c b/main.c
index 44b9a71..66232cd 100644
--- a/main.c
+++ b/main.c
@@ -4,8 +4,8 @@
 #include "output.h"
 #include "encode.h"
 
-#define OCTETBUF 4
-#define SXTETBUF 5
+#define OCTETBUF  300
+#define SXTETBUF  400
 
 unsigned char obuf[OCTETBUF];
 unsigned char sbuf[SXTETBUF];
@@ -59,16 +59,16 @@ main(int argc, char *argv[])
             }
         } else if (wrp) {
             last = 0;
-            while ((n = getocts((in) ? in : stdin, obuf))) {
+            while ((n = fread(obuf, sizeof(*obuf), OCTETBUF, (in) ? in : stdin))) {
                 n = encode(obuf, n, sbuf, url);
                 last = printw((out) ? out : stdout, sbuf, n);
             }
             if (last != '\n')
                 fprintf((out) ? out : stdout, "\n");
         } else {
-            while ((n = getocts((in) ? in : stdin, obuf))) {
-                encode(obuf, n, sbuf, url);
-                fprintf((out) ? out : stdout, "%s", sbuf);
+            while ((n = fread(obuf, sizeof(*obuf), OCTETBUF, (in) ? in : stdin))) {
+                n = encode(obuf, n, sbuf, url);
+                fwrite(sbuf, sizeof(*sbuf), n, (out) ? out : stdout);
             }
         }
         if (in)