migrating to the latest JUCE version

This commit is contained in:
2022-11-04 23:11:33 +01:00
committed by Nikolai Rodionov
parent 4257a0f8ba
commit faf8f18333
2796 changed files with 888518 additions and 784244 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,169 +1,169 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
struct ImageCache::Pimpl : private Timer,
private DeletedAtShutdown
{
Pimpl() {}
~Pimpl() override { clearSingletonInstance(); }
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (ImageCache::Pimpl)
Image getFromHashCode (const int64 hashCode) noexcept
{
const ScopedLock sl (lock);
for (auto& item : images)
{
if (item.hashCode == hashCode)
{
item.lastUseTime = Time::getApproximateMillisecondCounter();
return item.image;
}
}
return {};
}
void addImageToCache (const Image& image, const int64 hashCode)
{
if (image.isValid())
{
if (! isTimerRunning())
startTimer (2000);
const ScopedLock sl (lock);
images.add ({ image, hashCode, Time::getApproximateMillisecondCounter() });
}
}
void timerCallback() override
{
auto now = Time::getApproximateMillisecondCounter();
const ScopedLock sl (lock);
for (int i = images.size(); --i >= 0;)
{
auto& item = images.getReference(i);
if (item.image.getReferenceCount() <= 1)
{
if (now > item.lastUseTime + cacheTimeout || now < item.lastUseTime - 1000)
images.remove (i);
}
else
{
item.lastUseTime = now; // multiply-referenced, so this image is still in use.
}
}
if (images.isEmpty())
stopTimer();
}
void releaseUnusedImages()
{
const ScopedLock sl (lock);
for (int i = images.size(); --i >= 0;)
if (images.getReference(i).image.getReferenceCount() <= 1)
images.remove (i);
}
struct Item
{
Image image;
int64 hashCode;
uint32 lastUseTime;
};
Array<Item> images;
CriticalSection lock;
unsigned int cacheTimeout = 5000;
JUCE_DECLARE_NON_COPYABLE (Pimpl)
};
JUCE_IMPLEMENT_SINGLETON (ImageCache::Pimpl)
//==============================================================================
Image ImageCache::getFromHashCode (const int64 hashCode)
{
if (Pimpl::getInstanceWithoutCreating() != nullptr)
return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode);
return {};
}
void ImageCache::addImageToCache (const Image& image, const int64 hashCode)
{
Pimpl::getInstance()->addImageToCache (image, hashCode);
}
Image ImageCache::getFromFile (const File& file)
{
auto hashCode = file.hashCode64();
auto image = getFromHashCode (hashCode);
if (image.isNull())
{
image = ImageFileFormat::loadFrom (file);
addImageToCache (image, hashCode);
}
return image;
}
Image ImageCache::getFromMemory (const void* imageData, const int dataSize)
{
auto hashCode = (int64) (pointer_sized_int) imageData;
auto image = getFromHashCode (hashCode);
if (image.isNull())
{
image = ImageFileFormat::loadFrom (imageData, (size_t) dataSize);
addImageToCache (image, hashCode);
}
return image;
}
void ImageCache::setCacheTimeout (const int millisecs)
{
jassert (millisecs >= 0);
Pimpl::getInstance()->cacheTimeout = (unsigned int) millisecs;
}
void ImageCache::releaseUnusedImages()
{
Pimpl::getInstance()->releaseUnusedImages();
}
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
struct ImageCache::Pimpl : private Timer,
private DeletedAtShutdown
{
Pimpl() = default;
~Pimpl() override { clearSingletonInstance(); }
JUCE_DECLARE_SINGLETON (ImageCache::Pimpl, false)
Image getFromHashCode (const int64 hashCode) noexcept
{
const ScopedLock sl (lock);
for (auto& item : images)
{
if (item.hashCode == hashCode)
{
item.lastUseTime = Time::getApproximateMillisecondCounter();
return item.image;
}
}
return {};
}
void addImageToCache (const Image& image, const int64 hashCode)
{
if (image.isValid())
{
if (! isTimerRunning())
startTimer (2000);
const ScopedLock sl (lock);
images.add ({ image, hashCode, Time::getApproximateMillisecondCounter() });
}
}
void timerCallback() override
{
auto now = Time::getApproximateMillisecondCounter();
const ScopedLock sl (lock);
for (int i = images.size(); --i >= 0;)
{
auto& item = images.getReference(i);
if (item.image.getReferenceCount() <= 1)
{
if (now > item.lastUseTime + cacheTimeout || now < item.lastUseTime - 1000)
images.remove (i);
}
else
{
item.lastUseTime = now; // multiply-referenced, so this image is still in use.
}
}
if (images.isEmpty())
stopTimer();
}
void releaseUnusedImages()
{
const ScopedLock sl (lock);
for (int i = images.size(); --i >= 0;)
if (images.getReference(i).image.getReferenceCount() <= 1)
images.remove (i);
}
struct Item
{
Image image;
int64 hashCode;
uint32 lastUseTime;
};
Array<Item> images;
CriticalSection lock;
unsigned int cacheTimeout = 5000;
JUCE_DECLARE_NON_COPYABLE (Pimpl)
};
JUCE_IMPLEMENT_SINGLETON (ImageCache::Pimpl)
//==============================================================================
Image ImageCache::getFromHashCode (const int64 hashCode)
{
if (Pimpl::getInstanceWithoutCreating() != nullptr)
return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode);
return {};
}
void ImageCache::addImageToCache (const Image& image, const int64 hashCode)
{
Pimpl::getInstance()->addImageToCache (image, hashCode);
}
Image ImageCache::getFromFile (const File& file)
{
auto hashCode = file.hashCode64();
auto image = getFromHashCode (hashCode);
if (image.isNull())
{
image = ImageFileFormat::loadFrom (file);
addImageToCache (image, hashCode);
}
return image;
}
Image ImageCache::getFromMemory (const void* imageData, const int dataSize)
{
auto hashCode = (int64) (pointer_sized_int) imageData;
auto image = getFromHashCode (hashCode);
if (image.isNull())
{
image = ImageFileFormat::loadFrom (imageData, (size_t) dataSize);
addImageToCache (image, hashCode);
}
return image;
}
void ImageCache::setCacheTimeout (const int millisecs)
{
jassert (millisecs >= 0);
Pimpl::getInstance()->cacheTimeout = (unsigned int) millisecs;
}
void ImageCache::releaseUnusedImages()
{
Pimpl::getInstance()->releaseUnusedImages();
}
} // namespace juce

