Android Question Bytes to fixed packet

Philip Prins

Active Member
Licensed User
Longtime User
Hello ,

I need to send a jpeg in packets of maximum 30 bytes to a server.
The problem is that the jpeg are different sizes.
How do i divide it?
I tried this , but how to handle oneven total data size?

B4X:
Public Sub SendPhoto(data() As Byte)
    Dim nbytes As Int=data.Length
    Dim bc As ByteConverter
    Dim ninp As Int
    Dim bufjpg(30) As Byte
    For ninp =0 To nbytes-1 Step 30
    bc.ArrayCopy(data,ninp,bufjpg,0,30)
    ptChannel.SendPublicCustomMessage(bufjpg,30)
    Next
End Sub
 

emexes

Expert
Licensed User
This won't work first go, but it'll be pretty close. I'll leave the assembly and polishing for you ;-)

Best put in a separate code module file (Project, add code module)

Call HandleImageMessage from that PTT incoming message routine, if all three of the following are true:

Data(0) = 0x01 'message is photo data
Data(1) = 0x01 'message is chunked (apparently everything is chunked, even small photos)
Data(8) = 0x01 or 0x02 or 0x03 'valid image types

HandleImageMessage will call ImageReceived whenever a full image has been received.

The image will probably be in JPEG file format. The easiest way to display it might be to write it to a file, then load the file to an ImageView.
B4X:
static variables:
    Dim CurrentSender As String = ""
    Dim NumChunks As Int = 0    'non-zero = reception in progress
    Dim ChunkBuffer As Map
 
Sub HandleImageMessage (Sender As String, Data() As Byte)

    If Sender <> CurrentSender Then
        CurrentSender = Sender
        NumChunks = 0
    End If

    If NumChunks = 0 Then
        Dim HighByte As Int = Bit.And(Data(6), 0xFF)
        Dim LowByte As Int = Bit.And(Data(7), 0xFF)
        Dim NumChunks = Bit.Or(Bit.ShiftLeft(HighByte, 8), LowByte)    '16-bit chunk count from header

        ChunkBuffer.Initialize
    End if

    Dim HighByte As Int = Bit.And(Data(4), 0xFF)
    Dim LowByte As Int = Bit.And(Data(5), 0xFF)
    Dim ThisChunkNumber = Bit.Or(Bit.ShiftLeft(HighByte, 8), LowByte)    '16 bit current chunk number from header

    ChunkBuffer.Put(ThisChunkNumber, Data())    'header and all - will strip that off when we assemble full image

    If ChunkBuffer.Size = NumChunks Then    'we have all chunks
        'determine size of full image (not including headers)

        Dim FullImageSize As Int = 0
        For ChunkNumber = 1 to NumChunks
            Dim B() As Byte = ChunkBuffer.Get(ChunkNumber)
            FullImageSize = FullImageSize + B.Length - 12
        Next

        'allocate buffer for assembly of full image

        Dim FullImage(FullImageSize) As Byte

        'assemble image

        Dim FullImageSizeSoFar As Int = 0
        For ChunkNumber = 1 to NumChunks
            Dim B() As Byte = ChunkBuffer.Get(ChunkNumber)

            bc.ArrayCopy(B, 12, FullImage, FullImageSizeSoFar, B.Length - 12)
            FullImageSizeSoFar = FullImageSizeSoFar + B.Length - 12
        Next

        NumChunks = 0    'prepare for next incoming
        ImageBuffer.Initialize    'clear buffer

        'pass to somebody who knows what to do with it...

        ImageReceived(Sender, FullImage, FullImage.Length)
    End If

End Sub
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Sender might be a reserved word in B4A. Should probably be using SenderID rather than Sender(name) anyway.

Also should probably check NumBlocks against each received packet, make sure that no monkey business is happening.
 
Upvote 0

emexes

Expert
Licensed User
I think this will fix the problem of interrupted image transfers (as long as the new image transfer has a different number of chunks)
B4X:
If Sender <> CurrentSender Then
    CurrentSender = Sender
    NumChunks = 0
End If

Dim HighByte As Int = Bit.And(Data(6), 0xFF)
Dim LowByte As Int = Bit.And(Data(7), 0xFF)
Dim ThisChunkNumChunks = Bit.Or(Bit.ShiftLeft(HighByte, 8), LowByte)    '16-bit chunk count from header

If ThisChunkNumChunks <> NumChunks Then    'resets reception if NumChunks = 0 or if NumChunks changes
    NumChunks = ThisChunkNumChunks
    ChunkBuffer.Initialize
End if
 
Upvote 0
Top