void lsm_filter_fast_blur (LsmFilterSurface *input, LsmFilterSurface *output, double sx, double sy) { gint kx, ky; guchar *intermediate; g_return_if_fail (input != NULL); g_return_if_fail (output != NULL); kx = floor (sx * 3 * sqrt (2 * M_PI) / 4 + 0.5); ky = floor (sy * 3 * sqrt (2 * M_PI) / 4 + 0.5); if (kx < 1 && ky < 1) return; intermediate = g_new (guchar, MAX (kx, ky)); box_blur (input, output, intermediate, kx, ky); box_blur (output, output, intermediate, kx, ky); box_blur (output, output, intermediate, kx, ky); g_free (intermediate); }
/** Requirements: img is SKRY_PIX_MONO8, box_radius < 2^11 */ struct SKRY_image *box_blur_img(const struct SKRY_image *img, unsigned box_radius, size_t iterations) { assert(SKRY_get_img_pix_fmt(img) == SKRY_PIX_MONO8); SKRY_Image *blurred = SKRY_new_image(SKRY_get_img_width(img), SKRY_get_img_height(img), SKRY_PIX_MONO8, 0, 0); if (blurred) { enum SKRY_result result = box_blur(SKRY_get_line(img, 0), SKRY_get_line(blurred, 0), SKRY_get_img_width(img), SKRY_get_img_height(img), SKRY_get_line_stride_in_bytes(img), SKRY_get_line_stride_in_bytes(blurred), box_radius, iterations); if (SKRY_SUCCESS == result) return blurred; else { SKRY_free_image(blurred); return 0; } } else return 0; }
/** Quality is the sum of differences between input image and its blurred version. In other words, sum of values of the high-frequency component. The sum is normalized by dividing by the number of pixels. */ SKRY_quality_t estimate_quality(uint8_t *pixels, unsigned width, unsigned height, ptrdiff_t line_stride, unsigned box_blur_radius) { uint8_t *blurred = malloc(width*height); box_blur(pixels, blurred, width, height, line_stride, width, box_blur_radius, QUALITY_ESTIMATE_BOX_BLUR_ITERATIONS); SKRY_quality_t quality = 0; uint8_t * restrict src_line = pixels; uint8_t * restrict blurred_line = blurred; for (unsigned y = 0; y < height; y++) { for (unsigned x = 0; x < width; x++) quality += abs(src_line[x] - blurred_line[x]); src_line += line_stride; blurred_line += width; } free(blurred); return quality / (width*height); }