View File

@ -1,127 +1,127 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
A global cache of images that have been loaded from files or memory.
If you're loading an image and may need to use the image in more than one
place, this is used to allow the same image to be shared rather than loading
multiple copies into memory.
Another advantage is that after images are released, they will be kept in
memory for a few seconds before it is actually deleted, so if you're repeatedly
loading/deleting the same image, it'll reduce the chances of having to reload it
each time.
@see Image, ImageFileFormat
@tags{Graphics}
*/
class JUCE_API ImageCache
{
public:
//==============================================================================
/** Loads an image from a file, (or just returns the image if it's already cached).
If the cache already contains an image that was loaded from this file,
that image will be returned. Otherwise, this method will try to load the
file, add it to the cache, and return it.
Remember that the image returned is shared, so drawing into it might
affect other things that are using it! If you want to draw on it, first
call Image::duplicateIfShared()
@param file the file to try to load
@returns the image, or null if it there was an error loading it
@see getFromMemory, getFromCache, ImageFileFormat::loadFrom
*/
static Image getFromFile (const File& file);
/** Loads an image from an in-memory image file, (or just returns the image if it's already cached).
If the cache already contains an image that was loaded from this block of memory,
that image will be returned. Otherwise, this method will try to load the
file, add it to the cache, and return it.
Remember that the image returned is shared, so drawing into it might
affect other things that are using it! If you want to draw on it, first
call Image::duplicateIfShared()
@param imageData the block of memory containing the image data
@param dataSize the data size in bytes
@returns the image, or an invalid image if it there was an error loading it
@see getFromMemory, getFromCache, ImageFileFormat::loadFrom
*/
static Image getFromMemory (const void* imageData, int dataSize);
//==============================================================================
/** Checks the cache for an image with a particular hashcode.
If there's an image in the cache with this hashcode, it will be returned,
otherwise it will return an invalid image.
@param hashCode the hash code that was associated with the image by addImageToCache()
@see addImageToCache
*/
static Image getFromHashCode (int64 hashCode);
/** Adds an image to the cache with a user-defined hash-code.
The image passed-in will be referenced (not copied) by the cache, so it's probably
a good idea not to draw into it after adding it, otherwise this will affect all
instances of it that may be in use.
@param image the image to add
@param hashCode the hash-code to associate with it
@see getFromHashCode
*/
static void addImageToCache (const Image& image, int64 hashCode);
/** Changes the amount of time before an unused image will be removed from the cache.
By default this is about 5 seconds.
*/
static void setCacheTimeout (int millisecs);
/** Releases any images in the cache that aren't being referenced by active
Image objects.
*/
static void releaseUnusedImages();
private:
//==============================================================================
struct Pimpl;
friend struct Pimpl;
ImageCache();
~ImageCache();
JUCE_DECLARE_NON_COPYABLE (ImageCache)
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
A global cache of images that have been loaded from files or memory.
If you're loading an image and may need to use the image in more than one
place, this is used to allow the same image to be shared rather than loading
multiple copies into memory.
Another advantage is that after images are released, they will be kept in
memory for a few seconds before it is actually deleted, so if you're repeatedly
loading/deleting the same image, it'll reduce the chances of having to reload it
each time.
@see Image, ImageFileFormat
@tags{Graphics}
*/
class JUCE_API ImageCache
{
public:
//==============================================================================
/** Loads an image from a file, (or just returns the image if it's already cached).
If the cache already contains an image that was loaded from this file,
that image will be returned. Otherwise, this method will try to load the
file, add it to the cache, and return it.
Remember that the image returned is shared, so drawing into it might
affect other things that are using it! If you want to draw on it, first
call Image::duplicateIfShared()
@param file the file to try to load
@returns the image, or null if it there was an error loading it
@see getFromMemory, getFromCache, ImageFileFormat::loadFrom
*/
static Image getFromFile (const File& file);
/** Loads an image from an in-memory image file, (or just returns the image if it's already cached).
If the cache already contains an image that was loaded from this block of memory,
that image will be returned. Otherwise, this method will try to load the
file, add it to the cache, and return it.
Remember that the image returned is shared, so drawing into it might
affect other things that are using it! If you want to draw on it, first
call Image::duplicateIfShared()
@param imageData the block of memory containing the image data
@param dataSize the data size in bytes
@returns the image, or an invalid image if it there was an error loading it
@see getFromMemory, getFromCache, ImageFileFormat::loadFrom
*/
static Image getFromMemory (const void* imageData, int dataSize);
//==============================================================================
/** Checks the cache for an image with a particular hashcode.
If there's an image in the cache with this hashcode, it will be returned,
otherwise it will return an invalid image.
@param hashCode the hash code that was associated with the image by addImageToCache()
@see addImageToCache
*/
static Image getFromHashCode (int64 hashCode);
/** Adds an image to the cache with a user-defined hash-code.
The image passed-in will be referenced (not copied) by the cache, so it's probably
a good idea not to draw into it after adding it, otherwise this will affect all
instances of it that may be in use.
@param image the image to add
@param hashCode the hash-code to associate with it
@see getFromHashCode
*/
static void addImageToCache (const Image& image, int64 hashCode);
/** Changes the amount of time before an unused image will be removed from the cache.
By default this is about 5 seconds.
*/
static void setCacheTimeout (int millisecs);
/** Releases any images in the cache that aren't being referenced by active
Image objects.
*/
static void releaseUnusedImages();
private:
//==============================================================================
struct Pimpl;
friend struct Pimpl;
ImageCache();
~ImageCache();
JUCE_DECLARE_NON_COPYABLE (ImageCache)
};
} // namespace juce

