| 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 | // MIPS DSPr2 version of YUV to RGB upsampling functions. | 
|---|
| 11 | // | 
|---|
| 12 | // Author(s):  Branimir Vasic (branimir.vasic@imgtec.com) | 
|---|
| 13 | //             Djordje Pesut  (djordje.pesut@imgtec.com) | 
|---|
| 14 |  | 
|---|
| 15 | #include "src/dsp/dsp.h" | 
|---|
| 16 |  | 
|---|
| 17 | #if defined(WEBP_USE_MIPS_DSP_R2) | 
|---|
| 18 |  | 
|---|
| 19 | #include "src/dsp/yuv.h" | 
|---|
| 20 |  | 
|---|
| 21 | //------------------------------------------------------------------------------ | 
|---|
| 22 | // simple point-sampling | 
|---|
| 23 |  | 
|---|
| 24 | #define ROW_FUNC_PART_1()                                                      \ | 
|---|
| 25 | "lbu              %[temp3],   0(%[v])                         \n\t"          \ | 
|---|
| 26 | "lbu              %[temp4],   0(%[u])                         \n\t"          \ | 
|---|
| 27 | "lbu              %[temp0],   0(%[y])                         \n\t"          \ | 
|---|
| 28 | "mul              %[temp1],   %[t_con_1],     %[temp3]        \n\t"          \ | 
|---|
| 29 | "mul              %[temp3],   %[t_con_2],     %[temp3]        \n\t"          \ | 
|---|
| 30 | "mul              %[temp2],   %[t_con_3],     %[temp4]        \n\t"          \ | 
|---|
| 31 | "mul              %[temp4],   %[t_con_4],     %[temp4]        \n\t"          \ | 
|---|
| 32 | "mul              %[temp0],   %[t_con_5],     %[temp0]        \n\t"          \ | 
|---|
| 33 | "subu             %[temp1],   %[temp1],       %[t_con_6]      \n\t"          \ | 
|---|
| 34 | "subu             %[temp3],   %[temp3],       %[t_con_7]      \n\t"          \ | 
|---|
| 35 | "addu             %[temp2],   %[temp2],       %[temp3]        \n\t"          \ | 
|---|
| 36 | "subu             %[temp4],   %[temp4],       %[t_con_8]      \n\t"          \ | 
|---|
| 37 |  | 
|---|
| 38 | #define ROW_FUNC_PART_2(R, G, B, K)                                            \ | 
|---|
| 39 | "addu             %[temp5],   %[temp0],       %[temp1]        \n\t"          \ | 
|---|
| 40 | "subu             %[temp6],   %[temp0],       %[temp2]        \n\t"          \ | 
|---|
| 41 | "addu             %[temp7],   %[temp0],       %[temp4]        \n\t"          \ | 
|---|
| 42 | ".if " #K "                                                     \n\t"          \ | 
|---|
| 43 | "lbu              %[temp0],   1(%[y])                         \n\t"          \ | 
|---|
| 44 | ".endif                                                         \n\t"          \ | 
|---|
| 45 | "shll_s.w         %[temp5],   %[temp5],       17              \n\t"          \ | 
|---|
| 46 | "shll_s.w         %[temp6],   %[temp6],       17              \n\t"          \ | 
|---|
| 47 | ".if " #K "                                                     \n\t"          \ | 
|---|
| 48 | "mul              %[temp0],   %[t_con_5],     %[temp0]        \n\t"          \ | 
|---|
| 49 | ".endif                                                         \n\t"          \ | 
|---|
| 50 | "shll_s.w         %[temp7],   %[temp7],       17              \n\t"          \ | 
|---|
| 51 | "precrqu_s.qb.ph  %[temp5],   %[temp5],       $zero           \n\t"          \ | 
|---|
| 52 | "precrqu_s.qb.ph  %[temp6],   %[temp6],       $zero           \n\t"          \ | 
|---|
| 53 | "precrqu_s.qb.ph  %[temp7],   %[temp7],       $zero           \n\t"          \ | 
|---|
| 54 | "srl              %[temp5],   %[temp5],       24              \n\t"          \ | 
|---|
| 55 | "srl              %[temp6],   %[temp6],       24              \n\t"          \ | 
|---|
| 56 | "srl              %[temp7],   %[temp7],       24              \n\t"          \ | 
|---|
| 57 | "sb               %[temp5],   " #R "(%[dst])                  \n\t"          \ | 
|---|
| 58 | "sb               %[temp6],   " #G "(%[dst])                  \n\t"          \ | 
|---|
| 59 | "sb               %[temp7],   " #B "(%[dst])                  \n\t"          \ | 
|---|
| 60 |  | 
|---|
| 61 | #define ASM_CLOBBER_LIST()                                                     \ | 
|---|
| 62 | : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),             \ | 
|---|
| 63 | [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),             \ | 
|---|
| 64 | [temp6]"=&r"(temp6), [temp7]"=&r"(temp7)                                   \ | 
|---|
| 65 | : [t_con_1]"r"(t_con_1), [t_con_2]"r"(t_con_2), [t_con_3]"r"(t_con_3),       \ | 
|---|
| 66 | [t_con_4]"r"(t_con_4), [t_con_5]"r"(t_con_5), [t_con_6]"r"(t_con_6),       \ | 
|---|
| 67 | [u]"r"(u), [v]"r"(v), [y]"r"(y), [dst]"r"(dst),                            \ | 
|---|
| 68 | [t_con_7]"r"(t_con_7), [t_con_8]"r"(t_con_8)                               \ | 
|---|
| 69 | : "memory", "hi", "lo"                                                       \ | 
|---|
| 70 |  | 
|---|
| 71 | #define ROW_FUNC(FUNC_NAME, XSTEP, R, G, B, A)                                 \ | 
|---|
| 72 | static void FUNC_NAME(const uint8_t* y,                                        \ | 
|---|
| 73 | const uint8_t* u, const uint8_t* v,                      \ | 
|---|
| 74 | uint8_t* dst, int len) {                                 \ | 
|---|
| 75 | int i;                                                                       \ | 
|---|
| 76 | uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;             \ | 
|---|
| 77 | const int t_con_1 = 26149;                                                   \ | 
|---|
| 78 | const int t_con_2 = 13320;                                                   \ | 
|---|
| 79 | const int t_con_3 = 6419;                                                    \ | 
|---|
| 80 | const int t_con_4 = 33050;                                                   \ | 
|---|
| 81 | const int t_con_5 = 19077;                                                   \ | 
|---|
| 82 | const int t_con_6 = 14234;                                                   \ | 
|---|
| 83 | const int t_con_7 = 8708;                                                    \ | 
|---|
| 84 | const int t_con_8 = 17685;                                                   \ | 
|---|
| 85 | for (i = 0; i < (len >> 1); i++) {                                           \ | 
|---|
| 86 | __asm__ volatile (                                                         \ | 
|---|
| 87 | ROW_FUNC_PART_1()                                                        \ | 
|---|
| 88 | ROW_FUNC_PART_2(R, G, B, 1)                                              \ | 
|---|
| 89 | ROW_FUNC_PART_2(R + XSTEP, G + XSTEP, B + XSTEP, 0)                      \ | 
|---|
| 90 | ASM_CLOBBER_LIST()                                                       \ | 
|---|
| 91 | );                                                                         \ | 
|---|
| 92 | if (A) dst[A] = dst[A + XSTEP] = 0xff;                                     \ | 
|---|
| 93 | y += 2;                                                                    \ | 
|---|
| 94 | ++u;                                                                       \ | 
|---|
| 95 | ++v;                                                                       \ | 
|---|
| 96 | dst += 2 * XSTEP;                                                          \ | 
|---|
| 97 | }                                                                            \ | 
|---|
| 98 | if (len & 1) {                                                               \ | 
|---|
| 99 | __asm__ volatile (                                                         \ | 
|---|
| 100 | ROW_FUNC_PART_1()                                                        \ | 
|---|
| 101 | ROW_FUNC_PART_2(R, G, B, 0)                                              \ | 
|---|
| 102 | ASM_CLOBBER_LIST()                                                       \ | 
|---|
| 103 | );                                                                         \ | 
|---|
| 104 | if (A) dst[A] = 0xff;                                                      \ | 
|---|
| 105 | }                                                                            \ | 
|---|
| 106 | } | 
|---|
| 107 |  | 
|---|
| 108 | ROW_FUNC(YuvToRgbRow_MIPSdspR2,      3, 0, 1, 2, 0) | 
|---|
| 109 | ROW_FUNC(YuvToRgbaRow_MIPSdspR2,     4, 0, 1, 2, 3) | 
|---|
| 110 | ROW_FUNC(YuvToBgrRow_MIPSdspR2,      3, 2, 1, 0, 0) | 
|---|
| 111 | ROW_FUNC(YuvToBgraRow_MIPSdspR2,     4, 2, 1, 0, 3) | 
|---|
| 112 |  | 
|---|
| 113 | #undef ROW_FUNC | 
|---|
| 114 | #undef ASM_CLOBBER_LIST | 
|---|
| 115 | #undef ROW_FUNC_PART_2 | 
|---|
| 116 | #undef ROW_FUNC_PART_1 | 
|---|
| 117 |  | 
|---|
| 118 | //------------------------------------------------------------------------------ | 
|---|
| 119 | // Entry point | 
|---|
| 120 |  | 
|---|
| 121 | extern void WebPInitSamplersMIPSdspR2(void); | 
|---|
| 122 |  | 
|---|
| 123 | WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplersMIPSdspR2(void) { | 
|---|
| 124 | WebPSamplers[MODE_RGB]  = YuvToRgbRow_MIPSdspR2; | 
|---|
| 125 | WebPSamplers[MODE_RGBA] = YuvToRgbaRow_MIPSdspR2; | 
|---|
| 126 | WebPSamplers[MODE_BGR]  = YuvToBgrRow_MIPSdspR2; | 
|---|
| 127 | WebPSamplers[MODE_BGRA] = YuvToBgraRow_MIPSdspR2; | 
|---|
| 128 | } | 
|---|
| 129 |  | 
|---|
| 130 | #else  // !WEBP_USE_MIPS_DSP_R2 | 
|---|
| 131 |  | 
|---|
| 132 | WEBP_DSP_INIT_STUB(WebPInitSamplersMIPSdspR2) | 
|---|
| 133 |  | 
|---|
| 134 | #endif  // WEBP_USE_MIPS_DSP_R2 | 
|---|
| 135 |  | 
|---|