Blame src/dsp/filters_mips_dsp_r2.c

Packit 9c6abc
// Copyright 2014 Google Inc. All Rights Reserved.
Packit 9c6abc
//
Packit 9c6abc
// Use of this source code is governed by a BSD-style license
Packit 9c6abc
// that can be found in the COPYING file in the root of the source
Packit 9c6abc
// tree. An additional intellectual property rights grant can be found
Packit 9c6abc
// in the file PATENTS. All contributing project authors may
Packit 9c6abc
// be found in the AUTHORS file in the root of the source tree.
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
//
Packit 9c6abc
// Spatial prediction using various filters
Packit 9c6abc
//
Packit 9c6abc
// Author(s): Branimir Vasic (branimir.vasic@imgtec.com)
Packit 9c6abc
//            Djordje Pesut (djordje.pesut@imgtec.com)
Packit 9c6abc
Packit 9c6abc
#include "src/dsp/dsp.h"
Packit 9c6abc
Packit 9c6abc
#if defined(WEBP_USE_MIPS_DSP_R2)
Packit 9c6abc
Packit 9c6abc
#include "src/dsp/dsp.h"
Packit 9c6abc
#include <assert.h>
Packit 9c6abc
#include <stdlib.h>
Packit 9c6abc
#include <string.h>
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
// Helpful macro.
Packit 9c6abc
Packit 9c6abc
# define SANITY_CHECK(in, out)                                                 \
Packit 9c6abc
  assert(in != NULL);                                                          \
Packit 9c6abc
  assert(out != NULL);                                                         \
Packit 9c6abc
  assert(width > 0);                                                           \
Packit 9c6abc
  assert(height > 0);                                                          \
Packit 9c6abc
  assert(stride >= width);                                                     \
Packit 9c6abc
  assert(row >= 0 && num_rows > 0 && row + num_rows <= height);                \
Packit 9c6abc
  (void)height;  // Silence unused warning.
Packit 9c6abc
Packit 9c6abc
#define DO_PREDICT_LINE(SRC, DST, LENGTH, INVERSE) do {                        \
Packit 9c6abc
    const uint8_t* psrc = (uint8_t*)(SRC);                                     \
Packit 9c6abc
    uint8_t* pdst = (uint8_t*)(DST);                                           \
Packit 9c6abc
    const int ilength = (int)(LENGTH);                                         \
Packit 9c6abc
    int temp0, temp1, temp2, temp3, temp4, temp5, temp6;                       \
