Author: post
Date: 2012-09-30 20:19:58 +0200 (Sun, 30 Sep 2012)
New Revision: 463

Modified:
   RawSpeed/BitPumpMSB.cpp
   RawSpeed/BitPumpMSB.h
Log:
Speed up bit parsing by using a bigger buffer, and utilize bswap instruction if 
available. ~10% overall speedup on Nikon, Pentax decoding.

Modified: RawSpeed/BitPumpMSB.cpp
===================================================================
--- RawSpeed/BitPumpMSB.cpp     2012-09-30 18:13:40 UTC (rev 462)
+++ RawSpeed/BitPumpMSB.cpp     2012-09-30 18:19:58 UTC (rev 463)
@@ -1,5 +1,6 @@
 #include "StdAfx.h"
 #include "BitPumpMSB.h"
+
 /*
     RawSpeed - RAW file decoder.
 
@@ -28,48 +29,68 @@
 
 
 BitPumpMSB::BitPumpMSB(ByteStream *s):
-    buffer(s->getData()), size(s->getRemainSize() + sizeof(uint32)), mLeft(0), 
mCurr(0), off(0) {
+    buffer(s->getData()), size(s->getRemainSize() + sizeof(uint32)), mLeft(0), 
off(0) {
   init();
 }
 
 BitPumpMSB::BitPumpMSB(const uchar8* _buffer, uint32 _size) :
-    buffer(_buffer), size(_size + sizeof(uint32)), mLeft(0), mCurr(0), off(0) {
+    buffer(_buffer), size(_size + sizeof(uint32)), mLeft(0), off(0) {
   init();
 }
 
 __inline void BitPumpMSB::init() {
+  current_buffer = (uchar8*)_aligned_malloc(16, 16);
+  if (!current_buffer)
+    ThrowRDE("BitPumpMSB::init(): Unable to allocate memory");
+  memset(current_buffer,0,16);
   fill();
 }
 
+void BitPumpMSB::fill()
+{
+  if (mLeft >=24)
+    return;
+  // Fill in 96 bits
+  int* b = (int*)current_buffer;
+  b[3] = b[0];
+#if defined(LE_PLATFORM_HAS_BSWAP)
+  b[2] = PLATFORM_BSWAP32(*(int*)&buffer[off]);
+  b[1] = PLATFORM_BSWAP32(*(int*)&buffer[off+4]);
+  b[0] = PLATFORM_BSWAP32(*(int*)&buffer[off+8]);
+  off+=12;
+#else
+  b[2] = (buffer[off] << 24) | (buffer[off+1] << 16)  | (buffer[off+2] << 8) | 
buffer[off+3];
+  off+=4;
+  b[1] = (buffer[off] << 24) | (buffer[off+1] << 16)  | (buffer[off+2] << 8) | 
buffer[off+3];
+  off+=4;
+  b[0] = (buffer[off] << 24) | (buffer[off+1] << 16)  | (buffer[off+2] << 8) | 
buffer[off+3];
+  off+=4;
+#endif
+  mLeft+=96;
+}
+
+
 uint32 BitPumpMSB::getBitSafe() {
-  if (!mLeft) {
-    fill();
-    checkPos();
-  }
+  fill();
+  checkPos();
 
-  return (mCurr >> (--mLeft)) & 1;
+  return getBitNoFill();
 }
 
 uint32 BitPumpMSB::getBitsSafe(unsigned int nbits) {
   if (nbits > MIN_GET_BITS)
     throw IOException("Too many bits requested");
 
-  if (mLeft < nbits) {
-    fill();
-    checkPos();
-  }
-
-  return ((mCurr >> (mLeft -= (nbits)))) & ((1 << nbits) - 1);
+  fill();
+  checkPos();
+  return getBitsNoFill(nbits);
 }
 
 
 uchar8 BitPumpMSB::getByteSafe() {
-  if (mLeft < 8) {
-    fill();
-    checkPos();
-  }
-
-  return ((mCurr >> (mLeft -= 8))) & 0xff;
+  fill();
+  checkPos();
+  return getBitsNoFill(8);
 }
 
 void BitPumpMSB::setAbsoluteOffset(unsigned int offset) {
@@ -77,7 +98,6 @@
     throw IOException("Offset set out of buffer");
 
   mLeft = 0;
-  mCurr = 0;
   off = offset;
   fill();
 }
@@ -85,6 +105,8 @@
 
 
 BitPumpMSB::~BitPumpMSB(void) {
+       _aligned_free(current_buffer);
 }
 
 } // namespace RawSpeed
+

Modified: RawSpeed/BitPumpMSB.h
===================================================================
--- RawSpeed/BitPumpMSB.h       2012-09-30 18:13:40 UTC (rev 462)
+++ RawSpeed/BitPumpMSB.h       2012-09-30 18:19:58 UTC (rev 463)
@@ -19,8 +19,8 @@
 
     http://www.klauspost.com
 */
-#ifndef BIT_PUMP_MSB_H
-#define BIT_PUMP_MSB_H
+#ifndef BIT_PUMP_MSB_H
+#define BIT_PUMP_MSB_H
 
 #include "ByteStream.h"
 
@@ -41,85 +41,67 @@
        uchar8 getByteSafe();
        void setAbsoluteOffset(uint32 offset);     // Set offset in bytes
   __inline uint32 getOffset() { return off-(mLeft>>3);}
