static void gimp_tile_put (GimpTile *tile) { extern GIOChannel *_writechannel; GPTileReq tile_req; GPTileData tile_data; GPTileData *tile_info; GimpWireMessage msg; tile_req.drawable_ID = -1; tile_req.tile_num = 0; tile_req.shadow = 0; gp_lock (); if (! gp_tile_req_write (_writechannel, &tile_req, NULL)) gimp_quit (); gimp_read_expect_msg (&msg, GP_TILE_DATA); tile_info = msg.data; tile_data.drawable_ID = tile->drawable->drawable_id; tile_data.tile_num = tile->tile_num; tile_data.shadow = tile->shadow; tile_data.bpp = tile->bpp; tile_data.width = tile->ewidth; tile_data.height = tile->eheight; tile_data.use_shm = tile_info->use_shm; tile_data.data = NULL; if (tile_info->use_shm) memcpy (gimp_shm_addr (), tile->data, tile->ewidth * tile->eheight * tile->bpp); else tile_data.data = tile->data; if (! gp_tile_data_write (_writechannel, &tile_data, NULL)) gimp_quit (); if (! tile_info->use_shm) tile_data.data = NULL; gimp_wire_destroy (&msg); gimp_read_expect_msg (&msg, GP_TILE_ACK); gp_unlock (); gimp_wire_destroy (&msg); }
static void gimp_plug_in_handle_tile_get (GimpPlugIn *plug_in, GPTileReq *request) { GPTileData tile_data; GimpWireMessage msg; GimpDrawable *drawable; GeglBuffer *buffer; const Babl *format; GeglRectangle tile_rect; gint tile_size; drawable = (GimpDrawable *) gimp_item_get_by_ID (plug_in->manager->gimp, request->drawable_ID); if (! GIMP_IS_DRAWABLE (drawable)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried reading from invalid drawable %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), request->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } else if (gimp_item_is_removed (GIMP_ITEM (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried reading from drawable %d which was removed " "from the image (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), request->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } if (request->shadow) { buffer = gimp_drawable_get_shadow_buffer (drawable); gimp_plug_in_cleanup_add_shadow (plug_in, drawable); } else { buffer = gimp_drawable_get_buffer (drawable); } if (! gimp_gegl_buffer_get_tile_rect (buffer, GIMP_PLUG_IN_TILE_WIDTH, GIMP_PLUG_IN_TILE_HEIGHT, request->tile_num, &tile_rect)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "requested invalid tile (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file)); gimp_plug_in_close (plug_in, TRUE); return; } format = gegl_buffer_get_format (buffer); if (! gimp_plug_in_precision_enabled (plug_in)) { format = gimp_babl_compat_u8_format (format); } tile_size = (babl_format_get_bytes_per_pixel (format) * tile_rect.width * tile_rect.height); tile_data.drawable_ID = request->drawable_ID; tile_data.tile_num = request->tile_num; tile_data.shadow = request->shadow; tile_data.bpp = babl_format_get_bytes_per_pixel (format); tile_data.width = tile_rect.width; tile_data.height = tile_rect.height; tile_data.use_shm = (plug_in->manager->shm != NULL); if (tile_data.use_shm) { gegl_buffer_get (buffer, &tile_rect, 1.0, format, gimp_plug_in_shm_get_addr (plug_in->manager->shm), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); } else { tile_data.data = g_malloc (tile_size); gegl_buffer_get (buffer, &tile_rect, 1.0, format, tile_data.data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); } if (! gp_tile_data_write (plug_in->my_write, &tile_data, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (! gimp_wire_read_msg (plug_in->my_read, &msg, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (msg.type != GP_TILE_ACK) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "expected tile ack and received: %d", msg.type); gimp_plug_in_close (plug_in, TRUE); return; } gimp_wire_destroy (&msg); }
static void gimp_plug_in_handle_tile_put (GimpPlugIn *plug_in, GPTileReq *request) { GPTileData tile_data; GPTileData *tile_info; GimpWireMessage msg; GimpDrawable *drawable; GeglBuffer *buffer; const Babl *format; GeglRectangle tile_rect; tile_data.drawable_ID = -1; tile_data.tile_num = 0; tile_data.shadow = 0; tile_data.bpp = 0; tile_data.width = 0; tile_data.height = 0; tile_data.use_shm = (plug_in->manager->shm != NULL); tile_data.data = NULL; if (! gp_tile_data_write (plug_in->my_write, &tile_data, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (! gimp_wire_read_msg (plug_in->my_read, &msg, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (msg.type != GP_TILE_DATA) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "expected tile data and received: %d", msg.type); gimp_plug_in_close (plug_in, TRUE); return; } tile_info = msg.data; drawable = (GimpDrawable *) gimp_item_get_by_ID (plug_in->manager->gimp, tile_info->drawable_ID); if (! GIMP_IS_DRAWABLE (drawable)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to invalid drawable %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } else if (gimp_item_is_removed (GIMP_ITEM (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to drawable %d which was removed " "from the image (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } if (tile_info->shadow) { /* don't check whether the drawable is a group or locked here, * the plugin will get a proper error message when it tries to * merge the shadow tiles, which is much better than just * killing it. */ buffer = gimp_drawable_get_shadow_buffer (drawable); gimp_plug_in_cleanup_add_shadow (plug_in, drawable); } else { if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to a locked drawable %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to a group layer %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } buffer = gimp_drawable_get_buffer (drawable); } if (! gimp_gegl_buffer_get_tile_rect (buffer, GIMP_PLUG_IN_TILE_WIDTH, GIMP_PLUG_IN_TILE_HEIGHT, tile_info->tile_num, &tile_rect)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "requested invalid tile (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file)); gimp_plug_in_close (plug_in, TRUE); return; } format = gegl_buffer_get_format (buffer); if (! gimp_plug_in_precision_enabled (plug_in)) { format = gimp_babl_compat_u8_format (format); } if (tile_data.use_shm) { gegl_buffer_set (buffer, &tile_rect, 0, format, gimp_plug_in_shm_get_addr (plug_in->manager->shm), GEGL_AUTO_ROWSTRIDE); } else { gegl_buffer_set (buffer, &tile_rect, 0, format, tile_info->data, GEGL_AUTO_ROWSTRIDE); } gimp_wire_destroy (&msg); if (! gp_tile_ack_write (plug_in->my_write, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } }