CConvolutionKernel::CConvolutionKernel(ESCALINGMETHOD method, int size) { m_size = size; m_floatpixels = new float[m_size * 4]; if (method == VS_SCALINGMETHOD_LANCZOS2) Lanczos2(); else if (method == VS_SCALINGMETHOD_SPLINE36_FAST) Spline36Fast(); else if (method == VS_SCALINGMETHOD_LANCZOS3_FAST) Lanczos3Fast(); else if (method == VS_SCALINGMETHOD_SPLINE36) Spline36(); else if (method == VS_SCALINGMETHOD_LANCZOS3) Lanczos3(); else if (method == VS_SCALINGMETHOD_CUBIC) Bicubic(1.0 / 3.0, 1.0 / 3.0); ToIntFract(); ToUint8(); }
void R_Resample(byte *source, int swidth, int sheight, byte *dest, int dwidth, int dheight, int components) { int i, j, k, l, count, left, right, num; int pixel; byte *raster; float center, weight, scale, width, height; contrib_list_t *contributors; // MD_PushTag(TAG_RESAMPLE); byte *work = (byte *)ri->Z_Malloc(dwidth * sheight * components, TAG_RESAMPLE, qfalse, 4); // Pre calculate filter contributions for rows contributors = (contrib_list_t *)ri->Z_Malloc(sizeof(contrib_list_t) * dwidth, TAG_RESAMPLE, qfalse, 4); float xscale = (float)dwidth / (float)swidth; if(xscale < 1.0f) { width = ceilf(LANCZOS3 / xscale); scale = xscale; } else { width = LANCZOS3; scale = 1.0f; } num = ((int)width * 2) + 1; for(i = 0; i < dwidth; i++) { contributors[i].n = 0; contributors[i].p = (contrib_t *)ri->Z_Malloc(num * sizeof(contrib_t), TAG_RESAMPLE, qfalse, 4); center = (float)i / xscale; left = (int)ceilf(center - width); right = (int)floorf(center + width); for(j = left; j <= right; j++) { weight = Lanczos3((center - (float)j) * scale) * scale; if(j < 0) { pixel = -j; } else if(j >= swidth) { pixel = (swidth - j) + swidth - 1; } else { pixel = j; } count = contributors[i].n++; contributors[i].p[count].pixel = pixel; contributors[i].p[count].weight = weight; } } // Apply filters to zoom horizontally from source to work for(k = 0; k < sheight; k++) { raster = source + (k * swidth * components); for(i = 0; i < dwidth; i++) { for(l = 0; l < components; l++) { weight = 0.0f; for(j = 0; j < contributors[i].n; j++) { weight += raster[(contributors[i].p[j].pixel * components) + l] * contributors[i].p[j].weight; } pixel = (byte)Com_Clamp(0.0f, 255.0f, weight); work[(k * dwidth * components) + (i * components) + l] = pixel; } } } // Clean up for(i = 0; i < dwidth; i++) { ri->Z_Free(contributors[i].p); } ri->Z_Free(contributors); // Columns contributors = (contrib_list_t *)ri->Z_Malloc(sizeof(contrib_list_t) * dheight, TAG_RESAMPLE, qfalse, 4); float yscale = (float)dheight / (float)sheight; if(yscale < 1.0f) { height = ceilf(LANCZOS3 / yscale); scale = yscale; } else { height = LANCZOS3; scale = 1.0f; } num = ((int)height * 2) + 1; for(i = 0; i < dheight; i++) { contributors[i].n = 0; contributors[i].p = (contrib_t *)ri->Z_Malloc(num * sizeof(contrib_t), TAG_RESAMPLE, qfalse, 4); center = (float)i / yscale; left = (int)ceilf(center - height); right = (int)floorf(center + height); for(j = left; j <= right; j++) { weight = Lanczos3((center - (float)j) * scale) * scale; if(j < 0) { pixel = -j; } else if(j >= sheight) { pixel = (sheight - j) + sheight - 1; } else { pixel = j; } count = contributors[i].n++; contributors[i].p[count].pixel = pixel; contributors[i].p[count].weight = weight; } } // Apply filter to columns for(k = 0; k < dwidth; k++) { for(l = 0; l < components; l++) { for(i = 0; i < dheight; i++) { weight = 0.0f; for(j = 0; j < contributors[i].n; j++) { weight += work[(contributors[i].p[j].pixel * dwidth * components) + (k * components) + l] * contributors[i].p[j].weight; } pixel = (byte)Com_Clamp(0.0f, 255.0f, weight); dest[(i * dwidth * components) + (k * components) + l] = pixel; } } } // Clean up for(i = 0; i < dheight; i++) { ri->Z_Free(contributors[i].p); } ri->Z_Free(contributors); ri->Z_Free(work); // MD_PopTag(); }