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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
#include "quality-quantizer.hpp"
#include <cctype>
static void setLookupTable(int tbl[256], int const value, unsigned const start = 0, unsigned const end = 256)
{
for (unsigned i = start; i < end; ++i) {
tbl[i] = value;
}
}
static void clearLookupTable(int tbl[256])
{
setLookupTable(tbl, -1);
}
static bool initLookupTable(int tbl[256], char const quant[])
{
unsigned i = 0;
unsigned limit = 0;
int value = -1;
int ws = 1;
int st = 0;
clearLookupTable(tbl);
for (unsigned cur = 0; quant[cur] != 0; ++cur) {
int const ch = quant[cur];
if (ws) {
if (isspace(ch))
continue;
ws = false;
}
switch (st) {
case 0:
if (isdigit(ch)) {
value = (value * 10) + ch - '0';
break;
}
else if (isspace(ch)) {
++st;
ws = true;
break;
}
++st;
/* no break */
case 1:
if (ch != ':')
return false;
ws = true;
++st;
break;
case 2:
if (isdigit(ch)) {
limit = (limit * 10) + ch - '0';
break;
}
else if (isspace(ch)) {
++st;
ws = true;
break;
}
else if (ch == '-' && limit == 0) {
setLookupTable(tbl, value, i);
return true;
}
++st;
/* no break */
case 3:
if (ch != ',')
return false;
ws = true;
st = 0;
if (i > limit)
return false;
setLookupTable(tbl, value, i, limit);
i = limit;
limit = value = 0;
break;
}
}
if (st == 0) {
switch (value) {
case 0:
for (unsigned i = 0; i < 256; ++i) {
tbl[i] = i;
}
return true;
case 1:
setLookupTable(tbl, 1, 0, 10);
setLookupTable(tbl, 10, 10, 20);
setLookupTable(tbl, 20, 20, 30);
setLookupTable(tbl, 30, 30);
return true;
case 2:
setLookupTable(tbl, 1, 0, 30);
setLookupTable(tbl, 30, 30);
return true;
}
}
return false;
}
QualityQuantizer::QualityQuantizer(char const spec[])
{
if (!initLookupTable(lookup, spec))
clearLookupTable(lookup);
}
|