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*)¤t_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*)¤t_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*)¤t_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