Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using CHRW to speed up writing binary files

28 views
Skip to first unread message

Antoni Gual Via

unread,
Oct 8, 2022, 12:45:19 PM10/8/22
to
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

unread,
Oct 8, 2022, 3:19:14 PM10/8/22
to
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

unread,
Oct 9, 2022, 9:26:09 AM10/9/22
to
On Sat, 8 Oct 2022 12:19:12 -0700 (PDT), Antoni Gual Via wrote:
> 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

unread,
Oct 10, 2022, 8:07:21 AM10/10/22
to
"Antoni Gual Via" <antoni...@gmail.com> wrote

> 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

unread,
Oct 10, 2022, 11:23:45 AM10/10/22
to
El dia dilluns, 10 d’octubre de 2022 a les 14:07:21 UTC+2, Mayayana va escriure:
> 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?

> 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

unread,
Oct 10, 2022, 5:41:24 PM10/10/22
to
"Antoni Gual Via" <antoni...@gmail.com> wrote

Do you know about WIA? Limited usefulness, but a great
deal of functionality with images:

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


0 new messages