Skip to content

Commit

Permalink
Import color_size(), get_pixel(), set_pixel() from gimp-fix-ca
Browse files Browse the repository at this point in the history
These functions will be useful for higher precision images.

Moved babl calls to refocus.c:run() so it is only called once.
  • Loading branch information
JoesCat committed Nov 26, 2024
1 parent 57afee1 commit c89f393
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 39 deletions.
84 changes: 69 additions & 15 deletions src/refocus.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#if __has_include("refocus-config.h")
#include "refocus-config.h"
#else
#define PLUGIN_VERSION "refocus is local"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
Expand All @@ -33,12 +27,12 @@
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#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
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
}
Expand Down
102 changes: 88 additions & 14 deletions src/util.c
Original file line number Diff line number Diff line change
@@ -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 <la@iki.fi>
*
* 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,
Expand All @@ -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 <https://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include "util.h"
#include <string.h>
#include <math.h>
#include <libgimp/gimp.h>

#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 <libgimp/gimpui.h>
#include "util.h"

gint
floorm (gint a, gint b)
Expand Down Expand Up @@ -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;
}
26 changes: 16 additions & 10 deletions src/util.h
Original file line number Diff line number Diff line change
@@ -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 <la@iki.fi>
*
* 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,
Expand All @@ -12,27 +14,27 @@
* 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 <https://www.gnu.org/licenses/>.
*/

#ifndef UTIL_H_INCLUDED
#define UTIL_H_INCLUDED
#include <glib.h>
#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__))
#else
#define GCC_UNUSED
#endif


extern gint floorm (gint a, gint b);

extern gint ceilm (gint a, gint b);
Expand All @@ -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 */

0 comments on commit c89f393

Please sign in to comment.