static void c2g_region (GimpPixelRgn *srcPR, GimpPixelRgn *destPR, gint bytes, /* Bytes per pixel */ gdouble radius, gdouble amount_p, gdouble gamma_p, gint x1, /* Corners of subregion */ gint x2, gint y1, gint y2, gboolean show_progress) { guchar *src; guchar *dest; guchar *bigsrc; guchar *bigdest; guchar *tmpdest; gint width = x2 - x1; gint height = y2 - y1; gdouble *cmatrix = NULL; gint cmatrix_length; gdouble *ctable; gint row, col, idx; gint w = c2g_params.radius+10; gdouble amount = c2g_params.amount; gdouble gamma = c2g_params.gamma; if (show_progress) gimp_progress_init (_("Blurring...")); iir_init(c2g_params.radius); /* allocate buffers */ src = g_new (guchar, MAX (width, height) * bytes); dest = g_new (guchar, MAX (width, height) * bytes); iir.p = g_new(gdouble, MAX (width, height)+2*w); bigsrc = g_new(guchar, width * height * bytes); bigdest = g_new(guchar, width * height * bytes); tmpdest = g_new(guchar, width * height * bytes); if (show_progress) gimp_progress_init (_("Colour converting...")); // 1. Calculate Nayatani Grey and Blur in LAB gimp_pixel_rgn_get_rect (srcPR, bigsrc, x1, y1, width, height); extract_lab(bigsrc, bytes, width * height, bigdest); nayatani(bigdest,bytes,width * height, bigdest); gimp_pixel_rgn_set_rect (destPR, bigdest, x1, y1, width, height); // 2. Make a blur of Grey LAB for (row = 0, idx=0; row < height; row++, idx+=width) { gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width); blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes); gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width); } for (col = 0; col < width; col++) { gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height); blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes); gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height); if (show_progress && col % 8 == 0) gimp_progress_update ((gdouble) col / (3 * width) + 0.33); } // 3. Convert grey and blur back to RGB. compose_lab(bigdest, width * height, bytes, bigdest); // bigdest=greyRGB gimp_pixel_rgn_get_rect (destPR, bigsrc, x1, y1, width, height); compose_lab(bigsrc, width * height, bytes, bigsrc); // bigsrc= blurgreyRGB // 4. Blur Colour RGB and write into destPR gimp_pixel_rgn_get_rect (srcPR, tmpdest, x1, y1, width, height); gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height); for (row = 0, idx=0; row < height; row++, idx+=width) { gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width); blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes); gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width); } for (col = 0; col < width; col++) { gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height); blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes); gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height); if (show_progress && col % 8 == 0) gimp_progress_update ((gdouble) col / (3 * width) + 0.33); } // destPR = blur colour RGB chromaunsharp( srcPR, destPR, bigdest, bigsrc, bytes, x1, y1, width, height, amount, gamma, tmpdest ); compose_lab(tmpdest, width * height, bytes, tmpdest); // tmpdest has unsharp gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height); if (show_progress) gimp_progress_update (0.0); g_free (bigsrc); g_free (bigdest); g_free (tmpdest); g_free (iir.p); g_free (dest); g_free (src); }
void y4munsharp(void) { int i, row, col, diff, value; u_char *i_ptr, *o_ptr; mjpeg_debug("Blurring Luma rows frame %d", frameno); for (row = 0; row < yheight; row++) { blur_line(ctable_y, cmatrix_y, cmatrix_y_len, &i_yuv[0][row * ywidth], &o_yuv[0][row * ywidth], ywidth); } if (uv_radius != -1.0) { mjpeg_debug("Blurring Chroma rows frame %d", frameno); for (row = 0; row < uvheight; row++) { blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len, &i_yuv[1][row * uvwidth], &o_yuv[1][row * uvwidth], uvwidth); blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len, &i_yuv[2][row * uvwidth], &o_yuv[2][row * uvwidth], uvwidth); } } else { memcpy(o_yuv[1], i_yuv[1], uvlen); memcpy(o_yuv[2], i_yuv[2], uvlen); } mjpeg_debug("Blurring Luma columns frame %d", frameno); for (col = 0; col < ywidth; col++) { /* * Do the entire frame if progressive, otherwise this does the only * the first field. */ get_column(&o_yuv[0][col], cur_col, interlaced ? 2 * ywidth : ywidth, interlaced ? yheight / 2 : yheight); blur_line(ctable_y, cmatrix_y, cmatrix_y_len, cur_col, dest_col, interlaced ? yheight / 2 : yheight); put_column(dest_col, &o_yuv[0][col], interlaced ? 2 * ywidth : ywidth, interlaced ? yheight / 2 : yheight); /* * If interlaced now process the second field (data source is offset * by 'ywidth'). */ if (interlaced) { get_column(&o_yuv[0][col + ywidth], cur_col, 2 * ywidth, yheight / 2); blur_line(ctable_y, cmatrix_y, cmatrix_y_len, cur_col, dest_col, interlaced ? yheight / 2 : yheight); put_column(dest_col, &o_yuv[0][col + ywidth], 2 * ywidth, yheight / 2); } } if (uv_radius == -1) goto merging; mjpeg_debug("Blurring chroma columns frame %d", frameno); for (col = 0; col < uvwidth; col++) { /* U */ get_column(&o_yuv[1][col], cur_col, interlaced ? 2 * uvwidth : uvwidth, interlaced ? uvheight / 2 : uvheight); blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len, cur_col, dest_col, interlaced ? uvheight / 2 : uvheight); put_column(dest_col, &o_yuv[1][col], interlaced ? 2 * uvwidth : uvwidth, interlaced ? uvheight / 2 : uvheight); if (interlaced) { get_column(&o_yuv[1][col + uvwidth], cur_col, 2 * uvwidth, uvheight / 2); blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len, cur_col, dest_col, interlaced ? uvheight / 2 : uvheight); put_column(dest_col, &o_yuv[1][col + uvwidth], 2 * uvwidth, uvheight / 2); } /* V */ get_column(&o_yuv[2][col], cur_col, interlaced ? 2 * uvwidth : uvwidth, interlaced ? uvheight / 2 : uvheight); blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len, cur_col, dest_col, interlaced ? uvheight / 2 : uvheight); put_column(dest_col, &o_yuv[2][col], interlaced ? 2 * uvwidth : uvwidth, interlaced ? uvheight / 2 : uvheight); if (interlaced) { get_column(&o_yuv[2][col + uvwidth], cur_col, 2 * uvwidth, uvheight / 2); blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len, cur_col, dest_col, interlaced ? uvheight / 2 : uvheight); put_column(dest_col, &o_yuv[2][col + uvwidth], 2 * uvwidth, uvheight / 2); } } merging: mjpeg_debug("Merging luma frame %d", frameno); for (row = 0, i_ptr = i_yuv[0], o_ptr = o_yuv[0]; row < yheight; row++) { for (i = 0; i < ywidth; i++, i_ptr++, o_ptr++) { diff = *i_ptr - *o_ptr; if (abs(2 * diff) < y_threshold) diff = 0; value = *i_ptr + (y_amount * diff); /* * For video the limits are 16 and 235 for the luma rather than 0 and 255! */ if (value < lowy) value = lowy; else if (value > highy) value = highy; *o_ptr = value; } } if (uv_radius == -1.0) goto done; mjpeg_debug("Merging chroma frame %d", frameno); for (row = 0, i_ptr = i_yuv[1], o_ptr = o_yuv[1]; row < uvheight; row++) { for (i = 0; i < uvwidth; i++, i_ptr++, o_ptr++) { diff = *i_ptr - *o_ptr; if (abs(2 * diff) < uv_threshold) diff = 0; value = *i_ptr + (uv_amount * diff); /* * For video the limits are 16 and 240 for the chroma rather than 0 and 255! */ if (value < lowuv) value = lowuv; else if (value > highuv) value = highuv; *o_ptr = value; } } for (row = 0, i_ptr = i_yuv[2], o_ptr = o_yuv[2]; row < uvheight; row++) { for (i = 0; i < uvwidth; i++, i_ptr++, o_ptr++) { diff = *i_ptr - *o_ptr; if (abs(2 * diff) < uv_threshold) diff = 0; value = *i_ptr + (uv_amount * diff); /* * For video the limits are 16 and 240 for the chroma rather than 0 and 255! */ if (value < 16) value = 16; else if (value > highuv) value = highuv; *o_ptr = value; } } done: return; }