148 lines
4.5 KiB
C
148 lines
4.5 KiB
C
/*
|
|
MIT License
|
|
Copyright (c) 2021 ryuku (ryuku@ennui.software - https://git.ennui.software/)
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
|
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include <gimp-2.0/libgimp/gimp.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
static void query(void);
|
|
static void run(const gchar* name, gint nparams, const GimpParam* param, gint* nreturn_vals, GimpParam** return_vals);
|
|
|
|
GimpPlugInInfo PLUG_IN_INFO ={ NULL, NULL, query, run };
|
|
|
|
MAIN()
|
|
|
|
static void query(void)
|
|
{
|
|
static GimpParamDef args[] =
|
|
{
|
|
{
|
|
GIMP_PDB_INT32,
|
|
"run-mode",
|
|
"Run mode"
|
|
},
|
|
{
|
|
GIMP_PDB_IMAGE,
|
|
"image",
|
|
"Input image"
|
|
},
|
|
{
|
|
GIMP_PDB_DRAWABLE,
|
|
"drawable",
|
|
"Input drawable"
|
|
}
|
|
};
|
|
|
|
gimp_install_procedure(
|
|
"c-plug-in-circle-map",
|
|
"square image to circle",
|
|
"square image to circle",
|
|
"Ryuku (ryuku@ennui.software - https://git.ennui.software/)",
|
|
"Ryuku",
|
|
"2021",
|
|
"_Circle map...",
|
|
"RGB*, GRAY*",
|
|
GIMP_PLUGIN,
|
|
G_N_ELEMENTS (args),
|
|
0,
|
|
args,
|
|
NULL
|
|
);
|
|
|
|
gimp_plugin_menu_register("c-plug-in-circle-map", "<Image>/Filters/Misc");
|
|
}
|
|
|
|
static void run(const gchar* name, gint nparams, const GimpParam* param, gint* nreturn_vals, GimpParam** return_vals)
|
|
{
|
|
static GimpParam values[1];
|
|
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
|
|
|
*nreturn_vals = 1;
|
|
*return_vals = values;
|
|
|
|
values[0].type = GIMP_PDB_STATUS;
|
|
values[0].data.d_status = status;
|
|
|
|
gimp_progress_init("Processing..");
|
|
|
|
gint32 image_id = param[1].data.d_image;
|
|
gint32 layer_id = param[2].data.d_drawable;
|
|
|
|
GimpDrawable* layer = gimp_drawable_get(layer_id);
|
|
guint width = layer->width;
|
|
gimp_drawable_detach(layer);
|
|
|
|
gimp_layer_scale(layer_id, width, width, FALSE);
|
|
gimp_layer_add_alpha(layer_id);
|
|
|
|
gint32 new_layer_id = gimp_layer_new(image_id, "circle map", width, width, GIMP_RGBA_IMAGE, 100.0, GIMP_NORMAL_MODE);
|
|
gimp_image_insert_layer(image_id, new_layer_id, 0, 0);
|
|
|
|
gdouble midx = width / 2;
|
|
gdouble midy = width / 2;
|
|
|
|
layer = gimp_drawable_get(layer_id);
|
|
GimpDrawable* new_layer = gimp_drawable_get(new_layer_id);
|
|
|
|
GimpPixelRgn orig_rgn;
|
|
gimp_pixel_rgn_init(&orig_rgn, layer, 0, 0, width, width, FALSE, FALSE);
|
|
|
|
GimpPixelRgn rgn;
|
|
gimp_pixel_rgn_init(&rgn, new_layer, 0, 0, width, width, FALSE, FALSE);
|
|
|
|
gdouble mx, my, nx, ny;
|
|
gint nbx, nby;
|
|
|
|
guchar* buf = malloc(4 * width * width);
|
|
guchar* new_buf = malloc(4 * width * width);
|
|
memset(buf, 0, 4 * width * width);
|
|
memset(new_buf, 0, 4 * width * width);
|
|
|
|
gimp_pixel_rgn_get_rect(&orig_rgn, buf, 0, 0, width, width);
|
|
|
|
for (guint x = 0; x < width; x++)
|
|
{
|
|
for (guint y = 0; y < width; y++)
|
|
{
|
|
mx = (x - midx) / midx;
|
|
my = (y - midy) / midy;
|
|
|
|
nx = mx * pow((1 - (my * my) / 2), 0.5);
|
|
ny = my * pow((1 - (mx * mx) / 2), 0.5);
|
|
|
|
nx = nx * midx + midx;
|
|
ny = ny * midy + midy;
|
|
|
|
nbx = nx;
|
|
nby = ny;
|
|
memcpy(new_buf + ((nbx + width * nby) * 4), buf + ((x + width * y) * 4), 4);
|
|
|
|
gimp_progress_update(y / width);
|
|
}
|
|
}
|
|
|
|
gimp_pixel_rgn_set_rect(&rgn, new_buf, 0, 0, width, width);
|
|
|
|
free(buf);
|
|
free(new_buf);
|
|
|
|
gimp_drawable_flush(new_layer);
|
|
gimp_drawable_update(new_layer_id, 0, 0, width, width);
|
|
|
|
gimp_drawable_detach(layer);
|
|
gimp_drawable_detach(new_layer);
|
|
} |