load "iupe-dbuffer.lua" dalosp.framebuffer = { get_settings = function (self) return { width = self.extra.width, height = self.extra.height, bpp = self.extra.bpp } end, input_change = function (self, ind) local h = self:get_linked_input(ind) if ind == 2 then if h then local cfg, s = h:readfile() s, cfg = pcall(loadstring, "local cfg = " .. cfg .. "\nreturn cfg\n") if s then self:apply_config(cfg) end end return end if h then h.getnextbyte = dalosp.framebuffer.getnextbyte end self:apply_config{} end, activate = function (self) self.extra.dlg:show() end, configure = function (self) invert_lookup = { [1] = 0, [2] = 1, [4] = 2, [8] = 3, [24] = 4, [32] = 5, } lookup = { [0] = 1, [1] = 2, [2] = 4, [3] = 8, [4] = 24, [5] = 32, } local owidth, oheight, obpp, oppdir = self.extra.width, self.extra.height, self.extra.bpp, self.extra.ppdir local cb = function (dlg, pi) if pi < 0 then return end local width, height, bpp, dir width = iup.GetParamParam(dlg, 1).value + 0 height = iup.GetParamParam(dlg, 2).value + 0 bpp = iup.GetParamParam(dlg, 3).value + 0 dir = iup.GetParamParam(dlg, 4).value + 0 self:apply_config{ width = width, height = height, bpp = lookup[bpp], dir = dir } end local s, nname, width, height, bpp, ppdir = iup.GetParam(self.name .. " configuration", cb, "New name: %s\nWidth: %i\nHeight: %i\nBpp: %l|1 bpp|2 bpp|4 bpp|8 bpp|24 bpp|32 bpp|\nDirection: %l|Little Endian|Big Endian|\n", self.name, self.extra.width, self.extra.height, invert_lookup[self.extra.bpp], self.extra.ppdir) if not s then self:apply_config{ width = owidth, height = oheight, bpp = obpp, ppdir = oppdir } else self.name = nname end end, apply_config = function (self, cfg) local fb = self.extra.fb local h = self:get_linked_input(1) if cfg.width then self.extra.width = cfg.width end if cfg.height then self.extra.height = cfg.height end if cfg.bpp then self.extra.bpp = cfg.bpp end if cfg.ppdir then self.extra.ppdir = cfg.ppdir end fb.cfg = { h = h, width = self.extra.width, height = self.extra.height, bpp = self.extra.bpp } fb:prepare() fb:draw() fb:action() end, getnextbyte = function (h) return h:tell() ~= h:getsize() and h:readU8() or 0 end, getbit = function (cfg) local rc local h = cfg.h local stateful = cfg.stateful if cfg.bpp >= 8 then return end stateful = cfg.stateful if not stateful or bit.band(stateful, 0x7f) == 0 then stateful = h:getnextbyte() * 2 + 1 else stateful = stateful * 2 end cfg.stateful = stateful return bit.band(bit.rshift(stateful, 8), 1) end, getnextpixel = function (cfg) local rc local r, g, b local h = cfg.h local getbit = function() return dalosp.framebuffer.getbit(cfg) end if cfg.bpp == 1 then rc = getbit() * 255 r, g, b = rc, rc, rc elseif cfg.bpp == 2 then rc = getbit() * 2 rc = (rc + getbit()) * 255 / 3 r, g, b = rc, rc, rc elseif cfg.bpp == 4 then rc = getbit() * 8 rc = rc + getbit() * 4 rc = rc + getbit() * 2 rc = (rc + getbit()) * 255 / 15 r, g, b = rc, rc, rc elseif cfg.bpp == 8 then rc = h:getnextbyte() r, g, b = rc, rc, rc elseif cfg.bpp == 24 then r = h:getnextbyte() g = h:getnextbyte() b = h:getnextbyte() elseif cfg.bpp == 32 then r = h:getnextbyte() g = h:getnextbyte() b = h:getnextbyte() h:getnextbyte() end return r, g, b end, prepare = function (self) local cfg = self.cfg local h = cfg.h local width = cfg.width local height = cfg.height local bpp = cfg.bpp local ppdir = cfg.ppdir local flipx = cfg.flipx local flipy = cfg.flipy local cim = im.ImageCreate(width, height, im.RGB, im.BYTE) self.cim = cim cim:Clear() if not h then return iup.DEFAULT end local getnextpixel = self.getnextpixel h:seek(0) cfg.stateful = 0 local r, g, b = cim[0], cim[1], cim[2] for y = 0, height - 1 do for x = 0, width - 1 do local px, py = flipx and width - x or x, flipy and height - y or y r[py][px], g[py][px], b[py][px] = getnextpixel(cfg) end end return iup.DEFAULT end, draw = function (self) local cvdb = self.cvdb if not cvdb then return iup.DEFAULT end cvdb:Clear() self.cim:cdCanvasPutImageRect(cvdb, 0, 0, 0, 0, 0, 0, 0, 0) -- use default values end, create = function (d, tab, settings) tab.ninputs = 2 tab.noutputs = 0 tab.otype = dalos.objtype.LUA_VIEWER tab.activate = dalosp.framebuffer.activate tab.configure = dalosp.framebuffer.configure tab.input_change = dalosp.framebuffer.input_change tab.default_name = "Framebuffer" tab.ntype = "Framebuffer" tab.get_settings = dalosp.framebuffer.get_settings local extra = { width = settings.width or 256 , height = settings.height or 256, bpp = settings.bpp or 32, ppdir = settings.dir or 0 } local obj = dalos.object(d, tab, extra) obj.apply_config = dalosp.framebuffer.apply_config local fb = iup.canvas { expand = "Yes", font = "Courier, 8", action = iupep.dbuffer.action, map_cb = iupep.dbuffer.map_cb, unmap_cb = iupep.dbuffer.unmap_cb, resize_cb = iupep.dbuffer.resize_cb, draw = dalosp.framebuffer.draw, prepare = dalosp.framebuffer.prepare, getnextpixel = dalosp.framebuffer.getnextpixel, rastersize = extra.width .. "x" .. extra.height, } local dlg = iup.dialog { fb, size = "320x200", title = obj.name, shrink = "Yes", } extra.dlg = dlg extra.fb = fb obj:apply_config{} return obj end, } dalos.framebuffer = dalosp.framebuffer.create dalos:register_obj("Framebuffer", dalos.framebuffer, "Basic Viewers")