At 04:29 �� 1/2/2002 +0100, you wrote:

>On 31 Jan 2002, at 15:10, Phoebus R. Dokos wrote:
>
> > Hi all,
> > After lots of trial and error (Mainly because I had to relearn binary
> > arithmetic ;-) My BMP2SCR-Win program is updated to official version 1.1
> >
>Hi, let me have the sources (or at least some doc on the windows
>BMP format), I'll try to see whather we can't have the same thing
>under SMSQ...
>Wolfgang
>-----------------
>www.wlenerz.com

Sending them over...

Careful the source is not fully (well not at all) commented... I'll add 
some comments and send it over (Don't be alarmed by the string handling 
though because VB can handle HUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUGE 
strings (1 Mbyte long strings is common!)

Phoebus

P.S. Remarks are noted with a "'" (single quote)
------------------------VB Source 
begins-------------------------------------------------------------

'*************************************************************************************************
'* BMP to QL Pointer Environment PIC File Converter for 
GD2                                      *
'* 
============================================================== 
*
'* � 2001 Phoebus R. Dokos - Original Program � 2001 Malcolm 
Lear                                *
'* This Program is 
Freeware                                                                      *
'*************************************************************************************************

Public glbFlagOk As Boolean
Sub ConvertFile32(BMPFile As String, PicFile As String)

Dim glbWidth As Long
Dim glbHeight As Long
Dim glbX As Long
Dim glbY As Long
Dim glbAddress As Long
Dim InputFileLength As Long
Dim OutFileLength As Long
Dim Remaining As Long
Dim Maximum As Long
Dim glbBlue As Integer
Dim glbUgreen As Integer
Dim glblGreen As Integer
Dim glbRed As Integer
Dim glbLoadedBytes(3932214) As Integer
Dim glbSavingBytes(3932160) As Integer
Dim glbCounter As Long
Dim BytesIn As String
Dim BytesOut As String
Dim TempText As String
Dim Counter As Long
Dim ReadMsg As String
Dim ConvertMsg As String
Dim SaveMsg As String

Close 'Close all files in case we forgot something
main.sbrStatus.Panels(1).Text = "Input File: " & BMPFile & " - Output File: 
" & PicFile 'Put info on status bar on name window
'Initialise Variables
ReadMsg = "Reading File: " & BMPFile 'Messages for the Progress bar 
(frmProgress)
ConvertMsg = "Converting"
SaveMsg = "Saving File: " & PicFile

frmProgress.Show 'Show the Progress Form
Open BMPFile For Binary As 1 'Open the file... Opening in binary format 
because it is faster than reading text streams
InputFileLength = LOF(1) 'Calculating Length
Remaining = InputFileLength 'Calculating Remaining and initializing
Maximum = Int(InputFileLength / 6) 'Assigning the size of the read block to 
1/6 of the size of the file.
'This is done solely because we want to show some progress on the screen 
with the progress bar. It could be adapted not to show progress at all.
'If we remove all progress crap then we can speed reading by 50%!!!!

frmProgress.ProgressBar1.Min = 0 'Set limits on the progress bar values
frmProgress.ProgressBar1.Max = 100 'same
Do Until EOF(1) 'Loop until we reach the end of the bmp file
frmProgress.ProgressBar1.Value = Int(Abs((InputFileLength - Remaining) * 
100) / InputFileLength) 'We set the value as a percentage
'of the progress
frmProgress.Caption = ReadMsg & " (" & frmProgress.ProgressBar1.Value & "% 
completed)" 'This changes the progress windows title according to how much 
% of the file we read
TempText = Input$(Maximum, 1) 'We read the file in chunks of "Maximum" from 
channel 1 and assign it to the temporary variable 'Text'
BytesIn = BytesIn + TempText 'We add the read part to the string BytesIn 
(Don't be confused, the $ sign must not be included since the variable was 
dimensioned as string above
Remaining = Remaining - Maximum 'Now we update the remaining variable
If Remaining < Maximum Then Maximum = Remaining 'Pretty self explanatory...
If Remaining = 0 Then Exit Do 'Get out of the loop immediately (if you 
don't put that it will crash) if no file remains
Loop 'Loop's end
Close 'Close the file

'Below we check absolute byte 28 (Strings in VBasic start from 1 not 0 
hence the 28 + 1) for the decimal value 24
'If it doesn't exist Show a Critical Error message box and exit
'The actual functions are:
'ASC (it's like CODE in S*Basic): Returns the Decimal value of a character
'MID($): Performs string slicing (Similar to the "TO" in Sbasic which is a 
lot more elegant) The $ identifier can be ommited (Only with VB DOS 1.0 and 
above
'In GWBASIC, QBASIC, QuickBASIC and PDS it has to be there


If Asc(Mid(BytesIn, 28 + 1, 1)) <> 24 Then MsgBox "NOT a 24 bit Image", 
vbCritical, "Colour Depth error": bmp2scrWin.glbFlagOk = False: Unload 
frmProgress: Exit Sub

'Now we get file information
'First Width
glbWidth = ((Asc(Mid(BytesIn, 19 + 1, 1))) * 256) + (Asc(Mid(BytesIn, 18 + 
1, 1)))
'Then Height
glbHeight = ((Asc(Mid(BytesIn, 23 + 1, 1))) * 256) + (Asc(Mid(BytesIn, 22 + 
1, 1)))
'Then we set the length of the output file (it's of course type 2 since 
there are two bytes per pixel)
OutFileLength = glbWidth * glbHeight * 2
'Now we prepare the temporary string that will handle the output. Sort of 
like RESPR (size)
'We can't do that with a DIM statement since string dimensioning goes up to 255
'So the way we do it is by using the String$ function that writes a number 
of characters "x" in an other string
'In this case we put white space... (Stay in line with the ASCII code)

