[SDL_image] PATCH: Windows Imaging Component backend

For the same reasons there is an ImageIO\UIImage backend for OSX\iOS i’ve
created a patch with Windows Imaging Component backend for Windows. You can
enable it by building with SDL_IMAGE_USE_WIC_BACKEND option. For now its
disabled cause according to wikipedia WIC is available starting from
Windows XP SP3. And I’m note sure that SP3 is mandatory for SDL2_image.
Also it would be great if someone could review the code or test it on a
large variety of images to find any errors\bugs.

Regards, Alexey
-------------- next part --------------

HG changeset patch

User stopiccot <@Alexey_Petruchik>

Date 1419778344 -10800

Sun Dec 28 17:52:24 2014 +0300

Node ID abaeb4ee032db096bf728f53fc4469cd35bdd5d8

Parent 2b0ada991468c1259dc8de3cf6b0f38f68690f53

Windows Imaging Component backend

diff --git a/.hgignore b/.hgignore
— a/.hgignore
+++ b/.hgignore
@@ -16,3 +16,12 @@
.DS_Store
SDL2_image.pc
showimage+
+# for Visual C++
+Debug
+Release
+.user
+
.ncb
+.suo
+
.sdf
+.opensdf
diff --git a/IMG_WindowsImagingComponent.cpp b/IMG_WindowsImagingComponent.cpp
new file mode 100644
— /dev/null
+++ b/IMG_WindowsImagingComponent.cpp
@@ -0,0 +1,264 @@
+/

  • SDL_image: An example image loading library for use with SDL
  • Copyright © 1997-2013 Sam Lantinga
  • This software is provided ‘as-is’, without any express or implied
  • warranty. In no event will the authors be held liable for any damages
  • arising from the use of this software.
  • Permission is granted to anyone to use this software for any purpose,
  • including commercial applications, and to alter it and redistribute it
  • freely, subject to the following restrictions:
    1. The origin of this software must not be misrepresented; you must not
  • claim that you wrote the original software. If you use this software
    
  • in a product, an acknowledgment in the product documentation would be
    
  • appreciated but is not required.
    
    1. Altered source versions must be plainly marked as such, and must not be
  • misrepresented as being the original software.
    
    1. This notice may not be removed or altered from any source distribution.
      +*/

+#if defined(SDL_IMAGE_USE_WIC_BACKEND)
+
+#include “SDL_image.h”
+#include <wincodec.h>
+
+extern “C” {
+
+#define SAFE_RELEASE(X) if ((X)) { (X)->Release(); }
+#define DONE_IF_FAILED(X) if (FAILED((X))) { goto done; }
+
+IWICImagingFactory2* wicFactory = NULL;
+
+int WIC_Init()
+{

  • if (wicFactory == NULL) {
  •   HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&wicFactory));
    
  •   if (FAILED(hr)) {
    
  •   	return -1;
    
  •   }
    
  • }
  • return 0;
    +}

+void WIC_Quit()
+{

  • SAFE_RELEASE(wicFactory);
    +}

+int IMG_InitPNG()
+{

  • return WIC_Init();
    +}

+void IMG_QuitPNG()
+{

  • WIC_Quit();
    +}

+int IMG_InitJPG()
+{

  • return WIC_Init();
    +}

+void IMG_QuitJPG()
+{

  • WIC_Quit();
    +}

+int IMG_InitTIF()
+{

  • return WIC_Init();
    +}

+void IMG_QuitTIF()
+{

  • WIC_Quit();
    +}

+int IMG_isPNG(SDL_RWops *src)
+{

  • Sint64 start;
  • int is_PNG;
  • Uint8 magic[4];
  • if ( !src ) {
  •    return 0;
    
  • }
  • start = SDL_RWtell(src);
  • is_PNG = 0;
  • if ( SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic) ) {
  •    if ( magic[0] == 0x89 &&
    
  •         magic[1] == 'P' &&
    
  •         magic[2] == 'N' &&
    
  •         magic[3] == 'G' ) {
    
  •        is_PNG = 1;
    
  •    }
    
  • }
  • SDL_RWseek(src, start, RW_SEEK_SET);
  • return(is_PNG);
    +}

