dsp.h 7.78 KB
Newer Older
wester committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
//   Speed-critical functions.
//
// Author: Skal (pascal.massimino@gmail.com)

#ifndef WEBP_DSP_DSP_H_
#define WEBP_DSP_DSP_H_

#include "../webp/types.h"

a  
Kai Westerkamp committed
19
#if defined(__cplusplus) || defined(c_plusplus)
wester committed
20 21 22 23 24 25
extern "C" {
#endif

//------------------------------------------------------------------------------
// CPU detection

a  
Kai Westerkamp committed
26
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
wester committed
27 28 29
#define WEBP_MSC_SSE2  // Visual C++ SSE2 targets
#endif

a  
Kai Westerkamp committed
30
#if defined(__SSE2__) || defined(WEBP_MSC_SSE2)
wester committed
31 32 33 34 35 36 37
#define WEBP_USE_SSE2
#endif

#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
#define WEBP_ANDROID_NEON  // Android targets that might support NEON
#endif

a  
Kai Westerkamp committed
38
#if defined(__ARM_NEON__) || defined(WEBP_ANDROID_NEON)
wester committed
39 40 41 42 43 44
#define WEBP_USE_NEON
#endif

typedef enum {
  kSSE2,
  kSSE3,
a  
Kai Westerkamp committed
45
  kNEON
wester committed
46 47 48
} CPUFeature;
// returns true if the CPU supports the feature.
typedef int (*VP8CPUInfo)(CPUFeature feature);
a  
Kai Westerkamp committed
49
extern VP8CPUInfo VP8GetCPUInfo;
wester committed
50 51 52 53 54 55 56 57 58 59 60 61 62

//------------------------------------------------------------------------------
// Encoding

// Transforms
// VP8Idct: Does one of two inverse transforms. If do_two is set, the transforms
//          will be done for (ref, in, dst) and (ref + 4, in + 16, dst + 4).
typedef void (*VP8Idct)(const uint8_t* ref, const int16_t* in, uint8_t* dst,
                        int do_two);
typedef void (*VP8Fdct)(const uint8_t* src, const uint8_t* ref, int16_t* out);
typedef void (*VP8WHT)(const int16_t* in, int16_t* out);
extern VP8Idct VP8ITransform;
extern VP8Fdct VP8FTransform;
a  
Kai Westerkamp committed
63
extern VP8WHT VP8ITransformWHT;
wester committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
extern VP8WHT VP8FTransformWHT;
// Predictions
// *dst is the destination block. *top and *left can be NULL.
typedef void (*VP8IntraPreds)(uint8_t *dst, const uint8_t* left,
                              const uint8_t* top);
typedef void (*VP8Intra4Preds)(uint8_t *dst, const uint8_t* top);
extern VP8Intra4Preds VP8EncPredLuma4;
extern VP8IntraPreds VP8EncPredLuma16;
extern VP8IntraPreds VP8EncPredChroma8;

typedef int (*VP8Metric)(const uint8_t* pix, const uint8_t* ref);
extern VP8Metric VP8SSE16x16, VP8SSE16x8, VP8SSE8x8, VP8SSE4x4;
typedef int (*VP8WMetric)(const uint8_t* pix, const uint8_t* ref,
                          const uint16_t* const weights);
extern VP8WMetric VP8TDisto4x4, VP8TDisto16x16;

typedef void (*VP8BlockCopy)(const uint8_t* src, uint8_t* dst);
extern VP8BlockCopy VP8Copy4x4;
// Quantization
struct VP8Matrix;   // forward declaration
typedef int (*VP8QuantizeBlock)(int16_t in[16], int16_t out[16],
a  
Kai Westerkamp committed
85
                                int n, const struct VP8Matrix* const mtx);
wester committed
86 87
extern VP8QuantizeBlock VP8EncQuantizeBlock;

a  
Kai Westerkamp committed
88 89
// Collect histogram for susceptibility calculation and accumulate in histo[].
struct VP8Histogram;
wester committed
90 91
typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
                          int start_block, int end_block,
a  
Kai Westerkamp committed
92 93
                          struct VP8Histogram* const histo);
extern const int VP8DspScan[16 + 4 + 4];
wester committed
94 95
extern VP8CHisto VP8CollectHistogram;

a  
Kai Westerkamp committed
96
void VP8EncDspInit(void);   // must be called before using any of the above
wester committed
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

//------------------------------------------------------------------------------
// Decoding

typedef void (*VP8DecIdct)(const int16_t* coeffs, uint8_t* dst);
// when doing two transforms, coeffs is actually int16_t[2][16].
typedef void (*VP8DecIdct2)(const int16_t* coeffs, uint8_t* dst, int do_two);
extern VP8DecIdct2 VP8Transform;
extern VP8DecIdct VP8TransformUV;
extern VP8DecIdct VP8TransformDC;
extern VP8DecIdct VP8TransformDCUV;
extern VP8WHT VP8TransformWHT;

