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) {
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 );

View File

@ -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 ();

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 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

View File

@ -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);

View File

@ -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
*/

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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 */