mirror of
https://github.com/ProjectSWGCore/pswgcommon.git
synced 2026-10-20 12:03:02 -04:00
Sped up targa bitmap loading significantly
This commit is contained in:
+56
-72
@@ -2,6 +2,7 @@ package com.projectswg.common.data.swgiff.parsers.terrain.bitmap
|
||||
|
||||
import java.io.FileInputStream
|
||||
import java.io.InputStream
|
||||
import kotlin.math.min
|
||||
|
||||
class TargaBitmap {
|
||||
|
||||
@@ -9,62 +10,19 @@ class TargaBitmap {
|
||||
private var colorMapType: Byte = 0
|
||||
private var dataTypeCode: Byte = 0
|
||||
private var colorMapDepth: Byte = 0
|
||||
private var bitsPerPixel: Byte = 0
|
||||
private var bitsPerPixel: Int = 0
|
||||
private var imageDescriptor: Byte = 0
|
||||
private var colorMapOrigin: Short = 0
|
||||
private var colorMapLength: Short = 0
|
||||
private var originX: Short = 0
|
||||
private var originY: Short = 0
|
||||
var width: Short = 0
|
||||
var width: Int = 0
|
||||
private set
|
||||
var height: Short = 0
|
||||
var height: Int = 0
|
||||
private set
|
||||
private lateinit var pixelData: Array<TargaPixel?>
|
||||
private lateinit var pixelData: ByteArray
|
||||
var fileName: String? = null
|
||||
|
||||
inner class TargaColorPixel : TargaPixel() {
|
||||
var r = 0.toChar()
|
||||
var g = 0.toChar()
|
||||
var b = 0.toChar()
|
||||
var a = 0.toChar()
|
||||
|
||||
override fun read(buffer: InputStream, bytes: Int) {
|
||||
when (bytes) {
|
||||
4 -> {
|
||||
r = Char(buffer.read().toUShort())
|
||||
g = Char(buffer.read().toUShort())
|
||||
b = Char(buffer.read().toUShort())
|
||||
a = Char(buffer.read().toUShort())
|
||||
}
|
||||
3 -> {
|
||||
r = Char(buffer.read().toUShort())
|
||||
g = Char(buffer.read().toUShort())
|
||||
b = Char(buffer.read().toUShort())
|
||||
a = 0.toChar()
|
||||
}
|
||||
2 -> {
|
||||
val first = Char(buffer.read().toUShort())
|
||||
val second = Char(buffer.read().toUShort())
|
||||
r = (first.code and 0x7c shl 1).toChar()
|
||||
g = (first.code and 0x03 shl 6 or (second.code and 0xe0 shl 2)).toChar()
|
||||
b = (second.code and 0x1f shl 3).toChar()
|
||||
a = (first.code and 0x80).toChar()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class TargaBlackPixel : TargaPixel() {
|
||||
var `val` = 0.toChar()
|
||||
override fun read(buffer: InputStream, bytes: Int) {
|
||||
`val` = Char(buffer.readByte().toUShort())
|
||||
}
|
||||
}
|
||||
|
||||
abstract inner class TargaPixel {
|
||||
abstract fun read(buffer: InputStream, bytes: Int)
|
||||
}
|
||||
|
||||
fun readFile(filePath: String) {
|
||||
fileName = filePath
|
||||
FileInputStream("clientdata/$filePath").use { inputStream ->
|
||||
@@ -76,9 +34,9 @@ class TargaBitmap {
|
||||
colorMapDepth = inputStream.readByte()
|
||||
originX = inputStream.readShort()
|
||||
originY = inputStream.readShort()
|
||||
width = inputStream.readShort()
|
||||
height = inputStream.readShort()
|
||||
bitsPerPixel = inputStream.readByte()
|
||||
width = inputStream.readShort().toInt()
|
||||
height = inputStream.readShort().toInt()
|
||||
bitsPerPixel = inputStream.readByte().toInt()
|
||||
imageDescriptor = inputStream.readByte()
|
||||
|
||||
var length = 0
|
||||
@@ -89,37 +47,35 @@ class TargaBitmap {
|
||||
else if (height > width)
|
||||
length = height * height
|
||||
|
||||
pixelData = arrayOfNulls(length)
|
||||
for (i in 0 until length) {
|
||||
var pixel: TargaPixel? = null
|
||||
when (dataTypeCode.toInt()) {
|
||||
3 -> pixel = TargaBlackPixel()
|
||||
2, 10 -> pixel = TargaColorPixel()
|
||||
}
|
||||
pixelData[i] = pixel
|
||||
}
|
||||
inputStream.skip((idLength + colorMapType * colorMapLength).toLong())
|
||||
val bytes = bitsPerPixel / 8
|
||||
if (width <= height) {
|
||||
for (i in width - 1 downTo 0) {
|
||||
for (j in 0 until height) {
|
||||
pixelData[i * width + j]!!.read(inputStream, bytes)
|
||||
}
|
||||
}
|
||||
if (bitsPerPixel == 8) {
|
||||
pixelData = inputStream.readNBytes(length)
|
||||
} else {
|
||||
for (i in height - 1 downTo 0) {
|
||||
for (j in 0 until width) {
|
||||
pixelData[i * height + j]!!.read(inputStream, bytes)
|
||||
}
|
||||
assert(dataTypeCode == 2.toByte() || dataTypeCode == 10.toByte())
|
||||
pixelData = ByteArray(length * 4)
|
||||
val pixelLoaderFunction = when (bitsPerPixel) {
|
||||
16 -> ::read2ByteColorPixel
|
||||
24 -> ::read3ByteColorPixel
|
||||
32 -> ::read4ByteColorPixel
|
||||
else -> throw NotImplementedError("unsupported bits per pixel: $bitsPerPixel")
|
||||
}
|
||||
val bytesPerPixel = bitsPerPixel / 8
|
||||
var index = 0
|
||||
for (i in 0 until length) {
|
||||
pixelLoaderFunction(inputStream, pixelData, index)
|
||||
index += bytesPerPixel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getData(offset: Int): Char {
|
||||
fun getData(offset: Int): Byte {
|
||||
if (offset < 0 || offset >= width * height)
|
||||
throw ArrayIndexOutOfBoundsException(offset)
|
||||
return (pixelData[offset] as TargaBlackPixel?)!!.`val`
|
||||
val smaller = min(width, height)
|
||||
val y = offset / smaller
|
||||
val x = offset % smaller
|
||||
return pixelData[(smaller - y - 1) * smaller + x]
|
||||
}
|
||||
|
||||
private fun InputStream.readByte(): Byte {
|
||||
@@ -130,4 +86,32 @@ class TargaBitmap {
|
||||
return ((read() or (read() shl 8)) and 0xFFFF).toShort()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun read4ByteColorPixel(src: InputStream, dst: ByteArray, indexIn: Int) {
|
||||
var index: Int = indexIn
|
||||
dst[index++] = src.read().toByte()
|
||||
dst[index++] = src.read().toByte()
|
||||
dst[index++] = src.read().toByte()
|
||||
dst[index] = src.read().toByte()
|
||||
}
|
||||
|
||||
private fun read3ByteColorPixel(src: InputStream, dst: ByteArray, indexIn: Int) {
|
||||
var index: Int = indexIn
|
||||
dst[index++] = src.read().toByte()
|
||||
dst[index++] = src.read().toByte()
|
||||
dst[index++] = src.read().toByte()
|
||||
dst[index] = 0
|
||||
}
|
||||
|
||||
private fun read2ByteColorPixel(src: InputStream, dst: ByteArray, indexIn: Int) {
|
||||
var index: Int = indexIn
|
||||
val first = src.read()
|
||||
val second = src.read()
|
||||
dst[index++] = (first and 0x7c shl 1).toByte()
|
||||
dst[index++] = (first and 0x03 shl 6 or (second and 0xe0 shl 2)).toByte()
|
||||
dst[index++] = (second and 0x1f shl 3).toByte()
|
||||
dst[index] = (first and 0x80).toByte()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -40,12 +40,12 @@ class FilterBitmap : FilterLayer() {
|
||||
var v25 = (v44 * (height - v41 - 1)).toInt()
|
||||
val v26 = (v39 * v44 / arg6).toInt()
|
||||
var v27 = (v43 * v44 / arg6).toInt()
|
||||
val v28 = (bitmap.getData(v27 + v25).code and 0xFF).toFloat()
|
||||
val v28 = (bitmap.getData(v27 + v25).toInt() and 0xFF).toFloat()
|
||||
//byte mapValue = v28;
|
||||
var arg2 = (bitmap.getData(v26 + v25).code and 0xFF).toFloat()
|
||||
var arg2 = (bitmap.getData(v26 + v25).toInt() and 0xFF).toFloat()
|
||||
val v29 = (v44 * (height - arg1 - 1)).toInt()
|
||||
v25 = bitmap.getData(v29 + v27).code and 0xFF
|
||||
v27 = bitmap.getData(v26 + v29).code and 0xFF
|
||||
v25 = bitmap.getData(v29 + v27).toInt() and 0xFF
|
||||
v27 = bitmap.getData(v26 + v29).toInt() and 0xFF
|
||||
arg6 = v25.toFloat()
|
||||
arg1 = v27.toFloat()
|
||||
val v30 = v42 - v43.toDouble()
|
||||
|
||||
Reference in New Issue
Block a user