Packit 9c6abc
    __asm__ volatile (                                                         \
Packit 9c6abc
      ".set      push                                   \n\t"                  \
Packit 9c6abc
      ".set      noreorder                              \n\t"                  \
Packit 9c6abc
      "srl       %[temp0],    %[length],    2           \n\t"                  \
Packit 9c6abc
      "beqz      %[temp0],    4f                        \n\t"                  \
Packit 9c6abc
      " andi     %[temp6],    %[length],    3           \n\t"                  \
Packit 9c6abc
    ".if " #INVERSE "                                   \n\t"                  \
Packit 9c6abc
    "1:                                                 \n\t"                  \
Packit 9c6abc
      "lbu       %[temp1],    -1(%[dst])                \n\t"                  \
Packit 9c6abc
      "lbu       %[temp2],    0(%[src])                 \n\t"                  \
Packit 9c6abc
      "lbu       %[temp3],    1(%[src])                 \n\t"                  \
Packit 9c6abc
      "lbu       %[temp4],    2(%[src])                 \n\t"                  \
Packit 9c6abc
      "lbu       %[temp5],    3(%[src])                 \n\t"                  \
Packit 9c6abc
      "addu      %[temp1],    %[temp1],     %[temp2]    \n\t"                  \
Packit 9c6abc
      "addu      %[temp2],    %[temp1],     %[temp3]    \n\t"                  \
Packit 9c6abc
      "addu      %[temp3],    %[temp2],     %[temp4]    \n\t"                  \
Packit 9c6abc
      "addu      %[temp4],    %[temp3],     %[temp5]    \n\t"                  \
Packit 9c6abc
      "sb        %[temp1],    0(%[dst])                 \n\t"                  \
Packit 9c6abc
      "sb        %[temp2],    1(%[dst])                 \n\t"                  \
Packit 9c6abc
      "sb        %[temp3],    2(%[dst])                 \n\t"                  \
Packit 9c6abc
      "sb        %[temp4],    3(%[dst])                 \n\t"                  \
Packit 9c6abc
      "addiu     %[src],      %[src],       4           \n\t"                  \
Packit 9c6abc
      "addiu     %[temp0],    %[temp0],     -1          \n\t"                  \
Packit 9c6abc
      "bnez      %[temp0],    1b                        \n\t"                  \
Packit 9c6abc
      " addiu    %[dst],      %[dst],       4           \n\t"                  \
Packit 9c6abc
    ".else                                              \n\t"                  \
Packit 9c6abc
    "1:                                                 \n\t"                  \
Packit 9c6abc
      "ulw       %[temp1],    -1(%[src])                \n\t"                  \
Packit 9c6abc
      "ulw       %[temp2],    0(%[src])                 \n\t"                  \
Packit 9c6abc
      "addiu     %[src],      %[src],       4           \n\t"                  \
Packit 9c6abc
      "addiu     %[temp0],    %[temp0],     -1          \n\t"                  \
Packit 9c6abc
      "subu.qb   %[temp3],    %[temp2],     %[temp1]    \n\t"                  \
Packit 9c6abc
      "usw       %[temp3],    0(%[dst])                 \n\t"                  \
Packit 9c6abc
      "bnez      %[temp0],    1b                        \n\t"                  \
Packit 9c6abc
      " addiu    %[dst],      %[dst],       4           \n\t"                  \
Packit 9c6abc
    ".endif                                             \n\t"                  \
Packit 9c6abc
    "4:                                                 \n\t"                  \
Packit 9c6abc
      "beqz      %[temp6],    3f                        \n\t"                  \
Packit 9c6abc
      " nop                                             \n\t"                  \
Packit 9c6abc
    "2:                                                 \n\t"                  \
Packit 9c6abc
      "lbu       %[temp2],    0(%[src])                 \n\t"                  \
Packit 9c6abc
    ".if " #INVERSE "                                   \n\t"                  \
Packit 9c6abc
      "lbu       %[temp1],    -1(%[dst])                \n\t"                  \
Packit 9c6abc
      "addu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
Packit 9c6abc
    ".else                                              \n\t"                  \
Packit 9c6abc
      "lbu       %[temp1],    -1(%[src])                \n\t"                  \
Packit 9c6abc
      "subu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
Packit 9c6abc
    ".endif                                             \n\t"                  \
Packit 9c6abc
      "addiu     %[src],      %[src],       1           \n\t"                  \
Packit 9c6abc
      "sb        %[temp3],    0(%[dst])                 \n\t"                  \
Packit 9c6abc
      "addiu     %[temp6],    %[temp6],     -1          \n\t"                  \
Packit 9c6abc
      "bnez      %[temp6],    2b                        \n\t"                  \
Packit 9c6abc
      " addiu    %[dst],      %[dst],       1           \n\t"                  \
Packit 9c6abc
    "3:                                                 \n\t"                  \
Packit 9c6abc
      ".set      pop                                    \n\t"                  \
Packit 9c6abc
      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),         \
Packit 9c6abc
        [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),         \
Packit 9c6abc
        [temp6]"=&r"(temp6), [dst]"+&r"(pdst), [src]"+&r"(psrc)                \
Packit 9c6abc
      : [length]"r"(ilength)                                                   \
Packit 9c6abc
      : "memory"                                                               \
Packit 9c6abc
    );                                                                         \
Packit 9c6abc
  } while (0)
