Author: post
Date: 2012-10-16 17:17:14 +0200 (Tue, 16 Oct 2012)
New Revision: 481

Modified:
   RawSpeed/BitPumpJPEG.cpp
   RawSpeed/BitPumpJPEG.h
Log:
Use bigger buffer for JPEG bit pump, Approximately 20% faster overall decoding 
of CR2/DNG.

Modified: RawSpeed/BitPumpJPEG.cpp
===================================================================
--- RawSpeed/BitPumpJPEG.cpp    2012-10-15 19:06:57 UTC (rev 480)
+++ RawSpeed/BitPumpJPEG.cpp    2012-10-16 15:17:14 UTC (rev 481)
@@ -1,5 +1,6 @@
 #include "StdAfx.h"
 #include "BitPumpJPEG.h"
+
 /*
     RawSpeed - RAW file decoder.
 
@@ -20,132 +21,77 @@
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
USA
 
     http://www.klauspost.com
-
-    This is based on code by Hubert Figuiere.
-    Copyright (C) 2007 Hubert Figuiere, released under LGPL
 */
 
 namespace RawSpeed {
 
 /*** Used for entropy encoded sections ***/
 
-#define BITS_PER_LONG (8*sizeof(uint32))
-#define MIN_GET_BITS  (BITS_PER_LONG-7)    /* max value for long getBuffer */
 
-
 BitPumpJPEG::BitPumpJPEG(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), stuffed(0) {
   init();
 }
 
-
 BitPumpJPEG::BitPumpJPEG(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), 
stuffed(0) {
   init();
 }
 
-
-void __inline BitPumpJPEG::init() {
-  stuffed = 0;
+__inline void BitPumpJPEG::init() {
+  current_buffer = (uchar8*)_aligned_malloc(16, 16);
+  if (!current_buffer)
+    ThrowRDE("BitPumpJPEG::init(): Unable to allocate memory");
+  memset(current_buffer,0,16);
   fill();
 }
 
-uint32 BitPumpJPEG::getBit() {
-  if (!mLeft) fill();
-
-  return (mCurr >> (--mLeft)) & 1;
+void BitPumpJPEG::fill()
+{
+  if (mLeft >=24)
+    return;
+  // Fill in 96 bits
+  int* b = (int*)current_buffer;
+  b[3] = b[0];
+  for (int i = 0; i < 12; i++) {
+        uchar8 val = buffer[off++];
+        if (val == 0xff)
+               if (buffer[off] == 0)
+                       off++;
+               else {
+                       val = 0;
+                       off--;
+                       stuffed++;
+               }
+     current_buffer[11-i] = val;
+  } 
+  mLeft+=96;
 }
 
 
-uint32 BitPumpJPEG::getBits(uint32 nbits) {
-  _ASSERTE(nbits < 24);
-
-  if (mLeft < nbits) {
-    fill();
-  }
-  return ((mCurr >> (mLeft -= (nbits)))) & ((1 << nbits) - 1);
-}
-
-
-uint32 BitPumpJPEG::peekBit() {
-  if (!mLeft) fill();
-  return (mCurr >> (mLeft - 1)) & 1;
-}
-
-
-uint32 BitPumpJPEG::peekBits(uint32 nbits) {
-  if (mLeft < nbits) {
-    fill();
-  }
-  return ((mCurr >> (mLeft - nbits))) & ((1 << nbits) - 1);
-}
-
-
-uint32 BitPumpJPEG::peekByte() {
-  if (mLeft < 8) {
-    fill();
-  }
-  if (off > size)
-    throw IOException("Out of buffer read");
-
-  return ((mCurr >> (mLeft - 8))) & 0xff;
-}
-
-
 uint32 BitPumpJPEG::getBitSafe() {
-  if (!mLeft) {
-    fill();
-    if (off > size)
-      throw IOException("Out of buffer read");
-  }
+  fill();
+  checkPos();
 
-  return (mCurr >> (--mLeft)) & 1;
+  return getBitNoFill();
 }
 
-
 uint32 BitPumpJPEG::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);
 }
 
 
-void BitPumpJPEG::skipBits(unsigned int nbits) {
-  _ASSERTE(nbits < 24);
-
-  if (mLeft < nbits) {
-    fill();
-    checkPos();
-  }
-
-  mLeft -= nbits;
-}
-
-
-uchar8 BitPumpJPEG::getByte() {
-  if (mLeft < 8) {
-    fill();
-  }
-
-  return ((mCurr >> (mLeft -= 8))) & 0xff;
-}
-
-
 uchar8 BitPumpJPEG::getByteSafe() {
-  if (mLeft < 8) {
-    fill();
-    checkPos();
-  }
-
-  return ((mCurr >> (mLeft -= 8))) & 0xff;
+  fill();
+  checkPos();
+  return getBitsNoFill(8);
 }
 
-
 void BitPumpJPEG::setAbsoluteOffset(unsigned int offset) {
   if (offset >= size)
     throw IOException("Offset set out of buffer");
@@ -156,7 +102,10 @@
 }
 
 
+
 BitPumpJPEG::~BitPumpJPEG(void) {
+       _aligned_free(current_buffer);
 }
 
 } // namespace RawSpeed
+

Modified: RawSpeed/BitPumpJPEG.h
===================================================================
--- RawSpeed/BitPumpJPEG.h      2012-10-15 19:06:57 UTC (rev 480)
+++ RawSpeed/BitPumpJPEG.h      2012-10-16 15:17:14 UTC (rev 481)
@@ -19,12 +19,14 @@
 
     http://www.klauspost.com
 */
