From 65f85a0b439681d9893b4c8d660078abe8227366c3a0663970b78dd2e9c7a93d Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Fri, 1 Aug 2025 01:30:15 -0400 Subject: [PATCH] Image (reference counted) now uses shared_ptr. --- src/dicache.cc | 16 ++++++++-------- src/form.cc | 2 +- src/html.cc | 24 ++++++++++-------------- src/html_common.hh | 8 ++++---- src/image.cc | 30 +++--------------------------- src/image.hh | 8 ++------ src/styleengine.cc | 5 ++--- src/web.cc | 1 - src/web.hh | 2 +- 9 files changed, 31 insertions(+), 65 deletions(-) diff --git a/src/dicache.cc b/src/dicache.cc index 994e4a9..4c9ae9c 100644 --- a/src/dicache.cc +++ b/src/dicache.cc @@ -399,7 +399,6 @@ static void *Dicache_image(int ImgType, const char *MimeType, void *Ptr, if (!web->Image) { web->Image = a_Image_new_with_dw(web->bw->render_layout, NULL, web->bgColor, 0); - a_Image_ref(web->Image); } DicEntry = a_Dicache_get_entry(web->url.get(), DIC_Last); @@ -407,26 +406,27 @@ static void *Dicache_image(int ImgType, const char *MimeType, void *Ptr, /* Create an entry for this image... */ DicEntry = Dicache_add_entry(web->url.get()); /* Attach a decoder */ + // TODO: Is this begging for a virtual dispatch? if (ImgType == DIC_Jpeg) { DicEntry->Decoder = (CA_Callback_t)a_Jpeg_callback; DicEntry->DecoderData = - a_Jpeg_new(web->Image, DicEntry->url, DicEntry->version); + a_Jpeg_new(web->Image.get(), DicEntry->url, DicEntry->version); } else if (ImgType == DIC_Gif) { DicEntry->Decoder = (CA_Callback_t)a_Gif_callback; DicEntry->DecoderData = - a_Gif_new(web->Image, DicEntry->url, DicEntry->version); + a_Gif_new(web->Image.get(), DicEntry->url, DicEntry->version); } else if (ImgType == DIC_Webp) { DicEntry->Decoder = (CA_Callback_t)a_Webp_callback; DicEntry->DecoderData = - a_Webp_new(web->Image, DicEntry->url, DicEntry->version); + a_Webp_new(web->Image.get(), DicEntry->url, DicEntry->version); } else if (ImgType == DIC_Png) { DicEntry->Decoder = (CA_Callback_t)a_Png_callback; DicEntry->DecoderData = - a_Png_new(web->Image, DicEntry->url, DicEntry->version); + a_Png_new(web->Image.get(), DicEntry->url, DicEntry->version); } else if (ImgType == DIC_Svg) { DicEntry->Decoder = (CA_Callback_t)a_Svg_callback; DicEntry->DecoderData = - a_Svg_new(web->Image, DicEntry->url, DicEntry->version); + a_Svg_new(web->Image.get(), DicEntry->url, DicEntry->version); } } else { /* Repeated image */ @@ -438,7 +438,7 @@ static void *Dicache_image(int ImgType, const char *MimeType, void *Ptr, *Data = DicEntry->DecoderData; *Call = (CA_Callback_t) a_Dicache_callback; - return (a_Image_get_dw (web->Image)); + return (a_Image_get_dw (web->Image.get())); } /** @@ -493,7 +493,7 @@ void a_Dicache_callback(int Op, CacheClient_t *Client) { uint_t i; DilloWeb *Web = reinterpret_cast< DilloWeb * >( Client->Web ); - DilloImage *Image = Web->Image; + DilloImage *Image = Web->Image.get(); DICacheEntry *DicEntry = a_Dicache_get_entry(Web->url.get(), DIC_Last); dReturn_if_fail ( DicEntry != NULL ); diff --git a/src/form.cc b/src/form.cc index ff1536c..8524300 100644 --- a/src/form.cc +++ b/src/form.cc @@ -2003,7 +2003,7 @@ DilloHtmlOption::~DilloHtmlOption () */ static Embed *Html_input_image(DilloHtml *html, const char *tag, int tagsize) { - DilloImage *Image; + std::shared_ptr< DilloImage > Image; Embed *button = NULL; html->styleEngine->setPseudoLink (); diff --git a/src/html.cc b/src/html.cc index 836eff1..b7c0f1f 100644 --- a/src/html.cc +++ b/src/html.cc @@ -107,7 +107,7 @@ void *a_Html_text(const char *type, void *P, CA_Callback_t *Call,void **Data); *---------------------------------------------------------------------------*/ static int Html_write_raw(DilloHtml *html, char *buf, int bufsize, int Eof); static bool Html_load_image(BrowserWindow *bw, DilloUrl *url, - const DilloUrl *requester, DilloImage *image); + const DilloUrl *requester, std::shared_ptr< DilloImage > image); static void Html_callback(int Op, CacheClient_t *Client); static void Html_tag_cleanup_at_close(DilloHtml *html, int TagIdx); int a_Html_tag_index(const char *tag); @@ -574,7 +574,7 @@ DilloHtml::~DilloHtml() for (int i = 0; i < images->size(); i++) { DilloHtmlImage *img = images->get(i); delete img->url; - a_Image_unref(img->image); + img->image.reset(); // Was: a_Image_unref(img->image); dFree(img); } delete (images); @@ -728,8 +728,7 @@ void DilloHtml::loadImages (const DilloUrl *pattern) assert(hi->url); if ((!pattern) || (!a_Url_cmp(hi->url, pattern))) { if (Html_load_image(bw, hi->url, requester, hi->image)) { - a_Image_unref (hi->image); - hi->image = NULL; // web owns it now + hi->image = nullptr; // web owns it now } } } @@ -2128,12 +2127,12 @@ void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize) html->images->size()); } -DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize) +std::shared_ptr< DilloImage > a_Html_image_new(DilloHtml *html, const char *tag, int tagsize) { bool load_now; const char *attrbuf; DilloUrl *url; - DilloImage *image; + std::shared_ptr< DilloImage > image; if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")) || !(url = a_Html_url_new(html, attrbuf, NULL, 0).release())) @@ -2148,7 +2147,6 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize) image = a_Image_new(html->dw->getLayout(), (void*)(dw::core::ImgRenderer*)dw, 0, 0); - a_Image_ref(image); if (HT2TB(html)->getBgColor()) image->bg_color = HT2TB(html)->getBgColor()->getColor(); @@ -2156,7 +2154,7 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize) if (HT2TB(html)->getFgColor()) image->fg_color = HT2TB(html)->getFgColor()->getColor(); - DilloHtmlImage *hi = dNew(DilloHtmlImage, 1); + DilloHtmlImage *hi = new DilloHtmlImage{}; hi->url = url; html->images->increase(); html->images->set(html->images->size() - 1, hi); @@ -2167,8 +2165,7 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize) if (load_now && Html_load_image(html->bw, url, html->page_url, image)) { // hi->image is NULL if dillo tries to load the image immediately - hi->image = NULL; - a_Image_unref(image); + hi->image = nullptr; } else { // otherwise a reference is kept in html->images hi->image = image; @@ -2181,14 +2178,13 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize) * Tell cache to retrieve image */ static bool Html_load_image(BrowserWindow *bw, DilloUrl *url, - const DilloUrl *requester, DilloImage *Image) + const DilloUrl *requester, std::shared_ptr< DilloImage > Image) { DilloWeb *Web; int ClientKey; /* Fill a Web structure for the cache query */ Web = a_Web_new(bw, url, requester); Web->Image = Image; - a_Image_ref(Image); Web->flags |= WEB_Image; /* Request image data from the cache */ if ((ClientKey = a_Capi_open_url(Web, NULL, NULL)) != 0) { @@ -2263,7 +2259,7 @@ static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_content_img(DilloHtml *html, const char *tag, int tagsize) { - DilloImage *Image; + std::shared_ptr< DilloImage > Image; const char *attrbuf; /* This avoids loading images. Useful for viewing suspicious HTML email. */ @@ -2336,7 +2332,7 @@ static void Html_tag_close_map(DilloHtml *html) * redraw. (It will only do so if it uses a map.) */ for (int i = 0; i < html->images->size(); i++) { - DilloImage *img = html->images->get(i)->image; + std::shared_ptr< DilloImage > img = html->images->get(i)->image; if (img) { // At this point, we know that img->ir represents an image diff --git a/src/html_common.hh b/src/html_common.hh index 6d63f61..0c36efc 100644 --- a/src/html_common.hh +++ b/src/html_common.hh @@ -118,10 +118,10 @@ typedef enum { * Data Structures */ -typedef struct { +struct DilloHtmlImage { DilloUrl *url; - DilloImage *image; -} DilloHtmlImage; + std::shared_ptr< DilloImage > image; +}; typedef struct { DilloHtmlParseMode parse_mode; @@ -283,7 +283,7 @@ std::unique_ptr< DilloUrl > a_Html_url_new(DilloHtml *html, int use_base_url); void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize); -DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize); +std::shared_ptr< DilloImage > a_Html_image_new(DilloHtml *html, const char *tag, int tagsize); char *a_Html_parse_entities(DilloHtml *html, const char *token, int toksize); void a_Html_pop_tag(DilloHtml *html, int TagIdx); diff --git a/src/image.cc b/src/image.cc index afec450..2347b2b 100644 --- a/src/image.cc +++ b/src/image.cc @@ -31,12 +31,11 @@ using namespace dw::core; /** * Create and initialize a new image structure. */ -DilloImage *a_Image_new(void *layout, void *img_rndr, +std::shared_ptr< DilloImage > a_Image_new(void *layout, void *img_rndr, int32_t bg_color, int32_t fg_color) { - DilloImage *Image; + auto Image= std::make_unique< DilloImage >(); - Image = dNew(DilloImage, 1); Image->layout = layout; Image->img_rndr = img_rndr; Image->width = 0; @@ -47,15 +46,13 @@ DilloImage *a_Image_new(void *layout, void *img_rndr, Image->ScanNumber = 0; Image->State = IMG_Empty; - Image->RefCount = 0; - return Image; } /** * Create and initialize a new image structure with an image widget. */ -DilloImage *a_Image_new_with_dw(void *layout, const char *alt_text, +std::shared_ptr< DilloImage > a_Image_new_with_dw(void *layout, const char *alt_text, int32_t bg_color, int32_t fg_color) { dw::Image *dw = new dw::Image(alt_text); @@ -73,27 +70,6 @@ void *a_Image_get_dw(DilloImage *Image) return (dw::Image*)(dw::core::ImgRenderer*)Image->img_rndr; } -/** - * Unref and free if necessary - * Do nothing if the argument is NULL - */ -void a_Image_unref(DilloImage *Image) -{ - _MSG(" %d ", Image->RefCount); - if (Image && --Image->RefCount == 0) - delete Image; -} - -/** - * Add a reference to an Image struct - * Do nothing if the argument is NULL - */ -void a_Image_ref(DilloImage *Image) -{ - if (Image) - ++Image->RefCount; -} - /** * Set initial parameters of the image */ diff --git a/src/image.hh b/src/image.hh index c1fdd6c..3c54089 100644 --- a/src/image.hh +++ b/src/image.hh @@ -69,21 +69,17 @@ struct DilloImage { std::unique_ptr< bitvec_t > BitVec; /**< Bit vector for decoded rows */ uint_t ScanNumber; /**< Current decoding scan */ ImageState State; /**< Processing status */ - - int RefCount; /**< Reference counter */ }; /* * Function prototypes */ -DilloImage *a_Image_new(void *layout, void *img_rndr, +std::shared_ptr< DilloImage > a_Image_new(void *layout, void *img_rndr, int32_t bg_color, int32_t fg_color); -DilloImage *a_Image_new_with_dw(void *layout, const char *alt_text, +std::shared_ptr< DilloImage > a_Image_new_with_dw(void *layout, const char *alt_text, int32_t bg_color, int32_t fg_color); void *a_Image_get_dw(DilloImage *Image); -void a_Image_ref(DilloImage *Image); -void a_Image_unref(DilloImage *Image); void a_Image_set_parms(DilloImage *Image, void *v_imgbuf, DilloUrl *url, int version, uint_t width, uint_t height, diff --git a/src/styleengine.cc b/src/styleengine.cc index 17a7f46..9a74d03 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -758,7 +758,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, !(URL_FLAGS(pageUrl) & URL_SpamSafe)) { attrs->backgroundImage = StyleImage::create(); - DilloImage *image = + auto image = a_Image_new(layout, (void*)attrs->backgroundImage ->getMainImgRenderer(), @@ -767,8 +767,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, // we use the pageUrl as requester to prevent cross // domain requests as specified in domainrc DilloWeb *web = a_Web_new(bw, imgUrl.get(), pageUrl); - web->Image = image; - a_Image_ref(image); + web->Image = std::move( image ); web->flags |= WEB_Image; int clientKey; diff --git a/src/web.cc b/src/web.cc index 97cad60..b11de8a 100644 --- a/src/web.cc +++ b/src/web.cc @@ -152,7 +152,6 @@ int a_Web_valid(DilloWeb *web) void a_Web_free(DilloWeb *web) { if (!web) return; - a_Image_unref(web->Image); dList_remove(ValidWebs, (void *)web); _MSG("a_Web_free: ValidWebs=%d\n", dList_length(ValidWebs)); delete web; diff --git a/src/web.hh b/src/web.hh index 61fafdc..7d89628 100644 --- a/src/web.hh +++ b/src/web.hh @@ -26,7 +26,7 @@ struct DilloWeb { BrowserWindow *bw; /**< The requesting browser window [reference] */ int flags; /**< Additional info */ - DilloImage *Image; /**< For image urls [reference] */ + std::shared_ptr< DilloImage > Image; /**< For image urls */ int32_t bgColor; /**< for image backgrounds */ std::optional< std::string > filename; /**< Variables for Local saving */