// *dst is the destination block, with stride BPS. Boundary samples are
// assumed accessible when needed.
typedef void (*VP8PredFunc)(uint8_t* dst);
a  
Kai Westerkamp committed
113 114 115
extern const VP8PredFunc VP8PredLuma16[/* NUM_B_DC_MODES */];
extern const VP8PredFunc VP8PredChroma8[/* NUM_B_DC_MODES */];
extern const VP8PredFunc VP8PredLuma4[/* NUM_BMODES */];
wester committed
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

// simple filter (only for luma)
typedef void (*VP8SimpleFilterFunc)(uint8_t* p, int stride, int thresh);
extern VP8SimpleFilterFunc VP8SimpleVFilter16;
extern VP8SimpleFilterFunc VP8SimpleHFilter16;
extern VP8SimpleFilterFunc VP8SimpleVFilter16i;  // filter 3 inner edges
extern VP8SimpleFilterFunc VP8SimpleHFilter16i;

// regular filter (on both macroblock edges and inner edges)
typedef void (*VP8LumaFilterFunc)(uint8_t* luma, int stride,
                                  int thresh, int ithresh, int hev_t);
typedef void (*VP8ChromaFilterFunc)(uint8_t* u, uint8_t* v, int stride,
                                    int thresh, int ithresh, int hev_t);
// on outer edge
extern VP8LumaFilterFunc VP8VFilter16;
extern VP8LumaFilterFunc VP8HFilter16;
extern VP8ChromaFilterFunc VP8VFilter8;
extern VP8ChromaFilterFunc VP8HFilter8;

// on inner edge
extern VP8LumaFilterFunc VP8VFilter16i;   // filtering 3 inner edges altogether
extern VP8LumaFilterFunc VP8HFilter16i;
extern VP8ChromaFilterFunc VP8VFilter8i;  // filtering u and v altogether
extern VP8ChromaFilterFunc VP8HFilter8i;

// must be called before anything using the above
void VP8DspInit(void);

//------------------------------------------------------------------------------
// WebP I/O

#define FANCY_UPSAMPLING   // undefined to remove fancy upsampling support

typedef void (*WebPUpsampleLinePairFunc)(
    const uint8_t* top_y, const uint8_t* bottom_y,
    const uint8_t* top_u, const uint8_t* top_v,
    const uint8_t* cur_u, const uint8_t* cur_v,
    uint8_t* top_dst, uint8_t* bottom_dst, int len);

#ifdef FANCY_UPSAMPLING

// Fancy upsampling functions to convert YUV to RGB(A) modes
extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];

a  
Kai Westerkamp committed
160 161 162 163 164 165
// Initializes SSE2 version of the fancy upsamplers.
void WebPInitUpsamplersSSE2(void);

// NEON version
void WebPInitUpsamplersNEON(void);

wester committed
166 167
#endif    // FANCY_UPSAMPLING

a  
Kai Westerkamp committed
168 169 170 171 172
// Point-sampling methods.
typedef void (*WebPSampleLinePairFunc)(
    const uint8_t* top_y, const uint8_t* bottom_y,
    const uint8_t* u, const uint8_t* v,
    uint8_t* top_dst, uint8_t* bottom_dst, int len);
wester committed
173

a  
Kai Westerkamp committed
174
extern const WebPSampleLinePairFunc WebPSamplers[/* MODE_LAST */];
wester committed
175 176 177 178 179 180 181 182 183 184 185

// General function for converting two lines of ARGB or RGBA.
// 'alpha_is_last' should be true if 0xff000000 is stored in memory as
// as 0x00, 0x00, 0x00, 0xff (little endian).
WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last);

// YUV444->RGB converters
typedef void (*WebPYUV444Converter)(const uint8_t* y,
                                    const uint8_t* u, const uint8_t* v,
                                    uint8_t* dst, int len);

a  
Kai Westerkamp committed
186
extern const WebPYUV444Converter WebPYUV444Converters[/* MODE_LAST */];
wester committed
187

a  
Kai Westerkamp committed
188
// Main function to be called
wester committed
189 190 191
void WebPInitUpsamplers(void);

//------------------------------------------------------------------------------
a  
Kai Westerkamp committed
192
// Pre-multiply planes with alpha values
wester committed
193 194 195 196 197 198 199 200 201 202 203

// Apply alpha pre-multiply on an rgba, bgra or argb plane of size w * h.
// alpha_first should be 0 for argb, 1 for rgba or bgra (where alpha is last).
extern void (*WebPApplyAlphaMultiply)(
    uint8_t* rgba, int alpha_first, int w, int h, int stride);

// Same, buf specifically for RGBA4444 format
extern void (*WebPApplyAlphaMultiply4444)(
    uint8_t* rgba4444, int w, int h, int stride);

// To be called first before using the above.
a  
Kai Westerkamp committed
204
void WebPInitPremultiply(void);
wester committed
205

a  
Kai Westerkamp committed
206 207
void WebPInitPremultiplySSE2(void);   // should not be called directly.
void WebPInitPremultiplyNEON(void);
wester committed
208 209 210

//------------------------------------------------------------------------------

a  
Kai Westerkamp committed
211
#if defined(__cplusplus) || defined(c_plusplus)
wester committed
212 213 214 215
}    // extern "C"
#endif

#endif  /* WEBP_DSP_DSP_H_ */