ImageCache bug?


#1

I am using the same logo image in my main GUI and in the about box within ImageButtons. When I close the about box (deleting all its children including ImageButton), after a second the ImageButton in the main GUI stops responding and if the Window is covered then on repaint the image button is gone. I suspect there is some bug in the ImageCache image deletion code.

My code for both image buttons looks like this (copied from Juce demo…):

Image* logoImage = ImageCache::getFromMemory(ACLogoData::aclogo_png, ACLogoData::aclogo_pngSize);
logoButton->setImages (true, true, true,
logoImage, 0.7f, Colours::transparentBlack,
logoImage, 1.0f, Colours::transparentBlack,
logoImage, 0.0f, Colours::pink,
0.5f);

I suspect that the bug might be around here:

void ImageCache::release (Image* const imageToRelease)
{
if (imageToRelease != 0 && instance != 0)
{
for (int i = instance->images.size(); --i >= 0;)
{
CachedImageInfo* const ci = (CachedImageInfo*)(instance->images.getUnchecked(i));

        if (ci->image == imageToRelease)
        {
            if (atomicDecrementAndReturn (ci->refCount) <= 0)
                ci->releaseTime = Time::getApproximateMillisecondCounter();

            if (! instance->isTimerRunning())
                instance->startTimer (999);

            break;
        }
    }
}

}

I don’t understand why the timer is started (with 999) even when reference count is not bellow 0 but I don’t realy understand this code

thanks


#2

ok, I’ll take a look. (The timer starting is correct though)


#3

Ok, problem found. I looked at Juce code and I saw that the images are not reference counted in their user (image button) but in the cache, so I can’t use the same image for the 3 images in the image button since the image will then be deleted (released) 3 times…I have to load the image 3 times from the cache and use it as 3 different images.

So the correct and working code is now:

Image* normalImage = ImageCache::getFromMemory(ACLogoData::aclogo_png, ACLogoData::aclogo_pngSize);
Image* overImage = ImageCache::getFromMemory(ACLogoData::aclogo_png, ACLogoData::aclogo_pngSize);
Image* downImage = ImageCache::getFromMemory(ACLogoData::aclogo_png, ACLogoData::aclogo_pngSize);
logoButton->setImages (true, true, true,
						normalImage, 0.7f, Colours::transparentBlack,
						overImage, 1.0f, Colours::transparentBlack,
						downImage, 0.0f, Colours::pink,
						0.5f);

#4