mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-28 02:30:05 +00:00
Made image-loading use CoreImage on the Mac and iOS.
This commit is contained in:
parent
4e68bd517b
commit
90b74fcdee
18 changed files with 991 additions and 911 deletions
|
|
@ -850,7 +850,6 @@
|
|||
2AA4DDD1F26188A570F4DBE2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RelativeCoordinate.cpp; path = ../../src/gui/graphics/geometry/juce_RelativeCoordinate.cpp; sourceTree = SOURCE_ROOT; };
|
||||
54D9BBB69BDA3837240F7749 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_RelativeCoordinate.h; path = ../../src/gui/graphics/geometry/juce_RelativeCoordinate.h; sourceTree = SOURCE_ROOT; };
|
||||
0F1C5770B363EF7DF64A876A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GIFLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
EFBDB957445BD56D0458535D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GIFLoader.h; path = ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.h; sourceTree = SOURCE_ROOT; };
|
||||
6619D27E74F623B1E8CE8F71 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_JPEGLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
EAF0F2EAB230F7539B91A7FB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_PNGLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
0337723C9D607B82CF8AA682 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CameraDevice.h; path = ../../src/gui/graphics/imaging/juce_CameraDevice.h; sourceTree = SOURCE_ROOT; };
|
||||
|
|
@ -1602,7 +1601,6 @@
|
|||
54D9BBB69BDA3837240F7749 ); name = geometry; sourceTree = "<group>"; };
|
||||
D71FD838B3FD1536FCA839A4 = { isa = PBXGroup; children = (
|
||||
0F1C5770B363EF7DF64A876A,
|
||||
EFBDB957445BD56D0458535D,
|
||||
6619D27E74F623B1E8CE8F71,
|
||||
EAF0F2EAB230F7539B91A7FB ); name = image_file_formats; sourceTree = "<group>"; };
|
||||
36A6F90D0C87EA1D8FBE9EC0 = { isa = PBXGroup; children = (
|
||||
|
|
|
|||
|
|
@ -766,7 +766,6 @@
|
|||
<Filter Name="imaging">
|
||||
<Filter Name="image_file_formats">
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.cpp"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.h"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_JPEGLoader.cpp"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_PNGLoader.cpp"/>
|
||||
</Filter>
|
||||
|
|
|
|||
|
|
@ -766,7 +766,6 @@
|
|||
<Filter Name="imaging">
|
||||
<Filter Name="image_file_formats">
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.cpp"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.h"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_JPEGLoader.cpp"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_PNGLoader.cpp"/>
|
||||
</Filter>
|
||||
|
|
|
|||
|
|
@ -768,7 +768,6 @@
|
|||
<Filter Name="imaging">
|
||||
<Filter Name="image_file_formats">
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.cpp"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.h"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_JPEGLoader.cpp"/>
|
||||
<File RelativePath="..\..\src\gui\graphics\imaging\image_file_formats\juce_PNGLoader.cpp"/>
|
||||
</Filter>
|
||||
|
|
|
|||
|
|
@ -707,7 +707,6 @@
|
|||
<ClInclude Include="..\..\src\gui\graphics\geometry\juce_Rectangle.h"/>
|
||||
<ClInclude Include="..\..\src\gui\graphics\geometry\juce_RectangleList.h"/>
|
||||
<ClInclude Include="..\..\src\gui\graphics\geometry\juce_RelativeCoordinate.h"/>
|
||||
<ClInclude Include="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.h"/>
|
||||
<ClInclude Include="..\..\src\gui\graphics\imaging\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\src\gui\graphics\imaging\juce_Image.h"/>
|
||||
<ClInclude Include="..\..\src\gui\graphics\imaging\juce_ImageCache.h"/>
|
||||
|
|
|
|||
|
|
@ -2043,9 +2043,6 @@
|
|||
<ClInclude Include="..\..\src\gui\graphics\geometry\juce_RelativeCoordinate.h">
|
||||
<Filter>Juce\Source\gui\graphics\geometry</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\gui\graphics\imaging\image_file_formats\juce_GIFLoader.h">
|
||||
<Filter>Juce\Source\gui\graphics\imaging\image_file_formats</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\gui\graphics\imaging\juce_CameraDevice.h">
|
||||
<Filter>Juce\Source\gui\graphics\imaging</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -850,7 +850,6 @@
|
|||
2AA4DDD1F26188A570F4DBE2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RelativeCoordinate.cpp; path = ../../src/gui/graphics/geometry/juce_RelativeCoordinate.cpp; sourceTree = SOURCE_ROOT; };
|
||||
54D9BBB69BDA3837240F7749 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_RelativeCoordinate.h; path = ../../src/gui/graphics/geometry/juce_RelativeCoordinate.h; sourceTree = SOURCE_ROOT; };
|
||||
0F1C5770B363EF7DF64A876A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GIFLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
EFBDB957445BD56D0458535D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GIFLoader.h; path = ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.h; sourceTree = SOURCE_ROOT; };
|
||||
6619D27E74F623B1E8CE8F71 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_JPEGLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
EAF0F2EAB230F7539B91A7FB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_PNGLoader.cpp; path = ../../src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
0337723C9D607B82CF8AA682 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CameraDevice.h; path = ../../src/gui/graphics/imaging/juce_CameraDevice.h; sourceTree = SOURCE_ROOT; };
|
||||
|
|
@ -1602,7 +1601,6 @@
|
|||
54D9BBB69BDA3837240F7749 ); name = geometry; sourceTree = "<group>"; };
|
||||
D71FD838B3FD1536FCA839A4 = { isa = PBXGroup; children = (
|
||||
0F1C5770B363EF7DF64A876A,
|
||||
EFBDB957445BD56D0458535D,
|
||||
6619D27E74F623B1E8CE8F71,
|
||||
EAF0F2EAB230F7539B91A7FB ); name = image_file_formats; sourceTree = "<group>"; };
|
||||
36A6F90D0C87EA1D8FBE9EC0 = { isa = PBXGroup; children = (
|
||||
|
|
|
|||
|
|
@ -1129,8 +1129,6 @@
|
|||
<GROUP id="UpDEgf4Fr" name="image_file_formats">
|
||||
<FILE id="82P2bqp" name="juce_GIFLoader.cpp" compile="1" resource="0"
|
||||
file="src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp"/>
|
||||
<FILE id="mvmvVPw1S" name="juce_GIFLoader.h" compile="0" resource="0"
|
||||
file="src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.h"/>
|
||||
<FILE id="SuwswXcCp" name="juce_JPEGLoader.cpp" compile="1" resource="0"
|
||||
file="src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp"/>
|
||||
<FILE id="GbTEpJRyd" name="juce_PNGLoader.cpp" compile="1" resource="0"
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -64,7 +64,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 55
|
||||
#define JUCE_BUILDNUMBER 56
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -60797,7 +60797,7 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
A type of ImageFileFormat for reading and writing PNG files.
|
||||
A subclass of ImageFileFormat for reading and writing PNG files.
|
||||
|
||||
@see ImageFileFormat, JPEGImageFormat
|
||||
*/
|
||||
|
|
@ -60815,7 +60815,7 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
A type of ImageFileFormat for reading and writing JPEG files.
|
||||
A subclass of ImageFileFormat for reading and writing JPEG files.
|
||||
|
||||
@see ImageFileFormat, PNGImageFormat
|
||||
*/
|
||||
|
|
@ -60842,6 +60842,24 @@ private:
|
|||
float quality;
|
||||
};
|
||||
|
||||
/**
|
||||
A subclass of ImageFileFormat for reading GIF files.
|
||||
|
||||
@see ImageFileFormat, PNGImageFormat, JPEGImageFormat
|
||||
*/
|
||||
class JUCE_API GIFImageFormat : public ImageFileFormat
|
||||
{
|
||||
public:
|
||||
|
||||
GIFImageFormat();
|
||||
~GIFImageFormat();
|
||||
|
||||
const String getFormatName();
|
||||
bool canUnderstand (InputStream& input);
|
||||
const Image decodeImage (InputStream& input);
|
||||
bool writeImageToStream (const Image& sourceImage, OutputStream& destStream);
|
||||
};
|
||||
|
||||
#endif // __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
|
||||
/*** End of inlined file: juce_ImageFileFormat.h ***/
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 55
|
||||
#define JUCE_BUILDNUMBER 56
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,260 +27,202 @@
|
|||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
#include "juce_GIFLoader.h"
|
||||
#include "../juce_ImageFileFormat.h"
|
||||
#include "../../../../io/streams/juce_InputStream.h"
|
||||
#include "../../colour/juce_PixelFormats.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
GIFLoader::GIFLoader (InputStream& in)
|
||||
: input (in),
|
||||
dataBlockIsZero (false),
|
||||
fresh (false),
|
||||
finished (false)
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER
|
||||
const Image juce_loadWithCoreImage (InputStream& input);
|
||||
#else
|
||||
|
||||
//==============================================================================
|
||||
class GIFLoader
|
||||
{
|
||||
currentBit = lastBit = lastByteIndex = 0;
|
||||
maxCode = maxCodeSize = codeSize = setCodeSize = 0;
|
||||
firstcode = oldcode = 0;
|
||||
clearCode = end_code = 0;
|
||||
|
||||
int imageWidth, imageHeight;
|
||||
int transparent = -1;
|
||||
|
||||
if (! getSizeFromHeader (imageWidth, imageHeight))
|
||||
return;
|
||||
|
||||
if ((imageWidth <= 0) || (imageHeight <= 0))
|
||||
return;
|
||||
|
||||
unsigned char buf [16];
|
||||
if (in.read (buf, 3) != 3)
|
||||
return;
|
||||
|
||||
int numColours = 2 << (buf[0] & 7);
|
||||
|
||||
if ((buf[0] & 0x80) != 0)
|
||||
readPalette (numColours);
|
||||
|
||||
for (;;)
|
||||
public:
|
||||
GIFLoader (InputStream& in)
|
||||
: input (in),
|
||||
dataBlockIsZero (false),
|
||||
fresh (false),
|
||||
finished (false)
|
||||
{
|
||||
if (input.read (buf, 1) != 1)
|
||||
break;
|
||||
currentBit = lastBit = lastByteIndex = 0;
|
||||
maxCode = maxCodeSize = codeSize = setCodeSize = 0;
|
||||
firstcode = oldcode = 0;
|
||||
clearCode = end_code = 0;
|
||||
|
||||
if (buf[0] == ';')
|
||||
break;
|
||||
int imageWidth, imageHeight;
|
||||
int transparent = -1;
|
||||
|
||||
if (buf[0] == '!')
|
||||
if (! getSizeFromHeader (imageWidth, imageHeight))
|
||||
return;
|
||||
|
||||
if ((imageWidth <= 0) || (imageHeight <= 0))
|
||||
return;
|
||||
|
||||
unsigned char buf [16];
|
||||
if (in.read (buf, 3) != 3)
|
||||
return;
|
||||
|
||||
int numColours = 2 << (buf[0] & 7);
|
||||
|
||||
if ((buf[0] & 0x80) != 0)
|
||||
readPalette (numColours);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (input.read (buf, 1) != 1)
|
||||
if (input.read (buf, 1) != 1 || buf[0] == ';')
|
||||
break;
|
||||
|
||||
if (processExtension (buf[0], transparent) < 0)
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf[0] != ',')
|
||||
continue;
|
||||
|
||||
if (input.read (buf, 9) != 9)
|
||||
break;
|
||||
|
||||
imageWidth = makeWord (buf[4], buf[5]);
|
||||
imageHeight = makeWord (buf[6], buf[7]);
|
||||
|
||||
numColours = 2 << (buf[8] & 7);
|
||||
|
||||
if ((buf[8] & 0x80) != 0)
|
||||
if (! readPalette (numColours))
|
||||
break;
|
||||
|
||||
image = Image ((transparent >= 0) ? Image::ARGB : Image::RGB,
|
||||
imageWidth, imageHeight, (transparent >= 0));
|
||||
|
||||
readImage ((buf[8] & 0x40) != 0, transparent);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GIFLoader::~GIFLoader()
|
||||
{
|
||||
}
|
||||
|
||||
bool GIFLoader::getSizeFromHeader (int& w, int& h)
|
||||
{
|
||||
char b[8];
|
||||
|
||||
if (input.read (b, 6) == 6)
|
||||
{
|
||||
if ((strncmp ("GIF87a", b, 6) == 0)
|
||||
|| (strncmp ("GIF89a", b, 6) == 0))
|
||||
{
|
||||
if (input.read (b, 4) == 4)
|
||||
if (buf[0] == '!')
|
||||
{
|
||||
w = makeWord (b[0], b[1]);
|
||||
h = makeWord (b[2], b[3]);
|
||||
return true;
|
||||
if (input.read (buf, 1) != 1)
|
||||
break;
|
||||
|
||||
if (processExtension (buf[0], transparent) < 0)
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf[0] != ',')
|
||||
continue;
|
||||
|
||||
if (input.read (buf, 9) != 9)
|
||||
break;
|
||||
|
||||
imageWidth = makeWord (buf[4], buf[5]);
|
||||
imageHeight = makeWord (buf[6], buf[7]);
|
||||
|
||||
numColours = 2 << (buf[8] & 7);
|
||||
|
||||
if ((buf[8] & 0x80) != 0)
|
||||
if (! readPalette (numColours))
|
||||
break;
|
||||
|
||||
image = Image ((transparent >= 0) ? Image::ARGB : Image::RGB,
|
||||
imageWidth, imageHeight, (transparent >= 0));
|
||||
|
||||
readImage ((buf[8] & 0x40) != 0, transparent);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
~GIFLoader() {}
|
||||
|
||||
Image image;
|
||||
|
||||
private:
|
||||
InputStream& input;
|
||||
uint8 buffer [300];
|
||||
uint8 palette [256][4];
|
||||
bool dataBlockIsZero, fresh, finished;
|
||||
int currentBit, lastBit, lastByteIndex;
|
||||
int codeSize, setCodeSize;
|
||||
int maxCode, maxCodeSize;
|
||||
int firstcode, oldcode;
|
||||
int clearCode, end_code;
|
||||
enum { maxGifCode = 1 << 12 };
|
||||
int table [2] [maxGifCode];
|
||||
int stack [2 * maxGifCode];
|
||||
int *sp;
|
||||
|
||||
bool getSizeFromHeader (int& w, int& h)
|
||||
{
|
||||
char b[8];
|
||||
|
||||
if (input.read (b, 6) == 6)
|
||||
{
|
||||
if ((strncmp ("GIF87a", b, 6) == 0)
|
||||
|| (strncmp ("GIF89a", b, 6) == 0))
|
||||
{
|
||||
if (input.read (b, 4) == 4)
|
||||
{
|
||||
w = makeWord (b[0], b[1]);
|
||||
h = makeWord (b[2], b[3]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GIFLoader::readPalette (const int numCols)
|
||||
{
|
||||
unsigned char rgb[4];
|
||||
|
||||
for (int i = 0; i < numCols; ++i)
|
||||
bool readPalette (const int numCols)
|
||||
{
|
||||
input.read (rgb, 3);
|
||||
unsigned char rgb[4];
|
||||
|
||||
palette [i][0] = rgb[0];
|
||||
palette [i][1] = rgb[1];
|
||||
palette [i][2] = rgb[2];
|
||||
palette [i][3] = 0xff;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int GIFLoader::readDataBlock (unsigned char* const dest)
|
||||
{
|
||||
unsigned char n;
|
||||
|
||||
if (input.read (&n, 1) == 1)
|
||||
{
|
||||
dataBlockIsZero = (n == 0);
|
||||
|
||||
if (dataBlockIsZero || (input.read (dest, n) == n))
|
||||
return n;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GIFLoader::processExtension (const int type, int& transparent)
|
||||
{
|
||||
unsigned char b [300];
|
||||
int n = 0;
|
||||
|
||||
if (type == 0xf9)
|
||||
{
|
||||
n = readDataBlock (b);
|
||||
if (n < 0)
|
||||
return 1;
|
||||
|
||||
if ((b[0] & 0x1) != 0)
|
||||
transparent = b[3];
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
n = readDataBlock (b);
|
||||
}
|
||||
while (n > 0);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int GIFLoader::getCode (const int codeSize_, const bool initialise)
|
||||
{
|
||||
if (initialise)
|
||||
{
|
||||
currentBit = 0;
|
||||
lastBit = 0;
|
||||
finished = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((currentBit + codeSize_) >= lastBit)
|
||||
{
|
||||
if (finished)
|
||||
return -1;
|
||||
|
||||
buffer[0] = buffer [lastByteIndex - 2];
|
||||
buffer[1] = buffer [lastByteIndex - 1];
|
||||
|
||||
const int n = readDataBlock (&buffer[2]);
|
||||
|
||||
if (n == 0)
|
||||
finished = true;
|
||||
|
||||
lastByteIndex = 2 + n;
|
||||
currentBit = (currentBit - lastBit) + 16;
|
||||
lastBit = (2 + n) * 8 ;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
int i = currentBit;
|
||||
|
||||
for (int j = 0; j < codeSize_; ++j)
|
||||
{
|
||||
result |= ((buffer[i >> 3] & (1 << (i & 7))) != 0) << j;
|
||||
++i;
|
||||
}
|
||||
|
||||
currentBit += codeSize_;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int GIFLoader::readLZWByte (const bool initialise, const int inputCodeSize)
|
||||
{
|
||||
int code, incode, i;
|
||||
|
||||
if (initialise)
|
||||
{
|
||||
setCodeSize = inputCodeSize;
|
||||
codeSize = setCodeSize + 1;
|
||||
clearCode = 1 << setCodeSize;
|
||||
end_code = clearCode + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
|
||||
getCode (0, true);
|
||||
|
||||
fresh = true;
|
||||
|
||||
for (i = 0; i < clearCode; ++i)
|
||||
for (int i = 0; i < numCols; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = i;
|
||||
input.read (rgb, 3);
|
||||
|
||||
palette [i][0] = rgb[0];
|
||||
palette [i][1] = rgb[1];
|
||||
palette [i][2] = rgb[2];
|
||||
palette [i][3] = 0xff;
|
||||
}
|
||||
|
||||
for (; i < maxGifCode; ++i)
|
||||
return true;
|
||||
}
|
||||
|
||||
int readDataBlock (unsigned char* dest)
|
||||
{
|
||||
unsigned char n;
|
||||
|
||||
if (input.read (&n, 1) == 1)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = 0;
|
||||
dataBlockIsZero = (n == 0);
|
||||
|
||||
if (dataBlockIsZero || (input.read (dest, n) == n))
|
||||
return n;
|
||||
}
|
||||
|
||||
sp = stack;
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
else if (fresh)
|
||||
|
||||
int processExtension (const int type, int& transparent)
|
||||
{
|
||||
fresh = false;
|
||||
unsigned char b [300];
|
||||
int n = 0;
|
||||
|
||||
if (type == 0xf9)
|
||||
{
|
||||
n = readDataBlock (b);
|
||||
if (n < 0)
|
||||
return 1;
|
||||
|
||||
if ((b[0] & 0x1) != 0)
|
||||
transparent = b[3];
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
firstcode = oldcode
|
||||
= getCode (codeSize, false);
|
||||
n = readDataBlock (b);
|
||||
}
|
||||
while (firstcode == clearCode);
|
||||
while (n > 0);
|
||||
|
||||
return firstcode;
|
||||
return n;
|
||||
}
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
|
||||
while ((code = getCode (codeSize, false)) >= 0)
|
||||
int readLZWByte (const bool initialise, const int inputCodeSize)
|
||||
{
|
||||
if (code == clearCode)
|
||||
int code, incode, i;
|
||||
|
||||
if (initialise)
|
||||
{
|
||||
setCodeSize = inputCodeSize;
|
||||
codeSize = setCodeSize + 1;
|
||||
clearCode = 1 << setCodeSize;
|
||||
end_code = clearCode + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
|
||||
getCode (0, true);
|
||||
|
||||
fresh = true;
|
||||
|
||||
for (i = 0; i < clearCode; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
|
|
@ -293,158 +235,277 @@ int GIFLoader::readLZWByte (const bool initialise, const int inputCodeSize)
|
|||
table[1][i] = 0;
|
||||
}
|
||||
|
||||
codeSize = setCodeSize + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
sp = stack;
|
||||
firstcode = oldcode = getCode (codeSize, false);
|
||||
return firstcode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (code == end_code)
|
||||
else if (fresh)
|
||||
{
|
||||
if (dataBlockIsZero)
|
||||
return -2;
|
||||
fresh = false;
|
||||
|
||||
unsigned char buf [260];
|
||||
|
||||
int n;
|
||||
while ((n = readDataBlock (buf)) > 0)
|
||||
{}
|
||||
|
||||
if (n != 0)
|
||||
return -2;
|
||||
}
|
||||
|
||||
incode = code;
|
||||
|
||||
if (code >= maxCode)
|
||||
{
|
||||
*sp++ = firstcode;
|
||||
code = oldcode;
|
||||
}
|
||||
|
||||
while (code >= clearCode)
|
||||
{
|
||||
*sp++ = table[1][code];
|
||||
if (code == table[0][code])
|
||||
return -2;
|
||||
|
||||
code = table[0][code];
|
||||
}
|
||||
|
||||
*sp++ = firstcode = table[1][code];
|
||||
|
||||
if ((code = maxCode) < maxGifCode)
|
||||
{
|
||||
table[0][code] = oldcode;
|
||||
table[1][code] = firstcode;
|
||||
++maxCode;
|
||||
|
||||
if ((maxCode >= maxCodeSize)
|
||||
&& (maxCodeSize < maxGifCode))
|
||||
do
|
||||
{
|
||||
maxCodeSize <<= 1;
|
||||
++codeSize;
|
||||
firstcode = oldcode
|
||||
= getCode (codeSize, false);
|
||||
}
|
||||
}
|
||||
while (firstcode == clearCode);
|
||||
|
||||
oldcode = incode;
|
||||
return firstcode;
|
||||
}
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
bool GIFLoader::readImage (const int interlace, const int transparent)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (input.read (&c, 1) != 1
|
||||
|| readLZWByte (true, c) < 0)
|
||||
return false;
|
||||
|
||||
if (transparent >= 0)
|
||||
{
|
||||
palette [transparent][0] = 0;
|
||||
palette [transparent][1] = 0;
|
||||
palette [transparent][2] = 0;
|
||||
palette [transparent][3] = 0;
|
||||
}
|
||||
|
||||
int index;
|
||||
int xpos = 0, ypos = 0, pass = 0;
|
||||
|
||||
const Image::BitmapData destData (image, true);
|
||||
uint8* p = destData.data;
|
||||
const bool hasAlpha = image.hasAlphaChannel();
|
||||
|
||||
while ((index = readLZWByte (false, c)) >= 0)
|
||||
{
|
||||
const uint8* const paletteEntry = palette [index];
|
||||
|
||||
if (hasAlpha)
|
||||
while ((code = getCode (codeSize, false)) >= 0)
|
||||
{
|
||||
((PixelARGB*) p)->setARGB (paletteEntry[3],
|
||||
paletteEntry[0],
|
||||
paletteEntry[1],
|
||||
paletteEntry[2]);
|
||||
|
||||
((PixelARGB*) p)->premultiply();
|
||||
}
|
||||
else
|
||||
{
|
||||
((PixelRGB*) p)->setARGB (0,
|
||||
paletteEntry[0],
|
||||
paletteEntry[1],
|
||||
paletteEntry[2]);
|
||||
}
|
||||
|
||||
p += destData.pixelStride;
|
||||
++xpos;
|
||||
|
||||
if (xpos == destData.width)
|
||||
{
|
||||
xpos = 0;
|
||||
|
||||
if (interlace)
|
||||
if (code == clearCode)
|
||||
{
|
||||
switch (pass)
|
||||
for (i = 0; i < clearCode; ++i)
|
||||
{
|
||||
case 0:
|
||||
case 1: ypos += 8; break;
|
||||
case 2: ypos += 4; break;
|
||||
case 3: ypos += 2; break;
|
||||
table[0][i] = 0;
|
||||
table[1][i] = i;
|
||||
}
|
||||
|
||||
while (ypos >= destData.height)
|
||||
for (; i < maxGifCode; ++i)
|
||||
{
|
||||
++pass;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 1: ypos = 4; break;
|
||||
case 2: ypos = 2; break;
|
||||
case 3: ypos = 1; break;
|
||||
default: return true;
|
||||
}
|
||||
table[0][i] = 0;
|
||||
table[1][i] = 0;
|
||||
}
|
||||
|
||||
codeSize = setCodeSize + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
sp = stack;
|
||||
firstcode = oldcode = getCode (codeSize, false);
|
||||
return firstcode;
|
||||
|
||||
}
|
||||
else if (code == end_code)
|
||||
{
|
||||
if (dataBlockIsZero)
|
||||
return -2;
|
||||
|
||||
unsigned char buf [260];
|
||||
|
||||
int n;
|
||||
while ((n = readDataBlock (buf)) > 0)
|
||||
{}
|
||||
|
||||
if (n != 0)
|
||||
return -2;
|
||||
}
|
||||
|
||||
incode = code;
|
||||
|
||||
if (code >= maxCode)
|
||||
{
|
||||
*sp++ = firstcode;
|
||||
code = oldcode;
|
||||
}
|
||||
|
||||
while (code >= clearCode)
|
||||
{
|
||||
*sp++ = table[1][code];
|
||||
if (code == table[0][code])
|
||||
return -2;
|
||||
|
||||
code = table[0][code];
|
||||
}
|
||||
|
||||
*sp++ = firstcode = table[1][code];
|
||||
|
||||
if ((code = maxCode) < maxGifCode)
|
||||
{
|
||||
table[0][code] = oldcode;
|
||||
table[1][code] = firstcode;
|
||||
++maxCode;
|
||||
|
||||
if ((maxCode >= maxCodeSize)
|
||||
&& (maxCodeSize < maxGifCode))
|
||||
{
|
||||
maxCodeSize <<= 1;
|
||||
++codeSize;
|
||||
}
|
||||
}
|
||||
|
||||
oldcode = incode;
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int getCode (const int codeSize_, const bool initialise)
|
||||
{
|
||||
if (initialise)
|
||||
{
|
||||
currentBit = 0;
|
||||
lastBit = 0;
|
||||
finished = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((currentBit + codeSize_) >= lastBit)
|
||||
{
|
||||
if (finished)
|
||||
return -1;
|
||||
|
||||
buffer[0] = buffer [lastByteIndex - 2];
|
||||
buffer[1] = buffer [lastByteIndex - 1];
|
||||
|
||||
const int n = readDataBlock (&buffer[2]);
|
||||
|
||||
if (n == 0)
|
||||
finished = true;
|
||||
|
||||
lastByteIndex = 2 + n;
|
||||
currentBit = (currentBit - lastBit) + 16;
|
||||
lastBit = (2 + n) * 8 ;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
int i = currentBit;
|
||||
|
||||
for (int j = 0; j < codeSize_; ++j)
|
||||
{
|
||||
result |= ((buffer[i >> 3] & (1 << (i & 7))) != 0) << j;
|
||||
++i;
|
||||
}
|
||||
|
||||
currentBit += codeSize_;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool readImage (const int interlace, const int transparent)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (input.read (&c, 1) != 1
|
||||
|| readLZWByte (true, c) < 0)
|
||||
return false;
|
||||
|
||||
if (transparent >= 0)
|
||||
{
|
||||
palette [transparent][0] = 0;
|
||||
palette [transparent][1] = 0;
|
||||
palette [transparent][2] = 0;
|
||||
palette [transparent][3] = 0;
|
||||
}
|
||||
|
||||
int index;
|
||||
int xpos = 0, ypos = 0, pass = 0;
|
||||
|
||||
const Image::BitmapData destData (image, true);
|
||||
uint8* p = destData.data;
|
||||
const bool hasAlpha = image.hasAlphaChannel();
|
||||
|
||||
while ((index = readLZWByte (false, c)) >= 0)
|
||||
{
|
||||
const uint8* const paletteEntry = palette [index];
|
||||
|
||||
if (hasAlpha)
|
||||
{
|
||||
((PixelARGB*) p)->setARGB (paletteEntry[3],
|
||||
paletteEntry[0],
|
||||
paletteEntry[1],
|
||||
paletteEntry[2]);
|
||||
|
||||
((PixelARGB*) p)->premultiply();
|
||||
}
|
||||
else
|
||||
{
|
||||
++ypos;
|
||||
((PixelRGB*) p)->setARGB (0,
|
||||
paletteEntry[0],
|
||||
paletteEntry[1],
|
||||
paletteEntry[2]);
|
||||
}
|
||||
|
||||
p = destData.getPixelPointer (xpos, ypos);
|
||||
p += destData.pixelStride;
|
||||
++xpos;
|
||||
|
||||
if (xpos == destData.width)
|
||||
{
|
||||
xpos = 0;
|
||||
|
||||
if (interlace)
|
||||
{
|
||||
switch (pass)
|
||||
{
|
||||
case 0:
|
||||
case 1: ypos += 8; break;
|
||||
case 2: ypos += 4; break;
|
||||
case 3: ypos += 2; break;
|
||||
}
|
||||
|
||||
while (ypos >= destData.height)
|
||||
{
|
||||
++pass;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 1: ypos = 4; break;
|
||||
case 2: ypos = 2; break;
|
||||
case 3: ypos = 1; break;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++ypos;
|
||||
}
|
||||
|
||||
p = destData.getPixelPointer (xpos, ypos);
|
||||
}
|
||||
|
||||
if (ypos >= destData.height)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ypos >= destData.height)
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
static inline int makeWord (const uint8 a, const uint8 b) { return (b << 8) | a; }
|
||||
|
||||
GIFLoader (const GIFLoader&);
|
||||
GIFLoader& operator= (const GIFLoader&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
GIFImageFormat::GIFImageFormat() {}
|
||||
GIFImageFormat::~GIFImageFormat() {}
|
||||
|
||||
const String GIFImageFormat::getFormatName() { return "GIF"; }
|
||||
|
||||
bool GIFImageFormat::canUnderstand (InputStream& in)
|
||||
{
|
||||
char header [4];
|
||||
|
||||
return (in.read (header, sizeof (header)) == sizeof (header))
|
||||
&& header[0] == 'G'
|
||||
&& header[1] == 'I'
|
||||
&& header[2] == 'F';
|
||||
}
|
||||
|
||||
const Image GIFImageFormat::decodeImage (InputStream& in)
|
||||
{
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER
|
||||
return juce_loadWithCoreImage (in);
|
||||
#else
|
||||
const ScopedPointer <GIFLoader> loader (new GIFLoader (in));
|
||||
return loader->image;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GIFImageFormat::writeImageToStream (const Image& /*sourceImage*/, OutputStream& /*destStream*/)
|
||||
{
|
||||
jassertfalse; // writing isn't implemented for GIFs!
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCE_GIFLOADER_JUCEHEADER__
|
||||
#define __JUCE_GIFLOADER_JUCEHEADER__
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "../../../../io/streams/juce_InputStream.h"
|
||||
#include "../juce_Image.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Used internally by ImageFileFormat - don't use this class directly in your
|
||||
application.
|
||||
|
||||
@see ImageFileFormat
|
||||
*/
|
||||
class GIFLoader
|
||||
{
|
||||
public:
|
||||
GIFLoader (InputStream& in);
|
||||
~GIFLoader();
|
||||
|
||||
const Image& getImage() const { return image; }
|
||||
|
||||
private:
|
||||
Image image;
|
||||
InputStream& input;
|
||||
uint8 buffer [300];
|
||||
uint8 palette [256][4];
|
||||
bool dataBlockIsZero, fresh, finished;
|
||||
int currentBit, lastBit, lastByteIndex;
|
||||
int codeSize, setCodeSize;
|
||||
int maxCode, maxCodeSize;
|
||||
int firstcode, oldcode;
|
||||
int clearCode, end_code;
|
||||
enum { maxGifCode = 1 << 12 };
|
||||
int table [2] [maxGifCode];
|
||||
int stack [2 * maxGifCode];
|
||||
int *sp;
|
||||
|
||||
bool getSizeFromHeader (int& width, int& height);
|
||||
bool readPalette (const int numCols);
|
||||
int readDataBlock (unsigned char* dest);
|
||||
int processExtension (int type, int& transparent);
|
||||
int readLZWByte (bool initialise, int input_code_size);
|
||||
int getCode (int code_size, bool initialise);
|
||||
bool readImage (int interlace, int transparent);
|
||||
static inline int makeWord (const uint8 a, const uint8 b) { return (b << 8) | a; }
|
||||
|
||||
GIFLoader (const GIFLoader&);
|
||||
GIFLoader& operator= (const GIFLoader&);
|
||||
};
|
||||
|
||||
#endif // DOXYGEN
|
||||
|
||||
#endif // __JUCE_GIFLOADER_JUCEHEADER__
|
||||
|
|
@ -249,8 +249,15 @@ bool JPEGImageFormat::canUnderstand (InputStream& in)
|
|||
return false;
|
||||
}
|
||||
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER
|
||||
const Image juce_loadWithCoreImage (InputStream& input);
|
||||
#endif
|
||||
|
||||
const Image JPEGImageFormat::decodeImage (InputStream& in)
|
||||
{
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER
|
||||
return juce_loadWithCoreImage (in);
|
||||
#else
|
||||
using namespace jpeglibNamespace;
|
||||
using namespace JPEGHelpers;
|
||||
|
||||
|
|
@ -344,6 +351,7 @@ const Image JPEGImageFormat::decodeImage (InputStream& in)
|
|||
}
|
||||
|
||||
return image;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
|
||||
|
|
|
|||
|
|
@ -148,8 +148,15 @@ bool PNGImageFormat::canUnderstand (InputStream& in)
|
|||
&& header[3] == 'G';
|
||||
}
|
||||
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER
|
||||
const Image juce_loadWithCoreImage (InputStream& input);
|
||||
#endif
|
||||
|
||||
const Image PNGImageFormat::decodeImage (InputStream& in)
|
||||
{
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER
|
||||
return juce_loadWithCoreImage (in);
|
||||
#else
|
||||
using namespace pnglibNamespace;
|
||||
Image image;
|
||||
|
||||
|
|
@ -257,6 +264,7 @@ const Image PNGImageFormat::decodeImage (InputStream& in)
|
|||
}
|
||||
|
||||
return image;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
|
||||
|
|
|
|||
|
|
@ -31,43 +31,6 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../io/streams/juce_MemoryInputStream.h"
|
||||
#include "../../../io/files/juce_FileInputStream.h"
|
||||
#include "../../../io/streams/juce_BufferedInputStream.h"
|
||||
#include "image_file_formats/juce_GIFLoader.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class GIFImageFormat : public ImageFileFormat
|
||||
{
|
||||
public:
|
||||
GIFImageFormat() {}
|
||||
~GIFImageFormat() {}
|
||||
|
||||
const String getFormatName()
|
||||
{
|
||||
return "GIF";
|
||||
}
|
||||
|
||||
bool canUnderstand (InputStream& in)
|
||||
{
|
||||
const int bytesNeeded = 4;
|
||||
char header [bytesNeeded];
|
||||
|
||||
return (in.read (header, bytesNeeded) == bytesNeeded)
|
||||
&& header[0] == 'G'
|
||||
&& header[1] == 'I'
|
||||
&& header[2] == 'F';
|
||||
}
|
||||
|
||||
const Image decodeImage (InputStream& in)
|
||||
{
|
||||
const ScopedPointer <GIFLoader> loader (new GIFLoader (in));
|
||||
return loader->getImage();
|
||||
}
|
||||
|
||||
bool writeImageToStream (const Image& /*sourceImage*/, OutputStream& /*destStream*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
/**
|
||||
A type of ImageFileFormat for reading and writing PNG files.
|
||||
A subclass of ImageFileFormat for reading and writing PNG files.
|
||||
|
||||
@see ImageFileFormat, JPEGImageFormat
|
||||
*/
|
||||
|
|
@ -159,7 +159,7 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
/**
|
||||
A type of ImageFileFormat for reading and writing JPEG files.
|
||||
A subclass of ImageFileFormat for reading and writing JPEG files.
|
||||
|
||||
@see ImageFileFormat, PNGImageFormat
|
||||
*/
|
||||
|
|
@ -188,6 +188,25 @@ private:
|
|||
float quality;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A subclass of ImageFileFormat for reading GIF files.
|
||||
|
||||
@see ImageFileFormat, PNGImageFormat, JPEGImageFormat
|
||||
*/
|
||||
class JUCE_API GIFImageFormat : public ImageFileFormat
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
GIFImageFormat();
|
||||
~GIFImageFormat();
|
||||
|
||||
//==============================================================================
|
||||
const String getFormatName();
|
||||
bool canUnderstand (InputStream& input);
|
||||
const Image decodeImage (InputStream& input);
|
||||
bool writeImageToStream (const Image& sourceImage, OutputStream& destStream);
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
|
||||
|
|
|
|||
|
|
@ -770,4 +770,42 @@ LowLevelGraphicsContext* CoreGraphicsImage::createLowLevelContext()
|
|||
return new CoreGraphicsContext (context, height);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER
|
||||
const Image juce_loadWithCoreImage (InputStream& input)
|
||||
{
|
||||
MemoryBlock data;
|
||||
input.readIntoMemoryBlock (data, -1);
|
||||
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData (0, data.getData(), data.getSize(), 0);
|
||||
CGImageSourceRef imageSource = CGImageSourceCreateWithDataProvider (provider, 0);
|
||||
CGDataProviderRelease (provider);
|
||||
|
||||
if (imageSource != 0)
|
||||
{
|
||||
CGImageRef loadedImage = CGImageSourceCreateImageAtIndex (imageSource, 0, 0);
|
||||
CFRelease (imageSource);
|
||||
|
||||
if (loadedImage != 0)
|
||||
{
|
||||
const bool hasAlphaChan = CGImageGetAlphaInfo (loadedImage) != kCGImageAlphaNone;
|
||||
Image image (hasAlphaChan ? Image::ARGB : Image::RGB,
|
||||
(int) CGImageGetWidth (loadedImage), (int) CGImageGetHeight (loadedImage),
|
||||
hasAlphaChan, Image::NativeImage);
|
||||
|
||||
CoreGraphicsImage* const cgImage = dynamic_cast<CoreGraphicsImage*> (image.getSharedImage());
|
||||
jassert (cgImage != 0); // if USE_COREGRAPHICS_RENDERING is set, the CoreGraphicsImage class should have been used.
|
||||
|
||||
CGContextDrawImage (cgImage->context, CGRectMake (0, 0, image.getWidth(), image.getHeight()), loadedImage);
|
||||
CGContextFlush (cgImage->context);
|
||||
CFRelease (loadedImage);
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
return Image::null;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue