diff --git a/src/refocus.c b/src/refocus.c index f27e465..c5020d7 100644 --- a/src/refocus.c +++ b/src/refocus.c @@ -18,12 +18,6 @@ * along with this program. If not, see . */ -#if __has_include("refocus-config.h") -#include "refocus-config.h" -#else -#define PLUGIN_VERSION "refocus is local" -#endif - #include #include #include @@ -33,12 +27,12 @@ #include #include #include +#include "util.h" #include "refocus.h" #include "prevman.h" #include "matrix.h" #include "conv.h" #include "bdclosure.h" -#include "util.h" /* No i18n for now */ #define _(x) x @@ -85,6 +79,10 @@ typedef struct { typedef struct { config *config; GimpDrawable *drawable; + gint rgb; + gint bpp; + gint bpc; + const Babl *format; CMat *matrix; gdouble mat_width_d; } ref_params; @@ -95,6 +93,7 @@ static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals); +static int color_size (const Babl *format, gint is_rgb); static gboolean refocus_dialog (ref_params *params); static gint doit (ref_params *params); static int check_config_values (config *my_config, gboolean reset); @@ -184,13 +183,25 @@ static void run (const gchar *name, gint n_params, const GimpParam *param, my_params.drawable = drawable = gimp_drawable_get (param[2].data.d_drawable); /* Make sure that the drawable is gray or RGB color */ - if (!gimp_drawable_is_rgb (drawable->drawable_id) && + if (!(my_params.rgb = gimp_drawable_is_rgb (drawable->drawable_id)) && !gimp_drawable_is_gray (drawable->drawable_id)) { g_message("Image is not RGB, RGBA, gray or grayA!"); status = GIMP_PDB_EXECUTION_ERROR;; return; } + gegl_init (NULL, NULL); + + my_params.format = gimp_drawable_get_format (drawable->drawable_id); + my_params.bpp = babl_format_get_bytes_per_pixel (my_params.format); + my_params.bpc = color_size (my_params.format, my_params.rgb); +#ifdef RF_DEBUG + printf("Image size: X=%d Y=%d, ", + my_params.drawable->width, my_params.drawable->height); + printf("bytes per pixel=%d, bytes per color=%d\n", + my_params.bpp, my_params.bpc); +#endif + /* Although the convolution should work fine with a tiny cache, it is made bigger to improve scrolling speed */ gimp_tile_cache_ntiles (20); @@ -250,9 +261,55 @@ static void run (const gchar *name, gint n_params, const GimpParam *param, gimp_drawable_detach (drawable); } + gegl_exit (); + values[0].data.d_status = status; } +static int color_size (const Babl *format, gint is_rgb) { + int bpp = babl_format_get_bytes_per_pixel (format); + const char *str = babl_get_name (format); + +#ifdef RF_DEBUG + printf("color_size(), format=<%s>, bytes per pixel=%d\n", str, bpp); +#endif + if (strstr(str, "double") != NULL) + return (-8); /* IEEE 754 double precision */ + if (strstr(str, "float") != NULL) + return (-4); /* IEEE 754 single precision */ + //if (strstr(str, "half") != NULL) + // return (-2); /* IEEE 754 half precision */ + if (strstr(str, "u15") != NULL) + return (-99); /* TODO for another day */ + if (strstr(str, " u") == NULL) + return (-99); /* not unsigned integer size */ + if (is_rgb) { /* RGB, RGBA */ + if (bpp > 32) + return (-99); /* unknown size */ + if (bpp >= 24) + return (8); + if (bpp >= 12) + return (4); + if (bpp >= 6) + return (2); + if (bpp >= 3) + return (1); + } else { /* gray, grayA */ + if (bpp > 16) + return (-99); /* unknown size */ + if (bpp >= 8) + return (8); + if (bpp >= 4) + return (4); + if (bpp >= 2) + return (2); + return (1); + } + + /* probably RGB in 1 byte, TODO for another day */ + return (-99); +} + static int update_matrix (ref_params *params) { /* Recompute matrix if needed */ CMat circle, gaussian, convolution; @@ -351,8 +408,7 @@ static void preview_callback (GtkWidget * widget, ref_params *params) { GimpDrawablePreview *preview; GimpPreview *ptr; gint32 preview_ID; - gint image_x, image_y, im_width, im_height, bppImg; - const Babl *format; + gint image_x, image_y, im_width, im_height; TileSource source; TileSink sink; gint row; @@ -366,8 +422,6 @@ static void preview_callback (GtkWidget * widget, ref_params *params) { gimp_preview_get_size (ptr, &im_width, &im_height); preview_ID = gimp_drawable_preview_get_drawable_id (preview); - format = gimp_drawable_get_format (preview_ID); - bppImg = babl_format_get_bytes_per_pixel(format); params->config->mat_width = round(params->mat_width_d); if (!(update_matrix (params))) return; @@ -383,12 +437,12 @@ static void preview_callback (GtkWidget * widget, ref_params *params) { TB_BOUNDARY_MIRROR, params->matrix, 2 * params->config->mat_width + 1, &update_progress_closure); - buf = g_new (guchar, im_height * im_width * bppImg); + buf = g_new (guchar, im_height * im_width * params->bpp); for (row = 0; event_is_current && (row < im_height); row++) { - tile_sink_get_row (&sink, &buf[row * im_width * bppImg], + tile_sink_get_row (&sink, &buf[row * im_width * params->bpp], image_x, image_y + row, im_width); }; - gimp_preview_draw_buffer (ptr, buf, im_width * bppImg); + gimp_preview_draw_buffer (ptr, buf, im_width * params->bpp); g_free (buf); tile_sink_free_buffers (&sink); } diff --git a/src/util.c b/src/util.c index fd4718d..ff6dcd3 100644 --- a/src/util.c +++ b/src/util.c @@ -1,9 +1,12 @@ /* Refocus plug-in - * Copyright (C) 1999-2003 Ernst Lippe - * - * This program is free software; you can redistribute it and/or modify + * Copyright (C) 1999-2004... Ernst Lippe - (original author) + * Copyright (C) 2024 Jose Da Silva (updates and improvements) + * + * Based on the Convolution Matrix plug-in by Lauri Alanko + * + * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -12,21 +15,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Version $Id: util.c,v 1.1.1.1 2003/01/30 21:30:19 ernstl Exp $ + * along with this program. If not, see . */ #include -#include "util.h" #include -#include #include - -#ifndef lint -static char vcid[] GCC_UNUSED = "$Id: util.c,v 1.1.1.1 2003/01/30 21:30:19 ernstl Exp $"; -#endif /* lint */ +#include +#include "util.h" gint floorm (gint a, gint b) @@ -120,3 +116,81 @@ tile_height (void) { return (gimp_tile_height ()); } + +/** + * get_pixel: + * @ptr: pointer to pixel_color value in source image. + * @bpc: color value type as defined from refocus.c:run(). + * This function gets a color pixel from the source image + * and returns a converted double[0.0..1.0] value. + **/ +gdouble +get_pixel (guchar *ptr, gint bpc) +{ + /* Returned value is in the range of [0.0..1.0]. */ + gdouble ret = 0.0; + if (bpc == 1) { + ret += *ptr; + ret /= 255; + } else if (bpc == 2) { + uint16_t *p = (uint16_t *)(ptr); + ret += *p; + ret /= 65535; + } else if (bpc == 4) { + uint32_t *p = (uint32_t *)(ptr); + ret += *p; + ret /= 4294967295; + } else if (bpc == 8) { + uint64_t *p = (uint64_t *)(ptr); + long double lret = 0.0; + lret += *p; + lret /= 18446744073709551615UL; + ret = lret; + } else if (bpc == -8) { + double *p = (double *)(ptr); + ret += *p; + } else if (bpc == -4) { + float *p = (float *)(ptr); + ret += *p; +//} else if (bpc == -2) { +// half *p = ptr; +// ret += *p; + } + return ret; +} + +/** + * set_pixel: + * @dest: pointer to destination image to set color pixel. + * @d: input pixel_color value in range [0.0..1.0]. + * @bpc: color value type as defined from refocus.c:run(). + * This function sets a color pixel in destination image. + * The input value is a double in the range [0.0..1.0]. + **/ +void +set_pixel (guchar *dest, gdouble d, gint bpc) +{ + /* input value is in the range of [0.0..1.0]. */ + if (bpc == 1) { + *dest = round (d * 255); + } else if (bpc == 2) { + uint16_t *p = (uint16_t *)(dest); + *p = round (d * 65535); + } else if (bpc == 4) { + uint32_t *p = (uint32_t *)(dest); + *p = round (d * 4294967295); + } else if (bpc == 8) { + uint64_t *p = (uint64_t *)(dest); + *p = roundl (d * 18446744073709551615UL); + } else if (bpc == -8) { + double *p = (double *)(dest); + *p = d; + } else if (bpc == -4) { + float *p = (float *)(dest); + *p = (float)(d); +//} else if (bpc == -2) { +// half *p = (half *)(dest); +// *p = d; + } + return; +} diff --git a/src/util.h b/src/util.h index 8e6f058..12e55e8 100644 --- a/src/util.h +++ b/src/util.h @@ -1,9 +1,11 @@ /* Refocus plug-in - * Copyright (C) 1999-2003 Ernst Lippe - * - * This program is free software; you can redistribute it and/or modify + * Copyright (C) 1999-2004... Ernst Lippe + * + * Based on the Convolution Matrix plug-in by Lauri Alanko + * + * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -12,19 +14,20 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Version $Id: util.h,v 1.1.1.1 2003/01/30 21:30:19 ernstl Exp $ + * along with this program. If not, see . */ #ifndef UTIL_H_INCLUDED #define UTIL_H_INCLUDED #include +#if __has_include("refocus-config.h") +#include "refocus-config.h" +#else +#define PLUGIN_VERSION "refocus is local" +#endif G_BEGIN_DECLS - /* This macro can be used to silence gcc's warnings about unused variables. */ #ifdef __GNUC__ #define GCC_UNUSED __attribute__ ((__unused__)) @@ -32,7 +35,6 @@ G_BEGIN_DECLS #define GCC_UNUSED #endif - extern gint floorm (gint a, gint b); extern gint ceilm (gint a, gint b); @@ -47,5 +49,9 @@ extern gint tile_width (void); extern gint tile_height (void); +gdouble get_pixel (guchar *ptr, gint bpc); + +void set_pixel (guchar *dest, gdouble d, gint bpc); + G_END_DECLS #endif /* UTIL_H_INCLUDED */