BytesOut = BytesOut & String$(OutFileLength, 32)

'Again some setup for the progress bar
frmProgress.ProgressBar1.Max = OutFileLength
frmProgress.ProgressBar1.Min = 0
frmProgress.ProgressBar1.Value = 1

  'We initialize the counter - REMEMBER BMP files have reverse scan lines 
(bottom to top) that's why we are going upside down
  '... in case you noticed! :-)

  Counter = 0
  main.sbrStatus.Panels(2).Text = "Conversion in Progress...." 'Same old, 
same old for main window
  frmProgress.Caption = ConvertMsg & " and " & SaveMsg 'Blah.. blah..'
  For glbY = glbHeight - 1 To 0 Step -1
      For glbX = 0 To glbWidth - 1
          glbAddress = glbX * 3 + glbY * 3 * glbWidth + 54 'we set the 
address. Since it's 24 bit (3 bytes)
          'we multiply by 3... and add an offset of 54 from the beginning 
of the file (skipping the file header that is)
          glbBlue = (Asc(Mid(BytesIn, glbAddress + 1, 1))) And 248: 'Now we 
grab using are string functions the value for blue
          'The binary ADD actually masks the MSB first 5 bits (Mode 32 has 
5 bit blue)
          glbUgreen = (Asc(Mid(BytesIn, glbAddress + 2, 1))) And 224 'The 
same with the green with the following reservations:
          '1: We need to chop it in two pieces Since half goes to the first 
byte and half to the left
          '2: We get 6 bits in total (The original code grabbed only 5 and 
left the 6th bit
          glblGreen = (Asc(Mid(BytesIn, glbAddress + 2, 1))) And 28 'And 
here it is 28 (Binary mask of 00011100) instead of 24 (Binary mask of 00011000)
          glbRed = (Asc(Mid(BytesIn, glbAddress + 3, 1))) And 248 'And the 
Red (as in the blue)
          'Note that as I discuss above BMP scans from the bottom up and 
that's why the byte order is reversed... Instead of RGB it's BGR :-)

          'Now we shift the bits around if needed and replace the white 
space in the output string using the Mid$ function
          'First we write the first byte (Shift the three bits of Lower 
green bits left by 3 positions), shift the Blue right by 3)
          'Essentially if we wrote them out as we had we would have a big 
mess in our hands since(L=Lower Green, B is blue):
          'BBBBB000 occupies the left five bits and 000LLL00 occupies part 
of the left five bits...
          'Our resulting byte is LLLBBBBB (which is the correct one ;-)
          'Note division shifts to the right, multiplication to the left :-)

          Mid$(BytesOut, Counter + 1, 1) = Chr$((glblGreen * 8) + (glbBlue 
/ 8))
          'We do the same for the next byte but by shifting the UG five 
places to the right. The red remains as is
          'We then have RRRRRGGG

          Mid$(BytesOut, Counter + 2, 1) = Chr$((glbUgreen / 32) + glbRed)
          Counter = Counter + 2
      Next glbX
      frmProgress.ProgressBar1.Value = Counter 'A little more progress bar 
crap to show that we are professionals
      main.sbrStatus.Panels(2).Text = "Conversion in Progress.... Now 
converting Byte: " & Counter
Next glbY



frmProgress.Caption = SaveMsg

'We then open the output file, write the one string and close it... All done!
Open PicFile For Output As #2
Print #2, BytesOut;
Close #2

main.sbrStatus.Panels(2).Text = ""
Unload frmProgress
bmp2scrWin.glbFlagOk = True
End Sub
Sub ConvertFile33(BMPFile As String, PicFile As String)

'The only differences between this and the previous procedure is in the 
conversion. See the remarks there