+int IMG_isJPG(SDL_RWops *src)
+{

  • Sint64 start;
  • int is_JPG;
  • int in_scan;
  • Uint8 magic[4];
  • /* This detection code is by Steaphan Greene */
  • /* Blame me, not Sam, if this doesn’t work right. */
  • /* And don’t forget to report the problem to the the sdl list too! */
  • if (!src)
  •   return 0;
    
  • start = SDL_RWtell(src);
  • is_JPG = 0;
  • in_scan = 0;
  • if (SDL_RWread(src, magic, 2, 1)) {
  •   if ((magic[0] == 0xFF) && (magic[1] == 0xD8)) {
    
  •   	is_JPG = 1;
    
  •   	while (is_JPG == 1) {
    
  •   		if (SDL_RWread(src, magic, 1, 2) != 2) {
    
  •   			is_JPG = 0;
    
  •   		}
    
  •   		else if ((magic[0] != 0xFF) && (in_scan == 0)) {
    
  •   			is_JPG = 0;
    
  •   		}
    
  •   		else if ((magic[0] != 0xFF) || (magic[1] == 0xFF)) {
    
  •   			/* Extra padding in JPEG (legal) */
    
  •   			/* or this is data and we are scanning */
    
  •   			SDL_RWseek(src, -1, RW_SEEK_CUR);
    
  •   		}
    
  •   		else if (magic[1] == 0xD9) {
    
  •   			/* Got to end of good JPEG */
    
  •   			break;
    
  •   		}
    
  •   		else if ((in_scan == 1) && (magic[1] == 0x00)) {
    
  •   			/* This is an encoded 0xFF within the data */
    
  •   		}
    
  •   		else if ((magic[1] >= 0xD0) && (magic[1] < 0xD9)) {
    
  •   			/* These have nothing else */
    
  •   		}
    
  •   		else if (SDL_RWread(src, magic + 2, 1, 2) != 2) {
    
  •   			is_JPG = 0;
    
  •   		}
    
  •   		else {
    
  •   			/* Yes, it's big-endian */
    
  •   			Sint64 innerStart;
    
  •   			Uint32 size;
    
  •   			Sint64 end;
    
  •   			innerStart = SDL_RWtell(src);
    
  •   			size = (magic[2] << 8) + magic[3];
    
  •   			end = SDL_RWseek(src, size - 2, RW_SEEK_CUR);
    
  •   			if (end != innerStart + size - 2) is_JPG = 0;
    
  •   			if (magic[1] == 0xDA) {
    
  •   				/* Now comes the actual JPEG meat */
    

+#ifdef FAST_IS_JPEG

  •   				/* Ok, I'm convinced.  It is a JPEG. */
    
  •   				break;
    

+#else

  •   				/* I'm not convinced.  Prove it! */
    
  •   				in_scan = 1;
    

+#endif

  •   			}
    
  •   		}
    
  •   	}
    
  •   }
    
  • }
  • SDL_RWseek(src, start, RW_SEEK_SET);
  • return(is_JPG);
    +}

+int IMG_isTIF(SDL_RWops* src)
+{

  • Sint64 start;
  • int is_TIF;
  • Uint8 magic[4];
  • if (!src)
  •   return 0;
    
  • start = SDL_RWtell(src);
  • is_TIF = 0;
  • if (SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic)) {
  •   if ((magic[0] == 'I' &&
    
  •   	magic[1] == 'I' &&
    
  •   	magic[2] == 0x2a &&
    
  •   	magic[3] == 0x00) ||
    
  •   	(magic[0] == 'M' &&
    
  •   	magic[1] == 'M' &&
    
  •   	magic[2] == 0x00 &&
    
  •   	magic[3] == 0x2a)) {
    
  •   	is_TIF = 1;
    
  •   }
    
  • }
  • SDL_RWseek(src, start, RW_SEEK_SET);
  • return(is_TIF);
    +}

