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