@@ -454,7 +454,7 @@ Project::Item Project::Item::createGroup (Project& project, const String& name, | |||
bool Project::Item::isFile() const { return state.hasType (Tags::file); } | |||
bool Project::Item::isGroup() const { return state.hasType (Tags::group) || isMainGroup(); } | |||
bool Project::Item::isMainGroup() const { return state.hasType (Tags::projectMainGroup); } | |||
bool Project::Item::isImageFile() const { return isFile() && getFile().hasFileExtension ("png;jpg;jpeg;gif;drawable"); } | |||
bool Project::Item::isImageFile() const { return isFile() && ImageFileFormat::findImageFormatForFileExtension (getFile()) != nullptr; } | |||
Project::Item Project::Item::findItemWithID (const String& targetId) const | |||
{ | |||
@@ -415,7 +415,8 @@ private: | |||
GIFImageFormat::GIFImageFormat() {} | |||
GIFImageFormat::~GIFImageFormat() {} | |||
String GIFImageFormat::getFormatName() { return "GIF"; } | |||
String GIFImageFormat::getFormatName() { return "GIF"; } | |||
bool GIFImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("gif"); } | |||
bool GIFImageFormat::canUnderstand (InputStream& in) | |||
{ | |||
@@ -210,7 +210,8 @@ void JPEGImageFormat::setQuality (const float newQuality) | |||
quality = newQuality; | |||
} | |||
String JPEGImageFormat::getFormatName() { return "JPEG"; } | |||
String JPEGImageFormat::getFormatName() { return "JPEG"; } | |||
bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("jpeg;jpg"); } | |||
bool JPEGImageFormat::canUnderstand (InputStream& in) | |||
{ | |||
@@ -124,7 +124,8 @@ namespace PNGHelpers | |||
PNGImageFormat::PNGImageFormat() {} | |||
PNGImageFormat::~PNGImageFormat() {} | |||
String PNGImageFormat::getFormatName() { return "PNG"; } | |||
String PNGImageFormat::getFormatName() { return "PNG"; } | |||
bool PNGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("png"); } | |||
bool PNGImageFormat::canUnderstand (InputStream& in) | |||
{ | |||
@@ -23,35 +23,55 @@ | |||
============================================================================== | |||
*/ | |||
ImageFileFormat* ImageFileFormat::findImageFormatForStream (InputStream& input) | |||
struct DefaultImageFormats | |||
{ | |||
struct DefaultImageFormats | |||
static ImageFileFormat** get() | |||
{ | |||
static DefaultImageFormats formats; | |||
return formats.formats; | |||
} | |||
private: | |||
DefaultImageFormats() noexcept | |||
{ | |||
PNGImageFormat png; | |||
JPEGImageFormat jpg; | |||
GIFImageFormat gif; | |||
}; | |||
formats[0] = &png; | |||
formats[1] = &jpg; | |||
formats[2] = &gif; | |||
formats[3] = nullptr; | |||
} | |||
static DefaultImageFormats defaultImageFormats; | |||
PNGImageFormat png; | |||
JPEGImageFormat jpg; | |||
GIFImageFormat gif; | |||
ImageFileFormat* formats[] = { &defaultImageFormats.png, | |||
&defaultImageFormats.jpg, | |||
&defaultImageFormats.gif }; | |||
ImageFileFormat* formats[4]; | |||
}; | |||
ImageFileFormat* ImageFileFormat::findImageFormatForStream (InputStream& input) | |||
{ | |||
const int64 streamPos = input.getPosition(); | |||
for (int i = 0; i < numElementsInArray (formats); ++i) | |||
for (ImageFileFormat** i = DefaultImageFormats::get(); *i != nullptr; ++i) | |||
{ | |||
const bool found = formats[i]->canUnderstand (input); | |||
const bool found = (*i)->canUnderstand (input); | |||
input.setPosition (streamPos); | |||
if (found) | |||
return formats[i]; | |||
return *i; | |||
} | |||
return nullptr; | |||
} | |||
ImageFileFormat* ImageFileFormat::findImageFormatForFileExtension (const File& file) | |||
{ | |||
for (ImageFileFormat** i = DefaultImageFormats::get(); *i != nullptr; ++i) | |||
if ((*i)->usesFileExtension (file)) | |||
return *i; | |||
return nullptr; | |||
} | |||
//============================================================================== | |||
Image ImageFileFormat::loadFrom (InputStream& input) | |||
{ | |||
@@ -57,8 +57,7 @@ public: | |||
*/ | |||
virtual String getFormatName() = 0; | |||
/** Returns true if the given stream seems to contain data that this format | |||
understands. | |||
/** Returns true if the given stream seems to contain data that this format understands. | |||
The format class should only read the first few bytes of the stream and sniff | |||
for header bytes that it understands. | |||
@@ -67,6 +66,9 @@ public: | |||
*/ | |||
virtual bool canUnderstand (InputStream& input) = 0; | |||
/** Returns true if this format uses the file extension of the given file. */ | |||
virtual bool usesFileExtension (const File& possibleFile) = 0; | |||
/** Tries to decode and return an image from the given stream. | |||
This will be called for an image format after calling its canUnderStand() method | |||
@@ -92,16 +94,19 @@ public: | |||
OutputStream& destStream) = 0; | |||
//============================================================================== | |||
/** Tries the built-in decoders to see if it can find one to read this stream. | |||
/** Tries the built-in formats to see if it can find one to read this stream. | |||
There are currently built-in decoders for PNG, JPEG and GIF formats. | |||
The object that is returned should not be deleted by the caller. | |||
@see canUnderstand, decodeImage, loadFrom | |||
*/ | |||
static ImageFileFormat* findImageFormatForStream (InputStream& input); | |||
/** Looks for a format that can handle the given file extension. | |||
There are currently built-in formats for PNG, JPEG and GIF formats. | |||
The object that is returned should not be deleted by the caller. | |||
*/ | |||
static ImageFileFormat* findImageFormatForFileExtension (const File& file); | |||
//============================================================================== | |||
/** Tries to load an image from a stream. | |||
@@ -130,7 +135,6 @@ public: | |||
*/ | |||
static Image loadFrom (const void* rawData, | |||
size_t numBytesOfData); | |||
}; | |||
//============================================================================== | |||
@@ -148,6 +152,7 @@ public: | |||
//============================================================================== | |||
String getFormatName(); | |||
bool usesFileExtension (const File& possibleFile); | |||
bool canUnderstand (InputStream& input); | |||
Image decodeImage (InputStream& input); | |||
bool writeImageToStream (const Image& sourceImage, OutputStream& destStream); | |||
@@ -177,6 +182,7 @@ public: | |||
//============================================================================== | |||
String getFormatName(); | |||
bool usesFileExtension (const File& possibleFile); | |||
bool canUnderstand (InputStream& input); | |||
Image decodeImage (InputStream& input); | |||
bool writeImageToStream (const Image& sourceImage, OutputStream& destStream); | |||
@@ -200,6 +206,7 @@ public: | |||
//============================================================================== | |||
String getFormatName(); | |||
bool usesFileExtension (const File& possibleFile); | |||
bool canUnderstand (InputStream& input); | |||
Image decodeImage (InputStream& input); | |||
bool writeImageToStream (const Image& sourceImage, OutputStream& destStream); | |||