Packit 9c6abc
Packit 9c6abc
static WEBP_INLINE void PredictLine_MIPSdspR2(const uint8_t* src, uint8_t* dst,
Packit 9c6abc
                                              int length) {
Packit 9c6abc
  DO_PREDICT_LINE(src, dst, length, 0);
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
#define DO_PREDICT_LINE_VERTICAL(SRC, PRED, DST, LENGTH, INVERSE) do {         \
Packit 9c6abc
    const uint8_t* psrc = (uint8_t*)(SRC);                                     \
Packit 9c6abc
    const uint8_t* ppred = (uint8_t*)(PRED);                                   \
Packit 9c6abc
    uint8_t* pdst = (uint8_t*)(DST);                                           \
Packit 9c6abc
    const int ilength = (int)(LENGTH);                                         \
Packit 9c6abc
    int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;                \
Packit 9c6abc
    __asm__ volatile (                                                         \
Packit 9c6abc
      ".set      push                                   \n\t"                  \
Packit 9c6abc
      ".set      noreorder                              \n\t"                  \
Packit 9c6abc
      "srl       %[temp0],    %[length],    0x3         \n\t"                  \
Packit 9c6abc
      "beqz      %[temp0],    4f                        \n\t"                  \
Packit 9c6abc
      " andi     %[temp7],    %[length],    0x7         \n\t"                  \
Packit 9c6abc
    "1:                                                 \n\t"                  \
Packit 9c6abc
      "ulw       %[temp1],    0(%[src])                 \n\t"                  \
Packit 9c6abc
      "ulw       %[temp2],    0(%[pred])                \n\t"                  \
Packit 9c6abc
      "ulw       %[temp3],    4(%[src])                 \n\t"                  \
Packit 9c6abc
      "ulw       %[temp4],    4(%[pred])                \n\t"                  \
Packit 9c6abc
      "addiu     %[src],      %[src],       8           \n\t"                  \
Packit 9c6abc
    ".if " #INVERSE "                                   \n\t"                  \
Packit 9c6abc
      "addu.qb   %[temp5],    %[temp1],     %[temp2]    \n\t"                  \
Packit 9c6abc
      "addu.qb   %[temp6],    %[temp3],     %[temp4]    \n\t"                  \
Packit 9c6abc
    ".else                                              \n\t"                  \
Packit 9c6abc
      "subu.qb   %[temp5],    %[temp1],     %[temp2]    \n\t"                  \
Packit 9c6abc
      "subu.qb   %[temp6],    %[temp3],     %[temp4]    \n\t"                  \
Packit 9c6abc
    ".endif                                             \n\t"                  \
Packit 9c6abc
      "addiu     %[pred],     %[pred],      8           \n\t"                  \
Packit 9c6abc
      "usw       %[temp5],    0(%[dst])                 \n\t"                  \
Packit 9c6abc
      "usw       %[temp6],    4(%[dst])                 \n\t"                  \
Packit 9c6abc
      "addiu     %[temp0],    %[temp0],     -1          \n\t"                  \
Packit 9c6abc
      "bnez      %[temp0],    1b                        \n\t"                  \
Packit 9c6abc
      " addiu    %[dst],      %[dst],       8           \n\t"                  \
Packit 9c6abc
    "4:                                                 \n\t"                  \
Packit 9c6abc
      "beqz      %[temp7],    3f                        \n\t"                  \
Packit 9c6abc
      " nop                                             \n\t"                  \
Packit 9c6abc
    "2:                                                 \n\t"                  \
Packit 9c6abc
      "lbu       %[temp1],    0(%[src])                 \n\t"                  \
Packit 9c6abc
      "lbu       %[temp2],    0(%[pred])                \n\t"                  \
Packit 9c6abc
      "addiu     %[src],      %[src],       1           \n\t"                  \
Packit 9c6abc
      "addiu     %[pred],     %[pred],      1           \n\t"                  \
Packit 9c6abc
    ".if " #INVERSE "                                   \n\t"                  \
Packit 9c6abc
      "addu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
Packit 9c6abc
    ".else                                              \n\t"                  \
Packit 9c6abc
      "subu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
Packit 9c6abc
    ".endif                                             \n\t"                  \
Packit 9c6abc
      "sb        %[temp3],    0(%[dst])                 \n\t"                  \
Packit 9c6abc
      "addiu     %[temp7],    %[temp7],     -1          \n\t"                  \
Packit 9c6abc
      "bnez      %[temp7],    2b                        \n\t"                  \
Packit 9c6abc
      " addiu    %[dst],      %[dst],       1           \n\t"                  \
Packit 9c6abc
    "3:                                                 \n\t"                  \
Packit 9c6abc
      ".set      pop                                    \n\t"                  \
Packit 9c6abc
      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),         \
Packit 9c6abc
        [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),         \
Packit 9c6abc
        [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [pred]"+&r"(ppred),          \
Packit 9c6abc
        [dst]"+&r"(pdst), [src]"+&r"(psrc)                                     \
Packit 9c6abc
      : [length]"r"(ilength)                                                   \
Packit 9c6abc
      : "memory"                                                               \
Packit 9c6abc
    );                                                                         \
Packit 9c6abc
  } while (0)
Packit 9c6abc
Packit 9c6abc
#define PREDICT_LINE_ONE_PASS(SRC, PRED, DST) do {                             \
Packit 9c6abc
    int temp1, temp2, temp3;                                                   \
