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 |