Dim glbWidth As Long
Dim glbHeight As Long
Dim glbX As Long
Dim glbY As Long
Dim glbAddress As Long
Dim InputFileLength As Long
Dim OutFileLength As Long
Dim Remaining As Long
Dim Maximum As Long
Dim glbBlue As Integer
Dim glbGreen As Integer
Dim glbRed As Integer
Dim glbLoadedBytes(3932214) As Integer
Dim glbSavingBytes(3932160) As Integer
Dim glbCounter As Long
Dim BytesIn As String
Dim BytesOut As String
Dim TempText As String
Dim Counter As Long
Dim ReadMsg As String
Dim ConvertMsg As String
Dim SaveMsg As String

Close 'Close all files in case we forgot something
main.sbrStatus.Panels(1).Text = "Input File: " & BMPFile & " - Output File: 
" & PicFile
'Initialise Variables
ReadMsg = "Reading File: " & BMPFile
ConvertMsg = "Converting"
SaveMsg = "Saving File: " & PicFile

frmProgress.Show 'Show the Progress Form
Open BMPFile For Binary As 1
InputFileLength = LOF(1)
Remaining = InputFileLength
Maximum = Int(InputFileLength / 6)
frmProgress.ProgressBar1.Min = 0
frmProgress.ProgressBar1.Max = 100
Do Until EOF(1)
frmProgress.ProgressBar1.Value = Int(Abs((InputFileLength - Remaining) * 
100) / InputFileLength)
frmProgress.Caption = ReadMsg & " (" & frmProgress.ProgressBar1.Value & "% 
completed)"
TempText = Input$(Maximum, 1)
BytesIn = BytesIn + TempText
Remaining = Remaining - Maximum
If Remaining < Maximum Then Maximum = Remaining
If Remaining = 0 Then Exit Do
Loop
Close

If Asc(Mid(BytesIn, 28 + 1, 1)) <> 24 Then MsgBox "NOT a 24 bit Image", 
vbCritical, "Colour Depth error": bmp2scrWin.glbFlagOk = False: Unload 
frmProgress: Exit Sub
glbWidth = ((Asc(Mid(BytesIn, 19 + 1, 1))) * 256) + (Asc(Mid(BytesIn, 18 + 
1, 1)))
glbHeight = ((Asc(Mid(BytesIn, 23 + 1, 1))) * 256) + (Asc(Mid(BytesIn, 22 + 
1, 1)))
OutFileLength = glbWidth * glbHeight * 2
BytesOut = BytesOut & String$(OutFileLength, 32)

frmProgress.ProgressBar1.Max = OutFileLength
frmProgress.ProgressBar1.Min = 0
frmProgress.ProgressBar1.Value = 1

  Counter = 0
  main.sbrStatus.Panels(2).Text = "Conversion in Progress...."
  frmProgress.Caption = ConvertMsg & " and " & SaveMsg
  For glbY = glbHeight - 1 To 0 Step -1
      For glbX = 0 To glbWidth - 1
          glbAddress = glbX * 3 + glbY * 3 * glbWidth + 54
          glbBlue = (Asc(Mid(BytesIn, glbAddress + 1, 1))) And 248 'Same as 
above (5 bits for blue)
          Blue6 = ((Asc(Mid(BytesIn, glbAddress + 1, 1))) And 4) / 4 'Aha 
difference!. That's the 6th bit (see below)
          glbGreen = (Asc(Mid(BytesIn, glbAddress + 2, 1))) And 248 'Same 
as above but we don't slice and we have one less bit (5 bits for Green)
          Green6 = ((Asc(Mid(BytesIn, glbAddress + 2, 1))) And 4) / 4 'The 
same as above. See below
          glbURed = (Asc(Mid(BytesIn, glbAddress + 3, 1))) And 224 'Now we 
chop off the red
          glbLred = (Asc(Mid(BytesIn, glbAddress + 3, 1))) And 24 'And its 
bottom part
          Red6 = ((Asc(Mid(BytesIn, glbAddress + 3, 1))) And 4) / 4 'And 
the 6th bit
          If Blue6 + Green6 + Red6 >= 2 Then Intensity = 1 Else Intensity = 0
          'Here's the trick. If at least TWO of the 6th bits are set, then 
we set the Intensity bit
          'else we leave it blank. Since the I bit is connected to all 
three it's better to have an approximation
          'of sorts...

          Mid$(BytesOut, Counter + 1, 1) = Chr$((glbGreen) + (glbURed / 32))
          'As above with the difference of the colour placement for each 
byte and the intensity bit
          Mid$(BytesOut, Counter + 2, 1) = Chr$((glbBlue / 4) + (glbLred * 
8) + Intensity)
          Counter = Counter + 2
      Next glbX
      frmProgress.ProgressBar1.Value = Counter
      main.sbrStatus.Panels(2).Text = "Conversion in Progress.... Now 
converting Byte: " & Counter
Next glbY



frmProgress.Caption = SaveMsg

Open PicFile For Output As #2
Print #2, BytesOut;
Close #2

main.sbrStatus.Panels(2).Text = ""
Unload frmProgress
bmp2scrWin.glbFlagOk = True
End Sub

Reply via email to