changeset 490:1b532e7dd521

Decrease PBG3 loading time by improving lzss and bitstream integration.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 04 Oct 2013 14:28:49 +0200
parents 59bd29568753
children 2276229282fd
files pytouhou/formats/pbg3.py pytouhou/utils/bitstream.pxd pytouhou/utils/bitstream.pyx pytouhou/utils/lzss.pyx
diffstat 4 files changed, 29 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/formats/pbg3.py
+++ b/pytouhou/formats/pbg3.py
@@ -24,7 +24,7 @@ a file table, and LZSS-compressed files.
 from collections import namedtuple
 
 from pytouhou.utils.bitstream import BitStream
-import pytouhou.utils.lzss as lzss
+from pytouhou.utils import lzss
 
 from pytouhou.utils.helpers import get_logger
 
new file mode 100644
--- /dev/null
+++ b/pytouhou/utils/bitstream.pxd
@@ -0,0 +1,10 @@
+cdef class BitStream:
+    cdef public object io
+    cdef unsigned int bits
+    cdef unsigned char byte
+
+    cdef bint read_bit(self) except? -1
+    cpdef unsigned int read(self, unsigned int nb_bits) except? 4242
+    cpdef write_bit(self, bint bit)
+    cpdef write(self, unsigned int bits, unsigned int nb_bits)
+    cpdef flush(self)
--- a/pytouhou/utils/bitstream.pyx
+++ b/pytouhou/utils/bitstream.pyx
@@ -13,12 +13,6 @@
 ##
 
 cdef class BitStream:
-    cdef public object io
-    cdef unsigned int bits
-    cdef unsigned char byte
-    cdef bytes bytes
-
-
     def __init__(self, io):
         self.io = io
         self.bits = 0
@@ -39,31 +33,25 @@ cdef class BitStream:
         self.bits = 0
 
 
-    def tell(self):
-        return self.io.tell()
-
-
-    def tell2(self):
-        return self.io.tell(), self.bits
-
-
-    cpdef unsigned char read_bit(self) except? -1:
+    cdef bint read_bit(self):
+        cdef bytes byte
         if not self.bits:
-            self.bytes = self.io.read(1)
-            self.byte = (<unsigned char*> self.bytes)[0]
+            byte = self.io.read(1)
+            self.byte = (<unsigned char*>byte)[0]
             self.bits = 8
         self.bits -= 1
         return (self.byte >> self.bits) & 0x01
 
 
-    cpdef unsigned int read(self, unsigned int nb_bits) except? -1:
+    cpdef unsigned int read(self, unsigned int nb_bits):
         cdef unsigned int value = 0, read = 0
         cdef unsigned int nb_bits2 = nb_bits
+        cdef bytes byte
 
         while nb_bits2:
             if not self.bits:
-                self.bytes = self.io.read(1)
-                self.byte = (<unsigned char*> self.bytes)[0]
+                byte = self.io.read(1)
+                self.byte = (<unsigned char*>byte)[0]
                 self.bits = 8
             read = self.bits if nb_bits2 > self.bits else nb_bits2
             nb_bits2 -= read
@@ -72,7 +60,7 @@ cdef class BitStream:
         return value & ((1 << nb_bits) - 1)
 
 
-    cpdef write_bit(self, bit):
+    cpdef write_bit(self, bint bit):
         if self.bits == 8:
             self.io.write(chr(self.byte))
             self.bits = 0
@@ -82,12 +70,12 @@ cdef class BitStream:
         self.bits += 1
 
 
-    def write(self, bits, nb_bits):
+    cpdef write(self, unsigned int bits, unsigned int nb_bits):
         for i in range(nb_bits):
             self.write_bit(bits >> (nb_bits - 1 - i) & 0x01)
 
 
-    def flush(self):
+    cpdef flush(self):
         self.io.write(chr(self.byte))
         self.bits = 0
         self.byte = 0
--- a/pytouhou/utils/lzss.pyx
+++ b/pytouhou/utils/lzss.pyx
@@ -12,19 +12,23 @@
 ## GNU General Public License for more details.
 ##
 
+cimport cython
 from libc.stdlib cimport calloc, malloc, free
 
+from .bitstream cimport BitStream
 
-cpdef bytes decompress(object bitstream,
+
+@cython.cdivision(True)
+cpdef bytes decompress(BitStream bitstream,
                        Py_ssize_t size,
                        unsigned int dictionary_size=0x2000,
                        unsigned int offset_size=13,
                        unsigned int length_size=4,
                        unsigned int minimum_match_length=3):
-    cdef unsigned int i, ptr, dictionary_head, offset, length
+    cdef Py_ssize_t ptr, length
+    cdef unsigned int dictionary_head
     cdef unsigned char byte
     cdef char *out_data, *dictionary
-    cdef bytes _out_data
 
     out_data = <char*> malloc(size)
     dictionary = <char*> calloc(dictionary_size, 1)