Home | History | Annotate | Download | only in dsp
      1 // Copyright 2014 Google Inc. All Rights Reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style license
      4 // that can be found in the COPYING file in the root of the source
      5 // tree. An additional intellectual property rights grant can be found
      6 // in the file PATENTS. All contributing project authors may
      7 // be found in the AUTHORS file in the root of the source tree.
      8 // -----------------------------------------------------------------------------
      9 //
     10 // Utilities for processing transparent channel.
     11 //
     12 // Author(s): Branimir Vasic (branimir.vasic (at) imgtec.com)
     13 //            Djordje Pesut  (djordje.pesut (at) imgtec.com)
     14 
     15 #include "./dsp.h"
     16 
     17 #if defined(WEBP_USE_MIPS_DSP_R2)
     18 
     19 static int DispatchAlpha(const uint8_t* alpha, int alpha_stride,
     20                          int width, int height,
     21                          uint8_t* dst, int dst_stride) {
     22   uint32_t alpha_mask = 0xffffffff;
     23   int i, j, temp0;
     24 
     25   for (j = 0; j < height; ++j) {
     26     uint8_t* pdst = dst;
     27     const uint8_t* palpha = alpha;
     28     for (i = 0; i < (width >> 2); ++i) {
     29       int temp1, temp2, temp3;
     30 
     31       __asm__ volatile (
     32         "ulw    %[temp0],      0(%[palpha])                \n\t"
     33         "addiu  %[palpha],     %[palpha],     4            \n\t"
     34         "addiu  %[pdst],       %[pdst],       16           \n\t"
     35         "srl    %[temp1],      %[temp0],      8            \n\t"
     36         "srl    %[temp2],      %[temp0],      16           \n\t"
     37         "srl    %[temp3],      %[temp0],      24           \n\t"
     38         "and    %[alpha_mask], %[alpha_mask], %[temp0]     \n\t"
     39         "sb     %[temp0],      -16(%[pdst])                \n\t"
     40         "sb     %[temp1],      -12(%[pdst])                \n\t"
     41         "sb     %[temp2],      -8(%[pdst])                 \n\t"
     42         "sb     %[temp3],      -4(%[pdst])                 \n\t"
     43         : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
     44           [temp3]"=&r"(temp3), [palpha]"+r"(palpha), [pdst]"+r"(pdst),
     45           [alpha_mask]"+r"(alpha_mask)
     46         :
     47         : "memory"
     48       );
     49     }
     50 
     51     for (i = 0; i < (width & 3); ++i) {
     52       __asm__ volatile (
     53         "lbu    %[temp0],      0(%[palpha])                \n\t"
     54         "addiu  %[palpha],     %[palpha],     1            \n\t"
     55         "sb     %[temp0],      0(%[pdst])                  \n\t"
     56         "and    %[alpha_mask], %[alpha_mask], %[temp0]     \n\t"
     57         "addiu  %[pdst],       %[pdst],       4            \n\t"
     58         : [temp0]"=&r"(temp0), [palpha]"+r"(palpha), [pdst]"+r"(pdst),
     59           [alpha_mask]"+r"(alpha_mask)
     60         :
     61         : "memory"
     62       );
     63     }
     64     alpha += alpha_stride;
     65     dst += dst_stride;
     66   }
     67 
     68   __asm__ volatile (
     69     "ext    %[temp0],      %[alpha_mask], 0, 16            \n\t"
     70     "srl    %[alpha_mask], %[alpha_mask], 16               \n\t"
     71     "and    %[alpha_mask], %[alpha_mask], %[temp0]         \n\t"
     72     "ext    %[temp0],      %[alpha_mask], 0, 8             \n\t"
     73     "srl    %[alpha_mask], %[alpha_mask], 8                \n\t"
     74     "and    %[alpha_mask], %[alpha_mask], %[temp0]         \n\t"
     75     : [temp0]"=&r"(temp0), [alpha_mask]"+r"(alpha_mask)
     76     :
     77   );
     78 
     79   return (alpha_mask != 0xff);
     80 }
     81 
     82 static void MultARGBRow(uint32_t* const ptr, int width, int inverse) {
     83   int x;
     84   const uint32_t c_00ffffff = 0x00ffffffu;
     85   const uint32_t c_ff000000 = 0xff000000u;
     86   const uint32_t c_8000000  = 0x00800000u;
     87   const uint32_t c_8000080  = 0x00800080u;
     88   for (x = 0; x < width; ++x) {
     89     const uint32_t argb = ptr[x];
     90     if (argb < 0xff000000u) {      // alpha < 255
     91       if (argb <= 0x00ffffffu) {   // alpha == 0
     92         ptr[x] = 0;
     93       } else {
     94         int temp0, temp1, temp2, temp3, alpha;
     95         __asm__ volatile (
     96           "srl          %[alpha],   %[argb],       24                \n\t"
     97           "replv.qb     %[temp0],   %[alpha]                         \n\t"
     98           "and          %[temp0],   %[temp0],      %[c_00ffffff]     \n\t"
     99           "beqz         %[inverse], 0f                               \n\t"
    100           "divu         $zero,      %[c_ff000000], %[alpha]          \n\t"
    101           "mflo         %[temp0]                                     \n\t"
    102         "0:                                                          \n\t"
    103           "andi         %[temp1],   %[argb],       0xff              \n\t"
    104           "ext          %[temp2],   %[argb],       8,             8  \n\t"
    105           "ext          %[temp3],   %[argb],       16,            8  \n\t"
    106           "mul          %[temp1],   %[temp1],      %[temp0]          \n\t"
    107           "mul          %[temp2],   %[temp2],      %[temp0]          \n\t"
    108           "mul          %[temp3],   %[temp3],      %[temp0]          \n\t"
    109           "precrq.ph.w  %[temp1],   %[temp2],      %[temp1]          \n\t"
    110           "addu         %[temp3],   %[temp3],      %[c_8000000]      \n\t"
    111           "addu         %[temp1],   %[temp1],      %[c_8000080]      \n\t"
    112           "precrq.ph.w  %[temp3],   %[argb],       %[temp3]          \n\t"
    113           "precrq.qb.ph %[temp1],   %[temp3],      %[temp1]          \n\t"
    114           : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
    115             [temp3]"=&r"(temp3), [alpha]"=&r"(alpha)
    116           : [inverse]"r"(inverse), [c_00ffffff]"r"(c_00ffffff),
    117             [c_8000000]"r"(c_8000000), [c_8000080]"r"(c_8000080),
    118             [c_ff000000]"r"(c_ff000000), [argb]"r"(argb)
    119           : "memory", "hi", "lo"
    120         );
    121         ptr[x] = temp1;
    122       }
    123     }
    124   }
    125 }
    126 
    127 //------------------------------------------------------------------------------
    128 // Entry point
    129 
    130 extern void WebPInitAlphaProcessingMIPSdspR2(void);
    131 
    132 WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) {
    133   WebPDispatchAlpha = DispatchAlpha;
    134   WebPMultARGBRow = MultARGBRow;
    135 }
    136 
    137 #else  // !WEBP_USE_MIPS_DSP_R2
    138 
    139 WEBP_DSP_INIT_STUB(WebPInitAlphaProcessingMIPSdspR2)
    140 
    141 #endif  // WEBP_USE_MIPS_DSP_R2
    142