From 4a8037d66ee16a992604fb5c6830cdda169fcb0c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 27 May 2013 02:04:54 +0000 Subject: [PATCH] - Move bitdepth check outside the loop for grayscale unpacking. Also, don't use a multiply for 1-bit pixels. Use a lookup table for 2-bit pixels, because it's probably faster than a bunch of shifts and register juggling. SVN r4291 (trunk) --- src/m_png.cpp | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/m_png.cpp b/src/m_png.cpp index 1e1a331af..2bec48103 100644 --- a/src/m_png.cpp +++ b/src/m_png.cpp @@ -1162,6 +1162,8 @@ static void UnpackPixels (int width, int bytesPerRow, int bitdepth, const BYTE * BYTE pack; int lastbyte; + assert(bitdepth == 1 || bitdepth == 2 || bitdepth == 4); + out = rowout + width; in = rowin + bytesPerRow; @@ -1243,25 +1245,42 @@ static void UnpackPixels (int width, int bytesPerRow, int bitdepth, const BYTE * break; } - // Expand gray scale to 8bpp - if(grayscale) + // Expand grayscale to 8bpp + if (grayscale) { - out = rowout + width; - while(--out >= rowout) + // Put the 2-bit lookup table on the stack, since it's probably already + // in a cache line. + union { - switch(bitdepth) + uint32 bits2l; + BYTE bits2[4]; + }; + + out = rowout + width; + switch (bitdepth) + { + case 1: + while (--out >= rowout) { - case 1: - *out *= 0xFF; - break; - case 2: - *out |= (*out<<2)|(*out<<4)|(*out<<6); - break; - case 4: - *out |= (*out<<4); - break; - default: break; + // 1 becomes -1 (0xFF), and 0 remains untouched. + *out = 0 - *out; } + break; + + case 2: + bits2l = MAKE_ID(0x00,0x55,0xAA,0xFF); + while (--out >= rowout) + { + *out = bits2[*out]; + } + break; + + case 4: + while (--out >= rowout) + { + *out |= (*out << 4); + } + break; } } }