View File

@ -1,296 +1,296 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
ImageConvolutionKernel::ImageConvolutionKernel (int sizeToUse)
: values ((size_t) (sizeToUse * sizeToUse)),
size (sizeToUse)
{
clear();
}
ImageConvolutionKernel::~ImageConvolutionKernel()
{
}
//==============================================================================
float ImageConvolutionKernel::getKernelValue (const int x, const int y) const noexcept
{
if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size))
return values [x + y * size];
jassertfalse;
return 0;
}
void ImageConvolutionKernel::setKernelValue (const int x, const int y, const float value) noexcept
{
if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size))
{
values [x + y * size] = value;
}
else
{
jassertfalse;
}
}
void ImageConvolutionKernel::clear()
{
for (int i = size * size; --i >= 0;)
values[i] = 0;
}
void ImageConvolutionKernel::setOverallSum (const float desiredTotalSum)
{
double currentTotal = 0.0;
for (int i = size * size; --i >= 0;)
currentTotal += values[i];
rescaleAllValues ((float) (desiredTotalSum / currentTotal));
}
void ImageConvolutionKernel::rescaleAllValues (const float multiplier)
{
for (int i = size * size; --i >= 0;)
values[i] *= multiplier;
}
//==============================================================================
void ImageConvolutionKernel::createGaussianBlur (const float radius)
{
const double radiusFactor = -1.0 / (radius * radius * 2);
const int centre = size >> 1;
for (int y = size; --y >= 0;)
{
for (int x = size; --x >= 0;)
{
auto cx = x - centre;
auto cy = y - centre;
values [x + y * size] = (float) std::exp (radiusFactor * (cx * cx + cy * cy));
}
}
setOverallSum (1.0f);
}
//==============================================================================
void ImageConvolutionKernel::applyToImage (Image& destImage,
const Image& sourceImage,
const Rectangle<int>& destinationArea) const
{
if (sourceImage == destImage)
{
destImage.duplicateIfShared();
}
else
{
if (sourceImage.getWidth() != destImage.getWidth()
|| sourceImage.getHeight() != destImage.getHeight()
|| sourceImage.getFormat() != destImage.getFormat())
{
jassertfalse;
return;
}
}
auto area = destinationArea.getIntersection (destImage.getBounds());
if (area.isEmpty())
return;
auto right = area.getRight();
auto bottom = area.getBottom();
const Image::BitmapData destData (destImage, area.getX(), area.getY(), area.getWidth(), area.getHeight(),
Image::BitmapData::writeOnly);
uint8* line = destData.data;
const Image::BitmapData srcData (sourceImage, Image::BitmapData::readOnly);
if (destData.pixelStride == 4)
{
for (int y = area.getY(); y < bottom; ++y)
{
uint8* dest = line;
line += destData.lineStride;
for (int x = area.getX(); x < right; ++x)
{
float c1 = 0;
float c2 = 0;
float c3 = 0;
float c4 = 0;
for (int yy = 0; yy < size; ++yy)
{
const int sy = y + yy - (size >> 1);
if (sy >= srcData.height)
break;
if (sy >= 0)
{
int sx = x - (size >> 1);
const uint8* src = srcData.getPixelPointer (sx, sy);
for (int xx = 0; xx < size; ++xx)
{
if (sx >= srcData.width)
break;
if (sx >= 0)
{
const float kernelMult = values [xx + yy * size];
c1 += kernelMult * *src++;
c2 += kernelMult * *src++;
c3 += kernelMult * *src++;
c4 += kernelMult * *src++;
}
else
{
src += 4;
}
++sx;
}
}
}
*dest++ = (uint8) jmin (0xff, roundToInt (c1));
*dest++ = (uint8) jmin (0xff, roundToInt (c2));
*dest++ = (uint8) jmin (0xff, roundToInt (c3));
*dest++ = (uint8) jmin (0xff, roundToInt (c4));
}
}
}
else if (destData.pixelStride == 3)
{
for (int y = area.getY(); y < bottom; ++y)
{
uint8* dest = line;
line += destData.lineStride;
for (int x = area.getX(); x < right; ++x)
{
float c1 = 0;
float c2 = 0;
float c3 = 0;
for (int yy = 0; yy < size; ++yy)
{
const int sy = y + yy - (size >> 1);
if (sy >= srcData.height)
break;
if (sy >= 0)
{
int sx = x - (size >> 1);
const uint8* src = srcData.getPixelPointer (sx, sy);
for (int xx = 0; xx < size; ++xx)
{
if (sx >= srcData.width)
break;
if (sx >= 0)
{
const float kernelMult = values [xx + yy * size];
c1 += kernelMult * *src++;
c2 += kernelMult * *src++;
c3 += kernelMult * *src++;
}
else
{
src += 3;
}
++sx;
}
}
}
*dest++ = (uint8) roundToInt (c1);
*dest++ = (uint8) roundToInt (c2);
*dest++ = (uint8) roundToInt (c3);
}
}
}
else if (destData.pixelStride == 1)
{
for (int y = area.getY(); y < bottom; ++y)
{
uint8* dest = line;
line += destData.lineStride;
for (int x = area.getX(); x < right; ++x)
{
float c1 = 0;
for (int yy = 0; yy < size; ++yy)
{
const int sy = y + yy - (size >> 1);
if (sy >= srcData.height)
break;
if (sy >= 0)
{
int sx = x - (size >> 1);
const uint8* src = srcData.getPixelPointer (sx, sy);
for (int xx = 0; xx < size; ++xx)
{
if (sx >= srcData.width)
break;
if (sx >= 0)
{
const float kernelMult = values [xx + yy * size];
c1 += kernelMult * *src++;
}
else
{
src += 3;
}
++sx;
}
}
}
*dest++ = (uint8) roundToInt (c1);
}
}
}
}
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
ImageConvolutionKernel::ImageConvolutionKernel (int sizeToUse)
: values ((size_t) (sizeToUse * sizeToUse)),
size (sizeToUse)
{
clear();
}
ImageConvolutionKernel::~ImageConvolutionKernel()
{
}
//==============================================================================
float ImageConvolutionKernel::getKernelValue (const int x, const int y) const noexcept
{
if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size))
return values [x + y * size];
jassertfalse;
return 0;
}
void ImageConvolutionKernel::setKernelValue (const int x, const int y, const float value) noexcept
{
if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size))
{
values [x + y * size] = value;
}
else
{
jassertfalse;
}
}
void ImageConvolutionKernel::clear()
{
for (int i = size * size; --i >= 0;)
values[i] = 0;
}
void ImageConvolutionKernel::setOverallSum (const float desiredTotalSum)
{
double currentTotal = 0.0;
for (int i = size * size; --i >= 0;)
currentTotal += values[i];
rescaleAllValues ((float) (desiredTotalSum / currentTotal));
}
void ImageConvolutionKernel::rescaleAllValues (const float multiplier)
{
for (int i = size * size; --i >= 0;)
values[i] *= multiplier;
}
//==============================================================================
void ImageConvolutionKernel::createGaussianBlur (const float radius)
{
const double radiusFactor = -1.0 / (radius * radius * 2);
const int centre = size >> 1;
for (int y = size; --y >= 0;)
{
for (int x = size; --x >= 0;)
{
auto cx = x - centre;
auto cy = y - centre;
values [x + y * size] = (float) std::exp (radiusFactor * (cx * cx + cy * cy));
}
}
setOverallSum (1.0f);
}
//==============================================================================
void ImageConvolutionKernel::applyToImage (Image& destImage,
const Image& sourceImage,
const Rectangle<int>& destinationArea) const
{
if (sourceImage == destImage)
{
destImage.duplicateIfShared();
}
else
{
if (sourceImage.getWidth() != destImage.getWidth()
|| sourceImage.getHeight() != destImage.getHeight()
|| sourceImage.getFormat() != destImage.getFormat())
{
jassertfalse;
return;
}
}
auto area = destinationArea.getIntersection (destImage.getBounds());
if (area.isEmpty())
return;
auto right = area.getRight();
auto bottom = area.getBottom();
const Image::BitmapData destData (destImage, area.getX(), area.getY(), area.getWidth(), area.getHeight(),
Image::BitmapData::writeOnly);
uint8* line = destData.data;
const Image::BitmapData srcData (sourceImage, Image::BitmapData::readOnly);
if (destData.pixelStride == 4)
{
for (int y = area.getY(); y < bottom; ++y)
{
uint8* dest = line;
line += destData.lineStride;
for (int x = area.getX(); x < right; ++x)
{
float c1 = 0;
float c2 = 0;
float c3 = 0;
float c4 = 0;
for (int yy = 0; yy < size; ++yy)
{
const int sy = y + yy - (size >> 1);
if (sy >= srcData.height)
break;
if (sy >= 0)
{
int sx = x - (size >> 1);
const uint8* src = srcData.getPixelPointer (sx, sy);
for (int xx = 0; xx < size; ++xx)
{
if (sx >= srcData.width)
break;
if (sx >= 0)
{
const float kernelMult = values [xx + yy * size];
c1 += kernelMult * *src++;
c2 += kernelMult * *src++;
c3 += kernelMult * *src++;
c4 += kernelMult * *src++;
}
else
{
src += 4;
}
++sx;
}
}
}
*dest++ = (uint8) jmin (0xff, roundToInt (c1));
*dest++ = (uint8) jmin (0xff, roundToInt (c2));
*dest++ = (uint8) jmin (0xff, roundToInt (c3));
*dest++ = (uint8) jmin (0xff, roundToInt (c4));
}
}
}
else if (destData.pixelStride == 3)
{
for (int y = area.getY(); y < bottom; ++y)
{
uint8* dest = line;
line += destData.lineStride;
for (int x = area.getX(); x < right; ++x)
{
float c1 = 0;
float c2 = 0;
float c3 = 0;
for (int yy = 0; yy < size; ++yy)
{
const int sy = y + yy - (size >> 1);
if (sy >= srcData.height)
break;
if (sy >= 0)
{
int sx = x - (size >> 1);
const uint8* src = srcData.getPixelPointer (sx, sy);
for (int xx = 0; xx < size; ++xx)
{
if (sx >= srcData.width)
break;
if (sx >= 0)
{
const float kernelMult = values [xx + yy * size];
c1 += kernelMult * *src++;
c2 += kernelMult * *src++;
c3 += kernelMult * *src++;
}
else
{
src += 3;
}
++sx;
}
}
}
*dest++ = (uint8) roundToInt (c1);
*dest++ = (uint8) roundToInt (c2);
*dest++ = (uint8) roundToInt (c3);
}
}
}
else if (destData.pixelStride == 1)
{
for (int y = area.getY(); y < bottom; ++y)
{
uint8* dest = line;
line += destData.lineStride;
for (int x = area.getX(); x < right; ++x)
{
float c1 = 0;
for (int yy = 0; yy < size; ++yy)
{
const int sy = y + yy - (size >> 1);
if (sy >= srcData.height)
break;
if (sy >= 0)
{
int sx = x - (size >> 1);
const uint8* src = srcData.getPixelPointer (sx, sy);
for (int xx = 0; xx < size; ++xx)
{
if (sx >= srcData.width)
break;
if (sx >= 0)
{
const float kernelMult = values [xx + yy * size];
c1 += kernelMult * *src++;
}
else
{
src += 3;
}
++sx;
}
}
}
*dest++ = (uint8) roundToInt (c1);
}
}
}
}
} // namespace juce

