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