OLD | NEW |
1 // Copyright 2014 Google Inc. All Rights Reserved. | 1 // Copyright 2015 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Use of this source code is governed by a BSD-style license | 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 | 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 | 5 // tree. An additional intellectual property rights grant can be found |
6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
9 // | 9 // |
10 // MIPS version of lossless functions | 10 // MIPS version of lossless functions |
11 // | 11 // |
12 // Author(s): Djordje Pesut (djordje.pesut@imgtec.com) | 12 // Author(s): Djordje Pesut (djordje.pesut@imgtec.com) |
13 // Jovan Zelincevic (jovan.zelincevic@imgtec.com) | 13 // Jovan Zelincevic (jovan.zelincevic@imgtec.com) |
14 | 14 |
15 #include "./dsp.h" | 15 #include "./dsp.h" |
16 #include "./lossless.h" | 16 #include "./lossless.h" |
17 | 17 |
18 #if defined(WEBP_USE_MIPS32) | 18 #if defined(WEBP_USE_MIPS32) |
19 | 19 |
20 #include <assert.h> | 20 #include <assert.h> |
21 #include <math.h> | 21 #include <math.h> |
22 #include <stdlib.h> | 22 #include <stdlib.h> |
23 #include <string.h> | 23 #include <string.h> |
24 | 24 |
25 #define APPROX_LOG_WITH_CORRECTION_MAX 65536 | |
26 #define APPROX_LOG_MAX 4096 | |
27 #define LOG_2_RECIPROCAL 1.44269504088896338700465094007086 | |
28 | |
29 static float FastSLog2Slow(uint32_t v) { | 25 static float FastSLog2Slow(uint32_t v) { |
30 assert(v >= LOG_LOOKUP_IDX_MAX); | 26 assert(v >= LOG_LOOKUP_IDX_MAX); |
31 if (v < APPROX_LOG_WITH_CORRECTION_MAX) { | 27 if (v < APPROX_LOG_WITH_CORRECTION_MAX) { |
32 uint32_t log_cnt, y, correction; | 28 uint32_t log_cnt, y, correction; |
33 const int c24 = 24; | 29 const int c24 = 24; |
34 const float v_f = (float)v; | 30 const float v_f = (float)v; |
35 uint32_t temp; | 31 uint32_t temp; |
36 | 32 |
37 // Xf = 256 = 2^8 | 33 // Xf = 256 = 2^8 |
38 // log_cnt is index of leading one in upper 24 bits | 34 // log_cnt is index of leading one in upper 24 bits |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 "sw %[temp0], 0(%[temp2]) \n\t" \ | 206 "sw %[temp0], 0(%[temp2]) \n\t" \ |
211 "2: \n\t" \ | 207 "2: \n\t" \ |
212 : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), \ | 208 : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), \ |
213 [temp3]"=&r"(temp3), [temp0]"+r"(temp0) \ | 209 [temp3]"=&r"(temp3), [temp0]"+r"(temp0) \ |
214 : [pstreaks]"r"(pstreaks), [pcnts]"r"(pcnts), \ | 210 : [pstreaks]"r"(pstreaks), [pcnts]"r"(pcnts), \ |
215 [streak]"r"(streak) \ | 211 [streak]"r"(streak) \ |
216 : "memory" \ | 212 : "memory" \ |
217 ); | 213 ); |
218 | 214 |
219 // Returns the various RLE counts | 215 // Returns the various RLE counts |
220 static VP8LStreaks HuffmanCostCount(const uint32_t* population, int length) { | 216 static WEBP_INLINE void GetEntropyUnrefinedHelper( |
221 int i; | 217 uint32_t val, int i, uint32_t* const val_prev, int* const i_prev, |
222 int streak = 0; | 218 VP8LBitEntropy* const bit_entropy, VP8LStreaks* const stats) { |
223 VP8LStreaks stats; | 219 int* const pstreaks = &stats->streaks[0][0]; |
224 int* const pstreaks = &stats.streaks[0][0]; | 220 int* const pcnts = &stats->counts[0]; |
225 int* const pcnts = &stats.counts[0]; | |
226 int temp0, temp1, temp2, temp3; | 221 int temp0, temp1, temp2, temp3; |
227 memset(&stats, 0, sizeof(stats)); | 222 const int streak = i - *i_prev; |
228 for (i = 0; i < length - 1; ++i) { | 223 |
229 ++streak; | 224 // Gather info for the bit entropy. |
230 if (population[i] == population[i + 1]) { | 225 if (*val_prev != 0) { |
231 continue; | 226 bit_entropy->sum += (*val_prev) * streak; |
| 227 bit_entropy->nonzeros += streak; |
| 228 bit_entropy->nonzero_code = *i_prev; |
| 229 bit_entropy->entropy -= VP8LFastSLog2(*val_prev) * streak; |
| 230 if (bit_entropy->max_val < *val_prev) { |
| 231 bit_entropy->max_val = *val_prev; |
232 } | 232 } |
233 temp0 = (population[i] != 0); | |
234 HUFFMAN_COST_PASS | |
235 streak = 0; | |
236 } | 233 } |
237 ++streak; | 234 |
238 temp0 = (population[i] != 0); | 235 // Gather info for the Huffman cost. |
| 236 temp0 = (*val_prev != 0); |
239 HUFFMAN_COST_PASS | 237 HUFFMAN_COST_PASS |
240 | 238 |
241 return stats; | 239 *val_prev = val; |
242 } | 240 *i_prev = i; |
243 | |
244 static VP8LStreaks HuffmanCostCombinedCount(const uint32_t* X, | |
245 const uint32_t* Y, int length) { | |
246 int i; | |
247 int streak = 0; | |
248 VP8LStreaks stats; | |
249 int* const pstreaks = &stats.streaks[0][0]; | |
250 int* const pcnts = &stats.counts[0]; | |
251 int temp0, temp1, temp2, temp3; | |
252 memset(&stats, 0, sizeof(stats)); | |
253 for (i = 0; i < length - 1; ++i) { | |
254 const uint32_t xy = X[i] + Y[i]; | |
255 const uint32_t xy_next = X[i + 1] + Y[i + 1]; | |
256 ++streak; | |
257 if (xy == xy_next) { | |
258 continue; | |
259 } | |
260 temp0 = (xy != 0); | |
261 HUFFMAN_COST_PASS | |
262 streak = 0; | |
263 } | |
264 { | |
265 const uint32_t xy = X[i] + Y[i]; | |
266 ++streak; | |
267 temp0 = (xy != 0); | |
268 HUFFMAN_COST_PASS | |
269 } | |
270 | |
271 return stats; | |
272 } | 241 } |
273 | 242 |
274 #define ASM_START \ | 243 #define ASM_START \ |
275 __asm__ volatile( \ | 244 __asm__ volatile( \ |
276 ".set push \n\t" \ | 245 ".set push \n\t" \ |
277 ".set at \n\t" \ | 246 ".set at \n\t" \ |
278 ".set macro \n\t" \ | 247 ".set macro \n\t" \ |
279 "1: \n\t" | 248 "1: \n\t" |
280 | 249 |
281 // P2 = P0 + P1 | 250 // P2 = P0 + P1 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 358 |
390 #undef ADD_VECTOR_EQ | 359 #undef ADD_VECTOR_EQ |
391 #undef ADD_VECTOR | 360 #undef ADD_VECTOR |
392 #undef ASM_END_1 | 361 #undef ASM_END_1 |
393 #undef ASM_END_0 | 362 #undef ASM_END_0 |
394 #undef ASM_END_COMMON_1 | 363 #undef ASM_END_COMMON_1 |
395 #undef ASM_END_COMMON_0 | 364 #undef ASM_END_COMMON_0 |
396 #undef ADD_TO_OUT | 365 #undef ADD_TO_OUT |
397 #undef ASM_START | 366 #undef ASM_START |
398 | 367 |
399 #endif // WEBP_USE_MIPS32 | |
400 | |
401 //------------------------------------------------------------------------------ | 368 //------------------------------------------------------------------------------ |
402 // Entry point | 369 // Entry point |
403 | 370 |
404 extern void VP8LDspInitMIPS32(void); | 371 extern void VP8LEncDspInitMIPS32(void); |
405 | 372 |
406 void VP8LDspInitMIPS32(void) { | 373 WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInitMIPS32(void) { |
407 #if defined(WEBP_USE_MIPS32) | |
408 VP8LFastSLog2Slow = FastSLog2Slow; | 374 VP8LFastSLog2Slow = FastSLog2Slow; |
409 VP8LFastLog2Slow = FastLog2Slow; | 375 VP8LFastLog2Slow = FastLog2Slow; |
410 VP8LExtraCost = ExtraCost; | 376 VP8LExtraCost = ExtraCost; |
411 VP8LExtraCostCombined = ExtraCostCombined; | 377 VP8LExtraCostCombined = ExtraCostCombined; |
412 VP8LHuffmanCostCount = HuffmanCostCount; | 378 VP8LGetEntropyUnrefinedHelper = GetEntropyUnrefinedHelper; |
413 VP8LHuffmanCostCombinedCount = HuffmanCostCombinedCount; | |
414 VP8LHistogramAdd = HistogramAdd; | 379 VP8LHistogramAdd = HistogramAdd; |
| 380 } |
| 381 |
| 382 #else // !WEBP_USE_MIPS32 |
| 383 |
| 384 WEBP_DSP_INIT_STUB(VP8LEncDspInitMIPS32) |
| 385 |
415 #endif // WEBP_USE_MIPS32 | 386 #endif // WEBP_USE_MIPS32 |
416 } | |
OLD | NEW |