-#ifndef BIT_PUMP_JPEG_H
-#define BIT_PUMP_JPEG_H
+#ifndef BIT_PUMP_JPEG_H
+#define BIT_PUMP_JPEG_H
 
 #include "ByteStream.h"
-#include "IOException.h"
 
+#define BITS_PER_LONG (8*sizeof(uint32))
+#define MIN_GET_BITS  (BITS_PER_LONG-7)    /* max value for long getBuffer */
+
 namespace RawSpeed {
 
 // Note: Allocated buffer MUST be at least size+sizeof(uint32) large.
@@ -34,90 +36,107 @@
 public:
   BitPumpJPEG(ByteStream *s);
   BitPumpJPEG(const uchar8* _buffer, uint32 _size );
-       uint32 getBits(uint32 nbits);
-       uint32 getBit();
        uint32 getBitsSafe(uint32 nbits);
        uint32 getBitSafe();
-       uint32 peekBits(uint32 nbits);
-       uint32 peekBit();
-  uint32 peekByte();
-  void skipBits(uint32 nbits);
-  __inline void skipBitsNoFill(uint32 nbits){ mLeft -= nbits; }
-  __inline void checkPos()  { if (off>size) throw IOException("Out of buffer 
read");};        // Check if we have a valid position
-       uchar8 getByte();
        uchar8 getByteSafe();
        void setAbsoluteOffset(uint32 offset);     // Set offset in bytes
-  uint32 getOffset() { return off-(mLeft>>3)+stuffed;}
-  __inline uint32 getBitNoFill() {return (mCurr >> (--mLeft)) & 1;}
-  __inline uint32 peekByteNoFill() {return ((mCurr >> (mLeft-8))) & 0xff; }
-  __inline uint32 peekBitsNoFill(uint32 nbits) {return ((mCurr >> 
(mLeft-nbits))) & ((1 << nbits) - 1); }
-  __inline uint32 getBitsNoFill(uint32 nbits) { return ((mCurr >> (mLeft -= 
(nbits)))) & ((1 << nbits) - 1);}
+  __inline uint32 getOffset() { return off-(mLeft>>3)+stuffed;}
+  __inline void checkPos()  { if (off>size+12) throw IOException("Out of 
buffer read");};        // Check if we have a valid position
 
-#define TEST_IF_FF(VAL) if (VAL == 0xFF) {\
-  if (buffer[off] == 0)\
-  off++;\
-  else  {\
-  VAL = 0;off--;stuffed++;\
-  }\
-  }
+  // Fill the buffer with at least 24 bits
+ 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);
+ }
 
 
-  // Fill the buffer with at least 24 bits
-  __inline void fill() {
-    uchar8 c, c2, c3;
+__inline uint32 getBit() {
+  if (!mLeft) fill();
+  mLeft--;
+  uint32 _byte = mLeft >> 3;
+  return (current_buffer[_byte] >> (mLeft & 0x7)) & 1;
+}
 
-    int m = mLeft >> 3;
+__inline uint32 getBitsNoFill(uint32 nbits) {
+       uint32 ret = peekBitsNoFill(nbits);
+       mLeft -= nbits;
+       return ret;
+}
+__inline uint32 getBits(uint32 nbits) {
+       fill();
+       return getBitsNoFill(nbits);
+}
 
-    if (mLeft > 23)
-      return;
+__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;
+}
 
-    if (m == 2)
-    {
-      // 16 to 23 bits left, we can add 1 byte
-      c = buffer[off++];
-      TEST_IF_FF(c);
-      mCurr = (mCurr << 8) | c;
-      mLeft += 8;
-      return;
-    }
+__inline uint32 peekByteNoFill() {
+  int shift = mLeft-8;
+  uint32 ret = *(uint32*)&current_buffer[shift>>3];
+  ret >>= shift & 7;
+  return ret & 0xff;
+}
 
-    if (m == 1)
-    {
-      // 8 to 15 bits left, we can add 2 bytes
-      c = buffer[off++];
-      TEST_IF_FF(c);
-      c2 = buffer[off++];
-      TEST_IF_FF(c2);
-      mCurr = (mCurr << 16) | (c<<8) | c2;
-      mLeft += 16;
-      return;
+__inline uint32 peekBits(uint32 nbits) {
+  fill();
+  return peekBitsNoFill(nbits);
+}
+
+__inline uint32 peekByte() {
+   fill();
+ 
+  if (off > size)
+    throw IOException("Out of buffer read");
+
+  return peekByteNoFill();
+} 
+
+  __inline void skipBits(unsigned int nbits) {
+    while (nbits) {
+      fill();
+      checkPos();
+      int n = MIN(nbits, mLeft);
+      mLeft -= n;
+      nbits -= n;
     }
+  }
 
-    // 0 to 7 bits left, we can add 3 bytes
-    c = buffer[off++];
-    TEST_IF_FF(c);
-    c2 = buffer[off++];
-    TEST_IF_FF(c2);
-    c3 = buffer[off++];
-    TEST_IF_FF(c3);
-    mCurr = (mCurr << 24) | (c<<16) | (c2<<8) | c3;
-    mLeft += 24;
+  __inline void skipBitsNoFill(unsigned int nbits) {
+    mLeft -= nbits;
   }
 
-#undef TEST_IF_FF
+  __inline unsigned char getByte() {
+    fill();
+    mLeft-=8;
+    int shift = mLeft;
+    uint32 ret = *(uint32*)&current_buffer[shift>>3];
+    ret >>= shift & 7;
+    return ret & 0xff;
+  }
 
   virtual ~BitPumpJPEG(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
   uint32 stuffed;              // How many bytes has been stuffed?
 private:
 };
 
 } // namespace RawSpeed
-
-#endif
+
+#endif//BIT_PUMP_JPEG_H


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

Reply via email to