Packit 9c6abc
    __asm__ volatile (                                                         \
Packit 9c6abc
      "lbu       %[temp1],   0(%[src])               \n\t"                     \
Packit 9c6abc
      "lbu       %[temp2],   0(%[pred])              \n\t"                     \
Packit 9c6abc
      "subu      %[temp3],   %[temp1],   %[temp2]    \n\t"                     \
Packit 9c6abc
      "sb        %[temp3],   0(%[dst])               \n\t"                     \
Packit 9c6abc
      : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3)          \
Packit 9c6abc
      : [pred]"r"((PRED)), [dst]"r"((DST)), [src]"r"((SRC))                    \
Packit 9c6abc
      : "memory"                                                               \
Packit 9c6abc
    );                                                                         \
Packit 9c6abc
  } while (0)
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
// Horizontal filter.
Packit 9c6abc
Packit 9c6abc
#define FILTER_LINE_BY_LINE do {                                               \
Packit 9c6abc
    while (row < last_row) {                                                   \
Packit 9c6abc
      PREDICT_LINE_ONE_PASS(in, preds - stride, out);                          \
Packit 9c6abc
      DO_PREDICT_LINE(in + 1, out + 1, width - 1, 0);                          \
Packit 9c6abc
      ++row;                                                                   \
Packit 9c6abc
      preds += stride;                                                         \
Packit 9c6abc
      in += stride;                                                            \
Packit 9c6abc
      out += stride;                                                           \
Packit 9c6abc
    }                                                                          \
Packit 9c6abc
  } while (0)
Packit 9c6abc
Packit 9c6abc
static WEBP_INLINE void DoHorizontalFilter_MIPSdspR2(const uint8_t* in,
Packit 9c6abc
                                                     int width, int height,
Packit 9c6abc
                                                     int stride,
Packit 9c6abc
                                                     int row, int num_rows,
Packit 9c6abc
                                                     uint8_t* out) {
Packit 9c6abc
  const uint8_t* preds;
Packit 9c6abc
  const size_t start_offset = row * stride;
Packit 9c6abc
  const int last_row = row + num_rows;
Packit 9c6abc
  SANITY_CHECK(in, out);
Packit 9c6abc
  in += start_offset;
Packit 9c6abc
  out += start_offset;
Packit 9c6abc
  preds = in;
Packit 9c6abc
Packit 9c6abc
  if (row == 0) {
Packit 9c6abc
    // Leftmost pixel is the same as input for topmost scanline.
Packit 9c6abc
    out[0] = in[0];
Packit 9c6abc
    PredictLine_MIPSdspR2(in + 1, out + 1, width - 1);
Packit 9c6abc
    row = 1;
Packit 9c6abc
    preds += stride;
Packit 9c6abc
    in += stride;
Packit 9c6abc
    out += stride;
Packit 9c6abc
  }
Packit 9c6abc
Packit 9c6abc
  // Filter line-by-line.
Packit 9c6abc
  FILTER_LINE_BY_LINE;
Packit 9c6abc
}
Packit 9c6abc
#undef FILTER_LINE_BY_LINE
Packit 9c6abc
Packit 9c6abc
static void HorizontalFilter_MIPSdspR2(const uint8_t* data,
Packit 9c6abc
                                       int width, int height,
Packit 9c6abc
                                       int stride, uint8_t* filtered_data) {
Packit 9c6abc
  DoHorizontalFilter_MIPSdspR2(data, width, height, stride, 0, height,
Packit 9c6abc
                               filtered_data);
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
// Vertical filter.
Packit 9c6abc
Packit 9c6abc
#define FILTER_LINE_BY_LINE do {                                               \
Packit 9c6abc
    while (row < last_row) {                                                   \
Packit 9c6abc
      DO_PREDICT_LINE_VERTICAL(in, preds, out, width, 0);                      \
Packit 9c6abc
      ++row;                                                                   \
Packit 9c6abc
      preds += stride;                                                         \
Packit 9c6abc
      in += stride;                                                            \
Packit 9c6abc
      out += stride;                                                           \
Packit 9c6abc
    }                                                                          \
Packit 9c6abc
  } while (0)
