ImageType::create() should return ReferenceCountedObject


#1

Prototype should appear as below, or else custom implementations of create() have to do backflips to maintain reference counts:

juce_Image.cpp

virtual ReferenceCountedObjectPtr <ImagePixelData> ImageType::create (...

#2

I don’t understand why you’d have a problem with that? Any sensible code should work just fine, e.g.

Image im (type->create (...)); ReferenceCountedObjectPtr <ImagePixelData> data (type->create (..));


#3

If you write your own ImageType and try to construct a temporary Image from the ImagePixelData in order to do some manipulations before returning it, then the ImagePixelData will get freed unless you manually manage the reference counts:

ImagePixelData* MyImageType::create (...)
{
  ImagePixelData* myData = new MyImagePixelData (...);
  Image temp (myData);
  return myData; // crash, myData has been freed
}

Now if you try to use ReferenceCountedObjectPtr as a local, you still crash:

ImagePixelData* MyImageType::create (...)
{
  ReferenceCountedObjectPtr <ImagePixelData> myData = new MyImagePixelData (...);
  Image temp (myData);
  return myData; // caller will crash, myData has been freed
}

The only current solution is manual management of reference count:

ImagePixelData* MyImageType::create (...)
{
  ReferenceCountedObjectPtr <ImagePixelData> myData = new MyImagePixelData (...);
  Image temp (myData);
  myData->incReferenceCount (); // for the caller
  return myData; // okay
}

Or, if we just change the return type nothing else should break and we don’t need manual reference count management:

ReferenceCountedObjectPtr <ImagePixelData> MyImageType::create (...)
{
  ReferenceCountedObjectPtr <ImagePixelData> myData = new MyImagePixelData (...);
  Image temp (myData);
  return myData; // good
}

You yourself point out that raw pointers are best avoided…the pointer return of ImageType::create() is a legacy holdover that should be fixed (and it shouldn’t break anything either since the callers use ReferenceCountedObjectPtr anyway).

This comes up because I have implemented a custom image type that presents individual channels of an existing ARGB Image, as a SingleChannel image pointing to the same data, to make compositing operations and manipulating masks easier.


#4

Ah, I see. Ok, fair point, I’ll update that.