Discussion:
Using CHRW to speed up writing binary files
(too old to reply)
Antoni Gual Via
2022-10-08 16:45:17 UTC
Permalink
Hello. I'm experimenting on creating bmp files in VBScript and I have good results writing byte to byte with CHR. The idea is to speed it up writing two bytes at a time using CHRW and an UTF16 Stream. The code below tries to test the concept by writing random long values, then reading them from file and comparing with the original values. It does'nt work, I have probably missed something in my code dealing with signed values. Could you give it a look?

fn=CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2)& "\testwchr.bin"

Function long2wstr( x)
Dim k1,k2,x1
k1= CInt ((x And &h7fff) Or (&H8000 And ((X And &h8000)<>0)))

'k2= ((X and &h7fff0000 ) \&h10000)
k2=((X And &h7fffffff) \ &h10000) Or (&H8000 And ((X And &h80000000) <>0 ))
long2wstr=chrw(k1) & chrw(k2)
End Function


Function wstr2long(s)
x1=AscW(mid(s,1,1))
'xx1=x1-(65536 *(x1<0))
x2=AscW(mid(s,2,1))
wstr2long=CLng(x2*65536+x1)
End Function

Function rndlong() rndlong=CLng(4294967296* rnd()-2147483648) :End Function

Dim a(1000)
With CreateObject("ADODB.Stream")
.Charset = "UTF-16LE" 'o "UTF16-BE"
.Type = 2' adTypeText
.open
Randomize 1
For I=0 To 1000
a(i)=rndlong
.writetext long2wstr(a(i))
Next
.savetofile fn,2
.close

'now read the file to see if ADODB has changed anything
.open
.loadfromfile fn
.position=2 'skip bom

cnt=0
For I=0 To 1000

j= wstr2long(.readtext (2))
If j<>a(i) Then WScript.Echo a(i),j:cnt=cnt+1 ' print unmatching pairs
Next
WScript.Echo cnt 'should print 0 and nothing else
.close
End With
Antoni Gual Via
2022-10-08 19:19:12 UTC
Permalink
I have found the solution. To write data to a binary file two bytes at a time is possible, but the increase ins speed is just marginal (in my old laptop). I forgot you can add a "&" suffix to a number to declare it as a long. Here is the code:


fn=CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2)& "\testwchr.bmp"

Function long2wstr( x) 'falta muy poco!!!
Dim k1,k2,x1
k1=((x And &h7fff) Or (&H8000& And ((X And &h8000&)<>0)))

k2=((X And &h7fffffff&) \ &h10000&) Or (&H8000& And ((X And &h80000000&) <>0 ))
long2wstr=chrw(k1) & chrw(k2)
End Function


Function wstr2long(s)
x1=AscW(mid(s,1,1))
xx1=x1-(65536 *(x1<0))
x2=AscW(mid(s,2,1))
wstr2long=x2*65536+xx1
End Function

Function rndlong() rndlong=CLng(4294967296* rnd()-2147483648+256*rnd) :End Function

Dim a(1000)
With CreateObject("ADODB.Stream")
.Charset = "UTF-16LE" 'o "UTF16-BE"
.Type = 2' adTypeText
.open
Randomize timer
For I=0 To 1000
a(i)=rndlong
.writetext long2wstr(a(i))
Next
.savetofile fn,2
.close

'now read the file to see if ADODB has changed anything
.open
.loadfromfile fn
.position=2 'skip bom
cnt=0
For I=0 To 1000
j= wstr2long(.readtext (2))
If j<>a(i) Then WScript.Echo a(i),j:cnt=cnt+1
Next
WScript.Echo cnt 'should print 0
.close
End With
JJ
2022-10-09 13:26:06 UTC
Permalink
Post by Antoni Gual Via
I have found the solution. To write data to a binary file two bytes at a
time is possible, but the increase ins speed is just marginal (in my old
laptop).
Only if it's used to process a file whose size is not large enough.

The difference would be significant if the total data size is large enough
file.

e.g. if the difference is 0.1 second for one 1MB file; if it's used to
process one 100MB file, or 100 files of 1MB each, the difference would be 10
seconds.
Mayayana
2022-10-10 12:06:10 UTC
Permalink
Post by Antoni Gual Via
Hello. I'm experimenting on creating bmp files in VBScript
https://www.jsware.net/jsware/scrfiles.php5#bints

No ADODB needed. Straight Textstream. The only limitation
is that it won't work on DBCS systems. (Japanese, Chinese,
Korean.) It requires a true ANSI read/write: 1 byte = 1 character.

If you start getting into writing two bytes at a time you
open yourself up to endless complications. The whole point
of a binary file is that it's a byte stream. So any edit that's
not an even number of bytes would corrupt your file. It
might be OK for BMPs, with their simple header and their
even-numbered grid lines, but once you try to touch anything
else you'll likely be in trouble.
Antoni Gual Via
2022-10-10 15:23:43 UTC
Permalink
Post by Mayayana
https://www.jsware.net/jsware/scrfiles.php5#bints
A great vbs resource.! I will check it in my spare time. Thanks for the link. Perhaps it's your site?
Post by Mayayana
If you start getting into writing two bytes at a time you open yourself up to endless complications.
Yes,you are right. In fact i'm having some problem in building a 8 bit per pixel BMP that requires padding...
I just wanted to try UTF16 streams, and challenged myself to solve the stupid problems the signed variable types create. I posted the same question at Stack Overflow a month ago and no one answered it.The day i posted it here, i found the solution by myself.

Here are my VBS graphics scripts https://github.com/antonig/VBScript/tree/master/VBScript_graphics
Mayayana
2022-10-10 21:40:14 UTC
Permalink
Post by Antoni Gual Via
Here are my VBS graphics scripts
https://github.com/antonig/VBScript/tree/master/VBScript_graphics
Do you know about WIA? Limited usefulness, but a great
deal of functionality with images:

https://www.jsware.net/jsware/scrfiles.php5#wiaed

Loading...