about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/html/dom.nim2
-rw-r--r--src/js/base64.nim20
-rw-r--r--src/loader/response.nim5
-rw-r--r--src/local/term.nim36
4 files changed, 33 insertions, 30 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index e6ea61d4..f3fe472d 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -2918,7 +2918,7 @@ proc loadResource(window: Window; image: HTMLImageElement) =
         if res.isNone:
           return
         let response = res.get
-        let contentType = response.getContentType()
+        let contentType = response.getContentType("image/x-unknown")
         if contentType.until('/') != "image":
           return
         let request = newRequest(
diff --git a/src/js/base64.nim b/src/js/base64.nim
index 85844e09..b6941ef6 100644
--- a/src/js/base64.nim
+++ b/src/js/base64.nim
@@ -1,7 +1,7 @@
-import monoucha/quickjs
 import js/domexception
 import monoucha/javascript
 import monoucha/jstypes
+import monoucha/quickjs
 import types/opt
 import utils/twtstr
 
@@ -9,6 +9,7 @@ import utils/twtstr
 # anything above latin-1.)
 
 proc atob*(data: string): DOMResult[NarrowString] =
+  # Note: the actual atob implementation (atob0) is in twtstr.
   let r = atob0(data)
   if r.isNone:
     return err(newDOMException(r.error, "InvalidCharacterError"))
@@ -16,13 +17,7 @@ proc atob*(data: string): DOMResult[NarrowString] =
 
 const AMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 
-func btoa*(data: openArray[uint8]): string =
-  if data.len == 0:
-    return ""
-  var L = data.len div 3 * 4
-  if (let rem = data.len mod 3; rem) > 0:
-    L += 3 - rem
-  var s = newStringOfCap(L)
+func btoa*(s: var string; data: openArray[uint8]) =
   var i = 0
   let endw = data.len - 2
   while i < endw:
@@ -47,6 +42,15 @@ func btoa*(data: openArray[uint8]): string =
       s &= AMap[b1 shl 4 and 0x3F] # 2 bits of b1
       s &= '='
     s &= '='
+
+func btoa*(data: openArray[uint8]): string =
+  if data.len == 0:
+    return ""
+  var L = data.len div 3 * 4
+  if (let rem = data.len mod 3; rem) > 0:
+    L += 3 - rem
+  var s = newStringOfCap(L)
+  s.btoa(data)
   return s
 
 func btoa*(data: string): string =
diff --git a/src/loader/response.nim b/src/loader/response.nim
index 2f624a1a..ab74571e 100644
--- a/src/loader/response.nim
+++ b/src/loader/response.nim
@@ -101,13 +101,14 @@ func getCharset*(this: Response; fallback: Charset): Charset =
     return fallback
   return cs
 
-func getContentType*(this: Response): string =
+func getContentType*(this: Response; fallback = "application/octet-stream"):
+    string =
   if "Content-Type" in this.headers.table:
     let header = this.headers.table["Content-Type"][0].toLowerAscii()
     return header.until(';').strip()
   # also use DefaultGuess for container, so that local mime.types cannot
   # override buffer mime.types
-  return DefaultGuess.guessContentType(this.url.pathname)
+  return DefaultGuess.guessContentType(this.url.pathname, fallback)
 
 type TextOpaque = ref object of RootObj
   buf: string
diff --git a/src/local/term.nim b/src/local/term.nim
index db479734..3c8621a1 100644
--- a/src/local/term.nim
+++ b/src/local/term.nim
@@ -691,28 +691,26 @@ proc outputSixelImage(term: Terminal; x, y, offx, offy, dispw, disph: int;
 
 proc outputKittyImage(term: Terminal; x, y, offx, offy, dispw, disph: int;
     bmp: Bitmap) =
-  const MaxPixels = ((4096 div 4) * 3) div 3 # max 4096 bytes, base64 encoded
-  var outs = term.cursorGoto(x, y)
-  outs &= APC & "Gf=24,m=1,a=T,C=1,s=" & $bmp.width & ",v=" & $bmp.height &
-    ",x=" & $offx & ",y=" & $offy & ",w=" & $dispw & ",h=" & $disph & ';'
-  var buf = newStringOfCap(MaxPixels * 4)
-  var i = 0
+  const MaxBytes = 4096 * 3 div 4
+  var i = MaxBytes
   # transcode to RGB
-  while i < bmp.px.len:
-    if i > 0 and i mod MaxPixels == 0:
-      outs &= btoa(buf)
-      outs &= ST
-      term.write(outs)
-      buf.setLen(0)
-      outs = APC & "Gm=1;"
-    buf &= char(bmp.px[i].r)
-    buf &= char(bmp.px[i].g)
-    buf &= char(bmp.px[i].b)
-    inc i
-  outs = APC & "Gm=0;"
-  outs &= btoa(buf)
+  let p = cast[ptr UncheckedArray[uint8]](addr bmp.px[0])
+  let L = bmp.px.len * 4
+  let m = if i < L: '1' else: '0'
+  var outs = term.cursorGoto(x, y) &
+    APC & "Gf=32,m=" & m & ",a=T,C=1,s=" & $bmp.width & ",v=" & $bmp.height &
+    ",x=" & $offx & ",y=" & $offy & ",w=" & $dispw & ",h=" & $disph & ';'
+  outs.btoa(p.toOpenArray(0, min(L, i) - 1))
   outs &= ST
   term.write(outs)
+  while i < L:
+    let j = i
+    i += MaxBytes
+    let m = if i < L: '1' else: '0'
+    var outs = APC & "Gm=" & m & ';'
+    outs.btoa(p.toOpenArray(j, min(L, i) - 1))
+    outs &= ST
+    term.write(outs)
 
 # x, y, maxw, maxh in cells
 # x, y can be negative, then image starts outside the screen