static gboolean test_opacity_common (const Babl *in_format, const Babl *out_format) { /* Validate that gegl:opacity produces out_format when given in_format */ gboolean result = TRUE; GeglNode *ptn, *src, *opacity, *sink; GeglBuffer *src_buffer; GeglBuffer *sink_buffer = NULL; src_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, 10, 10), in_format); ptn = gegl_node_new (); src = gegl_node_new_child (ptn, "operation", "gegl:buffer-source", "buffer", src_buffer, NULL); opacity = gegl_node_new_child (ptn, "operation", "gegl:opacity", "value", 0.5, NULL); sink = gegl_node_new_child (ptn, "operation", "gegl:buffer-sink", "buffer", &sink_buffer, "format", NULL, NULL); gegl_node_link_many (src, opacity, sink, NULL); gegl_node_blit_buffer (sink, NULL, NULL, 0, GEGL_ABYSS_NONE); if (out_format != gegl_buffer_get_format (sink_buffer)) { printf ("Got %s expected %s\n", babl_get_name (gegl_buffer_get_format (sink_buffer)), babl_get_name (out_format)); result = FALSE; } if (!gegl_rectangle_equal (gegl_buffer_get_extent (src_buffer), gegl_buffer_get_extent (sink_buffer))) result = FALSE; g_object_unref (ptn); g_object_unref (src_buffer); g_object_unref (sink_buffer); return result; }
static gboolean gimp_operation_histogram_sink_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglBuffer *input; GeglBuffer *aux; if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a sink", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); aux = gegl_operation_context_get_source (context, "aux"); if (! input) { g_warning ("received NULL input"); return FALSE; } if (aux) { /* do hist with mask */ g_printerr ("aux format: %s\n", babl_get_name (gegl_buffer_get_format (aux))); g_object_unref (aux); } else { /* without */ } g_printerr ("input format: %s\n", babl_get_name (gegl_buffer_get_format (input))); g_object_unref (input); return TRUE; }
const gchar * gegl_format_get_name (GValue *value) { Babl *format; if (!(G_TYPE_POINTER == G_VALUE_TYPE(value))) return NULL; format = g_value_get_pointer (value); if (!format) return NULL; return babl_get_name (format); }
const gchar * gimp_babl_get_description (const Babl *babl) { const gchar *description; g_return_val_if_fail (babl != NULL, NULL); if (G_UNLIKELY (! babl_description_hash)) { gint i; babl_description_hash = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; i < G_N_ELEMENTS (babl_descriptions); i++) g_hash_table_insert (babl_description_hash, (gpointer) babl_descriptions[i].name, gettext (babl_descriptions[i].description)); } if (babl_format_is_palette (babl)) { if (babl_format_has_alpha (babl)) return _("Indexed-alpha"); else return _("Indexed"); } description = g_hash_table_lookup (babl_description_hash, babl_get_name (babl)); if (description) return description; return g_strconcat ("ERROR: unknown Babl format ", babl_get_name (babl), NULL); }
static char * babl_fish_serialize (Babl *fish, char *dest, int n) { char *d = dest; if (fish->class_type != BABL_FISH_PATH) return NULL; snprintf (d, n, "%s\n%s\n", babl_get_name (fish->fish.source), babl_get_name (fish->fish.destination)); n -= strlen (d);d += strlen (d); snprintf (d, n, "\tpixels=%li", fish->fish.pixels); n -= strlen (d);d += strlen (d); snprintf (d, n, " processings=%i", fish->fish.processings); n -= strlen (d);d += strlen (d); snprintf (d, n, " cost=%d", (int)fish->fish_path.cost); n -= strlen (d);d += strlen (d); snprintf (d, n, " error=%f", fish->fish.error); n -= strlen (d);d += strlen (d); snprintf (d, n, "\n"); n -= strlen (d);d += strlen (d); for (int i = 0; i < fish->fish_path.conversion_list->count; i++) { snprintf (d, n, "\t%s\n", babl_get_name(fish->fish_path.conversion_list->items[i] )); n -= strlen (d);d += strlen (d); } return dest; }
GimpImageType gimp_babl_format_get_image_type (const Babl *format) { const gchar *name; g_return_val_if_fail (format != NULL, -1); name = babl_get_name (babl_format_get_model (format)); if (! strcmp (name, "Y") || ! strcmp (name, "Y'") || ! strcmp (name, "Y~")) { return GIMP_GRAY_IMAGE; } else if (! strcmp (name, "YA") || ! strcmp (name, "Y'A") || ! strcmp (name, "Y~A")) { return GIMP_GRAYA_IMAGE; } else if (! strcmp (name, "RGB") || ! strcmp (name, "R'G'B'") || ! strcmp (name, "R~G~B~")) { return GIMP_RGB_IMAGE; } else if (! strcmp (name, "RGBA") || ! strcmp (name, "R'G'B'A") || ! strcmp (name, "R~G~B~A")) { return GIMP_RGBA_IMAGE; } else if (babl_format_is_palette (format)) { if (babl_format_has_alpha (format)) return GIMP_INDEXEDA_IMAGE; else return GIMP_INDEXED_IMAGE; } g_return_val_if_reached (-1); }
static gboolean test_scale (const gdouble scale, const gint x, const gint y, const Babl *format) { GeglNode *checkerboard; GeglBuffer *tmp_buffer; gboolean result = FALSE; const gint bpp = babl_format_get_bytes_per_pixel (format); const gint scaled_width = 32; const gint scaled_height = 32; gint pad = 32; guchar *output_buffer_scaled = gegl_malloc (scaled_width * scaled_height * bpp); guchar *output_node_scaled = gegl_malloc (scaled_width * scaled_height * bpp); if (2 / scale > pad) pad = 2 / scale + 2; tmp_buffer = gegl_buffer_new (GEGL_RECTANGLE ((x / scale) - pad, (y / scale) - pad, (scaled_width / scale) + (2 * pad), (scaled_height / scale) + (2 * pad)), babl_format ("RGBA float")); checkerboard = gegl_node_new_child(NULL, "operation", "gegl:checkerboard", "x", 16, "y", 16, NULL); gegl_node_blit_buffer (checkerboard, tmp_buffer, NULL, 0, GEGL_ABYSS_NONE); gegl_buffer_get (tmp_buffer, GEGL_RECTANGLE (x, y, scaled_width, scaled_height), scale, format, output_buffer_scaled, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); g_object_unref (checkerboard); g_object_unref (tmp_buffer); /* Re-create the node so we don't hit its cache */ checkerboard = gegl_node_new_child(NULL, "operation", "gegl:checkerboard", "x", 16, "y", 16, NULL); gegl_node_blit (checkerboard, scale, GEGL_RECTANGLE (x, y, scaled_width, scaled_height), format, output_node_scaled, GEGL_AUTO_ROWSTRIDE, 0); g_object_unref (checkerboard); if (0 == memcmp (output_buffer_scaled, output_node_scaled, scaled_width * scaled_height * bpp)) { printf ("."); fflush(stdout); result = TRUE; } else { printf ("\n scale=%.4f at %d, %d in \"%s\" ... FAIL\n", scale, x, y, babl_get_name (format)); result = FALSE; } gegl_free (output_buffer_scaled); gegl_free (output_node_scaled); return result; }
static void lcms_layers_transform_rgb (gint *layers, gint num_layers, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, GimpColorRenderingIntent intent, gboolean bpc) { gint i; for (i = 0; i < num_layers; i++) { gint32 layer_id = layers[i]; const Babl *layer_format; gboolean has_alpha; const Babl *type; const Babl *iter_format = NULL; cmsUInt32Number lcms_format = 0; cmsHTRANSFORM transform = NULL; gint *children; gint num_children; children = gimp_item_get_children (layer_id, &num_children); if (children) { lcms_layers_transform_rgb (children, num_children, src_profile, dest_profile, intent, bpc); g_free (children); continue; } layer_format = gimp_drawable_get_format (layer_id); has_alpha = babl_format_has_alpha (layer_format); type = babl_format_get_type (layer_format, 0); if (type == babl_type ("u8")) { if (has_alpha) { lcms_format = TYPE_RGBA_8; iter_format = babl_format ("R'G'B'A u8"); } else { lcms_format = TYPE_RGB_8; iter_format = babl_format ("R'G'B' u8"); } } else if (type == babl_type ("u16")) { if (has_alpha) { lcms_format = TYPE_RGBA_16; iter_format = babl_format ("R'G'B'A u16"); } else { lcms_format = TYPE_RGB_16; iter_format = babl_format ("R'G'B' u16"); } } else if (type == babl_type ("half")) /* 16-bit floating point (half) */ { #ifdef TYPE_RGB_HALF_FLT /* half float types are only in lcms 2.4 and newer */ if (has_alpha) { lcms_format = TYPE_RGBA_HALF_FLT; iter_format = babl_format ("R'G'B'A half"); } else { lcms_format = TYPE_RGB_HALF_FLT; iter_format = babl_format ("R'G'B' float"); } #endif /* TYPE_RGB_HALF_FLT */ } else if (type == babl_type ("float")) { if (has_alpha) { lcms_format = TYPE_RGBA_FLT; iter_format = babl_format ("R'G'B'A float"); } else { lcms_format = TYPE_RGB_FLT; iter_format = babl_format ("R'G'B' float"); } } else if (type == babl_type ("double")) { if (has_alpha) { #ifdef TYPE_RGBA_DBL /* RGBA double not implemented in lcms */ lcms_format = TYPE_RGBA_DBL; iter_format = babl_format ("R'G'B'A double"); #endif /* TYPE_RGBA_DBL */ } else { lcms_format = TYPE_RGB_DBL; iter_format = babl_format ("R'G'B' double"); } } if (lcms_format == 0) { g_printerr ("lcms: layer format %s not supported, " "falling back to float\n", babl_get_name (layer_format)); if (has_alpha) { lcms_format = TYPE_RGBA_FLT; iter_format = babl_format ("R'G'B'A float"); } else { lcms_format = TYPE_RGB_FLT; iter_format = babl_format ("R'G'B' float"); } } transform = cmsCreateTransform (src_profile, lcms_format, dest_profile, lcms_format, intent, cmsFLAGS_NOOPTIMIZE | (bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0)); if (transform) { GeglBuffer *src_buffer; GeglBuffer *dest_buffer; GeglBufferIterator *iter; gint layer_width; gint layer_height; gint layer_bpp; gboolean layer_alpha; gdouble progress_start = (gdouble) i / num_layers; gdouble progress_end = (gdouble) (i + 1) / num_layers; gdouble range = progress_end - progress_start; gint count = 0; gint done = 0; src_buffer = gimp_drawable_get_buffer (layer_id); dest_buffer = gimp_drawable_get_shadow_buffer (layer_id); layer_width = gegl_buffer_get_width (src_buffer); layer_height = gegl_buffer_get_height (src_buffer); layer_bpp = babl_format_get_bytes_per_pixel (iter_format); layer_alpha = babl_format_has_alpha (iter_format); iter = gegl_buffer_iterator_new (src_buffer, NULL, 0, iter_format, GEGL_ACCESS_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, dest_buffer, NULL, 0, iter_format, GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { /* lcms doesn't touch the alpha channel, simply * copy everything to dest before the transform */ if (layer_alpha) memcpy (iter->data[1], iter->data[0], iter->length * layer_bpp); cmsDoTransform (transform, iter->data[0], iter->data[1], iter->length); } g_object_unref (src_buffer); g_object_unref (dest_buffer); gimp_drawable_merge_shadow (layer_id, TRUE); gimp_drawable_update (layer_id, 0, 0, layer_width, layer_height); if (count++ % 32 == 0) { gimp_progress_update (progress_start + (gdouble) done / (layer_width * layer_height) * range); } cmsDeleteTransform (transform); } } }
static inline gboolean _gegl_buffer_cl_cache_flush2 (GeglTileHandlerCache *cache, const GeglRectangle *roi) { size_t size; GList *elem; GeglRectangle tmp; cl_int cl_err = 0; gpointer data; gboolean need_cl = FALSE; for (elem=cache_entries; elem; elem=elem->next) { CacheEntry *entry = elem->data; if (entry->valid && entry->tile_storage->cache == cache && (!roi || gegl_rectangle_intersect (&tmp, roi, &entry->roi))) { entry->valid = FALSE; entry->used ++; gegl_cl_color_babl (entry->buffer->soft_format, &size); data = g_malloc(entry->roi.width * entry->roi.height * size); cl_err = gegl_clEnqueueReadBuffer(gegl_cl_get_command_queue(), entry->tex, CL_TRUE, 0, entry->roi.width * entry->roi.height * size, data, 0, NULL, NULL); /* tile-ize */ gegl_buffer_set (entry->buffer, &entry->roi, 0, entry->buffer->soft_format, data, GEGL_AUTO_ROWSTRIDE); entry->used --; need_cl = TRUE; g_free(data); CL_CHECK; } } if (need_cl) { cl_err = gegl_clFinish (gegl_cl_get_command_queue ()); CL_CHECK; g_mutex_lock (&cache_mutex); while (cache_entry_find_invalid (&data)) { CacheEntry *entry = data; #if 1 GEGL_NOTE (GEGL_DEBUG_OPENCL, "Removing from cl-cache: %p %s {%d %d %d %d}", entry->buffer, babl_get_name(entry->buffer->soft_format), entry->roi.x, entry->roi.y, entry->roi.width, entry->roi.height); #endif gegl_clReleaseMemObject(entry->tex); memset (entry, 0x0, sizeof (CacheEntry)); g_slice_free (CacheEntry, data); cache_entries = g_list_remove (cache_entries, data); } g_mutex_unlock (&cache_mutex); } return TRUE; error: g_mutex_lock (&cache_mutex); while (cache_entry_find_invalid (&data)) { g_slice_free (CacheEntry, data); cache_entries = g_list_remove (cache_entries, data); } g_mutex_unlock (&cache_mutex); /* XXX : result is corrupted */ return FALSE; }
/** * gimp_color_profile_get_format: * @format: a #Babl format * @lcms_format: return location for an lcms format * * This function takes a #Babl format and returns the lcms format to * be used with that @format. It also returns a #Babl format to be * used instead of the passed @format, which usually is the same as * @format, unless lcms doesn't support @format. * * Note that this function currently only supports RGB, RGBA, R'G'B', * R'G'B'A, Y, YA, Y', Y'A and the cairo-RGB24 and cairo-ARGB32 formats. * * Return value: the #Babl format to be used instead of @format, or %NULL * is the passed @format is not supported at all. * * Since: 2.10 **/ const Babl * gimp_color_profile_get_format (const Babl *format, guint32 *lcms_format) { const Babl *output_format = NULL; const Babl *type; const Babl *model; gboolean has_alpha; gboolean gray; gboolean linear; g_return_val_if_fail (format != NULL, NULL); g_return_val_if_fail (lcms_format != NULL, NULL); has_alpha = babl_format_has_alpha (format); type = babl_format_get_type (format, 0); model = babl_format_get_model (format); if (format == babl_format ("cairo-RGB24")) { *lcms_format = TYPE_RGB_8; return babl_format ("R'G'B' u8"); } else if (format == babl_format ("cairo-ARGB32")) { *lcms_format = TYPE_RGBA_8; return babl_format ("R'G'B'A u8"); } else if (model == babl_model ("RGB") || model == babl_model ("RGBA")) { gray = FALSE; linear = TRUE; } else if (model == babl_model ("R'G'B'") || model == babl_model ("R'G'B'A")) { gray = FALSE; linear = FALSE; } else if (model == babl_model ("Y") || model == babl_model ("YA")) { gray = TRUE; linear = TRUE; } else if (model == babl_model ("Y'") || model == babl_model ("Y'A")) { gray = TRUE; linear = FALSE; } else if (babl_format_is_palette (format)) { if (has_alpha) { *lcms_format = TYPE_RGBA_8; return babl_format ("R'G'B'A u8"); } else { *lcms_format = TYPE_RGB_8; return babl_format ("R'G'B' u8"); } } else { g_printerr ("format: %s\n" "has_alpha = %s\n" "type = %s\n" "model = %s\n", babl_get_name (format), has_alpha ? "TRUE" : "FALSE", babl_get_name (type), babl_get_name (model)); g_return_val_if_reached (NULL); } *lcms_format = 0; if (type == babl_type ("u8")) { if (has_alpha) { if (gray) *lcms_format = TYPE_GRAYA_8; else *lcms_format = TYPE_RGBA_8; } else { if (gray) *lcms_format = TYPE_GRAY_8; else *lcms_format = TYPE_RGB_8; } output_format = format; } else if (type == babl_type ("u16")) { if (has_alpha) { if (gray) *lcms_format = TYPE_GRAYA_16; else *lcms_format = TYPE_RGBA_16; } else { if (gray) *lcms_format = TYPE_GRAY_16; else *lcms_format = TYPE_RGB_16; } output_format = format; } else if (type == babl_type ("half")) /* 16-bit floating point (half) */ { if (has_alpha) { if (gray) *lcms_format = TYPE_GRAYA_HALF_FLT; else *lcms_format = TYPE_RGBA_HALF_FLT; } else { if (gray) *lcms_format = TYPE_GRAY_HALF_FLT; else *lcms_format = TYPE_RGB_HALF_FLT; } output_format = format; } else if (type == babl_type ("float")) { if (has_alpha) { if (gray) *lcms_format = TYPE_GRAYA_FLT; else *lcms_format = TYPE_RGBA_FLT; } else { if (gray) *lcms_format = TYPE_GRAY_FLT; else *lcms_format = TYPE_RGB_FLT; } output_format = format; } else if (type == babl_type ("double")) { if (has_alpha) { if (gray) *lcms_format = TYPE_GRAYA_DBL; else *lcms_format = TYPE_RGBA_DBL; } else { if (gray) *lcms_format = TYPE_GRAY_DBL; else *lcms_format = TYPE_RGB_DBL; } output_format = format; } if (*lcms_format == 0) { g_printerr ("%s: layer format %s not supported, " "falling back to float\n", G_STRFUNC, babl_get_name (format)); if (has_alpha) { if (gray) { *lcms_format = TYPE_GRAYA_FLT; if (linear) output_format = babl_format ("YA float"); else output_format = babl_format ("Y'A float"); } else { *lcms_format = TYPE_RGBA_FLT; if (linear) output_format = babl_format ("RGBA float"); else output_format = babl_format ("R'G'B'A float"); } } else { if (gray) { *lcms_format = TYPE_GRAY_FLT; if (linear) output_format = babl_format ("Y float"); else output_format = babl_format ("Y' float"); } else { *lcms_format = TYPE_RGB_FLT; if (linear) output_format = babl_format ("RGB float"); else output_format = babl_format ("R'G'B' float"); } } } return output_format; }
static int export_tiff (GeglOperation *operation, GeglBuffer *input, const GeglRectangle *result) { GeglProperties *o = GEGL_PROPERTIES(operation); Priv *p = (Priv*) o->user_data; gshort color_space, compression = COMPRESSION_NONE; gushort bits_per_sample, samples_per_pixel; gboolean has_alpha, alpha_is_premultiplied = FALSE; gushort sample_format, predictor = 0; gushort extra_types[1]; glong rows_per_stripe = 1; gint bytes_per_row; const Babl *type, *model; gchar format_string[32]; const Babl *format; g_return_val_if_fail(p->tiff != NULL, -1); TIFFSetField(p->tiff, TIFFTAG_SUBFILETYPE, 0); TIFFSetField(p->tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(p->tiff, TIFFTAG_IMAGEWIDTH, result->width); TIFFSetField(p->tiff, TIFFTAG_IMAGELENGTH, result->height); format = gegl_buffer_get_format(input); model = babl_format_get_model(format); type = babl_format_get_type(format, 0); if (model == babl_model("Y") || model == babl_model("Y'")) { has_alpha = FALSE; color_space = PHOTOMETRIC_MINISBLACK; model = babl_model("Y'"); samples_per_pixel = 1; } else if (model == babl_model("YA") || model == babl_model("Y'A")) { has_alpha = TRUE; alpha_is_premultiplied = FALSE; color_space = PHOTOMETRIC_MINISBLACK; model = babl_model("Y'A"); samples_per_pixel = 2; } else if (model == babl_model("YaA") || model == babl_model("Y'aA")) { has_alpha = TRUE; alpha_is_premultiplied = TRUE; color_space = PHOTOMETRIC_MINISBLACK; model = babl_model("Y'aA"); samples_per_pixel = 2; } else if (model == babl_model("RGB") || model == babl_model("R'G'B'")) { has_alpha = FALSE; color_space = PHOTOMETRIC_RGB; model = babl_model("R'G'B'"); samples_per_pixel = 3; predictor = 2; } else if (model == babl_model("RGBA") || model == babl_model("R'G'B'A")) { has_alpha = TRUE; alpha_is_premultiplied = FALSE; color_space = PHOTOMETRIC_RGB; model = babl_model("R'G'B'A"); samples_per_pixel = 4; predictor = 2; } else if (model == babl_model("RaGaBaA") || model == babl_model("R'aG'aB'aA")) { has_alpha = TRUE; alpha_is_premultiplied = TRUE; color_space = PHOTOMETRIC_RGB; model = babl_model("R'aG'aB'aA"); samples_per_pixel = 4; predictor = 2; } else { g_warning("color space not supported: %s", babl_get_name(model)); has_alpha = TRUE; alpha_is_premultiplied = TRUE; color_space = PHOTOMETRIC_RGB; model = babl_model("R'aG'aB'aA"); samples_per_pixel = 4; predictor = 2; } TIFFSetField(p->tiff, TIFFTAG_PHOTOMETRIC, color_space); TIFFSetField(p->tiff, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel); TIFFSetField(p->tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); if (has_alpha) { if (alpha_is_premultiplied) extra_types[0] = EXTRASAMPLE_ASSOCALPHA; else extra_types[0] = EXTRASAMPLE_UNASSALPHA; TIFFSetField(p->tiff, TIFFTAG_EXTRASAMPLES, 1, extra_types); } if (predictor != 0) { if (compression == COMPRESSION_LZW) TIFFSetField(p->tiff, TIFFTAG_PREDICTOR, predictor); else if (compression == COMPRESSION_ADOBE_DEFLATE) TIFFSetField(p->tiff, TIFFTAG_PREDICTOR, predictor); } if (type == babl_type("u8")) { sample_format = SAMPLEFORMAT_UINT; bits_per_sample = 8; } else if (type == babl_type("half")) { sample_format = SAMPLEFORMAT_IEEEFP; bits_per_sample = 16; } else if (type == babl_type("u16")) { sample_format = SAMPLEFORMAT_UINT; bits_per_sample = 16; } else if (type == babl_type("float")) { sample_format = SAMPLEFORMAT_IEEEFP; bits_per_sample = 32; } else if (type == babl_type("u32")) { sample_format = SAMPLEFORMAT_UINT; bits_per_sample = 32; } else if (type == babl_type("double")) { sample_format = SAMPLEFORMAT_IEEEFP; bits_per_sample = 64; } else { g_warning("sample format not supported: %s", babl_get_name(type)); sample_format = SAMPLEFORMAT_UINT; type = babl_type("u8"); bits_per_sample = 8; } TIFFSetField(p->tiff, TIFFTAG_BITSPERSAMPLE, bits_per_sample); TIFFSetField(p->tiff, TIFFTAG_SAMPLEFORMAT, sample_format); TIFFSetField(p->tiff, TIFFTAG_COMPRESSION, compression); if ((compression == COMPRESSION_CCITTFAX3 || compression == COMPRESSION_CCITTFAX4) && (bits_per_sample != 1 || samples_per_pixel != 1)) { g_critical("only monochrome pictures can be compressed " "with \"CCITT Group 4\" or \"CCITT Group 3\""); return -1; } g_snprintf(format_string, 32, "%s %s", babl_get_name(model), babl_get_name(type)); format = babl_format(format_string); /* "Choose RowsPerStrip such that each strip is about 8K bytes." */ bytes_per_row = babl_format_get_bytes_per_pixel(format) * result->width; while (bytes_per_row * rows_per_stripe <= 8192) rows_per_stripe++; rows_per_stripe = MIN(rows_per_stripe, result->height); TIFFSetField(p->tiff, TIFFTAG_ROWSPERSTRIP, rows_per_stripe); return save_contiguous(operation, input, result, format); }
/** * gimp_color_profile_get_format: * @format: a #Babl format * @lcms_format: return location for an lcms format * * This function takes a #Babl format and returns the lcms format to * be used with that @format. It also returns a #Babl format to be * used instead of the passed @format, which usually is the same as * @format, unless lcms doesn't support @format. * * Note that this function currently only supports RGB, RGBA, R'G'B' and * R'G'B'A formats. * * Return value: the #Babl format to be used instead of @format, or %NULL * is the passed @format is not supported at all. * * Since: 2.10 **/ const Babl * gimp_color_profile_get_format (const Babl *format, guint32 *lcms_format) { const Babl *output_format = NULL; const Babl *type; const Babl *model; gboolean has_alpha; gboolean linear; g_return_val_if_fail (format != NULL, NULL); g_return_val_if_fail (lcms_format != NULL, NULL); has_alpha = babl_format_has_alpha (format); type = babl_format_get_type (format, 0); model = babl_format_get_model (format); if (model == babl_model ("RGB") || model == babl_model ("RGBA")) { linear = TRUE; } else if (model == babl_model ("R'G'B'") || model == babl_model ("R'G'B'A")) { linear = FALSE; } else { g_return_val_if_reached (NULL); } *lcms_format = 0; if (type == babl_type ("u8")) { if (has_alpha) *lcms_format = TYPE_RGBA_8; else *lcms_format = TYPE_RGB_8; output_format = format; } else if (type == babl_type ("u16")) { if (has_alpha) *lcms_format = TYPE_RGBA_16; else *lcms_format = TYPE_RGB_16; output_format = format; } else if (type == babl_type ("half")) /* 16-bit floating point (half) */ { if (has_alpha) *lcms_format = TYPE_RGBA_HALF_FLT; else *lcms_format = TYPE_RGB_HALF_FLT; output_format = format; } else if (type == babl_type ("float")) { if (has_alpha) *lcms_format = TYPE_RGBA_FLT; else *lcms_format = TYPE_RGB_FLT; output_format = format; } else if (type == babl_type ("double")) { if (has_alpha) { #ifdef TYPE_RGBA_DBL /* RGBA double not implemented in lcms */ *lcms_format = TYPE_RGBA_DBL; output_format = format; #endif /* TYPE_RGBA_DBL */ } else { *lcms_format = TYPE_RGB_DBL; output_format = format; } } if (*lcms_format == 0) { g_printerr ("%s: layer format %s not supported, " "falling back to float\n", G_STRFUNC, babl_get_name (format)); if (has_alpha) { *lcms_format = TYPE_RGBA_FLT; if (linear) output_format = babl_format ("RGBA float"); else output_format = babl_format ("R'G'B'A float"); } else { *lcms_format = TYPE_RGB_FLT; if (linear) output_format = babl_format ("RGB float"); else output_format = babl_format ("R'G'B' float"); } } return output_format; }
void combine_paint_mask_to_canvas_mask (const GimpTempBuf *paint_mask, gint mask_x_offset, gint mask_y_offset, GeglBuffer *canvas_buffer, gint x_offset, gint y_offset, gfloat opacity, gboolean stipple) { GeglRectangle roi; GeglBufferIterator *iter; const gint mask_stride = gimp_temp_buf_get_width (paint_mask); const gint mask_start_offset = mask_y_offset * mask_stride + mask_x_offset; const Babl *mask_format = gimp_temp_buf_get_format (paint_mask); roi.x = x_offset; roi.y = y_offset; roi.width = gimp_temp_buf_get_width (paint_mask) - mask_x_offset; roi.height = gimp_temp_buf_get_height (paint_mask) - mask_y_offset; iter = gegl_buffer_iterator_new (canvas_buffer, &roi, 0, babl_format ("Y float"), GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE); if (stipple) { if (mask_format == babl_format ("Y u8")) { const guint8 *mask_data = (const guint8 *) gimp_temp_buf_get_data (paint_mask); mask_data += mask_start_offset; while (gegl_buffer_iterator_next (iter)) { gfloat *out_pixel = (gfloat *)iter->data[0]; int iy, ix; for (iy = 0; iy < iter->roi[0].height; iy++) { int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x; const guint8 *mask_pixel = &mask_data[mask_offset]; for (ix = 0; ix < iter->roi[0].width; ix++) { out_pixel[0] += (1.0 - out_pixel[0]) * (*mask_pixel / 255.0f) * opacity; mask_pixel += 1; out_pixel += 1; } } } } else if (mask_format == babl_format ("Y float")) { const gfloat *mask_data = (const gfloat *) gimp_temp_buf_get_data (paint_mask); mask_data += mask_start_offset; while (gegl_buffer_iterator_next (iter)) { gfloat *out_pixel = (gfloat *)iter->data[0]; int iy, ix; for (iy = 0; iy < iter->roi[0].height; iy++) { int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x; const gfloat *mask_pixel = &mask_data[mask_offset]; for (ix = 0; ix < iter->roi[0].width; ix++) { out_pixel[0] += (1.0 - out_pixel[0]) * (*mask_pixel) * opacity; mask_pixel += 1; out_pixel += 1; } } } } else { g_warning("Mask format not supported: %s", babl_get_name (mask_format)); } } else { if (mask_format == babl_format ("Y u8")) { const guint8 *mask_data = (const guint8 *) gimp_temp_buf_get_data (paint_mask); mask_data += mask_start_offset; while (gegl_buffer_iterator_next (iter)) { gfloat *out_pixel = (gfloat *)iter->data[0]; int iy, ix; for (iy = 0; iy < iter->roi[0].height; iy++) { int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x; const guint8 *mask_pixel = &mask_data[mask_offset]; for (ix = 0; ix < iter->roi[0].width; ix++) { if (opacity > out_pixel[0]) out_pixel[0] += (opacity - out_pixel[0]) * (*mask_pixel / 255.0f) * opacity; mask_pixel += 1; out_pixel += 1; } } } } else if (mask_format == babl_format ("Y float")) { const gfloat *mask_data = (const gfloat *) gimp_temp_buf_get_data (paint_mask); mask_data += mask_start_offset; while (gegl_buffer_iterator_next (iter)) { gfloat *out_pixel = (gfloat *)iter->data[0]; int iy, ix; for (iy = 0; iy < iter->roi[0].height; iy++) { int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x; const gfloat *mask_pixel = &mask_data[mask_offset]; for (ix = 0; ix < iter->roi[0].width; ix++) { if (opacity > out_pixel[0]) out_pixel[0] += (opacity - out_pixel[0]) * (*mask_pixel) * opacity; mask_pixel += 1; out_pixel += 1; } } } } else { g_warning("Mask format not supported: %s", babl_get_name (mask_format)); } } }
static gboolean test_buffer_open (void) { gboolean result = TRUE; gchar *tmpdir = NULL; gchar *buf_a_path = NULL; GeglBuffer *buf_a = NULL; const Babl *format = babl_format ("R'G'B'A u8"); GeglRectangle roi = {0, 0, 128, 128}; tmpdir = g_dir_make_tmp ("test-backend-file-XXXXXX", NULL); g_return_val_if_fail (tmpdir, FALSE); buf_a_path = g_build_filename (tmpdir, "buf_a.gegl", NULL); buf_a = g_object_new (GEGL_TYPE_BUFFER, "format", format, "path", buf_a_path, "x", roi.x, "y", roi.y, "width", roi.width, "height", roi.height, NULL); gegl_buffer_flush (buf_a); g_object_unref (buf_a); buf_a = gegl_buffer_open (buf_a_path); if (!GEGL_IS_BUFFER (buf_a)) { printf ("Failed to load file:%s\n", buf_a_path); result = FALSE; } if (!gegl_rectangle_equal (gegl_buffer_get_extent (buf_a), &roi)) { printf ("Extent does not match:\n"); gegl_rectangle_dump (gegl_buffer_get_extent (buf_a)); gegl_rectangle_dump (&roi); result = FALSE; } if (gegl_buffer_get_format (buf_a) != format) { printf ("Formats do not match:\n%s\n%s\n", babl_get_name (gegl_buffer_get_format (buf_a)), babl_get_name (format)); result = FALSE; } g_object_unref (buf_a); g_unlink (buf_a_path); g_remove (tmpdir); g_free (tmpdir); g_free (buf_a_path); return result; }
static gboolean process (GeglOperation *operation, GeglBuffer *input, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); if (o->buffer) { GeglBuffer *output = GEGL_BUFFER (o->buffer); const Babl *in_format = gegl_buffer_get_format (input); const Babl *out_format = gegl_buffer_get_format (output); if (gegl_operation_use_opencl (operation) && gegl_cl_color_supported (in_format, out_format) == GEGL_CL_COLOR_CONVERT) { size_t size; gboolean err; cl_int cl_err = 0; GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output, result, out_format, GEGL_CL_BUFFER_WRITE); gint read = gegl_buffer_cl_iterator_add (i, input, result, out_format, GEGL_CL_BUFFER_READ, GEGL_ABYSS_NONE); gegl_cl_color_babl (out_format, &size); GEGL_NOTE (GEGL_DEBUG_OPENCL, "write-buffer: " "%p %p %s %s {%d %d %d %d}", input, output, babl_get_name (in_format), babl_get_name (out_format), result->x, result->y, result->width, result->height); while (gegl_buffer_cl_iterator_next (i, &err)) { if (err) break; cl_err = gegl_clEnqueueCopyBuffer (gegl_cl_get_command_queue (), i->tex[read], i->tex[0], 0, 0, i->size[0] * size, 0, NULL, NULL); if (cl_err != CL_SUCCESS) { GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", gegl_cl_errstring (cl_err)); break; } } if (cl_err || err) gegl_buffer_copy (input, result, output, result); } else gegl_buffer_copy (input, result, output, result); gegl_buffer_flush (output); } return TRUE; }