' Set graphics mode.
SCREEN _NEWIMAGE(640, 480, 32)

' Prepare mem block(s) and image(s).
DIM m AS _MEM
t = _NEWIMAGE(16, 16, 32)
m = _MEMIMAGE(t)

' Send colored pixels to the destination "t".
_DEST t
CIRCLE (8, 8), 7, -1
PAINT (8, 8), -1

' --> So far, nothing has appeared on the screen! <--

' Copy the contents of "t" to the clipboard and display the result.
_CLIPBOARD$ = MemImagetoDATA$(m, "t", 160)

_DEST 0

COLOR _RGB(255, 255, 255)
PRINT "Hex representation of a small filled circle:": PRINT
COLOR _RGB(155, 155, 155)
PRINT LEFT$(_CLIPBOARD$, 800)
PRINT "... etc. etc. ..."
PRINT RIGHT$(_CLIPBOARD$, 100)
PRINT
COLOR _RGB(255, 255, 255)
PRINT "This information is already contained in the DATA statements in this program."
PRINT "Press any key to convert this data back to an image."

DO: LOOP UNTIL INKEY$ <> ""

' Restore using the proper label associated with the data.
RESTORE TheDataLabel

' Create and display a new image using the data.
t1 = DATAtoImage
_PUTIMAGE (320, 400), t1

END

TheDataLabel:
DATA 16,16,4
DATA 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000
DATA 0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
DATA 00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000
DATA 000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000

FUNCTION DATAtoImage&
    'Requires a RESTORE label for the proper data BEFORE calling this routine
    READ w, h, ps
    SELECT CASE ps
        CASE 1: ps = 256 '256 color screen
        CASE 2: ps = 0 'text screen
        CASE 4: ps = 32 '32-bit color screen
    END SELECT
    DATAtoImage& = _NEWIMAGE(w, h, ps)
    DIM m AS _MEM
    m = _MEMIMAGE(DATAtoImage&)
    DIM h AS _UNSIGNED _BYTE
    DO
        READ hx$
        FOR i = 1 TO LEN(hx$) STEP 2
            h = VAL("&H" + MID$(hx$, i, 2))
            _MEMPUT m, m.OFFSET + o, h
            o = o + 1
        NEXT
        LOCATE 1, 1: PRINT o, m.SIZE
    LOOP UNTIL o >= m.SIZE
    _MEMFREE m
END FUNCTION

FUNCTION MemImagetoDATA$ (m AS _MEM, label$, break)
    DIM b AS _UNSIGNED _BYTE
    s = ConvertOffset(m.SIZE) - 1
    label$ = _TRIM$(label$)
    IF label$ = "" THEN label$ = "generic_label_placeholder:"
    IF RIGHT$(label$, 1) <> ":" THEN label$ = label$ + ":"
    MemImagetoDATA$ = label$ + CHR$(10) + "DATA "
    MemImagetoDATA$ = MemImagetoDATA$ + STR$(_WIDTH(m.IMAGE)) + ", "
    MemImagetoDATA$ = MemImagetoDATA$ + STR$(_HEIGHT(m.IMAGE)) + ", "
    MemImagetoDATA$ = MemImagetoDATA$ + STR$(_PIXELSIZE(m.IMAGE)) + CHR$(10) + "DATA "
    FOR i = 0 TO s
        _MEMGET m, m.OFFSET + i, b
        h$ = HEX$(b)
        IF LEN(h$) = 1 THEN h$ = "0" + h$
        MemImagetoDATA$ = MemImagetoDATA$ + h$
        IF i MOD break = break - 1 AND i < s THEN
            MemImagetoDATA$ = MemImagetoDATA$ + CHR$(10) + "DATA "
        END IF
    NEXT
END FUNCTION

FUNCTION ConvertOffset&& (value AS _OFFSET)
    DIM m AS _MEM 'Define a memblock
    m = _MEM(value) 'Point it to use value
    $IF 64BIT THEN
        'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
        _MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
    $ELSE
        'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
        _MEMGET m, m.OFFSET, temp& 'Like this
        ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
    $END IF
    _MEMFREE m 'Free the memblock
END FUNCTION
