if not modules then modules = { } end modules ['grph-raw'] = {
    version   = 1.001,
    comment   = "companion to grph-raw.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- This module is for Mojca, who wanted something like this for
-- her gnuplot project. It's somewhat premliminary code but it
-- works ok for that purpose.

local tonumber, type = tonumber, type
local char = string.char
local concat = table.concat

local report_bitmap = logs.reporter("graphics","bitmaps")

local context = context

local palettes   = figures.palettes or { }
figures.palettes = palettes

function figures.bytepalette(palette)
    if type(palette) == "string" then
        palette = palettes[palette]
    end
    if type(palette) == "table" and palette[0] then
        local count = #palette
        if count > 0 then
            local result = { }
            for i=0,count do
                local p = palette[i]
                local r = p[1] or 0 ; if r < 0 then r = 0 elseif r > 255 then r = 255 end
                local g = p[2] or 0 ; if g < 0 then g = 0 elseif g > 255 then g = 255 end
                local b = p[3] or 0 ; if b < 0 then b = 0 elseif b > 255 then b = 255 end
                result[i] = char(r//1,g//1,b//1)
            end
            return concat(result,"",0,count)
        end
    end
end

local function bitmapimage(t)
    local data        = t.data
    local xresolution = t.xresolution
    local yresolution = t.yresolution
    if data and xresolution and yresolution then
        local palette = t.palette
        if palette then
            palette = palettes[palette]
        end
        local n = backends.nodeinjections.injectbitmap {
            xresolution = xresolution,
            yresolution = yresolution,
            width       = t.width,
            height      = t.height,
            data        = data,
            mask        = t.mask,
            colorspace  = t.colorspace,
            format      = t.format,
            bytes       = t.bytes or false,
            reduce      = t.reduce,
            palette     = palette,
        }
        if n then
         -- context.hpack(n)
            context(nodes.hpack(n))
        else
            report_bitmap("format not supported by backend")
        end
    else
        report_bitmap("invalid specification")
    end
end

figures.bitmapimage = bitmapimage

interfaces.implement {
    name      = "bitmapimage",
    actions   = bitmapimage,
    arguments = {
        {
            { "data" },
            { "colorspace" },
            { "width", "dimen" },
            { "height", "dimen"  },
            { "xresolution", "integer" },
            { "yresolution", "integer" },
        }
    }
}

--

local gsub, char = string.gsub, string.char

local rgbbytes = attributes.colors.rgbbytes

local function qrbitmap(str,color,width)
if not width then
    width = color
    color = nil
end
    local data, size = qrcodegen.generate(str)
    if color and color ~= "" then
        -- we can pass yes and nop
        color = rgbbytes(color)
        if color ~= rgbbytes("black") then
            local black = char(0)
            local white = char(230,230,230)
            data = gsub(data,"(.)",function(c)
                return c == black and color or white
            end)
        end
    end
    bitmapimage {
        xresolution = size,
        yresolution = size,
        width       = width or size,
        height      = width or size,
        data        = data,
        format      = "png",
        bytes       = true,
     }
end

qrcodegen.bitmap = qrbitmap
figures.qrcode   = qrbitmap

interfaces.implement {
    name      = "qrcodestring",
    arguments = { "string", "string", "dimension" },
    actions   = qrbitmap
}

interfaces.implement {
    name      = "qrcodebuffer",
    arguments = { "string", "string", "dimension" },
    actions   = function(str,color,width)
        qrbitmap(buffers.getcontent(str),color,width)
    end
}