Packit 9c6abc
Packit 9c6abc
static WEBP_INLINE void DoVerticalFilter_MIPSdspR2(const uint8_t* in,
Packit 9c6abc
                                                   int width, int height,
Packit 9c6abc
                                                   int stride,
Packit 9c6abc
                                                   int row, int num_rows,
Packit 9c6abc
                                                   uint8_t* out) {
Packit 9c6abc
  const uint8_t* preds;
Packit 9c6abc
  const size_t start_offset = row * stride;
Packit 9c6abc
  const int last_row = row + num_rows;
Packit 9c6abc
  SANITY_CHECK(in, out);
Packit 9c6abc
  in += start_offset;
Packit 9c6abc
  out += start_offset;
Packit 9c6abc
  preds = in;
Packit 9c6abc
Packit 9c6abc
  if (row == 0) {
Packit 9c6abc
    // Very first top-left pixel is copied.
Packit 9c6abc
    out[0] = in[0];
Packit 9c6abc
    // Rest of top scan-line is left-predicted.
Packit 9c6abc
    PredictLine_MIPSdspR2(in + 1, out + 1, width - 1);
Packit 9c6abc
    row = 1;
Packit 9c6abc
    in += stride;
Packit 9c6abc
    out += stride;
Packit 9c6abc
  } else {
Packit 9c6abc
    // We are starting from in-between. Make sure 'preds' points to prev row.
Packit 9c6abc
    preds -= stride;
Packit 9c6abc
  }
Packit 9c6abc
Packit 9c6abc
  // Filter line-by-line.
Packit 9c6abc
  FILTER_LINE_BY_LINE;
Packit 9c6abc
}
Packit 9c6abc
#undef FILTER_LINE_BY_LINE
Packit 9c6abc
Packit 9c6abc
static void VerticalFilter_MIPSdspR2(const uint8_t* data, int width, int height,
Packit 9c6abc
                                     int stride, uint8_t* filtered_data) {
Packit 9c6abc
  DoVerticalFilter_MIPSdspR2(data, width, height, stride, 0, height,
Packit 9c6abc
                             filtered_data);
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
// Gradient filter.
Packit 9c6abc
Packit 9c6abc
static int GradientPredictor_MIPSdspR2(uint8_t a, uint8_t b, uint8_t c) {
Packit 9c6abc
  int temp0;
Packit 9c6abc
  __asm__ volatile (
Packit 9c6abc
    "addu             %[temp0],   %[a],       %[b]        \n\t"
Packit 9c6abc
    "subu             %[temp0],   %[temp0],   %[c]        \n\t"
Packit 9c6abc
    "shll_s.w         %[temp0],   %[temp0],   23          \n\t"
Packit 9c6abc
    "precrqu_s.qb.ph  %[temp0],   %[temp0],   $zero       \n\t"
Packit 9c6abc
    "srl              %[temp0],   %[temp0],   24          \n\t"
Packit 9c6abc
    : [temp0]"=&r"(temp0)
Packit 9c6abc
    : [a]"r"(a),[b]"r"(b),[c]"r"(c)
Packit 9c6abc
  );
Packit 9c6abc
  return temp0;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
#define FILTER_LINE_BY_LINE(PREDS, OPERATION) do {                             \
Packit 9c6abc
    while (row < last_row) {                                                   \
Packit 9c6abc
      int w;                                                                   \
Packit 9c6abc
      PREDICT_LINE_ONE_PASS(in, PREDS - stride, out);                          \
Packit 9c6abc
      for (w = 1; w < width; ++w) {                                            \
Packit 9c6abc
        const int pred = GradientPredictor_MIPSdspR2(PREDS[w - 1],             \
Packit 9c6abc
                                                     PREDS[w - stride],        \
Packit 9c6abc
                                                     PREDS[w - stride - 1]);   \
Packit 9c6abc
        out[w] = in[w] OPERATION pred;                                         \
Packit 9c6abc
      }                                                                        \
Packit 9c6abc
      ++row;                                                                   \
Packit 9c6abc
      in += stride;                                                            \
Packit 9c6abc
      out += stride;                                                           \
Packit 9c6abc
    }                                                                          \
Packit 9c6abc
  } while (0)
Packit 9c6abc
Packit 9c6abc
static void DoGradientFilter_MIPSdspR2(const uint8_t* in,
Packit 9c6abc
                                       int width, int height, int stride,
Packit 9c6abc
                                       int row, int num_rows, uint8_t* out) {
Packit 9c6abc
  const uint8_t* preds;
Packit 9c6abc
  const size_t start_offset = row * stride;
Packit 9c6abc
  const int last_row = row + num_rows;
Packit 9c6abc
  SANITY_CHECK(in, out);
Packit 9c6abc
  in += start_offset;
Packit 9c6abc
  out += start_offset;
Packit 9c6abc
  preds = in;
Packit 9c6abc
Packit 9c6abc
  // left prediction for top scan-line
Packit 9c6abc
  if (row == 0) {
Packit 9c6abc
    out[0] = in[0];
Packit 9c6abc
    PredictLine_MIPSdspR2(in + 1, out + 1, width - 1);
Packit 9c6abc
    row = 1;
Packit 9c6abc
    preds += stride;
Packit 9c6abc
    in += stride;
Packit 9c6abc
    out += stride;
Packit 9c6abc
  }
Packit 9c6abc
Packit 9c6abc
  // Filter line-by-line.
Packit 9c6abc
  FILTER_LINE_BY_LINE(in, -);
Packit 9c6abc
}
Packit 9c6abc
#undef FILTER_LINE_BY_LINE
Packit 9c6abc
Packit 9c6abc
static void GradientFilter_MIPSdspR2(const uint8_t* data, int width, int height,
Packit 9c6abc
                                     int stride, uint8_t* filtered_data) {
Packit 9c6abc
  DoGradientFilter_MIPSdspR2(data, width, height, stride, 0, height,
Packit 9c6abc
                             filtered_data);
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
Packit 9c6abc
static void HorizontalUnfilter_MIPSdspR2(const uint8_t* prev, const uint8_t* in,
Packit 9c6abc
                                         uint8_t* out, int width) {
Packit 9c6abc
 out[0] = in[0] + (prev == NULL ? 0 : prev[0]);
Packit 9c6abc
 DO_PREDICT_LINE(in + 1, out + 1, width - 1, 1);
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
static void VerticalUnfilter_MIPSdspR2(const uint8_t* prev, const uint8_t* in,
Packit 9c6abc
                                       uint8_t* out, int width) {
Packit 9c6abc
  if (prev == NULL) {
Packit 9c6abc
    HorizontalUnfilter_MIPSdspR2(NULL, in, out, width);
Packit 9c6abc
  } else {
Packit 9c6abc
    DO_PREDICT_LINE_VERTICAL(in, prev, out, width, 1);
Packit 9c6abc
  }
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
static void GradientUnfilter_MIPSdspR2(const uint8_t* prev, const uint8_t* in,
Packit 9c6abc
                                       uint8_t* out, int width) {
Packit 9c6abc
  if (prev == NULL) {
Packit 9c6abc
    HorizontalUnfilter_MIPSdspR2(NULL, in, out, width);
Packit 9c6abc
  } else {
Packit 9c6abc
    uint8_t top = prev[0], top_left = top, left = top;
Packit 9c6abc
    int i;
Packit 9c6abc
    for (i = 0; i < width; ++i) {
Packit 9c6abc
      top = prev[i];  // need to read this first, in case prev==dst
Packit 9c6abc
      left = in[i] + GradientPredictor_MIPSdspR2(left, top, top_left);
Packit 9c6abc
      top_left = top;
Packit 9c6abc
      out[i] = left;
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
#undef DO_PREDICT_LINE_VERTICAL
Packit 9c6abc
#undef PREDICT_LINE_ONE_PASS
Packit 9c6abc
#undef DO_PREDICT_LINE
Packit 9c6abc
#undef SANITY_CHECK
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
// Entry point
Packit 9c6abc
Packit 9c6abc
extern void VP8FiltersInitMIPSdspR2(void);
Packit 9c6abc
Packit 9c6abc
WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitMIPSdspR2(void) {
Packit 9c6abc
  WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter_MIPSdspR2;
Packit 9c6abc
  WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter_MIPSdspR2;
Packit 9c6abc
  WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter_MIPSdspR2;
Packit 9c6abc
Packit 9c6abc
  WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter_MIPSdspR2;
Packit 9c6abc
  WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter_MIPSdspR2;
Packit 9c6abc
  WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter_MIPSdspR2;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
#else  // !WEBP_USE_MIPS_DSP_R2
Packit 9c6abc
Packit 9c6abc
WEBP_DSP_INIT_STUB(VP8FiltersInitMIPSdspR2)
Packit 9c6abc
Packit 9c6abc
#endif  // WEBP_USE_MIPS_DSP_R2