Author Topic: BASIMAGE converter isn't processing data  (Read 2514 times)

0 Members and 1 Guest are viewing this topic.

Offline johannhowitzer

  • Forum Regular
  • Posts: 118
    • View Profile
BASIMAGE converter isn't processing data
« on: February 03, 2021, 05:07:30 pm »
Spriggs was kind enough on my game dev topic to share this BASIMAGE program that will convert an image file into an $INCLUDEable code file, which allows you to bake source images into your executables so the end user can't just reskin your program or see things they're not supposed to see.

I dissected it to try to figure out how it works, and also cleaned up a lot of the code - it was a mess of spaghetti to untangle, probably mainly to save resources back when users cared about every byte.  For example, I've coded the filenames directly since I'm not using this from the command line.

I ran into a snag.  The program seems to use "indata$" and count on that containing something, which it immediately uses _DEFLATE$ on.  But this doesn't seem to be something QB64 knows about, and the wiki documentation doesn't list indata$ as anything special, so it looks like it's carrying a value of "", and running this just produced a tiny empty file with no image in it.

This is a little above my station to remedy, does anyone know how QB64 should be handling this?  I assume indata$ is meant to carry the binary data in the image's memory, converted via ASCII into a string, based on how the rest of the code is processing it.

Code: [Select]
$screenhide
_screenhide
defint A-Z
declare function e$(b$)

in$  = "data.png"
out$ = "data.dat"

' Load input image into m
screen _loadimage(in$, 32)
sleep 1
dim m as _mem
m = _memimage(0)

indata$ = _deflate$(indata$) ' *** How does indata$ have a value already?
wid = _width
hih = _height
screen 0
open out$ for output as 2
q$ = chr$(34) ' Quotation mark

inFunc$ = left$(in$, len(in$) - 4) ' Input file without extension
' Remove punctuation, except backslash
for i = 32 to 47
   if instr(inFunc$, chr$(i)) then
      inFunc$ = string.remove(inFunc$, chr$(i))
   end if
next i
for i = 58 to 64
   if instr(inFunc$, chr$(i)) then
      inFunc$ = string.remove(inFunc$, chr$(i))
   end if
next i
for i = 91 to 96
   if instr(inFunc$, chr$(i)) then
      if i <> 92 then
         inFunc$ = string.remove(inFunc$, chr$(i))
      end if
   end if
next i

print #2, "function __" + stripdirectory(inFunc$) + "&"
print #2, "dim v&"
print #2, "dim a$"
print #2, "dim btemp$"
print #2, "dim i&"
print #2, "dim b$"
print #2, "dim c%"
print #2, "dim f$"
print #2, "dim c$"
print #2, "dim j"
print #2, "dim t%"
print #2, "dim b&"
print #2, "dim x$"
print #2, "v& = _newimage("; wid; ", "; hih; ", 32)"
print #2, "dim m as _mem: m = _memimage(v&)"
print #2, "a$ = "; q$; q$
print #2, "a$ = a$ + "; q$;
bc& = 1

do
   a$ = mid$(indata$, bc&, 3)
   bc& = bc& + 3: ll& = ll& + 4
   if ll& = 60 then
      ll& = 0
      print #2, e$(a$);: print #2, q$
      print #2, "a$ = a$ + "; q$;
   else
      print #2, e$(a$);
   end if

   if len(indata$) - bc& < 3 then
      a$ = mid$(indata$, len(indata$) - bc&, 1): b$ = e$(a$)
      select case len(b$)
         case 0: a$ = q$
         case 1: a$ = "%%%" + b$ + q$
         case 2: a$ = "%%" + b$ + q$
         case 3: a$ = "%" + b$ + q$
      end select: print #2, a$;: exit do
   end if
loop: print #2, ""

