| 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 |