-  __inline void checkPos()  { if (off>size) throw IOException("Out of buffer 
read");};        // Check if we have a valid position
-  __inline uint32 getBitNoFill() {return (mCurr >> (--mLeft)) & 1;}
-  __inline uint32 peekByteNoFill() {return ((mCurr >> (mLeft-8))) & 0xff; }
-  __inline uint32 getBitsNoFill(uint32 nbits) {return ((mCurr >> (mLeft -= 
(nbits)))) & ((1 << nbits) - 1);}
-  __inline uint32 peekBitsNoFill(uint32 nbits) {return ((mCurr >> 
(mLeft-nbits))) & ((1 << nbits) - 1); }
+  __inline void checkPos()  { if (off>size+12) throw IOException("Out of 
buffer read");};        // Check if we have a valid position
 
   // Fill the buffer with at least 24 bits
-__inline void fill() {
-  unsigned char c, c2, c3;
-  int m = mLeft >> 3;
+ void fill();
+ __inline uint32 peekBitsNoFill( uint32 nbits )
+ {
+   int shift = mLeft-nbits;
+   uint32 ret = *(uint32*)&current_buffer[shift>>3];
+   ret >>= shift & 7;
+   return ret & ((1 << nbits) - 1);
+ }
 
-  if (mLeft > 23)
-    return;
 
-  if (m == 2) {
-     // 16 to 23 bits left, we can add 1 byte
-     c = buffer[off++];
-     mCurr = (mCurr << 8) | c;
-     mLeft += 8;
-     return;
-  }
+__inline uint32 getBit() {
+  if (!mLeft) fill();
+  mLeft--;
+  uint32 _byte = mLeft >> 3;
+  return (current_buffer[_byte] >> (mLeft & 0x7)) & 1;
+}
 
-  if (m == 1) {
-    // 8 to 15 bits left, we can add 2 bytes
-      c = buffer[off++];
-         c2 = buffer[off++];
-         mCurr = (mCurr << 16) | (c<<8) | c2;
-         mLeft += 16;
-         return;
-  }
+__inline uint32 getBitsNoFill(uint32 nbits) {
+       uint32 ret = peekBitsNoFill(nbits);
+       mLeft -= nbits;
+       return ret;
+}
+__inline uint32 getBits(uint32 nbits) {
+       fill();
+       return getBitsNoFill(nbits);
+}
 
-  // 0 to 7 bits left, we can add 3 bytes
-  c = buffer[off++];
-  c2 = buffer[off++];
-  c3 = buffer[off++];
-  mCurr = (mCurr << 24) | (c<<16) | (c2<<8) | c3;
-  mLeft += 24;
+__inline uint32 peekBit() {
+  if (!mLeft) fill();
+  return (current_buffer[(mLeft-1) >> 3] >> ((mLeft-1) & 0x7)) & 1;
+}
+__inline uint32 getBitNoFill() {
+  mLeft--;
+  uint32 ret = (current_buffer[mLeft >> 3] >> (mLeft & 0x7)) & 1;
+  return ret;
+}
 
+__inline uint32 peekByteNoFill() {
+  int shift = mLeft-8;
+  uint32 ret = *(uint32*)&current_buffer[shift>>3];
+  ret >>= shift & 7;
+  return ret & 0xff;
 }
 
-  __inline uint32 getBit() {
-    if (!mLeft) fill();
+__inline uint32 peekBits(uint32 nbits) {
+  fill();
+  return peekBitsNoFill(nbits);
+}
 
-    return (mCurr >> (--mLeft)) & 1;
-  }
+__inline uint32 peekByte() {
+   fill();
+ 
+  if (off > size)
+    throw IOException("Out of buffer read");
 
-  __inline uint32 getBits(uint32 nbits) {
-    if (mLeft < nbits) {
-      fill();
-    }
+  return peekByteNoFill();
+} 
 
-    return ((mCurr >> (mLeft -= (nbits)))) & ((1 << nbits) - 1);
-  }
-
-  __inline uint32 peekBit() {
-    if (!mLeft) fill();
-
-    return (mCurr >> (mLeft - 1)) & 1;
-  }
-
-  __inline uint32 peekBits(uint32 nbits) {
-    if (mLeft < nbits) {
-      fill();
-    }
-
-    return ((mCurr >> (mLeft - nbits))) & ((1 << nbits) - 1);
-  }
-
-  __inline uint32 peekByte() {
-    if (mLeft < 8) {
-      fill();
-    }
-
-    if (off > size)
-      throw IOException("Out of buffer read");
-
-    return ((mCurr >> (mLeft - 8))) & 0xff;
-  }
-
   __inline void skipBits(unsigned int nbits) {
     while (nbits) {
       fill();
@@ -135,24 +117,25 @@
   }
 
   __inline unsigned char getByte() {
-    if (mLeft < 8) {
-      fill();
-    }
-
-    return ((mCurr >> (mLeft -= 8))) & 0xff;
+    fill();
+    mLeft-=8;
+    int shift = mLeft;
+    uint32 ret = *(uint32*)&current_buffer[shift>>3];
+    ret >>= shift & 7;
+    return ret & 0xff;
   }
 
   virtual ~BitPumpMSB(void);
 protected:
   void __inline init();
   const uchar8* buffer;
+  uchar8* current_buffer;
   const uint32 size;            // This if the end of buffer.
   uint32 mLeft;
-  uint32 mCurr;
   uint32 off;                  // Offset in bytes
 private:
 };
 
 } // namespace RawSpeed
-
-#endif
+
+#endif//BIT_PUMP_MSB_H


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to