Jump to content

Convert from 16-bit little-endian to big-endian


Nologic
 Share

Recommended Posts

Hi guys I'm kind of banging my head against a wall.

I'm looking at converting a binary file from little-endian to big-endian...I've seen tons of examples of how to do this in C, C++, C# and a few other langs...but turned up nothing for doing so in AutoIt...any help would be most welcome.

Thanks ahead of time.

Link to comment
Share on other sites

I played with FileOpen but didn't get much love there.

Sample file: http://www.megaupload.com/?d=XRPD4VPJ

Allegedly I just need to byteswap the endianness of the file...which should result in a MD5 hash of: f5ed78a173619060232b7c1eb28c140f

Link to comment
Share on other sites

You don't have to do anything to the data.

1. Read the file to memory (to an AutoIt variable), as in: $vData = FileRead($sFileName)

2. If the file type is not automatically recognized (unlikely, but possible), then:

- a. Open the file with FileOpen() in the appropriate mode first

- b. Then FileRead()

- b. Be sure to FileClose() the handle

3. After reading the data, open the file to write with FileOpen() and the appropriate flags

4. FileWrite()

5. FileClose()

6. ???

7. Profit!

:graduated:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Okay FileOpen seems to work fine except I end up with FE FF prefixed to the data, which offsets the data.

$Junk = FileOpen ( "track02.raw" , 32 )
$MoreJunk = FileRead ( $Junk )
FileClose( $Junk )

$NewJunk = FileOpen ( "track02.bak" , 66 )
FileWrite ( $NewJunk , $MoreJunk )
FileClose ( $NewJunk )

Just wondering if I'm missing something here...I can certainly trim the data...but it would certainly be nice not to. :graduated:

Okay what I'm doing now which gets me what I wanted:

; Read in Little Endian
$Open_01 = FileOpen ( "track02.raw" , 32 )
$Read_01 = FileRead ( $Open_01 )
FileClose( $Open_01 )

; Over Write in Big Endian
$Open_02 = FileOpen ( "track02.raw" , 66 )
FileWrite ( $Open_02 , $Read_01 )
FileClose ( $Open_02 )

; Read Binary Stepping in 2 - Removes FE FF
$Open_03 = FileOpen ( "track02.raw" , 16 )
$Read_02 = FileRead ( $Open_03 , 2 )
$Read_03 = FileRead ( $Open_03 )
FileClose( $Open_03 )

; Over Write Binary
$Open_04 = FileOpen ( "track02.raw" , 18 )
FileWrite ( $Open_04 , $Read_03 )
FileClose ( $Open_04 )

I'd like to say thanks for all the help I got, and if anyone has a cleaner suggestion I'm all ears. :(

Edited by Nologic
Link to comment
Share on other sites

Not sure what it is you are trying to work around. What did I miss? Doesn't this work for you?

$sFile = @ScriptDir & "\Test.dat"

; Create little-endian file to start with
$hFile = FileOpen($sFile, 32+2) ; Overwrite UTF-16 LE
For $n = 1 To 10
    FileWriteLine($hFile, "Test file line: " & $n)
Next
FileClose($hFile)

MsgBox(64, "Pause", "Created UTF-16 LE file:  " & $sFile & @CRLF & _
    "Encoding = " & FileGetEncoding($sFile) & @CRLF & @CRLF & _
    FileRead($sFile))

; Read little-endian file
$hFile = FileOpen($sFile) ; Open UTF-16 LE file
$vData = FileRead($hFile) ; Read file
FileClose($hFile)

; Overwrite as big-endian
$hFile = FileOpen($sFile, 64+2) ; Overwrite UTF-16 BE
FileWrite($hFile, $vData)
FileClose($hFile)

MsgBox(64, "Done", "Converted file to UTF-16 BE:  " & $sFile& @CRLF & _
    "Encoding = " & FileGetEncoding($sFile) & @CRLF & @CRLF & _
    FileRead($sFile))

:graduated:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

If you view the resulting file from your script in Hex mode you'll notice FE FF at the start...which is something I'm trying to avoid.

Don't take what I said in the wrong context, I'm sincerely thankful for you help...I was looking everywhere but the FileOpen command.

Link to comment
Share on other sites

Ah, I get it now. You are stripping the UTF-16 BOM. The BOM is always 0xFEFF but gets re-ordered by encoding to expose big/little endian usage (0xFEFF = big-endian; 0xFFFE = little-endian).

In UTF-8 there is no need for the BOM, but I thought it was either required or highly recommended for UTF-16. What app do you need UTF-16 with no BOM for?

:graduated:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Nologic, the 'FE FF' is a Byte-Order-Mark that is created when using FileOpen. Its useful to have this for any application trying to read the file as text, because then it will know how to interpret it.

However, you can use FileOpen with a binary flag to force it not to create the BOM. Prior to doing this, call StringToBinary() (see Help file), then take that binary data and write it to the file.

*edit: oops, looks like Psalty and I crossed posts. Also the 'StringToBinary' would be used only if you are reading in the data as Unicode, not binary. In that case you'd need a BinaryToString() also, which would be a waste..

Edited by Ascend4nt
Link to comment
Share on other sites

PsaltyDS -

Thanks for the info.

No app really...actually it deals with emulation. Dreamcast GD-Roms store the data tracks as little-endian & audio tracks as big-endian..however when these tracks are stored into a single file by Mame's CHDman upon export they are all little-endian...so to restore things to original condition the audio tracks have to be converted back over to big-endian...but it doesn't have the BOM marker present.

Ascend4nt -

Thanks for the info & additional suggestions.

Ended up doing the following which works fine for my needs. :graduated:

; Change Endian Condition
        If $Game_Tracks[$i][1] = 'AUDIO' Then
            ; Read Little Endian
            $Endian_Open_01 = FileOpen ( $Track , 16 )
            $Endian_Read_01 = FileRead ( $Endian_Open_01 )
            FileClose( $Endian_Open_01 )

            ; Change Endian
            $Endian_Read_01 = BinaryToString( $Endian_Read_01 , 2 )
            $Endian_Read_01 = StringToBinary( $Endian_Read_01 , 3 )

            ; Over Write Big Endian
            $Endian_Open_02 = FileOpen  ( $Track , 18 )
            FileWrite ( $Endian_Open_02 , $Endian_Read_01 )
            FileClose ( $Endian_Open_02 )
        EndIf
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...