From: theAdib Date: Mon, 11 May 2009 22:08:17 +0000 (+0000) Subject: BUG: #273767: crash on ...; resolved crash on several pixbuf operations X-Git-Url: https://git.tokkee.org/?p=inkscape.git;a=commitdiff_plain;h=00cd8cdd29c4bcef32835fb75ed803cefeec6d10 BUG: #273767: crash on ...; resolved crash on several pixbuf operations --- diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 1cfe97125..b50a66086 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -75,24 +75,30 @@ int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { has_alpha = true; if (image_pixbuf) g_free(image_pixbuf); - image_pixbuf = g_new(unsigned char, 4 * width * height); - memset(image_pixbuf, 0x00, 4 * width * height); - - NRGC gc(NULL); - /* Update to renderable state */ - double sf = 1.0; - Geom::Matrix t(Geom::Scale(sf, sf)); - nr_arena_item_set_transform(ai, &t); - gc.transform.setIdentity(); - nr_arena_item_invoke_update( ai, NULL, &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE ); - nr_pixblock_setup_extern(pb, NR_PIXBLOCK_MODE_R8G8B8A8N, - (int)rect.x0, (int)rect.y0, (int)rect.x1, (int)rect.y1, - image_pixbuf, 4 * width, FALSE, FALSE ); - - nr_arena_item_invoke_render(NULL, ai, &rect, pb, NR_ARENA_ITEM_RENDER_NO_CACHE); - + image_pixbuf = g_try_new(unsigned char, 4L * width * height); + if(image_pixbuf != NULL) + { + memset(image_pixbuf, 0x00, 4 * width * height); + + NRGC gc(NULL); + /* Update to renderable state */ + double sf = 1.0; + Geom::Matrix t(Geom::Scale(sf, sf)); + nr_arena_item_set_transform(ai, &t); + gc.transform.setIdentity(); + nr_arena_item_invoke_update( ai, NULL, &gc, + NR_ARENA_ITEM_STATE_ALL, + NR_ARENA_ITEM_STATE_NONE ); + nr_pixblock_setup_extern(pb, NR_PIXBLOCK_MODE_R8G8B8A8N, + (int)rect.x0, (int)rect.y0, (int)rect.x1, (int)rect.y1, + image_pixbuf, 4 * width, FALSE, FALSE ); + + nr_arena_item_invoke_render(NULL, ai, &rect, pb, NR_ARENA_ITEM_RENDER_NO_CACHE); + } + else + { + g_warning("FilterImage::render: not enough memory to create pixel buffer. Need %ld.", 4L * width * height); + } nr_arena_item_unref(ai); nr_object_unref((NRObject *) arena); } diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index 49a8cc28c..c7984137a 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -99,6 +99,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, { + GdkPixbuf* pixbuf = NULL; /* Create new arena for offscreen rendering*/ NRArena *arena = NRArena::create(); nr_arena_set_renderoffscreen(arena); @@ -140,36 +141,45 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, nr_arena_item_invoke_update(root, &final_bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); - guchar *px = g_new(guchar, 4 * width * height); + guchar *px = g_try_new(guchar, 4L * width * height); - NRPixBlock B; - nr_pixblock_setup_extern( &B, NR_PIXBLOCK_MODE_R8G8B8A8N, - final_bbox.x0, final_bbox.y0, final_bbox.x1, final_bbox.y1, - px, 4 * width, FALSE, FALSE ); - - unsigned char dtc[4]; - dtc[0] = NR_RGBA32_R(bgcolor); - dtc[1] = NR_RGBA32_G(bgcolor); - dtc[2] = NR_RGBA32_B(bgcolor); - dtc[3] = NR_RGBA32_A(bgcolor); + if(px != NULL) + { - for (unsigned int fy = 0; fy < height; fy++) { - guchar *p = NR_PIXBLOCK_PX(&B) + fy * B.rs; - for (unsigned int fx = 0; fx < width; fx++) { - for (int i = 0; i < 4; i++) { - *p++ = dtc[i]; + NRPixBlock B; + g_warning("sp_generate_internal_bitmap: nr_pixblock_setup_extern."); + nr_pixblock_setup_extern( &B, NR_PIXBLOCK_MODE_R8G8B8A8N, + final_bbox.x0, final_bbox.y0, final_bbox.x1, final_bbox.y1, + px, 4 * width, FALSE, FALSE ); + + unsigned char dtc[4]; + dtc[0] = NR_RGBA32_R(bgcolor); + dtc[1] = NR_RGBA32_G(bgcolor); + dtc[2] = NR_RGBA32_B(bgcolor); + dtc[3] = NR_RGBA32_A(bgcolor); + + for (unsigned int fy = 0; fy < height; fy++) { + guchar *p = NR_PIXBLOCK_PX(&B) + fy * B.rs; + for (unsigned int fx = 0; fx < width; fx++) { + for (int i = 0; i < 4; i++) { + *p++ = dtc[i]; + } } } - } - - nr_arena_item_invoke_render(NULL, root, &final_bbox, &B, NR_ARENA_ITEM_RENDER_NO_CACHE ); + - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(px, GDK_COLORSPACE_RGB, - TRUE, - 8, width, height, width * 4, - (GdkPixbufDestroyNotify)g_free, - NULL); + nr_arena_item_invoke_render(NULL, root, &final_bbox, &B, NR_ARENA_ITEM_RENDER_NO_CACHE ); + pixbuf = gdk_pixbuf_new_from_data(px, GDK_COLORSPACE_RGB, + TRUE, + 8, width, height, width * 4, + (GdkPixbufDestroyNotify)g_free, + NULL); + } + else + { + g_warning("sp_generate_internal_bitmap: not enough memory to create pixel buffer. Need %ld.", 4L * width * height); + } sp_item_invoke_hide (SP_ITEM(sp_document_root(doc)), dkey); nr_object_unref((NRObject *) arena); diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index 0e056e981..3ac900680 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -133,6 +133,7 @@ sp_png_write_rgba_striped(SPDocument *doc, png_uint_32 r; g_return_val_if_fail(filename != NULL, false); + g_return_val_if_fail(data != NULL, false); /* open the file */ @@ -496,7 +497,7 @@ sp_export_png_file(SPDocument *doc, gchar const *filename, nr_pixelstore_64K_free(ebp.px); } else { ebp.sheight = 64; - ebp.px = g_new(guchar, 4 * ebp.sheight * width); + ebp.px = g_try_new(guchar, 4 * ebp.sheight * width); write_status = sp_png_write_rgba_striped(doc, path, width, height, xdpi, ydpi, sp_export_get_rows, &ebp); g_free(ebp.px); }