end
local fractal = mandelbrot(512, 512, 128)
+local frac_emb = mandelbrot(64, 64, 64)
local checker = gen_checkers(512, 512, 32)
local floor = math.floor
local abs = math.abs
+local data_emb = {}
local data_mb = {}
local data_ck = {}
+for i=1, #frac_emb do
+ data_emb[i] = {
+ r = floor(abs(frac_emb[i] * 2 - 1) * 255),
+ g = floor(abs(1 - frac_emb[i]) * 255),
+ b = floor(frac_emb[i] * 255),
+ a = frac_emb[i] < 0.95 and 255 or 0,
+ }
+end
for i=1, #fractal do
data_mb[i] = {
r = floor(fractal[i] * 255),
groups = { dig_immediate = 2 },
})
+
+local png_emb = "[png:" .. minetest.encode_base64(minetest.encode_png(64,64,data_emb))
+
+minetest.register_node("testnodes:generated_png_emb", {
+ description = S("Generated In-Band Mandelbrot PNG Test Node"),
+ tiles = { png_emb },
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:generated_png_src_emb", {
+ description = S("Generated In-Band Source Blit Mandelbrot PNG Test Node"),
+ tiles = { png_emb .. "^testnodes_damage_neg.png" },
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:generated_png_dst_emb", {
+ description = S("Generated In-Band Dest Blit Mandelbrot PNG Test Node"),
+ tiles = { "testnodes_generated_ck.png^" .. png_emb },
+
+ groups = { dig_immediate = 2 },
+})
#include "imagefilters.h"
#include "guiscalingfilter.h"
#include "renderingengine.h"
+#include "util/base64.h"
/*
A cache from texture name to texture path
return out;
}
+void blitBaseImage(video::IImage* &src, video::IImage* &dst)
+{
+ //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl;
+ // Size of the copied area
+ core::dimension2d<u32> dim = src->getDimension();
+ //core::dimension2d<u32> dim(16,16);
+ // Position to copy the blitted to in the base image
+ core::position2d<s32> pos_to(0,0);
+ // Position to copy the blitted from in the blitted image
+ core::position2d<s32> pos_from(0,0);
+ // Blit
+ /*image->copyToWithAlpha(baseimg, pos_to,
+ core::rect<s32>(pos_from, dim),
+ video::SColor(255,255,255,255),
+ NULL);*/
+
+ core::dimension2d<u32> dim_dst = dst->getDimension();
+ if (dim == dim_dst) {
+ blit_with_alpha(src, dst, pos_from, pos_to, dim);
+ } else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) {
+ // Upscale overlying image
+ video::IImage *scaled_image = RenderingEngine::get_video_driver()->
+ createImage(video::ECF_A8R8G8B8, dim_dst);
+ src->copyToScaling(scaled_image);
+
+ blit_with_alpha(scaled_image, dst, pos_from, pos_to, dim_dst);
+ scaled_image->drop();
+ } else {
+ // Upscale base image
+ video::IImage *scaled_base = RenderingEngine::get_video_driver()->
+ createImage(video::ECF_A8R8G8B8, dim);
+ dst->copyToScaling(scaled_base);
+ dst->drop();
+ dst = scaled_base;
+
+ blit_with_alpha(src, dst, pos_from, pos_to, dim);
+ }
+}
+
bool TextureSource::generateImagePart(std::string part_of_name,
video::IImage *& baseimg)
{
// Else blit on base.
else
{
- //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl;
- // Size of the copied area
- core::dimension2d<u32> dim = image->getDimension();
- //core::dimension2d<u32> dim(16,16);
- // Position to copy the blitted to in the base image
- core::position2d<s32> pos_to(0,0);
- // Position to copy the blitted from in the blitted image
- core::position2d<s32> pos_from(0,0);
- // Blit
- /*image->copyToWithAlpha(baseimg, pos_to,
- core::rect<s32>(pos_from, dim),
- video::SColor(255,255,255,255),
- NULL);*/
-
- core::dimension2d<u32> dim_dst = baseimg->getDimension();
- if (dim == dim_dst) {
- blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
- } else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) {
- // Upscale overlying image
- video::IImage *scaled_image = RenderingEngine::get_video_driver()->
- createImage(video::ECF_A8R8G8B8, dim_dst);
- image->copyToScaling(scaled_image);
-
- blit_with_alpha(scaled_image, baseimg, pos_from, pos_to, dim_dst);
- scaled_image->drop();
- } else {
- // Upscale base image
- video::IImage *scaled_base = RenderingEngine::get_video_driver()->
- createImage(video::ECF_A8R8G8B8, dim);
- baseimg->copyToScaling(scaled_base);
- baseimg->drop();
- baseimg = scaled_base;
-
- blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
- }
+ blitBaseImage(image, baseimg);
}
//cleanup
image->drop();
baseimg->drop();
baseimg = img;
}
+ /*
+ [png:base64
+ Decodes a PNG image in base64 form.
+ Use minetest.encode_png and minetest.encode_base64
+ to produce a valid string.
+ */
+ else if (str_starts_with(part_of_name, "[png:")) {
+ Strfnd sf(part_of_name);
+ sf.next(":");
+ std::string png;
+ {
+ std::string blob = sf.next("");
+ if (!base64_is_valid(blob)) {
+ errorstream << "generateImagePart(): "
+ << "malformed base64 in '[png'"
+ << std::endl;
+ return false;
+ }
+ png = base64_decode(blob);
+ }
+
+ auto *device = RenderingEngine::get_raw_device();
+ auto *fs = device->getFileSystem();
+ auto *vd = device->getVideoDriver();
+ auto *memfile = fs->createMemoryReadFile(png.data(), png.size(), "__temp_png");
+ video::IImage* pngimg = vd->createImageFromFile(memfile);
+ memfile->drop();
+
+ if (baseimg) {
+ blitBaseImage(pngimg, baseimg);
+ } else {
+ core::dimension2d<u32> dim = pngimg->getDimension();
+ baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
+ pngimg->copyTo(baseimg);
+ }
+ pngimg->drop();
+ }
else
{
errorstream << "generateImagePart(): Invalid "