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; }
static GimpTempBuf * tile_manager_create_preview (TileManager *tiles, const Babl *format, gint src_x, gint src_y, gint src_width, gint src_height, gint dest_width, gint dest_height) { GimpTempBuf *preview; PixelRegion srcPR; PixelRegion destPR; gint subsample = 1; preview = gimp_temp_buf_new (dest_width, dest_height, format); pixel_region_init (&srcPR, tiles, src_x, src_y, src_width, src_height, FALSE); pixel_region_init_temp_buf (&destPR, preview, 0, 0, dest_width, dest_height); /* calculate 'acceptable' subsample */ while ((dest_width * (subsample + 1) * 2 < src_width) && (dest_height * (subsample + 1) * 2 < src_height)) subsample += 1; subsample_region (&srcPR, &destPR, subsample); return preview; }
GimpData * gimp_pattern_new (GimpContext *context, const gchar *name) { GimpPattern *pattern; guchar *data; gint row, col; g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (name[0] != '\n', NULL); pattern = g_object_new (GIMP_TYPE_PATTERN, "name", name, NULL); pattern->mask = gimp_temp_buf_new (32, 32, babl_format ("R'G'B' u8")); data = gimp_temp_buf_get_data (pattern->mask); for (row = 0; row < gimp_temp_buf_get_height (pattern->mask); row++) for (col = 0; col < gimp_temp_buf_get_width (pattern->mask); col++) { memset (data, (col % 2) && (row % 2) ? 255 : 0, 3); data += 3; } return GIMP_DATA (pattern); }
static GimpTempBuf * gimp_pattern_get_new_preview (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpPattern *pattern = GIMP_PATTERN (viewable); GimpTempBuf *temp_buf; GeglBuffer *src_buffer; GeglBuffer *dest_buffer; gint copy_width; gint copy_height; copy_width = MIN (width, gimp_temp_buf_get_width (pattern->mask)); copy_height = MIN (height, gimp_temp_buf_get_height (pattern->mask)); temp_buf = gimp_temp_buf_new (copy_width, copy_height, gimp_temp_buf_get_format (pattern->mask)); src_buffer = gimp_temp_buf_create_buffer (pattern->mask); dest_buffer = gimp_temp_buf_create_buffer (temp_buf); gegl_buffer_copy (src_buffer, GEGL_RECTANGLE (0, 0, copy_width, copy_height), GEGL_ABYSS_NONE, dest_buffer, GEGL_RECTANGLE (0, 0, 0, 0)); g_object_unref (src_buffer); g_object_unref (dest_buffer); return temp_buf; }
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; }
GimpTempBuf * gimp_drawable_get_sub_preview (GimpDrawable *drawable, gint src_x, gint src_y, gint src_width, gint src_height, gint dest_width, gint dest_height) { GimpItem *item; GimpImage *image; GeglBuffer *buffer; GimpTempBuf *preview; gdouble scale; gint scaled_x; gint scaled_y; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (src_x >= 0, NULL); g_return_val_if_fail (src_y >= 0, NULL); g_return_val_if_fail (src_width > 0, NULL); g_return_val_if_fail (src_height > 0, NULL); g_return_val_if_fail (dest_width > 0, NULL); g_return_val_if_fail (dest_height > 0, NULL); item = GIMP_ITEM (drawable); g_return_val_if_fail ((src_x + src_width) <= gimp_item_get_width (item), NULL); g_return_val_if_fail ((src_y + src_height) <= gimp_item_get_height (item), NULL); image = gimp_item_get_image (item); if (! image->gimp->config->layer_previews) return NULL; buffer = gimp_drawable_get_buffer (drawable); preview = gimp_temp_buf_new (dest_width, dest_height, gimp_drawable_get_preview_format (drawable)); scale = MIN ((gdouble) dest_width / (gdouble) src_width, (gdouble) dest_height / (gdouble) src_height); scaled_x = RINT ((gdouble) src_x * scale); scaled_y = RINT ((gdouble) src_y * scale); gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, dest_width, dest_height), scale, gimp_temp_buf_get_format (preview), gimp_temp_buf_get_data (preview), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); return preview; }
static GeglBuffer * gimp_ink_get_paint_buffer (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, const GimpCoords *coords, gint *paint_buffer_x, gint *paint_buffer_y) { GimpInk *ink = GIMP_INK (paint_core); gint x, y; gint width, height; gint dwidth, dheight; gint x1, y1, x2, y2; gimp_blob_bounds (ink->cur_blob, &x, &y, &width, &height); dwidth = gimp_item_get_width (GIMP_ITEM (drawable)); dheight = gimp_item_get_height (GIMP_ITEM (drawable)); x1 = CLAMP (x / SUBSAMPLE - 1, 0, dwidth); y1 = CLAMP (y / SUBSAMPLE - 1, 0, dheight); x2 = CLAMP ((x + width) / SUBSAMPLE + 2, 0, dwidth); y2 = CLAMP ((y + height) / SUBSAMPLE + 2, 0, dheight); /* configure the canvas buffer */ if ((x2 - x1) && (y2 - y1)) { GimpTempBuf *temp_buf; const Babl *format; if (gimp_drawable_get_linear (drawable)) format = babl_format ("RGBA float"); else format = babl_format ("R'G'B'A float"); temp_buf = gimp_temp_buf_new ((x2 - x1), (y2 - y1), format); *paint_buffer_x = x1; *paint_buffer_y = y1; if (paint_core->paint_buffer) g_object_unref (paint_core->paint_buffer); paint_core->paint_buffer = gimp_temp_buf_create_buffer (temp_buf); gimp_temp_buf_unref (temp_buf); return paint_core->paint_buffer; } return NULL; }
static void gimp_pattern_clipboard_buffer_changed (Gimp *gimp, GimpPattern *pattern) { if (pattern->mask) { gimp_temp_buf_unref (pattern->mask); pattern->mask = NULL; } if (gimp->global_buffer) { GimpBuffer *buffer = gimp->global_buffer; gint width; gint height; width = MIN (gimp_buffer_get_width (buffer), 2048); height = MIN (gimp_buffer_get_height (buffer), 2048); pattern->mask = gimp_temp_buf_new (width, height, gimp_buffer_get_format (buffer)); gegl_buffer_get (gimp_buffer_get_buffer (buffer), GEGL_RECTANGLE (0, 0, width, height), 1.0, NULL, gimp_temp_buf_get_data (pattern->mask), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); } else { pattern->mask = gimp_temp_buf_new (16, 16, babl_format ("R'G'B' u8")); memset (gimp_temp_buf_get_data (pattern->mask), 255, 16 * 16 * 3); } gimp_data_dirty (GIMP_DATA (pattern)); }
static GdkPixbuf * gimp_buffer_get_new_pixbuf (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); GdkPixbuf *pixbuf; gdouble scale; pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); scale = MIN ((gdouble) width / (gdouble) gimp_buffer_get_width (buffer), (gdouble) height / (gdouble) gimp_buffer_get_height (buffer)); if (buffer->color_profile) { GimpColorProfile *srgb_profile; GimpTempBuf *temp_buf; GeglBuffer *src_buf; GeglBuffer *dest_buf; srgb_profile = gimp_color_profile_new_rgb_srgb (); temp_buf = gimp_temp_buf_new (width, height, gimp_buffer_get_format (buffer)); gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), scale, gimp_temp_buf_get_format (temp_buf), gimp_temp_buf_get_data (temp_buf), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); src_buf = gimp_temp_buf_create_buffer (temp_buf); dest_buf = gimp_pixbuf_create_buffer (pixbuf); gimp_temp_buf_unref (temp_buf); gimp_gegl_convert_color_profile (src_buf, GEGL_RECTANGLE (0, 0, width, height), buffer->color_profile, dest_buf, GEGL_RECTANGLE (0, 0, 0, 0), srgb_profile, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, TRUE, NULL); g_object_unref (src_buf); g_object_unref (dest_buf); g_object_unref (srgb_profile); } else { gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), scale, gimp_pixbuf_get_format (pixbuf), gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), GEGL_ABYSS_CLAMP); } return pixbuf; }
static void gimp_brush_clipboard_buffer_changed (Gimp *gimp, GimpBrush *brush) { gint width; gint height; if (brush->mask) { gimp_temp_buf_unref (brush->mask); brush->mask = NULL; } if (brush->pixmap) { gimp_temp_buf_unref (brush->pixmap); brush->pixmap = NULL; } if (gimp->global_buffer) { GeglBuffer *buffer = gimp_buffer_get_buffer (gimp->global_buffer); const Babl *format = gegl_buffer_get_format (buffer); GeglBuffer *dest_buffer; width = MIN (gimp_buffer_get_width (gimp->global_buffer), 512); height = MIN (gimp_buffer_get_height (gimp->global_buffer), 512); brush->mask = gimp_temp_buf_new (width, height, babl_format ("Y u8")); brush->pixmap = gimp_temp_buf_new (width, height, babl_format ("R'G'B' u8")); /* copy the alpha channel into the brush's mask */ if (babl_format_has_alpha (format)) { dest_buffer = gimp_temp_buf_create_buffer (brush->mask); gegl_buffer_set_format (dest_buffer, babl_format ("A u8")); gegl_buffer_copy (buffer, NULL, dest_buffer, NULL); g_object_unref (dest_buffer); } else { memset (gimp_temp_buf_get_data (brush->mask), 255, width * height); } /* copy the color channels into the brush's pixmap */ dest_buffer = gimp_temp_buf_create_buffer (brush->pixmap); gegl_buffer_copy (buffer, NULL, dest_buffer, NULL); g_object_unref (dest_buffer); } else { width = 17; height = 17; brush->mask = gimp_temp_buf_new (width, height, babl_format ("Y u8")); gimp_temp_buf_data_clear (brush->mask); } brush->x_axis.x = width / 2; brush->x_axis.y = 0; brush->y_axis.x = 0; brush->y_axis.y = height / 2; gimp_data_dirty (GIMP_DATA (brush)); }
GdkPixbuf * gimp_drawable_get_sub_pixbuf (GimpDrawable *drawable, gint src_x, gint src_y, gint src_width, gint src_height, gint dest_width, gint dest_height) { GimpItem *item; GimpImage *image; GeglBuffer *buffer; GdkPixbuf *pixbuf; gdouble scale; gint scaled_x; gint scaled_y; GimpColorTransform *transform; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (src_x >= 0, NULL); g_return_val_if_fail (src_y >= 0, NULL); g_return_val_if_fail (src_width > 0, NULL); g_return_val_if_fail (src_height > 0, NULL); g_return_val_if_fail (dest_width > 0, NULL); g_return_val_if_fail (dest_height > 0, NULL); item = GIMP_ITEM (drawable); g_return_val_if_fail ((src_x + src_width) <= gimp_item_get_width (item), NULL); g_return_val_if_fail ((src_y + src_height) <= gimp_item_get_height (item), NULL); image = gimp_item_get_image (item); if (! image->gimp->config->layer_previews) return NULL; buffer = gimp_drawable_get_buffer (drawable); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, dest_width, dest_height); scale = MIN ((gdouble) dest_width / (gdouble) src_width, (gdouble) dest_height / (gdouble) src_height); scaled_x = RINT ((gdouble) src_x * scale); scaled_y = RINT ((gdouble) src_y * scale); transform = gimp_image_get_color_transform_to_srgb_u8 (image); if (transform) { GimpTempBuf *temp_buf; GeglBuffer *src_buf; GeglBuffer *dest_buf; temp_buf = gimp_temp_buf_new (dest_width, dest_height, gimp_drawable_get_format (drawable)); gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, dest_width, dest_height), scale, gimp_temp_buf_get_format (temp_buf), gimp_temp_buf_get_data (temp_buf), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); src_buf = gimp_temp_buf_create_buffer (temp_buf); dest_buf = gimp_pixbuf_create_buffer (pixbuf); gimp_temp_buf_unref (temp_buf); gimp_color_transform_process_buffer (transform, src_buf, GEGL_RECTANGLE (0, 0, dest_width, dest_height), dest_buf, GEGL_RECTANGLE (0, 0, 0, 0)); g_object_unref (src_buf); g_object_unref (dest_buf); } else { gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, dest_width, dest_height), scale, gimp_pixbuf_get_format (pixbuf), gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), GEGL_ABYSS_CLAMP); } return pixbuf; }
static void gimp_convolve_motion (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, const GimpCoords *coords) { GimpConvolve *convolve = GIMP_CONVOLVE (paint_core); GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); GimpConvolveOptions *options = GIMP_CONVOLVE_OPTIONS (paint_options); GimpContext *context = GIMP_CONTEXT (paint_options); GimpDynamics *dynamics = GIMP_BRUSH_CORE (paint_core)->dynamics; GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); GeglBuffer *paint_buffer; gint paint_buffer_x; gint paint_buffer_y; GimpTempBuf *temp_buf; GeglBuffer *convolve_buffer; gdouble fade_point; gdouble opacity; gdouble rate; fade_point = gimp_paint_options_get_fade (paint_options, image, paint_core->pixel_dist); opacity = gimp_dynamics_get_linear_value (dynamics, GIMP_DYNAMICS_OUTPUT_OPACITY, coords, paint_options, fade_point); if (opacity == 0.0) return; paint_buffer = gimp_paint_core_get_paint_buffer (paint_core, drawable, paint_options, coords, &paint_buffer_x, &paint_buffer_y); if (! paint_buffer) return; rate = (options->rate * gimp_dynamics_get_linear_value (dynamics, GIMP_DYNAMICS_OUTPUT_RATE, coords, paint_options, fade_point)); gimp_convolve_calculate_matrix (convolve, options->type, gimp_brush_get_width (brush_core->brush) / 2, gimp_brush_get_height (brush_core->brush) / 2, rate); /* need a linear buffer for gimp_gegl_convolve() */ temp_buf = gimp_temp_buf_new (gegl_buffer_get_width (paint_buffer), gegl_buffer_get_height (paint_buffer), gegl_buffer_get_format (paint_buffer)); convolve_buffer = gimp_temp_buf_create_buffer (temp_buf); gimp_temp_buf_unref (temp_buf); gegl_buffer_copy (gimp_drawable_get_buffer (drawable), GEGL_RECTANGLE (paint_buffer_x, paint_buffer_y, gegl_buffer_get_width (paint_buffer), gegl_buffer_get_height (paint_buffer)), convolve_buffer, GEGL_RECTANGLE (0, 0, 0, 0)); gimp_gegl_convolve (convolve_buffer, GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (convolve_buffer), gegl_buffer_get_height (convolve_buffer)), paint_buffer, GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (paint_buffer), gegl_buffer_get_height (paint_buffer)), convolve->matrix, 3, convolve->matrix_divisor, GIMP_NORMAL_CONVOL, TRUE); g_object_unref (convolve_buffer); gimp_brush_core_replace_canvas (brush_core, drawable, coords, MIN (opacity, GIMP_OPACITY_OPAQUE), gimp_context_get_opacity (context), gimp_paint_options_get_brush_mode (paint_options), 1.0, GIMP_PAINT_INCREMENTAL); }
static GimpTempBuf * gimp_brush_generated_calc (GimpBrushGenerated *brush, GimpBrushGeneratedShape shape, gfloat radius, gint spikes, gfloat hardness, gfloat aspect_ratio, gfloat angle, GimpVector2 *xaxis, GimpVector2 *yaxis) { guchar *centerp; guchar *lookup; guchar a; gint x, y; gdouble c, s, cs, ss; GimpVector2 x_axis; GimpVector2 y_axis; GimpTempBuf *mask; gint width; gint height; gint half_width; gint half_height; gimp_brush_generated_get_size (brush, shape, radius, spikes, hardness, aspect_ratio, angle, &width, &height, &s, &c, &x_axis, &y_axis); mask = gimp_temp_buf_new (width, height, babl_format ("Y u8")); half_width = width / 2; half_height = height / 2; centerp = gimp_temp_buf_get_data (mask) + half_height * width + half_width; lookup = gimp_brush_generated_calc_lut (radius, hardness); cs = cos (- 2 * G_PI / spikes); ss = sin (- 2 * G_PI / spikes); /* for an even number of spikes compute one half and mirror it */ for (y = ((spikes % 2) ? -half_height : 0); y <= half_height; y++) { for (x = -half_width; x <= half_width; x++) { gdouble d = 0; gdouble tx = c * x - s * y; gdouble ty = fabs (s * x + c * y); if (spikes > 2) { gdouble angle = atan2 (ty, tx); while (angle > G_PI / spikes) { gdouble sx = tx; gdouble sy = ty; tx = cs * sx - ss * sy; ty = ss * sx + cs * sy; angle -= 2 * G_PI / spikes; } } ty *= aspect_ratio; switch (shape) { case GIMP_BRUSH_GENERATED_CIRCLE: d = sqrt (SQR (tx) + SQR (ty)); break; case GIMP_BRUSH_GENERATED_SQUARE: d = MAX (fabs (tx), fabs (ty)); break; case GIMP_BRUSH_GENERATED_DIAMOND: d = fabs (tx) + fabs (ty); break; } if (d < radius + 1) a = lookup[(gint) RINT (d * OVERSAMPLING)]; else a = 0; centerp[y * width + x] = a; if (spikes % 2 == 0) centerp[-1 * y * width - x] = a; } } g_free (lookup); if (xaxis) *xaxis = x_axis; if (yaxis) *yaxis = y_axis; return mask; }
GdkPixbuf * gimp_image_get_new_pixbuf (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpImage *image = GIMP_IMAGE (viewable); GdkPixbuf *pixbuf; gdouble scale_x; gdouble scale_y; GimpColorTransform *transform; scale_x = (gdouble) width / (gdouble) gimp_image_get_width (image); scale_y = (gdouble) height / (gdouble) gimp_image_get_height (image); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); transform = gimp_image_get_color_transform_to_srgb_u8 (image); if (transform) { GimpTempBuf *temp_buf; GeglBuffer *src_buf; GeglBuffer *dest_buf; temp_buf = gimp_temp_buf_new (width, height, gimp_pickable_get_format (GIMP_PICKABLE (image))); 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 (temp_buf), gimp_temp_buf_get_data (temp_buf), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); src_buf = gimp_temp_buf_create_buffer (temp_buf); dest_buf = gimp_pixbuf_create_buffer (pixbuf); gimp_temp_buf_unref (temp_buf); gimp_color_transform_process_buffer (transform, src_buf, GEGL_RECTANGLE (0, 0, width, height), dest_buf, GEGL_RECTANGLE (0, 0, 0, 0)); g_object_unref (src_buf); g_object_unref (dest_buf); } else { gegl_buffer_get (gimp_pickable_get_buffer (GIMP_PICKABLE (image)), GEGL_RECTANGLE (0, 0, width, height), MIN (scale_x, scale_y), gimp_pixbuf_get_format (pixbuf), gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), GEGL_ABYSS_CLAMP); } return pixbuf; }
GList * gimp_pattern_load (GimpContext *context, GFile *file, GInputStream *input, GError **error) { GimpPattern *pattern = NULL; const Babl *format = NULL; PatternHeader header; gsize size; gsize bytes_read; gint bn_size; gchar *name = NULL; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* read the size */ if (! g_input_stream_read_all (input, &header, sizeof (header), &bytes_read, NULL, error) || bytes_read != sizeof (header)) { g_prefix_error (error, _("File appears truncated: ")); goto error; } /* rearrange the bytes in each unsigned int */ header.header_size = g_ntohl (header.header_size); header.version = g_ntohl (header.version); header.width = g_ntohl (header.width); header.height = g_ntohl (header.height); header.bytes = g_ntohl (header.bytes); header.magic_number = g_ntohl (header.magic_number); /* Check for correct file format */ if (header.magic_number != GPATTERN_MAGIC || header.version != 1 || header.header_size <= sizeof (header)) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Unknown pattern format version %d."), header.version); goto error; } /* Check for supported bit depths */ if (header.bytes < 1 || header.bytes > 4) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Unsupported pattern depth %d.\n" "GIMP Patterns must be GRAY or RGB."), header.bytes); goto error; } /* Read in the pattern name */ if ((bn_size = (header.header_size - sizeof (header)))) { gchar *utf8; name = g_new (gchar, bn_size); if (! g_input_stream_read_all (input, name, bn_size, &bytes_read, NULL, error) || bytes_read != bn_size) { g_prefix_error (error, _("File appears truncated.")); g_free (name); goto error; } utf8 = gimp_any_to_utf8 (name, -1, _("Invalid UTF-8 string in pattern file '%s'."), gimp_file_get_utf8_name (file)); g_free (name); name = utf8; } if (! name) name = g_strdup (_("Unnamed")); pattern = g_object_new (GIMP_TYPE_PATTERN, "name", name, "mime-type", "image/x-gimp-pat", NULL); g_free (name); switch (header.bytes) { case 1: format = babl_format ("Y' u8"); break; case 2: format = babl_format ("Y'A u8"); break; case 3: format = babl_format ("R'G'B' u8"); break; case 4: format = babl_format ("R'G'B'A u8"); break; } pattern->mask = gimp_temp_buf_new (header.width, header.height, format); size = header.width * header.height * header.bytes; if (! g_input_stream_read_all (input, gimp_temp_buf_get_data (pattern->mask), size, &bytes_read, NULL, error) || bytes_read != size) { g_prefix_error (error, _("File appears truncated.")); goto error; } return g_list_prepend (NULL, pattern); error: if (pattern) g_object_unref (pattern); g_prefix_error (error, _("Fatal parse error in pattern file: ")); return NULL; }