view files.pde @ 200:dffdbdb4ded6

Split mpSaveBinaryFile() into mpSaveBinaryBlob() for saving JavaScript Blobs, which is what mpSaveBinaryFile() converts given byte array into.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 29 Aug 2018 14:06:55 +0300
parents b36cfb497223
children c6c1dd769566
line wrap: on
line source

boolean mpHaveLocalStorage()
{
    var test = 'mpLSTest';
    try {
        localStorage.setItem(test, test);
        if (localStorage.getItem(test) == test)
        {
            localStorage.removeItem(test);
            return true;
        }
    }
    catch (e) {
        return false;
    }
    return false;
}


function mpLoadFileSelector(fmtname, fmtexts, fcallback)
{
    var mpUI = stGE("mpUI");
    if (mpUI)
    {
        stClearChildren(mpUI);
        mpUI.style.background = "red";
        mpUI.style.padding = "0.5em";

        mobj = stCE("input", "mpFileSelector");
        mobj.type = "file";
        mobj.name = "name";
        mobj.multiple = false;

        if (fmtexts != null)
            mobj.accept = fmtexts;

        stAddEventOb(mobj.name, mobj, "change",
            function(evt)
            {
                var files = evt.target.files;
                if (files.length > 0)
                {
                    var freader = new FileReader();

                    freader.onloadend = (function(theFile) {
                        fcallback(theFile, new Uint8Array(freader.result));
                    });

                    freader.readAsArrayBuffer(files[0]);
                }
                stClearChildren(mpUI);
                mpUI.style.background = null;
            });

        mpUI.appendChild(mobj);

        mobj = stCE("span", "mpFileInfo");
        mobj.innerHTML = "Load / import an '<b>"+ fmtname +"</b>' file.";
        mpUI.appendChild(mobj);
    }
    else
        return null;
}


//
// Basically the same as Processing loadBytes(), but it seems
// that Processing.JS's loadBytes() is broken at least in v1.4.8
// and does not return byte-clean data. So roll a replacement of
// our own design. --ccr
//
byte[] mpLoadBinaryFile(String url)
{
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, false);
    xhr.overrideMimeType("text/plain; charset=x-user-defined");
    xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT");
    xhr.send(null);

    if (xhr.status !== 200 && xhr.status !== 0)
        return null;

    var string = xhr.responseText;
    byte[] ret = new byte[string.length];

    for (var i = 0; i < string.length; i++)
    {
        ret[i] = string.charCodeAt(i) & 0xff;
    }

    return ret;
}


Blob mpMakeBinaryBlob(byte[] data)
{
    var blob = null;
    if (data == null)
        return null;

    if (typeof(data) == "string")
        blob = new Blob([data], {type: "application/octet-stream"});
    else
    if (typeof(data) == "object")
        blob = new Blob([new Uint8Array(data)], {type: "application/octet-stream"});

    return blob;
}


//
// "Save" a byte array to file. Basically creates a blob URI
// and dumps it in the DOM, giving user a download.
//
boolean mpSaveBinaryBlob(String name, void blob)
{
    var url = window.URL.createObjectURL(blob);
    if (url == null)
    {
        console.log("Could not create URL from BLOB object.");
        return false;
    }

    var alink = stCE("a");
    var mpUI = stGE("mpUI");
    stClearChildren(mpUI);
    mpUI.appendChild(alink);

    alink.style = "display: none";
    alink.href = url;
    alink.download = name;
    alink.click();

    window.URL.revokeObjectURL(url);
    return true;
}


boolean mpSaveBinaryFile(String name, byte[] data)
{
    var blob = mpMakeBinaryBlob(data);
    if (blob == null)
    {
        console.log("Could not create BLOB from data.");
        return false;
    }

    return mpSaveBinaryBlob(name, blob);
}


// bordh/v = 64, 32, omag = 1
void mpSavePNGImage(String name, int fmt, boolean border, int bordh, int bordv, int omag)
{
    PImage simg = mpRenderImage(border, bordh, bordv, omag);
//    if (g_data[int('Q')] == 0)

    if (simg !== null)
    {
        // XXX TODO .. actually save the image, something like ..
        //simg.canvas.toBlob(function(idata){ mpSaveBinaryFile(name, idata); }, "image/png", 0.95);
    }
}


int mpLoadPNGImage(String name)
{
    PImage simg = null;
    if (simg == null)
        return -1;

    int lefth = g_farge;
    int righth = g_backg;
    storeparameters();

    g_data[int('d')] = 0;
    g_data[int('t')] = 0;
    g_data[int('b')] = 1; //old IQ

    if (!mpImportFromImage(simg))
        return -2;

    restoreparameters();
    refreshpalette();
    refresh();
    g_boxreconstruct = 2;
    selectcolor(0, lefth);
    selectcolor(1, righth);
    return 0;
}


byte[] mpGetNativeImage()
{
    //save the picture page g_map[], make sure some essential parameters are correct
    g_map[3] = byte(g_machine);
    g_map[5] = byte(MX);
    g_map[7] = byte(MY);

    return g_map;
}


int mpSetNativeImage(byte[] data, boolean noError)
{
    if (data == null)
        return -1;

    if (data[3] != g_machine && !noError)
        return -2;

    store_undo();

    g_map = data;

    refreshpalette();
    consistency();
    g_farge = int(g_realfront);
    g_ofarge = g_farge;
    g_backg = int(g_realback);
    sussborder();

    return 0;
}


int mpLoadNativeImage(String name, boolean noError)
{
    return mpSetNativeImage(
        mpLoadBinaryFile(name), noError);
}


boolean mpLoadPalette(String fname)
{
    if (g_map[13] != C64)
    {
        return false;
    }

    byte fdata[] = mpLoadbinaryFile(fname);
    if (fdata == null ||
        fdata.length != 772 ||
        fdata[0x301] != byte(0x10) ||
        fdata[0x302] != byte(0xff) ||
        fdata[0x303] != byte(0xff))
    {
        return false;
    }

    for (int n = 0; n < 16; n++)
    {
        makecolor(n,
            int(fdata[n * 3]),
            int(fdata[n * 3 + 1]),
            int(fdata[n * 3 + 2]));
    }

    mpSetUIColors();

    sussborder();
    refresh_all();

    return true;
}