+SDL_Surface* WIC_LoadImage(SDL_RWops *src)
+{

  • SDL_Surface* surface = NULL;
  • IWICStream* stream = NULL;
  • IWICBitmapDecoder* bitmapDecoder = NULL;
  • IWICBitmapFrameDecode* bitmapFrame = NULL;
  • IWICFormatConverter* formatConverter = NULL;
  • Sint64 fileSize = SDL_RWsize(src);
  • Uint8* memoryBuffer = (Uint8*)SDL_malloc(fileSize);
  • SDL_RWread(src, memoryBuffer, 1, fileSize);
  • DONE_IF_FAILED(wicFactory->CreateStream(&stream));
  • DONE_IF_FAILED(stream->InitializeFromMemory(memoryBuffer, fileSize));
  • DONE_IF_FAILED(wicFactory->CreateDecoderFromStream(stream, NULL, WICDecodeMetadataCacheOnDemand, &bitmapDecoder));
  • DONE_IF_FAILED(bitmapDecoder->GetFrame(0, &bitmapFrame));
  • DONE_IF_FAILED(wicFactory->CreateFormatConverter(&formatConverter));
  • DONE_IF_FAILED(formatConverter->Initialize(bitmapFrame, GUID_WICPixelFormat32bppPRGBA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom));
  • UINT width, height;
  • DONE_IF_FAILED(bitmapFrame->GetSize(&width, &height));
  • Uint32 Amask = 0xFF000000;
  • Uint32 Rmask = 0x00FF0000;
  • Uint32 Gmask = 0x0000FF00;
  • Uint32 Bmask = 0x000000FF;
  • surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, Rmask, Gmask, Bmask, Amask);
  • formatConverter->CopyPixels(NULL, width * 4, width * height * 4, (BYTE*)surface->pixels);

+done:

  • SAFE_RELEASE(formatConverter);
  • SAFE_RELEASE(bitmapFrame);
  • SAFE_RELEASE(bitmapDecoder);
  • SAFE_RELEASE(stream);
  • if (memoryBuffer) {
  •   SDL_free(memoryBuffer);
    
  • }
  • return surface;
    +}

+SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
+{

  • return WIC_LoadImage(src);
    +}

+SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src)
+{

  • return WIC_LoadImage(src);
    +}

+SDL_Surface *IMG_LoadTIF_RW(SDL_RWops *src)
+{

  • return WIC_LoadImage(src);
    +}

+}
+
+#endif
\ No newline at end of file
diff --git a/IMG_jpg.c b/IMG_jpg.c
— a/IMG_jpg.c
+++ b/IMG_jpg.c
@@ -19,7 +19,7 @@
3. This notice may not be removed or altered from any source distribution.
*/

-#if !defined(APPLE) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
+#if !(defined(APPLE) || defined(SDL_IMAGE_USE_WIC_BACKEND)) || defined(SDL_IMAGE_USE_COMMON_BACKEND)

/* This is a JPEG image file loading framework */

diff --git a/IMG_png.c b/IMG_png.c
— a/IMG_png.c
+++ b/IMG_png.c
@@ -23,7 +23,7 @@

#include “SDL_image.h”

-#if !defined(APPLE) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
+#if !(defined(APPLE) || defined(SDL_IMAGE_USE_WIC_BACKEND)) || defined(SDL_IMAGE_USE_COMMON_BACKEND)

#ifdef LOAD_PNG

diff --git a/IMG_tif.c b/IMG_tif.c
— a/IMG_tif.c
+++ b/IMG_tif.c
@@ -19,7 +19,7 @@
3. This notice may not be removed or altered from any source distribution.
*/

-#if !defined(APPLE) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
+#if !(defined(APPLE) || defined(SDL_IMAGE_USE_WIC_BACKEND)) || defined(SDL_IMAGE_USE_COMMON_BACKEND)

/* This is a TIFF image file loading framework */

diff --git a/VisualC/SDL_image_VS2008.vcproj b/VisualC/SDL_image_VS2008.vcproj
— a/VisualC/SDL_image_VS2008.vcproj
+++ b/VisualC/SDL_image_VS2008.vcproj
@@ -773,6 +773,10 @@
>

<File

  •   		RelativePath="..\IMG_WindowsImagingComponent.c"
    
  •   		>
    
  •   	</File>
    
  •   	<File
      		RelativePath="..\IMG_xcf.c"
      		>
      		<FileConfiguration
    

diff --git a/VisualC/SDL_image_VS2010.vcxproj b/VisualC/SDL_image_VS2010.vcxproj
— a/VisualC/SDL_image_VS2010.vcxproj
+++ b/VisualC/SDL_image_VS2010.vcxproj
@@ -336,6 +336,7 @@
%(PreprocessorDefinitions)

  • %(AdditionalIncludeDirectories) %(PreprocessorDefinitions)

diff --git a/VisualC/SDL_image_VS2012.vcxproj b/VisualC/SDL_image_VS2012.vcxproj
— a/VisualC/SDL_image_VS2012.vcxproj
+++ b/VisualC/SDL_image_VS2012.vcxproj
@@ -332,6 +332,7 @@
%(PreprocessorDefinitions)

  • %(AdditionalIncludeDirectories) %(PreprocessorDefinitions)

