napperley
04/08/2021, 2:37 AMinternal actual fun combineImageFiles(dirPath: String) {
val appendBinaryMode = "ab"
val readBinaryMode = "rb"
val arena = Arena()
val entries = listDirectory(dirPath).sortedWith(ImageNameComparator())
val videoFile = fopen("$dirPath/video.mjpg", appendBinaryMode)
entries.forEach { e ->
val dataSize = fileSize("$dirPath/$e")
val tmpFile = fopen("$dirPath/$e", readBinaryMode)
val data = arena.allocArray<ByteVar>(dataSize.toInt())
fread(__n = 1, __stream = tmpFile, __ptr = data, __size = dataSize)
fclose(tmpFile)
fwrite(__n = 1, __s = videoFile, __ptr = data, __size = dataSize)
}
arena.clear()
fclose(videoFile)
Unit
}
This snippet works however it is using multiple buffers which isn't ideal. If there are a lot of image files being handled then the memory usage would become excessive.Dominaezzz
04/08/2021, 8:11 AMallocArray
here, you can just use a ByteArray
and temporarily pin it.ByteArray(4096)
and have more frequent calls to fread
and fwrite
when the file is big. This is how JVM InputStream.copyTo(OutputStream)
does it.mbonnin
04/08/2021, 10:56 AMnapperley
04/08/2021, 10:02 PMmbonnin
04/09/2021, 7:57 AMnapperley
04/13/2021, 2:01 AMinternal fun clearBuffer(buffer: CArrayPointer<ByteVar>, bufferSize: ULong) {
memset(__s = buffer, __c = 0, bufferSize)
}
internal actual fun combineImageFiles(dirPath: String) = memScoped {
val appendBinaryMode = "ab"
val readBinaryMode = "rb"
val entries = listDirectory(dirPath).sortedWith(ImageNameComparator())
val videoFile = fopen("$dirPath/video.mjpg", appendBinaryMode)
val bufferSize = 71680
val buffer = allocArray<ByteVar>(bufferSize)
entries.forEach { e ->
val dataSize = fileSize("$dirPath/$e")
val tmpFile = fopen("$dirPath/$e", readBinaryMode)
clearBuffer(buffer, bufferSize.toULong())
fread(__n = 1, __stream = tmpFile, __ptr = buffer, __size = dataSize)
fclose(tmpFile)
fwrite(__n = 1, __s = videoFile, __ptr = buffer, __size = dataSize)
}
fclose(videoFile)
Unit
}