📄 video_util_resize.cpp
字号:
scaler_t *scale_image_init(image_t *dst, image_t *src, double (*filterf)(double), double fwidth){ scaler_t *scaler; int i, j, k; /* loop variables */ int n; /* pixel number */ int xx; double center = 0.0, left, right; /* filter calculation variables */ double width, fscale, weight; /* filter calculation variables */ double xscale, yscale; double maxwidth; CLIST contribX; CLIST *contribY; instruction_t *prg; scaler = (scaler_t*)malloc(sizeof(scaler_t)); scaler->src = src; scaler->dst = dst; /* create intermediate column to hold horizontal dst column scale */ scaler->tmp = (pixel_t*)malloc(src->ysize * sizeof(pixel_t)); if(scaler->tmp == NULL) { free(scaler); return 0; } xscale = (double) dst->xsize / (double) src->xsize; /* Build y weights */ /* pre-calculate filter contributions for a column */ contribY = (CLIST *)calloc(dst->ysize, sizeof(CLIST)); if(contribY == NULL) { free(scaler->tmp); free(scaler); return 0; } yscale = (double) dst->ysize / (double) src->ysize; if(yscale < 1.0) { width = fwidth / yscale; fscale = 1.0 / yscale; for(i = 0; i < dst->ysize; ++i) { contribY[i].n = 0; contribY[i].p = (CONTRIB *)calloc((int) (width * 2 + 1), sizeof(CONTRIB)); if(contribY[i].p == NULL) { free(scaler->tmp); free(contribY); free(scaler); return 0; } center = (double) i / yscale; left = ceil(center - width); right = floor(center + width); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight / fscale) / fscale; if(j < 0) { n = -j; } else if(j >= src->ysize) { n = (src->ysize - j) + src->ysize - 1; } else { n = j; } k = contribY[i].n++; contribY[i].p[k].pixel = n; contribY[i].p[k].weight = double2fixdouble(weight); } } } else { for(i = 0; i < dst->ysize; ++i) { contribY[i].n = 0; contribY[i].p = (CONTRIB *)calloc((int) (fwidth * 2 + 1), sizeof(CONTRIB)); if(contribY[i].p == NULL) { free(scaler->tmp); free(scaler); return 0; } center = (double) i / yscale; left = ceil(center - fwidth); right = floor(center + fwidth); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight); if(j < 0) { n = -j; } else if(j >= src->ysize) { n = (src->ysize - j) + src->ysize - 1; } else { n = j; } k = contribY[i].n++; contribY[i].p[k].pixel = n; contribY[i].p[k].weight = double2fixdouble(weight); } } } /* ------------------------------------------------------------- streamline contributions into two simple bytecode programs. This single optimalization nearly doubles the performance! */ maxwidth = fwidth; if (xscale < 1.0 || yscale < 1.0) maxwidth = fwidth / (xscale < yscale ? xscale : yscale); prg = scaler->programX = (instruction_t*)calloc(scaler->dst->xsize * (2 + 2*(int)(maxwidth*2+1)), sizeof(instruction_t)); for(xx = 0; xx < scaler->dst->xsize; xx++) { calc_x_contrib(&contribX, xscale, fwidth, scaler->dst->xsize, scaler->src->xsize, filterf, xx); /*pel = get_pixel(scaler->src, contribX.p[0].pixel, k);*/ (prg++)->index = contribX.p[0].pixel * scaler->src->span; (prg++)->count = contribX.n; for(j = 0; j < contribX.n; ++j) { /*pel2 = get_pixel(scaler->src, contribX.p[j].pixel, k);*/ (prg++)->index = contribX.p[j].pixel * scaler->src->span; /*weight += pel2 * contribX.p[j].weight;*/ (prg++)->weight = contribX.p[j].weight; } free(contribX.p); } prg = scaler->programY = (instruction_t*)calloc(scaler->dst->ysize * (2 + 2*(int)(maxwidth*2+1)), sizeof(instruction_t)); /* The temp column has been built. Now stretch it vertically into dst column. */ for(i = 0; i < scaler->dst->ysize; ++i) { /**(prg++) = scaler->contribY[i].p[0].pixel;*/ (prg++)->pixel = scaler->tmp + contribY[i].p[0].pixel; (prg++)->count = contribY[i].n; for(j = 0; j < contribY[i].n; ++j) { /*(prg++) = scaler->contribY[i].p[j].pixel;*/ (prg++)->pixel = scaler->tmp + contribY[i].p[j].pixel; (prg++)->weight = contribY[i].p[j].weight; } } /* next dst row */ /* --------------------------------------------------- free the memory allocated for vertical filter weights -- no longer needed, we have programX and programY */ for(i = 0; i < scaler->dst->ysize; ++i) free(contribY[i].p); free(contribY); return scaler;}void scale_image_process(scaler_t *scaler){ int x; int i = 0, j, k; /* loop variables */ pixel_t pel, pel2; int bPelDelta; fixdouble weight; pixel_t *in; pixel_t *out = scaler->dst->data; pixel_t *tmpOut; instruction_t *prgY, *prgX = NULL, *prgXa; prgXa = scaler->programX; for(x = scaler->dst->xsize; x; --x) { /* Apply horz filter to make dst column in tmp. */ for(in = scaler->src->data, tmpOut = scaler->tmp, k = scaler->src->ysize; k; --k, in++) { prgX = prgXa; weight = 0; bPelDelta = false; pel = in[(prgX++)->index]; for(j = (prgX++)->count; j; --j) { pel2 = in[(prgX++)->index]; if(pel2 != pel) { bPelDelta = true; } weight += pel2 * (prgX++)->weight; } *(tmpOut++) = bPelDelta ? (pixel_t)CLAMP(fixdouble2int(weight)) : pel; } /* next row in temp column */ prgXa = prgX; /* * The temp column has been built. * Now stretch it vertically into dst column. */ prgY = scaler->programY; for(i = scaler->dst->ysize; i; --i) { weight = 0; bPelDelta = false; pel = *((prgY++)->pixel); for(j = (prgY++)->count; j; --j) { pel2 = *((prgY++)->pixel); if(pel2 != pel) { bPelDelta = true; } weight += pel2 * (prgY++)->weight; } *(out++) = bPelDelta ? (pixel_t)CLAMP(fixdouble2int(weight)) : pel; } /* next dst row */ } /* next dst column */}void scale_image_done(scaler_t *scaler){ free(scaler->tmp); free(scaler->programY); free(scaler->programX); free(scaler);}void CopyYuv (const uint8_t *fY, const uint8_t *fU, const uint8_t *fV, uint32_t fyStride, uint32_t fuStride, uint32_t fvStride, uint8_t *tY, uint8_t *tU, uint8_t *tV, uint32_t tyStride, uint32_t tuStride, uint32_t tvStride, uint32_t w, uint32_t h){ const uint8_t *from; uint8_t *to; uint ix; if (fY == NULL || fU == NULL || fV == NULL || tY == NULL || tU == NULL || tV == NULL) return; if (fyStride == tyStride) { memcpy(tY, fY, fyStride * h); } else { to = tY; from = fY; for (ix = 0; ix < h; ix++) { memcpy(to, from, w); to += tyStride; from += fyStride; } } h /= 2; w /= 2; if (fuStride == tuStride) { memcpy(tU, fU, fuStride * h); } else { to = tU; from = fU; for (ix = 0; ix < h; ix++) { memcpy(to, from, w); to += tuStride; from += fuStride; } } if (fvStride == tvStride) { memcpy(tV, fV, fvStride * h); } else { to = tV; from = fV; for (ix = 0; ix < h; ix++) { memcpy(to, from, w); to += tuStride; from += fuStride; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -