1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#include "Quantize.h"
#include <assert.h>
#include <math.h>
using namespace Sexy;
bool Sexy::Quantize8Bit(const uint32_t* theSrcBits, int theWidth, int theHeight, uchar* theDestColorIndices, uint32_t* theDestColorTable)
{
int aSize = theWidth*theHeight;
int aColorTableSize = 0;
uint32_t aSearchTable[256];
uchar aTranslationTable[256]; // From search table to color table
if (aSize > 0)
{
aSearchTable[0] = theSrcBits[0];
theDestColorTable[0] = theSrcBits[0];
aTranslationTable[0] = 0;
theDestColorIndices[0] = 0;
aColorTableSize++;
}
for (int anIdx = 1; anIdx < aSize; anIdx++)
{
uint32_t aColor = theSrcBits[anIdx];
int aLeftPos = 0;
int aRightPos = aColorTableSize-1;
int aMiddlePos = (aLeftPos+aRightPos)/2;
for (;;)
{
uint32_t aCheckColor = aSearchTable[aMiddlePos];
if (aColor < aCheckColor)
aRightPos = aMiddlePos - 1;
else if (aColor > aCheckColor)
aLeftPos = aMiddlePos + 1;
else
{
theDestColorIndices[anIdx] = aTranslationTable[aMiddlePos];
break;
}
if (aLeftPos > aRightPos)
{
if (aColorTableSize >= 256)
return false;
int anInsertPos = aLeftPos;
if ((anInsertPos < aColorTableSize) && (aColor > aSearchTable[anInsertPos]))
anInsertPos++;
// Insert color into the table
memmove(aSearchTable+anInsertPos+1, aSearchTable+anInsertPos, (aColorTableSize-anInsertPos) * sizeof(uint32_t));
aSearchTable[anInsertPos] = aColor;
memmove(aTranslationTable+anInsertPos+1, aTranslationTable+anInsertPos, (aColorTableSize-anInsertPos) * sizeof(uchar));
aTranslationTable[anInsertPos] = aColorTableSize;
theDestColorTable[aColorTableSize] = aColor;
theDestColorIndices[anIdx] = aColorTableSize;
aColorTableSize++;
break;
}
aMiddlePos = (aLeftPos+aRightPos)/2;
}
}
return true;
}
|