diff --git a/VisualC/SDL_image_VS2013.vcxproj b/VisualC/SDL_image_VS2013.vcxproj
— a/VisualC/SDL_image_VS2013.vcxproj
+++ b/VisualC/SDL_image_VS2013.vcxproj
@@ -332,6 +332,7 @@
%(PreprocessorDefinitions)

  • %(AdditionalIncludeDirectories) %(PreprocessorDefinitions)

Alexey,

Neat! Less external dependencies is (almost) always nice. :slight_smile:

Do you mind filing a bug report at http://bugzilla.libsdl.org http://bugzilla.libsdl.org/ with this patch? Just trying to help facilitate things to help the SDL development team ? it probably stands a better chance there of not being lost or forgotten about.

Cheers,
Jeffrey Carpenter <@Jeffrey_Carpenter>

-------------- next part --------------
A non-text attachment was scrubbed…
Name: smime.p7s
Type: application/pkcs7-signature
Size: 1572 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20141228/fa9cd14a/attachment-0001.bin

I think a requirement for SP3 given that Microsoft now has the requirement that you use something newer is quite reasonable.

I am reluctant to raise the bar to a Vista or greater level because Windows 7 is the only version since that I don’t absolutely hate using, and also ? 32 bit testing.

JosephSent via mobile

On Dec 28, 2014, at 07:07, Alexey Petruchik <alexey.petruchik at gmail.com> wrote:

For the same reasons there is an ImageIO\UIImage backend for OSX\iOS i’ve created a patch with Windows Imaging Component backend for Windows. You can enable it by building with SDL_IMAGE_USE_WIC_BACKEND option. For now its disabled cause according to wikipedia WIC is available starting from Windows XP SP3. And I’m note sure that SP3 is mandatory for SDL2_image. Also it would be great if someone could review the code or test it on a large variety of images to find any errors\bugs.

Regards, Alexey
<patch.diff>


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Added a bug in bugzilla - https://bugzilla.libsdl.org/show_bug.cgi?id=2829On Tue, Dec 30, 2014 at 4:00 AM, Sik the hedgehog < sik.the.hedgehog at gmail.com> wrote:

2014-12-29 15:20 GMT-03:00, T. Joseph Carter <tjcarter at spiritsubstance.com

:
I think a requirement for SP3 given that Microsoft now has the
requirement
that you use something newer is quite reasonable.

I believe to assume that XP having SP3 is safe by now. That said…

I am reluctant to raise the bar to a Vista or greater level because
Windows
7 is the only version since that I don’t absolutely hate using, and also
?
32 bit testing.

Support for XP is pretty much dead and the absolute majority of
programs need Vista or 7 now. Really the only reason to keep around XP
support is because of some programs that were in development from
earlier that need to keep that promise around, but I imagine that
sooner or later SDL2 and its satellites libraries will need to get rid
of it, especially given how aggresively Microsoft has been pushing its
newer APIs lately. (maybe a compile-time define for could be allowed
to decide whether to break XP support or not, but I wonder how much of
a mess that will make)

32-bit still isn’t going away though, for some reason there’s a lot of
people using 32-bit Windows 7. I could understand with XP, but with
7…

All of that probably belongs in another thread though.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2014-12-29 15:20 GMT-03:00, T. Joseph Carter :

I think a requirement for SP3 given that Microsoft now has the requirement
that you use something newer is quite reasonable.

I believe to assume that XP having SP3 is safe by now. That said…

I am reluctant to raise the bar to a Vista or greater level because Windows
7 is the only version since that I don’t absolutely hate using, and also ?
32 bit testing.

Support for XP is pretty much dead and the absolute majority of
programs need Vista or 7 now. Really the only reason to keep around XP
support is because of some programs that were in development from
earlier that need to keep that promise around, but I imagine that
sooner or later SDL2 and its satellites libraries will need to get rid
of it, especially given how aggresively Microsoft has been pushing its
newer APIs lately. (maybe a compile-time define for could be allowed
to decide whether to break XP support or not, but I wonder how much of
a mess that will make)

32-bit still isn’t going away though, for some reason there’s a lot of
people using 32-bit Windows 7. I could understand with XP, but with
7…

All of that probably belongs in another thread though.