180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2008 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkFilter_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkFilter_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMath.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFixed.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef unsigned (*SkFilterProc)(unsigned x00, unsigned x01,
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 unsigned x10, unsigned x11);
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkFilterProc* SkGetBilinearFilterProcTable();
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline SkFilterProc SkGetBilinearFilterProc(const SkFilterProc* table,
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                            SkFixed x, SkFixed y)
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // convert to dot 2
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = (unsigned)(x << 16) >> 30;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    y = (unsigned)(y << 16) >> 30;
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return table[(y << 2) | x];
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline SkFilterProc SkGetBilinearFilterProc22(const SkFilterProc* table,
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                              unsigned x, unsigned y)
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // extract low 2 bits
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = x << 30 >> 30;
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    y = y << 30 >> 30;
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return table[(y << 2) | x];
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline const SkFilterProc* SkGetBilinearFilterProc22Row(const SkFilterProc* table,
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                        unsigned y)
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // extract low 2 bits and shift up 2
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return &table[y << 30 >> 28];
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline SkFilterProc SkGetBilinearFilterProc22RowProc(const SkFilterProc* row,
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                     unsigned x)
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(row);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // extract low 2 bits
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return row[x << 30 >> 30];
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef unsigned (*SkFilter32Proc)(uint32_t x00, uint32_t x01,
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   uint32_t x10, uint32_t x11);
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkFilter32Proc* SkGetFilter32ProcTable();
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline SkFilter32Proc SkGetFilter32Proc22(const SkFilter32Proc* table,
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                          unsigned x, unsigned y)
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // extract low 2 bits
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = x << 30 >> 30;
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    y = y << 30 >> 30;
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return table[(y << 2) | x];
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline const SkFilter32Proc* SkGetFilter32Proc22Row(const SkFilter32Proc* table,
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    unsigned y)
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // extract low 2 bits and shift up 2
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return &table[y << 30 >> 28];
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline SkFilter32Proc SkGetFilter32Proc22RowProc(const SkFilter32Proc* row,
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 unsigned x)
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(row);
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // extract low 2 bits
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return row[x << 30 >> 30];
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Special version of SkFilterProc. This takes the address of 4 ints, and combines them a byte at a
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    time. AABBCCDD.
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef uint32_t (*SkFilterPtrProc)(const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkFilterPtrProc* SkGetBilinearFilterPtrProcTable();
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline SkFilterPtrProc SkGetBilinearFilterPtrProc(const SkFilterPtrProc* table, SkFixed x, SkFixed y)
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // convert to dot 2
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = (unsigned)(x << 16) >> 30;
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    y = (unsigned)(y << 16) >> 30;
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return table[(y << 2) | x];
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Given a Y value, return a subset of the proc table for that value.
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Pass this to SkGetBilinearFilterPtrXProc with the corresponding X value to get the
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    correct proc.
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline const SkFilterPtrProc* SkGetBilinearFilterPtrProcYTable(const SkFilterPtrProc* table, SkFixed y)
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    y = (unsigned)(y << 16) >> 30;
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return table + (y << 2);
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Given a subtable returned by SkGetBilinearFilterPtrProcYTable(), return the proc for the
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    specified X value.
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline SkFilterPtrProc SkGetBilinearFilterPtrXProc(const SkFilterPtrProc* table, SkFixed x)
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(table);
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // convert to dot 2
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = (unsigned)(x << 16) >> 30;
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return table[x];
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
136