View File

@ -1,112 +1,112 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
Represents a filter kernel to use in convoluting an image.
@see Image::applyConvolution
@tags{Graphics}
*/
class JUCE_API ImageConvolutionKernel
{
public:
//==============================================================================
/** Creates an empty convolution kernel.
@param size the length of each dimension of the kernel, so e.g. if the size
is 5, it will create a 5x5 kernel
*/
ImageConvolutionKernel (int size);
/** Destructor. */
~ImageConvolutionKernel();
//==============================================================================
/** Resets all values in the kernel to zero. */
void clear();
/** Returns one of the kernel values. */
float getKernelValue (int x, int y) const noexcept;
/** Sets the value of a specific cell in the kernel.
The x and y parameters must be in the range 0 < x < getKernelSize().
@see setOverallSum
*/
void setKernelValue (int x, int y, float value) noexcept;
/** Rescales all values in the kernel to make the total add up to a fixed value.
This will multiply all values in the kernel by (desiredTotalSum / currentTotalSum).
*/
void setOverallSum (float desiredTotalSum);
/** Multiplies all values in the kernel by a value. */
void rescaleAllValues (float multiplier);
/** Initialises the kernel for a gaussian blur.
@param blurRadius this may be larger or smaller than the kernel's actual
size but this will obviously be wasteful or clip at the
edges. Ideally the kernel should be just larger than
(blurRadius * 2).
*/
void createGaussianBlur (float blurRadius);
//==============================================================================
/** Returns the size of the kernel.
E.g. if it's a 3x3 kernel, this returns 3.
*/
int getKernelSize() const { return size; }
//==============================================================================
/** Applies the kernel to an image.
@param destImage the image that will receive the resultant convoluted pixels.
@param sourceImage the source image to read from - this can be the same image as
the destination, but if different, it must be exactly the same
size and format.
@param destinationArea the region of the image to apply the filter to
*/
void applyToImage (Image& destImage,
const Image& sourceImage,
const Rectangle<int>& destinationArea) const;
private:
//==============================================================================
HeapBlock<float> values;
const int size;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageConvolutionKernel)
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
Represents a filter kernel to use in convoluting an image.
@see Image::applyConvolution
@tags{Graphics}
*/
class JUCE_API ImageConvolutionKernel
{
public:
//==============================================================================
/** Creates an empty convolution kernel.
@param size the length of each dimension of the kernel, so e.g. if the size
is 5, it will create a 5x5 kernel
*/
ImageConvolutionKernel (int size);
/** Destructor. */
~ImageConvolutionKernel();
//==============================================================================
/** Resets all values in the kernel to zero. */
void clear();
/** Returns one of the kernel values. */
float getKernelValue (int x, int y) const noexcept;
/** Sets the value of a specific cell in the kernel.
The x and y parameters must be in the range 0 < x < getKernelSize().
@see setOverallSum
*/
void setKernelValue (int x, int y, float value) noexcept;
/** Rescales all values in the kernel to make the total add up to a fixed value.
This will multiply all values in the kernel by (desiredTotalSum / currentTotalSum).
*/
void setOverallSum (float desiredTotalSum);
/** Multiplies all values in the kernel by a value. */
void rescaleAllValues (float multiplier);
/** Initialises the kernel for a gaussian blur.
@param blurRadius this may be larger or smaller than the kernel's actual
size but this will obviously be wasteful or clip at the
edges. Ideally the kernel should be just larger than
(blurRadius * 2).
*/
void createGaussianBlur (float blurRadius);
//==============================================================================
/** Returns the size of the kernel.
E.g. if it's a 3x3 kernel, this returns 3.
*/
int getKernelSize() const { return size; }
//==============================================================================
/** Applies the kernel to an image.
@param destImage the image that will receive the resultant convoluted pixels.
@param sourceImage the source image to read from - this can be the same image as
the destination, but if different, it must be exactly the same
size and format.
@param destinationArea the region of the image to apply the filter to
*/
void applyToImage (Image& destImage,
const Image& sourceImage,
const Rectangle<int>& destinationArea) const;
private:
//==============================================================================
HeapBlock<float> values;
const int size;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageConvolutionKernel)
};
} // namespace juce

