Fixed bug 2788 - color space fix for ImageIO backend (OS X, iOS)

Jeffrey Carpenter

Test case resources (should be able to be replaced with your own as long as the pixel format and file encoding matches):
  test.bmp RGB8888 (24-bit, BMP)
  test.png ARGB8888 (32-bit, PNG)

This patch reverts [revision 292](https://hg.libsdl.org/SDL_image/log?rev=292) back to the original author's implementation (Eric Wing). The comments made in this revision seem to contradict what is intended; see CGColorSpaceCreateCalibratedRGB [1] and CGColorSpaceCreateDeviceRGB [2] for Apple's API notes. Also note that the revision comments by "Albert" use a test case that is for use with SDL1 -- how this may change things is unknown to me.

1. https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGColorSpace/index.html#//apple_ref/c/func/CGColorSpaceCreateCalibratedRGB
2. https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGColorSpace/index.html#//apple_ref/c/func/CGColorSpaceCreateDeviceRGB

  Additional notes
* Tested on Mac OS X 10.10 "Yosemite".
* Has not been tested against iOS, SDL1 or images that have been processed with pre-multiplied alpha.

Build test case:
  clang++ sdl2_image-colorspace-fix.cpp -o sdl2_image-colorspace-fix -framework SDL2 -framework SDL2_image

Run test case to generate my existing data (my baseline / reference):
(output in diag_main.txt, using test.bmp and test.png)

bitmap(0, 0) = ff6e8fbd
png(0, 0) = ff6e8fbd
sdlbmp(0, 0) = 6e90be

bitmap(31, 0) = ff6e8fbd
png(31, 0) = ff6e8fbd
sdlbmp(31, 0) = 6e90be

<snip remaining debug info>

NOTE: ff6e8fbd = R(110) G(143) B(189)
The actual pixel value is 110, 144, 190. SDL_LoadBMP gets it right in both
cases, whereas IMG_Load (ImageIO backend) gets it wrong on both counts.

Apply revert-rev-292.patch:
  hg import revert-rev-292.patch

Rebuild test case, ensuring that we compile and **run** with the proper runtime
search paths for our patched SDL2_image library (I built mine using Xcode project files):

```sh
# man dyld (1)
DYLD_FRAMEWORK_PATH=<my_local_prefix_lib_path> ./sdl2_image-colorspace-fix
```

Comparison output of reference data with patched library:
(output in diag_main.txt, using test.bmp and test.png)

bitmap(0, 0) = ff6e90be
png(0, 0) = ff6e90be
sdlbmp(0, 0) = 6e90be

bitmap(31, 0) = ff6e90be
png(31, 0) = ff6e90be
sdlbmp(31, 0) = 6e90be

<snip remaining debug info>

NOTE: ff6e90be = R(110) G(144) B(190)
The actual pixel values match using both SDL_LoadBMP and IMG_Load. This is the
expected behavior.

  References
1. [Introduction of ImageIO backend](https://forums.libsdl.org/viewtopic.php?p=14777)
2. [Pixel bug in Mac OS X](https://forums.libsdl.org/viewtopic.php?p=30317)
3. [Perhaps again? Pixel bug in Mac OS X](https://forums.libsdl.org/viewtopic.php?t=10013&sid=34e8ef7cf74074039495037c1a077025)
Fixed bug 2795 - SDL library detection selects the wrong lib

Chris Beck

When creating a homebrew recipe for wesnoth, I discovered that the SDL image configuration routine does not detect libpng properly -- if you have multiple instances of libpng on your system, and you use environment variables to select an instance which is not in your system directory, the build can be broken, because it will run configuration tests against the system installed version, but deduce that it should use the filename of the system-installed version. In a vanilla build of wesnoth using homebrew, this results in segfaults at runtime, because you end up linking against two different versions of libpng, which is also needed independently of SDL.

The problem is essentially in the "find_lib" routine in the configure file:



find_lib()
{
    gcc_bin_path=[`$CC -print-search-dirs 2>/dev/null | fgrep programs: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'`]
    gcc_lib_path=[`$CC -print-search-dirs 2>/dev/null | fgrep libraries: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'`]
    env_lib_path=[`echo $LIBS $LDFLAGS | sed 's/-L[ ]*//g'`]
    for path in $gcc_bin_path $gcc_lib_path $env_lib_path /usr/lib /usr/local/lib; do
        lib=[`ls -- $path/$1 2>/dev/null | sort -r | sed 's/.*\/\(.*\)/\1/; q'`]
        if test x$lib != x; then
            echo $lib
            return
        fi
    done
}



Because the for loop goes over the system directories before the environment directories, any system-installed lib will shadow the lib selected via environment variables. This is contrary to the behavior of the configuration tests earlier in the script, which prefers the environment variable libs over the system-installed libs. The 'for' loop should instead be:



    for path in $env_lib_path $gcc_bin_path $gcc_lib_path /usr/lib /usr/local/lib; do



You can see the full discussion on the Homebrew / linuxbrew issue tracker here: https://github.com/Homebrew/linuxbrew/issues/172

I have checked that this bug also affects SDL 1.2.15, SDL_mixer and SDL_ttf 1.2, which all use this same "find_lib" routine. I have not determined if the bug affects SDL 2.0, which seems not to use this exact routine.