print #2, "btemp$ = "; q$; q$
print #2, "for i& = 1 to len(a$) step 4: b$ = mid$(a$, i&, 4)"
print #2, "if instr(1, b$, "; q$; "%"; q$; ") then"
print #2, "for c% = 1 to len(b$): f$ = mid$(b$, c%, 1)"
print #2, "if f$ <> "; q$; "%"; q$; " then c$ = c$ + f$"
print #2, "next: b$ = c$: end if: for j = 1 to len(b$)"
print #2, "if mid$(b$, j, 1) = "; q$; "#"; q$; " then"
print #2, "mid$(b$, j) = "; q$; "@"; q$; ": end if: next"
print #2, "for t% = len(b$) to 1 step -1"
print #2, "b& = (b& * 64) + asc(mid$(b$, t%)) - 48"
print #2, "next: x$ = "; q$; q$; ": for t% = 1 to len(b$) - 1"
print #2, "x$ = x$ + chr$(b& and 255): b& = b& \ 256"
print #2, "next: btemp$ = btemp$ + x$: next"
print #2, "btemp$ = _inflate$(btemp$)"
print #2, "_memput m, m.offset, btemp$: _memfree m"
print #2, "__" + inFunc$ + "& = _copyimage(v&): _freeimage v&"
print #2, "end function"
system


function e$(b$)

for t% = len(b$) to 1 step -1
   b& = (b& * 256) + asc(mid$(b$, t%))
next t%

a$ = ""

for t% = 1 to len(b$) + 1
   g$ = chr$(48 + (b& and 63)): b& = b& \ 64
   if g$ = "@" then g$ = "#"
   a$ = a$ + g$
next t%: e$ = a$

end function


function stripdirectory$(ofile$)

do
   ofile$ = right$(ofile$, len(ofile$) - instr(ofile$, "\"))
loop while instr(ofile$, "\")
stripdirectory$ = ofile$

end function


function string.remove$(a as string, b as string)

dim c as string
c = ""
j = instr(a, b)

if j > 0 then
   r$ = left$(a, j - 1) + c + string.remove(right$(a, len(a) - j + 1 - len(b)), b)
else
   r$ = a
end if

string.remove = r$

end function

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: BASIMAGE converter isn't processing data
« Reply #1 on: February 03, 2021, 06:03:47 pm »
I'll take them blame for the spaghetti code mess.  The encoding/decoding functions are from an old qbasic program i did long ago, and I should have cleaned it up more when porting it to qb64.  When I get to my laptop later on i'll check it out. Unless @SpriggsySpriggs  jumps in first...

- Dav
« Last Edit: February 03, 2021, 06:51:52 pm by Dav »

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: BASIMAGE converter isn't processing data
« Reply #2 on: February 03, 2021, 06:50:49 pm »
Ok, I'm back at my pc.  Not 100% sure, but when comparing what you posted to my basimage original there is something missing before the indata$ line you noted.  Your indata$ does appear to be empty because the move from screen memory to string data is missing.

Here's what I would try adding.  See if it works...

- Dav

Code: QB64: [Select]
  1. ' Load input image into m
  2. m = _memimage(0)
  3.  
  4.  
  5. indata$ = space$(m.SIZE)   '<<<<<<<<<< Add this
  6. _mget m, m.OFFSET, indata$ '<<<<<<<<< Add this
  7.  
  8.  
  9. indata$ = _deflate$(indata$) ' *** How does indata$ have a value already?
  10.  
« Last Edit: February 03, 2021, 06:53:44 pm by Dav »

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: BASIMAGE converter isn't processing data
« Reply #3 on: February 03, 2021, 09:14:37 pm »
Yeah from what I saw it looks like you removed the bit that actually made it work.
Shuwatch!

Offline johannhowitzer

  • Forum Regular
  • Posts: 118
    • View Profile
Re: BASIMAGE converter isn't processing data
« Reply #4 on: February 03, 2021, 11:02:57 pm »
Oh hey, you're right.  I didn't remove it though, I remember leaving that intact.  Seems when I copied the code (using my phone, probably not the best idea), a piece turned up missing.  That makes way more sense.  I'll retry when I get off work, thanks for catching that.

Mainly by spaghetti I mean a lot of pairs of statements are combined into one line with a colon, which makes it hard for me to read.  Cool to analyze how it works, though, this is a clever little tool!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: BASIMAGE converter isn't processing data
« Reply #5 on: February 05, 2021, 04:33:39 pm »
@johannhowitzer Yeah, Dav is an absolute wizard with these things+
Shuwatch!