View File

@ -1,111 +1,111 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
struct DefaultImageFormats
{
static ImageFileFormat** get()
{
static DefaultImageFormats formats;
return formats.formats;
}
private:
DefaultImageFormats() noexcept
{
formats[0] = &png;
formats[1] = &jpg;
formats[2] = &gif;
formats[3] = nullptr;
}
PNGImageFormat png;
JPEGImageFormat jpg;
GIFImageFormat gif;
ImageFileFormat* formats[4];
};
ImageFileFormat* ImageFileFormat::findImageFormatForStream (InputStream& input)
{
const int64 streamPos = input.getPosition();
for (ImageFileFormat** i = DefaultImageFormats::get(); *i != nullptr; ++i)
{
const bool found = (*i)->canUnderstand (input);
input.setPosition (streamPos);
if (found)
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)
{
if (ImageFileFormat* format = findImageFormatForStream (input))
return format->decodeImage (input);
return Image();
}
Image ImageFileFormat::loadFrom (const File& file)
{
FileInputStream stream (file);
if (stream.openedOk())
{
BufferedInputStream b (stream, 8192);
return loadFrom (b);
}
return Image();
}
Image ImageFileFormat::loadFrom (const void* rawData, const size_t numBytes)
{
if (rawData != nullptr && numBytes > 4)
{
MemoryInputStream stream (rawData, numBytes, false);
return loadFrom (stream);
}
return Image();
}
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
struct DefaultImageFormats
{
static ImageFileFormat** get()
{
static DefaultImageFormats formats;
return formats.formats;
}
private:
DefaultImageFormats() noexcept
{
formats[0] = &png;
formats[1] = &jpg;
formats[2] = &gif;
formats[3] = nullptr;
}
PNGImageFormat png;
JPEGImageFormat jpg;
GIFImageFormat gif;
ImageFileFormat* formats[4];
};
ImageFileFormat* ImageFileFormat::findImageFormatForStream (InputStream& input)
{
const int64 streamPos = input.getPosition();
for (ImageFileFormat** i = DefaultImageFormats::get(); *i != nullptr; ++i)
{
const bool found = (*i)->canUnderstand (input);
input.setPosition (streamPos);
if (found)
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)
{
if (ImageFileFormat* format = findImageFormatForStream (input))
return format->decodeImage (input);
return Image();
}
Image ImageFileFormat::loadFrom (const File& file)
{
FileInputStream stream (file);
if (stream.openedOk())
{
BufferedInputStream b (stream, 8192);
return loadFrom (b);
}
return Image();
}
Image ImageFileFormat::loadFrom (const void* rawData, const size_t numBytes)
{
if (rawData != nullptr && numBytes > 4)
{
MemoryInputStream stream (rawData, numBytes, false);
return loadFrom (stream);
}
return Image();
}
} // namespace juce

View File

@ -1,223 +1,223 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
Base-class for codecs that can read and write image file formats such
as PNG, JPEG, etc.
This class also contains static methods to make it easy to load images
from files, streams or from memory.
@see Image, ImageCache
@tags{Graphics}
*/
class JUCE_API ImageFileFormat
{
protected:
//==============================================================================
/** Creates an ImageFormat. */
ImageFileFormat() = default;
public:
/** Destructor. */
virtual ~ImageFileFormat() = default;
//==============================================================================
/** Returns a description of this file format.
E.g. "JPEG", "PNG"
*/
virtual String getFormatName() = 0;
/** 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.
Note that this will advance the stream and leave it in a new position, so if you're
planning on re-using it, you may want to rewind it after calling this method.
@see decodeImage
*/
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
to see if it can handle the stream.
@param input the stream to read the data from. The stream will be positioned
at the start of the image data (but this may not necessarily
be position 0)
@returns the image that was decoded, or an invalid image if it fails.
@see loadFrom
*/
virtual Image decodeImage (InputStream& input) = 0;
//==============================================================================
/** Attempts to write an image to a stream.
To specify extra information like encoding quality, there will be appropriate parameters
in the subclasses of the specific file types.
@returns true if it nothing went wrong.
*/
virtual bool writeImageToStream (const Image& sourceImage,
OutputStream& destStream) = 0;
//==============================================================================
/** 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.
This will use the findImageFormatForStream() method to locate a suitable
codec, and use that to load the image.
@returns the image that was decoded, or an invalid image if it fails.
*/
static Image loadFrom (InputStream& input);
/** Tries to load an image from a file.
This will use the findImageFormatForStream() method to locate a suitable
codec, and use that to load the image.
@returns the image that was decoded, or an invalid image if it fails.
*/
static Image loadFrom (const File& file);
/** Tries to load an image from a block of raw image data.
This will use the findImageFormatForStream() method to locate a suitable
codec, and use that to load the image.
@returns the image that was decoded, or an invalid image if it fails.
*/
static Image loadFrom (const void* rawData,
size_t numBytesOfData);
};
//==============================================================================
/**
A subclass of ImageFileFormat for reading and writing PNG files.
@see ImageFileFormat, JPEGImageFormat
@tags{Graphics}
*/
class JUCE_API PNGImageFormat : public ImageFileFormat
{
public:
//==============================================================================
PNGImageFormat();
~PNGImageFormat() override;
//==============================================================================
String getFormatName() override;
bool usesFileExtension (const File&) override;
bool canUnderstand (InputStream&) override;
Image decodeImage (InputStream&) override;
bool writeImageToStream (const Image&, OutputStream&) override;
};
//==============================================================================
/**
A subclass of ImageFileFormat for reading and writing JPEG files.
@see ImageFileFormat, PNGImageFormat
@tags{Graphics}
*/
class JUCE_API JPEGImageFormat : public ImageFileFormat
{
public:
//==============================================================================
JPEGImageFormat();
~JPEGImageFormat() override;
//==============================================================================
/** Specifies the quality to be used when writing a JPEG file.
@param newQuality a value 0 to 1.0, where 0 is low quality, 1.0 is best, or
any negative value is "default" quality
*/
void setQuality (float newQuality);
//==============================================================================
String getFormatName() override;
bool usesFileExtension (const File&) override;
bool canUnderstand (InputStream&) override;
Image decodeImage (InputStream&) override;
bool writeImageToStream (const Image&, OutputStream&) override;
private:
float quality;
};
//==============================================================================
/**
A subclass of ImageFileFormat for reading GIF files.
@see ImageFileFormat, PNGImageFormat, JPEGImageFormat
@tags{Graphics}
*/
class JUCE_API GIFImageFormat : public ImageFileFormat
{
public:
//==============================================================================
GIFImageFormat();
~GIFImageFormat() override;
//==============================================================================
String getFormatName() override;
bool usesFileExtension (const File&) override;
bool canUnderstand (InputStream&) override;
Image decodeImage (InputStream&) override;
bool writeImageToStream (const Image&, OutputStream&) override;
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
Base-class for codecs that can read and write image file formats such
as PNG, JPEG, etc.
This class also contains static methods to make it easy to load images
from files, streams or from memory.
@see Image, ImageCache
@tags{Graphics}
*/
class JUCE_API ImageFileFormat
{
protected:
//==============================================================================
/** Creates an ImageFormat. */
ImageFileFormat() = default;
public:
/** Destructor. */
virtual ~ImageFileFormat() = default;
//==============================================================================
/** Returns a description of this file format.
E.g. "JPEG", "PNG"
*/
virtual String getFormatName() = 0;
/** 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.
Note that this will advance the stream and leave it in a new position, so if you're
planning on re-using it, you may want to rewind it after calling this method.
@see decodeImage
*/
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
to see if it can handle the stream.
@param input the stream to read the data from. The stream will be positioned
at the start of the image data (but this may not necessarily
be position 0)
@returns the image that was decoded, or an invalid image if it fails.
@see loadFrom
*/
virtual Image decodeImage (InputStream& input) = 0;
//==============================================================================
/** Attempts to write an image to a stream.
To specify extra information like encoding quality, there will be appropriate parameters
in the subclasses of the specific file types.
@returns true if it nothing went wrong.
*/
virtual bool writeImageToStream (const Image& sourceImage,
OutputStream& destStream) = 0;
//==============================================================================
/** 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.
This will use the findImageFormatForStream() method to locate a suitable
codec, and use that to load the image.
@returns the image that was decoded, or an invalid image if it fails.
*/
static Image loadFrom (InputStream& input);
/** Tries to load an image from a file.
This will use the findImageFormatForStream() method to locate a suitable
codec, and use that to load the image.
@returns the image that was decoded, or an invalid image if it fails.
*/
static Image loadFrom (const File& file);
/** Tries to load an image from a block of raw image data.
This will use the findImageFormatForStream() method to locate a suitable
codec, and use that to load the image.
@returns the image that was decoded, or an invalid image if it fails.
*/
static Image loadFrom (const void* rawData,
size_t numBytesOfData);
};
//==============================================================================
/**
A subclass of ImageFileFormat for reading and writing PNG files.
@see ImageFileFormat, JPEGImageFormat
@tags{Graphics}
*/
class JUCE_API PNGImageFormat : public ImageFileFormat
{
public:
//==============================================================================
PNGImageFormat();
~PNGImageFormat() override;
//==============================================================================
String getFormatName() override;
bool usesFileExtension (const File&) override;
bool canUnderstand (InputStream&) override;
Image decodeImage (InputStream&) override;
bool writeImageToStream (const Image&, OutputStream&) override;
};
//==============================================================================
/**
A subclass of ImageFileFormat for reading and writing JPEG files.
@see ImageFileFormat, PNGImageFormat
@tags{Graphics}
*/
class JUCE_API JPEGImageFormat : public ImageFileFormat
{
public:
//==============================================================================
JPEGImageFormat();
~JPEGImageFormat() override;
//==============================================================================
/** Specifies the quality to be used when writing a JPEG file.
@param newQuality a value 0 to 1.0, where 0 is low quality, 1.0 is best, or
any negative value is "default" quality
*/
void setQuality (float newQuality);
//==============================================================================
String getFormatName() override;
bool usesFileExtension (const File&) override;
bool canUnderstand (InputStream&) override;
Image decodeImage (InputStream&) override;
bool writeImageToStream (const Image&, OutputStream&) override;
private:
float quality;
};
//==============================================================================
/**
A subclass of ImageFileFormat for reading GIF files.
@see ImageFileFormat, PNGImageFormat, JPEGImageFormat
@tags{Graphics}
*/
class JUCE_API GIFImageFormat : public ImageFileFormat
{
public:
//==============================================================================
GIFImageFormat();
~GIFImageFormat() override;
//==============================================================================
String getFormatName() override;
bool usesFileExtension (const File&) override;
bool canUnderstand (InputStream&) override;
Image decodeImage (InputStream&) override;
bool writeImageToStream (const Image&, OutputStream&) override;
};
} // namespace juce

View File

@ -0,0 +1,82 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
/**
An image that will be resampled before it is drawn.
A plain Image only stores plain pixels, but does not store any information
about how these pixels correspond to points. This means that if the image's
dimensions are interpreted as points, then the image will be blurry when
drawn on high resolution displays. If the image's dimensions are instead
interpreted as corresponding to exact pixel positions, then the logical
size of the image will change depending on the scale factor of the screen
used to draw it.
The ScaledImage class is designed to store an image alongside a scale
factor that informs a renderer how to convert between the image's pixels
and points.
*/
class JUCE_API ScaledImage
{
public:
/** Creates a ScaledImage with an invalid image and unity scale.
*/
ScaledImage() = default;
/** Creates a ScaledImage from an Image, where the dimensions of the image
in pixels are exactly equal to its dimensions in points.
*/
explicit ScaledImage (const Image& imageIn)
: ScaledImage (imageIn, 1.0) {}
/** Creates a ScaledImage from an Image, using a custom scale factor.
A scale of 1.0 means that the image's dimensions in pixels is equal to
its dimensions in points.
A scale of 2.0 means that the image contains 2 pixels per point in each
direction.
*/
ScaledImage (const Image& imageIn, double scaleIn)
: image (imageIn), scaleFactor (scaleIn) {}
/** Returns the image at its original dimensions. */
Image getImage() const { return image; }
/** Returns the image's scale. */
double getScale() const { return scaleFactor; }
/** Returns the bounds of this image expressed in points. */
Rectangle<double> getScaledBounds() const { return image.getBounds().toDouble() / scaleFactor; }
private:
Image image;
double scaleFactor = 1.0;
};
} // namespace juce