void gimp_create_image_from_buffer (Gimp *gimp, GeglBuffer *buffer) { GimpImage *image; GimpLayer *layer; const Babl *format; g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (GEGL_IS_BUFFER (buffer)); format = gegl_buffer_get_format (buffer); image = gimp_create_image (gimp, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer), gimp_babl_format_get_base_type (format), gimp_babl_format_get_precision (format), FALSE); layer = gimp_layer_new_from_buffer (buffer, image, format, "Debug Image", GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE); gimp_image_add_layer (image, layer, NULL, -1, FALSE); gimp_create_display (gimp, image, GIMP_UNIT_PIXEL, 1.0); }
static GimpTempBuf * gimp_buffer_get_new_preview (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); const Babl *format = gimp_buffer_get_format (buffer); GimpTempBuf *preview; if (babl_format_is_palette (format)) format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA, babl_format_has_alpha (format)); else format = gimp_babl_format (gimp_babl_format_get_base_type (format), gimp_babl_precision (GIMP_COMPONENT_TYPE_U8, gimp_babl_format_get_linear (format)), babl_format_has_alpha (format)); preview = gimp_temp_buf_new (width, height, format); gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), MIN ((gdouble) width / (gdouble) gimp_buffer_get_width (buffer), (gdouble) height / (gdouble) gimp_buffer_get_height (buffer)), format, gimp_temp_buf_get_data (preview), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); return preview; }
GimpTempBuf * gimp_image_get_new_preview (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpImage *image = GIMP_IMAGE (viewable); const Babl *format; gboolean linear; GimpTempBuf *buf; gdouble scale_x; gdouble scale_y; scale_x = (gdouble) width / (gdouble) gimp_image_get_width (image); scale_y = (gdouble) height / (gdouble) gimp_image_get_height (image); format = gimp_projectable_get_format (GIMP_PROJECTABLE (image)); linear = gimp_babl_format_get_linear (format); format = gimp_babl_format (gimp_babl_format_get_base_type (format), gimp_babl_precision (GIMP_COMPONENT_TYPE_U8, linear), babl_format_has_alpha (format)); buf = gimp_temp_buf_new (width, height, format); gegl_buffer_get (gimp_pickable_get_buffer (GIMP_PICKABLE (image)), GEGL_RECTANGLE (0, 0, width, height), MIN (scale_x, scale_y), gimp_temp_buf_get_format (buf), gimp_temp_buf_get_data (buf), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); return buf; }
const Babl * gimp_babl_compat_u8_mask_format (const Babl *format) { g_return_val_if_fail (format != NULL, NULL); return gimp_babl_format (gimp_babl_format_get_base_type (format), GIMP_PRECISION_U8_LINEAR, FALSE, NULL); }
const Babl * gimp_babl_compat_u8_format (const Babl *format) { g_return_val_if_fail (format != NULL, NULL); /* indexed images only exist in u8, return the same format */ if (babl_format_is_palette (format)) return format; return gimp_babl_format (gimp_babl_format_get_base_type (format), GIMP_PRECISION_U8, babl_format_has_alpha (format)); }
static void gimp_levels_tool_color_picked (GimpImageMapTool *color_tool, gpointer identifier, gdouble x, gdouble y, const Babl *sample_format, const GimpRGB *color) { GimpLevelsTool *tool = GIMP_LEVELS_TOOL (color_tool); guint value = GPOINTER_TO_UINT (identifier); if (value & PICK_ALL_CHANNELS && gimp_babl_format_get_base_type (sample_format) == GIMP_RGB) { GimpHistogramChannel channel; /* first reset the value channel */ switch (value & 0xF) { case PICK_LOW_INPUT: tool->config->low_input[GIMP_HISTOGRAM_VALUE] = 0.0; break; case PICK_GAMMA: tool->config->gamma[GIMP_HISTOGRAM_VALUE] = 1.0; break; case PICK_HIGH_INPUT: tool->config->high_input[GIMP_HISTOGRAM_VALUE] = 1.0; break; default: break; } /* then adjust all color channels */ for (channel = GIMP_HISTOGRAM_RED; channel <= GIMP_HISTOGRAM_BLUE; channel++) { levels_input_adjust_by_color (tool->config, value, channel, color); } } else { levels_input_adjust_by_color (tool->config, value, tool->config->channel, color); } }
static const Babl * choose_format (GeglBuffer *buffer, GimpSelectCriterion select_criterion, gint *n_components, gboolean *has_alpha) { const Babl *format = gegl_buffer_get_format (buffer); *has_alpha = babl_format_has_alpha (format); switch (select_criterion) { case GIMP_SELECT_CRITERION_COMPOSITE: if (babl_format_is_palette (format)) format = babl_format ("R'G'B'A float"); else format = gimp_babl_format (gimp_babl_format_get_base_type (format), GIMP_PRECISION_FLOAT_GAMMA, *has_alpha); break; case GIMP_SELECT_CRITERION_R: case GIMP_SELECT_CRITERION_G: case GIMP_SELECT_CRITERION_B: case GIMP_SELECT_CRITERION_A: format = babl_format ("R'G'B'A float"); break; case GIMP_SELECT_CRITERION_H: case GIMP_SELECT_CRITERION_S: case GIMP_SELECT_CRITERION_V: format = babl_format ("HSVA float"); break; default: g_return_val_if_reached (NULL); break; } *n_components = babl_format_get_n_components (format); return format; }
static void gimp_text_undo_pop (GimpUndo *undo, GimpUndoMode undo_mode, GimpUndoAccumulator *accum) { GimpTextUndo *text_undo = GIMP_TEXT_UNDO (undo); GimpTextLayer *layer = GIMP_TEXT_LAYER (GIMP_ITEM_UNDO (undo)->item); GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum); switch (undo->undo_type) { case GIMP_UNDO_TEXT_LAYER: if (text_undo->pspec) { GValue *value; g_return_if_fail (layer->text != NULL); value = g_slice_new0 (GValue); g_value_init (value, text_undo->pspec->value_type); g_object_get_property (G_OBJECT (layer->text), text_undo->pspec->name, value); g_object_set_property (G_OBJECT (layer->text), text_undo->pspec->name, text_undo->value); g_value_unset (text_undo->value); g_slice_free (GValue, text_undo->value); text_undo->value = value; } else { GimpText *text; text = (layer->text ? gimp_config_duplicate (GIMP_CONFIG (layer->text)) : NULL); if (layer->text && text_undo->text) gimp_config_sync (G_OBJECT (text_undo->text), G_OBJECT (layer->text), 0); else gimp_text_layer_set_text (layer, text_undo->text); if (text_undo->text) g_object_unref (text_undo->text); text_undo->text = text; } break; case GIMP_UNDO_TEXT_LAYER_MODIFIED: { gboolean modified; #if 0 g_print ("setting layer->modified from %s to %s\n", layer->modified ? "TRUE" : "FALSE", text_undo->modified ? "TRUE" : "FALSE"); #endif modified = layer->modified; g_object_set (layer, "modified", text_undo->modified, NULL); text_undo->modified = modified; gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer)); } break; case GIMP_UNDO_TEXT_LAYER_CONVERT: { const Babl *format; format = gimp_drawable_get_format (GIMP_DRAWABLE (layer)); gimp_drawable_convert_type (GIMP_DRAWABLE (layer), gimp_item_get_image (GIMP_ITEM (layer)), gimp_babl_format_get_base_type (text_undo->format), gimp_babl_format_get_precision (text_undo->format), 0, 0, FALSE); text_undo->format = format; } break; default: g_assert_not_reached (); } }
static void gimp_color_frame_update (GimpColorFrame *frame) { const gchar *names[GIMP_COLOR_FRAME_ROWS] = { NULL, }; gchar **values = NULL; gboolean has_alpha; gint i; has_alpha = babl_format_has_alpha (frame->sample_format); if (frame->sample_valid) { gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area), &frame->color); } switch (frame->frame_mode) { case GIMP_COLOR_FRAME_MODE_PIXEL: { GimpImageBaseType base_type; base_type = gimp_babl_format_get_base_type (frame->sample_format); if (frame->sample_valid) { const Babl *print_format = NULL; guchar print_pixel[32]; switch (gimp_babl_format_get_precision (frame->sample_format)) { case GIMP_PRECISION_U8_GAMMA: if (babl_format_is_palette (frame->sample_format)) { print_format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA, has_alpha); break; } /* else fall thru */ case GIMP_PRECISION_U8_LINEAR: case GIMP_PRECISION_U16_LINEAR: case GIMP_PRECISION_U16_GAMMA: case GIMP_PRECISION_U32_LINEAR: case GIMP_PRECISION_U32_GAMMA: case GIMP_PRECISION_FLOAT_LINEAR: case GIMP_PRECISION_FLOAT_GAMMA: case GIMP_PRECISION_DOUBLE_LINEAR: case GIMP_PRECISION_DOUBLE_GAMMA: print_format = frame->sample_format; break; case GIMP_PRECISION_HALF_GAMMA: print_format = gimp_babl_format (base_type, GIMP_PRECISION_FLOAT_GAMMA, has_alpha); break; case GIMP_PRECISION_HALF_LINEAR: print_format = gimp_babl_format (base_type, GIMP_PRECISION_FLOAT_LINEAR, has_alpha); break; } if (frame->sample_average) { /* FIXME: this is broken: can't use the averaged sRGB GimpRGB * value for displaying pixel values when color management * is enabled */ gimp_rgba_get_pixel (&frame->color, print_format, print_pixel); } else { babl_process (babl_fish (frame->sample_format, print_format), frame->pixel, print_pixel, 1); } values = gimp_babl_print_pixel (print_format, print_pixel); } if (base_type == GIMP_GRAY) { names[0] = _("Value:"); if (has_alpha) names[1] = _("Alpha:"); } else { names[0] = _("Red:"); names[1] = _("Green:"); names[2] = _("Blue:"); if (has_alpha) names[3] = _("Alpha:"); if (babl_format_is_palette (frame->sample_format)) { names[4] = _("Index:"); if (frame->sample_valid) { gchar **v = g_new0 (gchar *, 6); gchar **tmp = values; memcpy (v, values, 4 * sizeof (gchar *)); values = v; g_free (tmp); if (! frame->sample_average) values[4] = g_strdup_printf ("%d", frame->pixel[0]); } } } }
void gimp_gegl_convolve (GeglBuffer *src_buffer, const GeglRectangle *src_rect, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, const gfloat *kernel, gint kernel_size, gdouble divisor, GimpConvolutionType mode, gboolean alpha_weighting) { GeglBufferIterator *iter; GeglRectangle *src_roi; GeglRectangle *dest_roi; const Babl *src_format; const Babl *dest_format; gint src_components; gint dest_components; src_format = gegl_buffer_get_format (src_buffer); if (babl_format_is_palette (src_format)) src_format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_FLOAT_LINEAR, babl_format_has_alpha (src_format)); else src_format = gimp_babl_format (gimp_babl_format_get_base_type (src_format), GIMP_PRECISION_FLOAT_LINEAR, babl_format_has_alpha (src_format)); dest_format = gegl_buffer_get_format (dest_buffer); if (babl_format_is_palette (dest_format)) dest_format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_FLOAT_LINEAR, babl_format_has_alpha (dest_format)); else dest_format = gimp_babl_format (gimp_babl_format_get_base_type (dest_format), GIMP_PRECISION_FLOAT_LINEAR, babl_format_has_alpha (dest_format)); src_components = babl_format_get_n_components (src_format); dest_components = babl_format_get_n_components (dest_format); iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0, src_format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE); src_roi = &iter->roi[0]; gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, dest_format, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE); dest_roi = &iter->roi[1]; while (gegl_buffer_iterator_next (iter)) { /* Convolve the src image using the convolution kernel, writing * to dest Convolve is not tile-enabled--use accordingly */ const gfloat *src = iter->data[0]; gfloat *dest = iter->data[1]; const gint components = src_components; const gint a_component = components - 1; const gint rowstride = src_components * src_roi->width; const gint margin = kernel_size / 2; const gint x1 = src_roi->x; const gint y1 = src_roi->y; const gint x2 = src_roi->x + src_roi->width - 1; const gint y2 = src_roi->y + src_roi->height - 1; gint x, y; gfloat offset; /* If the mode is NEGATIVE_CONVOL, the offset should be 128 */ if (mode == GIMP_NEGATIVE_CONVOL) { offset = 0.5; mode = GIMP_NORMAL_CONVOL; } else { offset = 0.0; } for (y = 0; y < dest_roi->height; y++) { gfloat *d = dest; if (alpha_weighting) { for (x = 0; x < dest_roi->width; x++) { const gfloat *m = kernel; gdouble total[4] = { 0.0, 0.0, 0.0, 0.0 }; gdouble weighted_divisor = 0.0; gint i, j, b; for (j = y - margin; j <= y + margin; j++) { for (i = x - margin; i <= x + margin; i++, m++) { gint xx = CLAMP (i, x1, x2); gint yy = CLAMP (j, y1, y2); const gfloat *s = src + yy * rowstride + xx * components; const gfloat a = s[a_component]; if (a) { gdouble mult_alpha = *m * a; weighted_divisor += mult_alpha; for (b = 0; b < a_component; b++) total[b] += mult_alpha * s[b]; total[a_component] += mult_alpha; } } } if (weighted_divisor == 0.0) weighted_divisor = divisor; for (b = 0; b < a_component; b++) total[b] /= weighted_divisor; total[a_component] /= divisor; for (b = 0; b < components; b++) { total[b] += offset; if (mode != GIMP_NORMAL_CONVOL && total[b] < 0.0) total[b] = - total[b]; *d++ = CLAMP (total[b], 0.0, 1.0); } } } else { for (x = 0; x < dest_roi->width; x++) { const gfloat *m = kernel; gdouble total[4] = { 0.0, 0.0, 0.0, 0.0 }; gint i, j, b; for (j = y - margin; j <= y + margin; j++) { for (i = x - margin; i <= x + margin; i++, m++) { gint xx = CLAMP (i, x1, x2); gint yy = CLAMP (j, y1, y2); const gfloat *s = src + yy * rowstride + xx * components; for (b = 0; b < components; b++) total[b] += *m * s[b]; } } for (b = 0; b < components; b++) { total[b] = total[b] / divisor + offset; if (mode != GIMP_NORMAL_CONVOL && total[b] < 0.0) total[b] = - total[b]; total[b] = CLAMP (total[b], 0.0, 1.0); } } } dest += dest_roi->width * dest_components; } } }
void gimp_gegl_convert_color_profile (GeglBuffer *src_buffer, const GeglRectangle *src_rect, GimpColorProfile *src_profile, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, GimpColorProfile *dest_profile, GimpColorRenderingIntent intent, gboolean bpc) { const Babl *src_format; const Babl *dest_format; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; cmsUInt32Number lcms_src_format; cmsUInt32Number lcms_dest_format; cmsUInt32Number flags; cmsHTRANSFORM transform; /* FIXME: we need the unconditional full copy only in two cases: * - if we return without doing anything * - if there is an alpha channel, because lcms doesn't copy it */ gegl_buffer_copy (src_buffer, src_rect, GEGL_ABYSS_NONE, dest_buffer, dest_rect); src_format = gegl_buffer_get_format (src_buffer); dest_format = gegl_buffer_get_format (dest_buffer); if ((gimp_babl_format_get_base_type (src_format) != GIMP_RGB) || (gimp_babl_format_get_base_type (dest_format) != GIMP_RGB)) return; if (gimp_color_profile_can_gegl_copy (src_profile, dest_profile)) return; src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); src_format = gimp_color_profile_get_format (src_format, &lcms_src_format); dest_format = gimp_color_profile_get_format (dest_format, &lcms_dest_format); flags = cmsFLAGS_NOOPTIMIZE; if (bpc) flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; transform = cmsCreateTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, intent, flags); if (transform) { GeglBufferIterator *iter; iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0, src_format, GEGL_ACCESS_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, dest_format, GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { cmsDoTransform (transform, iter->data[0], iter->data[1], iter->length); } cmsDeleteTransform (transform); } }
void gimp_histogram_calculate (GimpHistogram *histogram, GeglBuffer *buffer, const GeglRectangle *buffer_rect, GeglBuffer *mask, const GeglRectangle *mask_rect) { GeglBufferIterator *iter; const Babl *format; gint n_components; g_return_if_fail (histogram != NULL); g_return_if_fail (GEGL_IS_BUFFER (buffer)); g_return_if_fail (buffer_rect != NULL); format = gegl_buffer_get_format (buffer); if (babl_format_is_palette (format)) format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8, babl_format_has_alpha (format)); else format = gimp_babl_format (gimp_babl_format_get_base_type (format), GIMP_PRECISION_U8, babl_format_has_alpha (format)); n_components = babl_format_get_n_components (format); gimp_histogram_alloc_values (histogram, n_components); iter = gegl_buffer_iterator_new (buffer, buffer_rect, 0, format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE); if (mask) gegl_buffer_iterator_add (iter, mask, mask_rect, 0, babl_format ("Y float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); #define VALUE(c,i) (histogram->values[(c) * 256 + (i)]) while (gegl_buffer_iterator_next (iter)) { const guchar *data = iter->data[0]; gint max; if (mask) { const gfloat *mask_data = iter->data[1]; switch (n_components) { case 1: while (iter->length) { const gdouble masked = *mask_data; VALUE (0, data[0]) += masked; data += n_components; mask_data += 1; } break; case 2: while (iter->length--) { const gdouble masked = *mask_data; const gdouble weight = data[1] / 255.0; VALUE (0, data[0]) += weight * masked; VALUE (1, data[1]) += masked; data += n_components; mask_data += 1; } break; case 3: /* calculate separate value values */ while (iter->length--) { const gdouble masked = *mask_data; VALUE (1, data[0]) += masked; VALUE (2, data[1]) += masked; VALUE (3, data[2]) += masked; max = MAX (data[0], data[1]); max = MAX (data[2], max); VALUE (0, max) += masked; data += n_components; mask_data += 1; } break; case 4: /* calculate separate value values */ while (iter->length--) { const gdouble masked = *mask_data; const gdouble weight = data[3] / 255.0; VALUE (1, data[0]) += weight * masked; VALUE (2, data[1]) += weight * masked; VALUE (3, data[2]) += weight * masked; VALUE (4, data[3]) += masked; max = MAX (data[0], data[1]); max = MAX (data[2], max); VALUE (0, max) += weight * masked; data += n_components; mask_data += 1; } break; } } else /* no mask */ { switch (n_components) { case 1: while (iter->length--) { VALUE (0, data[0]) += 1.0; data += n_components; } break; case 2: while (iter->length--) { const gdouble weight = data[1] / 255; VALUE (0, data[0]) += weight; VALUE (1, data[1]) += 1.0; data += n_components; } break; case 3: /* calculate separate value values */ while (iter->length--) { VALUE (1, data[0]) += 1.0; VALUE (2, data[1]) += 1.0; VALUE (3, data[2]) += 1.0; max = MAX (data[0], data[1]); max = MAX (data[2], max); VALUE (0, max) += 1.0; data += n_components; } break; case 4: /* calculate separate value values */ while (iter->length--) { const gdouble weight = data[3] / 255; VALUE (1, data[0]) += weight; VALUE (2, data[1]) += weight; VALUE (3, data[2]) += weight; VALUE (4, data[3]) += 1.0; max = MAX (data[0], data[1]); max = MAX (data[2], max); VALUE (0, max) += weight; data += n_components; } break; } } } #undef VALUE }