[Rawstudio-commit] rawspeed r165 - RawSpeed
Klaus Post
klauspost at gmail.com
Tue Nov 3 17:52:46 CET 2009
Author: post
Date: 2009-11-03 17:52:46 +0100 (Tue, 03 Nov 2009)
New Revision: 165
Modified:
RawSpeed/BitPumpMSB.cpp
RawSpeed/BitPumpMSB.h
RawSpeed/OrfDecoder.cpp
Log:
- Unrolled ORF decoder. Approx 5% speedup.
- Inlined Bitpump.
Modified: RawSpeed/BitPumpMSB.cpp
===================================================================
--- RawSpeed/BitPumpMSB.cpp 2009-10-29 16:14:00 UTC (rev 164)
+++ RawSpeed/BitPumpMSB.cpp 2009-11-03 16:52:46 UTC (rev 165)
@@ -40,7 +40,7 @@
init();
}
-void __inline BitPumpMSB::init() {
+__inline void BitPumpMSB::init() {
for (int i = 0; i < 31; i++) {
masks[i] = (1 << i) - 1;
}
@@ -48,7 +48,7 @@
fill();
}
-void BitPumpMSB::fill() {
+__inline void BitPumpMSB::fill() {
guchar c;
while (mLeft < MIN_GET_BITS) {
@@ -59,51 +59,7 @@
}
}
-guint BitPumpMSB::getBit() {
- if (!mLeft) fill();
- return (mCurr >> (--mLeft)) & 1;
-}
-
-guint BitPumpMSB::getBits(guint nbits) {
- if (mLeft < nbits) {
- if (nbits>24)
- throw IOException("Invalid data, attempting to read more than 24 bits.");
-
- fill();
- }
-
- return ((mCurr >> (mLeft -= (nbits)))) & masks[nbits];
-}
-
-guint BitPumpMSB::peekBit() {
- if (!mLeft) fill();
-
- return (mCurr >> (mLeft - 1)) & 1;
-}
-
-guint BitPumpMSB::peekBits(guint nbits) {
- if (mLeft < nbits) {
- if (nbits>24)
- throw IOException("Invalid data, attempting to read more than 24 bits.");
-
- fill();
- }
-
- return ((mCurr >> (mLeft - nbits))) & masks[nbits];
-}
-
-guint BitPumpMSB::peekByte() {
- if (mLeft < 8) {
- fill();
- }
-
- if (off > size)
- throw IOException("Out of buffer read");
-
- return ((mCurr >> (mLeft - 8))) & 0xff;
-}
-
guint BitPumpMSB::getBitSafe() {
if (!mLeft) {
fill();
@@ -129,29 +85,7 @@
return ((mCurr >> (mLeft -= (nbits)))) & masks[nbits];
}
-void BitPumpMSB::skipBits(unsigned int nbits) {
- if (mLeft < nbits) {
- fill();
- if (off > size)
- throw IOException("Out of buffer read");
- }
-
- mLeft -= nbits;
-}
-
-void BitPumpMSB::skipBitsNoFill(unsigned int nbits) {
- mLeft -= nbits;
-}
-
-unsigned char BitPumpMSB::getByte() {
- if (mLeft < 8) {
- fill();
- }
-
- return ((mCurr >> (mLeft -= 8))) & 0xff;
-}
-
unsigned char BitPumpMSB::getByteSafe() {
if (mLeft < 8) {
fill();
Modified: RawSpeed/BitPumpMSB.h
===================================================================
--- RawSpeed/BitPumpMSB.h 2009-10-29 16:14:00 UTC (rev 164)
+++ RawSpeed/BitPumpMSB.h 2009-11-03 16:52:46 UTC (rev 165)
@@ -31,27 +31,86 @@
public:
BitPumpMSB(ByteStream *s);
BitPumpMSB(const guchar* _buffer, guint _size );
- guint getBits(guint nbits);
- guint getBit();
guint getBitsSafe(guint nbits);
guint getBitSafe();
- guint peekBits(guint nbits);
- guint peekBit();
- guint peekByte();
- void skipBits(guint nbits);
- void skipBitsNoFill(guint nbits);
- __inline void checkPos() { if (off>size) throw IOException("Out of buffer read");}; // Check if we have a valid position
- guchar getByte();
guchar getByteSafe();
void setAbsoluteOffset(guint offset); // Set offset in bytes
- guint getOffset() { return off-(mLeft>>3);}
+ __inline guint 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 guint getBitNoFill() {return (mCurr >> (--mLeft)) & 1;}
__inline guint peekByteNoFill() {return ((mCurr >> (mLeft-8))) & 0xff; }
__inline guint getBitsNoFill(guint nbits) {return ((mCurr >> (mLeft -= (nbits)))) & masks[nbits];}
__inline guint peekBitsNoFill(guint nbits) {return ((mCurr >> (mLeft-nbits))) &masks[nbits]; }
- void fill(); // Fill the buffer with at least 24 bits
+ __inline void fill(); // Fill the buffer with at least 24 bits
+ __inline guint BitPumpMSB::getBit() {
+ if (!mLeft) fill();
+ return (mCurr >> (--mLeft)) & 1;
+ }
+
+ __inline guint BitPumpMSB::getBits(guint nbits) {
+ if (mLeft < nbits) {
+ if (nbits>24)
+ throw IOException("Invalid data, attempting to read more than 24 bits.");
+
+ fill();
+ }
+
+ return ((mCurr >> (mLeft -= (nbits)))) & masks[nbits];
+ }
+
+ __inline guint BitPumpMSB::peekBit() {
+ if (!mLeft) fill();
+
+ return (mCurr >> (mLeft - 1)) & 1;
+ }
+
+ __inline guint BitPumpMSB::peekBits(guint nbits) {
+ if (mLeft < nbits) {
+ if (nbits>24)
+ throw IOException("Invalid data, attempting to read more than 24 bits.");
+
+ fill();
+ }
+
+ return ((mCurr >> (mLeft - nbits))) & masks[nbits];
+ }
+
+ __inline guint BitPumpMSB::peekByte() {
+ if (mLeft < 8) {
+ fill();
+ }
+
+ if (off > size)
+ throw IOException("Out of buffer read");
+
+ return ((mCurr >> (mLeft - 8))) & 0xff;
+ }
+
+ __inline void BitPumpMSB::skipBits(unsigned int nbits) {
+ if (mLeft < nbits) {
+ fill();
+
+ if (off > size)
+ throw IOException("Out of buffer read");
+ }
+
+ mLeft -= nbits;
+ }
+
+ __inline void BitPumpMSB::skipBitsNoFill(unsigned int nbits) {
+ mLeft -= nbits;
+ }
+
+ __inline unsigned char BitPumpMSB::getByte() {
+ if (mLeft < 8) {
+ fill();
+ }
+
+ return ((mCurr >> (mLeft -= 8))) & 0xff;
+ }
+
virtual ~BitPumpMSB(void);
protected:
void __inline init();
Modified: RawSpeed/OrfDecoder.cpp
===================================================================
--- RawSpeed/OrfDecoder.cpp 2009-10-29 16:14:00 UTC (rev 164)
+++ RawSpeed/OrfDecoder.cpp 2009-11-03 16:52:46 UTC (rev 165)
@@ -104,8 +104,8 @@
*/
void OrfDecoder::decodeCompressed(ByteStream& s, guint w, guint h) {
- int nbits, sign, low, high, i, wo, n, nw;
- int acarry[2][3], *carry, pred, diff;
+ int nbits, sign, low, high, i, wo0, n, nw0, wo1, nw1;
+ int acarry0[3], acarry1[3], pred, diff;
guchar* data = mRaw->getData();
gint pitch = mRaw->pitch;
@@ -119,19 +119,20 @@
break;
bittable[i] = high;
}
-
+ wo0 = nw0 = wo1 = nw1 = 0;
s.skipBytes(7);
BitPumpMSB bits(&s);
for (guint y = 0; y < h; y++) {
- memset(acarry, 0, sizeof acarry);
+ memset(acarry0, 0, sizeof acarry0);
+ memset(acarry1, 0, sizeof acarry1);
gushort* dest = (gushort*) & data[y*pitch];
for (guint x = 0; x < w; x++) {
bits.checkPos();
bits.fill();
- carry = acarry[x & 1];
- i = 2 * (carry[2] < 3);
- for (nbits = 2 + i; (gushort) carry[0] >> (nbits + i); nbits++);
+ i = 2 * (acarry0[2] < 3);
+ for (nbits = 2 + i; (gushort) acarry0[0] >> (nbits + i); nbits++);
+
int b = bits.peekBitsNoFill(15);
sign = (b >> 14) * -1;
low = (b >> 12) & 3;
@@ -141,25 +142,91 @@
if (high == 12)
high = bits.getBits(16 - nbits) >> 1;
- carry[0] = (high << nbits) | bits.getBits(nbits);
- diff = (carry[0] ^ sign) + carry[1];
- carry[1] = (diff * 3 + carry[1]) >> 5;
- carry[2] = carry[0] > 16 ? 0 : carry[2] + 1;
- if (y < 2 && x < 2) pred = 0;
- else if (y < 2) pred = dest[x-2];
- else if (x < 2) pred = dest[-pitch+((gint)x)]; // Pitch is in bytes, and dest is in short, so we skip two lines
- else {
- wo = dest[x-2];
+
+ acarry0[0] = (high << nbits) | bits.getBits(nbits);
+ diff = (acarry0[0] ^ sign) + acarry0[1];
+ acarry0[1] = (diff * 3 + acarry0[1]) >> 5;
+ acarry0[2] = acarry0[0] > 16 ? 0 : acarry0[2] + 1;
+
+ if (y < 2 || x < 2) {
+ if (y < 2 && x < 2)
+ pred = 0;
+ else if (y < 2)
+ pred = wo0;
+ else {
+ pred = dest[-pitch+((gint)x)];
+ nw0 = pred;
+ }
+ dest[x] = pred + ((diff << 2) | low);
+ // Set predictor
+ wo0 = dest[x];
+ } else {
n = dest[-pitch+((gint)x)];
- nw = dest[-pitch+((gint)x)-2];
- if ((wo < nw && nw < n) || (n < nw && nw < wo)) {
- if (abs(wo - nw) > 32 || abs(n - nw) > 32)
- pred = wo + n - nw;
- else pred = (wo + n) >> 1;
- } else pred = abs(wo - nw) > abs(n - nw) ? wo : n;
+ if (((wo0 < nw0) & (nw0 < n)) | ((n < nw0) & (nw0 < wo0))) {
+ if (abs(wo0 - nw0) > 32 || abs(n - nw0) > 32)
+ pred = wo0 + n - nw0;
+ else
+ pred = (wo0 + n) >> 1;
+ } else
+ pred = abs(wo0 - nw0) > abs(n - nw0) ? wo0 : n;
+
+ dest[x] = pred + ((diff << 2) | low);
+ // Set predictors
+ wo0 = dest[x];
+ nw0 = n;
}
- dest[x] = pred + ((diff << 2) | low);
_ASSERTE(0 == dest[x] >> 12) ;
+
+ // ODD PIXELS
+ x += 1;
+ bits.checkPos();
+ bits.fill();
+ i = 2 * (acarry1[2] < 3);
+ for (nbits = 2 + i; (gushort) acarry1[0] >> (nbits + i); nbits++);
+ b = bits.peekBitsNoFill(15);
+ sign = (b >> 14) * -1;
+ low = (b >> 12) & 3;
+ high = bittable[b&4095];
+ // Skip bits used above.
+ bits.skipBitsNoFill(min(12+3, high + 1 + 3));
+
+ if (high == 12)
+ high = bits.getBits(16 - nbits) >> 1;
+
+ acarry1[0] = (high << nbits) | bits.getBits(nbits);
+ diff = (acarry1[0] ^ sign) + acarry1[1];
+ acarry1[1] = (diff * 3 + acarry1[1]) >> 5;
+ acarry1[2] = acarry1[0] > 16 ? 0 : acarry1[2] + 1;
+
+ if (y < 2 || x < 2) {
+ if (y < 2 && x < 2)
+ pred = 0;
+ else if (y < 2)
+ pred = wo1;
+ else {
+ pred = dest[-pitch+((gint)x)];
+ nw1 = pred;
+ }
+ dest[x] = pred + ((diff << 2) | low);
+ // Set predictor
+ wo1 = dest[x];
+ } else {
+ n = dest[-pitch+((gint)x)];
+ if (((wo1 < nw1) & (nw1 < n)) | ((n < nw1) & (nw1 < wo1))) {
+ if (abs(wo1 - nw1) > 32 || abs(n - nw1) > 32)
+ pred = wo1 + n - nw1;
+ else
+ pred = (wo1 + n) >> 1;
+ } else
+ pred = abs(wo1 - nw1) > abs(n - nw1) ? wo1 : n;
+
+ dest[x] = pred + ((diff << 2) | low);
+
+ // Set predictors
+ wo1 = dest[x];
+ nw1 = n;
+ }
+ _ASSERTE(0 == dest[x] >> 12) ;
}
}
}
More information about the Rawstudio-commit
mailing list