/* * Copyright (c) 2014 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
x = 0;
y = offset; while ((y >> INTERP_PRECISION_BITS) < (INTERP_TAPS / 2 - 1)) {
x++;
y += delta;
}
x1 = x;
x = outlength - 1;
y = delta * x + offset; while ((y >> INTERP_PRECISION_BITS) + (int64_t)(INTERP_TAPS / 2) >=
inlength) {
x--;
y -= delta;
}
x2 = x; if (x1 > x2) { for (x = 0, y = offset; x < outlength; ++x, y += delta) { const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
filter = interp_filters[sub_pel];
sum = 0; for (k = 0; k < INTERP_TAPS; ++k) { constint pk = int_pel - INTERP_TAPS / 2 + 1 + k;
sum += filter[k] *
input[(pk < 0 ? 0 : (pk >= inlength ? inlength - 1 : pk))];
}
*optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
}
} else { // Initial part. for (x = 0, y = offset; x < x1; ++x, y += delta) { const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
filter = interp_filters[sub_pel];
sum = 0; for (k = 0; k < INTERP_TAPS; ++k)
sum += filter[k] * input[(int_pel - INTERP_TAPS / 2 + 1 + k < 0
? 0
: int_pel - INTERP_TAPS / 2 + 1 + k)];
*optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
} // Middle part. for (; x <= x2; ++x, y += delta) { const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
filter = interp_filters[sub_pel];
sum = 0; for (k = 0; k < INTERP_TAPS; ++k)
sum += filter[k] * input[int_pel - INTERP_TAPS / 2 + 1 + k];
*optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
} // End part. for (; x < outlength; ++x, y += delta) { const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
filter = interp_filters[sub_pel];
sum = 0; for (k = 0; k < INTERP_TAPS; ++k)
sum += filter[k] * input[(int_pel - INTERP_TAPS / 2 + 1 + k >= inlength
? inlength - 1
: int_pel - INTERP_TAPS / 2 + 1 + k)];
*optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
}
}
}
staticvoid down2_symeven(const uint8_t *const input, int length,
uint8_t *output) { // Actual filter len = 2 * filter_len_half. const int16_t *filter = vp9_down2_symeven_half_filter; constint filter_len_half = sizeof(vp9_down2_symeven_half_filter) / 2; int i, j;
uint8_t *optr = output; int l1 = filter_len_half; int l2 = (length - filter_len_half);
l1 += (l1 & 1);
l2 += (l2 & 1); if (l1 > l2) { // Short input length. for (i = 0; i < length; i += 2) { int sum = (1 << (FILTER_BITS - 1)); for (j = 0; j < filter_len_half; ++j) {
sum += (input[(i - j < 0 ? 0 : i - j)] +
input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) *
filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
}
} else { // Initial part. for (i = 0; i < l1; i += 2) { int sum = (1 << (FILTER_BITS - 1)); for (j = 0; j < filter_len_half; ++j) {
sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + 1 + j]) * filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
} // Middle part. for (; i < l2; i += 2) { int sum = (1 << (FILTER_BITS - 1)); for (j = 0; j < filter_len_half; ++j) {
sum += (input[i - j] + input[i + 1 + j]) * filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
} // End part. for (; i < length; i += 2) { int sum = (1 << (FILTER_BITS - 1)); for (j = 0; j < filter_len_half; ++j) {
sum += (input[i - j] +
input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) *
filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
}
}
}
staticvoid down2_symodd(const uint8_t *const input, int length,
uint8_t *output) { // Actual filter len = 2 * filter_len_half - 1. const int16_t *filter = vp9_down2_symodd_half_filter; constint filter_len_half = sizeof(vp9_down2_symodd_half_filter) / 2; int i, j;
uint8_t *optr = output; int l1 = filter_len_half - 1; int l2 = (length - filter_len_half + 1);
l1 += (l1 & 1);
l2 += (l2 & 1); if (l1 > l2) { // Short input length. for (i = 0; i < length; i += 2) { int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; for (j = 1; j < filter_len_half; ++j) {
sum += (input[(i - j < 0 ? 0 : i - j)] +
input[(i + j >= length ? length - 1 : i + j)]) *
filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
}
} else { // Initial part. for (i = 0; i < l1; i += 2) { int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; for (j = 1; j < filter_len_half; ++j) {
sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + j]) * filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
} // Middle part. for (; i < l2; i += 2) { int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; for (j = 1; j < filter_len_half; ++j) {
sum += (input[i - j] + input[i + j]) * filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
} // End part. for (; i < length; i += 2) { int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; for (j = 1; j < filter_len_half; ++j) {
sum += (input[i - j] + input[(i + j >= length ? length - 1 : i + j)]) *
filter[j];
}
sum >>= FILTER_BITS;
*optr++ = clip_pixel(sum);
}
}
}
staticint get_down2_length(int length, int steps) { int s; for (s = 0; s < steps; ++s) length = (length + 1) >> 1; return length;
}
staticint get_down2_steps(int in_length, int out_length) { int steps = 0; int proj_in_length; while ((proj_in_length = get_down2_length(in_length, 1)) >= out_length) {
++steps;
in_length = proj_in_length; if (in_length == 1) { // Special case: we break because any further calls to get_down2_length() // with be with length == 1, which return 1, resulting in an infinite // loop. break;
}
} return steps;
}
staticvoid resize_multistep(const uint8_t *const input, int length,
uint8_t *output, int olength, uint8_t *otmp) { int steps; if (length == olength) {
memcpy(output, input, sizeof(output[0]) * length); return;
}
steps = get_down2_steps(length, olength);
if (steps > 0) { int s;
uint8_t *out = NULL;
uint8_t *otmp2; int filteredlength = length;
assert(otmp != NULL);
otmp2 = otmp + get_down2_length(length, 1); for (s = 0; s < steps; ++s) { constint proj_filteredlength = get_down2_length(filteredlength, 1); const uint8_t *const in = (s == 0 ? input : out); if (s == steps - 1 && proj_filteredlength == olength)
out = output; else
out = (s & 1 ? otmp2 : otmp); if (filteredlength & 1)
down2_symodd(in, filteredlength, out); else
down2_symeven(in, filteredlength, out);
filteredlength = proj_filteredlength;
} if (filteredlength != olength) {
interpolate(out, filteredlength, output, olength);
}
} else {
interpolate(input, length, output, olength);
}
}
staticvoid fill_col_to_arr(uint8_t *img, int stride, int len, uint8_t *arr) { int i;
uint8_t *iptr = img;
uint8_t *aptr = arr; for (i = 0; i < len; ++i, iptr += stride) {
*aptr++ = *iptr;
}
}
staticvoid fill_arr_to_col(uint8_t *img, int stride, int len, uint8_t *arr) { int i;
uint8_t *iptr = img;
uint8_t *aptr = arr; for (i = 0; i < len; ++i, iptr += stride) {
*iptr = *aptr++;
}
}
void vp9_resize_plane(const uint8_t *const input, int height, int width, int in_stride, uint8_t *output, int height2, int width2, int out_stride) { int i;
uint8_t *intbuf = (uint8_t *)calloc(width2 * height, sizeof(*intbuf));
uint8_t *tmpbuf =
(uint8_t *)calloc(width < height ? height : width, sizeof(*tmpbuf));
uint8_t *arrbuf = (uint8_t *)calloc(height, sizeof(*arrbuf));
uint8_t *arrbuf2 = (uint8_t *)calloc(height2, sizeof(*arrbuf2)); if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL || arrbuf2 == NULL) goto Error;
assert(width > 0);
assert(height > 0);
assert(width2 > 0);
assert(height2 > 0); for (i = 0; i < height; ++i)
resize_multistep(input + in_stride * i, width, intbuf + width2 * i, width2,
tmpbuf); for (i = 0; i < width2; ++i) {
fill_col_to_arr(intbuf + i, width2, height, arrbuf);
resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf);
fill_arr_to_col(output + i, out_stride, height2, arrbuf2);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.