diff options
-rw-r--r-- | img.mu | 121 |
1 files changed, 113 insertions, 8 deletions
diff --git a/img.mu b/img.mu index cae31b1f..7aecbabf 100644 --- a/img.mu +++ b/img.mu @@ -1,6 +1,11 @@ # load an image from disk and display it on screen type image { + type: int # supported types: + # 1: portable bitmap (P1) - pixels 0 or 1 + # 2: portable greymap (P2) - pixels 1-byte greyscale values + # 3: portable pixmap (P3) - pixels 3-byte rgb values + max: int width: int height: int data: (handle array byte) @@ -24,7 +29,42 @@ fn load-image self: (addr image), data-disk: (addr disk) { # stream -> gap-buffer (HACK: we temporarily cannibalize the sandbox's gap-buffer) draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "parsing", 3/fg, 0/bg move-cursor-to-left-margin-of-next-line 0/screen - initialize-image-from-pgm self, s + initialize-image self, s +} + +fn initialize-image _self: (addr image), in: (addr stream byte) { + var self/esi: (addr image) <- copy _self + var mode-storage: slice + var mode/ecx: (addr slice) <- address mode-storage + next-word in, mode + { + var P1?/eax: boolean <- slice-equal? mode, "P1" + compare P1?, 0/false + break-if-= + var type-a/eax: (addr int) <- get self, type + copy-to *type-a, 1 + initialize-image-from-pbm self, in + return + } + { + var P2?/eax: boolean <- slice-equal? mode, "P2" + compare P2?, 0/false + break-if-= + var type-a/eax: (addr int) <- get self, type + copy-to *type-a, 2 + initialize-image-from-pgm self, in + return + } + { + var P3?/eax: boolean <- slice-equal? mode, "P3" + compare P3?, 0/false + break-if-= + var type-a/eax: (addr int) <- get self, type + copy-to *type-a, 3 + initialize-image-from-ppm self, in + return + } + abort "unrecognized image type" } # import a black-and-white ascii bitmap @@ -32,17 +72,19 @@ fn initialize-image-from-pbm _self: (addr image), in: (addr stream byte) { var self/esi: (addr image) <- copy _self var curr-word-storage: slice var curr-word/ecx: (addr slice) <- address curr-word-storage - next-word in, curr-word # skip 'P1' + # load width, height next-word in, curr-word var tmp/eax: int <- parse-decimal-int-from-slice curr-word var width/edx: int <- copy tmp next-word in, curr-word tmp <- parse-decimal-int-from-slice curr-word var height/ebx: int <- copy tmp + # save width, height var dest/eax: (addr int) <- get self, width copy-to *dest, width dest <- get self, height copy-to *dest, height + # initialize data var capacity/edx: int <- copy width capacity <- multiply height var data-ah/edi: (addr handle array byte) <- get self, data @@ -64,27 +106,90 @@ fn initialize-image-from-pbm _self: (addr image), in: (addr stream byte) { } } -# import a greyscale ascii bitmap +# import a greyscale ascii "greymap" fn initialize-image-from-pgm _self: (addr image), in: (addr stream byte) { var self/esi: (addr image) <- copy _self var curr-word-storage: slice var curr-word/ecx: (addr slice) <- address curr-word-storage - next-word in, curr-word # skip 'P2' + # load width, height next-word in, curr-word var tmp/eax: int <- parse-decimal-int-from-slice curr-word var width/edx: int <- copy tmp -#? draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, width, 3/fg 0/bg next-word in, curr-word tmp <- parse-decimal-int-from-slice curr-word var height/ebx: int <- copy tmp -#? draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, height, 4/fg 0/bg - next-word in, curr-word # skip levels of grey - var dest/eax: (addr int) <- get self, width + # check and save color levels + next-word in, curr-word + { + tmp <- parse-decimal-int-from-slice curr-word + compare tmp, 0xff + break-if-<= + abort "initialize-image-from-pgm: no more than 255 levels of grey" + } + var dest/edi: (addr int) <- get self, max + copy-to *dest, tmp + # save width, height + dest <- get self, width + copy-to *dest, width + dest <- get self, height + copy-to *dest, height + # initialize data + var capacity/edx: int <- copy width + capacity <- multiply height + var data-ah/edi: (addr handle array byte) <- get self, data + populate data-ah, capacity + var _data/eax: (addr array byte) <- lookup *data-ah + var data/edi: (addr array byte) <- copy _data + var i/ebx: int <- copy 0 + { + compare i, capacity + break-if->= + next-word in, curr-word + var src/eax: int <- parse-decimal-int-from-slice curr-word + { + var dest/ecx: (addr byte) <- index data, i + copy-byte-to *dest, src + } + i <- increment + loop + } +} + +# import a color ascii "pixmap" +fn initialize-image-from-ppm _self: (addr image), in: (addr stream byte) { + var self/esi: (addr image) <- copy _self + var curr-word-storage: slice + var curr-word/ecx: (addr slice) <- address curr-word-storage + # load width, height + next-word in, curr-word + var tmp/eax: int <- parse-decimal-int-from-slice curr-word + var width/edx: int <- copy tmp + next-word in, curr-word + tmp <- parse-decimal-int-from-slice curr-word + var height/ebx: int <- copy tmp + next-word in, curr-word + # check color levels + { + tmp <- parse-decimal-int-from-slice curr-word + compare tmp, 0xff + break-if-= + abort "initialize-image-from-ppm: supports exactly 255 levels per rgb channel" + } + var dest/edi: (addr int) <- get self, max + copy-to *dest, tmp + # save width, height + dest <- get self, width copy-to *dest, width dest <- get self, height copy-to *dest, height + # initialize data var capacity/edx: int <- copy width capacity <- multiply height + # . multiply by 3 for the r/g/b channels + var tmp/eax: int <- copy capacity + tmp <- shift-left 1 + capacity <- add tmp + # var data-ah/edi: (addr handle array byte) <- get self, data populate data-ah, capacity var _data/eax: (addr array byte) <- lookup *data-ah |