| OLD | NEW |
| 1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2014 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 // Rescaling functions | 10 // MIPS version of rescaling functions |
| 11 // | 11 // |
| 12 // Author: Skal (pascal.massimino@gmail.com) | 12 // Author(s): Djordje Pesut (djordje.pesut@imgtec.com) |
| 13 | 13 |
| 14 #include <assert.h> | 14 #include "./dsp.h" |
| 15 #include <stdlib.h> | |
| 16 #include <string.h> | |
| 17 #include "./rescaler.h" | |
| 18 #include "../dsp/dsp.h" | |
| 19 | |
| 20 //------------------------------------------------------------------------------ | |
| 21 // Implementations of critical functions ImportRow / ExportRow | |
| 22 | |
| 23 // Import a row of data and save its contribution in the rescaler. | |
| 24 // 'channel' denotes the channel number to be imported. 'Expand' corresponds to | |
| 25 // the wrk->x_expand case. Otherwise, 'Shrink' is to be used. | |
| 26 typedef void (*WebPRescalerImportRowFunc)(WebPRescaler* const wrk, | |
| 27 const uint8_t* src); | |
| 28 static WebPRescalerImportRowFunc WebPRescalerImportRowExpand; | |
| 29 static WebPRescalerImportRowFunc WebPRescalerImportRowShrink; | |
| 30 | |
| 31 // Export one row (starting at x_out position) from rescaler. | |
| 32 // 'Expand' corresponds to the wrk->y_expand case. | |
| 33 // Otherwise 'Shrink' is to be used | |
| 34 typedef void (*WebPRescalerExportRowFunc)(WebPRescaler* const wrk); | |
| 35 static WebPRescalerExportRowFunc WebPRescalerExportRowExpand; | |
| 36 static WebPRescalerExportRowFunc WebPRescalerExportRowShrink; | |
| 37 | |
| 38 #define WEBP_RESCALER_RFIX 32 // fixed-point precision for multiplies | |
| 39 #define WEBP_RESCALER_ONE (1ull << WEBP_RESCALER_RFIX) | |
| 40 #define WEBP_RESCALER_FRAC(x, y) \ | |
| 41 ((uint32_t)(((uint64_t)(x) << WEBP_RESCALER_RFIX) / (y))) | |
| 42 #define ROUNDER (WEBP_RESCALER_ONE >> 1) | |
| 43 #define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX) | |
| 44 | |
| 45 static void ImportRowExpandC(WebPRescaler* const wrk, const uint8_t* src) { | |
| 46 const int x_stride = wrk->num_channels; | |
| 47 const int x_out_max = wrk->dst_width * wrk->num_channels; | |
| 48 int channel; | |
| 49 assert(!WebPRescalerInputDone(wrk)); | |
| 50 assert(wrk->x_expand); | |
| 51 for (channel = 0; channel < x_stride; ++channel) { | |
| 52 int x_in = channel; | |
| 53 int x_out = channel; | |
| 54 // simple bilinear interpolation | |
| 55 int accum = wrk->x_add; | |
| 56 int left = src[x_in]; | |
| 57 int right = (wrk->src_width > 1) ? src[x_in + x_stride] : left; | |
| 58 x_in += x_stride; | |
| 59 while (1) { | |
| 60 wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum; | |
| 61 x_out += x_stride; | |
| 62 if (x_out >= x_out_max) break; | |
| 63 accum -= wrk->x_sub; | |
| 64 if (accum < 0) { | |
| 65 left = right; | |
| 66 x_in += x_stride; | |
| 67 assert(x_in < wrk->src_width * x_stride); | |
| 68 right = src[x_in]; | |
| 69 accum += wrk->x_add; | |
| 70 } | |
| 71 } | |
| 72 assert(wrk->x_sub == 0 /* <- special case for src_width=1 */ || accum == 0); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 static void ImportRowShrinkC(WebPRescaler* const wrk, const uint8_t* src) { | |
| 77 const int x_stride = wrk->num_channels; | |
| 78 const int x_out_max = wrk->dst_width * wrk->num_channels; | |
| 79 int channel; | |
| 80 assert(!WebPRescalerInputDone(wrk)); | |
| 81 assert(!wrk->x_expand); | |
| 82 for (channel = 0; channel < x_stride; ++channel) { | |
| 83 int x_in = channel; | |
| 84 int x_out = channel; | |
| 85 uint32_t sum = 0; | |
| 86 int accum = 0; | |
| 87 while (x_out < x_out_max) { | |
| 88 uint32_t base = 0; | |
| 89 accum += wrk->x_add; | |
| 90 while (accum > 0) { | |
| 91 accum -= wrk->x_sub; | |
| 92 assert(x_in < wrk->src_width * x_stride); | |
| 93 base = src[x_in]; | |
| 94 sum += base; | |
| 95 x_in += x_stride; | |
| 96 } | |
| 97 { // Emit next horizontal pixel. | |
| 98 const rescaler_t frac = base * (-accum); | |
| 99 wrk->frow[x_out] = sum * wrk->x_sub - frac; | |
| 100 // fresh fractional start for next pixel | |
| 101 sum = (int)MULT_FIX(frac, wrk->fx_scale); | |
| 102 } | |
| 103 x_out += x_stride; | |
| 104 } | |
| 105 assert(accum == 0); | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 //------------------------------------------------------------------------------ | |
| 110 // Row export | |
| 111 | |
| 112 static void ExportRowExpandC(WebPRescaler* const wrk) { | |
| 113 int x_out; | |
| 114 uint8_t* const dst = wrk->dst; | |
| 115 rescaler_t* const irow = wrk->irow; | |
| 116 const int x_out_max = wrk->dst_width * wrk->num_channels; | |
| 117 const rescaler_t* const frow = wrk->frow; | |
| 118 assert(!WebPRescalerOutputDone(wrk)); | |
| 119 assert(wrk->y_accum <= 0); | |
| 120 assert(wrk->y_expand); | |
| 121 assert(wrk->y_sub != 0); | |
| 122 if (wrk->y_accum == 0) { | |
| 123 for (x_out = 0; x_out < x_out_max; ++x_out) { | |
| 124 const uint32_t J = frow[x_out]; | |
| 125 const int v = (int)MULT_FIX(J, wrk->fy_scale); | |
| 126 assert(v >= 0 && v <= 255); | |
| 127 dst[x_out] = v; | |
| 128 } | |
| 129 } else { | |
| 130 const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub); | |
| 131 const uint32_t A = (uint32_t)(WEBP_RESCALER_ONE - B); | |
| 132 for (x_out = 0; x_out < x_out_max; ++x_out) { | |
| 133 const uint64_t I = (uint64_t)A * frow[x_out] | |
| 134 + (uint64_t)B * irow[x_out]; | |
| 135 const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); | |
| 136 const int v = (int)MULT_FIX(J, wrk->fy_scale); | |
| 137 assert(v >= 0 && v <= 255); | |
| 138 dst[x_out] = v; | |
| 139 } | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 static void ExportRowShrinkC(WebPRescaler* const wrk) { | |
| 144 int x_out; | |
| 145 uint8_t* const dst = wrk->dst; | |
| 146 rescaler_t* const irow = wrk->irow; | |
| 147 const int x_out_max = wrk->dst_width * wrk->num_channels; | |
| 148 const rescaler_t* const frow = wrk->frow; | |
| 149 const uint32_t yscale = wrk->fy_scale * (-wrk->y_accum); | |
| 150 assert(!WebPRescalerOutputDone(wrk)); | |
| 151 assert(wrk->y_accum <= 0); | |
| 152 assert(!wrk->y_expand); | |
| 153 if (yscale) { | |
| 154 for (x_out = 0; x_out < x_out_max; ++x_out) { | |
| 155 const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale); | |
| 156 const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale); | |
| 157 assert(v >= 0 && v <= 255); | |
| 158 dst[x_out] = v; | |
| 159 irow[x_out] = frac; // new fractional start | |
| 160 } | |
| 161 } else { | |
| 162 for (x_out = 0; x_out < x_out_max; ++x_out) { | |
| 163 const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale); | |
| 164 assert(v >= 0 && v <= 255); | |
| 165 dst[x_out] = v; | |
| 166 irow[x_out] = 0; | |
| 167 } | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 //------------------------------------------------------------------------------ | |
| 172 // Main entry calls | |
| 173 | |
| 174 void WebPRescalerImportRow(WebPRescaler* const wrk, const uint8_t* src) { | |
| 175 assert(!WebPRescalerInputDone(wrk)); | |
| 176 if (!wrk->x_expand) { | |
| 177 WebPRescalerImportRowShrink(wrk, src); | |
| 178 } else { | |
| 179 WebPRescalerImportRowExpand(wrk, src); | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 void WebPRescalerExportRow(WebPRescaler* const wrk) { | |
| 184 if (wrk->y_accum <= 0) { | |
| 185 assert(!WebPRescalerOutputDone(wrk)); | |
| 186 if (wrk->y_expand) { | |
| 187 WebPRescalerExportRowExpand(wrk); | |
| 188 } else if (wrk->fxy_scale) { | |
| 189 WebPRescalerExportRowShrink(wrk); | |
| 190 } else { // very special case for src = dst = 1x1 | |
| 191 int i; | |
| 192 assert(wrk->src_width == 1 && wrk->dst_width <= 2); | |
| 193 assert(wrk->src_height == 1 && wrk->dst_height == 1); | |
| 194 for (i = 0; i < wrk->num_channels * wrk->dst_width; ++i) { | |
| 195 wrk->dst[i] = wrk->irow[i]; | |
| 196 wrk->irow[i] = 0; | |
| 197 } | |
| 198 } | |
| 199 wrk->y_accum += wrk->y_add; | |
| 200 wrk->dst += wrk->dst_stride; | |
| 201 ++wrk->dst_y; | |
| 202 } | |
| 203 } | |
| 204 | |
| 205 //------------------------------------------------------------------------------ | |
| 206 // MIPS version | |
| 207 | 15 |
| 208 #if defined(WEBP_USE_MIPS32) | 16 #if defined(WEBP_USE_MIPS32) |
| 209 | 17 |
| 210 static void ImportRowShrinkMIPS(WebPRescaler* const wrk, const uint8_t* src) { | 18 #include <assert.h> |
| 19 #include "../utils/rescaler.h" |
| 20 |
| 21 //------------------------------------------------------------------------------ |
| 22 // Row import |
| 23 |
| 24 static void ImportRowShrink(WebPRescaler* const wrk, const uint8_t* src) { |
| 211 const int x_stride = wrk->num_channels; | 25 const int x_stride = wrk->num_channels; |
| 212 const int x_out_max = wrk->dst_width * wrk->num_channels; | 26 const int x_out_max = wrk->dst_width * wrk->num_channels; |
| 213 const int fx_scale = wrk->fx_scale; | 27 const int fx_scale = wrk->fx_scale; |
| 214 const int x_add = wrk->x_add; | 28 const int x_add = wrk->x_add; |
| 215 const int x_sub = wrk->x_sub; | 29 const int x_sub = wrk->x_sub; |
| 216 const int x_stride1 = x_stride << 2; | 30 const int x_stride1 = x_stride << 2; |
| 217 int channel; | 31 int channel; |
| 218 assert(!wrk->x_expand); | 32 assert(!wrk->x_expand); |
| 219 assert(!WebPRescalerInputDone(wrk)); | 33 assert(!WebPRescalerInputDone(wrk)); |
| 220 | 34 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 [temp2]"=&r"(temp2), [temp1]"=&r"(temp1) | 73 [temp2]"=&r"(temp2), [temp1]"=&r"(temp1) |
| 260 : [x_stride]"r"(x_stride), [fx_scale]"r"(fx_scale), | 74 : [x_stride]"r"(x_stride), [fx_scale]"r"(fx_scale), |
| 261 [x_sub]"r"(x_sub), [x_add]"r"(x_add), | 75 [x_sub]"r"(x_sub), [x_add]"r"(x_add), |
| 262 [loop_c]"r"(loop_c), [x_stride1]"r"(x_stride1) | 76 [loop_c]"r"(loop_c), [x_stride1]"r"(x_stride1) |
| 263 : "memory", "hi", "lo" | 77 : "memory", "hi", "lo" |
| 264 ); | 78 ); |
| 265 assert(accum == 0); | 79 assert(accum == 0); |
| 266 } | 80 } |
| 267 } | 81 } |
| 268 | 82 |
| 269 static void ImportRowExpandMIPS(WebPRescaler* const wrk, const uint8_t* src) { | 83 static void ImportRowExpand(WebPRescaler* const wrk, const uint8_t* src) { |
| 270 const int x_stride = wrk->num_channels; | 84 const int x_stride = wrk->num_channels; |
| 271 const int x_out_max = wrk->dst_width * wrk->num_channels; | 85 const int x_out_max = wrk->dst_width * wrk->num_channels; |
| 272 const int x_add = wrk->x_add; | 86 const int x_add = wrk->x_add; |
| 273 const int x_sub = wrk->x_sub; | 87 const int x_sub = wrk->x_sub; |
| 274 const int src_width = wrk->src_width; | 88 const int src_width = wrk->src_width; |
| 275 const int x_stride1 = x_stride << 2; | 89 const int x_stride1 = x_stride << 2; |
| 276 int channel; | 90 int channel; |
| 277 assert(wrk->x_expand); | 91 assert(wrk->x_expand); |
| 278 assert(!WebPRescalerInputDone(wrk)); | 92 assert(!WebPRescalerInputDone(wrk)); |
| 279 | 93 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 [x_out_max]"r"(x_out_max) | 137 [x_out_max]"r"(x_out_max) |
| 324 : "memory", "hi", "lo" | 138 : "memory", "hi", "lo" |
| 325 ); | 139 ); |
| 326 assert(wrk->x_sub == 0 /* <- special case for src_width=1 */ || accum == 0); | 140 assert(wrk->x_sub == 0 /* <- special case for src_width=1 */ || accum == 0); |
| 327 } | 141 } |
| 328 } | 142 } |
| 329 | 143 |
| 330 //------------------------------------------------------------------------------ | 144 //------------------------------------------------------------------------------ |
| 331 // Row export | 145 // Row export |
| 332 | 146 |
| 333 static void ExportRowExpandMIPS(WebPRescaler* const wrk) { | 147 static void ExportRowExpand(WebPRescaler* const wrk) { |
| 334 uint8_t* dst = wrk->dst; | 148 uint8_t* dst = wrk->dst; |
| 335 rescaler_t* irow = wrk->irow; | 149 rescaler_t* irow = wrk->irow; |
| 336 const int x_out_max = wrk->dst_width * wrk->num_channels; | 150 const int x_out_max = wrk->dst_width * wrk->num_channels; |
| 337 const rescaler_t* frow = wrk->frow; | 151 const rescaler_t* frow = wrk->frow; |
| 338 int temp0, temp1, temp3, temp4, temp5, loop_end; | 152 int temp0, temp1, temp3, temp4, temp5, loop_end; |
| 339 const int temp2 = (int)wrk->fy_scale; | 153 const int temp2 = (int)wrk->fy_scale; |
| 340 const int temp6 = x_out_max << 2; | 154 const int temp6 = x_out_max << 2; |
| 341 assert(!WebPRescalerOutputDone(wrk)); | 155 assert(!WebPRescalerOutputDone(wrk)); |
| 342 assert(wrk->y_accum <= 0); | 156 assert(wrk->y_accum <= 0); |
| 343 assert(wrk->y_expand); | 157 assert(wrk->y_expand); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 "bne %[frow], %[loop_end], 1b \n\t" | 200 "bne %[frow], %[loop_end], 1b \n\t" |
| 387 : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3), | 201 : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3), |
| 388 [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow), | 202 [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow), |
| 389 [irow]"+r"(irow), [dst]"+r"(dst), [loop_end]"=&r"(loop_end) | 203 [irow]"+r"(irow), [dst]"+r"(dst), [loop_end]"=&r"(loop_end) |
| 390 : [temp2]"r"(temp2), [temp6]"r"(temp6), [A]"r"(A), [B]"r"(B) | 204 : [temp2]"r"(temp2), [temp6]"r"(temp6), [A]"r"(A), [B]"r"(B) |
| 391 : "memory", "hi", "lo" | 205 : "memory", "hi", "lo" |
| 392 ); | 206 ); |
| 393 } | 207 } |
| 394 } | 208 } |
| 395 | 209 |
| 396 static void ExportRowShrinkMIPS(WebPRescaler* const wrk) { | 210 static void ExportRowShrink(WebPRescaler* const wrk) { |
| 397 const int x_out_max = wrk->dst_width * wrk->num_channels; | 211 const int x_out_max = wrk->dst_width * wrk->num_channels; |
| 398 uint8_t* dst = wrk->dst; | 212 uint8_t* dst = wrk->dst; |
| 399 rescaler_t* irow = wrk->irow; | 213 rescaler_t* irow = wrk->irow; |
| 400 const rescaler_t* frow = wrk->frow; | 214 const rescaler_t* frow = wrk->frow; |
| 401 const int yscale = wrk->fy_scale * (-wrk->y_accum); | 215 const int yscale = wrk->fy_scale * (-wrk->y_accum); |
| 402 int temp0, temp1, temp3, temp4, temp5, loop_end; | 216 int temp0, temp1, temp3, temp4, temp5, loop_end; |
| 403 const int temp2 = (int)wrk->fxy_scale; | 217 const int temp2 = (int)wrk->fxy_scale; |
| 404 const int temp6 = x_out_max << 2; | 218 const int temp6 = x_out_max << 2; |
| 405 | 219 |
| 406 assert(!WebPRescalerOutputDone(wrk)); | 220 assert(!WebPRescalerOutputDone(wrk)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 "bne %[irow], %[loop_end], 1b \n\t" | 265 "bne %[irow], %[loop_end], 1b \n\t" |
| 452 : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3), | 266 : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3), |
| 453 [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [irow]"+r"(irow), | 267 [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [irow]"+r"(irow), |
| 454 [dst]"+r"(dst), [loop_end]"=&r"(loop_end) | 268 [dst]"+r"(dst), [loop_end]"=&r"(loop_end) |
| 455 : [temp2]"r"(temp2), [temp6]"r"(temp6) | 269 : [temp2]"r"(temp2), [temp6]"r"(temp6) |
| 456 : "memory", "hi", "lo" | 270 : "memory", "hi", "lo" |
| 457 ); | 271 ); |
| 458 } | 272 } |
| 459 } | 273 } |
| 460 | 274 |
| 461 #endif // WEBP_USE_MIPS32 | 275 //------------------------------------------------------------------------------ |
| 276 // Entry point |
| 462 | 277 |
| 463 //------------------------------------------------------------------------------ | 278 extern void WebPRescalerDspInitMIPS32(void); |
| 464 | 279 |
| 465 void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height, | 280 WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitMIPS32(void) { |
| 466 uint8_t* const dst, | 281 WebPRescalerImportRowExpand = ImportRowExpand; |
| 467 int dst_width, int dst_height, int dst_stride, | 282 WebPRescalerImportRowShrink = ImportRowShrink; |
| 468 int num_channels, rescaler_t* const work) { | 283 WebPRescalerExportRowExpand = ExportRowExpand; |
| 469 const int x_add = src_width, x_sub = dst_width; | 284 WebPRescalerExportRowShrink = ExportRowShrink; |
| 470 const int y_add = src_height, y_sub = dst_height; | |
| 471 wrk->x_expand = (src_width < dst_width); | |
| 472 wrk->y_expand = (src_height < dst_height); | |
| 473 wrk->src_width = src_width; | |
| 474 wrk->src_height = src_height; | |
| 475 wrk->dst_width = dst_width; | |
| 476 wrk->dst_height = dst_height; | |
| 477 wrk->src_y = 0; | |
| 478 wrk->dst_y = 0; | |
| 479 wrk->dst = dst; | |
| 480 wrk->dst_stride = dst_stride; | |
| 481 wrk->num_channels = num_channels; | |
| 482 | |
| 483 // for 'x_expand', we use bilinear interpolation | |
| 484 wrk->x_add = wrk->x_expand ? (x_sub - 1) : x_add; | |
| 485 wrk->x_sub = wrk->x_expand ? (x_add - 1) : x_sub; | |
| 486 if (!wrk->x_expand) { // fx_scale is not used otherwise | |
| 487 wrk->fx_scale = WEBP_RESCALER_FRAC(1, wrk->x_sub); | |
| 488 } | |
| 489 // vertical scaling parameters | |
| 490 wrk->y_add = wrk->y_expand ? y_add - 1 : y_add; | |
| 491 wrk->y_sub = wrk->y_expand ? y_sub - 1 : y_sub; | |
| 492 wrk->y_accum = wrk->y_expand ? wrk->y_sub : wrk->y_add; | |
| 493 if (!wrk->y_expand) { | |
| 494 // this is WEBP_RESCALER_FRAC(dst_height, x_add * y_add) without the cast. | |
| 495 const uint64_t ratio = | |
| 496 (uint64_t)dst_height * WEBP_RESCALER_ONE / (wrk->x_add * wrk->y_add); | |
| 497 if (ratio != (uint32_t)ratio) { | |
| 498 // We can't represent the ratio with the current fixed-point precision. | |
| 499 // => We special-case fxy_scale = 0, in WebPRescalerExportRow(). | |
| 500 wrk->fxy_scale = 0; | |
| 501 } else { | |
| 502 wrk->fxy_scale = (uint32_t)ratio; | |
| 503 } | |
| 504 wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->y_sub); | |
| 505 } else { | |
| 506 wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->x_add); | |
| 507 // wrk->fxy_scale is unused here. | |
| 508 } | |
| 509 wrk->irow = work; | |
| 510 wrk->frow = work + num_channels * dst_width; | |
| 511 memset(work, 0, 2 * dst_width * num_channels * sizeof(*work)); | |
| 512 | |
| 513 if (WebPRescalerImportRowExpand == NULL) { | |
| 514 WebPRescalerImportRowExpand = ImportRowExpandC; | |
| 515 WebPRescalerImportRowShrink = ImportRowShrinkC; | |
| 516 WebPRescalerExportRowExpand = ExportRowExpandC; | |
| 517 WebPRescalerExportRowShrink = ExportRowShrinkC; | |
| 518 if (VP8GetCPUInfo != NULL) { | |
| 519 #if defined(WEBP_USE_MIPS32) | |
| 520 if (VP8GetCPUInfo(kMIPS32)) { | |
| 521 WebPRescalerImportRowExpand = ImportRowExpandMIPS; | |
| 522 WebPRescalerImportRowShrink = ImportRowShrinkMIPS; | |
| 523 WebPRescalerExportRowExpand = ExportRowExpandMIPS; | |
| 524 WebPRescalerExportRowShrink = ExportRowShrinkMIPS; | |
| 525 } | |
| 526 #endif | |
| 527 } | |
| 528 } | |
| 529 } | 285 } |
| 530 | 286 |
| 531 #undef MULT_FIX | 287 #else // !WEBP_USE_MIPS32 |
| 532 #undef WEBP_RESCALER_RFIX | |
| 533 #undef WEBP_RESCALER_ONE | |
| 534 #undef WEBP_RESCALER_FRAC | |
| 535 #undef ROUNDER | |
| 536 | 288 |
| 537 //------------------------------------------------------------------------------ | 289 WEBP_DSP_INIT_STUB(WebPRescalerDspInitMIPS32) |
| 538 // all-in-one calls | |
| 539 | 290 |
| 540 int WebPRescaleNeededLines(const WebPRescaler* const wrk, int max_num_lines) { | 291 #endif // WEBP_USE_MIPS32 |
| 541 const int num_lines = (wrk->y_accum + wrk->y_sub - 1) / wrk->y_sub; | |
| 542 return (num_lines > max_num_lines) ? max_num_lines : num_lines; | |
| 543 } | |
| 544 | |
| 545 int WebPRescalerImport(WebPRescaler* const wrk, int num_lines, | |
| 546 const uint8_t* src, int src_stride) { | |
| 547 int total_imported = 0; | |
| 548 while (total_imported < num_lines && !WebPRescalerHasPendingOutput(wrk)) { | |
| 549 if (wrk->y_expand) { | |
| 550 rescaler_t* const tmp = wrk->irow; | |
| 551 wrk->irow = wrk->frow; | |
| 552 wrk->frow = tmp; | |
| 553 } | |
| 554 WebPRescalerImportRow(wrk, src); | |
| 555 if (!wrk->y_expand) { // Accumulate the contribution of the new row. | |
| 556 int x; | |
| 557 for (x = 0; x < wrk->num_channels * wrk->dst_width; ++x) { | |
| 558 wrk->irow[x] += wrk->frow[x]; | |
| 559 } | |
| 560 } | |
| 561 ++wrk->src_y; | |
| 562 src += src_stride; | |
| 563 ++total_imported; | |
| 564 wrk->y_accum -= wrk->y_sub; | |
| 565 } | |
| 566 return total_imported; | |
| 567 } | |
| 568 | |
| 569 int WebPRescalerExport(WebPRescaler* const rescaler) { | |
| 570 int total_exported = 0; | |
| 571 while (WebPRescalerHasPendingOutput(rescaler)) { | |
| 572 WebPRescalerExportRow(rescaler); | |
| 573 ++total_exported; | |
| 574 } | |
| 575 return total_exported; | |
| 576 } | |
| 577 | |
| 578 //------------------------------------------------------------------------------ | |
| OLD | NEW |