luckylambonie / stb-imv

Automatically exported from code.google.com/p/stb-imv
GNU General Public License v2.0
0 stars 0 forks source link

Enhancement: Use GDI+ to load images #4

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
This is probably a better place than the forum to post this:

Currently, stb(imv) uses stb-img and FreeImage to decode images. stb-img
doesn't handle all file types, and FreeImage requires an additional DLL to
be distributed with the app. Additionally, FreeImage has issues with
certain file types, including crash bugs on BMPs generated by Adobe Photoshop.

GDI+ should solve both of these issues. GDI+ is already distributed with
most versions of Windows, so it doesn't need to be redistributed.
Secondarily, GDI+ is probably more stable than FreeImage, should handle
more file types/variations, and probably doesn't crash.

Some additional requirements for implementation are:
1) The build shouldn't require a new Platform SDK (i.e. should build with
any version fo Visual Studio 6 or better)
2) Should be implemented in C (rather than C++).

The GDI+ DLL is actually a pure C DLL that exports an unsupported "flat"
API, and the supported C++ interface is transparently implemented in header
files. These header files essentially behave as documentation for the flat
API. It should be a trivial matter to first implement the functionality in
C++, replace it with the equivalent flat C calls, and then dynamically link
the C entry points.

The relevant methods are: GdipCreateBitmapFromFile, GdipBitmapLockBits
GdipBitmapUnlockBits, GdipDisposeImage, GdipGdiplusShutdown, GdiplusStartup.

Original issue reported on code.google.com by wonchun on 17 Jul 2007 at 8:53

GoogleCodeExporter commented 9 years ago
This would be very nice. (I think the issue is not that we want
to avoid C++ as stated in (2), but that (3) we want to use LoadLibrary,
which pretty much requires using that flat API, and certainly
the combination of (3) and (1) suggests there's no benefit to C++.)

Original comment by nothings...@gmail.com on 18 Jul 2007 at 12:23

GoogleCodeExporter commented 9 years ago
The OleLoadPicture method might be an easy way to accomplish something similar, 
but
it doesn't support PNG.

http://www.arstdesign.com/articles/picloader.html
http://msdn2.microsoft.com/en-us/library/ms693724.aspx

Original comment by wonchun on 23 Jul 2007 at 12:27

GoogleCodeExporter commented 9 years ago
Attached is an incomplete, proof-of-concept for loading images in Gdiplus (i.e. 
not
integration-ready, but try-out-able). It is a patch off of revision 71.

In addition to the modifications necessary to get the thing working, I disabled 
the
command-line logging in DEBUG, and the standard stb_image loading.

Notable features:
 * Progressive JPEGs
 * Icons, GIF, TIFF

Missing features:
 * Red and Blue channels are swapped. Odd.
 * Gdiplus wants to make a thread. Bad Gdiplus.
 * No resource management (leaks everything)
 * No error checking
 * Forces an 32-bit alpha pixel format.

I'll address these issues tomorrow. There is a way, for example, to suppress the
Gdiplus thread, but it wasn't worth doing immediately. What do you think the 
best way
to deal with the color swapping?

Original comment by wonchun on 30 Jul 2007 at 10:38

Attachments:

GoogleCodeExporter commented 9 years ago
OK, looks like I have something reasonable to merge. Using Sean's test images, 
it
looks like GDI+ doesn't crash on all of the files, but doesn't successfully 
load them
all either.

Red/Blue swap is fixed by threading a "swap_br" flag through some image loading
calls, so GDI+ image loading doesn't require the swap in make_image. Although I
haven't tested it, neither should FreeImage.

Gdiplus still is making that thread. Dealing with these hook/unhook functions 
will
require some experimentation.

Stuff should be getting freed properly, now, with the exception of the Gdiplus
startup token (but that is hardly a leak, since it's lifetime is for the 
duration of
the program). As an aside, there appears to be a fair deal of redundancy 
between the
image loading and make_image since there is a bunch of memcpys going on. It 
might be
nice to pare that down a bit. Now that I understand what's going on, maybe I can
refactor it, maybe even into a different file. For example, if struct Image had 
a
"dipose" callback, then the loading library could be responsible for freeing 
images
that it loaded, potentially avoiding the copy.

Errors are checked, but they could be handled/logged better. TBD.

I haven't extensively tested the 24/32-bit PixelFormat code, but it appears to 
work
in my test cases.

Original comment by wonchun on 31 Jul 2007 at 12:19

Attachments:

GoogleCodeExporter commented 9 years ago
Fixed, closed.

Original comment by nothings...@gmail.com on 14 Aug 2007 at 5:55