mirror of https://github.com/buggins/dlangui.git
use Derelict/FreeImage instead of libpng to fix library version issues
This commit is contained in:
parent
a3d195fb8b
commit
81a71fab33
|
@ -190,13 +190,10 @@
|
|||
</Config>
|
||||
<Folder name="dlangui">
|
||||
<Folder name="3rdparty">
|
||||
<Folder name="DerelictUtil">
|
||||
<File path="..\DerelictUtil\source\derelict\util\exception.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\loader.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\sharedlib.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\system.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\wintypes.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\xtypes.d" />
|
||||
<Folder name="DerelictFT">
|
||||
<File path="..\DerelictFT\source\derelict\freetype\ft.d" />
|
||||
<File path="..\DerelictFT\source\derelict\freetype\functions.d" />
|
||||
<File path="..\DerelictFT\source\derelict\freetype\types.d" />
|
||||
</Folder>
|
||||
<Folder name="DerelictGL3">
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\arb.d" />
|
||||
|
@ -215,10 +212,18 @@
|
|||
<File path="..\DerelictGL3\source\derelict\opengl3\wgl.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\wglext.d" />
|
||||
</Folder>
|
||||
<Folder name="DerelictFT">
|
||||
<File path="..\DerelictFT\source\derelict\freetype\ft.d" />
|
||||
<File path="..\DerelictFT\source\derelict\freetype\functions.d" />
|
||||
<File path="..\DerelictFT\source\derelict\freetype\types.d" />
|
||||
<Folder name="DerelictUtil">
|
||||
<File path="..\DerelictUtil\source\derelict\util\exception.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\loader.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\sharedlib.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\system.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\wintypes.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\xtypes.d" />
|
||||
</Folder>
|
||||
<Folder name="DerelictFI">
|
||||
<File path="..\DerelictFI\source\derelict\freeimage\freeimage.d" />
|
||||
<File path="..\DerelictFI\source\derelict\freeimage\functions.d" />
|
||||
<File path="..\DerelictFI\source\derelict\freeimage\types.d" />
|
||||
</Folder>
|
||||
<Folder name="gl3n">
|
||||
<File path="..\gl3n\gl3n\aabb.d" />
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -216,8 +216,11 @@ ColorDrawBuf loadImage(string filename) {
|
|||
ColorDrawBuf loadImage(InputStream stream) {
|
||||
if (stream is null || !stream.isOpen)
|
||||
return null;
|
||||
// TODO: support more image types
|
||||
return loadPngImage(stream);
|
||||
static if (USE_FREEIMAGE) {
|
||||
return loadFreeImage(stream);
|
||||
} else static if (USE_LIBPNG) {
|
||||
return loadPngImage(stream);
|
||||
}
|
||||
}
|
||||
|
||||
class ImageDecodingException : Exception {
|
||||
|
@ -226,110 +229,205 @@ class ImageDecodingException : Exception {
|
|||
}
|
||||
}
|
||||
|
||||
extern (C) void lvpng_error_func (png_structp png, png_const_charp msg)
|
||||
{
|
||||
string s = fromStringz(msg);
|
||||
Log.d("Error while reading PNG image: ", s);
|
||||
// todo: exceptions do not work inside C function
|
||||
throw new ImageDecodingException("Error while decoding PNG image");
|
||||
immutable bool USE_LIBPNG = false;
|
||||
immutable bool USE_FREEIMAGE = true;
|
||||
|
||||
shared static this() {
|
||||
//import derelict.freeimage.freeimage;
|
||||
//DerelictFI.load();
|
||||
}
|
||||
|
||||
extern (C) void lvpng_warning_func (png_structp png, png_const_charp msg)
|
||||
{
|
||||
string s = fromStringz(msg);
|
||||
Log.d("Warn while reading PNG image: ", s);
|
||||
// todo: exceptions do not work inside C function
|
||||
throw new ImageDecodingException("Error while decoding PNG image");
|
||||
static if (USE_FREEIMAGE) {
|
||||
ColorDrawBuf loadFreeImage(InputStream stream) {
|
||||
import derelict.freeimage.freeimage;
|
||||
|
||||
static bool FREE_IMAGE_LOADED;
|
||||
if (!FREE_IMAGE_LOADED) {
|
||||
DerelictFI.load();
|
||||
FREE_IMAGE_LOADED = true;
|
||||
}
|
||||
|
||||
ubyte imagebuf[];
|
||||
ubyte readbuf[4096];
|
||||
for (;;) {
|
||||
size_t bytesRead = stream.read(readbuf);
|
||||
if (!bytesRead)
|
||||
break;
|
||||
imagebuf ~= readbuf[0..bytesRead];
|
||||
}
|
||||
//pointer to the image, once loaded
|
||||
FIBITMAP *dib = null; //image format
|
||||
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
||||
// attach the binary data to a memory stream
|
||||
FIMEMORY *hmem = FreeImage_OpenMemory(imagebuf.ptr, imagebuf.length);
|
||||
fif = FreeImage_GetFileTypeFromMemory(hmem);
|
||||
//check that the plugin has reading capabilities and load the file
|
||||
if(!FreeImage_FIFSupportsReading(fif)) {
|
||||
FreeImage_CloseMemory(hmem);
|
||||
return null;
|
||||
}
|
||||
|
||||
// load an image from the memory stream
|
||||
dib = FreeImage_LoadFromMemory(fif, hmem, 0);
|
||||
|
||||
//if the image failed to load, return failure
|
||||
if (!dib) {
|
||||
Log.e("Failed to decode image");
|
||||
FreeImage_CloseMemory(hmem);
|
||||
return null;
|
||||
}
|
||||
//retrieve the image data
|
||||
ubyte * data = cast(ubyte*)FreeImage_GetBits(dib);
|
||||
//get the image width and height, and size per pixel
|
||||
int width = FreeImage_GetWidth(dib);
|
||||
int height = FreeImage_GetHeight(dib);
|
||||
int pixelSize = FreeImage_GetBPP(dib)/8;
|
||||
int size = width*height*pixelSize;
|
||||
|
||||
ColorDrawBuf res = new ColorDrawBuf(width, height);
|
||||
|
||||
//swap R and B and invert image while copying
|
||||
ubyte* src;
|
||||
uint* dst;
|
||||
uint r, g, b, a;
|
||||
for( int i = 0, ii = height-1; i < height ; ++i, --ii ) {
|
||||
dst = res.scanLine(i);
|
||||
src = data + (ii * width) * pixelSize;
|
||||
for( int j = 0; j < width; ++j, ++dst, src += pixelSize ) {
|
||||
a = 0;
|
||||
switch (pixelSize) {
|
||||
case 4:
|
||||
a = src[3] ^ 255;
|
||||
case 3:
|
||||
r = src[2];
|
||||
g = src[1];
|
||||
b = src[0];
|
||||
break;
|
||||
case 2:
|
||||
// todo: do something better
|
||||
r = g = src[1];
|
||||
b = src[0];
|
||||
break;
|
||||
default:
|
||||
case 1:
|
||||
r = g = b = src[0];
|
||||
break;
|
||||
}
|
||||
dst[0] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
FreeImage_CloseMemory(hmem);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
extern (C) void lvpng_read_func(png_structp png, png_bytep buf, png_size_t len)
|
||||
{
|
||||
InputStream stream = cast(InputStream)png_get_io_ptr(png);
|
||||
ubyte[] localbuf = new ubyte[len];
|
||||
if (stream.read(localbuf) != len)
|
||||
throw new ImageDecodingException("Error while reading PNG image");
|
||||
for (uint i = 0; i < len; i++)
|
||||
buf[i] = localbuf[i];
|
||||
}
|
||||
static if (USE_LIBPNG) {
|
||||
|
||||
/// load and decode PNG image
|
||||
ColorDrawBuf loadPngImage(InputStream stream)
|
||||
{
|
||||
png_structp png_ptr = null;
|
||||
png_infop info_ptr = null;
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
cast(png_voidp)stream, &lvpng_error_func, &lvpng_warning_func);
|
||||
if ( !png_ptr )
|
||||
return null;
|
||||
extern (C) void lvpng_error_func (png_structp png, png_const_charp msg)
|
||||
{
|
||||
string s = fromStringz(msg);
|
||||
Log.d("Error while reading PNG image: ", s);
|
||||
// todo: exceptions do not work inside C function
|
||||
throw new ImageDecodingException("Error while decoding PNG image");
|
||||
}
|
||||
|
||||
try {
|
||||
//
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
lvpng_error_func(png_ptr, "cannot create png info struct");
|
||||
png_set_read_fn(png_ptr,
|
||||
cast(void*)stream, &lvpng_read_func);
|
||||
png_read_info( png_ptr, info_ptr );
|
||||
extern (C) void lvpng_warning_func (png_structp png, png_const_charp msg)
|
||||
{
|
||||
string s = fromStringz(msg);
|
||||
Log.d("Warn while reading PNG image: ", s);
|
||||
// todo: exceptions do not work inside C function
|
||||
throw new ImageDecodingException("Error while decoding PNG image");
|
||||
}
|
||||
|
||||
extern (C) void lvpng_read_func(png_structp png, png_bytep buf, png_size_t len)
|
||||
{
|
||||
InputStream stream = cast(InputStream)png_get_io_ptr(png);
|
||||
ubyte[] localbuf = new ubyte[len];
|
||||
if (stream.read(localbuf) != len)
|
||||
throw new ImageDecodingException("Error while reading PNG image");
|
||||
for (uint i = 0; i < len; i++)
|
||||
buf[i] = localbuf[i];
|
||||
}
|
||||
|
||||
/// load and decode PNG image
|
||||
ColorDrawBuf loadPngImage(InputStream stream)
|
||||
{
|
||||
png_structp png_ptr = null;
|
||||
png_infop info_ptr = null;
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
cast(png_voidp)stream, &lvpng_error_func, &lvpng_warning_func);
|
||||
if ( !png_ptr )
|
||||
return null;
|
||||
|
||||
try {
|
||||
//
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
lvpng_error_func(png_ptr, "cannot create png info struct");
|
||||
png_set_read_fn(png_ptr,
|
||||
cast(void*)stream, &lvpng_read_func);
|
||||
png_read_info( png_ptr, info_ptr );
|
||||
|
||||
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height,
|
||||
&bit_depth, &color_type, &interlace_type,
|
||||
null, null);
|
||||
ColorDrawBuf drawbuf = new ColorDrawBuf(width, height);
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height,
|
||||
&bit_depth, &color_type, &interlace_type,
|
||||
null, null);
|
||||
ColorDrawBuf drawbuf = new ColorDrawBuf(width, height);
|
||||
|
||||
if (color_type & PNG_COLOR_MASK_PALETTE)
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
if (color_type & PNG_COLOR_MASK_PALETTE)
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
png_set_invert_alpha(png_ptr);
|
||||
png_set_invert_alpha(png_ptr);
|
||||
|
||||
if (bit_depth < 8)
|
||||
png_set_packing(png_ptr);
|
||||
if (bit_depth < 8)
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
|
||||
png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
|
||||
int number_passes = png_set_interlace_handling(png_ptr);
|
||||
png_set_bgr(png_ptr);
|
||||
int number_passes = png_set_interlace_handling(png_ptr);
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
for (int pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
uint * row = drawbuf.scanLine(y);
|
||||
png_read_rows(png_ptr, cast(ubyte **)&row, null, 1);
|
||||
}
|
||||
}
|
||||
for (int pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
uint * row = drawbuf.scanLine(y);
|
||||
png_read_rows(png_ptr, cast(ubyte **)&row, null, 1);
|
||||
}
|
||||
}
|
||||
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, null);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, null);
|
||||
|
||||
return drawbuf;
|
||||
} catch (ImageDecodingException e) {
|
||||
if (png_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return drawbuf;
|
||||
} catch (ImageDecodingException e) {
|
||||
if (png_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//bool LVPngImageSource::CheckPattern( const lUInt8 * buf, int )
|
||||
//{
|
||||
//return( !png_sig_cmp((unsigned char *)buf, (png_size_t)0, 4) );
|
||||
//}
|
||||
//bool LVPngImageSource::CheckPattern( const lUInt8 * buf, int )
|
||||
//{
|
||||
//return( !png_sig_cmp((unsigned char *)buf, (png_size_t)0, 4) );
|
||||
//}
|
||||
|
||||
}
|
Loading…
Reference in New Issue