3

I have react native app, that load binary file which contains JPG data inside. I packed 3 JPG(images) inside binary file. In begin of that file I put some extra information:

  1. Total number of JPG files
  2. Image 1 file size
  3. Image 2 file size
  4. Image 3 file size

I can download binary data with fetch and get Blob object. But how I can read this extra information from binary files?

enter image description here

1 Answer 1

2

Finally I did it myself

import React, { Component, useState } from 'react'
import { View, Button, Text, Image } from 'react-native'

export const TestScreen = ({ navigation }) => {
    const [base64data, setBase64data] = useState(undefined)

    let previewBase64 = []

    const appUpdate = async () => {
        fetch('preview.data').then(
            async (data) => {
                let binary = await data.blob()
                
                //read 10 bytes of file header
                let bytes = binary.slice(0, 10)
                blob2base64(bytes).then(async (data) => {
                    const bytes = base642bytes(data)
                    const totalImages = bytes[0]

                    let imageBytesOffset = 0
                    for (let i = 0; i < totalImages; i++) {
                        const imageSize = sumBytes(
                            bytes[i * 3 + 1],
                            bytes[i * 3 + 2],
                            bytes[i * 3 + 3]
                        )

                        const start = 10 + imageBytesOffset
                        const end = 10 + imageSize + imageBytesOffset
                        const imageBlob = binary.slice(start, end)
                        //adding new image to array
                        previewBase64.push(await blob2base64(imageBlob))
                        imageBytesOffset += imageSize

                        console.log(imageSize)
                    }
                    //loading 3d image from binary file
                    setBase64data(previewBase64[2])
                })
            }
        )
    }

    const blob2base64 = (value) => {
        return new Promise((resolve, reject) => {
            const fileReaderInstance = new FileReader()
            fileReaderInstance.readAsDataURL(value)
            fileReaderInstance.onload = () => {
                resolve(fileReaderInstance.result)
            }
        })
    }

    const base642bytes = (value) => {
        const content = atob(
            value.substr('data:application/octet-stream;base64,'.length)
        )

        const buffer = new ArrayBuffer(content.length)
        const view = new Uint8Array(buffer)
        view.set(Array.from(content).map((c) => c.charCodeAt(0)))
        return view
    }

    const sumBytes = (byte1, byte2, byte3) => {
        let bytes = new Uint8Array(3)
        bytes[0] = byte1
        bytes[1] = byte2
        bytes[2] = byte3

        const result =
            ((bytes[0] & 0xff) << 16) |
            ((bytes[1] & 0xff) << 8) |
            (bytes[2] & 0xff)

        return result
    }

    const chars =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
    const atob = (input = '') => {
        let str = input.replace(/=+$/, '')
        let output = ''

        if (str.length % 4 == 1) {
            throw new Error(
                "'atob' failed: The string to be decoded is not correctly encoded."
            )
        }
        for (
            let bc = 0, bs = 0, buffer, i = 0;
            (buffer = str.charAt(i++));
            ~buffer && ((bs = bc % 4 ? bs * 64 + buffer : buffer), bc++ % 4)
                ? (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6))))
                : 0
        ) {
            buffer = chars.indexOf(buffer)
        }

        return output
    }

    console.log('TestScreen')

    return (
        <View style={{ backgroundColor: '#FFFFFF', flex: 1, paddingTop: 60 }}>
            <Button
                title="Update app"
                color="#000000"
                onPress={appUpdate}
            ></Button>
            <Image
                source={{ uri: base64data }}
                style={{
                    height: 200,
                    width: null,
                    flex: 1,
                    resizeMode: 'contain',
                }}
            />
        </View>
    )
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.