Image (reference counted) now uses shared_ptr.

This commit is contained in:
2025-08-01 01:30:15 -04:00
parent b2963b17d2
commit 65f85a0b43
9 changed files with 31 additions and 65 deletions

View File

@ -399,7 +399,6 @@ static void *Dicache_image(int ImgType, const char *MimeType, void *Ptr,
if (!web->Image) { if (!web->Image) {
web->Image = web->Image =
a_Image_new_with_dw(web->bw->render_layout, NULL, web->bgColor, 0); 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); 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... */ /* Create an entry for this image... */
DicEntry = Dicache_add_entry(web->url.get()); DicEntry = Dicache_add_entry(web->url.get());
/* Attach a decoder */ /* Attach a decoder */
// TODO: Is this begging for a virtual dispatch?
if (ImgType == DIC_Jpeg) { if (ImgType == DIC_Jpeg) {
DicEntry->Decoder = (CA_Callback_t)a_Jpeg_callback; DicEntry->Decoder = (CA_Callback_t)a_Jpeg_callback;
DicEntry->DecoderData = 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) { } else if (ImgType == DIC_Gif) {
DicEntry->Decoder = (CA_Callback_t)a_Gif_callback; DicEntry->Decoder = (CA_Callback_t)a_Gif_callback;
DicEntry->DecoderData = 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) { } else if (ImgType == DIC_Webp) {
DicEntry->Decoder = (CA_Callback_t)a_Webp_callback; DicEntry->Decoder = (CA_Callback_t)a_Webp_callback;
DicEntry->DecoderData = 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) { } else if (ImgType == DIC_Png) {
DicEntry->Decoder = (CA_Callback_t)a_Png_callback; DicEntry->Decoder = (CA_Callback_t)a_Png_callback;
DicEntry->DecoderData = 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) { } else if (ImgType == DIC_Svg) {
DicEntry->Decoder = (CA_Callback_t)a_Svg_callback; DicEntry->Decoder = (CA_Callback_t)a_Svg_callback;
DicEntry->DecoderData = DicEntry->DecoderData =
a_Svg_new(web->Image, DicEntry->url, DicEntry->version); a_Svg_new(web->Image.get(), DicEntry->url, DicEntry->version);
} }
} else { } else {
/* Repeated image */ /* Repeated image */
@ -438,7 +438,7 @@ static void *Dicache_image(int ImgType, const char *MimeType, void *Ptr,
*Data = DicEntry->DecoderData; *Data = DicEntry->DecoderData;
*Call = (CA_Callback_t) a_Dicache_callback; *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; uint_t i;
DilloWeb *Web = reinterpret_cast< DilloWeb * >( Client->Web ); 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); DICacheEntry *DicEntry = a_Dicache_get_entry(Web->url.get(), DIC_Last);
dReturn_if_fail ( DicEntry != NULL ); dReturn_if_fail ( DicEntry != NULL );

View File

@ -2003,7 +2003,7 @@ DilloHtmlOption::~DilloHtmlOption ()
*/ */
static Embed *Html_input_image(DilloHtml *html, const char *tag, int tagsize) static Embed *Html_input_image(DilloHtml *html, const char *tag, int tagsize)
{ {
DilloImage *Image; std::shared_ptr< DilloImage > Image;
Embed *button = NULL; Embed *button = NULL;
html->styleEngine->setPseudoLink (); html->styleEngine->setPseudoLink ();

View File

@ -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 int Html_write_raw(DilloHtml *html, char *buf, int bufsize, int Eof);
static bool Html_load_image(BrowserWindow *bw, DilloUrl *url, 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_callback(int Op, CacheClient_t *Client);
static void Html_tag_cleanup_at_close(DilloHtml *html, int TagIdx); static void Html_tag_cleanup_at_close(DilloHtml *html, int TagIdx);
int a_Html_tag_index(const char *tag); int a_Html_tag_index(const char *tag);
@ -574,7 +574,7 @@ DilloHtml::~DilloHtml()
for (int i = 0; i < images->size(); i++) { for (int i = 0; i < images->size(); i++) {
DilloHtmlImage *img = images->get(i); DilloHtmlImage *img = images->get(i);
delete img->url; delete img->url;
a_Image_unref(img->image); img->image.reset(); // Was: a_Image_unref(img->image);
dFree(img); dFree(img);
} }
delete (images); delete (images);
@ -728,8 +728,7 @@ void DilloHtml::loadImages (const DilloUrl *pattern)
assert(hi->url); assert(hi->url);
if ((!pattern) || (!a_Url_cmp(hi->url, pattern))) { if ((!pattern) || (!a_Url_cmp(hi->url, pattern))) {
if (Html_load_image(bw, hi->url, requester, hi->image)) { if (Html_load_image(bw, hi->url, requester, hi->image)) {
a_Image_unref (hi->image); hi->image = nullptr; // web owns it now
hi->image = NULL; // web owns it now
} }
} }
} }
@ -2128,12 +2127,12 @@ void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize)
html->images->size()); 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; bool load_now;
const char *attrbuf; const char *attrbuf;
DilloUrl *url; DilloUrl *url;
DilloImage *image; std::shared_ptr< DilloImage > image;
if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")) || if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")) ||
!(url = a_Html_url_new(html, attrbuf, NULL, 0).release())) !(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 = image =
a_Image_new(html->dw->getLayout(), (void*)(dw::core::ImgRenderer*)dw, 0, 0); a_Image_new(html->dw->getLayout(), (void*)(dw::core::ImgRenderer*)dw, 0, 0);
a_Image_ref(image);
if (HT2TB(html)->getBgColor()) if (HT2TB(html)->getBgColor())
image->bg_color = HT2TB(html)->getBgColor()->getColor(); 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()) if (HT2TB(html)->getFgColor())
image->fg_color = HT2TB(html)->getFgColor()->getColor(); image->fg_color = HT2TB(html)->getFgColor()->getColor();
DilloHtmlImage *hi = dNew(DilloHtmlImage, 1); DilloHtmlImage *hi = new DilloHtmlImage{};
hi->url = url; hi->url = url;
html->images->increase(); html->images->increase();
html->images->set(html->images->size() - 1, hi); 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)) { 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 is NULL if dillo tries to load the image immediately
hi->image = NULL; hi->image = nullptr;
a_Image_unref(image);
} else { } else {
// otherwise a reference is kept in html->images // otherwise a reference is kept in html->images
hi->image = image; hi->image = image;
@ -2181,14 +2178,13 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize)
* Tell cache to retrieve image * Tell cache to retrieve image
*/ */
static bool Html_load_image(BrowserWindow *bw, DilloUrl *url, static bool Html_load_image(BrowserWindow *bw, DilloUrl *url,
const DilloUrl *requester, DilloImage *Image) const DilloUrl *requester, std::shared_ptr< DilloImage > Image)
{ {
DilloWeb *Web; DilloWeb *Web;
int ClientKey; int ClientKey;
/* Fill a Web structure for the cache query */ /* Fill a Web structure for the cache query */
Web = a_Web_new(bw, url, requester); Web = a_Web_new(bw, url, requester);
Web->Image = Image; Web->Image = Image;
a_Image_ref(Image);
Web->flags |= WEB_Image; Web->flags |= WEB_Image;
/* Request image data from the cache */ /* Request image data from the cache */
if ((ClientKey = a_Capi_open_url(Web, NULL, NULL)) != 0) { 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) static void Html_tag_content_img(DilloHtml *html, const char *tag, int tagsize)
{ {
DilloImage *Image; std::shared_ptr< DilloImage > Image;
const char *attrbuf; const char *attrbuf;
/* This avoids loading images. Useful for viewing suspicious HTML email. */ /* 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.) * redraw. (It will only do so if it uses a map.)
*/ */
for (int i = 0; i < html->images->size(); i++) { 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) { if (img) {
// At this point, we know that img->ir represents an image // At this point, we know that img->ir represents an image

View File

@ -118,10 +118,10 @@ typedef enum {
* Data Structures * Data Structures
*/ */
typedef struct { struct DilloHtmlImage {
DilloUrl *url; DilloUrl *url;
DilloImage *image; std::shared_ptr< DilloImage > image;
} DilloHtmlImage; };
typedef struct { typedef struct {
DilloHtmlParseMode parse_mode; DilloHtmlParseMode parse_mode;
@ -283,7 +283,7 @@ std::unique_ptr< DilloUrl > a_Html_url_new(DilloHtml *html,
int use_base_url); int use_base_url);
void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize); 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); char *a_Html_parse_entities(DilloHtml *html, const char *token, int toksize);
void a_Html_pop_tag(DilloHtml *html, int TagIdx); void a_Html_pop_tag(DilloHtml *html, int TagIdx);

View File

@ -31,12 +31,11 @@ using namespace dw::core;
/** /**
* Create and initialize a new image structure. * 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) int32_t bg_color, int32_t fg_color)
{ {
DilloImage *Image; auto Image= std::make_unique< DilloImage >();
Image = dNew(DilloImage, 1);
Image->layout = layout; Image->layout = layout;
Image->img_rndr = img_rndr; Image->img_rndr = img_rndr;
Image->width = 0; Image->width = 0;
@ -47,15 +46,13 @@ DilloImage *a_Image_new(void *layout, void *img_rndr,
Image->ScanNumber = 0; Image->ScanNumber = 0;
Image->State = IMG_Empty; Image->State = IMG_Empty;
Image->RefCount = 0;
return Image; return Image;
} }
/** /**
* Create and initialize a new image structure with an image widget. * 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) int32_t bg_color, int32_t fg_color)
{ {
dw::Image *dw = new dw::Image(alt_text); 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; 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 * Set initial parameters of the image
*/ */

View File

@ -69,21 +69,17 @@ struct DilloImage {
std::unique_ptr< bitvec_t > BitVec; /**< Bit vector for decoded rows */ std::unique_ptr< bitvec_t > BitVec; /**< Bit vector for decoded rows */
uint_t ScanNumber; /**< Current decoding scan */ uint_t ScanNumber; /**< Current decoding scan */
ImageState State; /**< Processing status */ ImageState State; /**< Processing status */
int RefCount; /**< Reference counter */
}; };
/* /*
* Function prototypes * 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); 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); int32_t bg_color, int32_t fg_color);
void *a_Image_get_dw(DilloImage *Image); 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, void a_Image_set_parms(DilloImage *Image, void *v_imgbuf, DilloUrl *url,
int version, uint_t width, uint_t height, int version, uint_t width, uint_t height,

View File

@ -758,7 +758,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
!(URL_FLAGS(pageUrl) & URL_SpamSafe)) !(URL_FLAGS(pageUrl) & URL_SpamSafe))
{ {
attrs->backgroundImage = StyleImage::create(); attrs->backgroundImage = StyleImage::create();
DilloImage *image = auto image =
a_Image_new(layout, a_Image_new(layout,
(void*)attrs->backgroundImage (void*)attrs->backgroundImage
->getMainImgRenderer(), ->getMainImgRenderer(),
@ -767,8 +767,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
// we use the pageUrl as requester to prevent cross // we use the pageUrl as requester to prevent cross
// domain requests as specified in domainrc // domain requests as specified in domainrc
DilloWeb *web = a_Web_new(bw, imgUrl.get(), pageUrl); DilloWeb *web = a_Web_new(bw, imgUrl.get(), pageUrl);
web->Image = image; web->Image = std::move( image );
a_Image_ref(image);
web->flags |= WEB_Image; web->flags |= WEB_Image;
int clientKey; int clientKey;

View File

@ -152,7 +152,6 @@ int a_Web_valid(DilloWeb *web)
void a_Web_free(DilloWeb *web) void a_Web_free(DilloWeb *web)
{ {
if (!web) return; if (!web) return;
a_Image_unref(web->Image);
dList_remove(ValidWebs, (void *)web); dList_remove(ValidWebs, (void *)web);
_MSG("a_Web_free: ValidWebs=%d\n", dList_length(ValidWebs)); _MSG("a_Web_free: ValidWebs=%d\n", dList_length(ValidWebs));
delete web; delete web;

View File

@ -26,7 +26,7 @@ struct DilloWeb {
BrowserWindow *bw; /**< The requesting browser window [reference] */ BrowserWindow *bw; /**< The requesting browser window [reference] */
int flags; /**< Additional info */ int flags; /**< Additional info */
DilloImage *Image; /**< For image urls [reference] */ std::shared_ptr< DilloImage > Image; /**< For image urls */
int32_t bgColor; /**< for image backgrounds */ int32_t bgColor; /**< for image backgrounds */
std::optional< std::string > filename; /**< Variables for Local saving */ std::optional< std::string > filename; /**< Variables for Local saving */