/*
 * Copyright 2008 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkFilter_DEFINED
#define SkFilter_DEFINED

#include "SkMath.h"
#include "SkFixed.h"

typedef unsigned (*SkFilterProc)(unsigned x00, unsigned x01,
                                 unsigned x10, unsigned x11);

const SkFilterProc* SkGetBilinearFilterProcTable();

inline SkFilterProc SkGetBilinearFilterProc(const SkFilterProc* table,
                                            SkFixed x, SkFixed y)
{
    SkASSERT(table);

    // convert to dot 2
    x = (unsigned)(x << 16) >> 30;
    y = (unsigned)(y << 16) >> 30;
    return table[(y << 2) | x];
}

inline SkFilterProc SkGetBilinearFilterProc22(const SkFilterProc* table,
                                              unsigned x, unsigned y)
{
    SkASSERT(table);

    // extract low 2 bits
    x = x << 30 >> 30;
    y = y << 30 >> 30;
    return table[(y << 2) | x];
}

inline const SkFilterProc* SkGetBilinearFilterProc22Row(const SkFilterProc* table,
                                                        unsigned y)
{
    SkASSERT(table);
    // extract low 2 bits and shift up 2
    return &table[y << 30 >> 28];
}

inline SkFilterProc SkGetBilinearFilterProc22RowProc(const SkFilterProc* row,
                                                     unsigned x)
{
    SkASSERT(row);
    // extract low 2 bits
    return row[x << 30 >> 30];
}

///////////////////////////////////////////////////////////////////////////////

typedef unsigned (*SkFilter32Proc)(uint32_t x00, uint32_t x01,
                                   uint32_t x10, uint32_t x11);

const SkFilter32Proc* SkGetFilter32ProcTable();

inline SkFilter32Proc SkGetFilter32Proc22(const SkFilter32Proc* table,
                                          unsigned x, unsigned y)
{
    SkASSERT(table);

    // extract low 2 bits
    x = x << 30 >> 30;
    y = y << 30 >> 30;
    return table[(y << 2) | x];
}

inline const SkFilter32Proc* SkGetFilter32Proc22Row(const SkFilter32Proc* table,
                                                    unsigned y)
{
    SkASSERT(table);
    // extract low 2 bits and shift up 2
    return &table[y << 30 >> 28];
}

inline SkFilter32Proc SkGetFilter32Proc22RowProc(const SkFilter32Proc* row,
                                                 unsigned x)
{
    SkASSERT(row);
    // extract low 2 bits
    return row[x << 30 >> 30];
}

///////////////////////////////////////////////////////////////////////////////

/** Special version of SkFilterProc. This takes the address of 4 ints, and combines them a byte at a
    time. AABBCCDD.
*/
typedef uint32_t (*SkFilterPtrProc)(const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);

const SkFilterPtrProc* SkGetBilinearFilterPtrProcTable();
inline SkFilterPtrProc SkGetBilinearFilterPtrProc(const SkFilterPtrProc* table, SkFixed x, SkFixed y)
{
    SkASSERT(table);

    // convert to dot 2
    x = (unsigned)(x << 16) >> 30;
    y = (unsigned)(y << 16) >> 30;
    return table[(y << 2) | x];
}

/** Given a Y value, return a subset of the proc table for that value.
    Pass this to SkGetBilinearFilterPtrXProc with the corresponding X value to get the
    correct proc.
*/
inline const SkFilterPtrProc* SkGetBilinearFilterPtrProcYTable(const SkFilterPtrProc* table, SkFixed y)
{
    SkASSERT(table);

    y = (unsigned)(y << 16) >> 30;
    return table + (y << 2);
}

/** Given a subtable returned by SkGetBilinearFilterPtrProcYTable(), return the proc for the
    specified X value.
*/
inline SkFilterPtrProc SkGetBilinearFilterPtrXProc(const SkFilterPtrProc* table, SkFixed x)
{
    SkASSERT(table);

    // convert to dot 2
    x = (unsigned)(x << 16) >> 30;
    return table[x];
}

#endif
