#include <stdio.h>
#include <stdlib.h>
#include <algorithm>

#define DC_IDX  1
#define HOR_IDX 10
#define VER_IDX 26

static const int intraFilterThreshold[5] =
{
    10, //4x4
    7,  //8x8
    1,  //16x16
    0,  //32x32
    10, //64x64
};

int filteringIntraReferenceSamples(int dirMode, int log2TrSize)
{
    bool bFilter;

    if (dirMode == DC_IDX || log2TrSize <= 2)
    {
        bFilter = false; // no smoothing for DC
    }
    else
    {
        int diff = std::min<int>(abs((int)dirMode - HOR_IDX), abs((int)dirMode - VER_IDX));
        int sizeIdx = log2TrSize - 2;
        bFilter = diff > intraFilterThreshold[sizeIdx];
    }

    return bFilter;
}

unsigned char IntraFilterType[][35] =
{
    //  Index:    0, 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
    /*  4x4  */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    /*  8x8  */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    /* 16x16 */ { 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
    /* 32x32 */ { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
    /* 64x64 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};


int main()
{
    for(int size=2; size<=5; size++)
    {
        for(int mode=0; mode<=34; mode++)
        {
            int x0 = filteringIntraReferenceSamples(mode, size);
            int x1 = IntraFilterType[size-2][mode];

            if (x0 != x1)
            {
                printf("Mistake at size %dx%d, mode %d\n", (1 << size), mode);
            }
        }
    }

    return 0;
}
