cairo_pattern_t * gimp_cairo_stipple_pattern_create (const GimpRGB *fg, const GimpRGB *bg, gint index) { cairo_surface_t *surface; cairo_pattern_t *pattern; guchar *data; guchar *d; guchar fg_r, fg_g, fg_b, fg_a; guchar bg_r, bg_g, bg_b, bg_a; gint x, y; g_return_val_if_fail (fg != NULL, NULL); g_return_val_if_fail (bg != NULL, NULL); data = g_malloc (8 * 8 * 4); gimp_rgba_get_uchar (fg, &fg_r, &fg_g, &fg_b, &fg_a); gimp_rgba_get_uchar (bg, &bg_r, &bg_g, &bg_b, &bg_a); d = data; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { if ((x + y + index) % 8 >= 4) GIMP_CAIRO_ARGB32_SET_PIXEL (d, fg_r, fg_g, fg_b, fg_a); else GIMP_CAIRO_ARGB32_SET_PIXEL (d, bg_r, bg_g, bg_b, bg_a); d += 4; } } surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, 8, 8, 8 * 4); cairo_surface_set_user_data (surface, &surface_data_key, data, (cairo_destroy_func_t) g_free); pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); cairo_surface_destroy (surface); return pattern; }
static void gimp_view_renderer_gradient_render (GimpViewRenderer *renderer, GtkWidget *widget) { GimpViewRendererGradient *rendergrad = GIMP_VIEW_RENDERER_GRADIENT (renderer); GimpGradient *gradient = GIMP_GRADIENT (renderer->viewable); GimpGradientSegment *seg = NULL; GimpColorTransform *transform; guchar *buf; guchar *dest; gint dest_stride; gint x; gint y; gdouble dx, cur_x; GimpRGB color; buf = g_alloca (4 * renderer->width); dx = (rendergrad->right - rendergrad->left) / (renderer->width - 1); cur_x = rendergrad->left; for (x = 0, dest = buf; x < renderer->width; x++, dest += 4) { guchar r, g, b, a; seg = gimp_gradient_get_color_at (gradient, renderer->context, seg, cur_x, rendergrad->reverse, &color); cur_x += dx; gimp_rgba_get_uchar (&color, &r, &g, &b, &a); GIMP_CAIRO_ARGB32_SET_PIXEL (dest, r, g, b, a); } if (! renderer->surface) renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, renderer->width, renderer->height); cairo_surface_flush (renderer->surface); dest = cairo_image_surface_get_data (renderer->surface); dest_stride = cairo_image_surface_get_stride (renderer->surface); transform = gimp_view_renderer_get_color_transform (renderer, widget, babl_format ("cairo-ARGB32"), babl_format ("cairo-ARGB32")); if (transform) gimp_color_transform_process_pixels (transform, babl_format ("cairo-ARGB32"), buf, babl_format ("cairo-ARGB32"), buf, renderer->width); for (y = 0; y < renderer->height; y++, dest += dest_stride) { memcpy (dest, buf, renderer->width * 4); } cairo_surface_mark_dirty (renderer->surface); }
static void gimp_levels_tool_color_picked (GimpColorTool *color_tool, GimpColorPickState pick_state, GimpImageType sample_type, GimpRGB *color, gint color_index) { GimpLevelsTool *tool = GIMP_LEVELS_TOOL (color_tool); guchar col[5]; guint value; gimp_rgba_get_uchar (color, col + RED_PIX, col + GREEN_PIX, col + BLUE_PIX, col + ALPHA_PIX); value = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tool->active_picker), "pick_value")); if (value & ALL_CHANNELS && GIMP_IMAGE_TYPE_IS_RGB (sample_type)) { GimpHistogramChannel channel; /* first reset the value channel */ switch (value & 0xF) { case LOW_INPUT: tool->levels->low_input[GIMP_HISTOGRAM_VALUE] = 0; break; case GAMMA: tool->levels->gamma[GIMP_HISTOGRAM_VALUE] = 1.0; break; case HIGH_INPUT: tool->levels->high_input[GIMP_HISTOGRAM_VALUE] = 255; break; default: break; } /* then adjust all color channels */ for (channel = GIMP_HISTOGRAM_RED; channel <= GIMP_HISTOGRAM_BLUE; channel++) { levels_input_adjust_by_color (tool->levels, value, channel, col); } } else { levels_input_adjust_by_color (tool->levels, value, tool->channel, col); } levels_update (tool, ALL); gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool)); }
static VALUE rb_gimp_rgba_get_uchar (VALUE self) { Get_TypedStruct(self, GimpRGB, color); guchar r, g, b, a; gimp_rgba_get_uchar(color, &r, &g, &b, &a); return rb_ary_new3(4, INT2FIX(r), INT2FIX(g), INT2FIX(b), INT2FIX(a)); }
static void poke (GimpPixelRgn *dest_rgn, gint x, gint y, GimpRGB *color) { static guchar data[4]; gimp_rgba_get_uchar (color, &data[0], &data[1], &data[2], &data[3]); gimp_pixel_rgn_set_pixel (dest_rgn, data, x, y); }
void poke (gint x, gint y, GimpRGB *color, gpointer data) { static guchar col[4]; gimp_rgba_get_uchar (color, &col[0], &col[1], &col[2], &col[3]); gimp_pixel_rgn_set_pixel (&dest_region, col, x, y); }
void gimp_drawable_get_color_uchar (gint32 drawable_ID, const GimpRGB *color, guchar *color_uchar) { g_return_if_fail (color != NULL); g_return_if_fail (color_uchar != NULL); switch (gimp_drawable_type (drawable_ID)) { case GIMP_RGB_IMAGE: gimp_rgb_get_uchar (color, &color_uchar[0], &color_uchar[1], &color_uchar[2]); color_uchar[3] = 255; break; case GIMP_RGBA_IMAGE: gimp_rgba_get_uchar (color, &color_uchar[0], &color_uchar[1], &color_uchar[2], &color_uchar[3]); break; case GIMP_GRAY_IMAGE: color_uchar[0] = gimp_rgb_luminance_uchar (color); color_uchar[1] = 255; break; case GIMP_GRAYA_IMAGE: color_uchar[0] = gimp_rgb_luminance_uchar (color); gimp_rgba_get_uchar (color, NULL, NULL, NULL, &color_uchar[1]); break; default: break; } }
static void to_alpha_func (const guchar *src, guchar *dest, gint bpp, gpointer data) { GimpRGB color; if (bpp == 3) gimp_rgba_set_uchar (&color, src[0], src[1], src[2], 255); else gimp_rgba_set_uchar (&color, src[0], src[1], src[2], src[3]); color_to_alpha (&color, &pvals.color); gimp_rgba_get_uchar (&color, &dest[0], &dest[1], &dest[2], &dest[3]); }
static inline void filter (void) { static void (* overlap)(guchar *, const guchar *); GimpPixelRgn src; GimpPixelRgn dst; GimpRGB color; guchar pixel[4]; gint division_x; gint division_y; gint offset_x; gint offset_y; Tile *tiles; gint numof_tiles; Tile *t; gint i; gint x; gint y; gint move_max_pixels; gint clear_x0; gint clear_y0; gint clear_x1; gint clear_y1; gint clear_width; gint clear_height; guchar *pixels; guchar *buffer; gint dindex; gint sindex; gint px, py; GRand *gr; gr = g_rand_new (); /* INITIALIZE */ gimp_pixel_rgn_init (&src, p.drawable, 0, 0, p.drawable->width, p.drawable->height, FALSE, FALSE); gimp_pixel_rgn_init (&dst, p.drawable, 0, 0, p.drawable->width, p.drawable->height, TRUE, TRUE); pixels = g_new (guchar, p.drawable->bpp * p.drawable->width * p.drawable->height); buffer = g_new (guchar, p.drawable->bpp * p.params.tile_width * p.params.tile_height); overlap = p.drawable_has_alpha ? overlap_RGBA : overlap_RGB; gimp_progress_init (_("Paper Tile")); gimp_drawable_mask_bounds (p.drawable->drawable_id, &p.selection.x0, &p.selection.y0, &p.selection.x1, &p.selection.y1); p.selection.width = p.selection.x1 - p.selection.x0; p.selection.height = p.selection.y1 - p.selection.y0; gimp_tile_cache_ntiles (2 * (p.selection.width / gimp_tile_width () + 1)); /* TILES */ division_x = p.params.division_x; division_y = p.params.division_y; if (p.params.fractional_type == FRACTIONAL_TYPE_FORCE) { if (0 < p.drawable->width % p.params.tile_width) division_x++; if (0 < p.drawable->height % p.params.tile_height) division_y++; if (p.params.centering) { if (1 < p.drawable->width % p.params.tile_width) { division_x++; offset_x = (p.drawable->width % p.params.tile_width) / 2 - p.params.tile_width; } else { offset_x = 0; } if (1 < p.drawable->height % p.params.tile_height) { division_y++; offset_y = (p.drawable->height % p.params.tile_height) / 2 - p.params.tile_height; } else { offset_y = 0; } } else { offset_x = 0; offset_y = 0; } } else { if (p.params.centering) { offset_x = (p.drawable->width % p.params.tile_width) / 2; offset_y = (p.drawable->height % p.params.tile_height) / 2; } else { offset_x = 0; offset_y = 0; } } move_max_pixels = p.params.move_max_rate * p.params.tile_width / 100.0; numof_tiles = division_x * division_y; t = tiles = g_new(Tile, numof_tiles); for (y = 0; y < division_y; y++) { gint srcy = offset_y + p.params.tile_height * y; for (x = 0; x < division_x; x++, t++) { gint srcx = offset_x + p.params.tile_width * x; if (srcx < 0) { t->x = 0; t->width = srcx + p.params.tile_width; } else if (srcx + p.params.tile_width < p.drawable->width) { t->x = srcx; t->width = p.params.tile_width; } else { t->x = srcx; t->width = p.drawable->width - srcx; } if (srcy < 0) { t->y = 0; t->height = srcy + p.params.tile_height; } else if (srcy + p.params.tile_height < p.drawable->height) { t->y = srcy; t->height = p.params.tile_height; } else { t->y = srcy; t->height = p.drawable->height - srcy; } t->z = g_rand_int (gr); random_move (&t->move_x, &t->move_y, move_max_pixels); } } qsort (tiles, numof_tiles, sizeof *tiles, tile_compare); gimp_pixel_rgn_get_rect (&src, pixels, 0, 0, p.drawable->width, p.drawable->height); if (p.params.fractional_type == FRACTIONAL_TYPE_IGNORE) { clear_x0 = offset_x; clear_y0 = offset_y; clear_width = p.params.tile_width * division_x; clear_height = p.params.tile_height * division_y; } else { clear_x0 = 0; clear_y0 = 0; clear_width = p.drawable->width; clear_height = p.drawable->height; } clear_x1 = clear_x0 + clear_width; clear_y1 = clear_y0 + clear_height; switch (p.params.background_type) { case BACKGROUND_TYPE_TRANSPARENT: for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for (i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = 0; } } } break; case BACKGROUND_TYPE_INVERTED: for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); pixels[dindex+0] = 255 - pixels[dindex+0]; pixels[dindex+1] = 255 - pixels[dindex+1]; pixels[dindex+2] = 255 - pixels[dindex+2]; } } break; case BACKGROUND_TYPE_IMAGE: break; case BACKGROUND_TYPE_FOREGROUND: gimp_context_get_foreground (&color); gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]); pixel[3] = 255; for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for (i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = pixel[i]; } } } break; case BACKGROUND_TYPE_BACKGROUND: gimp_context_get_background (&color); gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]); pixel[3] = 255; for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for(i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = pixel[i]; } } } break; case BACKGROUND_TYPE_COLOR: gimp_rgba_get_uchar (&p.params.background_color, pixel, pixel + 1, pixel + 2, pixel + 3); for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for(i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = pixel[i]; } } } break; } /* DRAW */ for (t = tiles, i = 0; i < numof_tiles; i++, t++) { gint x0 = t->x + t->move_x; gint y0 = t->y + t->move_y; gimp_pixel_rgn_get_rect (&src, buffer, t->x, t->y, t->width, t->height); for (y = 0; y < t->height; y++) { py = y0 + y; for (x = 0; x < t->width; x++) { px = x0 + x; sindex = p.drawable->bpp * (t->width * y + x); if (0 <= px && px < p.drawable->width && 0 <= py && py < p.drawable->height) { dindex = p.drawable->bpp * (p.drawable->width * py + px); overlap(&pixels[dindex], &buffer[sindex]); } else if (p.params.wrap_around) { px = (px + p.drawable->width) % p.drawable->width; py = (py + p.drawable->height) % p.drawable->height; dindex = p.drawable->bpp * (p.drawable->width * py + px); overlap(&pixels[dindex], &buffer[sindex]); } } } gimp_progress_update ((gdouble) i / (gdouble) numof_tiles); } gimp_pixel_rgn_set_rect (&dst, pixels, 0, 0, p.drawable->width, p.drawable->height); gimp_progress_update (1.0); gimp_drawable_flush (p.drawable); gimp_drawable_merge_shadow (p.drawable->drawable_id, TRUE); gimp_drawable_update (p.drawable->drawable_id, p.selection.x0, p.selection.y0, p.selection.width, p.selection.height); g_rand_free (gr); g_free (buffer); g_free (pixels); g_free (tiles); }
static void prepare_coef (params *p) { GimpRGB color1; GimpRGB color2; gdouble scalex = svals.scalex; gdouble scaley = svals.scaley; GRand *gr; gr = g_rand_new (); g_rand_set_seed (gr, svals.seed); switch (svals.colorization) { case BILINEAR: p->blend = bilinear; break; case SINUS: p->blend = cosinus; break; case LINEAR: default: p->blend = linear; } if (svals.perturbation==IDEAL) { /* Presumably the 0 * g_rand_int ()s are to pop random * values off the prng, I don't see why though. */ p->c11= 0 * g_rand_int (gr); p->c12= g_rand_double_range (gr, -1, 1) * scaley; p->c13= g_rand_double_range (gr, 0, 2 * G_PI); p->c21= 0 * g_rand_int (gr); p->c22= g_rand_double_range (gr, -1, 1) * scaley; p->c23= g_rand_double_range (gr, 0, 2 * G_PI); p->c31= g_rand_double_range (gr, -1, 1) * scalex; p->c32= 0 * g_rand_int (gr); p->c33= g_rand_double_range (gr, 0, 2 * G_PI); } else { p->c11= g_rand_double_range (gr, -1, 1) * scalex; p->c12= g_rand_double_range (gr, -1, 1) * scaley; p->c13= g_rand_double_range (gr, 0, 2 * G_PI); p->c21= g_rand_double_range (gr, -1, 1) * scalex; p->c22= g_rand_double_range (gr, -1, 1) * scaley; p->c23= g_rand_double_range (gr, 0, 2 * G_PI); p->c31= g_rand_double_range (gr, -1, 1) * scalex; p->c32= g_rand_double_range (gr, -1, 1) * scaley; p->c33= g_rand_double_range (gr, 0, 2 * G_PI); } if (svals.tiling) { p->c11= ROUND (p->c11/(2*G_PI))*2*G_PI; p->c12= ROUND (p->c12/(2*G_PI))*2*G_PI; p->c21= ROUND (p->c21/(2*G_PI))*2*G_PI; p->c22= ROUND (p->c22/(2*G_PI))*2*G_PI; p->c31= ROUND (p->c31/(2*G_PI))*2*G_PI; p->c32= ROUND (p->c32/(2*G_PI))*2*G_PI; } color1 = svals.col1; color2 = svals.col2; if (drawable_is_grayscale) { gimp_rgb_set (&color1, 1.0, 1.0, 1.0); gimp_rgb_set (&color2, 0.0, 0.0, 0.0); } else { switch (svals.colors) { case USE_COLORS: break; case B_W: gimp_rgb_set (&color1, 1.0, 1.0, 1.0); gimp_rgb_set (&color2, 0.0, 0.0, 0.0); break; case USE_FG_BG: gimp_context_get_background (&color1); gimp_context_get_foreground (&color2); break; } } gimp_rgba_get_uchar (&color1, &p->r, &p->g, &p->b, &p->a); gimp_rgba_subtract (&color2, &color1); p->dr = color2.r * 255.0; p->dg = color2.g * 255.0; p->db = color2.b * 255.0; p->da = color2.a * 255.0; g_rand_free (gr); }
static void grid (gint32 image_ID, GimpDrawable *drawable, GimpPreview *preview) { GimpPixelRgn srcPR, destPR; gint bytes; gint x_offset, y_offset; guchar *dest, *buffer = NULL; gint x, y; gboolean alpha; gboolean blend; guchar hcolor[4]; guchar vcolor[4]; guchar icolor[4]; guchar *cmap; gint ncolors; gimp_rgba_get_uchar (&grid_cfg.hcolor, hcolor, hcolor + 1, hcolor + 2, hcolor + 3); gimp_rgba_get_uchar (&grid_cfg.vcolor, vcolor, vcolor + 1, vcolor + 2, vcolor + 3); gimp_rgba_get_uchar (&grid_cfg.icolor, icolor, icolor + 1, icolor + 2, icolor + 3); switch (gimp_image_base_type (image_ID)) { case GIMP_RGB: blend = TRUE; break; case GIMP_GRAY: hcolor[0] = gimp_rgb_luminance_uchar (&grid_cfg.hcolor); vcolor[0] = gimp_rgb_luminance_uchar (&grid_cfg.vcolor); icolor[0] = gimp_rgb_luminance_uchar (&grid_cfg.icolor); blend = TRUE; break; case GIMP_INDEXED: cmap = gimp_image_get_colormap (image_ID, &ncolors); hcolor[0] = best_cmap_match (cmap, ncolors, &grid_cfg.hcolor); vcolor[0] = best_cmap_match (cmap, ncolors, &grid_cfg.vcolor); icolor[0] = best_cmap_match (cmap, ncolors, &grid_cfg.icolor); g_free (cmap); blend = FALSE; break; default: g_assert_not_reached (); blend = FALSE; } bytes = drawable->bpp; alpha = gimp_drawable_has_alpha (drawable->drawable_id); if (preview) { gimp_preview_get_position (preview, &sx1, &sy1); gimp_preview_get_size (preview, &sx2, &sy2); buffer = g_new (guchar, bytes * sx2 * sy2); sx2 += sx1; sy2 += sy1; } else { gimp_drawable_mask_bounds (drawable->drawable_id, &sx1, &sy1, &sx2, &sy2); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, sx2 - sx1, sy2 - sy1, TRUE, TRUE); } gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, sx2 - sx1, sy2 - sy1, FALSE, FALSE); dest = g_new (guchar, (sx2 - sx1) * bytes); for (y = sy1; y < sy2; y++) { gimp_pixel_rgn_get_row (&srcPR, dest, sx1, y, (sx2 - sx1)); y_offset = y - grid_cfg.hoffset; while (y_offset < 0) y_offset += grid_cfg.hspace; if ((y_offset + (grid_cfg.hwidth / 2)) % grid_cfg.hspace < grid_cfg.hwidth) { for (x = sx1; x < sx2; x++) { pix_composite (&dest[(x-sx1) * bytes], hcolor, bytes, blend, alpha); } } for (x = sx1; x < sx2; x++) { x_offset = grid_cfg.vspace + x - grid_cfg.voffset; while (x_offset < 0) x_offset += grid_cfg.vspace; if ((x_offset + (grid_cfg.vwidth / 2)) % grid_cfg.vspace < grid_cfg.vwidth) { pix_composite (&dest[(x-sx1) * bytes], vcolor, bytes, blend, alpha); } if ((x_offset + (grid_cfg.iwidth / 2)) % grid_cfg.vspace < grid_cfg.iwidth && ((y_offset % grid_cfg.hspace >= grid_cfg.ispace && y_offset % grid_cfg.hspace < grid_cfg.ioffset) || (grid_cfg.hspace - (y_offset % grid_cfg.hspace) >= grid_cfg.ispace && grid_cfg.hspace - (y_offset % grid_cfg.hspace) < grid_cfg.ioffset))) { pix_composite (&dest[(x-sx1) * bytes], icolor, bytes, blend, alpha); } } if ((y_offset + (grid_cfg.iwidth / 2)) % grid_cfg.hspace < grid_cfg.iwidth) { for (x = sx1; x < sx2; x++) { x_offset = grid_cfg.vspace + x - grid_cfg.voffset; while (x_offset < 0) x_offset += grid_cfg.vspace; if ((x_offset % grid_cfg.vspace >= grid_cfg.ispace && x_offset % grid_cfg.vspace < grid_cfg.ioffset) || (grid_cfg.vspace - (x_offset % grid_cfg.vspace) >= grid_cfg.ispace && grid_cfg.vspace - (x_offset % grid_cfg.vspace) < grid_cfg.ioffset)) { pix_composite (&dest[(x-sx1) * bytes], icolor, bytes, blend, alpha); } } } if (preview) { memcpy (buffer + (y - sy1) * (sx2 - sx1) * bytes, dest, (sx2 - sx1) * bytes); } else { gimp_pixel_rgn_set_row (&destPR, dest, sx1, y, (sx2 - sx1)); if (y % 16 == 0) gimp_progress_update ((gdouble) y / (gdouble) (sy2 - sy1)); } } g_free (dest); if (preview) { gimp_preview_draw_buffer (preview, buffer, bytes * (sx2 - sx1)); g_free (buffer); } else { gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, sx1, sy1, sx2 - sx1, sy2 - sy1); } }