Some gif improvments.
This commit is contained in:
parent
dc52e6f77b
commit
d248457b0b
|
@ -22,6 +22,7 @@ proc readBit(bs: BitStream, pos: int): int =
|
||||||
|
|
||||||
proc read*(bs: BitStream, bits: int): int =
|
proc read*(bs: BitStream, bits: int): int =
|
||||||
## Reads number of bits
|
## Reads number of bits
|
||||||
|
# TODO: This can be faster.
|
||||||
for i in 0 ..< bits:
|
for i in 0 ..< bits:
|
||||||
result = result shl 1
|
result = result shl 1
|
||||||
result += bs.readBit(bs.pos + bits - i - 1)
|
result += bs.readBit(bs.pos + bits - i - 1)
|
||||||
|
@ -70,7 +71,7 @@ proc decodeGIF*(data: string): Image =
|
||||||
let blockType = data.readUint8(i)
|
let blockType = data.readUint8(i)
|
||||||
i += 1
|
i += 1
|
||||||
case blockType:
|
case blockType:
|
||||||
of 0x2c: # IMAGE
|
of 0x2c: # Read IMAGE block.
|
||||||
if i + 9 >= data.len: failInvalid()
|
if i + 9 >= data.len: failInvalid()
|
||||||
let
|
let
|
||||||
left = data.readUint16(i + 0)
|
left = data.readUint16(i + 0)
|
||||||
|
@ -114,8 +115,8 @@ proc decodeGIF*(data: string): Image =
|
||||||
i += lzwEncodedLen.int
|
i += lzwEncodedLen.int
|
||||||
|
|
||||||
let
|
let
|
||||||
clearMark = 1 shl lzwMinBitSize
|
clearCode = 1 shl lzwMinBitSize
|
||||||
endMark = clearMark + 1
|
endCode = clearCode + 1
|
||||||
|
|
||||||
# Turn full lzw data into bit stream.
|
# Turn full lzw data into bit stream.
|
||||||
var
|
var
|
||||||
|
@ -127,7 +128,8 @@ proc decodeGIF*(data: string): Image =
|
||||||
colorIndexes: seq[int]
|
colorIndexes: seq[int]
|
||||||
|
|
||||||
# Main decode loop.
|
# Main decode loop.
|
||||||
while codeLast != endMark:
|
while codeLast != endCode:
|
||||||
|
|
||||||
if bs.pos + bitSize.int > bs.len: failInvalid()
|
if bs.pos + bitSize.int > bs.len: failInvalid()
|
||||||
var
|
var
|
||||||
# Read variable bits out of the table.
|
# Read variable bits out of the table.
|
||||||
|
@ -135,16 +137,16 @@ proc decodeGIF*(data: string): Image =
|
||||||
# Some time we need to carry over table information.
|
# Some time we need to carry over table information.
|
||||||
carryOver: seq[int]
|
carryOver: seq[int]
|
||||||
|
|
||||||
if codeId == clearMark:
|
if codeId == clearCode:
|
||||||
# Clear and re-init the tables.
|
# Clear and re-init the tables.
|
||||||
bitSize = lzwMinBitSize + 1
|
bitSize = lzwMinBitSize + 1
|
||||||
currentCodeTableMax = (1 shl (bitSize)) - 1
|
currentCodeTableMax = (1 shl (bitSize)) - 1
|
||||||
codeLast = -1
|
codeLast = -1
|
||||||
codeTable.setLen(0)
|
codeTable.setLen(0)
|
||||||
for x in 0 ..< endMark + 1:
|
for x in 0 ..< endCode + 1:
|
||||||
codeTable.add(@[x])
|
codeTable.add(@[x])
|
||||||
|
|
||||||
elif codeId == endMark:
|
elif codeId == endCode:
|
||||||
# Exit we are done.
|
# Exit we are done.
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -154,7 +156,7 @@ proc decodeGIF*(data: string): Image =
|
||||||
colorIndexes.add(current)
|
colorIndexes.add(current)
|
||||||
carryOver = @[current[0]]
|
carryOver = @[current[0]]
|
||||||
|
|
||||||
elif codeLast != -1 and codeLast != clearMark and codeLast != endMark:
|
elif codeLast notin [-1, clearCode, endCode]:
|
||||||
# Its in the current table use it.
|
# Its in the current table use it.
|
||||||
if codeLast >= codeTable.len: failInvalid()
|
if codeLast >= codeTable.len: failInvalid()
|
||||||
var previous = codeTable[codeLast]
|
var previous = codeTable[codeLast]
|
||||||
|
@ -166,7 +168,7 @@ proc decodeGIF*(data: string): Image =
|
||||||
inc bitSize
|
inc bitSize
|
||||||
currentCodeTableMax = (1 shl (bitSize)) - 1
|
currentCodeTableMax = (1 shl (bitSize)) - 1
|
||||||
|
|
||||||
if codeLast != -1 and codeLast != clearMark and codeLast != endMark:
|
if codeLast notin [-1, clearCode, endCode]:
|
||||||
# We had some left over and need to expand table.
|
# We had some left over and need to expand table.
|
||||||
if codeLast >= codeTable.len: failInvalid()
|
if codeLast >= codeTable.len: failInvalid()
|
||||||
codeTable.add(codeTable[codeLast] & carryOver)
|
codeTable.add(codeTable[codeLast] & carryOver)
|
||||||
|
@ -178,8 +180,8 @@ proc decodeGIF*(data: string): Image =
|
||||||
if idx >= colors.len or j >= result.data.len: failInvalid()
|
if idx >= colors.len or j >= result.data.len: failInvalid()
|
||||||
result.data[j] = colors[idx]
|
result.data[j] = colors[idx]
|
||||||
|
|
||||||
of 0x21:
|
of 0x21: # Read EXTENSION block.
|
||||||
# Skip over all extensions (mostly animation information)
|
# Skip over all extensions (mostly animation information).
|
||||||
let extentionType = data.readUint8(i)
|
let extentionType = data.readUint8(i)
|
||||||
inc i
|
inc i
|
||||||
let byteLen = data.readUint8(i)
|
let byteLen = data.readUint8(i)
|
||||||
|
@ -187,7 +189,7 @@ proc decodeGIF*(data: string): Image =
|
||||||
i += byteLen.int
|
i += byteLen.int
|
||||||
doAssert data.readUint8(i) == 0
|
doAssert data.readUint8(i) == 0
|
||||||
inc i
|
inc i
|
||||||
of 0x3b:
|
of 0x3b: # Read TERMINAL block.
|
||||||
# Exit block byte - we are done.
|
# Exit block byte - we are done.
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue