diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt
index 21b76ce5d49efc0715e4a3bb9da4db80c1c0ac6e..30e92c355c7be0a4ccc959d15e585088d8b5a7f6 100755
--- a/Utilities/CMakeLists.txt
+++ b/Utilities/CMakeLists.txt
@@ -4,6 +4,10 @@ IF(NOT OTB_USE_EXTERNAL_ITK)
 	SUBDIRS( ITK )
 ENDIF(NOT OTB_USE_EXTERNAL_ITK)
 
+IF(NOT OTB_USE_EXTERNAL_FLTK)
+	SUBDIRS( FLTK )
+ENDIF(NOT OTB_USE_EXTERNAL_FLTK)
+
 SUBDIRS(BGL otbsvm dxflib InsightJournal otbossim otb6S otbgeotiff)
 
 IF(BUILD_TESTING)
diff --git a/Utilities/FLTK/.cvsignore b/Utilities/FLTK/.cvsignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b7eb8a9dc42b664d8e98fdbe15e3fc18b37d637
--- /dev/null
+++ b/Utilities/FLTK/.cvsignore
@@ -0,0 +1,9 @@
+config.cache
+config.h
+config.log
+config.status
+configure
+fltk-config
+fltk.list
+makeinclude
+*.bck
diff --git a/Utilities/FLTK/ANNOUNCEMENT b/Utilities/FLTK/ANNOUNCEMENT
new file mode 100644
index 0000000000000000000000000000000000000000..5f67d25c7a2adebfc284039968ca61d03fa95d14
--- /dev/null
+++ b/Utilities/FLTK/ANNOUNCEMENT
@@ -0,0 +1,349 @@
+The FLTK Team is proud to announce the release of FLTK 1.1.7,
+a cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11),
+Microsoft(r) Windows(r), and MacOS(r) X. FLTK provides
+modern GUI functionality without the bloat and supports 3D
+graphics via OpenGL(r) and its built-in GLUT emulation.
+
+FLTK 1.1.7 fixes many bugs, adds some new example programs, and
+adds many new improvements to the FLUID software including
+multi-level undo, syntax highlighting in all code fields, widget
+alignment and sizing guides, dialog templates, widget subclasses,
+and printing and testing of user interfaces within FLUID.
+
+FLTK is provided under the GNU Library Public License with
+exceptions that allow for static linking.
+
+Changes since FLTK 1.1.6 include:
+
+	- Added Fl::screen_count() and Fl::screen_xywh() APIs to
+	  support multi-screen displays.
+	- Added Greg Ercolano's simple Fl_Input_Choice widget
+	  which is a combination of the Fl_Input and
+	  Fl_Menu_Button widgets (STR #650)
+	- Added many new FLUID features: syntax highlighting,
+	  multi-level undo, templates, comments, live code view,
+	  live UI test, alignment/sizing guides, printing, and
+	  widget subclassing!
+	- Documentation fixes (STR #571, STR #648, STR #692, STR
+	  #730, STR #744, STR #745, STR #931, STR #942, STR #960,
+	  STR #969)
+	- Build system fixes (STR #636, STR #638, STR #645, STR
+	  #724, STR #774, STR #863, STR #893, STR #926, STR #972,
+	  STR #995, STR #996, STR #997, STR #1087, STR #1123)
+	- fltk-config fixes (STR #840, STR #868, STR #869)
+	- Threading fixes (STR #1138)
+	- X11 fixes (STR #711, STR #933, STR #1012)
+	- MacOS fixes (STR #602, STR #662, STR #765, STR #804,
+	  STR #905, STR #908, STR #968, STR #1099)
+	- WIN32 fixes (STR #647, STR #726, STR #821, STR #828,
+	  STR #831, STR #848, STR #862, STR #905, STR #961, STR
+	  #968, STR #1007, STR #1019, STR #1079, STR #1104)
+	- Drawing API fixes (STR #837, STR #924, STR
+	  #1052)
+	- Filename handling fixes (STR #741, STR #816, STR #854,
+	  STR #874)
+	- Plastic scheme fixes (STR #769, STR #841, STR #852, STR
+	  #906)
+	- Image class fixes (STR #632, STR #652, STR #676, STR
+	  #739, STR #825, STR #914, STR #915, STR #918)
+	- FLUID fixes (STR #668, STR #701, STR #718, STR #742,
+	  STR #776, STR #783, STR #784, STR #790, STR #791, STR
+	  #798, STR #799, STR #850, STR #851, STR #873, STR #879,
+	  STR #891, STR #904, STR #912, STR #959, STR #964, STR
+	  #979, STR #984, STR #999, STR #1129)
+	- Example program fixes (STR #777, STR #809, STR #843,
+	  STR #867, STR #909)
+	- Fl_Widget fixes (STR #643, STR #707, STR #860, STR
+	  #910)
+	- Browser widget fixes (STR #681, STR #729, STR #786, STR
+	  #834, STR #839, STR #967)
+	- Fl_Chart would draw outside its bounding box (STR #780)
+	- Fl_Clock_Output::value() did not return the previously
+	  set value (STR #748)
+	- Fl_File_Chooser fixes (STR #653, STR #654, STR #746,
+	  STR #747, STR #766, STR #770, STR #811, STR #819, STR
+	  #884, STR #958, STR #970)
+	- Fl_Help_View fixes (STR #631, STR #768, STR #815, STR
+	  #871, STR #998)
+	- Input widget fixes (STR #727, STR #836, STR #903, STR
+	  #941, STR #981)
+	- Menu widget fixes (STR #637, STR #651, STR #685, STR
+	  #704, STR #706, STR #740, STR #781, STR #795, STR #973,
+	  STR #1140, STR #1143, STR #1144)
+	- Fl_Preferences fixes (STR #720, STR #872, STR #1025)
+	- Fl_Scrollbar didn't compute the correct knob size when
+	  using the "nice" types (STR #845)
+	- Fl_Tabs fixes (STR #870, STR #882)
+	- Fl_Text_Display/Editor fixes (STR #635, STR #762, STR
+	  #915, STR #1069, STR #1122)
+	- Valuator widget fixes (STR #911, STR #971, STR #1037)
+	- Window widget fixes (STR #641, STR #723, STR #886, STR
+	  #898)
+	- FL_SHADOW_BOX/FRAME drew outside of the bounding box
+	  (STR #694)
+	- Fl::delete_widget would hang fl_wait() after deleting the
+	  window (STR #679)
+	- Fl::event_number() didn't always match the value sent
+	  to the handle() method (STR #634)
+	- Fl::paste() would sometimes not recoginze external 
+	  changes of the clipboard (STR #722)
+	- Fixed fl_message() code so that it does not get
+	  accidentaly addded to the current group (STR #253)
+	- The keyboard shortcut handling code did not handle
+	  8-bit characters properly (STR #731)
+
+----HTML----
+
+<P>The FLTK Team is proud to announce the release of FLTK 1.1.7,
+a cross-platform C++ GUI toolkit for UNIX&reg;/Linux&reg; (X11),
+Microsoft&reg; Windows&reg;, and MacOS&reg; X. FLTK provides
+modern GUI functionality without the bloat and supports 3D
+graphics via OpenGL&reg; and its built-in GLUT emulation.
+
+<P>FLTK 1.1.7 fixes many bugs, adds some new example programs, and
+adds many new improvements to the FLUID software including
+multi-level undo, syntax highlighting in all code fields, widget
+alignment and sizing guides, the ability to create widget
+subclasses, and the ability to print and test your user
+interfaces within FLUID.
+
+<P>FLTK is provided under the GNU Library Public License with
+exceptions that allow for static linking.
+
+<P>Changes since FLTK 1.1.6 include:
+
+<UL>
+
+	<li>Added Fl::screen_count() and Fl::screen_xywh() APIs to
+	support multi-screen displays.</li>
+
+	<li>Added Greg Ercolano's simple Fl_Input_Choice widget
+	which is a combination of the Fl_Input and Fl_Menu_Button
+	widgets (<a href='str.php?L650'>STR #650</a>)</li>
+
+	<li>Added many new FLUID features: syntax highlighting,
+	multi-level undo, templates, comments, live code view,
+	live UI test, alignment/sizing guides, printing, and
+	widget subclassing!</li>
+
+	<li>Documentation fixes (<a href='str.php?L571'>STR
+	#571</a>, <a href='str.php?L648'>STR #648</a>, <a
+	href='str.php?L692'>STR #692</a>, <a
+	href='str.php?L730'>STR #730</a>, <a
+	href='str.php?L744'>STR #744</a>, <a
+	href='str.php?L745'>STR #745</a>, <a
+	href='str.php?L931'>STR #931</a>, <a
+	href='str.php?L942'>STR #942</a>, <a
+	href='str.php?L960'>STR #960</a>, <a
+	href='str.php?L969'>STR #969</a>)</li>
+
+	<li>Build system fixes (<a href='str.php?L636'>STR
+	#636</a>, <a href='str.php?L638'>STR #638</a>, <a
+	href='str.php?L645'>STR #645</a>, <a
+	href='str.php?L724'>STR #724</a>, <a
+	href='str.php?L774'>STR #774</a>, <a
+	href='str.php?L863'>STR #863</a>, <a
+	href='str.php?L893'>STR #893</a>, <a
+	href='str.php?L926'>STR #926</a>, <a
+	href='str.php?L972'>STR #972</a>, <a
+	href='str.php?L995'>STR #995</a>, <a
+	href='str.php?L996'>STR #996</a>, <a
+	href='str.php?L997'>STR #997</a>, <a
+	href='str.php?L1087'>STR #1087</a>, <a
+	href='str.php?L1123'>STR #1123</a>)</li>
+
+	<li>fltk-config fixes (<a href='str.php?L840'>STR
+	#840</a>, <a href='str.php?L868'>STR #868</a>, <a
+	href='str.php?L869'>STR #869</a>)</li>
+
+	<li>Threading fixes (<a href='str.php?L1138'>STR
+	#1138</a>)</li>
+
+	<li>X11 fixes (<a href='str.php?L711'>STR #711</a>, <a
+	href='str.php?L933'>STR #933</a>, <a href='str.php?L1012'>STR
+	#1012</a>)</li>
+
+	<li>MacOS fixes (<a href='str.php?L602'>STR #602</a>, <a
+	href='str.php?L662'>STR #662</a>, <a
+	href='str.php?L765'>STR #765</a>, <a
+	href='str.php?L804'>STR #804</a>, <a
+	href='str.php?L905'>STR #905</a>, <a
+	href='str.php?L908'>STR #908</a>, <a
+	href='str.php?L968'>STR #968</a>, <a
+	href='str.php?L1099'>STR #1099</a>)</li>
+
+	<li>WIN32 fixes (<a href='str.php?L647'>STR #647</a>, <a
+	href='str.php?L726'>STR #726</a>, <a
+	href='str.php?L821'>STR #821</a>, <a
+	href='str.php?L828'>STR #828</a>, <a
+	href='str.php?L831'>STR #831</a>, <a
+	href='str.php?L848'>STR #848</a>, <a
+	href='str.php?L862'>STR #862</a>, <a
+	href='str.php?L905'>STR #905</a>, <a
+	href='str.php?L961'>STR #961</a>, <a
+	href='str.php?L968'>STR #968</a>, <a
+	href='str.php?L1007'>STR #1007</a>, <a
+	href='str.php?L1019'>STR #1019</a>, <a
+	href='str.php?L1079'>STR #1079</a>, <a
+	href='str.php?L1104'>STR #1104</a>)</li>
+
+	<li>Drawing API fixes (<a href='str.php?L837'>STR
+	#837</a>, <a href='str.php?L924'>STR #924</a>, <a
+	href='str.php?L1052'>STR #1052</a>)</li>
+
+	<li>Filename handling fixes (<a href='str.php?L741'>STR
+	#741</a>, <a href='str.php?L816'>STR #816</a>, <a
+	href='str.php?L854'>STR #854</a>, <a
+	href='str.php?L874'>STR #874</a>)</li>
+
+	<li>Plastic scheme fixes (<a href='str.php?L769'>STR
+	#769</a>, <a href='str.php?L841'>STR #841</a>, <a
+	href='str.php?L852'>STR #852</a>, <a
+	href='str.php?L906'>STR #906</a>)</li>
+
+	<li>Image class fixes (<a href='str.php?L632'>STR
+	#632</a>, <a href='str.php?L652'>STR #652</a>, <a
+	href='str.php?L676'>STR #676</a>, <a
+	href='str.php?L739'>STR #739</a>, <a
+	href='str.php?L825'>STR #825</a>, <a
+	href='str.php?L914'>STR #914</a>, <a
+	href='str.php?L915'>STR #915</a>, <a
+	href='str.php?L918'>STR #918</a>)</li>
+
+	<li>FLUID fixes (<a href='str.php?L668'>STR #668</a>, <a
+	href='str.php?L701'>STR #701</a>, <a
+	href='str.php?L718'>STR #718</a>, <a
+	href='str.php?L742'>STR #742</a>, <a
+	href='str.php?L776'>STR #776</a>, <a
+	href='str.php?L783'>STR #783</a>, <a
+	href='str.php?L784'>STR #784</a>, <a
+	href='str.php?L790'>STR #790</a>, <a
+	href='str.php?L791'>STR #791</a>, <a
+	href='str.php?L798'>STR #798</a>, <a
+	href='str.php?L799'>STR #799</a>, <a
+	href='str.php?L850'>STR #850</a>, <a
+	href='str.php?L851'>STR #851</a>, <a
+	href='str.php?L873'>STR #873</a>, <a
+	href='str.php?L879'>STR #879</a>, <a
+	href='str.php?L891'>STR #891</a>, <a
+	href='str.php?L904'>STR #904</a>, <a
+	href='str.php?L912'>STR #912</a>, <a
+	href='str.php?L959'>STR #959</a>, <a
+	href='str.php?L964'>STR #964</a>, <a
+	href='str.php?L979'>STR #979</a>, <a
+	href='str.php?L984'>STR #984</a>, <a
+	href='str.php?L999'>STR #999</a>, <a
+	href='str.php?L1129'>STR #1129</a>)</li>
+
+	<li>Example program fixes (<a href='str.php?L777'>STR
+	#777</a>, <a href='str.php?L809'>STR #809</a>, <a
+	href='str.php?L843'>STR #843</a>, <a
+	href='str.php?L867'>STR #867</a>, <a
+	href='str.php?L909'>STR #909</a>)</li>
+
+	<li>Fl_Widget fixes (<a href='str.php?L643'>STR #643</a>,
+	<a href='str.php?L707'>STR #707</a>, <a
+	href='str.php?L860'>STR #860</a>, <a
+	href='str.php?L910'>STR #910</a>)</li>
+
+	<li>Browser widget fixes (<a href='str.php?L681'>STR
+	#681</a>, <a href='str.php?L729'>STR #729</a>, <a
+	href='str.php?L786'>STR #786</a>, <a
+	href='str.php?L834'>STR #834</a>, <a
+	href='str.php?L839'>STR #839</a>, <a
+	href='str.php?L967'>STR #967</a>)</li>
+
+	<li>Fl_Chart would draw outside its bounding box (<a
+	href='str.php?L780'>STR #780</a>)</li>
+
+	<li>Fl_Clock_Output::value() did not return the
+	previously set value (<a href='str.php?L748'>STR
+	#748</a>)</li>
+
+	<li>Fl_File_Chooser fixes (<a href='str.php?L653'>STR
+	#653</a>, <a href='str.php?L654'>STR #654</a>, <a
+	href='str.php?L746'>STR #746</a>, <a
+	href='str.php?L747'>STR #747</a>, <a
+	href='str.php?L766'>STR #766</a>, <a
+	href='str.php?L770'>STR #770</a>, <a
+	href='str.php?L811'>STR #811</a>, <a
+	href='str.php?L819'>STR #819</a>, <a
+	href='str.php?L884'>STR #884</a>, <a
+	href='str.php?L958'>STR #958</a>, <a
+	href='str.php?L970'>STR #970</a>)</li>
+
+	<li>Fl_Help_View fixes (<a href='str.php?L631'>STR
+	#631</a>, <a href='str.php?L768'>STR #768</a>, <a
+	href='str.php?L815'>STR #815</a>, <a
+	href='str.php?L871'>STR #871</a>, <a
+	href='str.php?L998'>STR #998</a>)</li>
+
+	<li>Input widget fixes (<a href='str.php?L727'>STR
+	#727</a>, <a href='str.php?L836'>STR #836</a>, <a
+	href='str.php?L903'>STR #903</a>, <a
+	href='str.php?L941'>STR #941</a>, <a
+	href='str.php?L981'>STR #981</a>)</li>
+
+	<li>Menu widget fixes (<a href='str.php?L637'>STR
+	#637</a>, <a href='str.php?L651'>STR #651</a>, <a
+	href='str.php?L685'>STR #685</a>, <a
+	href='str.php?L704'>STR #704</a>, <a
+	href='str.php?L706'>STR #706</a>, <a
+	href='str.php?L740'>STR #740</a>, <a
+	href='str.php?L781'>STR #781</a>, <a
+	href='str.php?L795'>STR #795</a>, <a
+	href='str.php?L973'>STR #973</a>, <a
+	href='str.php?L1140'>STR #1140</a>, <a
+	href='str.php?L1143'>STR #1143</a>, <a
+	href='str.php?L1144'>STR #1144</a>)</li>
+
+	<li>Fl_Preferences fixes (<a href='str.php?L720'>STR
+	#720</a>, <a href='str.php?L872'>STR #872</a>, <a
+	href='str.php?L1025'>STR #1025</a>)</li>
+
+	<li>Fl_Scrollbar didn't compute the correct knob size
+	when using the "nice" types (<a href='str.php?L845'>STR
+	#845</a>)</li>
+
+	<li>Fl_Tabs fixes (<a href='str.php?L870'>STR #870</a>,
+	<a href='str.php?L882'>STR #882</a>)</li>
+
+	<li>Fl_Text_Display/Editor fixes (<a
+	href='str.php?L635'>STR #635</a>, <a
+	href='str.php?L762'>STR #762</a>, <a
+	href='str.php?L915'>STR #915</a>, <a
+	href='str.php?L1069'>STR #1069</a>, <a
+	href='str.php?L1122'>STR #1122</a>)</li>
+
+	<li>Valuator widget fixes (<a href='str.php?L911'>STR
+	#911</a>, <a href='str.php?L971'>STR #971</a>, <a
+	href='str.php?L1037'>STR #1037</a>)</li>
+
+	<li>Window widget fixes (<a href='str.php?L641'>STR
+	#641</a>, <a href='str.php?L723'>STR #723</a>, <a
+	href='str.php?L886'>STR #886</a>, <a
+	href='str.php?L898'>STR #898</a>)</li>
+
+	<li>FL_SHADOW_BOX/FRAME drew outside of the bounding box
+	(<a href='str.php?L694'>STR #694</a>)</li>
+
+	<li>Fl::delete_widget would hang fl_wait() after deleting
+	the window (<a href='str.php?L679'>STR #679</a>)</li>
+
+	<li>Fl::event_number() didn't always match the value sent
+	to the handle() method (<a href='str.php?L634'>STR
+	#634</a>)</li>
+
+	<li>Fl::paste() would sometimes not recoginze external 
+	changes of the clipboard (<a href='str.php?L722'>STR
+	#722</a>)</li>
+
+	<li>Fixed fl_message() code so that it does not get
+	accidentaly addded to the current group (<a
+	href='str.php?L253'>STR #253</a>)</li>
+
+	<li>The keyboard shortcut handling code did not handle
+	8-bit characters properly (<a href='str.php?L731'>STR
+	#731</a>)</li>
+
+</UL>
diff --git a/Utilities/FLTK/CHANGES b/Utilities/FLTK/CHANGES
new file mode 100644
index 0000000000000000000000000000000000000000..ed0a33e60afa0dbc9cab55d441fe30e30bbfe467
--- /dev/null
+++ b/Utilities/FLTK/CHANGES
@@ -0,0 +1,3049 @@
+CHANGES IN FLTK 1.1.7
+
+	- Documentation fixes (STR #571, STR #648, STR #692, STR
+	  #730, STR #744, STR #745, STR #931, STR #942, STR #960,
+	  STR #969)
+	- Various menu widget fixes (STR #1140, STR #1143, STR
+	  #1144)
+	- The threads demo would display negative prime numbers
+	  on MacOS X; this appears to be a MacOS X bug, but we
+	  added a workaround to "fix" this (STR #1138)
+	- Fl::dnd() now sets the content type of the drag to
+	  "text/uri-list" when it sees the dragged text is
+	  composed of URIs.
+	- Fixed keyboard shortcut handling in FLUID and shortcut
+	  labeling in FLTK (STR #1129)
+	- Fixed include path for CMake build (STR #1123)
+	- Fixed unnecessary delay in WIN32 event handling 
+	  (STR #1104)
+	- Fixed handling of Ctrl-C in Fl_Text_Display (STR #1122)
+	- OS X Quartz version now draw a nice resize control (STR
+	  #1099)
+	- FLTK now enables large file support when available (STR
+	  #1087)
+	- Fl_Clock_Output depended on a time value that was the
+	  same as an unsigned long, which is incorrect for WIN64
+	  and VC++ 2005 (STR #1079)
+	- Fl_Text_Display::wrap_mode() would crash if no buffer
+	  was associated with the widget (STR #1069)
+	- Updated the default label and text colors of all widgets
+	  to use FL_FOREGROUND_COLOR instead of FL_BLACK (STR
+	  #1052)
+	- Fl::set_fonts() now works with Xft (STR #1012)
+	- Fl_Value_Input now uses the screen-absolute position
+	  instead of the window-relative position when dragging
+	  the value; this avoids some jumping conditions (STR
+	  #1037)
+	- Menus now pop up fully inside the screen if possible
+	  (STR #973)
+	- Fixed illegal access in Preferences (STR #1025)
+	- Fixed x-offset problem in Help_Widget (STR #998)
+	- Clipboard will persist if owner window is hidden (STR
+	  #1019)
+	- Fixed handling of Win32 Device Contexts (STR #1007)
+	- Fixed C++ style comments in C files (STR #997)
+	- Fixed signedness of scanf() argument (STR #996)
+	- Fixed cross-compiling problem (STR #995).
+	- FLUID now knows if a static callback is already
+	  declared in a class and won't declare it 'extern' (STR
+	  #776)
+	- Some actions in FLUID would not set the  "changed" flag
+	  (STR #984, STR #999)
+	- fl_filename_list now always appends a forward slash to
+	  directory names (STR #874)
+	- Multiline Input will update right if a space character is
+	  inserted in word wrap mode (STR #981)
+	- FLUID group labels redraw correctly (STR #959)
+	- FLUID now updates color of Fl_Tabs children (STR #979)
+	- FLUID now supports 'size_range()' (STR #851)
+	- FLUID selection boxes now synchronised (STR #964)
+	- fl_filename_list() now recognizes pathnames without
+	  trailing  slash as directions (STR #854)
+	- Fl_Text_Display now auto-scrolls in all 
+	  directions (STR #915)
+	- Borderless windows will not show in the taskbar anymore
+	  on X11 (STR #933)
+	- Fixed event_text() field on FL_DND_* event on 
+	  OS X and WIN32 (STR #968)
+	- The fltk-config utility now supports "--cc" and "--cxx"
+	  options to get the C and C++ compilers that were used
+	  to compile FLTK (STR #868)
+	- Fl_Valuator-derived widgets could show more digits than
+	  were necessary (STR #971)
+	- Fl_GIF_Image did not handle images with an incorrect
+	  number of data bits (STR #914)
+	- Fixed some plastic drawing artifacts (STR #906)
+	- Fl_Help_View now draws the box outside the scrollbars,
+	  like the other scrollable widgets (STR #871)
+	- The fltk-config script now handles invocation via a
+	  symlink (STR #869)
+	- Updated WIN32 cut/paste code to consistently handle DOS
+	  text (STR #961)
+	- Added shared library support for Cygwin and MingW (STR
+	  #893)
+	- Fl_File_Chooser did not implement the user_data()
+	  methods (STR #970)
+	- Compilation could fail if a previous installation of
+	  FLTK was in the same (non-standard) directory as an
+	  image library (STR #926)
+	- Fixed OSX compilation problems with non-HFS filesystems
+	  (STR #972)
+	- Problems with CMake on MinGW have been solved, thanks
+	  to Mr. "fltk.x0", who submitted the patch. (STR #863)
+	- Fixed memory leak in Fl_Check_Browser reported by
+	  "miguel2i". (STR #967)
+	- Fl_File_Input could draw in the wrong window (STR #958)
+	- WIN32: Internal WM_PAINT message now ignored (STR #831)
+	- Added Windows support for Fl_Window::xclass() (STR #848)
+	- Floating point input field allows characters from
+	  current locale (STR #903)
+	- Fixed integration of Fl_Input_Choice into FLUID (STR
+	  #879)
+	- New windows touching the right screen border would be 
+	  positioned all the way to the left (STR #898)
+	- Made pie drawing size for WIN32 and OS X the same as
+	  X11 (STR #905)
+	- Fixed OS X issue with OpenGL windows inside of Tabs
+	  (STR #602)
+	- FLUID Code Editor would occasionally not draw the last
+	  character in the buffer (STR #798)
+	- FLUID Declaration private flag fixed (STR #799)
+	- FLUID overlay now shows a seperate bounding box of
+	  selected items with correct handles and a dotted
+	  boundig box for all  labels (STR #790)
+	- Fixed left overhang of large chracters in Fl_Input_
+	  (STR #941)
+	- Fixed button resizing in File Chooser (STR #884)
+	- Fixed FLUID redraw issue (STR #912)
+	- Added 32bit BMP Image file format support (STR #918)
+	- Value Sliders would not receive focus when clicked on
+	  (STR #911)
+	- Added redraw of some widgets to show focus change (STR
+	  #910)
+	- Fl::set_font would not clear 'pretty' name (STR #902)
+	- Fixed unescaped '@' in fonts demo (STR #867)
+	- FLUID should not open the Display connection anymore if
+	  creating code only (STR #904)
+	- Improved hidden copy / ctor implementation (STR #860)
+	- Increased matrix stack depth and added over/underflow
+	  error (STR #924)
+	- Reverted Mac Carbon Clipping simplification that broke
+	  subwindow clipping (STR #908, SVN r4386)
+	- Fixed bitmap scaling code
+	- Fixed tiny memory leak (STR #878)
+	- Fixed hang on corrupt jpeg (STR #915)
+	- Fixed static allocation of font buffer in demo (STR #909)
+	- Added symbols 'refresh', 'reload', 'undo', and 'redo'.
+	- Fixed focus loss on Fl_Window:resize()
+	- Fl::delete_widget would hang fl_wait after deleting the
+	  window (STR #679)
+	- Fl::paste would sometimes not recoginze external 
+	  changes of the clipboard (STR #722)
+	- Clipping fixes for OSX
+	- Removed attempt to find items via 
+	  Fl_Menu_::find_item() in linked submenus
+	- FLUID interactive window resizing fixes (STR #873, 791)
+	- FLUID panel resize and alignment fixes (STR #891)
+	- Fl_Window::show(argc, argv) now sets the scheme before
+	  showing the window; this should eliminate any
+	  flickering between the standard and plastic schemes on
+	  startup (STR #886)
+	- Selected tabs are now drawn slightly larger than
+	  unselected tabs so they stand out more (STR #882)
+	- Round Plastic boxes now draw round (STR #841)
+	- FL_PLASTIC_DOWN_BOX drew with artifacts (STR #852)
+	- Changed initializations on WIN32 (STR #862)
+	- Fl_Preferences::getUserdataPath() didn't work for
+	  sub-groups (STR #872)
+	- Fixed some redraw issues on Windows XP.
+	- FLUID didn't set the initial size of widgets properly
+	  (STR #850)
+	- Fl_Tabs would steal focus away from its children on a
+	  window focus change (STR #870)
+	- filename_relative() now converts the current directory
+	  to forward slashes as needed on WIN32 (STR #816)
+	- Fl_File_Chooser::value() and ::directory() now handle
+	  paths with backslashes on WIN32 (STR #811)
+	- Added the standard rgb.txt file from X11 to the test
+	  directory, allowing all platforms to try the colbrowser
+	  demo (STR #843)
+	- Resizing of OpenGL subwindows was broken on OSX (STR #804)
+	- The fltk-config script now supports running from a
+	  source directory (STR #840)
+	- Fl_Browser_ didn't update the position properly when an
+	  item was deleted (STR #839)
+	- fl_contrast() now compares the luminosity of each color
+	  (STR #837)
+	- Fl_Input_ crashed on some platforms when wrapping
+	  international text characters (STR #836)
+	- Fixed some BMP images loading bugs (STR #825)
+	- Fl_File_Chooser now returns directory names with a
+	  trailing slash to avoid problems with relative
+	  filenames (STR #819)
+	- Fl_Help_View now supports the FONT and U elements (STR
+	  #815)
+	- OpenGL windows that were completely off-screen caused
+	  problems with some graphics cards on WIN32 (STR #831)
+	- Multiple screen support didn't work on Windows NT and
+	  95 (STR #821)
+	- Fl_Scrollbar didn't compute the correct knob size when
+	  using the "nice" types (STR #845)
+	- fl_draw() would segfault on WIN32 if no font was set;
+	  it now uses the default font (STR #828)
+	- Fl_Browser_ was calling the callback multiple times for
+	  a single selection change with FL_WHEN_CHANGED (STR
+	  #834)
+	- Added "filenew", "fileopen", "filesave", "filesaveas",
+	  and "fileprint" symbols with standard toolbar
+	  symbology.
+	- Updated Fl_Tabs to check the contrast of the label
+	  color against the tab background, and to highlight the
+	  top 5 lines of the tab pane with the selection color so
+	  that selected tabs stand out more.
+	- The example programs can now compile separate from the
+	  FLTK source distribution (STR #809)
+	- The example programs are now installed with the
+	  documentation (STR #809)
+	- Fixed the drawing of the Fl_Browser_ selection box (STR
+	  #786)
+	- Dropped Codewarrier project files and support.
+	- The FLTK string functions are now compiled in on all
+	  systems (STR #774)
+	- Fixed symbol demo label bug (STR #777)
+	- Fixed position of menu titles (STR #795)
+	- Added missing Fl_Window::copy_label() method.
+	- Fixed wrong tooltip in fluid (STR #784)
+	- Added zlib path to fluid (STR #783)
+	- Menus and other pop-up windows now obey screen
+	  boundaries on multi-screen displays (STR #781)
+	- Fl_Chart would draw outside its bounding box (STR #780)
+	- Added Fl::screen_count() and Fl::screen_xywh() APIs to
+	  support multi-screen displays.
+	- FLUID now supports direct creation of widget classes.
+	- Fl_File_Chooser now correctly handles multiple
+	  selections that are a mix of files and directories.
+	- Fl_File_Chooser no longer resets the type() when
+	  choosing a single file, and it now works when selecting
+	  multiple directories (STR #747)
+	- Fl_File_Icon::load_system_icons() now only loads 16x16
+	  and 32x32 icon images to improve startup performance.
+	- Pressing Enter in the file chooser when selecting a
+	  directory will choose that directory if it is currently
+	  shown (STR #746)
+	- Added a fl_file_chooser_ok_label() function to set the
+	  "OK" button label for the fl_file_chooser() and
+	  fl_dir_chooser() functions.
+	- Added Fl_File_Chooser::ok_label() methods to set the
+	  "OK" button label.
+	- The fl_ask() function is now deprecated since it does
+	  not conform to the FLTK Human Interface Guidelines.
+	- The Fl_File_Chooser window now properly resizes its
+	  controls (STR #766)
+	- The Fl_Help_Dialog window now properly resizes its
+	  controls (STR #768)
+	- The Fl_File_Chooser favorites window is now resizable
+	  (STR #770)
+	- Now provide FL_PLASTIC_ROUND_UP/DOWN_BOX box types
+	  which are used by the plastic scheme.
+	- FLUID windows that are resized through the widget panel
+	  now remain resizable by the window manager.
+	- Increased the size of the background image used by
+	  the plastic scheme to reduce the CPU load of redraws
+	  (STR #769)
+	- Fixed a syntax highlighting bug in the editor demo.
+	- Fl_Progress now contrasts the label color with the bar
+	  color, so labels will be readable at all times.
+	- fl_read_image() didn't use the right red, green, and
+	  blue masks on XFree86.
+	- Fixed Quickdraw drawing of 3 and 4 sided polygons (STR
+	  #765)
+	- Fixed fl_message() code so that it does not get
+	  accidentaly addded to the current group (STR #253)
+	- FLUID now highlights code in the widget callback and
+	  code editors.
+	- FLUID now supports printing of windows.
+	- Fixed inactive drawing of border, embossed, and
+	  engraved box types.
+	- Added Fl_Spinner widget (another combination of
+	  existing widgets in a header file)
+	- FLUID now provides support for UI templates.
+	- fl_not_clipped() incorrectly used the current window
+	  dimensions for gross clipping, which interfered with
+	  off-screen rendering.
+	- Fl_Window::draw() and Fl_Window::iconlabel() could leak
+	  memory if copy_label() was used on the window.
+	- fl_shortcut_label() now shows letter shortcuts in
+	  uppercase, e.g. "Ctrl+N" instead of "Ctrl+n" to be
+	  consistent with other toolkits.
+	- FLUID now provides unlimited undo/redo support.
+	- FLUID now provides an option to choose which scheme
+	  (default, none, plastic) to display.
+	- Fixed scheme background issue with windows in FLUID.
+	- In FLUID, new widgets are now created with the ideal
+	  size by default, and menu bars are positioned to use
+	  the entire width of the window.
+	- Added Layout/Widget Size submenu to select default
+	  label and text size (Tiny, Small, and Normal).
+	- Added Edit/Duplicate command to FLUID to duplicate the
+	  current selection.
+	- FLUID now tracks the current state of the widget bin
+	  and overlays.
+	- Now fill the widget image paths with relative
+	  filenames.
+	- Fixed frame drawing of Fl_Text_Display (STR #762)
+	- Fl_Clock_Output::value() did not return the previously
+	  set value (STR #748)
+	- Added comment type to FLUID. This is useful for
+	  generating copyright notices in the source and header
+	  files.
+	- Fl_Valuator would not format text output with decimal 
+	  point when the step value was fractional, but above 1.
+	- fl_filename_relative() didn't compare drive letters in
+	  a case-insensitive way (STR #741)
+	- Fixed menu item width calculations with symbols (STR
+	  #740)
+	- The keyboard shortcut handling code did not handle
+	  8-bit characters properly (STR #731)
+	- Fl_JPEG_Image could still crash an app with a corrupt
+	  JPEG file (STR #739)
+	- Using the layout alignment controls on a menu widget
+	  would cause FLUID to crash (STR #742)
+	- Added QNX bug workaround for menu handling (STR #704)
+	- Added Greg Ercolano's simple Fl_Input_Choice widget
+	  which is a combination of the Fl_Input and
+	  Fl_Menu_Button widgets (STR #650)
+	- Fl_Multiline_Input now scrolls the full height of the
+	  widget instead of 5 lines when the user presses PageUp
+	  or PageDown (STR #727)
+	- CMake build fixes (STR #724)
+	- Fl_Browser::swap() didn't handle redraws properly when
+	  the swapped lines had different heights (STR #729)
+	- FL_MOUSEWHEEL events are now sent first to the widget
+	  under the mouse pointer and then to the first widget
+	  which accepts them. This is similar to the way
+	  shortcut events are handled and is consistent with the
+	  way the mouse wheel is handled by other toolkits.
+	- Fl::wait() could block on WIN32 if the window was
+	  deleted via Fl::delete_widget() (STR #679)
+	- Fl_Preferences::RootNode did not find the user's home
+	  directory on some non-US versions of Windows (STR
+	  #720)
+	- Fl_Window::hide() didn't delete the current clipping
+	  region on WIN32, causing a GDI resource leak in some
+	  situations (STR #723)
+	- Removed a few warnings when compiling on OS X
+	- Fl_Menu now draws the arrow more like other toolkits
+	  and 2.0 (STR #651)
+	- Fixed a VC++ compiler error in Fl_JPEG_Image.cxx (STR
+	  #676)
+	- FL_SHADOW_BOX/FRAME drew outside of the bounding box
+	  (STR #694)
+	- Fl_Widget::copy_label(NULL) didn't work (STR #707)
+	- Fl_Choice now allows click selection like
+	  Fl_Menu_Button and Fl_Menubar (STR #706)
+	- Updated cmake support (STR #645)
+	- Fl_Check_Browser didn't draw properly when inactive
+	  (STR #681)
+	- Removed some redundant code in Fl_Group::handle() (STR
+	  #669)
+	- The file chooser didn't always deactivate the OK
+	  button when necessary (STR #653)
+	- Image drawing on OSX changed the current drawing
+	  colors (STR #662)
+	- Fixed some compiler errors on WIN32 (STR #647, STR
+	  #726)
+	- FLUID didn't update the widget panel X/Y/W/H values
+	  when moving the selected window (STR #701)
+	- FLUID didn't use the label type constant names for
+	  menu items, causing them to be drawn using the normal
+	  label type (STR #668)
+	- Fl_File_Chooser was slow with large directories (STR
+	  #654)
+	- FLUID didn't add xclass() calls to windows (STR #718)
+	- The X11 DND code did not correctly select a text
+	  format for incoming data (STR #711)
+	- Fixes to Fl_JPEG_Image error handler.
+	- Fl_Menu::popup() and ::pulldown() would crash an
+	  application if a callback created widgets before they
+	  returned (STR #685)
+	- Fl_Double_Window would cause a full redraw, even if
+	  only small parts of the UI were changed on Mac OS X.
+	- Fl_JPEG_Image did not correctly handle errors reported
+	  by the JPEG library (STR #652)
+	- Fl_Menu now draws sub-menu arrows like other toolkits
+	  and FLTK 2.0 (STR #651)
+	- Fixed a compiler warning in Fl_Window.H (STR #641)
+	- Tooltips disabled shortcut processing (STR #643)
+	- Fl::event_number() didn't always match the value sent
+	  to the handle() method (STR #634)
+	- Fl_Shared_Image::reload() didn't set the image_
+	  pointer properly in all cases (STR #632)
+	- Fl_Help_View::topline() incorrectly set the changed()
+	  flag (STR #631)
+	- Fl_Choice::value() now supports NULL or -1 to deselect
+	  the current item (STR #637)
+	- More VC++ 6 project file fixes (STR #638)
+	- Added missing Watcom makefile in the test directory
+	  (STR #636)
+	- Fl_Text_Display::word_left would hang if the cursor
+	  was at position 0 (STR #635)
+
+
+CHANGES IN FLTK 1.1.6
+
+	- Documentation updates (STR #552, STR #608)
+	- Added the 2.0 Fl_Widget::copy_label() method to
+	  allow FLTK 1.x applications to have their label
+	  strings managed by FLTK (STR #630)
+	- Added Fl::delete_widget() method to safely delete
+	  widgets in callback methods (STR #629)
+	- Fl_Widget::damage(uchar,int,int,int,int) didn't clip
+	  the bounding box properly (STR #626)
+	- Windows could appear on the wrong screen on OSX (STR
+	  #628)
+	- Fl_Double_Window produced an error on resize with X11
+	- FLUID didn't display menu items using images properly
+	  (STR #564)
+	- Fl_Sys_Menu_Bar didn't compile on case-sensitive
+	  file-systems (STR #622)
+	- FLUID didn't handle default function parameters
+	  properly (STR #579)
+	- Moving or resizing widgets in FLUID didn't always
+	  update the widget panel (STR #600)
+	- FLTK windows could appear off-screen on X11 (STR #586)
+	- The configure script did not support
+	  --disable-localfoo to completely disable image file
+	  support (STR #582)
+	- The Visual C++ 6.0 project files still listed the old
+	  JPEG, PNG, and ZLIB library names (STR #577)
+	- Fixed the scandir() conditional code for HP-UX 11i
+	  (STR #585)
+	- Fl_Text_Display didn't support CTRL/CMD-A/C (STR #601)
+	- Watcom fixes (STR #581, STR #584, STR #594, STR #595,
+	  STR #623, STR #627)
+	- Fixed library include order when building DSOs on
+	  MacOS X (STR #596)
+	- fl_xid() could cause a WIN32 application to crash (STR
+	  #560, STR #576, STR #618)
+	- Fl_Browser::remove_() removed the item from the list
+	  before computing the item height, which caused
+	  problems with some programs (STR #613)
+
+
+CHANGES IN FLTK 1.1.5
+
+	- Documentation updates (STR #568, STR #570)
+	- Shortcuts were incorrectly underlined in multi-line
+	  labels (STR #566)
+	- More CMake updates (STR #499)
+	- The Watcom C++ compiler needed a small change (STR
+	  #567)
+	- Added DESTDIR support and now remove all man pages for
+	  the "uninstall" target (STR #545)
+	- Fix PNG drawing on buggy WIN32 graphics cards (STR
+	  #548)
+	- The configure script didn't propagate the CPPFLAGS
+	  environment variable (STR #549)
+	- The numpad keys didn't work properly on WIN32 (STR
+	  #502)
+	- fl_input() and friends now set the input focus to the
+	  text field when the dialog is shown (STR #553)
+	- Fixed background color mixup when drawing Fl_Choice
+	  menus (STR #544)
+	- Fixed MingW makefiles (STR #550)
+	- More VC++ project file tweaking (STR #559)
+	- Fl_PNG_Image didn't use the png_set_trns_to_alpha
+	  function when available (STR #547)
+	- The FL_UNFOCUS event wasn't always sent when switching
+	  tabs (STR #558)
+
+
+CHANGES IN FLTK 1.1.5rc3
+
+	- Documentation updates (STR #505, STR #513)
+	- Updated PNG library source to 1.2.7.
+	- Updated ZLIB library source to 1.2.1.
+	- Fixed VC++ project file problems (STR #476, STR #478,
+	  STR #520, STR #527, STR #537)
+	- Now look for 8 bits of alpha when the developer has
+	  requested FL_RGB8 (STR #541)
+	- The last line in an Fl_Help_View widget was not
+	  aligned properly (STR #536)
+	- The "search" symbol looked like a Q (STR #536)
+	- Changed Fl_Help_View::get_color() to use a lookup
+	  table to avoid serious Borland C++ 5.5 compiler bugs
+	  (STR #533)
+	- Fixed Watcom compiler warnings with FL/Fl_Widget.H
+	  (STR #540)
+	- The image class copy() methods did not always make a
+	  separate copy of the image data (STR #539)
+	- Fixed an edge case in fl_old_shortcut() that could
+	  cause it to read beyond then end of the shortcut
+	  string (used for XForms named shortcuts)
+	- Added (unsupported) CMake files (STR #499)
+	- Tooltips would not reappear on the same widget, and
+	  the initial tooltip delay was not used after a tooltip
+	  was shown (STR #465)
+	- Fixed a compile problem with the Linux 2.6 threading
+	  support (STR #483)
+	- Fixed problems with 2-byte Xpm files on 64-bit
+	  platforms (STR #525)
+	- FLTK didn't handle the ReparentNotify event on X11
+	  (STR #524)
+	- The old source file "fl_set_gray.cxx" is not needed
+	  (STR #516)
+	- Fl_Text_Display still called delete[] instead of
+	  free() in one place (STR #503)
+	- The symbol test program did not handle the @+ symbol
+	  properly (STR #490)
+	- Fl_File_Chooser didn't correctly call isprint() and
+	  isspace() when checking to see if the current file was
+	  text that can be previewed (STR #517)
+	- FLUID didn't compile with Borland C++ due to a
+	  compiler bug (STR #496)
+	- Fl_Positioner did not handle reversed min and max
+	  values (STR #510)
+	- fl_descent(), fl_height(), and fl_width() would crash
+	  a program if you didn't call fl_font() first; they now
+	  return -1 if no font is set (STR #500)
+	- Added test/unittests to verify pixel drawing and 
+	  alignment across platforms
+	- Fl_Menu_::find_item() didn't determine the menu path
+	  properly (STR #481)
+	- The build system now installs image library header
+	  files in FL/images/filename.h so that FLTK programs
+	  will use the same header files as the FLTK image
+	  libraries.
+	- The build system now creates image libraries named
+	  "libfltk_name.a" instead of "libname.a" to avoid
+	  clobbering an existing installed library (STR #480)
+
+
+CHANGES IN FLTK 1.1.5rc2
+
+	- Documentation updates (STR #365, STR #399, STR #407,
+	  STR #412, STR #414, STR #452, STR #462)
+	- Fl_Text_Display did not handle drawing of overlapping
+	  text (italic next to plain, etc.) properly (STR #381)
+	- All of the core widgets now consistently set changed()
+	  before calling the callback function for a change in
+	  value; this allows programs to check the changed()
+	  state in a callback to see why they are being called
+	  (STR #475)
+	- Fl_File_Chooser did not handle some cases for filename
+	  completion (STR #376)
+	- Fl_Help_View didn't properly compute the default
+	  maximum width of the page properly, resulting in
+	  non-wrapped text in table cells (STR #464)
+	- Fl_Text_Editor no longer tries to emulate the Emacs
+	  CTRL-A shortcut to move to the first column, since
+	  there is a key for that and the widget does not
+	  emulate any other Emacs keys (STR #421)
+	- Fl_File_Chooser always disabled the OK button when the
+	  user pressed DELETE or BACKSPACE (STR #397)
+	- Added Fl_Browser::swap() methods (STR #459)
+	- Fl_Counter didn't use a thin down box for the text
+	  field if the box type was set to FL_THIN_UP_BOX (STR
+	  #467)
+	- Fl_Help_View now resets the scrollbars if they go
+	  outside the current view (STR #464)
+	- fl_dir_chooser() did not show the previous selection
+	  as documented (STR #443)
+	- Fl_Text_Display used delete[] instead of free() in
+	  some places (STR #466)
+	- FLTK now includes copies of the PNG, JPEG, and ZLIB
+	  libraries for platforms that do not have them (STR
+	  #441)
+	- The fltk-config script did not include the
+	  "-mno-cygwin" option under CygWin (STR #434)
+	- Fl_Help_View::find() did not check for a NULL value
+	  (STR #442)
+	- Added search symbol to the search field of
+	  Fl_Help_Dialog (STR #417)
+	- Added two new symbols, @search and @FLTK, which can be
+	  used in labels.
+	- MacOS X: fixed NumLock mixup, added support for
+	  FL_Menu and FL_Delete keys on external (PC) keyboards
+	  (STR #445)
+	- Fl_File_Icon::draw() did not support drawing of complex
+	  polygons in icon descriptions (STR #474)
+	- The configure script now offers options for JPEG, PNG,
+	  and ZLIB libraries (STR #416)
+	- The first menu item in a list would not go invisible 
+	  (STR #406)
+	- Fl_Text_Buffer::replace() now range checks its input
+	  (STR #385)
+	- FLTK now builds with the current release of MinGW (STR
+	  #325, STR #401, STR #402)
+	- FLTK now honors the numlock key state (STR #369)
+	- The Fl_Text_Display widget did not redraw selections
+	  when focus changed (STR #390)
+	- The plastic background image is now less contrasty
+	  (STR #394)
+	- Fl_Scroll now uses a full redraw when the scheme is
+	  set to plastic and the box type is a frame (STR #205)
+	- Fl_Window::resize() did not work properly with KDE 3.2
+	  (STR #356)
+	- FLTK didn't delete font bitmaps when the last OpenGL
+	  window was deleted, preventing future text from
+	  displaying (STR #310)
+	- FLUID didn't include a full initialization record for
+	  the trailing NULL menu items (STR #375)
+	- Fl_Browser::item_width() did not properly handle
+	  format modifiers (STR #372)
+	- Fl_Browser::item_height() did not handle columns
+	  properly (STR #371)
+	- Fl_Gl_Window's on WIN32 now prefer accelerated pixel
+	  formats over generic formats (STR #382)
+	- Fl_Window::resize() did not work on some systems if
+	  the window was not shown (STR #373)
+	- FLUID did not write the user_data type if the
+	  user_data field was empty (STR #374)
+	- The value(const Fl_Menu_Item*) method was not
+	  implemented for Fl_Choice (STR #366)
+        - Fl_Pack didn't draw child widget labels the same way
+          as Fl_Group, causing display problems (STR #360)
+        - fl_read_image() didn't work when reading from an
+          offscreen buffer with some X11 servers (STR #364)
+
+
+CHANGES IN FLTK 1.1.5rc1
+
+	- Documentation updates (STR #186, STR #245, STR #250,
+	  STR #277, STR #281, STR #328, STR #338)
+	- fl_scroll() did not handle scrolling from off-screen on
+	  WIN32 (STR #315)
+	- Fl_File_Chooser did not allow manual entry of a drive
+	  letter (STR #339)
+	- Fl_Menu now uses the boxtype to redraw the menu
+	  background (STR #204)
+	- Fl_Scroll now shows the background image when a framed
+	  box type is used and the Fl_Scroll is a direct
+	  decendent of a window (STR #205)
+	- Added a new_directory_tooltip string pointer to allow
+	  localization of the file chooser's new directory
+	  button (STR #340)
+	- Added Fl_Menu_::find_item() method (STR #316)
+	- The Fl_Widget copy operator definitions were not
+	  conditionally compiled properly (STR #329)
+	- FLUID's Layout functionality did not move child
+	  widgets when laying out group widgets (STR #319)
+	- FLUID's Layout->Center In Group functionality did not
+	  properly handle widgets that were children of a
+	  Fl_Window widget (STR #318)
+	- The Fl_Text_Display destructor did not remove the
+	  predelete callback associated with the current buffer
+	  (STR #332)
+	- Fixed several bugs in the MacOS X Fl::add_fd()
+	  handling (STR #333, STR #337)
+	- The Fl_Text_Display widget did not display selections
+	  set by the application (STR #322)
+	- FLUID crashed if you did layout with a window widget
+	  (STR #317)
+	- Fl_Scroll::clear() didn't remove the child widget from
+	  the Fl_Scroll widget (STR #327)
+	- Fl_Value_Slider::draw_bg() didn't always apply the
+	  clipping rectangle (STR #235)
+	- fl_filename_relative() returned the wrong string if
+	  the absolute pathname was equal to the current working
+	  directory (STR #224)
+	- Fl_Help_Dialog didn't correctly restore the scroll
+	  position when going forward/back in the link history
+	  if the file changed (STR #218)
+	- glutGetModifiers() did not mask off extra state bits,
+	  confusing some GLUT-based applications (STR #213)
+	- Fixed mouse capture problems on MacOS X (STR #209, STR
+	  #229)
+	- Fl_Sys_Menu_Bar is now built into the library for
+	  MacOS X (STR #229)
+	- Fl_Menu_ now provides item_pathname() methods to get
+	  the "pathname" of a menu item, e.g. "File/Quit" (STR
+	  #283)
+	- Fl_Text_Display now provides cursor_color() methods to
+	  get and set the cursor color (STR #271)
+	- Fl_Scroll didn't honor FL_NO_BOX (STR #305)
+	- FLUID declaration blocks didn't support public/private
+	  definitions (STR #301)
+	- Fl_Preferences incorrectly created the preferences
+	  directory before necessary (STR #247)
+	- The WIN32 project files still defined the (obsolete)
+	  FL_STATIC constant (STR #279)
+	- Fl_Text_Display::buffer() did not support NULL values,
+	  making it impossible to clean up text buffers from a
+	  subclass (STR #295)
+	- Fl_Text_Display did not support a NULL
+	  unfinishedStyleCB function (STR #241)
+	- Fl::background2() incorrectly marked the foreground
+	  color as initialized (STR #255)
+	- Fixed the X11 CTRL + "-" detection code to properly
+	  track the state of the CTRL key (STR #264)
+	- Fl_File_Icon::load_system_icons() didn't support KDE
+	  3.x (STR #299)
+	- WIN32's scandir() emulation did not allocate enough
+	  memory for directory names (STR #263)
+	- Fl::compose() did not handle special keys like
+	  backspace properly (STR #293)
+	- Fl_Choice did not clip its text when drawing using the
+	  plastic scheme (STR #287)
+	- Fl_Group incorrectly mapped the emacs CTRL keys to
+	  keyboard navigation (STR #228)
+	- Fl_File_Browser::load() didn't handle a NULL directory
+	  name (STR #266)
+	- 64-bit library fixes (STR #261)
+	- The Fl_Valuator::format() function did not limit the
+	  size of the number buffer (STR #268)
+	- The keypad Enter key works as the normal Enter/Return
+	  key in common widgets (STR #191)
+	- Fixed some OS/2-specific build problems (STR #185, STR
+	  #197)
+	- Calling Fl_Text_Display::buffer() with the same buffer
+	  would cause an application to lockup (STR #196)
+	- Some of the widgets could crash an application if the
+	  cursor was changed after a window was deleted (STR
+	  #181)
+	- The Fl_Gl_Window WIN32 pixel format code did not
+	  choose the pixel format with the largest depth buffer
+	  (STR #175)
+	- The configure script didn't leave space between the
+	  CFLAGS/CXXFLAGS and X_CFLAGS variables (STR #174)
+	- The Fl_JPEG_Image and Fl_PNG_Image classes did not
+	  trap errors from the corresponding image libraries
+	  (STR #168)
+	- Added "--with-links" configure option to control
+	  whether symlinks are created for the FLTK header files
+	  (STR #164)
+	- Added new hoverdelay() to Fl_Tooltip to control how
+	  quickly recent tooltips appear (STR #126)
+	- FLUID now sets the size range when a window is shown.
+	  This seems to be necessary with some window managers
+	  (STR #166)
+
+
+CHANGES IN FLTK 1.1.4
+
+	- The fl_read_image() function was not implemented on
+	  OSX (STR #161)
+	- VC++ 7.1 didn't like how the copy operators were
+	  disabled for the Fl_Widget class; now include inline
+	  code which will never be used but makes VC++ happy
+	  (STR #156)
+	- Fixed an IRIX compile problem caused by a missing
+	  #include (STR #157)
+	- FLUID didn't write color/selection_color() calls using
+	  the symbolic names when possible, nor did it cast
+	  integer colors to Fl_Color (STR #146)
+	- Fl_File_Chooser was very close for multiple file
+	  selection in large directories (STR #140)
+	- Fl_Text_Display/Editor did not disable the current
+	  selection when focus was shifted to another widget
+	  (STR #131)
+	- Fl_Choice didn't use the normal focus box when the
+	  plastic scheme was in use (STR #129)
+	- Fl_Text_Editor didn't use selection_color()
+	  consistently (STR #130)
+	- The fltk_forms, fltk_gl, and fltk_images DSO's and
+	  HP-UX shared libraries are now linked against the fltk
+	  shared library to provide complete dependency
+	  resolution (STR #118)
+	- The configure.in file did not work with autoconf 2.57.
+	- FLUID didn't redraw widgets when changing the X, Y, W,
+	  or H values in the widget panel (STR #120)
+	- Fl_Window::show(argc, argv) wasn't calling
+	  Fl::get_system_colors() as documented (STR #119)
+	- DSO (shared library) building wasn't quite right for
+	  some platforms (STR #118)
+	- OSX: some changes to make ProjectBuilder compiles
+	  possible.
+	- OSX: FLTK would not know where a window was positioned
+	  by the OS. As a result, popup menus could open at 
+	  wrong positions.
+
+
+CHANGES IN FLTK 1.1.4rc2
+
+	- Fl_Window::show(argc,argv) incorrectly opened the
+	  display prior to parsing the arguments; this prevented
+	  the "-display foo" option from working (STR #111)
+	- Images were not clipped properly on MacOS X (STR #114)
+	- Fl::reload_scheme() and Fl::scheme("foo") incorrectly
+	  called Fl::get_system_colors().  This prevented an
+	  application from setting its own color preferences
+	  (STR #115)
+	- The 'Enter' key event on OS X would not set
+	  Fl::e_text.
+	- Changed behaviour of fluid to always paste into
+	  a selected group (STR #88)
+	- Menuitem now changes font, even if fontsize
+	  is not set (STR #110)
+	- Swapped shortcut labels in OS X (STR #86)
+	- Non-square Fl_Dial would calculate angle from user
+	  input wrong (STR #101)
+	- Updated documentatiopn of fl_draw (STR #94)
+	  and Fl_Menu_::add() (STR #99)
+	- FLUID collapse triangle events were not offset by
+          horizontal scroll (STR #106)
+	- QuitAppleEvent now correctly returns from Fl::run()
+          instead of just exiting (STR #87)
+	- Hiding the first created OpenGL context was not
+	  possible. FLTK now manages a list of contexts (STR #77)
+	- FLUID didn't keep the double/single buffer type for
+	  windows.
+	- FLTK didn't work with Xft2.
+	- OSX window resizing didn't work (STR #64)
+	- Fixed MacOS X shared library generation (STR #51)
+	- Several widgets defined their own size() method but
+	  didn't provide an inline method that mapped to the
+	  Fl_Widget::size() method (STR #62)
+	- Fl_Scroll didn't provide its own clear() method, so
+	  calling clear() on a Fl_Scroll widget would also
+	  destroy the scrollbars (STR #75)
+	- Fl::event_text() was sometimes initialized to NULL
+	  instead of an empty string (STR #70)
+	- fl_draw() didn't properly handle a trailing escaped
+	  "@" character (STR #84)
+	- Added documentation for all forms of
+	  Fl_Widget::damage() (STR #61)
+	- Fl_Double_Window now has a type() value of
+	  FL_DOUBLE_WINDOW, to allow double-buffered windows to
+	  process redraws properly on WIN32 (STR #46)
+	- Added FL_DAMAGE_USER1 and FL_DAMAGE_USER2 damage bits
+	  for use by widget developers (STR #57)
+	- Fl_Help_View didn't support numeric character entities
+	  (STR #66)
+	- Menu shortcuts didn't use the Mac key names under
+	  MacOS X (STR #71)
+	- CodeWarrior Mac OS X updated to work with current
+	  CW8.3 (STR #34)
+	- Apple-C/X/V/Z didn't work in the Fl_Input widget due
+	  to a bad mapping to control keys (STR #79)
+	- Added the OSX-specific fl_open_callback() function to
+	  handle Open Documents messages from the Finder (STR
+	  #80)
+	- The configure script contained erroneous whitespace in
+	  various tests which caused errors on some platforms
+	  (STR #60)
+	- The fltk-config script still supported the deprecated
+	  --prefix and --exec-prefix options; dropped them since
+	  they serve no useful purpose and would never have
+	  worked for the intended purpose anyways... (STR #56)
+	- fl_filename_list returned 0 on Win32 if no directory
+	  existed (STR #54)
+	- Pressing 'home' after the last letter in a Text_Editor
+	  would move the cursor to pos 0 (STR #39)
+	- Fl::get_key(x) would mix up Ctrl and Meta on OS X (STR
+	  #55)
+	- The configure script used the wrong dynamic library
+	  linking command for OSX (STR #51)
+	- The Fl_Text_Editor widget did not set changed() nor
+	  did it call the widget's callback function for
+	  FL_WHEN_CHANGED when processing characters that
+	  Fl::compose() handles (STR #52)
+
+
+CHANGES IN FLTK 1.1.4rc1
+
+	- The file chooser did not reset the click count when
+	  changing directories; if you clicked on a file in the
+	  same position after changing directories with a
+	  double-click, the chooser treated it as a triple
+	  click (STR #27)
+	- Symbols with outlines did not get drawn inactive.
+	- The Fl_Help_View widget now provides a find() method
+	  to search for text within the page.
+	- The Fl_Help_Dialog widget now provides a search box
+	  for entering text to search for.
+	- The default font encoding on OSX did not match the
+	  default on WIN32 or X11.
+	- Menu items were not drawn using the font specified in
+	  the Fl_Menu_Item structure (STR #30)
+	- Long menus that were aligned such that the top of an
+	  item was exactly at the top of the screen would not
+	  scroll (STR #33)
+	- The OS issues appendix incorrectly stated that MacOS
+	  8.6 and 9 were supported; they are not (STR #28)
+	- Fixed handling of nested double-buffered windows (STR
+	  #1)
+	- Showing a subwindow inside a hidden window would crash
+	  the application (STR #23)
+	- OSX users couldn't enter some special chars when using
+	  some foreign key layouts (STR #32)
+	- Hiding subwindows on OSX would hide the parent window
+	  (STR #22)
+	- Added thin plastic box types.
+	- Fl_Pack ignored the box() setting and cleared any
+	  unused areas to the widget color; it now only does so
+	  if the box() is set to something other than FL_NO_BOX.
+	- Updated the Fl_Tabs widget to offset the first tab by
+	  the box dx value to avoid visual errors.
+	- Updated the plastic up box to draw only a single
+	  border frame instead of the old double one for
+	  improved appearance.
+	- Updated the default background color on OSX to provide
+	  better contrast.
+	- Fl_Text_Display and friends now look for the next
+	  non-punctuation/space character for word boundaries
+	  (STR #26)
+	- gl_font() didn't work properly for X11 when Xft was
+	  used (STR #12)
+	- Fl_File_Browser incorrectly included "." on WIN32 (STR
+	  #9)
+	- Include shellapi.h instead of ShellAPI.h in the WIN32
+	  drag-n-drop code in order to work with the MingW cross
+	  compiler (STR #6)
+	- The cursor was not properly restored when doing
+	  drag-n-drop on X11 (STR #4)
+	- Fl::remove_fd() didn't recalculate the highest file
+	  descriptor properly (STR #20)
+	- Fl_Preferences::deleteGroup() didn't work properly
+	  (STR #13)
+	- Fixed the fl_show_file_selector() function - it was
+	  copying using the wrong string size (STR #14)
+	- fl_font() and fl_size() were not implemented on MacOS
+	  X.
+	- Sorted the icon menu bar in fluid.
+	- Fixed minor memory access complaints from Valgrind
+	- Compiling src/flstring.h on OS X with BSD header would
+	  fail.
+	- Fl_Text_Editor didn't scroll the buffer when the user
+	  pressed Ctrl+End or Ctrl+Home.
+	- Fl_Text_Editor didn't show its cursor when the mouse
+	  was moved inside the window.
+	- FLUID now uses an Fl_Text_Display widget for command
+	  output, which allows you to copy and paste text from
+	  command output into other windows.
+	- Fl_Gl_Window could cause a bus error on MacOS X if the
+	  parent window was not yet shown.
+	- FLUID could crash after displaying a syntax error
+	  dialog for the callback code.
+	- FLUID would reset the callback code if you opened the
+	  widget panel for multiple widgets.
+	- Added a NULL check to Fl_Text_Display (SF Bug #706921).
+	- The fltk-config script placed the LDFLAGS at the wrong
+	  place in the linker options.
+	- Fl_Text_Display didn't draw the outer box in the right
+	  dimensions, so it was invisible.
+	- Fl_Help_Dialog used the same color for links as for
+	  the background, causing links to be invisible on pages
+	  without a background color set.
+
+
+CHANGES IN FLTK 1.1.3
+
+	- Documentation updates.
+	- FLTK now ignores KeyRelease events when X11 sends them
+	  for repeating keys.
+	- FLUID now supports up to two additional qualifiers
+	  before a class name (FL_EXPORT, etc.) to aide in
+	  developing DLL interfaces for WIN32.
+	- Additional NULL checks in Fl_Button,
+	  fl_draw_boxtype(), Fl_File_Chooser, and
+	  Fl_Window::hotspot().
+	- The Fl_Preferences header file needed to FL_EXPORT all
+	  of the nested classes for WIN32.
+	- Fl_Double_Window couldn't be nested on WIN32. [SF Bug
+	  #658219]
+	- Fl_Slider didn't call the callback function when the
+	  user changed the value using the keyboard and the
+	  "when" condition was FL_WHEN_RELEASE. [SF Bug #647072]
+	- Lines with less than 2 unique vertices and polygons
+	  with less the 3 unique vertices were not drawn
+	  properly. [SF Bug #647067]
+	- The size_range() values were not honored under MacOS
+	  X. [SF Bug #647074]
+	- OpenGL windows didn't resize correctly on MacOS X.
+          [SF Bug #667855]
+	- The menus incorrectly used the overlay visual when one
+	  or more menu items contained an image. [SF Bug #653846]
+	- Changed some error messages to use Fl::error() instead
+	  of fprintf()...
+	- Fl_Text_Buffer and Fl_Text_Display used free to free
+	  memory that was allocated using the new operator.
+	- Tweeked the plastic scheme under MacOSX to better
+	  match the colors.
+	- The Fl_Image.H always included the x.H header file,
+	  which included many system headers that could
+	  interfere with normal GUI applications.  It now uses
+	  the corresponding based types for the image id and
+	  mask to avoid this.
+	- The FLUID widget panel wasn't sorted, so keyboard
+	  navigation was strange. [SF Bug #647069]
+	- Fl_Scroll didn't compute the location of labels to the
+	  right or below when determining the area to erase.
+	- Added backward-compatibility macro for
+	  filename_setext().
+	- Fl_Bitmap::copy(), Fl_Pixmap::copy(), and
+	  Fl_RGB_Image::copy() all could overflow the source
+	  image when scaling the image.
+	- Double/triple clicks in Fl_Input fields didn't copy
+	  the expanded selection to the clipboard.
+	- Fl_Glut_Window and Fl_Gl_Window didn't always initialize
+	  the OpenGL context on MacOS.
+
+
+CHANGES IN FLTK 1.1.2
+
+	- Fl_Menu_Bar now supports drawing vertical dividers
+	  between menu items and submenus in the menu bar.
+	- Fl_File_Chooser::value() didn't return NULL when the
+	  user clicked Cancel while selecting a directory.  This
+	  bug also affected fl_dir_chooser().
+	- Fl_Menu_::add(const char *) used too small a menu item
+	  label buffer and didn't do bounds checking.
+	- Eliminate some compiler warnings with CodeWarrier
+	  under WIN32 (Paul Chambers)
+	- Fl_Gl_Window widgets did not resize properly under
+	  MacOS X.
+	- The cursor could be set for the wrong window in the
+	  text widgets.
+	- Fl_Check_Browser didn't provide const char * add
+	  methods as documented.
+	- Fl_Check_Browser didn't draw the same style of check
+	  marks at the other widgets.
+	- Fl_Button, Fl_Choice, and Fl_Menu_Button incorrectly
+	  activated the button/menu when the spacebar was
+	  pressed in conjunction with shift, control, alt, or
+	  meta.
+	- FLTK should now compile with Xft 2.0.
+	- Some versions of Tru64 4.0 have snprintf and
+	  vnsprintf, but don't have the prototypes for those
+	  functions.
+	- FLTK had trouble doing character composition with some
+	  keyboard layouts under X11 (in particular, Belgian).
+	- Fl_Text_Editor would cause a segfault if the user
+	  pressed CTRL-V (paste) without having any data in the
+	  clipboard...
+	- The tab key moved backwards in menus instead of
+	  forwards.  Shift-tab still moves backwards.
+	- The redraw_label() method didn't damage the parent
+	  window when the label was outside the widget's
+	  bounding box.
+	- Added a "draw_children()" method to Fl_Group to make
+	  subclassing Fl_Group with a custom draw() function
+	  easier.
+	- Fl_Text_Editor now supports basic undo functionality.
+	- FLUID now uses Fl_Text_Editor widgets for all
+	  multi-line code fields.
+	- Added new widget bin and icons to FLUID.
+	- FLUID would try running multiple commands in parallel,
+	  even though it wasn't capable of handling it.
+	- FLUID didn't generate code for some attributes when
+	  using custom/named widget classes.
+	- Added a new FL_COMMAND state bit which maps to FL_CTRL
+	  on X11 and WIN32 and FL_META on MacOS.
+	- MacOS keyboard modifiers mapping corrections. Cmd and
+	  Control are no longer swapped, event_key and event_text
+	  return (mostly) the same values as on other platforms.
+	- The Fl_Tabs widget should no longer be a focus hog;
+	  previously it would take focus from child widgets.
+	- The file chooser now activates the OK button when
+	  opening a directory in directory selection mode.
+	- Fixed a bug in the file chooser when entering an
+	  absolute path.
+	- Back-ported some FLTK 2.0 tooltip changes to eliminate
+	  erroneous tooltip display.
+	- MacOS windows were resizable, even when size_range
+	  would not allow for resizing.
+	- Fl_Text_Editor now supports Shift+Delete, Ctrl+Insert,
+	  and Shift+Insert for cut, copy, and paste,
+	  respectively.
+	- Fl_Text_Display didn't restore the mouse pointer when
+	  hidden.
+	- Fl::arg() now ignores the MacOS X -psn_N_NNNNN option.
+	- Added another change to the WIN32 redraw handling for
+	  the MingW compilers.
+	- Fl_File_Chooser didn't handle WIN32 home directories
+	  that used backslashes instead of forward slashes.
+	- Fl_Text_Display didn't limit the resize height to 1
+	  line.
+	- Fl_Scrollbar widgets incorrectly took keyboard focus
+	  when clicked on. This caused widgets such as
+	  Fl_Text_Display to hide the cursor when you scrolled
+	  the text.
+
+
+CHANGES IN FLTK 1.1.1
+
+	- Fl_Text_Display didn't always show the cursor.
+	- Fl_Tabs now only redraws the tabs themselves when
+	  making focus changes.  This reduces flicker in tabbed
+	  interfaces.
+	- The WIN32 redraw handler now correctly merges the FLTK
+	  and Windows redraw regions.
+	- The Fl_Text_* widgets use the C++ bool type, which is
+	  not supported by older C++ compilers.  Added a
+	  configure check and workaround code for this.
+	- Fl_X::set_xid() didn't initialize the backbuffer_bad
+	  element that was used with XDBE.
+	- Fl_Shared_Image::uncache() was not implemented.
+	- Fl::set_font() didn't 0-initialize all font descriptor
+	  data.
+	- Some OpenGL implementations don't support single-
+	  buffered visuals. The Fl_Gl_Window class now emulates
+	  single-buffered windows using double-buffered
+	  windows.
+	- Added a workaround for a compiler bug in Borland C++
+	  that prevented Fl_Help_View.cxx from compiling.
+	- Checkmarks didn't scale properly; copied the 2.0 check
+	  mark code over.
+	- Replaced several memcpy's with memmove's for
+	  portability (memmove allows for overlapping copies,
+	  memcpy does not)
+	- Bug #621737: Fl_Bitmap::copy(), Fl_Pixmap::copy(), and
+	  Fl_RGB_Image::copy() now range-check the new width and
+	  height to make sure they are positive integers.
+	- Bug #621740: the WIN32 port needed to handle WM_MOUSELEAVE events
+	  in order to avoid problems with tooltips.
+	- Fl_PNM_Image didn't set the "alloc" flag for the data,
+	  which could lead to a memory leak.
+	- fl_filename_match() was inconsistently doing case-
+	  insensitive matching.
+	- Fl_Button redraw fix for bug #620979 (focus boxes and
+	  check buttons).
+	- Fl_Text_Display fix for bug #620633 (crash on
+	  redisplay).
+	- Fl_Output now calls its callback when the user clicks
+	  or drags in the widget.
+	- Shortcuts now cause buttons to take focus when visible
+	  focus is enabled.
+	- fl_filename_relative() didn't check that the path was
+	  absolute under WIN32.
+	- fl_filename_relative() didn't check that the path was
+	  on the current drive under WIN32.
+	- The Fl_BMP_Image class now handles 16-bit BMP files
+	  and BMP files with a transparency mask.
+	- The fltk-config script didn't add the required include
+	  path, if any, when compiling a program.
+	- Added a license clarification that the FLTK manual is
+	  covered by the same license as FLTK itself.
+	- Fl_Check_Browser wasn't documented.
+	- Fl_Preferences::Node::addChild(), deleteEntry(), and
+	  remove() didn't set the "dirty" flag.
+	- The "no change" button didn't work in the FLUID widget
+	  panel.
+	- Vertical scrollbars did not draw the arrows inactive
+	  when the scrollbar was inactive.
+
+
+CHANGES IN FLTK 1.1.0
+
+	- Documentation updates.
+	- Added a Fl_Widget::redraw_label() method which flags a
+	  redraw of the appropriate area.  This helps to
+	  eliminate flicker when updating the value of a widget.
+	- Fl_Wizard::value() now resets the mouse cursor to the
+	  window's default cursor.
+	- Fl_File_Chooser::type() didn't enable/disable the new
+	  directory button correctly.
+	- Fl_Preferences::entryExists() did not work properly.
+	- FLUID's image file chooser pattern was incorrect.
+	- Fl_File_Icon::load_system_icons() now detects KDE
+	  icons in /opt/kde, /usr/local, and /usr automatically,
+	  and supports the KDEDIR environment variable as well.
+	- Submenus now display to the left of the parent menu if
+	  they won't fit to the right.  Previously they would
+	  display right on top of the parent menu...
+	- Fl_Menu_:add() didn't handle a trailing "\" character
+	  gracefully.
+	- Clicking/dragging the middle mouse button in a
+	  scrollbar now moves directly to that scroll position,
+	  matching the behavior of other toolkits.
+	- Added some more range checking to the Fl_Text_Display
+	  widget.
+	- The editor demo did not correctly update the style
+	  (syntax highlighting) information.
+
+
+CHANGES IN FLTK 1.1.0rc7
+
+	- Updated the Fl_Text_Buffer and Fl_Text_Display classes
+	  to be based on NEdit 5.3 (patch from George Garvey).
+	- Fixed a problem with Fl::wait(0.0) on MacOS X 10.2;
+	  this affected the fractals demo and other OpenGL
+	  applications.
+	- Fl_Glut_Window now takes keyboard focus and handles
+	  shortcut events.
+	- The MacOS X implementation of fl_ready() now checks
+	  the event queue for events.
+	- Fl_PNM_Image now supports the XV/GIMP thumbnail format
+	  (P7).
+	- Fl_Preferences would not find groups inside the root 
+	  group.
+	- Small bug fixes for Fl_Chart, Fl_Scrollbar, Fl_Tabs,
+	  and FLUID from Matthew Morrise.
+	- Fl_Chart didn't have its own destructor, so data in
+	  the chart wasn't freed.
+	- Fl_Menu_Button no longer responds to focus or keyboard
+	  events when box() is FL_NO_BOX.
+	- FLTK convenience dialogs put the buttons in the wrong
+	  order.
+	- Fl_BMP_Image didn't load 4-bit BMP files properly.
+	- Minor tweeks to the WIN32 DLL support.
+	- Fl_Text_Display::resize() could go into an infinite
+	  loop if the buffer is emptied.
+	- Fl::handle() didn't pass FL_RELEASE events to the
+	  grab() widget if pushed() was set (for proper menu
+	  handling...)
+	- DND events were being sent to the target window
+	  instead of the target widget under WIN32.
+	- The newest Cygwin needs the same scandir() handling as
+	  HP-UX.
+	- FLUID didn't register the image formats in the
+	  fltk_images library, and had some other image
+	  management problems.
+	- Fixed one more redraw bug in Fl_Browser_ where we
+	  weren't using the box function to erase empty space in
+	  the list.
+	- Fl_Text_Display::buffer() now calls resize() to show
+	  the buffer.
+	- Fl_Help_View didn't support HTML comments.
+	- Fl_Help_View didn't include the extra cellpadding when
+	  handling colspan attributes in cells.
+	- Fl_Help_View didn't support table alignment.
+
+
+CHANGES IN FLTK 1.1.0rc6
+
+	- Documentation updates.
+	- Fl::handle() didn't apply the modal tests for
+	  FL_RELEASE events, which caused Fl_Tabs to allow users
+	  to change tabs even when a modal window was open.
+	- Fl_Browser_, Fl_Input_, Fl_Slider now use the box
+	  function to erase the background.  This fixes some
+	  long-standing redraw problems.
+	- More snprintf/strlcpy/strlcat changes where needed.
+	- Fl::get_font_name() would leak 128 bytes.
+	- Eliminated most of the "shadowed" variables to avoid
+	  potential problems with using the wrong copy of "foo"
+	  in a class method.
+	- Moved Fl_BMP_Image, Fl_GIF_Image, and Fl_PNM_Image to
+	  the fltk_images library, so the only image formats
+	  that are supported by the core library are XBM and XPM
+	  files.  This reduces the size of the FLTK core library
+	  by about 16k...
+	- The Fl_Text_Display::resize() method was incorrectly
+	  flagged as protected.
+	- Fixed some memory/initialization bugs in
+	  Fl_File_Chooser that valgrind caught.
+	- The PNG library png_read_destroy() is deprecated and
+	  does not free all of the memory allocated by
+	  png_create_read_struct(). This caused a memory leak in
+	  FLTK apps that loaded PNG images.
+	- Added uncache() method to Fl_Image and friends.
+	- Added image() methods to Fl_Menu_Item.
+	- Added default_cursor() method and data to Fl_Window.
+	- Fl_Group would send FL_ENTER events before FL_LEAVE
+	  events, causing problems with adjacent widgets.
+	- Fixed filename problems with Fl_File_Chooser -
+	  changing the filename field directly or choosing files
+	  from the root directory could yield interesting
+	  filenames.
+	- Fl_Input_ could crash if it received an empty paste
+	  event.
+	- The mouse pointer now changes to the I beam
+	  (FL_CURSOR_INSERT) when moved over an input field or
+	  text widget.
+	- "make install" didn't automatically (re)compile the
+	  FLUID executable.
+	- Added an Fl::get_boxtype() method to get the current
+	  drawing function for a specific box type.
+	- Fl_Output and Fl_Multiline_Output didn't prevent
+	  middle-mouse pastes.
+	- Fl_JPEG_Image didn't compile out-of-the-box with Cygwin
+	  due to a bug in the Cygwin JPEG library headers.
+	- Fl_BMP_Image still didn't work with some old BMP files.
+	- "make distclean" didn't really clean out everything.
+	- Tweeked the look of the check button with a patch from
+	  Albrecht Schlosser.
+
+
+CHANGES IN FLTK 1.1.0rc5
+
+	- Added "wrap" type bit to Fl_Input_, so you can now
+	  have a multiline text field that wraps text.
+	- Setting the value() of an output text field no longer
+	  selects the text in it.
+	- Output text fields now show a caret for the cursor
+	  instead of the vertical bar.
+	- The newButton and previewButton widgets are now public
+	  members of the Fl_File_Chooser class.  This allows
+	  developers to disable or hide the "new directory" and
+	  "preview" buttons as desired.
+	- Added new visible focus flag bit and methods to
+	  Fl_Widget, so it is now possible to do both global and
+	  per-widget keyboard focus control.
+	- Removed extra 3 pixel border around input fields.
+	- No longer quote characters from 0x80 to 0x9f in input
+	  fields.
+	- Improved speed of Fl_Browser_::display() method with
+	  large lists (patch from Stephen Davies.)
+	- Fl_Help_View didn't properly handle NULL from the link
+	  callback (the original filename/directory name were
+	  not preserved...)
+	- Fl_Help_View didn't use the boxtype border values when
+	  clipping the page that was displayed.
+	- Added first steps to CodeWarrior/OS_X support (see
+	  fltk-1.1.x/CodeWarrior/OS_X.sit)
+	- Cleaned up the WIN32 export definitions for some of
+	  the widget classes.
+	- Fixed a filename completion bug when changing
+	  directories.
+	- Fl_File_Chooser::value() would return directories with
+	  a trailing slash, but would not accept a directory
+	  without a trailing slash.
+	- When installing shared libraries, FLUID is now linked
+	  against the shared libraries.
+	- MacOS: missing compile rule for .dylib files.
+	- Fl_Group::current(), Fl_Group::begin(), and
+	  Fl_Group::end() are no longer inlined so that they are
+	  properly exported in DLLs under WIN32.  Similar
+	  changes for all static inline methods in other
+	  classes.
+	- MacOS: support for Mac system menu (Fl_Sys_Menu_Bar)
+	- MacOS: wait(0) would not handle all pending events
+	- Added new makeinclude file for MingW using GCC 3.1.x.
+	- Fl_Choice::value(n) didn't range check "n".
+	- The MingW and OS/2 makeinclude files didn't have the
+	  new fltk_images library definitions.
+	- Fl_Text_Editor didn't scroll the text in the widget
+	  when dragging text.
+	- Config header file changes for Borland C++.
+	- FLTK didn't provide a Fl::remove_handler() method.
+
+
+CHANGES IN FLTK 1.1.0rc4
+
+	- Added new filter_value() methods to Fl_File_Chooser to
+	  get and set the current file filters.
+	- Added support for custom filters to Fl_File_Chooser.
+	- Added Borland C++ Builder IDE project files from
+	  Alexey Parshin.
+	- Resource leak fixes under WIN32 from Ori Berger.
+	- Now register a WIN32 message for thread messages.
+	- Fl_Window didn't initialize the min and max window
+	  size fields.
+	- The JPEG and PNG image classes have been moved to the
+	  fltk_images library, a la FLTK 2.0.  You can register
+	  all image file formats provided in fltk_images using
+	  the new fl_register_images() function.
+	- Fl_XBM_Image didn't correctly load XBM files.
+	- MacOS: Added Greg Ercolano's file descriptor support.
+	- MacOS: Fixed text width bug.
+	- A change in fl_fix_focus() broken click-focus in FLWM.
+	- Cygwin with -mnocygwin didn't like the FL/math.h
+	  header file.
+	- Fl_Browser_ cleared the click count unnecessarily.
+	- MacOS: Pixmap draw fix, gl_font implemented
+	  FL_FOCUS fix, window type fix for modal and nonmodal
+	  windows, glut uninitialised 'display' proc fix
+	- Now support FLTK_1_0_COMPAT symbol to define
+	  compatibility macros for the old FLTK 1.0.x function
+	  names to the 1.1.x names.
+	- Now translate the window coordinates when a window is
+	  shown, moved, or resized.  This should fix the "menus
+	  showing up at the wrong position" bug under XFree86.
+	- Fixed some more problems with the Fl_BMP_Image file
+	  loader.
+	- BC++ fixes.
+	- The pixmap_browser demo didn't check for a NULL image
+	  pointer.
+	- Fl_File_Icon::find() now uses fl_filename_isdir()
+	  under WIN32 to check for directories.
+	- Fl_File_Chooser's preview code called refcount()
+	  on the deleted image's object.
+	- Fixed another problem with the Fl_BMP_Image loader.
+	- The fl_file_chooser() callback was being called with a
+	  NULL filename.
+	- Documented that fl_push_clip() is preferred over
+	  fl_clip(), with a corresponding source change.
+	- Minor changes to the MacOS X event handling code.
+	- Added syntax highlighting example code to the editor
+	  test program.
+	- Fl_Text_Display didn't range check style buffer
+	  values.
+	- Added "dark" color constants (FL_DARK_RED, etc.)
+	- The MacOS font code was missing definitions for
+	  fl_font_ and fl_size_.
+
+
+CHANGES IN FLTK 1.1.0rc3
+
+	- Documentation updates.
+	- New file chooser from design contest.
+	- Did some testing with Valgrind and fixed some memory
+	  problems in Fl_Help_View::Fl_HelpView,
+	  Fl_Menu_::remove(), Fl_Text_Display::draw_vline(), and
+	  resizeform() (convenience dialogs).
+	- Fixed some redraw() bugs, and now redraw portions of
+	  the parent widget when the label appears outside the
+	  widget.
+	- The boolean (char) value methods in Fl_Preferences
+	  have been removed since some C++ compilers can't
+	  handle char and int value methods with the same name.
+	- Added fl_read_image() function.
+	- Fixed Fl_Valuator::format() so that the correct format
+	  type is used when step == 1.0.
+	- Fl_Help_View didn't support the TT markup.
+	- Fl_Shared_Image used a double-pointer to the image
+	  handler functions, which was unnecessary and
+	  unintuitive.
+	- Fl_PNM_Image didn't load the height of the image
+	  properly.
+	- Fl_BMP_Image, Fl_JPEG_Image, Fl_PNG_Image, and
+	  Fl_Shared_Image didn't delete image data that was
+	  allocated.
+	- Enabled the OpenGL and threads demos when compiling
+	  for MingW.
+	- Fl_File_Input didn't update the directory buttons if a
+	  callback was registered with the widget.
+	- The file chooser would return the last selected
+	  file(s) when cancel was pressed.
+	- The file chooser limited the resizing of the chooser
+	  window unnecessarily.
+	- Fixed WM_PAINT handling under WIN32.
+	- Minor tweeks to MingW and OS/2 config headers.
+	- Fl_Value_Input now correctly determines if step()
+	  specifies an integer value.
+	- Fl_Help_View didn't add links inside PRE elements.
+	- OS/2 build fixes from Alexander Mai.
+	- Now use strlcat() instead of strncat() which could
+	  cause buffer overflows.
+	- Now use of strlcpy() instead of strncpy() to simplify
+	  the code.
+	- Drag-n-drop under WIN32 now shows a [+] cursor instead
+	  of the link cursor.
+	- Fixed widget width tooltip and default argument
+	  handling code in FLUID.
+	- Fixed colors used when drawing antialiased text using
+	  Xft.
+	- Fl_Preferences::makePath() now uses access() instead
+	  of stat() when checking to see if the destination
+	  directory already exists.
+	- Fl_BMP_Image now supports older BMP files with the 12
+	  byte header.
+	- Optimized the redrawing of tabs and radio/check
+	  buttons when the keyboard focus changes.
+	- More tooltip fixes.
+	- DND text operations would loop under X11.
+
+
+CHANGES IN FLTK 1.1.0rc2
+
+	- Portability fixes.
+	- Backported 2.0 tooltip changes.
+	- Several of the valuators did not support tooltips.
+	- The last menu item in a menu didn't pick up on font
+	  changes.
+	- FLUID now properly handles default argument parameters
+	  properly.
+	- Fixed WM_PAINT handling under WIN32 - didn't validate
+	  the correct region that was drawn.
+	- Fl_Multiline_Output would insert the enter key.
+	- Fl_File_Browser didn't clip items to the column width.
+	- Fl_Window::draw() cleared the window label but didn't
+	  restore it, so windows could lose their titles.
+	- Eliminated multiple definitions of dirent structure
+	  when compiling under WIN32.
+	- Adjusted the size of the circle that is drawn inside
+	  radio buttons to scale better for larger labels.
+	- FLUID was opening the display when it shouldn't have.
+	- Fl_File_Chooser.cxx defined the file chooser functions
+	  again; they should only be defined in the header file.
+	- Wide arcs would draw with "teeth".
+	- The preferences demo included Fl/Fl_Preferences.H
+	  instead of FL/Fl_Preferences.H.
+
+
+CHANGES IN FLTK 1.1.0rc1
+
+	- The fl_file_chooser() and fl_dir_chooser() functions
+	  now support an optional "relative" argument to get
+	  relative pathnames; the default is to return absolute
+	  pathnames.
+	- The backspace and delete keys now work as expected in
+	  the file chooser when doing filename completion.
+	- FLUID now supports running shell commands.
+	- New Fl_File_Input widget that shows directory
+	  separators with filename in input field.
+	- The Fl_File_Chooser dialog now shows the absolute path
+	  in the filename field using the Fl_File_Input widget.
+	- FLUID now keeps track of grid, tooltip, and other
+	  GUI options, along with the last 10 files opened.
+	- Tooltip windows would show up in the task bar under
+	  WIN32.
+	- Now append trailing slash to directory names in names
+	  in WIN32 version of scandir().  This takes care of a
+	  file chooser performance problem with large
+	  directories.
+	- Added Fl_Preferences class from Matthias Melcher,
+	  including binary data support.
+	- FLUID now recognizes the "using" keyword in
+	  declarations.
+	- fl_file_chooser() didn't highlight the requested file
+	  the second time the file chooser dialog was shown.
+	- Fixed rendering of Fl_Light_Button with the plastic
+	  scheme.
+	- Fixed a bug in the MacOS font enumeration code.
+	- Now show a "locked" icon next to static/private
+	  elements in FLUID, and "unlocked" icon next to
+	  global/public elements.
+	- Implemented Fl_Menu_Item image labels using older
+	  1.0.x labeltype method.
+	- Updated the PNG library check to support both png.h
+	  and libpng/png.h.
+	- Fixed a recursion bug in tooltips that was causing
+	  random crashes.
+	- fl_file_chooser() could cause a segfault when passed a
+	  NULL filename parameter in some situations.
+	- Added a "-g" option to fltk-config to support quick
+	  compiling with debugging enabled.
+	- Fixed redraw problem with Fl_Input and anti-aliased
+	  text.
+	- Added threading support for MacOS X and Darwin.
+	- The filesystem list in the file chooser now works under
+	  MacOS X and Darwin.
+	- The fl_msg structure now contains all data passed to
+	  the WndProc function under WIN32.
+	- Fixed some window focus/positioning problems under
+	  MacOS X.
+	- Added fl_create_alphamask() function to create an alpha
+	  mask from 8-bit data; currently this always generates a
+	  1-bit screen-door bitmask, however in the future it will
+	  allow us to generate N-bit masks as needed by various
+	  OS's.
+	- Fl_File_Browser::load() didn't properly show drives
+	  when compiled in Cygwin mode.
+	- Now pass correctly pass keyboard and mouse events to
+	  widget under tooltip as needed...
+	- Added new Fl::dnd_text_ops() methods to enable/disable
+	  drag-and-drop text operations.
+	- Fl_Input now supports clicking inside a selection to
+	  set the new text position when drag-and-drop is
+	  enabled.
+	- Added support of X resources for scheme, dnd_text_ops,
+	  tooltips, and visible_focus...
+	- Fixed some case problems in includes for the MacOS X
+	  code.
+	- Fl_Widget::handle() returned 1 for FL_ENTER and
+	  FL_LEAVE events, which caused some compatibility
+	  problems with 1.0 code.
+	- Fl_Box::handle() now returns 1 for FL_ENTER and
+	  FL_LEAVE events so that tooltips will work with Fl_Box
+	  widgets.
+	- Some source files still defined strcasecmp and
+	  strncasecmp under WIN32.
+	- Some source files still used the "false" and "true"
+	  C++ keywords, even though several of our "supported"
+	  C++ compilers don't support them.  Using 0 and 1 until
+	  FLTK 2.0 (which uses the bool type instead of int for
+	  any boolean values...)
+	- Minor Fl_Color revamping, so that color constants map
+	  to the color cube and FL_FOREGROUND_COLOR,
+	  FL_BACKGROUND_COLOR, FL_BACKGROUND2_COLOR,
+	  FL_INACTIVE_COLOR, and FL_SELECTION_COLOR map to the
+	  user-defined colors.
+
+
+CHANGES IN FLTK 1.1.0b13
+
+	- Fixed a bug in the Xft support in Fl_Window::hide()
+	  (the config header wasn't included, so the Xft code
+	  wasn't getting called)
+	- Xdbe support must now be enabled explicitly using
+	  --enable-xdbe due to inconsistent bugs in XFree86 and
+	  others.
+	- Windows resized by a program would revert to their
+	  original size when moved under WIN32.
+	- Cygwin can only compile the new WIN32 drag-n-drop code
+	  using GCC 3.x.
+	- Tooltips now appear for inactive and output widgets.
+	- Tooltips no longer steal keyboard events other than
+	  ESCape.
+	- Tooltips are no longer delayed when moving between
+	  adjacent widgets.
+	- fl_beep(FL_BEEP_DEFAULT) now uses the PC speaker under
+	  Windows (0xFFFFFFFF) rather than an event sound.
+	- The configure script didn't include the -mwindows or
+	  -DWIN32 compiler options in the output of fltk-config
+	  when using the Cygwin tools.
+	- Fl_Output didn't take input focus when needed, so it
+	  was unable to support CTRL-C for copying text in the
+	  field and did not unhighlight selections when the
+	  widget lost focus.
+	- The fl_filename_name() function didn't handle a NULL
+	  input string.
+	- The input field used by the fl_input() and
+	  fl_password() functions was resized too small in
+	  1.1.0b12.
+	- Added casts in fl_set_fonts_win32.cxx for VC++ 5.0.
+	- Fl_File_Icon::find() did not check the basename of a
+	  filename for a match; this caused matches for a
+	  specific filename (e.g. "fluid") to fail.
+	- The Fl_Shared_Image class now supports additional
+	  image handling functions - this allows you to support
+	  additional image file formats transparently.
+
+
+CHANGES IN FLTK 1.1.0b12
+
+	- Documentation updates.
+	- Fl_Choice didn't clip the current value properly - it
+	  wasn't accounting for the box border width.
+	- The forms compatibility functions are now placed in a
+	  "fltk_forms" library to match FLTK 2.0.
+	- Renamed down() and frame() to fl_down() and
+	  fl_frame(), filename_xyz() to fl_filename_xyz(), and
+	  all of the define_FL_FOO() functions for the custom
+	  boxtypes to fl_define_FL_FOO() to avoid namespace
+	  clashes.
+	- Stereo OpenGL support (patch from Stuart Levy)
+	- All of the convenience functions defined in fl_ask.H
+	  now resize the widgets and dialog window as needed for
+	  the labels and prompt.
+	- Backported FLTK 2.0 dual cut/paste buffer code.
+	- Added support for Xft library to provide anti-aliased
+	  text on X11.
+	- Fl_Help_View didn't keep track of the background color
+	  of cells properly.
+	- Fl_Browser::item_width() didn't compute the width of
+	  the item properly when column_widths() was set.
+	- Fl_Button didn't check to see if the widget could
+	  accept focus before taking input focus.
+	- Fl_Help_View didn't preserve target names (e.g.
+	  "filename.html#target") when following links.
+	- Drag-and-drop support for MacOS.
+	- Updated MacOS issues documentation.
+
+
+CHANGES IN FLTK 1.1.0b11
+
+	- Now conditionally use the WIN32 TrackMouseEvent API
+	  (default is no...)
+	- Fixed a table rendering bug in the Fl_Help_View
+	  widget.
+	- The fltk-config script now recognizes all common C++
+	  extensions.
+	- The menu code was using overlay visuals when the
+	  scheme was set to "plastic".
+	- Fixed some drawing problems with Fl_Light_Button and
+	  its subclasses.
+	- Fixed a minor event propagation bug in Fl_Group that
+	  caused mousewheel events to be passed to scrollbars
+	  that were not visible.
+	- The fl_file_chooser() function did not preserve the
+	  old file/directory like the old file chooser did.
+	- The prototypes for fl_input() and fl_password() did
+	  not default the "default value" to NULL.
+	- Fl_Tabs now draws tabs using the selection_color() of
+	  the child groups; this allows the tabs to be colored
+	  separately from the body.  Selected tabs are a mix of
+	  the Fl_Tabs selection_color() and the child group's
+	  selection_color().
+	- Fl_Tabs didn't include images in the measurement of
+	  the tabs if no label text was defined.
+	- The WIN32 code didn't return 0 from the window
+	  procedure after handling WM_PAINT messages.
+	- fl_draw() would incorrectly test the clipping of
+	  labels the lay outside the bounding box.
+	- filename_relative() didn't always return the correct
+	  relative path.
+	- Updated the test makefile to work with more versions
+	  of "make".
+	- Added new "--with-optim" configure option to set the
+	  optimization flags to use when compiling FLTK.
+	- The fltk-config script no longer reports the
+	  optimization flags that were used to compile FLTK.
+	- Initial port of FLTK 2.0 drag-and-drop support.
+
+
+CHANGES IN FLTK 1.1.0b10
+
+	- Fixed the new WIN32 TrackMouseEvent code.
+	- Fixed the VC++ project files to link against
+	  comctl32.lib.
+
+
+CHANGES IN FLTK 1.1.0b9
+
+	- Better FL_LEAVE event handling for WIN32.
+	- The alpha mask was bit-reversed.
+	- Fl::scheme() applied the scheme tile image to overlay
+	  and menu windows, which caused problems when the
+	  overlay planes were in use.
+	- Fixed Fl::event_button() value when hiding tooltip on
+	  some systems.
+	- Added Fl_BMP_Image class to support loading of Windows
+	  bitmap (BMP) files.
+	- The shiny demo didn't work on some systems (no
+	  single-buffered OpenGL visual), and the new box types
+	  were reset when show(argc, argv) was called.
+	- Fl::scheme() didn't update windows that were not
+	  shown.
+	- The fractals demo would get far ahead of the UI with
+	  some Linux OpenGL drivers.  Now use glFinish() instead
+	  of glFlush() so we are at most 1 frame ahead.
+	- The fractals demo Y axis controls were backwards for
+	  the "flying" mode.
+	- MacOS: cleaned up src/Fl_mac.cxx
+	- MacOS: fixed Fl::wait(0.0), fixed Cmd-Q handling
+	- Update CygWin support for Fl::add_fd().
+	- Update the plastic scheme to not override the default
+	  colors - move the color code to the MacOS-specific
+	  code.  Also updates the tile image colormap to match
+	  the current background color.
+	- Add fl_parse_color() to X11 as well, removing a bunch
+	  of conditional code and providing a common interface
+	  for looking up color values.
+	- Fixed the make problems in the test directory - some
+	  make programs had trouble handling the recursive
+	  dependencies on the FLUID files...
+	- Now use rint() to round floating-point coordinates.
+	- Demo cleanup - made sure they all worked with schemes.
+	- Fl_Tabs no longer clears the unused area of the tab
+	  bar.
+	- Added show(argc, argv) method to Fl_Help_Dialog.
+	- MacOS: implemented cut/copy/paste.
+	- MacOS: improved keyboard handling, fixed keyboard
+	  focus handling, fixed get_key, modified 'keyboard'
+	  demo to show second mouse wheel and additional keys
+	  'help' and FL_NK+'='
+
+
+CHANGES IN FLTK 1.1.0b8
+
+	- OS/2 build fixes.
+	- fl_draw() didn't ignore symbol escapes properly for
+	  the browsers...
+	- New Fl::scheme() methods from FLTK 2.0; currently only
+	  the standard ("") and plastic ("plastic") methods are
+	  supported.  Schemes can be set on the command-line
+	  ("-scheme plastic") or using the FLTK_SCHEME
+	  environment variable.
+	- MacOS: fixed iBook keyboard handling, moved 
+	  remaining message handling to Carbon, added mouse
+	  capture support, added timer support, added overlay
+	  support, fixed double-buffering side effects.
+	- The configure script wasn't using the -fpermissive or
+	  -fno-exceptions options with GCC.
+	- Fl_JPEG_Image and friends didn't set the depth if the
+	  image file couldn't be loaded; since Fl_RGB_Image
+	  didn't check for this, it could fail when displaying
+	  or copying these images.
+	- filename_absolute() did not always free its temporary
+	  buffer.
+	- filename_relative() did not do a case-insensitive
+	  comparison under MacOS, OS/2, and Windows.
+	- filename_isdir() didn't properly handle "D:L" under
+	  WIN32.
+	- Fl_Shared_Image::get() did not check to see if the
+	  image could not be loaded.
+	- Fl_Help_View didn't clear the line array in the
+	  Fl_Help_Block structure; this causes erratic
+	  formatting for some pages.
+	- The font and size members of Fl_Help_Block were never
+	  used.
+	- The threading functions (Fl::lock() and friends) were
+	  not exported under WIN32.
+	- The Fl_Text_Display destructor deleted the scrollbars
+	  twice...
+	- Fl_Help_View didn't reset the horizontal scroll
+	  position when showing a new page.
+	- Fl_Pack now allows any child widget to be the
+	  resizable() widget, not just the last one.
+	- MacOS: opaque window resizing, all events except 
+	  Mac menus are now handled using Carbon, window 
+	  activation fixed, GL_SWAP_TYPE default changed to 
+	  make gl_overlay work.
+	- Fl_Help_View::resize() didn't resize the horizontal
+	  scrollbar.
+	- MacOS: list all fonts, fixed clipping and mouse
+	  pointer bugs.
+	- The Fl_File_Chooser widget now uses hotspot() to
+	  position the dialog under the mouse pointer prior to
+	  showing it.
+	- Added a configure check for *BSD - use -pthread option
+	  instead of -lpthread.
+	- Fl_Text_Display could get in an infinite loop when
+	  redrawing a portion of the screen.  Added a check for
+	  the return value from fl_clip_box() so that the
+	  correct bounding box is used.
+	- Removed the Fl_Mutex and Fl_Signal_Mutex classes from
+	  the threads example, since they weren't being used
+	  and apparently are not very portable.
+	- Fl_Help_View now ignores links when the link callback
+	  returns NULL, and displays a sensible error message
+	  when an unhandled URI scheme is used (e.g. http:,
+	  ftp:)
+	- Fl_File_Icon::load_system_icons() no longer complains
+	  about missing icon files, just files that exist but
+	  can't be loaded.
+	- FLUID didn't list the plastic box and frame types.
+	- Now hide the tooltip window whenever a window is
+	  hidden.  Otherwise a tooltip window could keep an
+	  application running.
+	- Updated FLUID to only append a trailing semicolon to
+	  code lines in a callback (so "#include" and friends
+	  will work...)
+	- The Fl_Color_Chooser widget now supports keyboard
+	  navigation.
+	- Fixed button and valuator widgets to call Fl::focus()
+	  instead of take_focus().
+	- Tweeked the radio button drawing code for better
+	  circles with different boxtypes.
+	- The Fl_File_Chooser widget did not provide a shown()
+	  method, and fl_file_chooser() and fl_dir_chooser() did
+	  not wait on shown(); this would cause them to return
+	  prematurely if you switched desktops/workspaces.
+	- Cosmetic changes to plastic boxtypes.  Now look much
+	  better for large areas and the buttons now have a much
+	  greater "3D" feeling to them.
+	- Added new Fl::draw_box_active() method so that
+	  boxtypes can find out if the widget they are drawing
+	  for is active or not.
+	- Fl_Button and its subclasses did not redraw the parent
+	  when the boxtype was FL_NO_BOX and they lost keyboard
+	  focus (the parent redraw clears the focus box.)
+	- Fixed the example program makefile - wasn't building
+	  the mandelbrot and shiny demos right.
+	- Fl::set_font(Fl_Font, Fl_Font) was not implemented.
+	- Fixed the documentation Makefile commands; was not
+	  using the fltk.book file for some reason...
+
+
+CHANGES IN FLTK 1.1.0b7
+
+	- More documentation updates...
+	- Mac OS X support works 95%
+	- The Fl_Window::hotspot() off-screen avoidance code was
+	  commented out.
+	- Mac OS X uses mostly Carbon event handling to support
+	  Mousewheel, three buttons, all modifier keys, etc.
+	- Updated paragraph 4 of the FLTK license exceptions;
+	  there was some question about the requirement to show
+	  that a program uses FLTK, which is required by section
+	  6 of the LGPL. The new exemption specifies that
+	  inclusion of the FLTK license is not required, just a
+	  statement that the program uses FLTK.
+	- Fl_Button::handle() was calling take_focus() for both
+	  FL_PUSH and FL_DRAG.
+	- File and memory fixes for Fl_GIF_Image, Fl_PNG_Image,
+	  Fl_PNM_Image, Fl_Shared_Image, Fl_Tiled_Image, and
+	  Fl_XBM_Image.
+	- filename_match() didn't handle backslashes properly
+	  under WIN32, and didn't use a case-insensitive
+	  comparison under MacOS X.
+	- The Fl class was missing access methods for the
+	  FL_MOUSEWHEEL event values - Fl::event_dx() and
+	  Fl::event_dy().
+	- The default help string didn't include the -nokbd
+	  option.
+	- "make uninstall" didn't uninstall the static OpenGL
+	  widget library.
+	- Mac cursor shapes added...
+	- Fl_Text_Display would lockup when all text was
+	  deleted; for example, when running the editor
+	  demo, you couldn't load a second file.
+	- Added Fl::lock() and friends from FLTK 2.0 to
+	  support multi-threaded applications; see the
+	  "threads" demo for an example of this.
+	- Fl_Check_Button and Fl_Round_Button now use the
+	  FL_NO_BOX box type to show the background of the
+	  parent widget.
+	- Tweeked the plastic boxtype code to draw with the
+	  right shading for narrow, but horizontal buttons.
+	- Fl_Progress now shades the bounding box instead of
+	  drawing a polygon inside it.
+	- Fl::warning() under WIN32 defaults to no action. This
+	  avoids warning dialogs when an image file cannot be
+	  loaded.
+	- Some Win32 drivers would draw into wrong buffers
+	  after OpenGL mode change
+	- The file chooser would cause a segfault if you
+	  clicked in an empty area of the file list.
+	- Fl_File_Icon::labeltype() would cause a segfault
+	  if the value pointer was NULL.
+	- Fl_File_Icon::load_image() could cause segfaults
+	  (NULL data and incrementing the data pointer too
+	  often.)
+	- Fl_File_Icon::load_image() now handles 2-byte
+	  per color XPM files.
+	- Some Win32 drivers would draw into wrong buffers
+	  after OpenGL mode change.
+	- Message handling and Resources for MacOS port.
+	- Fl_Help_View could get in an infinitely loop when
+	  determining the maximum width of the page; this
+	  was due to a bug in the get_length() method with
+	  percentages (100% width would cause the bug.)
+	- Don't need -lgdi32 for CygWin, since -mwindows
+	  does this for us.
+	- The WIN32 event handler did not properly handle
+	  WM_SYNCPAINT messages.
+	- Fl_Tabs now uses the boxtype exclusively to draw
+	  both the tabs and surrounding box, so alternate
+	  box types actually work and the look is a little
+	  nicer.
+	- Fixed the drawing of large areas with the new
+	  plastic boxtypes.
+	- Updated the Visual C++ demo projects to use fluid
+	  to generate the GUI files as needed.
+	- The demo program didn't load the right menu file
+	  when compiled for debugging under WIN32.
+	- Added plastic box types to forms demo.
+	- Added mousewheel to keyboard demo.
+	- The Fl_Text_Editor widget caused an infinite loop
+	  when it received keyboard focus.
+	- filename_isdir() didn't properly handle drive letters
+	  properly; WIN32 needs a trailing slash for drive
+	  letters by themselves, but cannot have a trailing
+	  slash for directory names, go figure...
+	- The Fl_Text_Buffer and Fl_Text_Display classes did not
+	  initialize all of their members.
+	- fl_normal_label() had a totally redundant set of
+	  if/else tests, which the new code handles all from
+	  fl_draw().
+	- The Fl_File_Chooser dialog contained two hotspots.
+	- The fl_draw_pixmap() function didn't free the 2-byte
+	  color lookup table properly (delete instead of
+	  delete[]).
+	- fl_draw() reset the text color under WIN32, causing
+	  bitmaps to draw incorrectly.
+	- Fl::get_font_sizes() is now implemented under WIN32.
+	- Fl_Text_Display now uses the same default colors for
+	  selection and text as Fl_Input_ and friends.
+	- Changed the default line scrolling in Fl_Text_Display
+	  to 3 lines for the mouse wheel and scrollbar arrows.
+
+
+CHANGES IN FLTK 1.1.0b6
+
+	- Documentation updates...
+	- The configure script now works within the CygWin
+	  environment.
+	- Tooltips are now enabled by default, but are not
+	  re-enabled when calling the Fl_Widget::tooltip()
+	  method.
+	- Added new Fl::version() method to get the current
+	  FLTK library version (for shared libraries/DLLs)
+	- Added new Fl::event() method to get the current
+	  event that is being processed.
+	- Added new fl_beep() function to do audible
+	  notifications of various types.
+	- Added new Fl_GIF_Image, Fl_JPEG_Image, Fl_PNG_Image,
+	  Fl_PNM_Image, Fl_XBM_Image, and Fl_XPM_Image classes.
+	- Added new Fl_Shared_Image class, a la FLTK 2.0.
+	- Added new Fl_Tiled_Image class for tiled backgrounds.
+	- Added new copy(), desaturate(), inactive(), and
+	  color_average() methods to the Fl_Image classes.
+	- Added a horizontal scrollbar to the Fl_Help_View
+	  widget.
+	- Added new FL_PLASTIC_{UP/DOWN}_{BOX/FRAME} boxtypes
+	  for a more "modern" look (sort of a cross between KDE
+	  2.2 and Aqua.)
+	- Fl_Float_Input and Fl_Int_Input no longer accept
+	  pasted text that is not a floating point or integer
+	  value.  Pasted numbers now replace text in these
+	  widgets.
+	- Implemented the Fl_File_Icon::load_png() method.
+	- The Fl_File_Icon::load_system_icons() method now
+	  supports KDE 2.x icons.
+	- Fixed PNG support in Fl_Help_View.
+	- Removed the "Microsoft" mode button from the menubar
+	  demo.
+	- The browser demo now makes sure that the input field
+	  contains a number.
+	- The Fl_Browser::make_visible() method now range checks
+	  the input.
+	- Updated the fl_draw() and fl_measure() methods to
+	  accept an optional draw_symbols argument, which
+	  controls whether symbols are drawn in the text.
+	- Added new Fl::visible_focus() methods to control
+	  whether the focus box is drawn.
+	- The focus box is now drawn using the contrast color.
+	- Fl_Repeat_Button didn't accept keyboard focus.
+	- Added new Fl::visible_focus() method and standard
+	  "-kbd" and "-nokbd" options in Fl::args() processing
+	  to control whether keyboard focus is shown and handled
+	  by non-text widgets.
+	- The wrong tooltip could be shown if the user moved the
+	  mouse over adjacent widgets with tooltips.
+	- The drop-down button on Fl_Choice widgets was not
+	  limited in width.
+	- Tooltips could appear off the screen.
+	- Mouse wheel events are now sent to the focus widget
+	  first, then to any other interested widget.
+	- The Fl_RGB_Image class now supports images with an
+	  alpha channel.  Images are currently drawn using
+	  "screen door" transparency...  See the "image" demo
+	  for an example.
+	- Added new fl_create_bitmask() and fl_delete_bitmask()
+	  functions that create bitmap objects for masking and
+	  bitmap drawing.
+	- Was sending FL_RELEASE events for buttons 4 and 5
+	  under X11, which are only for FL_MOUSEWHEEL.
+	- Fl_Help_View now supports the EM and STRONG elements.
+	- Didn't do callbacks when changing tabs via keyboard.
+	- FLUID didn't write tooltip strings to the message
+	  catalog file.
+	- Fl_File_Icon now uses Fl_Shared_Image to load icon
+	  images; the load_png() and load_xpm() methods have
+	  been replaced by a single load_image() method.
+	- Fl_File_Icon::load_system_icons() now does a better
+	  job of finding KDE icons.
+	- Now use Fl::warning() and Fl::error() in place of
+	  printf's in some of the newer widgets.
+	- The default behavior of Fl::error() is now to display
+	  an error but not to exit; Fl::fatal() still exits.
+	- FLUID now uses the Fl_Shared_Image class, so FLUID-
+	  generated GUIs can embed any of the supported image
+	  file formats.
+	- New filename_relative() function to convert an
+	  absolute filename to a relative one.
+	- Updated the filename_absolute(), filename_expand(),
+	  and filename_setext() functions to take the
+	  destination string size, with inline functions for the
+	  old FL_PATH_MAX size.
+	- fl_file_chooser() and fl_dir_chooser() now return a
+	  relative path.
+	- Fl_Help_View now supports all ampersand escapes.
+
+
+CHANGES IN FLTK 1.1.0b5
+
+	**** NOTE: DUE TO CHANGES IN THE WIDGET CLASSES,  ****
+	****       YOU MUST RECOMPILE ALL SOURCE FILES    ****
+	****       THAT USE FLTK!!!                       ****
+
+	- All FLTK color values are now 32-bits and support
+	  both the legacy 8-bit color values as well as 24-bit
+	  RGB values (0xRRGGBB00 for 24-bit RGB, 0x000000II
+	  for indexed color).
+	- Fl::set_boxtype() and fl_internal_boxtype() now keep
+	  track of when a boxtype is changed; this allows you to
+	  override the "special" boxtypes without references to
+	  those boxtypes causing them to be reset.
+	- Fl_Help_Func now takes a Fl_Widget pointer as well as
+	  a pathname.
+	- Added code to support FL_KEYUP events.
+	- Focus did not return to the Fl_Text_Display and Editor
+	  widgets when scrolling and then clicking inside the
+	  editor window.
+	- Now set the line size of the vertical scrollbar in the
+	  text editor to 1.
+	- The symbols demo didn't show the strings needed to
+	  show the corresponding symbol (the label string was
+	  not quoted...)
+	- FLTK should now compile with Cygwin cleanly.
+	- Shortcut changes were not being saved by FLUID.
+	- FLUID didn't write the deimage() static data.
+
+
+CHANGES IN FLTK 1.1.0b4
+
+	**** NOTE: DUE TO CHANGES IN THE FL_WIDGET CLASS, ****
+	****       YOU MUST RECOMPILE ALL SOURCE FILES    ****
+	****       THAT USE FLTK!!!                       ****
+
+	- Updated the flags_ member of Fl_Widget to be an
+	  integer instead of uchar, to support the new
+	  FL_OVERRIDE flag for Fl_Window.
+
+	- The parent() method of Fl_Widget now uses pointers to
+	  Fl_Group instead of Fl_Widget.
+
+	- Fl_Window now provides the FLTK 2.0 "override()" and
+	  "set_override()" methods for windows.
+
+	- Added a configure check (and warning) for GCC 3.0.x.
+
+	- Updated the configure script to check for the
+	  png_set_tRNS_to_alpha() function.
+
+	- Updated the config.h files for all platforms for the
+	  image and FLTK documentation defines.
+
+	- Updated the makeinclude files for all platforms to
+	  match the current makeinclude.in file.
+
+	- FLUID would crash if you cleared an image for a
+	  widget.
+
+	- Fl_Help_View::add_image() did not initialize the image
+	  member of the base (unscaled) image.
+
+	- Fl_Help_View didn't support A elements with both a
+	  NAME and HREF attribute - the HREF was ignored.
+
+	- Miscellaneous compile warning fixes.
+
+	- Tooltips were being reset by Fl::belowmouse(), which
+	  caused problems with the FLUID main window (flashing
+	  tooltip windows and serious problems with KDE 2.2)
+
+	- The editor demo had the save and discard button
+	  actions reversed.
+
+	- The Fl_Help_View widget now uses
+	  png_destroy_read_struct() if the older
+	  png_read_destroy() function is not available.
+
+	- The WIN32 DLL library now includes the OpenGL widgets.
+	  This is a simpler solution for the export/import
+	  dillemma under WIN32, as OpenGL and non-OpenGL symbols
+	  need to be exported at different times with the
+	  separate library scheme.  Since OpenGL is standard
+	  under Windows, this is less of a problem than under
+	  UNIX...
+
+
+CHANGES IN FLTK 1.1.0b3
+
+	- The top-level makefile did not include the makeinclude
+	  file, causing the fltk-config installation commands to
+	  fail.
+
+	- The fl_file_chooser.cxx source file conflicted with
+	  Fl_File_Chooser.cxx under Windows.  Similarly, the
+	  fl_file_chooser.H header file conflicts with the
+	  Fl_File_Chooser.H header file.
+
+	- Now save and restore the GDI pen object when
+	  responding to WIN32 paint messages.
+
+	- Documentation updates from A. Suatoni.
+
+
+CHANGES IN FLTK 1.1.0b2
+
+	- New fltk-config script.
+
+	- Fixed image/text label handling; in b1 the label
+	  needed a non-blank text string to display the image. 
+	  This bug also caused all sorts of crashes and display
+	  problems.
+
+	- Added new filetype() method to Fl_FileBrowser to allow
+	  for file or directory browsing.
+
+	- Fixed the drawing of the focus box around
+	  Fl_Return_Button.
+
+	- Fixed menu item measurement bug (wasn't initializing
+	  image pointers to 0...)
+
+	- Radio and checkbox menu items now draw with the new
+	  style (round radio buttons with dots and square check
+	  buttons with check marks.)
+
+	- Improved the appearance of Fl_Check_Button.
+
+	- Improved the Fl_HelpView table formatting code; now
+	  dynamically sizes the table columns, and supports
+	  COLSPAN.
+
+	- The FLUID keyboard shortcuts now work as expected
+	  (CTRL-C copies, SHIFT-CTRL-C writes code, etc.)
+
+	- The FLTK_DOCDIR environment variable can now be
+	  used to tell FLUID where to find the on-line
+	  documentation files.
+
+	- FLUID now supports image labels in addition to text
+	  labels + text over image alignment.
+
+	- FLUID now supports tooltips.
+
+	- The widget panel in FLUID is now tabbed, a la FLTK
+	  2.0.
+
+	- The FLUID pixmap destructor tried to free 1 too many
+	  lines of image data.
+
+	- FLUID now provides on-line help.
+
+	- Changed Fl_FileXYZ to Fl_File_XYZ.
+
+	- Changed Fl_HelpXYZ to Fl_Help_XYZ.
+
+	- Tooltip fixes for Fl_Browser_, Fl_Choice, and Fl_Input_.
+
+	- Added tooltips to FLUID, help dialog, and file chooser.
+
+	- Now load system icons in FLUID.
+
+
+CHANGES IN FLTK 1.1.0b1
+
+	- Added new image() and deimage() methods to support
+	  image + text labels more easily.
+
+	- Added new alignment bit FL_ALIGN_TEXT_OVER_IMAGE.
+
+	- Added tooltip support using Jacques Tremblay's tooltip
+	  patch.
+
+	- Added keyboard navigation to all widgets.
+
+	- Added support for mouse wheels using the new
+	  FL_MOUSEWHEEL event type.  Get the mouse wheel
+	  movement values from Fl::e_dx (horizontal) and
+	  Fl::e_dy (vertical).
+
+	- Added the Fl_Check_Browser, Fl_FileBrowser,
+	  Fl_FileChooser, Fl_FileIcon, Fl_HelpDialog,
+	  Fl_HelpView, Fl_Progress, and Fl_Wizard widgets from
+	  the bazaar.
+
+	- Added 2.0 Fl_Text_Display and Fl_Text_Editor widgets
+	  based on NEdit.
+
+	- The Fl_Choice widget now looks more line a combo box
+	  than a Motif option menu.
+
+	- Moved the OpenGL widgets into a separate library
+	  called fltkgl - this eliminates shared library
+	  dependencies on OpenGL when no OpenGL functionality is
+	  used/required.
+
+	- FLUID now supports the new Fl_CheckBrowser,
+	  Fl_FileBrowser, Fl_FileIcon, Fl_HelpView,
+	  Fl_Text_Display, Fl_Text_Editor, and Fl_Wizard
+	  widgets.
+
+	- Updated configure stuff to support shared libraries
+	  under AIX (link to -lfltk_s)
+
+	- Symbol labels can now contain regular text.
+
+	- FLUID now supports relative filenames for the source
+	  and header files you generate.
+
+	- Fl_Menu_Item::add() didn't use the flags that were
+	  passed in.
+
+	- Fixed a bug in Fl_Scrollbar - clicking in the "trough"
+	  of the scrollbar would move the scroller in the wrong
+	  direction.
+
+	- Made the Forms pixmap parameter const to match the
+	  Fl_Pixmap.H definitions.
+
+	- Changed the Fl_Pixmap constructor to use the explicit
+	  keyword which should work for all C++ compilers.
+
+	- Fl_Menu_add of a menu item with the same name as an
+	  existing submenu title would mess up by replacing that
+	  menu title, it now adds a new item.
+
+	- Fl_Menu::add() of text starting with '/' to a menu is
+	  assummed to be a filename. So "/foo/bar" creates a
+	  single menu item. You can also put filenames into
+	  submenus by doing "submenu//foo/bar", this will create
+	  a submenu called "submenu" with an item "/foo/bar".
+	  Menu items starting with "\_" will insert an item
+	  starting with '_' rather than a divider line. These
+	  changes make the menus compatable with fltk 2.0.
+
+	- Another little fix for the BoXX OpenGL overlays.
+
+	- Fl_Gl_Window no longer blanks the mouse pointer on
+	  WIN32 unless an OpenGL overlay is being used.  This
+	  should make non-overlay displays faster when a cursor
+	  is set.
+
+
+CHANGES SINCE FLTK 1.0.10
+
+	- CHANGED THE DEFAULT RUN-TIME LINKING TO "MULTITHREADED
+	  DLL". You'll need to change your project settings to
+	  use this as well or you'll get errors.
+
+	- Added new --disable-gl option to configure script.
+
+	- Added new const const pointer versions of pixmap
+	  functions to eliminate an annoying pointer warning
+	  message that was generated by the Sun and other C++
+	  compilers.
+
+	- Eliminated all "var hides class::var" warnings.
+
+	- Eliminated all "string literal converted to char *"
+	  warnings.
+
+	- OS/2 updates from Alexander Mai.
+
+	- Tidied up the HTML documentation to be more standards
+	  compliant.
+
+	- Compiling with -DBOXX_BUGS will work around some
+	  problems with the newest X drivers that BoXX delivers,
+	  the problems all affect use of Overlays for normal X
+	  drawing and OpenGL drawing. Normal compilation is
+	  unchanged.
+
+	- The file chooser buttons use user_data() rather than
+	  the label to decide what to do, allowing the label to
+	  be somewhat cleaner.
+
+	- Selection color on X changed to blue, to match what
+	  happens on Windows now.
+
+	- Added support for AIX (static library only).
+
+	- Added support for SunOS 4.x
+
+	- Now process WIN32 WM_ACTIVATEAPP message to reset the
+	  key and button states in Fl::e_state.
+
+	- Fl_has_idle only tested N-1 callbacks and missed one.
+
+	- Restored WM_SYNCPAINT handling under WIN32; this fixed
+	  a refresh bug under some versions of Windows.
+
+	- Check for OpenGL headers before checking to see if
+	  OpenGL is supported.  This should eliminate compile
+	  errors due to missing non-FLTK header files...
+
+	- Add -D_INCLUDE_POSIX_SOURCE option when compiling with
+	  the HP compilers.
+
+	- Replaced remaining _WIN32 symbols with WIN32
+
+	- Removed reference to unused GL/glu.h header file, which is missing on
+	  some Linux systems.
+
+	- Fl_Gl_Window has a new method to allow you to get and set the context:
+
+	      void Fl_Gl_Window::context(void*, int destroy = 0)
+	      void* Fl_Gl_Window::context() const;
+
+	  Return or set a pointer to the GLContext that this window is
+	  using. This is a system-dependent structure, but it is portable to
+	  copy the context from one window to another. You can also set it to
+	  NULL, which will force FLTK to recreate the context the next time
+	  make_current() is called, this is useful for getting around bugs in
+	  OpenGL implementations.
+
+	  If destroy_flag is true the context will be destroyed by fltk when
+	  the window is destroyed, or when the mode() is changed, or the next
+	  time context(x) is called.
+
+	- Some cleanup of Fl_Gl_Choice to move most of the system dependent
+	  #ifdefs into Fl_Gl_Choice.cxx.
+
+	- Fl_Gl_Window does not set drawbuffer(BACKBUFFER) for
+	  single-buffered windows.
+
+	- Fl_Input::replace(...) correctly updates the display
+	  if the replaced region does not include the mark,
+	  point, or selected region.
+
+	- Added Fl::add_check(...), Fl::remove_check, and
+	  Fl::has_check. These are similar to idle callbacks but
+	  are only called just before it waits for new events.
+	  They can be used to watch for changes in global state
+	  and respond to them.
+
+	- "accu-timer": some changes to repeat_timeout that seem
+	  to make it accurate on Unix and WIN32 at speeds up to
+	  500000 timeouts/second (and 700000 on Linux), and
+	  within about .001% as accurate as the system clock.
+
+	- Fix to Fl_Valuator::step() by Guillermo Andrade.
+
+	- Fixed the FLUID write-menu bug introduced in 1.0.10
+
+	- Fl::flush() now calls GdiFlush() under WIN32 to
+	  ensure that all graphics are drawn.
+
+	- fl_curve() now uses a much better algorithim to figure
+	  out how many pieces to cut the curve into.
+
+	- FLUID now uses GetTempPath() under WIN32 to determine
+	  where to store the clipboard.
+
+	- Right-ctrl does not delete selected text in Fl_Input,
+	  until you type a composed character.
+
+	- Added simple FLTK and FLUID manual pages.
+
+	- Fl_Gl_Window leaked memory under WIN32.
+
+	- The colbrowser demo was missing an include file when
+	  compiled under OS/2.
+
+
+CHANGES SINCE FLTK 1.0.9
+
+	- Added a strcasecmp() function to FLUID; AIX doesn't
+	  have it.
+
+	- Bug #115509: Fl_Scroll not repainting background.
+
+	- Updated the configure script and makeinclude.in file
+	  to work with the Sun PRO compilers.
+
+	- Disabled the WIN32 async socket select code by default:
+	  it doesn't seem to work anymore...
+
+	- Fl::below_mouse() was incorrectly clearing e_is_click;
+	  this prevented any double-clicks from getting
+	  through...
+
+	- No longer clear Fl::keysym on every event, this makes
+	  better back compatability and fixes Win2000
+
+	- FLUID now restores which tab in an Fl_Tabs was
+	  selected when loads .fl files.
+
+	- Hack to fix the annoying "raise another application
+	  when a modal window is closed" problem on WIN32.
+
+	- Fl_Tabs now draws the background behind the tabs.
+
+	- Fl::set_fonts() on WIN32 fixed to work before the
+	  first window is shown.
+
+	- CUA function keys, code submitted by George Yohng
+	  <yohng@drivex.dosware.8m.com>
+
+	- Another attempt to get glut.h to work on WIN32.
+
+	- Fl_Menu_::add() ignores '&' signs when comparing menu
+	  items, so you don't have to make the shortcuts the
+	  same all the time.
+
+	- Fixed bit-flipping patterns in WIN32 bitmap code.
+
+	- Fixed size of data written by gif images to .C files
+
+	- Menu titles and buttons in the menubar can be images
+	  (allows it to be used as a toolbar)
+
+	- Reads selectBackground from the xrdb database to set
+	  the selection color. Adding this to your .Xdefaults
+	  will make fltk and Motif programs look much more
+	  Windoze-like:
+
+	      *selectForeground: white
+	      *selectBackground: #000080
+
+	- FL_WHEN_RELEASE on Fl_Input will now do the callback
+	  when the input field is hidden, for instance when it
+	  is on a tab and the user switches to another tab.
+
+	- Fl_Gl_Window with an overlay on X always resized any
+	  child windows even if you turned resizable() off
+	  because it turned it back on to resize the overlay
+	  window. This patch avoids changing resizable().
+
+	- Fix so multiple Fl::add_idle() calls works
+
+	- The input focus got messed up if you called
+	  Fl_Tabs::value(x) and there was something that took
+	  focus on an earlier tab.
+
+	- Removed some (not all) of the warnings when compiled
+	  with -Wwrite-strings, this should also get similar
+	  warnings Solaris produces.
+
+	- Made Fl_Browser not hide the Fl_Widget::show() method
+
+	- Changes & additions for OS/2 from Alexander Mai
+
+	- Patch from Mike Lindner to make the turning on/off of
+	  scrollbars on Fl_Scroll smarter.
+
+	- Added missing FL_EXPORT for Fl_Valuator::format()
+
+	- Shortcuts for "buttons" in a Fl_Menu_Bar work again.
+
+	- Fix for cut/paste support and Xdnd.
+
+	- Shortcuts for submenu titles in a menubar pop up the
+	  submenu (rather than calling the callback)
+
+	- Added documentation for GL_SWAP_TYPE
+
+	- Buttons with box(FL_NO_BOX) did not draw.  Apparently
+	  they did in older versions of fltk, I restored this.
+	  (bug 108771)
+
+	- Removed 8-bit colormap drawing code that was not doing
+	  anything in fl_draw_image due to the colormap
+	  allocation changes.  I also made fl_color(r,g,b)
+	  actually allocate the requested color rather than the
+	  nearest fltk color-cube color (this is only done for
+	  the first color that maps to a given entry in the fltk
+	  color cube), the result is that pixmaps with a small
+	  number of colors are drawn much more accurately. The
+	  resulting code seems to produce better images and is a
+	  good deal smaller!
+
+	- Fixed makeinclude.in so CFLAGS are used for c source
+	  code instead of CXXFLAGS. (bug 108694)
+
+	- Better fix for gif files suggested by pauly (bug
+	  108770)
+
+	- Performance of Fl_Gl_Window may be improved on some
+	  types of OpenGL implementations, in particular MESA
+	  or other software emulators, by setting the
+	  GL_SWAP_TYPE environment variable.  This variable
+	  declares what is in the back buffer after you do a
+	  swapbuffers:
+
+	      setenv GL_SWAP_TYPE COPY
+
+	      This indicates that the back buffer is copied to
+	      the front buffer, and still contains it's old
+	      data. This is true of many hardware
+	      implementations.  Setting this will speed up
+	      emulation of overlays, and widgets that can do
+	      partial update can take advantage of this as
+	      damage() will not be cleared to -1.
+
+	      setenv GL_SWAP_TYPE NODAMAGE
+
+	      This indicates that nothing changes the back
+	      buffer except drawing into it.  This is true of
+	      MESA and Win32 software emulation and perhaps some
+	      hardware emulation on systems with lots of memory.
+
+	  All other values for GL_SWAP_TYPE, and not setting
+	  the variable, cause fltk to assumme that the back
+	  buffer must be completely redrawn after a swap.
+
+	  This is easily tested by running the gl_overlay demo
+	  program and seeing if the display is correct when
+	  you drag another window over it or if you drag the
+	  window off the screen and back on. You have to exit
+	  and run the program again for it to see any changes
+	  to the environment variable.
+
+	- Optimized colormap usage on 8-bit displays with
+	  images. New code only allocates colors as they are
+	  needed (still converts indexed images to full RGB and
+	  dithers, tho...)
+
+	- Fixed .gif files in fluid, they were broken by the fix
+	  for large .xpm files in version 1.0.9.
+
+	- Fix for OpenGL hardware overlays with the transparent
+	  index != 0. Tested on the brand new HP Linux
+	  Workstations, this is the only bug encountered.  Both
+	  X and OpenGL hardware overlay works perfectly on
+	  these, though configue may not enable it by
+	  default...)
+
+	- Fl_Choice and all other Fl_Menu_ subclasses draw the
+	  items using textcolor() as the default color of the
+	  text.
+
+	- Fix suggested by Stuart Levy to fix scrolling when
+	  deleting items from the browser.
+
+	- Replaced the -$(MAKEFLAGS) with $(MFLAGS) as per the
+	  gmake documenation.  Apperntly this works with other
+	  make programs and MAKEFLAGS is passed invisibly by
+	  gmake, though the documenation is not too clear...
+
+
+CHANGES SINCE FLTK 1.0.8
+
+	- More documentation fixes.
+	- GLUT_STROKE_*_ROMAN in glut.h are defined as 0,1 on
+	  WIN32 to match the glut header files there.
+	- Added Fl::has_timeout() and Fl::has_idle() functions.
+	- Added new Fl::repeat_timeout() method that
+	  measures time from when the last timeout was called. 
+	  This has slightly less overhead and allows accurate
+	  spacing of timeouts.
+	- More Cygwin changes
+	- FLUID could crash with identifiers with trailing
+	  whitespace.
+	- Fixed the XPM loading code in FLUID to handle files
+	  longer than 2048 lines.
+	- Added a bunch of missing FL_EXTERN's to glut.h to
+	  eliminate GLUT linking errors under WIN32.
+	- Fix for sliders so that clicking on one with a small
+	  (or zero) slider_size will not move the slider.
+	- fl_shortcut.cxx didn't export fl_old_shortcut() in the
+	  WIN32 DLL.
+	- Fixed xpaint link in the documentation.
+	- Included Fl_Input word-wrap fixes from Alexander Rabi
+	  Beels. This will not affect things much because
+	  word-wrap is normally disabled.
+	- Patch from Stuart Levy so the *last* widget in an
+	  Fl_Pack may be resizable.  This should be compatable
+	  because resizable didn't do anything before so there
+	  was no reason to set it.
+	- Cleaned up the timeout and Fl::wait() code.  The new
+	  code calls the clock function less than half as much,
+	  which results in a noticable performance improvement
+	  in some apps.
+	- Fl::wait(time) with a time greater than the system can
+	  handle (24.855 days on NT, the same on some Unix
+	  systems) will now act as though the time is infinity. 
+	  Before it would do unpredictable things.
+	- "USE_POLL" now compiles and works, although it is
+	  disabled by default. poll() is an alternative to the
+	  UNIX select() call which is available on some version
+	  of UNIX and may be faster depending on the platform;
+	  try it by editing config.h.
+	- The WIN32 USE_ASYNC_SELECT code now does translation
+	  and dispatching of the select events; this makes
+	  Windows a lot happier.
+	- Added a check for an open display in Fl::wait() so
+	  that you don't need an open window under X to call it.
+
+	  [changes in snapshot 2]
+
+	- fl_old_shortcut() wasn't being exported in the WIN32 DLL
+	  project.
+	- Updated Cygwin and Mingw makefiles.
+	- Updated the BC++ project file.
+	- You can no longer insert control chars into Fl_Int/Float_Input.
+	- Fl_Multiline_Input now resets the horizontal position when
+	  focus is changed; this caused problems when multiple multiline
+	  widgets were used in an application.
+	- All handle() methods are now public, and all draw() methods are
+	  now protected in FLTK widgets.
+	- More fixes to the OpenGL overlay code on win32.  This now
+	  seems to work quite reliably on several different pieces of
+	  hardware. Apparently doing SetLayerPaletteEntries with a
+	  palette larger than the overlay size caused the drivers to
+	  screw up in unpredictable ways. Also SwapBuffers swapped both
+	  the overlay and main window, which is not what fltk's
+	  interface wanted, this was easy to fix however.
+	- Patch for full scrollbars so that clicking on them does not
+	  move anything.
+	- Documentation fixes.
+	- Better horizontal scrolling of Fl_Input when cursor is near
+	  the end of the line.
+	- Fl_Input::value(x) selects all text.
+	- Fl_Output and Fl_Multiline_Output would scroll to the end
+	  of the text.
+	- filename_isdir() now drops any trailing slash from the
+	  filename (needed for Windows)
+	- Added return type for main() function in line_style demo.
+	- Running FLUID with the "-cs" option writes the I18N message
+	  file.
+	- The WIN32 version of XParseGeometry() didn't initialize some
+	  variables.  This caused a compiler warning but did not affect
+	  the actual code.
+
+	  [changes in snapshot 1]
+
+	- EMail changes - fltk-bugs@easysw.com now officially
+	  fltk-bugs@fltk.org.
+	- The FLTK DLL project file didn't include fl_compose.cxx
+	- Dropped the GCC -fno-rtti option since it caused problems
+	  with existing programs.
+	- Moved the .fl rules back to the test directory.
+	- Fixed some makefile and spec file problems.
+	- Fixed hardware overlays.  The problem was the new
+	  fl_clipped() code, which tests against the current window
+	  size.  The hardware overlay code did not set the current
+	  window when drawing the overlay.  I needed hardware overlay
+	  for DD's code, I'm not sure if these fixes are good enough to
+	  enable this in our general release.  Hardware overlay still
+	  only works on SGI Irix.
+	- Some patches to turn off the MSVC++ -Oa (assumme no aliasing)
+	  optimization flag.  Suprisingly this only broke a few parts
+	  of fltk, or at least these are the only ones I found.
+	- Does not unmap child windows when the main window is
+	  iconized.  This reduces flashing when the window is
+	  deiconized.
+	- Fl::key() is set to zero by all events except key down/up. 
+	  This will allow you to reliably test if an event or callback
+	  was produced by a keystroke.  Fixes the bug posted about
+	  stopping Escape from closing the window.
+	- User defined cursors on OpenGL windows slowed down NT a
+	  *LOT*.  Some attempts to fix this by turning off the cursor
+	  while drawing the window.
+	- Filename completion in the file chooser works better on NT. 
+	  Typing TAB fixes the case of everything you typed to match
+	  the shortest name that can be completed.
+
+
+CHANGES SINCE FLTK 1.0.7
+
+	- Many documentation changes/fixes/improvements.
+	- FLUID didn't save Fl_Double_Window's as
+	  double-buffered windows.
+	- Fl_Menu_ text color is used if Fl_Menu_Item text color
+	  is not set.
+	- Added Fl::first_window(window) method to change the
+	  "top" window that is used when showing modal windows.
+	  By default it is the window the user last
+	  clicked/typed in.
+	- The Fl_Menu::global() handler now uses the current top
+	  window instead of the menu bar for modal stuff.
+	- Added fl_line_style() function to set the line style. 
+	  Note that user-defined line styles ONLY WORK UNDER X11
+	  and Windows NT/2000. Windows 95/98 do, however,
+	  support the "standard" line styles.
+	- Fl::wait() does not return immediately when no windows
+	- XForms keyboard shortcuts using hex keycode constants
+	  now work.
+	- Updated the configure script for *BSD and to turn off
+	  exceptions and RTTI in the FLTK library itself (does
+	  not affect applications which use these things)
+	- FLUID now supports I18N using the POSIX or GNU
+	  mechanisms.
+	- Fixed definition of glutBitmapWidth to match header
+	  file.
+	- Does not turn visible() on when a window is iconized()
+	  or if a modal window is shown and it's parent is
+	  iconized.  This allows the code "while (w->visible()
+	  && w->damage()) Fl::check();" to reliably wait for the
+	  window to be mapped and drawn the first time.
+	- Setting box(FL_NO_BOX) on a button makes it an
+	  invisible overlay
+	- FL_NORMAL_SIZE is now a global variable so you can
+	  change the default text size prior to creating your
+	  widgets.
+	- Menus now draw properly with a box type of
+	  FL_FLAT_BOX.
+	- Cygwin fixes to compile in POSIX mode.
+	- Fl_Value_Input callback can call value() or
+	  destructor.
+	- OpenGL overlays now work under Windows NT!
+	- Fl_Slider and Fl_Scrollbar could cause a divide by
+	  zero.
+	- Clicking in an Fl_Input field no longer selects the
+	  whole field, it just moves the text cursor.
+	- Tru64 UNIX fixes for filename_list()
+	- Fl_Browser now draws itself properly when deactivated.
+	- FLUID GUIs now use Courier font for all code input.
+	- The FLUID OK and Cancel buttons are now all shown in
+	  the same order in all windows.
+	- Fixes to compile under GCC 2.95.2
+	- Fixed the BC5 project files.
+	- FL_LEFT_MOUSE and friends are now in
+	  <FL/Enumerations.H>
+	- Fixes for fake OpenGL overlay code under WIN32.
+	- Message windows are now resizeable.
+	- On WIN32 non_modal (but not modal) windows have the
+	  close and size boxes.
+	- Fl_Button and friends didn't honor the
+	  FL_WHEN_NOT_CHANGED condition.
+	- Disabled XDBE on all platforms.
+	- XGetDefault patch from James Roth
+	- New fl_open_display(Display *) function to allow FLTK
+	  to share a display connection with another toolkit
+	  (like Xt, GTK, etc.)
+	- Shortcut labels for special keys should now display
+	  properly under WIN32.
+	- fl_set_fonts() did not reuse fonts.
+	- Fixed shortcut problem under WIN32 when the focus
+	  window changes.
+	- "dead" keys should now work under X11.
+	- Fixes to make FLTK compile with GCC 2.95.2
+	- FL_SHORTCUT fix for I18N.
+	- Fixed cut/paste problems under WIN32
+	- FLUID now produces correct code for nested class
+	  destructors.
+	- Nested windows should now redraw properly under WIN32.
+	- "table" is now static in fl_cursor.cxx
+	- Fl_Chart used the textcolor() and not the color() for
+	  horizontal bar charts.
+	- Now set the input hint for TWM and TWM-derived window
+	  managers.
+	- Now look for TrueColor visual if FLTK is compiled with
+	  USE_COLORMAP == 0.
+	- Fl_Scrollbar could generate a divide-by-0 error if the
+	  min and max values were the same.
+	- Fl_Menu_::remove() now removes whole submenus if
+	  needed.
+	- Scrollbar buttons now draw themselves pushed in as
+	  needed.
+	- Fixed the gl_overlay demo (and gl overlays in general)
+	  when they are faked with no hardware and the window is
+	  resized.
+	- Selections weren't shown in Fl_Browser widgets when an
+	  item used the @B (background) format.
+	- Windows can now be resized by the program under X11
+	  for more window managers.
+	- OS/2 makeinclude updates.
+	- Added Fl.H required by an inline function in
+	  Fl_Repeat_Button.H
+	- Fl_add_idle adds new functions to the end of the queue
+	  ring, rather than the start, so they are executed in
+	  the order added, and a callback that adds itself does
+	  not prevent others from being called.
+	- FLUID lets you type in code that starts with '#' for
+	  cpp directives.
+	- XBell() could be called before the X11 display was
+	  opened, causing a segfault.
+	- Fixed Fl_Gl_Window::ortho() - Borland C++ doesn't
+	  define GLint to "int", but instead to "long"...
+	- Fixed Fl_Browser scrollbars within an Fl_Scroll
+	  widget.
+	- Fl_Output (and non-focused Fl_Input) now scroll in
+	  response to position()
+	- Fl_Input now does not scroll horizontally if the
+	  entire string will fit in the widget.
+	- Fl_Scrollbar didn't push the right arrow buttons when
+	  you clicked outside the scroller.
+	- Now use WSAAsyncSelect() for better socket performance
+	  with Fl::add_fd()
+
+
+CHANGES SINCE FLTK 1.0.6
+
+	- Fixed Fl_Input_ bug under WIN32 - no longer stop accepting input
+	  when one of the "Windows" keys is pressed.
+	- Now call TranslateEvent for all events under WIN32.
+	- Fixes for OpenBSD and NetBSD
+	- The FL_CURSOR_HAND cursor now uses the IDC_HAND cursor instead of
+	  IDC_UPARROW under Windows 98 and 2000.
+	- Fl_Scrollbar now does a page-up/down when you click outside the
+	  scroller.
+	- Fl_Window::show(0, NULL) causes core dump
+	- Fixed a compile-time error in fl_call_main.c for Borland C++.
+	- "fluid -c filename.fl" would try to open an X display if the
+	  FLUID file contained an Fl_Browser widget.
+	- Fl_Browser now correctly measures items with @C or @B color
+	  formatting commands.
+	- Fixed a bitmap drawing bug for WIN32 (bit reversal table was wrong)
+	- fl_xyz() dialogs now set a title in the title bar.
+	- fl_alert() sounds the bell under X11.
+	- fl_xyz() dialogs now call MessageBeep() under WIN32.
+	- Fl_Browser_ didn't draw the selection box with the inactive color
+	  when the browser wasn't activated.
+	- Fl_Browser now responds to FL_KEYBOARD as well as FL_SHORTCUT.  If
+	  you subclass it to accept focus then keyboard navigation will work.
+	- Fl_Tile and Fl_Tabs do their callback when the user changes their
+	  display.
+	- Made some of the private methods of Fl_Browser protected.
+	- Now set win_gravity correctly, this helps some X
+	  window managers that use it position the window where
+	  FLTK wants it to be.
+	- 0-width browsers crashed.
+	- Minor change: if the X window manager does not do
+	  anything else with windows that don't have their
+	  position specified, the windows appear centered in the
+	  screen, rather than in the top-left corner.  This
+	  happened with modal windows under Irix 4Dwm.  This
+	  also causes windows to be centered when no window
+	  manager is running, which might be useful for
+	  installation gui programs?
+	- Clicking in an Fl_Input field the first time selects the entire
+	  field.
+	- Clicking the middle mouse button in an Fl_Input field now inserts
+	  the text at the indicated position instead of the cursor position.
+	- Drag-selecting text in an Fl_Input field now copies the text
+	  automatically.
+	- Fl::flush() no longer calls the draw() method for invisible windows.
+	- Calling deactivate() on an invisible widget could cause an
+	  infinite loop in some obscure cases.
+	- Added #pragma's for SGI C++ compilers - the 6.{23} X headers had
+	  errors in them.
+	- Fl_Gl_Window::ortho() changed so that text and images
+	  are not erased if the origin is off the left/bottom of the
+	  window.
+	- Small change to Fl_Input so that a click that gives it
+	  the focus also selects all the text.
+	- Fixed a slider drawing problem.
+	- You can now add/delete children of Fl_Tabs widgets whether or
+	  not they are visible.
+	- Now embed woff options for SGI C++ compilers (gets rid of X11
+	  header warnings)
+	- draw_pixmap used a cast that the Digital UNIX C++ compiler didn't
+	  like.
+	- The GLUT function key constants were off by one.
+	- The XPM reading code didn't handle RGB colors other than #rrggbb.
+
+
+CHANGES SINCE FLTK 1.0.5
+
+    - Fl_win32.cxx defined WM_MOUSE_LEAVE instead of WM_MOUSELEAVE.
+    - Fl_get_key_win32.cxx needed to include <ctype.h>
+    - gl_draw_pixmap.cxx needed a pointer cast for ANSI C++.
+    - Fl_Repeat_Button didn't always delete its timeout.
+    - Now keep track of the current OpenGL context; this provides
+      significant performance improvements for OpenGL applications
+      with a single context.
+
+
+CHANGES SINCE FLTK 1.0.4
+
+    - Fl_Roller didn't handle a width and height of 0.
+    - filename_list() fix for FreeBSD.
+    - Fixed RPM install docos - needed "--install" option...
+    - Fl_Browser_ wouldn't draw the vertical scrollbar right away if it
+      added a horizontal one which covered the last line.
+    - Fl_Tabs problems - single-character labels don't show up (problem in
+      measure_tabs() or measure_label() methods?), and doesn't clear top
+      tab area before drawing tabs.
+    - Fl_Browser needs a destructor.
+    - fl_draw_label() quoted characters between 0x80 and 0xa0, which
+      caused problems for some programs using the WinANSI character set.
+    - FLUID didn't handle declared class destructors.
+    - Fixed another WIN32 cut/paste bug.
+    - Fl_Tabs didn't work properly when there was only 1 tab.
+    - Fl_Menu::add() didn't delete the old array.
+    - Fl_Repeat_Button didn't delete its timeout when disabled.
+    - fl_draw() would crash if no font was set (now defaults to
+      a 14-pixel Helvetica font)
+    - Can't forward declare classes; need to check for "class ", "struct ",
+      "union ", etc.  See Bill's message
+    - Added #pragma around xlib.h for IRIX
+    - FL_KEYBOARD events have the correct x/y when sent to child X
+      windows. Note that if you worked around this bug by adjusting the
+      x/y yourself you will have to change your code. In addition all
+      events have the correct x/y when sent to the grab() widget.  And
+      the code to do all this was simplified a lot.
+    - The XPM code didn't handle named colors with spaces in the names.
+    - Pressing ESCape closed the window with pointer focus, even if there
+      was a modal window open (now closes the modal window).
+    - FLUID no longer produces trigraphs accidentally in the image data.
+    - FLUID uses string constant concatenation to produce shorter image
+      data.
+    - The Fl_Group deletion code crashed if there was exactly one child
+      widget.
+    - Simulated overlays in single-buffered Fl_Gl_Windows now draw
+      correctly (though very slowly as it requires the entire window to
+      be redrawn to erase the overlay).  This fix ported our Digital
+      Domain programs better to systems with no overlay hardware.
+    - Added support for extern "C" declarations in FLUID.
+    - Added Fl_Pack support to FLUID.
+    - Fixed the order of #include's in FLUID generated header files.
+    - Fixed detection of vsnprintf and snprintf under HP-UX 10.20 once
+      and for all.
+    - The checkers demo did not compile with GCC 2.95
+    - FLUID didn't output virtual destructors properly.
+    - Added inline "make_visible()" method to Fl_Browser.
+    - Fl::wait() now returns immediately if any timeouts are
+      called.
+    - 16-bit XPM files are now properly handled.
+    - Fl_Window::resize() was missing FL_EXPORT (caused problems
+      with Windows DLLs)
+    - FLUID was writing extern declarations twice.
+    - New FLUID arrow key functionality: arrows move by one pixel, shift+arrow
+      resizes, ctrl+arrow steps by grid
+
+
+CHANGES SINCE FLTK 1.0.3
+
+    - Documentation updates
+    - Fl_Browser::bottomline(size) didn't scroll to the bottom
+      if the second-to-last line was visible.
+    - fl_wait() didn't poll FDs properly for WIN32.
+    - Fixed DLL definitions for BC++.
+    - FLUID now handles nested classes properly.
+    - The "connect" demo now does a wait() for the PPP process
+      so that you aren't left with a lot of zombie processes.
+    - Fixed the FLTK colormap to use FF instead of F4 for full
+      intensity values.
+    - Minor change to scrollbar drawing code to match other
+      toolkits.
+    - New selections would cancel themselves out in WIN32.
+    - The header file links were broken in the IRIX
+      distributions.
+    - fl_elapsed() now always uses GetClockTick() for WIN32.
+    - fl_display is now initialized to GetModuleHandle(NULL) -
+      this fixes problems people had with Cygwin and MingW32.
+    - WinMain() is no longer compiled in with Cygwin and
+      MingW32; it wasn't being used for those compilers anyways.
+    - Added Solaris compiler options to configure script.
+    - Fl_Value_Input wouldn't update properly if you set the
+      value from a callback.
+    - Fl_Tile wouldn't resize if the resizeable widget was the
+      last child.
+    - Was missing #include <ctype.h> and #include <stdlib.h> in
+      several files, which caused problems on some platforms.
+    - Fixed another case where Fl_Browser_ could get in an
+      infinite resizing loop.
+    - Fl_win32.cxx now includes <FL/filename.H> to export missing
+      DLL symbols.
+    - FLUID didn't handle member functions that include the
+      scope operator.
+    - Fl_Chart was dividing by 0 if there were no data samples
+      or if they were all the same (min == max).
+
+
+CHANGES SINCE FLTK 1.0.2
+
+    - XDBE is now enabled for IRIX 6.[234] as well as 6.5.
+    - FLUID didn't write the when() condition properly.
+    - Tab/space/backtab/backspace can be used to navigate
+      through menus.
+    - Changed $(DSONAME) in the src/Makefile to "libfltk.so.1
+      libfltk.sl.1".
+    - Fl_Browser could read past the end of the string when
+      computing the item height.
+    - Fl_Browser could get in an infinite loop when checking to
+      see if scrollbars needed to be displayed.
+    - FLUID now honors the return type of the outermost widget. 
+      This was a problem when substituting Fl_Group in an
+      Fl_Window widget.
+    - Fl_Menu_::copy() wasn't allocating a power of 2 for the
+      array size.
+    - FLWM would crash if fl_xmousewin was deleted.
+    - The fast_slow demo now uses output widgets.
+    - Timers under WIN32 were unreliable.
+
+
+CHANGES SINCE FLTK 1.0.1
+
+    - Documentation updates
+    - The Visual C++ project files didn't include fl_add_idle.cxx.
+    - LIBRARY/DSO name inconsistencies in src/Makefile.
+    - src/Makefile didn't clean the DSO.
+    - The valuator demo now has only a single callback.
+    - The code looked for HAVE_SYS_SELECT_H, but the
+      config file uses HAVE_SYS_SELECT.
+    - Fl_Image redraw not quite right under X11 or WIN32
+    - Problems with timeouts & cube demo under WIN32
+    - FLUID problems with inline functions.
+    - Documentation fixes...
+    - Fl_Browser::item_height() didn't handle blank lines or
+      non-default fonts properly.
+    - FL/math.h didn't have #ifndef...#define...#endif guards
+      against multiple inclusion...
+    - Fl_Menu_::copy() fix - didn't allocate power of 2...
+    - Fl::damage() now remains true until all windows are actually
+      redrawn.
+    - Fl_Widget destructor, hide(), and deactivate() methods no longer
+      send FL_LEAVE, FL_RELEASE, or FL_UNFOCUS events to the widget
+      (which could cause applications to crash).
+    - FLUID now outputs symbolic names for align() and when().
+    - Fixed select() to use maxfd + 1 instead of maxfd.
+    - Added "Fl::remove_fd(fd, when)" function so you can remove the
+      read and write callbacks separately.
+    - The Fl::add_fd() and Fl::add_timeout() arrays are now dynamically
+      allocated.
+    - FLUID didn't always turn the FL_SUBMENU flag on for submenu titles.
+    - The "extra code" in FLUID now is placed before the "o->end()" call
+      for Fl_Group and its derived classes.
+    - You can now set a FL_Window widget's class in FLUID to Fl_Group to
+      generate a function or class that builds part of a GUI (i.e. no window).
+    - FLUID now displays "Save file before exiting?" with the standard yes,
+      no, and cancel buttons rather than "Discard changes?".
+    - Fl_Menu_::add() now works with any type of menu, even one set with
+      the menu() method.
+    - The keypad keys were not always decoded properly under X11.
+    - Some pointers were not being turned off when widgets were deleted,
+      which caused some applications (like FLWM) to crash.
+
+
+CHANGES SINCE FLTK 1.0
+
+    - Documentation fixes.
+    - Fl::check() didn't return the correct value, breaking a number
+      of applications.
+    - Fixed fluid bug that caused styles patch to crash when you delete
+      a menu item.
+    - Updated valuators demo to put the values in the gui box.
+    - Fl_Browser_::item_height() didn't always compute the correct
+      value.
+    - Fixed the alignment of Fl_Choice text.
+    - Fixes for OS/2.
+    - Fl_Menu_Item::clear() didn't clear value.
+    - Added some changes to make FLTK work with Borland C++.
+    - ANSI C++ fixes.
+    - Plugged a memory leak in the fractal demo.
+    - Fl::add_timeout() didn't work under WIN32 with small values.
+    - The configure script and makefiles now define DSONAME and
+      use the static library for all example programs.    
diff --git a/Utilities/FLTK/CMake/CheckFunctionWithHeaderExists.cmake b/Utilities/FLTK/CMake/CheckFunctionWithHeaderExists.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..46694e82a58e8fc7235a93474e79e8978fda88e2
--- /dev/null
+++ b/Utilities/FLTK/CMake/CheckFunctionWithHeaderExists.cmake
@@ -0,0 +1,54 @@
+#
+# Check if the symbol exists in include files
+#
+# CHECK_FUNCTIONWITHHEADER_EXISTS - macro which checks the symbol exists in include files.
+# SYMBOL - symbol
+# FILES  - include files to check
+# VARIABLE - variable to return result
+#
+
+MACRO(CHECK_FUNCTIONWITHHEADER_EXISTS SYMBOL FILES VARIABLE)
+  IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+    SET(CHECK_SYMBOL_EXISTS_CONTENT "/* */\n")
+    SET(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
+    IF(CMAKE_REQUIRED_LIBRARIES)
+      SET(CHECK_SYMBOL_EXISTS_LIBS 
+        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
+    ENDIF(CMAKE_REQUIRED_LIBRARIES)
+    FOREACH(FILE ${FILES})
+      SET(CHECK_SYMBOL_EXISTS_CONTENT
+        "${CHECK_SYMBOL_EXISTS_CONTENT}#include <${FILE}>\n")
+    ENDFOREACH(FILE)
+    SET(CHECK_SYMBOL_EXISTS_CONTENT
+      "${CHECK_SYMBOL_EXISTS_CONTENT}\nint main()\n{\n${SYMBOL};return 0;\n}\n")
+
+    FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c 
+      "${CHECK_SYMBOL_EXISTS_CONTENT}")
+
+    MESSAGE(STATUS "Looking for ${SYMBOL}")
+    TRY_COMPILE(${VARIABLE}
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c
+      CMAKE_FLAGS 
+      -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS}
+      "${CHECK_SYMBOL_EXISTS_LIBS}"
+      OUTPUT_VARIABLE OUTPUT)
+    IF(${VARIABLE})
+      MESSAGE(STATUS "Looking for ${SYMBOL} - found")
+      SET(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
+      FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeOutput.log 
+        "Determining if the ${SYMBOL} "
+        "exist passed with the following output:\n"
+        "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c:\n"
+        "${CHECK_SYMBOL_EXISTS_CONTENT}\n")
+    ELSE(${VARIABLE})
+      MESSAGE(STATUS "Looking for ${SYMBOL} - not found.")
+      SET(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")
+      FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeError.log 
+        "Determining if the ${SYMBOL} "
+        "exist failed with the following output:\n"
+        "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c:\n"
+        "${CHECK_SYMBOL_EXISTS_CONTENT}\n")
+    ENDIF(${VARIABLE})
+  ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(CHECK_FUNCTIONWITHHEADER_EXISTS)
diff --git a/Utilities/FLTK/CMake/FLTKConfig.cmake.in b/Utilities/FLTK/CMake/FLTKConfig.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..6cbd3f6d25f8d1589691b4f38ea02192d297c441
--- /dev/null
+++ b/Utilities/FLTK/CMake/FLTKConfig.cmake.in
@@ -0,0 +1,39 @@
+#-----------------------------------------------------------------------------
+#
+# FLTKConfig.cmake - FLTK CMake configuration file for external projects.
+#
+# This file is configured by FLTK and used by the UseFLTK.cmake module
+# to load FLTK's settings for an external project.
+
+# The FLTK source tree.
+SET(FLTK_SOURCE_DIR "@FLTK_SOURCE_DIR@")
+
+# The FLTK include file directories.
+SET(FLUID_COMMAND "@FLTK_FLUID_COMMAND@")
+SET(FLTK_EXECUTABLE_DIRS "@FLTK_EXECUTABLE_DIRS@")
+SET(FLTK_LIBRARY_DIRS "@FLTK_LIBRARY_DIRS@")
+SET(FLTK_LIBRARIES "@FLTK_LIBRARIES@")
+SET(FLTK_INCLUDE_DIRS "@FLTK_INCLUDE_DIRS@")
+# OTB Add
+SET(FLTK_PLATFORM_DEPENDENT_LIBS "@FLTK_PLATFORM_DEPENDENT_LIBS@")
+
+# The C and C++ flags added by FLTK to the cmake-configured flags.
+SET(FLTK_REQUIRED_C_FLAGS "@FLTK_REQUIRED_C_FLAGS@")
+SET(FLTK_REQUIRED_CXX_FLAGS "@FLTK_REQUIRED_CXX_FLAGS@")
+
+# The FLTK version number
+SET(FLTK_VERSION_MAJOR "@FLTK_VERSION_MAJOR@")
+SET(FLTK_VERSION_MINOR "@FLTK_VERSION_MINOR@")
+SET(FLTK_VERSION_PATCH "@FLTK_VERSION_PATCH@")
+
+# Is FLTK using shared libraries?
+SET(FLTK_BUILD_SHARED_LIBS "@BUILD_SHARED_LIBS@")
+SET(FLTK_BUILD_SETTINGS_FILE "@FLTK_BUILD_SETTINGS_FILE@")
+
+# The location of the UseFLTK.cmake file.
+SET(FLTK11_USE_FILE "@FLTK_USE_FILE@")
+
+# The ExodusII library dependencies.
+IF(NOT FLTK_NO_LIBRARY_DEPENDS)
+  INCLUDE("@FLTK_LIBRARY_DEPENDS_FILE@")
+ENDIF(NOT FLTK_NO_LIBRARY_DEPENDS)
diff --git a/Utilities/FLTK/CMake/FLTKUse.cmake b/Utilities/FLTK/CMake/FLTKUse.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3512b5ef971584297ad82f53d21f955f5cb4866a
--- /dev/null
+++ b/Utilities/FLTK/CMake/FLTKUse.cmake
@@ -0,0 +1,68 @@
+IF(NOT FLTK11_FOUND)
+  MESSAGE(FATAL_ERROR "Something went wrong. You are including FLTKUse.cmake but FLTK was not found")
+ENDIF(NOT FLTK11_FOUND)
+
+# -------------------------------------------------------------
+# This macro automates wrapping of Fluid files
+# Specify the output variable name and the list of sources
+# The output variable can be directly added to the target.
+#
+# For example:
+#   FLTK_WRAP_FLUID(CubeView_SRCS CubeViewUI.fl)
+#   ADD_EXECUTABLE(CubeView CubeMain.cxx CubeView.cxx CubeView.h ${CubeView_SRCS})
+# -------------------------------------------------------------
+MACRO(FLTK_WRAP_FLUID VARIABLE)
+  FOREACH(src ${ARGN})
+    IF("${src}" MATCHES ".fl$")
+      GET_FILENAME_COMPONENT(fname ${src} NAME_WE)
+      GET_FILENAME_COMPONENT(fpath ${src} PATH)
+      GET_SOURCE_FILE_PROPERTY(gen ${src} GENERATED)
+      IF(gen)
+        SET(fluid_name "${src}")
+      ELSE(gen)
+        SET(fluid_name "${CMAKE_CURRENT_SOURCE_DIR}/${fpath}/${fname}.fl")
+        IF(NOT EXISTS "${fluid_name}")
+          SET(fluid_name "${CMAKE_CURRENT_BINARY_DIR}/${fpath}/${fname}.fl")
+          IF(NOT EXISTS "${fluid_name}")
+            SET(fluid_name "${fpath}/${fname}.fl")
+            IF(NOT EXISTS "${fluid_name}")
+              MESSAGE(SEND_ERROR "Cannot find Fluid source file: ${fpath}/${fname}.fl")
+            ENDIF(NOT EXISTS "${fluid_name}")
+          ENDIF(NOT EXISTS "${fluid_name}")
+        ENDIF(NOT EXISTS "${fluid_name}")
+      ENDIF(gen)
+      SET(cxx_name "${CMAKE_CURRENT_BINARY_DIR}/${fname}.cxx")
+      SET(h_name "${CMAKE_CURRENT_BINARY_DIR}/${fname}.h")
+      SET(${VARIABLE} "${${VARIABLE}};${cxx_name}")
+      ADD_CUSTOM_COMMAND(
+        OUTPUT ${cxx_name}
+        DEPENDS "${fluid_name}" "${FLUID_COMMAND}"
+        COMMAND ${FLUID_COMMAND}
+        ARGS -c ${fluid_name})
+      ADD_CUSTOM_COMMAND(
+        OUTPUT ${h_name}
+        DEPENDS "${fluid_name}" "${FLUID_COMMAND}"
+        COMMAND ${FLUID_COMMAND}
+        ARGS -c ${fluid_name})
+    ENDIF("${src}" MATCHES ".fl$")
+  ENDFOREACH(src)
+ENDMACRO(FLTK_WRAP_FLUID VARIABLE)
+
+
+# Make FLTK easier to use
+INCLUDE_DIRECTORIES(${FLTK_INCLUDE_DIRS})
+LINK_DIRECTORIES(${FLTK_LIBRARY_DIRS})
+
+# Load the compiler settings used for FLTK.
+IF(FLTK_BUILD_SETTINGS_FILE)
+  INCLUDE(CMakeImportBuildSettings)
+  CMAKE_IMPORT_BUILD_SETTINGS(${FLTK_BUILD_SETTINGS_FILE})
+ENDIF(FLTK_BUILD_SETTINGS_FILE)
+
+# Add compiler flags needed to use FLTK.
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLTK_REQUIRED_C_FLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLTK_REQUIRED_CXX_FLAGS}")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLTK_REQUIRED_EXE_LINKER_FLAGS}")
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLTK_REQUIRED_SHARED_LINKER_FLAGS}")
+SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLTK_REQUIRED_MODULE_LINKER_FLAGS}")
+
diff --git a/Utilities/FLTK/CMake/PlatformTests.cxx b/Utilities/FLTK/CMake/PlatformTests.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bfe97ac9512059f503c3caf59141bd4447959511
--- /dev/null
+++ b/Utilities/FLTK/CMake/PlatformTests.cxx
@@ -0,0 +1,81 @@
+#ifdef HAVE_LIBZ
+
+#include <zlib.h>
+
+int main()
+{
+	unsigned long compressedSize = 0;
+	unsigned char cd[100];
+	const unsigned char ud[100] = "";
+	unsigned long uncompressedSize = 0;
+
+	// Call zlib's compress function.
+	if(compress(cd, &compressedSize, ud, uncompressedSize) != Z_OK)
+		{
+		return 0;
+		}
+	return 1;
+}
+
+
+#endif
+
+#ifdef HAVE_LIBJPEG
+
+#include <stdio.h>
+#include <jpeglib.h>
+
+int main()
+{
+	struct jpeg_decompress_struct cinfo;
+	jpeg_create_decompress(&cinfo);
+	jpeg_read_header(&cinfo, TRUE);
+	return 1;
+}
+
+#endif
+
+#ifdef HAVE_LIBPNG
+#include <png.h>
+int main()
+{
+	png_structp png_ptr = png_create_read_struct
+		(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
+		 NULL, NULL);
+	png_infop info_ptr = png_create_info_struct(png_ptr);
+	png_set_sig_bytes(png_ptr, 8);
+	png_read_info(png_ptr, info_ptr);
+
+	return 0;
+}
+#endif
+
+#ifdef HAVE_PNG_H
+#include <png.h>
+int main() { retunr 0;}
+#endif
+
+#ifdef HAVE_PNG_GET_VALID
+#include <png.h>
+int main()
+{
+	png_structp png_ptr = png_create_read_struct
+		(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
+		 NULL, NULL);
+	png_infop info_ptr = png_create_info_struct(png_ptr);
+	png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
+	return 0;
+}
+#endif
+
+#ifdef HAVE_PNG_SET_TRNS_TO_ALPHA
+#include <png.h>
+int main()
+{
+	png_structp png_ptr = png_create_read_struct
+		(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
+		 NULL, NULL);
+	png_set_tRNS_to_alpha(png_ptr);
+	return 0;
+}
+#endif
diff --git a/Utilities/FLTK/CMakeLists.txt b/Utilities/FLTK/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4461ac0a22745529d85040fb1f822e90257d7c4c
--- /dev/null
+++ b/Utilities/FLTK/CMakeLists.txt
@@ -0,0 +1,410 @@
+# Main CMakeLists.txt to build the FLTK project using CMake (www.cmake.org)
+# Written by Andy Cedilnik and Julien Jomier
+
+PROJECT(FLTK)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.0)
+
+# The FLTK version
+SET(FLTK_VERSION_MAJOR "1")
+SET(FLTK_VERSION_MINOR "1")
+SET(FLTK_VERSION_PATCH "7")
+SET(FLTK_VERSION "${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}")
+SET(FLTK_VERSION_FULL "${FLTK_VERSION}.${FLTK_VERSION_PATCH}")
+
+SET(FLTK_LIBRARIES "fltk_images;fltk;fltk_gl;fltk_forms")
+
+# Executables and libraries should just go to bin
+SET(EXECUTABLE_OUTPUT_PATH "${OTB_BINARY_DIR}/bin" CACHE INTERNAL 
+  "Where to put the executables for FLTK"
+  )
+SET(LIBRARY_OUTPUT_PATH "${OTB_BINARY_DIR}/bin" CACHE INTERNAL 
+  "Where to put the libraries for FLTK"
+  )
+
+# Allow building shared libraries
+OPTION(BUILD_SHARED_LIBS "Build FLTK as a shared library" OFF)
+
+# Search for modules in the FLTK source dir first
+SET(CMAKE_MODULE_PATH "${FLTK_SOURCE_DIR}/CMake")
+
+#-----------------------------------------------------------------------------
+# Test for some required system information.
+FIND_PACKAGE(Threads)
+SET (CMAKE_USE_PTHREADS 
+  "${CMAKE_USE_PTHREADS_INIT}" CACHE BOOL "Use the pthreads library.")
+
+# We need ansi c-flags, especially on HP
+SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
+SET(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
+ 
+IF(WIN32)
+  IF(NOT CYGWIN)
+    IF(BORLAND)
+      SET( FLTK_PLATFORM_DEPENDENT_LIBS import32 )
+    ELSE(BORLAND)
+      SET( FLTK_PLATFORM_DEPENDENT_LIBS wsock32 comctl32 )
+    ENDIF(BORLAND)
+  ENDIF(NOT CYGWIN)
+ENDIF(WIN32)
+
+SET(FLTK_X11 1)
+SET(FLTK_APPLE 0)
+IF(APPLE)
+  OPTION(FLTK_APPLE_X11 "Use X11 on Mac instead of Carbon" OFF)
+  MARK_AS_ADVANCED(FLTK_APPLE_X11)
+  IF(NOT FLTK_APPLE_X11)
+    SET(FLTK_APPLE 1)
+    SET(FLTK_X11 0)
+    OPTION(FLTK_QUARTZ "Use Quartz instead of Quickdraw" OFF)
+  ENDIF(NOT FLTK_APPLE_X11)
+ENDIF(APPLE)
+
+IF(UNIX)
+  FIND_PACKAGE(X11)
+  SET( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} -lm)
+ENDIF(UNIX)
+
+IF(APPLE AND NOT FLTK_APPLE_X11)
+  SET( FLTK_PLATFORM_DEPENDENT_LIBS
+    "-framework Carbon -framework Cocoa -framework ApplicationServices -lz")
+ENDIF(APPLE AND NOT FLTK_APPLE_X11)
+
+IF(CYGWIN)
+  ADD_DEFINITIONS(-DWIN32)  
+  SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid comctl32 wsock32 supc++ -lm -lgdi32)
+ENDIF(CYGWIN)
+
+IF(MINGW)
+  ADD_DEFINITIONS(-DWIN32)
+  SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid wsock32 gdi32 comdlg32)
+ENDIF(MINGW)
+
+INCLUDE(CheckIncludeFiles)
+# Check if header file exists and add it to the list.
+MACRO(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
+  CHECK_INCLUDE_FILES("${PROJECT_INCLUDES};${FILE}" ${VARIABLE})
+  IF(${VARIABLE})
+    SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${FILE})
+  ENDIF(${VARIABLE})
+ENDMACRO(CHECK_INCLUDE_FILE_CONCAT)
+CHECK_INCLUDE_FILE_CONCAT("GL/glu.h"       HAVE_GL_GLU_H)
+CHECK_INCLUDE_FILE_CONCAT("OpenGL/glu.h"   HAVE_OPENGL_GLU_H)
+CHECK_INCLUDE_FILE_CONCAT("dirent.h"       HAVE_DIRENT_H)
+CHECK_INCLUDE_FILE_CONCAT("stdio.h"        HAVE_STDIO_H)
+CHECK_INCLUDE_FILE_CONCAT("strings.h"      HAVE_STRINGS_H)
+CHECK_INCLUDE_FILE_CONCAT("sys/dir.h"      HAVE_SYS_DIR_H)
+CHECK_INCLUDE_FILE_CONCAT("sys/ndir.h"     HAVE_SYS_NDIR_H)
+CHECK_INCLUDE_FILE_CONCAT("sys/select.h"   HAVE_SYS_SELECT_H)
+CHECK_INCLUDE_FILE_CONCAT("sys/stdtypes.h" HAVE_SYS_STDTYPES_H)
+CHECK_INCLUDE_FILE("pthread.h"      CMAKE_HAVE_PTHREAD_H)
+
+FIND_PACKAGE(ZLIB)
+FIND_PACKAGE(PNG)
+FIND_PACKAGE(JPEG)
+
+INCLUDE(CheckSymbolExists)
+INCLUDE(CheckFunctionWithHeaderExists)
+
+CHECK_FUNCTIONWITHHEADER_EXISTS("int strcasecmp()"  "${PROJECT_INCLUDES}" HAVE_STRCASECMP)
+
+CHECK_SYMBOL_EXISTS(strlcat       "${PROJECT_INCLUDES}" HAVE_STRLCAT)
+CHECK_SYMBOL_EXISTS(strlcpy       "${PROJECT_INCLUDES}" HAVE_STRLCPY)
+CHECK_SYMBOL_EXISTS(vsnprintf     "${PROJECT_INCLUDES}" HAVE_VSNPRINTF)
+CHECK_SYMBOL_EXISTS(snprintf      "${PROJECT_INCLUDES}" HAVE_SNPRINTF)
+CHECK_SYMBOL_EXISTS(scandir       "${PROJECT_INCLUDES}" HAVE_SCANDIR)
+
+INCLUDE(CheckTypeSize)
+
+CHECK_TYPE_SIZE(short SIZEOF_SHORT)
+CHECK_TYPE_SIZE(int   SIZEOF_INT)
+CHECK_TYPE_SIZE(long  SIZEOF_LONG)
+
+IF(${SIZEOF_SHORT} MATCHES "^2$")
+  SET(U16 "unsigned short")
+ENDIF(${SIZEOF_SHORT} MATCHES "^2$")
+
+IF(${SIZEOF_INT} MATCHES "^4$")
+  SET(U32 "unsigned")
+ELSE(${SIZEOF_INT} MATCHES "^4$")
+  IF(${SIZEOF_LONG} MATCHES "^4$")
+    SET(U32 "unsigned long")
+  ENDIF(${SIZEOF_LONG} MATCHES "^4$")
+ENDIF(${SIZEOF_INT} MATCHES "^4$")
+
+IF(${SIZEOF_INT} MATCHES "^8$")
+  SET(U64 "unsigned")
+ELSE(${SIZEOF_INT} MATCHES "^8$")
+  IF(${SIZEOF_LONG} MATCHES "^8$")
+    SET(U64 "unsigned long")
+  ENDIF(${SIZEOF_LONG} MATCHES "^8$")
+ENDIF(${SIZEOF_INT} MATCHES "^8$")
+
+# Set an option to build FLTK with OpenGL support
+SET(HAVE_GL 0)
+OPTION(USE_OPENGL "OpenGL Support" ON)
+# OTB Adds
+MARK_AS_ADVANCED(USE_OPENGL)
+
+IF(USE_OPENGL)
+  FIND_PACKAGE(OpenGL)
+  IF(OPENGL_FOUND)
+    SET(HAVE_GL 1)
+    INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
+  ENDIF(OPENGL_FOUND)
+ENDIF(USE_OPENGL)
+
+#
+# Perform the FLTK specific test with status output
+#
+MACRO(PERFORM_CMAKE_TEST FILE TEST)
+  IF("${TEST}" MATCHES "^${TEST}$")
+    # Perform test
+    SET(MACRO_CHECK_FUNCTION_DEFINITIONS 
+      "-D${TEST} ${CMAKE_REQUIRED_FLAGS}")
+    IF(CMAKE_REQUIRED_LIBRARIES)
+      SET(TEST_ADD_LIBRARIES
+        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
+    ENDIF(CMAKE_REQUIRED_LIBRARIES)
+    MESSAGE(STATUS "Performing Test ${TEST}")
+
+    TRY_COMPILE(${TEST}
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+      -DLINK_LIBRARIES:STRING=${CMAKE_TEST_SPECIAL_LIBRARIES}
+      "${TEST_ADD_LIBRARIES}"
+      OUTPUT_VARIABLE OUTPUT)
+    IF(${TEST})
+      SET(${TEST} 1 CACHE INTERNAL "CMake test ${FUNCTION}")
+      MESSAGE(STATUS "Performing Test ${TEST} - Success")
+    ELSE(${TEST})
+      MESSAGE(STATUS "Performing Test ${TEST} - Failed")
+      SET(${TEST} 0 CACHE INTERNAL "Test ${FUNCTION}")
+      WRITE_FILE(${CMAKE_BINARY_DIR}/CMakeError.log 
+        "Performing Test ${TEST} failed with the following output:\n"
+        "${OUTPUT}\n" APPEND)
+    ENDIF(${TEST})
+  ENDIF("${TEST}" MATCHES "^${TEST}$")
+ENDMACRO(PERFORM_CMAKE_TEST FILE TEST)
+
+# Set an option to build the zlib library or not
+OPTION(FLTK_USE_SYSTEM_ZLIB "Use's system zlib" OFF)
+# OTB Adds
+MARK_AS_ADVANCED(FLTK_USE_SYSTEM_ZLIBUS)
+IF(FLTK_USE_SYSTEM_ZLIB)
+  IF(ZLIB_FOUND)
+    SET(CMAKE_TEST_SPECIAL_LIBRARIES ${ZLIB_LIBRARIES})
+    SET(FLTK_ZLIB_LIBRARIES ${ZLIB_LIBRARIES})
+    PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBZ)
+  ENDIF(ZLIB_FOUND)
+  # We build the fltk zlib
+ELSE(FLTK_USE_SYSTEM_ZLIB)
+  MARK_AS_ADVANCED(ZLIB_INCLUDE_DIR)
+  MARK_AS_ADVANCED(ZLIB_LIBRARY)
+  SUBDIRS(zlib)
+  SET(HAVE_LIBZ 1)
+  SET(FLTK_ZLIB_LIBRARIES fltk_zlib)
+  SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_zlib")
+  INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/zlib")
+ENDIF(FLTK_USE_SYSTEM_ZLIB)
+
+# Set an option to build the jpeg library or not
+OPTION(FLTK_USE_SYSTEM_JPEG "Use's system jpeg" OFF)
+# OTB Adds
+MARK_AS_ADVANCED(FLTK_USE_SYSTEM_JPEG)
+
+IF(FLTK_USE_SYSTEM_JPEG)
+  IF(JPEG_FOUND)
+    SET(CMAKE_TEST_SPECIAL_LIBRARIES ${JPEG_LIBRARIES})
+    SET(FLTK_JPEG_LIBRARIES ${JPEG_LIBRARIES})
+    PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBJPEG)
+  ENDIF(JPEG_FOUND)
+  # We build the fltk png
+ELSE(FLTK_USE_SYSTEM_JPEG)
+  MARK_AS_ADVANCED(JPEG_INCLUDE_DIR)
+  MARK_AS_ADVANCED(JPEG_LIBRARY)
+  SUBDIRS(jpeg)
+  SET(HAVE_LIBJPEG 1)
+  SET(FLTK_JPEG_LIBRARIES fltk_jpeg)
+  SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_jpeg")
+  INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/jpeg")
+ENDIF(FLTK_USE_SYSTEM_JPEG)
+
+# Set an option to build the png library or not
+OPTION(FLTK_USE_SYSTEM_PNG "Use's system png" OFF)
+# OTB Adds
+MARK_AS_ADVANCED(FLTK_USE_SYSTEM_PNG)
+IF(FLTK_USE_SYSTEM_PNG)
+  IF(PNG_FOUND)
+    SET(CMAKE_TEST_SPECIAL_LIBRARIES ${PNG_LIBRARIES})
+    SET(FLTK_PNG_LIBRARIES ${PNG_LIBRARIES})
+    PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBPNG)
+    PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_PNG_GET_VALID)
+    PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_PNG_SET_TRNS_TO_ALPHA)
+    SET(HAVE_PNG_H 1)
+  ENDIF(PNG_FOUND)
+  # We build the fltk png
+ELSE(FLTK_USE_SYSTEM_PNG)
+  MARK_AS_ADVANCED(PNG_INCLUDE_DIR)
+  MARK_AS_ADVANCED(PNG_LIBRARY)
+  SUBDIRS(png)
+  SET(HAVE_LIBPNG 1)
+  SET(HAVE_PNG_H 1)
+  SET(FLTK_PNG_LIBRARIES fltk_png)
+  SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_png")
+  INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/png")
+ENDIF(FLTK_USE_SYSTEM_PNG)
+
+SET(FLTK_DATADIR "${CMAKE_INSTALL_PREFIX}/share/FLTK")
+SET(FLTK_DOCDIR  "${CMAKE_INSTALL_PREFIX}/share/doc/FLTK")
+
+# Write out configuration header file
+CONFIGURE_FILE(${FLTK_SOURCE_DIR}/configh.cmake.in
+# OTB Modifications: conflict name file with the OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h
+#  ${FLTK_BINARY_DIR}/config.h)
+  ${FLTK_BINARY_DIR}/fltk-config.h)
+
+# On unix create symlinks for backward compatibility
+SET(FLTK_CREATE_SYMLINKS 1)
+IF(WIN32)
+  IF(NOT UNIX)
+    SET(FLTK_CREATE_SYMLINKS 0)
+  ENDIF(NOT UNIX)
+ENDIF(WIN32)
+
+MACRO(SAFE_CREATE_SYMLINK SOURCE DESTINATION)
+  IF(EXISTS "${DESTINATION}")
+  ELSE(EXISTS "${DESTINATION}")
+    MESSAGE(STATUS "Create symlink from: \"${SOURCE}\" to \"${DESTINATION}\"")
+    # The quoting here does seems unnatural, but this is to prevent bug in CMake
+    EXEC_PROGRAM(ln ARGS 
+      "-s \"${SOURCE}\" \"${DESTINATION}\"" OUTPUT_VARIABLE ln_output
+      RETURN_VALUE ln_retval)
+    IF("${ln_retval}" GREATER 0)
+      MESSAGE(FATAL_ERROR "Problem creatin symlink from \"${SOURCE}\" to \"${DESTINATION}\":\n${ln_output}")
+    ENDIF("${ln_retval}" GREATER 0)
+  ENDIF(EXISTS "${DESTINATION}")
+ENDMACRO(SAFE_CREATE_SYMLINK SOURCE DESTINATION)
+
+# If this is out-of-source build, then copy FL directory
+FILE(GLOB FLTK_HEADER_FILES "${FLTK_SOURCE_DIR}/FL/*.[hHr]")
+FOREACH(file ${FLTK_HEADER_FILES})
+  GET_FILENAME_COMPONENT(ext "${file}" EXT)
+  GET_FILENAME_COMPONENT(namewe "${file}" NAME_WE)
+  GET_FILENAME_COMPONENT(name "${file}" NAME)
+  STRING(COMPARE EQUAL "${ext}" ".h" lower_case_h)
+  STRING(COMPARE EQUAL "${ext}" ".H" upper_case_h)
+  IF(lower_case_h OR upper_case_h)
+    SET(outfile_h "${FLTK_BINARY_DIR}/FL/${namewe}.h")
+    SET(outfile_H "${FLTK_BINARY_DIR}/FL/${namewe}.H")
+    CONFIGURE_FILE("${file}" "${outfile_H}" COPYONLY IMMEDIATE)
+    CONFIGURE_FILE("${file}" "${outfile_h}" COPYONLY IMMEDIATE)
+#    IF(FLTK_CREATE_SYMLINKS)
+#      SAFE_CREATE_SYMLINK("${outfile_H}" "${outfile_h}")
+#    ENDIF(FLTK_CREATE_SYMLINKS)
+  ELSE(lower_case_h OR upper_case_h)
+    STRING(COMPARE EQUAL "${ext}" ".r" mac_resource_file)
+    IF(mac_resource_file)
+      SET(outfile "${FLTK_BINARY_DIR}/FL/${name}")
+      CONFIGURE_FILE("${file}" "${outfile}" COPYONLY IMMEDIATE)
+    ENDIF(mac_resource_file)
+  ENDIF(lower_case_h OR upper_case_h)
+ENDFOREACH(file)
+
+IF(FLTK_CREATE_SYMLINKS)
+  SAFE_CREATE_SYMLINK(
+    "${FLTK_BINARY_DIR}/FL"
+    "${FLTK_BINARY_DIR}/Fl")
+
+  SAFE_CREATE_SYMLINK(
+    "${FLTK_BINARY_DIR}/FL/gl.H"
+    "${FLTK_BINARY_DIR}/FL/gl.h")
+
+  # Create the symlinks
+  FILE(READ ${FLTK_SOURCE_DIR}/fltk.list.in SYMLINKSFILE)
+  STRING(REGEX MATCHALL "(l 0000 root sys .includedir/)([^(\n)])+"
+  SYMLINKS ${SYMLINKSFILE})
+  FOREACH(var ${SYMLINKS} )
+    IF("${var}" MATCHES ".H")
+      STRING(REGEX MATCH "(/F)([^(\n)])+" tmp ${var})
+      STRING(REGEX MATCH "(/F)([^( )])+" in ${tmp})
+      STRING(REGEX MATCH "( )([^(\n)])+" out ${tmp}) 
+      STRING(REGEX REPLACE "( )" "" out ${out})
+      SAFE_CREATE_SYMLINK("${FLTK_BINARY_DIR}/FL/${out}" "${FLTK_BINARY_DIR}/${in}")
+    ENDIF("${var}" MATCHES ".H")
+  ENDFOREACH(var)
+ENDIF(FLTK_CREATE_SYMLINKS)
+
+# Set the fluid executable path
+UTILITY_SOURCE(FLUID_COMMAND fluid fluid fluid.cxx)
+SET(FLUID_COMMAND "${FLUID_COMMAND}" CACHE INTERNAL "" FORCE)
+
+# Include header files in fltk binary tree
+INCLUDE_DIRECTORIES(${FLTK_BINARY_DIR})
+
+# Do the build of fltk libraries and fluid
+SUBDIRS(src)
+SUBDIRS(fluid)
+
+
+#-----------------------------------------------------------------------------
+# Help outside projects build FLTK projects.
+INCLUDE(CMakeExportBuildSettings)
+EXPORT_LIBRARY_DEPENDENCIES(${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake)
+CMAKE_EXPORT_BUILD_SETTINGS(${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake)
+SET(FL_MAJOR_VERSION "${FLTK_VERSION_MAJOR}")
+SET(FL_MINOR_VERSION "${FLTK_VERSION_MINOR}")
+SET(FL_PATCH_VERSION "${FLTK_VERSION_PATCH}")
+
+SET(CFLAGS "${CMAKE_C_FLAGS}")
+SET(CXXFLAGS "${CMAKE_CXX_FLAGS}")
+SET(CC "${CMAKE_C_COMPILER}")
+SET(CXX "${CMAKE_CXX_COMPILER}")
+
+# For build tree usage
+SET(FLTK_FLUID_COMMAND "${FLUID_COMMAND}")
+SET(FLTK_LIBRARY_DEPENDS_FILE ${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake)
+SET(FLTK_EXECUTABLE_DIRS ${EXECUTABLE_OUTPUT_PATH})
+SET(FLTK_LIBRARY_DIRS ${LIBRARY_OUTPUT_PATH})
+SET(FLTK_USE_FILE ${FLTK_SOURCE_DIR}/CMake/FLTKUse.cmake)
+SET(FLTK_INCLUDE_DIRS "${FLTK_BINARY_DIR}/")
+SET(FLTK_BUILD_SETTINGS_FILE ${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake)
+SET(prefix "${FLTK_BINARY_DIR}")
+SET(exec_prefix "${prefix}")
+SET(exec_prefix_set "no")
+SET(bindir "${prefix}/bin")
+SET(includedir "${prefix}")
+SET(libdir "${prefix}/bin")
+SET(srcdir "${FLTK_SOURCE_DIR}")
+
+CONFIGURE_FILE("${FLTK_SOURCE_DIR}/CMake/FLTKConfig.cmake.in"
+  "${FLTK_BINARY_DIR}/FLTKConfig.cmake" @ONLY IMMEDIATE)
+CONFIGURE_FILE("${FLTK_SOURCE_DIR}/fltk-config.in"
+  "${FLTK_BINARY_DIR}/fltk-config" @ONLY IMMEDIATE)
+
+# For installed tree usage
+SET(FLTK_FLUID_COMMAND "${CMAKE_INSTALL_PREFIX}/bin/fluid")
+SET(FLTK_LIBRARY_DEPENDS_FILE ${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKLibraryDepends.cmake)
+SET(FLTK_EXECUTABLE_DIRS "${CMAKE_INSTALL_PREFIX}/bin")
+SET(FLTK_LIBRARY_DIRS "${CMAKE_INSTALL_PREFIX}/lib")
+SET(FLTK_USE_FILE "${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKUse.cmake")
+SET(FLTK_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/")
+SET(FLTK_BUILD_SETTINGS_FILE ${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKBuildSettings.cmake)
+SET(prefix "${CMAKE_INSTALL_PREFIX}")
+SET(exec_prefix "${prefix}")
+SET(exec_prefix_set "no")
+SET(bindir "${prefix}/bin")
+SET(includedir "${prefix}")
+SET(libdir "${prefix}/lib")
+SET(srcdir ".")
+
+CONFIGURE_FILE("${FLTK_SOURCE_DIR}/CMake/FLTKConfig.cmake.in"
+  "${FLTK_BINARY_DIR}/CMake/FLTKConfig.cmake" @ONLY IMMEDIATE)
+CONFIGURE_FILE("${FLTK_SOURCE_DIR}/fltk-config.in"
+  "${FLTK_BINARY_DIR}/CMake/fltk-config" @ONLY IMMEDIATE)
+
+INSTALL_FILES(/include/otb/Utilities/FLTK/FL FILES ${FLTK_HEADER_FILES})
+#INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_SOURCE_DIR}/CMake/FLTKUse.cmake")
+#INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake")
+#INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake")
+#INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/CMake/FLTKConfig.cmake")
diff --git a/Utilities/FLTK/COPYING b/Utilities/FLTK/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..0dd0e80d38549178b5bdd3580c431fdd6896c7ef
--- /dev/null
+++ b/Utilities/FLTK/COPYING
@@ -0,0 +1,528 @@
+                             FLTK License
+                           December 11, 2001
+
+The FLTK library and included programs are provided under the terms
+of the GNU Library General Public License (LGPL) with the following
+exceptions:
+
+    1. Modifications to the FLTK configure script, config
+       header file, and makefiles by themselves to support
+       a specific platform do not constitute a modified or
+       derivative work.
+
+       The authors do request that such modifications be
+       contributed to the FLTK project - send all
+       contributions to "fltk-bugs@fltk.org".
+
+    2. Widgets that are subclassed from FLTK widgets do not
+       constitute a derivative work.
+
+    3. Static linking of applications and widgets to the
+       FLTK library does not constitute a derivative work
+       and does not require the author to provide source
+       code for the application or widget, use the shared
+       FLTK libraries, or link their applications or
+       widgets against a user-supplied version of FLTK.
+
+       If you link the application or widget to a modified
+       version of FLTK, then the changes to FLTK must be
+       provided under the terms of the LGPL in sections
+       1, 2, and 4.
+
+    4. You do not have to provide a copy of the FLTK license
+       with programs that are linked to the FLTK library, nor
+       do you have to identify the FLTK license in your
+       program or documentation as required by section 6
+       of the LGPL.
+
+       However, programs must still identify their use of FLTK.
+       The following example statement can be included in user
+       documentation to satisfy this requirement:
+
+           [program/widget] is based in part on the work of
+           the FLTK project (http://www.fltk.org).
+
+-----------------------------------------------------------------------
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+			 Version 2, June 1991
+
+	  Copyright (C) 1991 Free Software Foundation, Inc.
+       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+     Everyone is permitted to copy and distribute verbatim copies
+      of this license document, but changing it is not allowed.
+
+    [This is the first released version of the library GPL.  It is
+   numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+			       Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/Utilities/FLTK/CREDITS b/Utilities/FLTK/CREDITS
new file mode 100644
index 0000000000000000000000000000000000000000..b8aac7caa5fb4f96aea7f12172ee8973ef5a7c4a
--- /dev/null
+++ b/Utilities/FLTK/CREDITS
@@ -0,0 +1,53 @@
+CREDITS - Fast Light Tool Kit (FLTK) Version 1.1.5
+--------------------------------------------------
+
+    This file lists the people responsible for the toolkit you
+    are now using.  If you've looking for your name in lights
+    but we've forgotten you here, please send an email to
+    "fltk-bugs@fltk.org" and we'll update this file accordingly.
+
+
+CORE DEVELOPERS
+
+    The following people do the day-to-day development of FLTK:
+
+        Craig P. Earls
+	Curtis Edwards (trilec@users.sourceforge.net)
+	Gustavo Hime (hime@users.sourceforge.net)
+	Talbot Hughes
+	Robert Kesterson (robertk@users.sourceforge.net)
+	Matthias Melcher (matthias@users.sourceforge.net)
+	James Dean Palmer (jamespalmer@users.sourceforge.net)
+	Vincent Penne (vincentp@users.sourceforge.net)
+	Bill Spitzak (spitzak@users.sourceforge.net)
+        Michael Sweet (easysw@users.sourceforge.net)
+	Carl Thompson (clip@users.sourceforge.net)
+	Nafees Bin Zafar (nafees@users.sourceforge.net)
+
+
+OTHER CONTRIBUTORS
+
+    The following people have contributed fixes or enhancements
+    for FLTK:
+
+	Teun Burgers
+	Paul Chambers
+	Fabien Costantini
+	Stephen Davies
+	Greg Ercolano
+	Yuri Fedorchenko
+	George Garvey
+	Mikael Hultgren
+	Stuart Levy
+	Howard Lightstone
+	Mike Lindner
+	Alexander Mai
+	Alexander Rabi
+	James Roth
+	Albrecht Schlosser
+        Andrea Suatoni
+	Paul Sydney
+	Aaron Ucko
+	Emanuele Vicentini
+	Jim Wilson
+	Ken Yarnall
diff --git a/Utilities/FLTK/DartConfig.cmake b/Utilities/FLTK/DartConfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..90e1ff6639242944ce002f819794d43b6c752a19
--- /dev/null
+++ b/Utilities/FLTK/DartConfig.cmake
@@ -0,0 +1,38 @@
+# Dashboard is opened for submissions for a 24 hour period starting at
+# the specified NIGHLY_START_TIME. Time is specified in 24 hour format.
+SET (NIGHTLY_START_TIME "21:00:00 EDT")
+
+# Dart server to submit results (used by client)
+SET (DROP_METHOD "http")
+SET (DROP_SITE "public.kitware.com")
+SET (DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi")
+SET (TRIGGER_SITE "http://${DROP_SITE}/cgi-bin/Submit-Fltk-TestingResults.pl")
+
+# Project Home Page
+SET (PROJECT_URL "http://www.fltk.org")
+
+# Dart server configuration 
+SET (ROLLUP_URL "http://${DROP_SITE}/cgi-bin/fltk-rollup-dashboard.sh")
+SET (CVS_WEB_URL "http://cvs.sourceforge.net/viewcvs.py/fltk/fltk/")
+SET (CVS_WEB_CVSROOT "fltk")
+
+SET (USE_GNATS "On")
+SET (GNATS_WEB_URL "http://www.fltk.org/str.php")
+
+# Continuous email delivery variables
+SET (CONTINUOUS_FROM "fltk-dashboard@public.kitware.com")
+SET (SMTP_MAILHOST "public.kitware.com")
+SET (CONTINUOUS_MONITOR_LIST "fltk-dashboard@public.kitware.com")
+SET (CONTINUOUS_BASE_URL "http://public.kitware.com/Fltk/Testing")
+
+SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_TEST_FAILURES ON)
+SET (DELIVER_BROKEN_BUILD_EMAIL "Continuous Nightly")
+SET (EMAIL_FROM "fltk-dashboard@public.kitware.com")
+SET (DARTBOARD_BASE_URL "http://public.kitware.com/Fltk/Testing")
+
+SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_CONFIGURE_FAILURES 1)
+SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_BUILD_ERRORS 1)
+SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_BUILD_WARNINGS 1)
+SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_TEST_NOT_RUNS 1)
+SET (DELIVER_BROKEN_BUILD_EMAIL_WITH_TEST_FAILURES 1)
+
diff --git a/Utilities/FLTK/FL/Enumerations.H b/Utilities/FLTK/FL/Enumerations.H
new file mode 100644
index 0000000000000000000000000000000000000000..4c3337cacdd9cd48ae2fb075c50e1595d690123f
--- /dev/null
+++ b/Utilities/FLTK/FL/Enumerations.H
@@ -0,0 +1,428 @@
+//
+// "$Id: Enumerations.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Enumerations for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Enumerations_H
+#define Fl_Enumerations_H
+
+#  include "Fl_Export.H"
+
+
+//
+// The FLTK version number; this is changed slightly from the beta versions
+// because the old "const double" definition would not allow for conditional
+// compilation...
+//
+// FL_VERSION is a double that describes the major and minor version numbers.
+// Version 1.1 is actually stored as 1.01 to allow for more than 9 minor
+// releases.
+//
+// The FL_MAJOR_VERSION, FL_MINOR_VERSION, and FL_PATCH_VERSION constants
+// give the integral values for the major, minor, and patch releases
+// respectively.
+//
+
+#define FL_MAJOR_VERSION	1
+#define FL_MINOR_VERSION	1
+#define FL_PATCH_VERSION	7
+#define FL_VERSION		((double)FL_MAJOR_VERSION + \
+				 (double)FL_MINOR_VERSION * 0.01 + \
+				 (double)FL_PATCH_VERSION * 0.0001)
+
+typedef unsigned char uchar;
+typedef unsigned long ulong;
+
+enum Fl_Event {	// events
+  FL_NO_EVENT		= 0,
+  FL_PUSH		= 1,
+  FL_RELEASE		= 2,
+  FL_ENTER		= 3,
+  FL_LEAVE		= 4,
+  FL_DRAG		= 5,
+  FL_FOCUS		= 6,
+  FL_UNFOCUS		= 7,
+  FL_KEYDOWN		= 8,
+  FL_KEYUP		= 9,
+  FL_CLOSE		= 10,
+  FL_MOVE		= 11,
+  FL_SHORTCUT		= 12,
+  FL_DEACTIVATE		= 13,
+  FL_ACTIVATE		= 14,
+  FL_HIDE		= 15,
+  FL_SHOW		= 16,
+  FL_PASTE		= 17,
+  FL_SELECTIONCLEAR	= 18,
+  FL_MOUSEWHEEL		= 19,
+  FL_DND_ENTER		= 20,
+  FL_DND_DRAG		= 21,
+  FL_DND_LEAVE		= 22,
+  FL_DND_RELEASE	= 23
+};
+#define FL_KEYBOARD FL_KEYDOWN
+
+enum Fl_When { // Fl_Widget::when():
+  FL_WHEN_NEVER		= 0,
+  FL_WHEN_CHANGED	= 1,
+  FL_WHEN_RELEASE	= 4,
+  FL_WHEN_RELEASE_ALWAYS= 6,
+  FL_WHEN_ENTER_KEY	= 8,
+  FL_WHEN_ENTER_KEY_ALWAYS=10,
+  FL_WHEN_ENTER_KEY_CHANGED=11,
+  FL_WHEN_NOT_CHANGED	= 2 // modifier bit to disable changed() test
+};
+
+// Fl::event_key() and Fl::get_key(n) (use ascii letters for all other keys):
+#define FL_Button	0xfee8 // use Fl_Button+FL_*_MOUSE
+#define FL_BackSpace	0xff08
+#define FL_Tab		0xff09
+#define FL_Enter	0xff0d
+#define FL_Pause	0xff13
+#define FL_Scroll_Lock	0xff14
+#define FL_Escape	0xff1b
+#define FL_Home		0xff50
+#define FL_Left		0xff51
+#define FL_Up		0xff52
+#define FL_Right	0xff53
+#define FL_Down		0xff54
+#define FL_Page_Up	0xff55
+#define FL_Page_Down	0xff56
+#define FL_End		0xff57
+#define FL_Print	0xff61
+#define FL_Insert	0xff63
+#define FL_Menu		0xff67 // the "menu/apps" key on XFree86
+#define FL_Help		0xff68 // the 'help' key on Mac keyboards
+#define FL_Num_Lock	0xff7f
+#define FL_KP		0xff80 // use FL_KP+'x' for 'x' on numeric keypad
+#define FL_KP_Enter	0xff8d // same as Fl_KP+'\r'
+#define FL_KP_Last	0xffbd // use to range-check keypad
+#define FL_F		0xffbd // use FL_F+n for function key n
+#define FL_F_Last	0xffe0 // use to range-check function keys
+#define FL_Shift_L	0xffe1
+#define FL_Shift_R	0xffe2
+#define FL_Control_L	0xffe3
+#define FL_Control_R	0xffe4
+#define FL_Caps_Lock	0xffe5
+#define FL_Meta_L	0xffe7 // the left MSWindows key on XFree86
+#define FL_Meta_R	0xffe8 // the right MSWindows key on XFree86
+#define FL_Alt_L	0xffe9
+#define FL_Alt_R	0xffea
+#define FL_Delete	0xffff
+
+// Fl::event_button():
+#define FL_LEFT_MOUSE	1
+#define FL_MIDDLE_MOUSE	2
+#define FL_RIGHT_MOUSE	3
+
+// Fl::event_state():
+#define FL_SHIFT	0x00010000
+#define FL_CAPS_LOCK	0x00020000
+#define FL_CTRL		0x00040000
+#define FL_ALT		0x00080000
+#define FL_NUM_LOCK	0x00100000 // most X servers do this?
+#define FL_META		0x00400000 // correct for XFree86
+#define FL_SCROLL_LOCK	0x00800000 // correct for XFree86
+#define FL_BUTTON1	0x01000000
+#define FL_BUTTON2	0x02000000
+#define FL_BUTTON3	0x04000000
+#define FL_BUTTONS	0x7f000000 // All possible buttons
+#define FL_BUTTON(n)	(0x00800000<<(n))
+
+#ifdef __APPLE__
+#  define FL_COMMAND	FL_META
+#else
+#  define FL_COMMAND	FL_CTRL
+#endif // __APPLE__
+
+enum Fl_Boxtype { // boxtypes (if you change these you must fix fl_boxtype.C):
+  FL_NO_BOX = 0,	FL_FLAT_BOX,
+
+  FL_UP_BOX,		FL_DOWN_BOX,
+  FL_UP_FRAME,		FL_DOWN_FRAME,
+  FL_THIN_UP_BOX,	FL_THIN_DOWN_BOX,
+  FL_THIN_UP_FRAME,	FL_THIN_DOWN_FRAME,
+  FL_ENGRAVED_BOX,	FL_EMBOSSED_BOX,
+  FL_ENGRAVED_FRAME,	FL_EMBOSSED_FRAME,
+  FL_BORDER_BOX,	_FL_SHADOW_BOX,
+  FL_BORDER_FRAME,	_FL_SHADOW_FRAME,
+  _FL_ROUNDED_BOX,	_FL_RSHADOW_BOX,
+  _FL_ROUNDED_FRAME,	_FL_RFLAT_BOX,
+  _FL_ROUND_UP_BOX,	_FL_ROUND_DOWN_BOX,
+  _FL_DIAMOND_UP_BOX,	_FL_DIAMOND_DOWN_BOX,
+  _FL_OVAL_BOX,		_FL_OSHADOW_BOX,
+  _FL_OVAL_FRAME,	_FL_OFLAT_BOX,
+  _FL_PLASTIC_UP_BOX,	_FL_PLASTIC_DOWN_BOX,
+  _FL_PLASTIC_UP_FRAME,	_FL_PLASTIC_DOWN_FRAME,
+  _FL_PLASTIC_THIN_UP_BOX,	_FL_PLASTIC_THIN_DOWN_BOX,
+  _FL_PLASTIC_ROUND_UP_BOX,	_FL_PLASTIC_ROUND_DOWN_BOX,
+  FL_FREE_BOXTYPE
+};
+extern FL_EXPORT Fl_Boxtype fl_define_FL_ROUND_UP_BOX();
+#define FL_ROUND_UP_BOX fl_define_FL_ROUND_UP_BOX()
+#define FL_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_ROUND_UP_BOX()+1)
+extern FL_EXPORT Fl_Boxtype fl_define_FL_SHADOW_BOX();
+#define FL_SHADOW_BOX fl_define_FL_SHADOW_BOX()
+#define FL_SHADOW_FRAME (Fl_Boxtype)(fl_define_FL_SHADOW_BOX()+2)
+extern FL_EXPORT Fl_Boxtype fl_define_FL_ROUNDED_BOX();
+#define FL_ROUNDED_BOX fl_define_FL_ROUNDED_BOX()
+#define FL_ROUNDED_FRAME (Fl_Boxtype)(fl_define_FL_ROUNDED_BOX()+2)
+extern FL_EXPORT Fl_Boxtype fl_define_FL_RFLAT_BOX();
+#define FL_RFLAT_BOX fl_define_FL_RFLAT_BOX()
+extern FL_EXPORT Fl_Boxtype fl_define_FL_RSHADOW_BOX();
+#define FL_RSHADOW_BOX fl_define_FL_RSHADOW_BOX()
+extern FL_EXPORT Fl_Boxtype fl_define_FL_DIAMOND_BOX();
+#define FL_DIAMOND_UP_BOX fl_define_FL_DIAMOND_BOX()
+#define FL_DIAMOND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_DIAMOND_BOX()+1)
+extern FL_EXPORT Fl_Boxtype fl_define_FL_OVAL_BOX();
+#define FL_OVAL_BOX fl_define_FL_OVAL_BOX()
+#define FL_OSHADOW_BOX (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+1)
+#define FL_OVAL_FRAME (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+2)
+#define FL_OFLAT_BOX (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+3)
+
+extern FL_EXPORT Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX();
+#define FL_PLASTIC_UP_BOX fl_define_FL_PLASTIC_UP_BOX()
+#define FL_PLASTIC_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+1)
+#define FL_PLASTIC_UP_FRAME (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+2)
+#define FL_PLASTIC_DOWN_FRAME (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+3)
+#define FL_PLASTIC_THIN_UP_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+4)
+#define FL_PLASTIC_THIN_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+5)
+#define FL_PLASTIC_ROUND_UP_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+6)
+#define FL_PLASTIC_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+7)
+
+// conversions of box types to other boxtypes:
+inline Fl_Boxtype fl_down(Fl_Boxtype b) {return (Fl_Boxtype)(b|1);}
+inline Fl_Boxtype fl_frame(Fl_Boxtype b) {return (Fl_Boxtype)(b|2);}
+
+// back-compatability box types:
+#define FL_FRAME FL_ENGRAVED_FRAME
+#define FL_FRAME_BOX FL_ENGRAVED_BOX
+#define FL_CIRCLE_BOX FL_ROUND_DOWN_BOX
+#define FL_DIAMOND_BOX FL_DIAMOND_DOWN_BOX
+
+enum Fl_Labeltype {	// labeltypes:
+  FL_NORMAL_LABEL	= 0,
+  FL_NO_LABEL,
+  _FL_SHADOW_LABEL,
+  _FL_ENGRAVED_LABEL,
+  _FL_EMBOSSED_LABEL,
+  _FL_MULTI_LABEL,
+  _FL_ICON_LABEL,
+  _FL_IMAGE_LABEL,
+
+  FL_FREE_LABELTYPE
+};
+#define FL_SYMBOL_LABEL FL_NORMAL_LABEL
+extern Fl_Labeltype FL_EXPORT fl_define_FL_SHADOW_LABEL();
+#define FL_SHADOW_LABEL fl_define_FL_SHADOW_LABEL()
+extern Fl_Labeltype FL_EXPORT fl_define_FL_ENGRAVED_LABEL();
+#define FL_ENGRAVED_LABEL fl_define_FL_ENGRAVED_LABEL()
+extern Fl_Labeltype FL_EXPORT fl_define_FL_EMBOSSED_LABEL();
+#define FL_EMBOSSED_LABEL fl_define_FL_EMBOSSED_LABEL()
+
+enum Fl_Align {	// align() values
+  FL_ALIGN_CENTER		= 0,
+  FL_ALIGN_TOP			= 1,
+  FL_ALIGN_BOTTOM		= 2,
+  FL_ALIGN_LEFT			= 4,
+  FL_ALIGN_RIGHT		= 8,
+  FL_ALIGN_INSIDE		= 16,
+  FL_ALIGN_TEXT_OVER_IMAGE	= 32,
+  FL_ALIGN_IMAGE_OVER_TEXT	= 0,
+  FL_ALIGN_CLIP			= 64,
+  FL_ALIGN_WRAP			= 128,
+  FL_ALIGN_TOP_LEFT		= FL_ALIGN_TOP | FL_ALIGN_LEFT,
+  FL_ALIGN_TOP_RIGHT		= FL_ALIGN_TOP | FL_ALIGN_RIGHT,
+  FL_ALIGN_BOTTOM_LEFT		= FL_ALIGN_BOTTOM | FL_ALIGN_LEFT,
+  FL_ALIGN_BOTTOM_RIGHT		= FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT,
+  FL_ALIGN_LEFT_TOP		= FL_ALIGN_TOP_LEFT,
+  FL_ALIGN_RIGHT_TOP		= FL_ALIGN_TOP_RIGHT,
+  FL_ALIGN_LEFT_BOTTOM		= FL_ALIGN_BOTTOM_LEFT,
+  FL_ALIGN_RIGHT_BOTTOM		= FL_ALIGN_BOTTOM_RIGHT,
+  FL_ALIGN_NOWRAP		= 0 // for back compatability
+};
+
+enum Fl_Font {	// standard fonts
+  FL_HELVETICA		= 0,
+  FL_HELVETICA_BOLD,
+  FL_HELVETICA_ITALIC,
+  FL_HELVETICA_BOLD_ITALIC,
+  FL_COURIER,
+  FL_COURIER_BOLD,
+  FL_COURIER_ITALIC,
+  FL_COURIER_BOLD_ITALIC,
+  FL_TIMES,
+  FL_TIMES_BOLD,
+  FL_TIMES_ITALIC,
+  FL_TIMES_BOLD_ITALIC,
+  FL_SYMBOL,
+  FL_SCREEN,
+  FL_SCREEN_BOLD,
+  FL_ZAPF_DINGBATS,
+
+  FL_FREE_FONT		= 16,	// first one to allocate
+  FL_BOLD		= 1,	// add this to helvetica, courier, or times
+  FL_ITALIC		= 2	// add this to helvetica, courier, or times
+};
+
+extern FL_EXPORT int FL_NORMAL_SIZE;
+
+enum Fl_Color {	// standard colors
+  // These are used as default colors in widgets and altered as necessary
+  FL_FOREGROUND_COLOR   = 0,
+  FL_BACKGROUND2_COLOR  = 7,
+  FL_INACTIVE_COLOR	= 8,
+  FL_SELECTION_COLOR	= 15,
+
+  // boxtypes generally limit themselves to these colors so
+  // the whole ramp is not allocated:
+  FL_GRAY0		= 32,	// 'A'
+  FL_DARK3		= 39,	// 'H'
+  FL_DARK2		= 45,   // 'N'
+  FL_DARK1		= 47,	// 'P'
+  FL_BACKGROUND_COLOR	= 49,	// 'R' default background color
+  FL_LIGHT1		= 50,	// 'S'
+  FL_LIGHT2		= 52,	// 'U'
+  FL_LIGHT3		= 54,	// 'W'
+
+  // FLTK provides a 5x8x5 color cube that is used with colormap visuals
+  FL_BLACK		= 56,
+  FL_RED		= 88,
+  FL_GREEN		= 63,
+  FL_YELLOW		= 95,
+  FL_BLUE		= 216,
+  FL_MAGENTA		= 248,
+  FL_CYAN		= 223,
+  FL_DARK_RED		= 72,
+
+  FL_DARK_GREEN		= 60,
+  FL_DARK_YELLOW	= 76,
+  FL_DARK_BLUE		= 136,
+  FL_DARK_MAGENTA	= 152,
+  FL_DARK_CYAN		= 140,
+
+  FL_WHITE		= 255
+};
+
+#define FL_FREE_COLOR		(Fl_Color)16
+#define FL_NUM_FREE_COLOR	16
+#define FL_GRAY_RAMP		(Fl_Color)32
+#define FL_NUM_GRAY		24
+#define FL_GRAY			FL_BACKGROUND_COLOR
+#define FL_COLOR_CUBE		(Fl_Color)56
+#define FL_NUM_RED		5
+#define FL_NUM_GREEN		8
+#define FL_NUM_BLUE		5
+
+FL_EXPORT Fl_Color fl_inactive(Fl_Color c);
+FL_EXPORT Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg);
+FL_EXPORT Fl_Color fl_color_average(Fl_Color c1, Fl_Color c2, float weight);
+inline Fl_Color fl_lighter(Fl_Color c) { return fl_color_average(c, FL_WHITE, .67f); }
+inline Fl_Color fl_darker(Fl_Color c) { return fl_color_average(c, FL_BLACK, .67f); }
+inline Fl_Color fl_rgb_color(uchar r, uchar g, uchar b) {
+  if (!r && !g && !b) return FL_BLACK;
+  else return (Fl_Color)(((((r << 8) | g) << 8) | b) << 8);
+}
+inline Fl_Color fl_rgb_color(uchar g) {
+  if (!g) return FL_BLACK;
+  else return (Fl_Color)(((((g << 8) | g) << 8) | g) << 8);
+}
+inline Fl_Color fl_gray_ramp(int i) {return (Fl_Color)(i+FL_GRAY_RAMP);}
+inline Fl_Color fl_color_cube(int r, int g, int b) {
+  return (Fl_Color)((b*FL_NUM_RED + r) * FL_NUM_GREEN + g + FL_COLOR_CUBE);}
+
+enum Fl_Cursor {	// standard cursors
+  FL_CURSOR_DEFAULT	= 0,
+  FL_CURSOR_ARROW	= 35,
+  FL_CURSOR_CROSS	= 66,
+  FL_CURSOR_WAIT	= 76,
+  FL_CURSOR_INSERT	= 77,
+  FL_CURSOR_HAND	= 31,
+  FL_CURSOR_HELP	= 47,
+  FL_CURSOR_MOVE	= 27,
+  // fltk provides bitmaps for these:
+  FL_CURSOR_NS		= 78,
+  FL_CURSOR_WE		= 79,
+  FL_CURSOR_NWSE	= 80,
+  FL_CURSOR_NESW	= 81,
+  FL_CURSOR_NONE	= 255,
+  // for back compatability (non MSWindows ones):
+  FL_CURSOR_N		= 70,
+  FL_CURSOR_NE		= 69,
+  FL_CURSOR_E		= 49,
+  FL_CURSOR_SE		= 8,
+  FL_CURSOR_S		= 9,
+  FL_CURSOR_SW		= 7,
+  FL_CURSOR_W		= 36,
+  FL_CURSOR_NW		= 68
+  //FL_CURSOR_NS	= 22,
+  //FL_CURSOR_WE	= 55,
+};
+
+enum { // values for "when" passed to Fl::add_fd()
+  FL_READ = 1,
+  FL_WRITE = 4,
+  FL_EXCEPT = 8
+};
+
+enum Fl_Mode { // visual types and Fl_Gl_Window::mode() (values match Glut)
+  FL_RGB	= 0,
+  FL_INDEX	= 1,
+  FL_SINGLE	= 0,
+  FL_DOUBLE	= 2,
+  FL_ACCUM	= 4,
+  FL_ALPHA	= 8,
+  FL_DEPTH	= 16,
+  FL_STENCIL	= 32,
+  FL_RGB8	= 64,
+  FL_MULTISAMPLE= 128,
+  FL_STEREO     = 256,
+  FL_FAKE_SINGLE = 512	// Fake single buffered windows using double-buffer
+};
+
+// damage masks
+
+enum Fl_Damage {
+  FL_DAMAGE_CHILD    = 0x01,
+  FL_DAMAGE_EXPOSE   = 0x02,
+  FL_DAMAGE_SCROLL   = 0x04,
+  FL_DAMAGE_OVERLAY  = 0x08,
+  FL_DAMAGE_USER1    = 0x10,
+  FL_DAMAGE_USER2    = 0x20,
+  FL_DAMAGE_ALL      = 0x80
+};
+
+// FLTK 1.0.x compatibility definitions...
+#  ifdef FLTK_1_0_COMPAT
+#    define contrast	fl_contrast
+#    define down	fl_down
+#    define frame	fl_frame
+#    define inactive	fl_inactive
+#  endif // FLTK_1_0_COMPAT
+
+#endif
+
+//
+// End of "$Id: Enumerations.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl.H b/Utilities/FLTK/FL/Fl.H
new file mode 100644
index 0000000000000000000000000000000000000000..455ed42ce318616c1647fc0ea61ff16a48c84a25
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl.H
@@ -0,0 +1,280 @@
+//
+// "$Id: Fl.H 4223 2005-03-31 16:01:24Z mike $"
+//
+// Main header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_H
+#  define Fl_H
+
+#  include "Enumerations.H"
+#  ifndef Fl_Object
+#    define Fl_Object Fl_Widget
+#  endif
+
+#  ifdef check
+#    undef check
+#  endif
+
+class Fl_Widget;
+class Fl_Window;
+class Fl_Image;
+struct Fl_Label;
+typedef void (Fl_Label_Draw_F)(const Fl_Label*, int,int,int,int, Fl_Align);
+typedef void (Fl_Label_Measure_F)(const Fl_Label*, int&, int&);
+typedef void (Fl_Box_Draw_F)(int,int,int,int, Fl_Color);
+
+typedef void (*Fl_Timeout_Handler)(void*);
+
+class FL_EXPORT Fl {
+  Fl() {}; // no constructor!
+
+public: // should be private!
+
+  static int e_number;
+  static int e_x;
+  static int e_y;
+  static int e_x_root;
+  static int e_y_root;
+  static int e_dx;
+  static int e_dy;
+  static int e_state;
+  static int e_clicks;
+  static int e_is_click;
+  static int e_keysym;
+  static char* e_text;
+  static int e_length;
+  static Fl_Widget* belowmouse_;
+  static Fl_Widget* pushed_;
+  static Fl_Widget* focus_;
+  static int damage_;
+  static Fl_Widget* selection_owner_;
+  static Fl_Window* modal_;
+  static Fl_Window* grab_;
+  static int compose_state;
+  static int visible_focus_;
+  static int dnd_text_ops_;
+  static void damage(int d) {damage_ = d;}
+
+  static void (*idle)();
+
+  static const char* scheme_;
+  static Fl_Image* scheme_bg_;
+
+public:
+
+  // API version number
+  static double version();
+
+  // argument parsers:
+  static int arg(int, char**, int&);
+  static int args(int, char**, int&, int (*)(int,char**,int&) = 0);
+  static const char* const help;
+  static void args(int, char**);
+
+  // things called by initialization:
+  static void display(const char*);
+  static int visual(int);
+  static int gl_visual(int, int *alist=0);
+  static void own_colormap();
+  static void get_system_colors();
+  static void foreground(uchar, uchar, uchar);
+  static void background(uchar, uchar, uchar);
+  static void background2(uchar, uchar, uchar);
+
+  // schemes:
+  static int scheme(const char*);
+  static const char* scheme() {return scheme_;}
+  static int reload_scheme();
+
+  // execution:
+  static int wait();
+  static double wait(double time);
+  static int check();
+  static int ready();
+  static int run();
+  static Fl_Widget* readqueue();
+  static void add_timeout(double t, Fl_Timeout_Handler,void* = 0);
+  static void repeat_timeout(double t, Fl_Timeout_Handler,void* = 0);
+  static int  has_timeout(Fl_Timeout_Handler, void* = 0);
+  static void remove_timeout(Fl_Timeout_Handler, void* = 0);
+  static void add_check(Fl_Timeout_Handler, void* = 0);
+  static int  has_check(Fl_Timeout_Handler, void* = 0);
+  static void remove_check(Fl_Timeout_Handler, void* = 0);
+  static void add_fd(int fd, int when, void (*cb)(int,void*),void* =0);
+  static void add_fd(int fd, void (*cb)(int, void*), void* = 0);
+  static void remove_fd(int, int when);
+  static void remove_fd(int);
+  static void add_idle(void (*cb)(void*), void* = 0);
+  static int  has_idle(void (*cb)(void*), void* = 0);
+  static void remove_idle(void (*cb)(void*), void* = 0);
+  static int damage() {return damage_;}
+  static void redraw();
+  static void flush();
+  static void (*warning)(const char*, ...);
+  static void (*error)(const char*, ...);
+  static void (*fatal)(const char*, ...);
+  static Fl_Window* first_window();
+  static void first_window(Fl_Window*);
+  static Fl_Window* next_window(const Fl_Window*);
+  static Fl_Window* modal() {return modal_;}
+  static Fl_Window* grab() {return grab_;}
+  static void grab(Fl_Window*);
+
+  // event information:
+  static int event()		{return e_number;}
+  static int event_x()	{return e_x;}
+  static int event_y()	{return e_y;}
+  static int event_x_root()	{return e_x_root;}
+  static int event_y_root()	{return e_y_root;}
+  static int event_dx()	{return e_dx;}
+  static int event_dy()	{return e_dy;}
+  static void get_mouse(int &,int &);
+  static int event_clicks()	{return e_clicks;}
+  static void event_clicks(int i) {e_clicks = i;}
+  static int event_is_click()	{return e_is_click;}
+  static void event_is_click(int i) {e_is_click = i;} // only 0 works!
+  static int event_button()	{return e_keysym-FL_Button;}
+  static int event_state()	{return e_state;}
+  static int event_state(int i) {return e_state&i;}
+  static int event_key()	{return e_keysym;}
+  static int event_key(int);
+  static int get_key(int);
+  static const char* event_text() {return e_text;}
+  static int event_length() {return e_length;}
+  static int compose(int &del);
+  static void compose_reset() {compose_state = 0;}
+  static int event_inside(int,int,int,int);
+  static int event_inside(const Fl_Widget*);
+  static int test_shortcut(int);
+
+  // event destinations:
+  static int handle(int, Fl_Window*);
+  static Fl_Widget* belowmouse() {return belowmouse_;}
+  static void belowmouse(Fl_Widget*);
+  static Fl_Widget* pushed()	{return pushed_;}
+  static void pushed(Fl_Widget*);
+  static Fl_Widget* focus()	{return focus_;}
+  static void focus(Fl_Widget*);
+  static void add_handler(int (*h)(int));
+  static void remove_handler(int (*h)(int));
+
+  // cut/paste:
+  static void copy(const char* stuff, int len, int clipboard = 0);
+  static void paste(Fl_Widget &receiver, int clipboard /*=0*/);
+  static int dnd();
+  // These are for back-compatability only:
+  static Fl_Widget* selection_owner() {return selection_owner_;}
+  static void selection_owner(Fl_Widget*);
+  static void selection(Fl_Widget &owner, const char*, int len);
+  static void paste(Fl_Widget &receiver);
+
+  // screen size:
+#if defined(WIN32) || defined(__APPLE__)
+  static int x();
+  static int y();
+#else
+  static int x() {return 0;}
+  static int y() {return 0;}
+#endif /* WIN32 || __APPLE__ */
+  static int w();
+  static int h();
+
+  // multi-head support:
+  static int screen_count();
+  static void screen_xywh(int &x, int &y, int &w, int &h) {
+    screen_xywh(x, y, w, h, e_x_root, e_y_root);
+  }
+  static void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my);
+  static void screen_xywh(int &x, int &y, int &w, int &h, int n);
+
+  // color map:
+  static void	set_color(Fl_Color, uchar, uchar, uchar);
+  static void	set_color(Fl_Color, unsigned);
+  static unsigned get_color(Fl_Color);
+  static void	get_color(Fl_Color, uchar&, uchar&, uchar&);
+  static void	free_color(Fl_Color, int overlay = 0);
+
+  // fonts:
+  static const char* get_font(Fl_Font);
+  static const char* get_font_name(Fl_Font, int* attributes = 0);
+  static int get_font_sizes(Fl_Font, int*& sizep);
+  static void set_font(Fl_Font, const char*);
+  static void set_font(Fl_Font, Fl_Font);
+  static Fl_Font set_fonts(const char* = 0);
+
+  // labeltypes:
+  static void set_labeltype(Fl_Labeltype,Fl_Label_Draw_F*,Fl_Label_Measure_F*);
+  static void set_labeltype(Fl_Labeltype, Fl_Labeltype from);
+
+  // boxtypes:
+  static Fl_Box_Draw_F *get_boxtype(Fl_Boxtype);
+  static void set_boxtype(Fl_Boxtype, Fl_Box_Draw_F*,uchar,uchar,uchar,uchar);
+  static void set_boxtype(Fl_Boxtype, Fl_Boxtype from);
+  static int box_dx(Fl_Boxtype);
+  static int box_dy(Fl_Boxtype);
+  static int box_dw(Fl_Boxtype);
+  static int box_dh(Fl_Boxtype);
+  static int draw_box_active();
+
+  // back compatability:
+  static void set_abort(void (*f)(const char*,...)) {fatal = f;}
+  static void (*atclose)(Fl_Window*,void*);
+  static void default_atclose(Fl_Window*,void*);
+  static void set_atclose(void (*f)(Fl_Window*,void*)) {atclose = f;}
+  static int event_shift() {return e_state&FL_SHIFT;}
+  static int event_ctrl() {return e_state&FL_CTRL;}
+  static int event_alt() {return e_state&FL_ALT;}
+  static int event_buttons() {return e_state&0x7f000000;}
+  static int event_button1() {return e_state&FL_BUTTON1;}
+  static int event_button2() {return e_state&FL_BUTTON2;}
+  static int event_button3() {return e_state&FL_BUTTON3;}
+  static void set_idle(void (*cb)()) {idle = cb;}
+  static void grab(Fl_Window&win) {grab(&win);}
+  static void release() {grab(0);}
+
+  // Visible focus methods...
+  static void visible_focus(int v) { visible_focus_ = v; }
+  static int  visible_focus() { return visible_focus_; }
+
+  // Drag-n-drop text operation methods...
+  static void dnd_text_ops(int v) { dnd_text_ops_ = v; }
+  static int  dnd_text_ops() { return dnd_text_ops_; }
+
+  // Multithreading support:
+  static void lock();
+  static void unlock();
+  static void awake(void* message = 0);
+  static void* thread_message();
+
+  // Widget deletion:
+  static void delete_widget(Fl_Widget *w);
+  static void do_widget_deletion();
+};
+
+#endif // !Fl_H
+
+//
+// End of "$Id: Fl.H 4223 2005-03-31 16:01:24Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Adjuster.H b/Utilities/FLTK/FL/Fl_Adjuster.H
new file mode 100644
index 0000000000000000000000000000000000000000..466283ae8a92c687ce557a761b4ba99998e8e99e
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Adjuster.H
@@ -0,0 +1,55 @@
+//
+// "$Id: Fl_Adjuster.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Adjuster widget header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// 3-button "slider", made for Nuke
+
+#ifndef Fl_Adjuster_H
+#define Fl_Adjuster_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+class FL_EXPORT Fl_Adjuster : public Fl_Valuator {
+  int drag;
+  int ix;
+  int soft_;
+protected:
+  void draw();
+  int handle(int);
+  void value_damage();
+public:
+  Fl_Adjuster(int X,int Y,int W,int H,const char *l=0);
+  void soft(int s) {soft_ = s;}
+  int soft() const {return soft_;}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Adjuster.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_BMP_Image.H b/Utilities/FLTK/FL/Fl_BMP_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..30bdcc4e7bfde374285320a2f5de4eda1d25b273
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_BMP_Image.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_BMP_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// BMP image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_BMP_Image_H
+#define Fl_BMP_Image_H
+#  include "Fl_Image.H"
+
+class FL_EXPORT Fl_BMP_Image : public Fl_RGB_Image {
+
+  public:
+
+  Fl_BMP_Image(const char* filename);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_BMP_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Bitmap.H b/Utilities/FLTK/FL/Fl_Bitmap.H
new file mode 100644
index 0000000000000000000000000000000000000000..e8686b09decde38579c8b3f24f4d6fc111f13123
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Bitmap.H
@@ -0,0 +1,64 @@
+//
+// "$Id: Fl_Bitmap.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Bitmap header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Bitmap_H
+#define Fl_Bitmap_H
+#  include "Fl_Image.H"
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+
+class FL_EXPORT Fl_Bitmap : public Fl_Image {
+  public:
+
+  const uchar *array;
+  int alloc_array; // Non-zero if data was allocated
+#if defined(__APPLE__) || defined(WIN32)
+  void *id; // for internal use
+#else
+  unsigned id; // for internal use
+#endif // __APPLE__ || WIN32
+  
+  Fl_Bitmap(const uchar *bits, int W, int H) :
+    Fl_Image(W,H,0), array(bits), alloc_array(0), id(0) {data((const char **)&array, 1);}
+  Fl_Bitmap(const char *bits, int W, int H) :
+    Fl_Image(W,H,0), array((const uchar *)bits), alloc_array(0), id(0) {data((const char **)&array, 1);}
+  virtual ~Fl_Bitmap();
+  virtual Fl_Image *copy(int W, int H);
+  Fl_Image *copy() { return copy(w(), h()); }
+  virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0);
+  void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);}
+  virtual void label(Fl_Widget*w);
+  virtual void label(Fl_Menu_Item*m);
+  virtual void uncache();
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Bitmap.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Box.H b/Utilities/FLTK/FL/Fl_Box.H
new file mode 100644
index 0000000000000000000000000000000000000000..36fdc0f0cf0b2e7a956a24ecefe04073d8b15407
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Box.H
@@ -0,0 +1,51 @@
+//
+// "$Id: Fl_Box.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Box header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Box_H
+#define Fl_Box_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+class FL_EXPORT Fl_Box : public Fl_Widget {
+protected:
+  void draw();
+public:
+  Fl_Box(int X, int Y, int W, int H, const char *l=0)
+	: Fl_Widget(X,Y,W,H,l) {}
+  Fl_Box(Fl_Boxtype b, int X, int Y, int W, int H, const char *l)
+	: Fl_Widget(X,Y,W,H,l) {box(b);}
+
+  virtual int handle(int);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Box.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Browser.H b/Utilities/FLTK/FL/Fl_Browser.H
new file mode 100644
index 0000000000000000000000000000000000000000..ed0af811d44f7bc1c54d09a41a09ae87bf574833
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Browser.H
@@ -0,0 +1,132 @@
+//
+// "$Id: Fl_Browser.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Forms-compatable browser.  Probably useful for other
+// lists of textual data.  Notice that the line numbers
+// start from 1, and 0 means "no line".
+
+#ifndef Fl_Browser_H
+#define Fl_Browser_H
+
+#include "Fl_Browser_.H"
+
+struct FL_BLINE;
+
+class FL_EXPORT Fl_Browser : public Fl_Browser_ {
+
+  FL_BLINE *first;		// the array of lines
+  FL_BLINE *last;
+  FL_BLINE *cache;
+  int cacheline;		// line number of cache
+  int lines;                	// Number of lines
+  int full_height_;
+  const int* column_widths_;
+  char format_char_;		// alternative to @-sign
+  char column_char_;		// alternative to tab
+
+protected:
+
+  // required routines for Fl_Browser_ subclass:
+  void* item_first() const ;
+  void* item_next(void*) const ;
+  void* item_prev(void*) const ;
+  int item_selected(void*) const ;
+  void item_select(void*, int);
+  int item_height(void*) const ;
+  int item_width(void*) const ;
+  void item_draw(void*, int, int, int, int) const ;
+  int full_height() const ;
+  int incr_height() const ;
+
+  FL_BLINE* find_line(int) const ;
+  FL_BLINE* _remove(int) ;
+  void insert(int, FL_BLINE*);
+  int lineno(void*) const ;
+  void swap(FL_BLINE *a, FL_BLINE *b);
+
+public:
+
+  void remove(int);
+  void add(const char*, void* = 0);
+  void insert(int, const char*, void* = 0);
+  void move(int to, int from);
+  int  load(const char* filename);
+  void swap(int a, int b);
+  void clear();
+
+  int size() const {return lines;}
+  void size(int W, int H) { Fl_Widget::size(W, H); }
+
+  int topline() const ;
+  enum Fl_Line_Position { TOP, BOTTOM, MIDDLE };
+  void lineposition(int, Fl_Line_Position);
+  void topline(int l) { lineposition(l, TOP); }
+  void bottomline(int l) { lineposition(l, BOTTOM); }
+  void middleline(int l) { lineposition(l, MIDDLE); }
+
+  int select(int, int=1);
+  int selected(int) const ;
+  void show(int n);
+  void show() {Fl_Widget::show();}
+  void hide(int n);
+  void hide() {Fl_Widget::hide();}
+  int visible(int n) const ;
+
+  int value() const ;
+  void value(int v) {select(v);}
+  const char* text(int) const ;
+  void text(int, const char*);
+  void* data(int) const ;
+  void data(int, void* v);
+
+  Fl_Browser(int, int, int, int, const char* = 0);
+  ~Fl_Browser() { clear(); }
+
+  char format_char() const {return format_char_;}
+  void format_char(char c) {format_char_ = c;}
+  char column_char() const {return column_char_;}
+  void column_char(char c) {column_char_ = c;}
+  const int* column_widths() const {return column_widths_;}
+  void column_widths(const int* l) {column_widths_ = l;}
+
+  int displayed(int n) const {return Fl_Browser_::displayed(find_line(n));}
+  void make_visible(int n) {
+  	if (n < 1) Fl_Browser_::display(find_line(1));
+	else if (n > lines) Fl_Browser_::display(find_line(lines));
+	else Fl_Browser_::display(find_line(n));
+  }
+
+  // for back compatability only:
+  void replace(int a, const char* b) {text(a, b);}
+  void display(int, int=1);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Browser.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Browser_.H b/Utilities/FLTK/FL/Fl_Browser_.H
new file mode 100644
index 0000000000000000000000000000000000000000..c66d414edccb5900a1922831c09309bf8aec8889
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Browser_.H
@@ -0,0 +1,153 @@
+//
+// "$Id: Fl_Browser_.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Common browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This is the base class for browsers.  To be useful it must
+// be subclassed and several virtual functions defined.  The
+// Forms-compatable browser and the file chooser's browser are
+// subclassed off of this.
+
+// Yes, I know this should be a template...
+
+#ifndef Fl_Browser__H
+#define Fl_Browser__H
+
+#ifndef Fl_Group_H
+#include "Fl_Group.H"
+#endif
+#include "Fl_Scrollbar.H"
+
+#define FL_NORMAL_BROWSER	0
+#define FL_SELECT_BROWSER	1
+#define FL_HOLD_BROWSER		2
+#define FL_MULTI_BROWSER	3
+
+class FL_EXPORT Fl_Browser_ : public Fl_Group {
+  int position_;	// where user wants it scrolled to
+  int real_position_;	// the current vertical scrolling position
+  int hposition_;	// where user wants it panned to
+  int real_hposition_;	// the current horizontal scrolling position
+  int offset_;		// how far down top_ item the real_position is
+  int max_width;	// widest object seen so far
+  uchar has_scrollbar_;	// which scrollbars are enabled
+  uchar textfont_, textsize_;
+  unsigned textcolor_;
+  void* top_;		// which item scrolling position is in
+  void* selection_;	// which is selected (except for FL_MULTI_BROWSER)
+  void *redraw1,*redraw2; // minimal update pointers
+  void* max_width_item;	// which item has max_width_
+
+  static int scrollbar_width_;
+
+  void update_top();
+
+protected:
+
+  // All of the following must be supplied by the subclass:
+  virtual void *item_first() const = 0;
+  virtual void *item_next(void *) const = 0;
+  virtual void *item_prev(void *) const = 0;
+  virtual int item_height(void *) const = 0;
+  virtual int item_width(void *) const = 0;
+  virtual int item_quick_height(void *) const ;
+  virtual void item_draw(void *,int,int,int,int) const = 0;
+  // you don't have to provide these but it may help speed it up:
+  virtual int full_width() const ;	// current width of all items
+  virtual int full_height() const ;	// current height of all items
+  virtual int incr_height() const ;	// average height of an item
+  // These only need to be done by subclass if you want a multi-browser:
+  virtual void item_select(void *,int=1);
+  virtual int item_selected(void *) const ;
+
+  // things the subclass may want to call:
+  void *top() const {return top_;}
+  void *selection() const {return selection_;}
+  void new_list(); // completely clobber all data, as though list replaced
+  void deleting(void *a); // get rid of any pointers to a
+  void replacing(void *a,void *b); // change a pointers to b
+  void inserting(void *a,void *b); // insert b near a
+  int displayed(void *) const ; // true if this line is visible
+  void redraw_line(void *); // minimal update, no change in size
+  void redraw_lines() {damage(FL_DAMAGE_SCROLL);} // redraw all of them
+  void bbox(int&,int&,int&,int&) const;
+  int leftedge() const;	// x position after scrollbar & border
+  void *find_item(int my); // item under mouse
+  void draw(int,int,int,int);
+  int handle(int,int,int,int,int);
+
+  void draw();
+  Fl_Browser_(int,int,int,int,const char * = 0);
+
+public:
+
+  Fl_Scrollbar scrollbar;		// Vertical scrollbar
+  Fl_Scrollbar hscrollbar;		// Horizontal scrollbar
+
+  int handle(int);
+  void resize(int,int,int,int);
+
+  int select(void *,int=1,int docallbacks=0);
+  int select_only(void *,int docallbacks=0);
+  int deselect(int docallbacks=0);
+  int position() const {return position_;}
+  int hposition() const {return hposition_;}
+  void position(int); // scroll to here
+  void hposition(int); // pan to here
+  void display(void*); // scroll so this item is shown
+
+  uchar has_scrollbar() const {return has_scrollbar_;}
+  void has_scrollbar(uchar i) {has_scrollbar_ = i;}
+  enum { // values for has_scrollbar()
+    HORIZONTAL = 1,
+    VERTICAL = 2,
+    BOTH = 3,
+    ALWAYS_ON = 4,
+    HORIZONTAL_ALWAYS = 5,
+    VERTICAL_ALWAYS = 6,
+    BOTH_ALWAYS = 7
+  };
+
+  Fl_Font textfont() const {return (Fl_Font)textfont_;}
+  void textfont(uchar s) {textfont_ = s;}
+  uchar textsize() const {return textsize_;}
+  void textsize(uchar s) {textsize_ = s;}
+  Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+  void textcolor(unsigned n) {textcolor_ = n;}
+
+  static void scrollbar_width(int b) {scrollbar_width_ = b;}
+  static int scrollbar_width() {return scrollbar_width_;}
+
+  // for back compatability:
+  void scrollbar_right() {scrollbar.align(FL_ALIGN_RIGHT);}
+  void scrollbar_left() {scrollbar.align(FL_ALIGN_LEFT);}
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Browser_.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Button.H b/Utilities/FLTK/FL/Fl_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..15510b137d640888afc551915d2aa7797d1aa427
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Button.H
@@ -0,0 +1,78 @@
+//
+// "$Id: Fl_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Button_H
+#define Fl_Button_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type()
+#define FL_NORMAL_BUTTON	0
+#define FL_TOGGLE_BUTTON	1
+#define FL_RADIO_BUTTON		(FL_RESERVED_TYPE+2)
+#define FL_HIDDEN_BUTTON	3 // for Forms compatability
+
+extern FL_EXPORT int fl_old_shortcut(const char*);
+
+class FL_EXPORT Fl_Button : public Fl_Widget {
+
+  int shortcut_;
+  char value_;
+  char oldval;
+  uchar down_box_;
+
+protected:
+
+  virtual void draw();
+
+public:
+
+  virtual int handle(int);
+  Fl_Button(int,int,int,int,const char * = 0);
+  int value(int);
+  char value() const {return value_;}
+  int set() {return value(1);}
+  int clear() {return value(0);}
+  void setonly(); // this should only be called on FL_RADIO_BUTTONs
+  int shortcut() const {return shortcut_;}
+  void shortcut(int s) {shortcut_ = s;}
+  Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;}
+  void down_box(Fl_Boxtype b) {down_box_ = b;}
+
+  // back compatability:
+  void shortcut(const char *s) {shortcut(fl_old_shortcut(s));}
+  Fl_Color down_color() const {return selection_color();}
+  void down_color(unsigned c) {selection_color(c);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Chart.H b/Utilities/FLTK/FL/Fl_Chart.H
new file mode 100644
index 0000000000000000000000000000000000000000..a705930991b996b54d974af5185cc2cd21356e77
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Chart.H
@@ -0,0 +1,93 @@
+//
+// "$Id: Fl_Chart.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Forms chart header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Chart_H
+#define Fl_Chart_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type()
+#define FL_BAR_CHART		0
+#define FL_HORBAR_CHART		1
+#define FL_LINE_CHART		2
+#define FL_FILL_CHART		3
+#define FL_SPIKE_CHART		4
+#define FL_PIE_CHART		5
+#define FL_SPECIALPIE_CHART	6
+
+#define FL_FILLED_CHART  FL_FILL_CHART	// compatibility
+
+#define FL_CHART_MAX		128
+#define FL_CHART_LABEL_MAX	18
+
+struct FL_CHART_ENTRY {
+   float val;
+   unsigned col;
+   char str[FL_CHART_LABEL_MAX+1];
+};
+
+class FL_EXPORT Fl_Chart : public Fl_Widget {
+    int numb;
+    int maxnumb;
+    int sizenumb;
+    FL_CHART_ENTRY *entries;
+    double min,max;
+    uchar autosize_;
+    uchar textfont_,textsize_;
+    unsigned textcolor_;
+protected:
+    void draw();
+public:
+    Fl_Chart(int,int,int,int,const char * = 0);
+    ~Fl_Chart();
+    void clear();
+    void add(double, const char * =0, unsigned=0);
+    void insert(int, double, const char * =0, unsigned=0);
+    void replace(int, double, const char * =0, unsigned=0);
+    void bounds(double *a,double *b) const {*a = min; *b = max;}
+    void bounds(double a,double b);
+    int size() const {return numb;}
+    void size(int W, int H) { Fl_Widget::size(W, H); }
+    int maxsize() const {return maxnumb;}
+    void maxsize(int);
+    Fl_Font textfont() const {return (Fl_Font)textfont_;}
+    void textfont(uchar s) {textfont_ = s;}
+    uchar textsize() const {return textsize_;}
+    void textsize(uchar s) {textsize_ = s;}
+    Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+    void textcolor(unsigned n) {textcolor_ = n;}
+    uchar autosize() const {return autosize_;}
+    void autosize(uchar n) {autosize_ = n;}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Chart.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Check_Browser.H b/Utilities/FLTK/FL/Fl_Check_Browser.H
new file mode 100644
index 0000000000000000000000000000000000000000..f474a03a0c903f8d7dee717796683d43c824e780
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Check_Browser.H
@@ -0,0 +1,98 @@
+//
+// "$Id: Fl_Check_Browser.H 4461 2005-08-05 13:31:02Z dejan $"
+//
+// Fl_Check_Browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Check_Browser_H
+#define Fl_Check_Browser_H
+
+#include "Fl.H"
+#include "Fl_Browser_.H"
+
+class FL_EXPORT Fl_Check_Browser : public Fl_Browser_ {
+  /* required routines for Fl_Browser_ subclass: */
+
+  void *item_first() const;
+  void *item_next(void *) const;
+  void *item_prev(void *) const;
+  int item_height(void *) const;
+  int item_width(void *) const;
+  void item_draw(void *, int, int, int, int) const;
+  void item_select(void *, int);
+  int item_selected(void *) const;
+
+  /* private data */
+
+  public: // IRIX 5.3 C++ compiler doesn't support private structures...
+
+  struct cb_item {
+	  cb_item *next;
+	  cb_item *prev;
+	  char checked;
+	  char selected;
+	  char *text;
+  };
+
+  private:
+
+  cb_item *first;
+  cb_item *last;
+  cb_item *cache;
+  int cached_item;
+  int nitems_;
+  int nchecked_;
+  cb_item *find_item(int) const;
+  int lineno(cb_item *) const;
+
+  public:
+
+  Fl_Check_Browser(int x, int y, int w, int h, const char *l = 0);
+  ~Fl_Check_Browser() { clear(); }
+  int add(char *s);               // add an (unchecked) item
+  int add(char *s, int b);        // add an item and set checked
+				  // both return the new nitems()
+
+  // inline const char * methods to avoid breaking binary compatibility...
+  int add(const char *s) { return add((char *)s); }
+  int add(const char *s, int b) { return add((char *)s, b); }
+
+  void clear();                   // delete all items
+  int nitems() const { return nitems_; }
+  int nchecked() const { return nchecked_; }
+  int checked(int item) const;
+  void checked(int item, int b);
+  void set_checked(int item) { checked(item, 1); }
+  void check_all();
+  void check_none();
+  int value() const;              // currently selected item
+  char *text(int item) const;     // returns pointer to internal buffer
+};
+
+#endif // Fl_Check_Browser_H
+
+//
+// End of "$Id: Fl_Check_Browser.H 4461 2005-08-05 13:31:02Z dejan $".
+//
+
diff --git a/Utilities/FLTK/FL/Fl_Check_Button.H b/Utilities/FLTK/FL/Fl_Check_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..4064cf5b91c1cbb4f54e65ba40ee3aa81e827ad7
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Check_Button.H
@@ -0,0 +1,42 @@
+//
+// "$Id: Fl_Check_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Check button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Check_Button_H
+#define Fl_Check_Button_H
+
+#include "Fl_Light_Button.H"
+
+class FL_EXPORT Fl_Check_Button : public Fl_Light_Button {
+public:
+  Fl_Check_Button(int x,int y,int w,int h,const char *l = 0);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Check_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Choice.H b/Utilities/FLTK/FL/Fl_Choice.H
new file mode 100644
index 0000000000000000000000000000000000000000..64e59b68f6d4db42729947de6bf90c2bef1dc9c6
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Choice.H
@@ -0,0 +1,48 @@
+//
+// "$Id: Fl_Choice.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Choice header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Choice_H
+#define Fl_Choice_H
+
+#include "Fl_Menu_.H"
+
+class FL_EXPORT Fl_Choice : public Fl_Menu_ {
+protected:
+  void draw();
+public:
+  int handle(int);
+  Fl_Choice(int,int,int,int,const char * = 0);
+  int value(const Fl_Menu_Item*);
+  int value(int i);
+  int value() const {return Fl_Menu_::value();}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Choice.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Clock.H b/Utilities/FLTK/FL/Fl_Clock.H
new file mode 100644
index 0000000000000000000000000000000000000000..261470c9f4ce1cbc2903245bd045744d4b88820e
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Clock.H
@@ -0,0 +1,75 @@
+//
+// "$Id: Fl_Clock.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Clock header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Clock_H
+#define Fl_Clock_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type:
+#define FL_SQUARE_CLOCK		0
+#define FL_ROUND_CLOCK		1
+#define FL_ANALOG_CLOCK FL_SQUARE_CLOCK
+#define FL_DIGITAL_CLOCK FL_SQUARE_CLOCK // nyi
+
+// a Fl_Clock_Output can be used to display a program-supplied time:
+
+class FL_EXPORT Fl_Clock_Output : public Fl_Widget {
+  int hour_, minute_, second_;
+  ulong value_;
+  void drawhands(Fl_Color,Fl_Color); // part of draw
+protected:
+  void draw(int, int, int, int);
+  void draw();
+public:
+  Fl_Clock_Output(int x,int y,int w,int h, const char *l = 0);
+  void value(ulong v);	// set to this Unix time
+  void value(int,int,int);	// set hour, minute, second
+  ulong value() const {return value_;}
+  int hour() const {return hour_;}
+  int minute() const {return minute_;}
+  int second() const {return second_;}
+};
+
+// a Fl_Clock displays the current time always by using a timeout:
+
+class FL_EXPORT Fl_Clock : public Fl_Clock_Output {
+public:
+  int handle(int);
+  void update();
+  Fl_Clock(int x,int y,int w,int h, const char *l = 0);
+  Fl_Clock(uchar t,int x,int y,int w,int h, const char *l);
+  ~Fl_Clock();
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Clock.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Color_Chooser.H b/Utilities/FLTK/FL/Fl_Color_Chooser.H
new file mode 100644
index 0000000000000000000000000000000000000000..2ef7250631ce864ec42883a46743ff1e5afeb610
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Color_Chooser.H
@@ -0,0 +1,104 @@
+//
+// "$Id: Fl_Color_Chooser.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Color chooser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// The color chooser object and the color chooser popup.  The popup
+// is just a window containing a single color chooser and some boxes
+// to indicate the current and cancelled color.
+
+#ifndef Fl_Color_Chooser_H
+#define Fl_Color_Chooser_H
+
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Value_Input.H>
+
+class FL_EXPORT Flcc_HueBox : public Fl_Widget {
+  int px, py;
+protected:
+  void draw();
+  int handle_key(int);
+public:
+  int handle(int);
+  Flcc_HueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
+  px = py = 0;}
+};
+
+class FL_EXPORT Flcc_ValueBox : public Fl_Widget {
+  int py;
+protected:
+  void draw();
+  int handle_key(int);
+public:
+  int handle(int);
+  Flcc_ValueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
+  py = 0;}
+};
+
+class FL_EXPORT Flcc_Value_Input : public Fl_Value_Input {
+public:
+  int format(char*);
+  Flcc_Value_Input(int X, int Y, int W, int H) : Fl_Value_Input(X,Y,W,H) {}
+};
+
+class FL_EXPORT Fl_Color_Chooser : public Fl_Group {
+  Flcc_HueBox huebox;
+  Flcc_ValueBox valuebox;
+  Fl_Choice choice;
+  Flcc_Value_Input rvalue;
+  Flcc_Value_Input gvalue;
+  Flcc_Value_Input bvalue;
+  Fl_Box resize_box;
+  double hue_, saturation_, value_;
+  double r_, g_, b_;
+  void set_valuators();
+  static void rgb_cb(Fl_Widget*, void*);
+  static void mode_cb(Fl_Widget*, void*);
+public:
+  int mode() {return choice.value();}
+  double hue() const {return hue_;}
+  double saturation() const {return saturation_;}
+  double value() const {return value_;}
+  double r() const {return r_;}
+  double g() const {return g_;}
+  double b() const {return b_;}
+  int hsv(double,double,double);
+  int rgb(double,double,double);
+  static void hsv2rgb(double, double, double,double&,double&,double&);
+  static void rgb2hsv(double, double, double,double&,double&,double&);
+  Fl_Color_Chooser(int,int,int,int,const char* = 0);
+};
+
+FL_EXPORT int fl_color_chooser(const char* name, double& r, double& g, double& b);
+FL_EXPORT int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b);
+
+#endif
+
+//
+// End of "$Id: Fl_Color_Chooser.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Counter.H b/Utilities/FLTK/FL/Fl_Counter.H
new file mode 100644
index 0000000000000000000000000000000000000000..73781a8b80db4ac1e7494c8b68649fb9d19313cf
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Counter.H
@@ -0,0 +1,76 @@
+//
+// "$Id: Fl_Counter.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Counter header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// A numerical value with up/down step buttons.  From Forms.
+
+#ifndef Fl_Counter_H
+#define Fl_Counter_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+// values for type():
+#define FL_NORMAL_COUNTER	0
+#define FL_SIMPLE_COUNTER	1
+
+class FL_EXPORT Fl_Counter : public Fl_Valuator {
+
+  uchar textfont_, textsize_;
+  unsigned textcolor_;
+  double lstep_;
+  uchar mouseobj;
+  static void repeat_callback(void *);
+  int calc_mouseobj();
+  void increment_cb();
+
+protected:
+
+  void draw();
+
+public:
+
+  int handle(int);
+  Fl_Counter(int,int,int,int,const char * = 0);
+  ~Fl_Counter();
+  void lstep(double a) {lstep_ = a;}
+  void step(double a,double b) {Fl_Valuator::step(a); lstep_ = b;}
+  void step(double a) {Fl_Valuator::step(a);}
+  Fl_Font textfont() const {return (Fl_Font)textfont_;}
+  void textfont(uchar s) {textfont_ = s;}
+  uchar textsize() const {return textsize_;}
+  void textsize(uchar s) {textsize_ = s;}
+  Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+  void textcolor(unsigned s) {textcolor_ = s;}
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Counter.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Dial.H b/Utilities/FLTK/FL/Fl_Dial.H
new file mode 100644
index 0000000000000000000000000000000000000000..f067036ff8d66163a0c88d100074e86dcd055bd2
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Dial.H
@@ -0,0 +1,67 @@
+//
+// "$Id: Fl_Dial.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Dial header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Dial_H
+#define Fl_Dial_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+// values for type():
+#define FL_NORMAL_DIAL	0
+#define FL_LINE_DIAL	1
+#define FL_FILL_DIAL	2
+
+class FL_EXPORT Fl_Dial : public Fl_Valuator {
+
+  short a1,a2;
+
+protected:
+
+  // these allow subclasses to put the dial in a smaller area:
+  void draw(int, int, int, int);
+  int handle(int, int, int, int, int);
+  void draw();
+
+public:
+
+  int handle(int);
+  Fl_Dial(int x,int y,int w,int h, const char *l = 0);
+  short angle1() const {return a1;}
+  void angle1(short a) {a1 = a;}
+  short angle2() const {return a2;}
+  void angle2(short a) {a2 = a;}
+  void angles(short a, short b) {a1 = a; a2 = b;}
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Dial.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Double_Window.H b/Utilities/FLTK/FL/Fl_Double_Window.H
new file mode 100644
index 0000000000000000000000000000000000000000..635c7cb3c484c57bd15e8fcf5279fc1cc1087162
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Double_Window.H
@@ -0,0 +1,54 @@
+//
+// "$Id: Fl_Double_Window.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Double-buffered window header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Double_Window_H
+#define Fl_Double_Window_H
+
+#include "Fl_Window.H"
+
+class FL_EXPORT Fl_Double_Window : public Fl_Window {
+protected:
+  void flush(int eraseoverlay);
+  char force_doublebuffering_; // force db, even if the OS already buffers windows (overlays need that on MacOS and Windows2000)
+public:
+  void show();
+  void show(int a, char **b) {Fl_Window::show(a,b);}
+  void flush();
+  void resize(int,int,int,int);
+  void hide();
+  ~Fl_Double_Window();
+  Fl_Double_Window(int W, int H, const char *l = 0) 
+    : Fl_Window(W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); }
+  Fl_Double_Window(int X, int Y, int W, int H, const char *l = 0)
+    : Fl_Window(X,Y,W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); }
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Double_Window.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Export.H b/Utilities/FLTK/FL/Fl_Export.H
new file mode 100644
index 0000000000000000000000000000000000000000..267f632224fa1fc25060175ec8bc18a8f4c2b374
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Export.H
@@ -0,0 +1,49 @@
+/*
+ * "$Id: Fl_Export.H 4288 2005-04-16 00:13:17Z mike $"
+ *
+ * WIN32 DLL export definitions for the Fast Light Tool Kit (FLTK).
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+#ifndef Fl_Export_H
+#  define Fl_Export_H
+
+/*
+ * The following is only used when building DLLs under WIN32...
+ */
+
+#  if defined(FL_DLL) && (defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) || __GNUC__ >= 3)
+#    ifdef FL_LIBRARY
+#      define FL_EXPORT	__declspec(dllexport)
+#    else
+#      define FL_EXPORT	__declspec(dllimport)
+#    endif /* FL_LIBRARY */
+#  else
+#    define FL_EXPORT
+#  endif /* FL_DLL */
+
+#endif /* !Fl_Export_H */
+
+/*
+ * End of "$Id: Fl_Export.H 4288 2005-04-16 00:13:17Z mike $".
+ */
diff --git a/Utilities/FLTK/FL/Fl_File_Browser.H b/Utilities/FLTK/FL/Fl_File_Browser.H
new file mode 100644
index 0000000000000000000000000000000000000000..3efbecc6ad91223fbf9af17cb935601a8008e578
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_File_Browser.H
@@ -0,0 +1,81 @@
+//
+// "$Id: Fl_File_Browser.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// FileBrowser definitions.
+//
+// Copyright 1999-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//
+// Include necessary header files...
+//
+
+#ifndef _Fl_File_Browser_H_
+#  define _Fl_File_Browser_H_
+
+#  include "Fl_Browser.H"
+#  include "Fl_File_Icon.H"
+#  include "filename.H"
+
+
+//
+// Fl_File_Browser class...
+//
+
+class FL_EXPORT Fl_File_Browser : public Fl_Browser
+{
+  int		filetype_;
+  const char	*directory_;
+  uchar		iconsize_;
+  const char	*pattern_;
+
+  int		full_height() const;
+  int		item_height(void *) const;
+  int		item_width(void *) const;
+  void		item_draw(void *, int, int, int, int) const;
+  int		incr_height() const { return (item_height(0)); }
+
+public:
+  enum { FILES, DIRECTORIES };
+
+  Fl_File_Browser(int, int, int, int, const char * = 0);
+
+  uchar		iconsize() const { return (iconsize_); };
+  void		iconsize(uchar s) { iconsize_ = s; redraw(); };
+
+  void	filter(const char *pattern);
+  const char	*filter() const { return (pattern_); };
+
+  int		load(const char *directory, Fl_File_Sort_F *sort = fl_numericsort);
+
+  uchar		textsize() const { return (Fl_Browser::textsize()); };
+  void		textsize(uchar s) { Fl_Browser::textsize(s); iconsize_ = (uchar)(3 * s / 2); };
+
+  int		filetype() const { return (filetype_); };
+  void		filetype(int t) { filetype_ = t; };
+};
+
+#endif // !_Fl_File_Browser_H_
+
+//
+// End of "$Id: Fl_File_Browser.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_File_Chooser.H b/Utilities/FLTK/FL/Fl_File_Chooser.H
new file mode 100644
index 0000000000000000000000000000000000000000..4382698aae69b09deff339f9921c58b6c983ac67
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_File_Chooser.H
@@ -0,0 +1,186 @@
+//
+// "$Id: Fl_File_Chooser.H 4473 2005-08-08 00:50:02Z mike $"
+//
+// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef Fl_File_Chooser_H
+#define Fl_File_Chooser_H
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Preferences.H>
+#include <FL/Fl_Tile.H>
+#include <FL/Fl_File_Browser.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_File_Input.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/fl_ask.H>
+
+class FL_EXPORT Fl_File_Chooser {
+public:
+  enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 };
+private:
+  static Fl_Preferences prefs_;
+  void (*callback_)(Fl_File_Chooser*, void *);
+  void *data_;
+  char directory_[1024];
+  char pattern_[1024];
+  char preview_text_[2048];
+  int type_;
+  void favoritesButtonCB();
+  void favoritesCB(Fl_Widget *w);
+  void fileListCB();
+  void fileNameCB();
+  void newdir();
+  static void previewCB(Fl_File_Chooser *fc);
+  void showChoiceCB();
+  void update_favorites();
+  void update_preview();
+public:
+  Fl_File_Chooser(const char *d, const char *p, int t, const char *title);
+private:
+  Fl_Double_Window *window;
+  void cb_window_i(Fl_Double_Window*, void*);
+  static void cb_window(Fl_Double_Window*, void*);
+  Fl_Choice *showChoice;
+  void cb_showChoice_i(Fl_Choice*, void*);
+  static void cb_showChoice(Fl_Choice*, void*);
+  Fl_Menu_Button *favoritesButton;
+  void cb_favoritesButton_i(Fl_Menu_Button*, void*);
+  static void cb_favoritesButton(Fl_Menu_Button*, void*);
+public:
+  Fl_Button *newButton;
+private:
+  void cb_newButton_i(Fl_Button*, void*);
+  static void cb_newButton(Fl_Button*, void*);
+  void cb__i(Fl_Tile*, void*);
+  static void cb_(Fl_Tile*, void*);
+  Fl_File_Browser *fileList;
+  void cb_fileList_i(Fl_File_Browser*, void*);
+  static void cb_fileList(Fl_File_Browser*, void*);
+  Fl_Box *previewBox;
+public:
+  Fl_Check_Button *previewButton;
+private:
+  void cb_previewButton_i(Fl_Check_Button*, void*);
+  static void cb_previewButton(Fl_Check_Button*, void*);
+  Fl_File_Input *fileName;
+  void cb_fileName_i(Fl_File_Input*, void*);
+  static void cb_fileName(Fl_File_Input*, void*);
+  Fl_Return_Button *okButton;
+  void cb_okButton_i(Fl_Return_Button*, void*);
+  static void cb_okButton(Fl_Return_Button*, void*);
+  Fl_Button *cancelButton;
+  void cb_cancelButton_i(Fl_Button*, void*);
+  static void cb_cancelButton(Fl_Button*, void*);
+  Fl_Double_Window *favWindow;
+  Fl_File_Browser *favList;
+  void cb_favList_i(Fl_File_Browser*, void*);
+  static void cb_favList(Fl_File_Browser*, void*);
+  Fl_Button *favUpButton;
+  void cb_favUpButton_i(Fl_Button*, void*);
+  static void cb_favUpButton(Fl_Button*, void*);
+  Fl_Button *favDeleteButton;
+  void cb_favDeleteButton_i(Fl_Button*, void*);
+  static void cb_favDeleteButton(Fl_Button*, void*);
+  Fl_Button *favDownButton;
+  void cb_favDownButton_i(Fl_Button*, void*);
+  static void cb_favDownButton(Fl_Button*, void*);
+  Fl_Button *favCancelButton;
+  void cb_favCancelButton_i(Fl_Button*, void*);
+  static void cb_favCancelButton(Fl_Button*, void*);
+  Fl_Return_Button *favOkButton;
+  void cb_favOkButton_i(Fl_Return_Button*, void*);
+  static void cb_favOkButton(Fl_Return_Button*, void*);
+public:
+  ~Fl_File_Chooser();
+  void callback(void (*cb)(Fl_File_Chooser *, void *), void *d = 0);
+  void color(Fl_Color c);
+  Fl_Color color();
+  int count();
+  void directory(const char *d);
+  char * directory();
+  void filter(const char *p);
+  const char * filter();
+  int filter_value();
+  void filter_value(int f);
+  void hide();
+  void iconsize(uchar s);
+  uchar iconsize();
+  void label(const char *l);
+  const char * label();
+  void ok_label(const char *l);
+  const char * ok_label();
+  void preview(int e);
+  int preview() const { return previewButton->value(); };
+  void rescan();
+  void show();
+  int shown();
+  void textcolor(Fl_Color c);
+  Fl_Color textcolor();
+  void textfont(uchar f);
+  uchar textfont();
+  void textsize(uchar s);
+  uchar textsize();
+  void type(int t);
+  int type();
+  void * user_data() const;
+  void user_data(void *d);
+  const char *value(int f = 1);
+  void value(const char *filename);
+  int visible();
+  static const char *add_favorites_label;
+  static const char *all_files_label;
+  static const char *custom_filter_label;
+  static const char *existing_file_label;
+  static const char *favorites_label;
+  static const char *filename_label;
+  static const char *filesystems_label;
+  static const char *manage_favorites_label;
+  static const char *new_directory_label;
+  static const char *new_directory_tooltip;
+  static const char *preview_label;
+  static const char *save_label;
+  static const char *show_label;
+  static Fl_File_Sort_F *sort;
+};
+FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0);
+FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0);
+FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*));
+FL_EXPORT void fl_file_chooser_ok_label(const char*l);
+#endif
+
+//
+// End of "$Id: Fl_File_Chooser.H 4473 2005-08-08 00:50:02Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_File_Icon.H b/Utilities/FLTK/FL/Fl_File_Icon.H
new file mode 100644
index 0000000000000000000000000000000000000000..85201296ab68de99dc1008586c476ab32ac17378
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_File_Icon.H
@@ -0,0 +1,115 @@
+//
+// "$Id: Fl_File_Icon.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Fl_File_Icon definitions.
+//
+// Copyright 1999-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//
+// Include necessary header files...
+//
+
+#ifndef _Fl_Fl_File_Icon_H_
+#  define _Fl_Fl_File_Icon_H_
+
+#  include "Fl.H"
+
+
+//
+// Special color value for the icon color.
+//
+
+#  define FL_ICON_COLOR (Fl_Color)0xffffffff
+
+
+//
+// Fl_File_Icon class...
+//
+
+class FL_EXPORT Fl_File_Icon			//// Icon data
+{
+  static Fl_File_Icon *first_;	// Pointer to first icon/filetype
+  Fl_File_Icon	*next_;		// Pointer to next icon/filetype
+  const char	*pattern_;	// Pattern string
+  int		type_;		// Match only if directory or file?
+  int		num_data_;	// Number of data elements
+  int		alloc_data_;	// Number of allocated elements
+  short		*data_;		// Icon data
+
+  public:
+
+  enum				// File types
+  {
+    ANY,			// Any kind of file
+    PLAIN,			// Only plain files
+    FIFO,			// Only named pipes
+    DEVICE,			// Only character and block devices
+    LINK,			// Only symbolic links
+    DIRECTORY			// Only directories
+  };
+
+  enum				// Data opcodes
+  {
+    END,			// End of primitive/icon
+    COLOR,			// Followed by color value (2 shorts)
+    LINE,			// Start of line
+    CLOSEDLINE,			// Start of closed line
+    POLYGON,			// Start of polygon
+    OUTLINEPOLYGON,		// Followed by outline color (2 shorts)
+    VERTEX			// Followed by scaled X,Y
+  };
+
+  Fl_File_Icon(const char *p, int t, int nd = 0, short *d = 0);
+  ~Fl_File_Icon();
+
+  short		*add(short d);
+  short		*add_color(Fl_Color c)
+		{ short *d = add((short)COLOR); add((short)(c >> 16)); add((short)c); return (d); }
+  short		*add_vertex(int x, int y)
+		{ short *d = add((short)VERTEX); add((short)x); add((short)y); return (d); }
+  short		*add_vertex(float x, float y)
+		{ short *d = add((short)VERTEX); add((short)(x * 10000.0));
+		  add((short)(y * 10000.0)); return (d); }
+  void		clear() { num_data_ = 0; }
+  void		draw(int x, int y, int w, int h, Fl_Color ic, int active = 1);
+  void		label(Fl_Widget *w);
+  static void	labeltype(const Fl_Label *o, int x, int y, int w, int h, Fl_Align a);
+  void		load(const char *f);
+  int		load_fti(const char *fti);
+  int		load_image(const char *i);
+  Fl_File_Icon	*next() { return (next_); }
+  const char	*pattern() { return (pattern_); }
+  int		size() { return (num_data_); }
+  int		type() { return (type_); }
+  short		*value() { return (data_); }
+
+  static Fl_File_Icon *find(const char *filename, int filetype = ANY);
+  static Fl_File_Icon *first() { return (first_); }
+  static void	load_system_icons(void);
+};
+
+#endif // !_Fl_Fl_File_Icon_H_
+
+//
+// End of "$Id: Fl_File_Icon.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_File_Input.H b/Utilities/FLTK/FL/Fl_File_Input.H
new file mode 100644
index 0000000000000000000000000000000000000000..b5ec6f1041e2c31c14b357b5bf35b25346eb34e9
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_File_Input.H
@@ -0,0 +1,68 @@
+//
+// "$Id: Fl_File_Input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// File_Input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+// Original version Copyright 1998 by Curtis Edwards.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_File_Input_H
+#  define Fl_File_Input_H
+
+#  include <FL/Fl_Input.H>
+
+
+class FL_EXPORT Fl_File_Input : public Fl_Input
+{
+  Fl_Color	errorcolor_;
+  char		ok_entry_;
+  uchar		down_box_;
+  short		buttons_[200];
+  short		pressed_;
+
+  void		draw_buttons();
+  int		handle_button(int event);
+  void		update_buttons();
+
+public:
+
+  Fl_File_Input(int,int,int,int,const char *t=0);
+
+  virtual int handle(int);
+  virtual void draw();
+
+  Fl_Boxtype	down_box() const { return (Fl_Boxtype)down_box_; }
+  void		down_box(Fl_Boxtype b) { down_box_ = b; }
+  Fl_Color	errorcolor() const { return errorcolor_; }
+  void		errorcolor(Fl_Color c) { errorcolor_ = c; }
+  int	value(const char*);
+  int	value(const char*, int);
+  const char	*value() { return Fl_Input_::value(); }
+};
+
+#endif // !Fl_File_Input_H
+
+
+//
+// End of "$Id: Fl_File_Input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Fill_Dial.H b/Utilities/FLTK/FL/Fl_Fill_Dial.H
new file mode 100644
index 0000000000000000000000000000000000000000..2472f6dc4214b7f58f95dc80f936b41f21c44296
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Fill_Dial.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Fill_Dial.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Filled dial header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Fill_Dial_H
+#define Fl_Fill_Dial_H
+
+#include "Fl_Dial.H"
+
+class Fl_Fill_Dial : public Fl_Dial {
+public:
+    Fl_Fill_Dial(int x,int y,int w,int h, const char *l = 0)
+	: Fl_Dial(x,y,w,h,l) {type(FL_FILL_DIAL);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Fill_Dial.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Fill_Slider.H b/Utilities/FLTK/FL/Fl_Fill_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..8635eeb821697a93438f8d41a43efe88c58c91b1
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Fill_Slider.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Filled slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Fill_Slider_H
+#define Fl_Fill_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Fill_Slider : public Fl_Slider {
+public:
+    Fl_Fill_Slider(int x,int y,int w,int h,const char *l=0)
+	: Fl_Slider(x,y,w,h,l) {type(FL_VERT_FILL_SLIDER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Float_Input.H b/Utilities/FLTK/FL/Fl_Float_Input.H
new file mode 100644
index 0000000000000000000000000000000000000000..526674d2bd0073edb5fb75092b2d947e36d07e79
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Float_Input.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Float_Input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Floating point input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Float_Input_H
+#define Fl_Float_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Float_Input : public Fl_Input {
+public:
+    Fl_Float_Input(int X,int Y,int W,int H,const char *l = 0)
+	: Fl_Input(X,Y,W,H,l) {type(FL_FLOAT_INPUT);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Float_Input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_FormsBitmap.H b/Utilities/FLTK/FL/Fl_FormsBitmap.H
new file mode 100644
index 0000000000000000000000000000000000000000..caa3a0734b1a886a80baedffdfaeaca8bc7555d0
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_FormsBitmap.H
@@ -0,0 +1,48 @@
+//
+// "$Id: Fl_FormsBitmap.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Forms bitmap header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_FormsBitmap_H
+#define Fl_FormsBitmap_H
+
+#include "Fl_Bitmap.H"
+
+class FL_EXPORT Fl_FormsBitmap : public Fl_Widget {
+    Fl_Bitmap *b;
+protected:
+    void draw();
+public:
+    Fl_FormsBitmap(Fl_Boxtype, int, int, int, int, const char * = 0);
+    void set(int W, int H, const uchar *bits);
+    void bitmap(Fl_Bitmap *B) {b = B;}
+    Fl_Bitmap *bitmap() const {return b;}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_FormsBitmap.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_FormsPixmap.H b/Utilities/FLTK/FL/Fl_FormsPixmap.H
new file mode 100644
index 0000000000000000000000000000000000000000..f25bed6d76c812f1d310ae236cb56f75263b1187
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_FormsPixmap.H
@@ -0,0 +1,48 @@
+//
+// "$Id: Fl_FormsPixmap.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Forms pixmap header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_FormsPixmap_H
+#define Fl_FormsPixmap_H
+
+#include "Fl_Pixmap.H"
+
+class FL_EXPORT Fl_FormsPixmap : public Fl_Widget {
+    Fl_Pixmap *b;
+protected:
+    void draw();
+public:
+    Fl_FormsPixmap(Fl_Boxtype, int, int, int, int, const char * = 0);
+    void set(/*const*/char * const * bits);
+    void Pixmap(Fl_Pixmap *B) {b = B;}
+    Fl_Pixmap *Pixmap() const {return b;}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_FormsPixmap.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Free.H b/Utilities/FLTK/FL/Fl_Free.H
new file mode 100644
index 0000000000000000000000000000000000000000..7895dfe17b91b7c6d7b39c890ca934d72a109741
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Free.H
@@ -0,0 +1,66 @@
+//
+// "$Id: Fl_Free.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Forms free header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Free_H
+#define Fl_Free_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+#define FL_NORMAL_FREE		1
+#define FL_SLEEPING_FREE	2
+#define FL_INPUT_FREE		3
+#define FL_CONTINUOUS_FREE	4
+#define FL_ALL_FREE		5
+
+typedef int (*FL_HANDLEPTR)(Fl_Widget *, int , float, float, char);
+
+class FL_EXPORT Fl_Free : public Fl_Widget {
+    FL_HANDLEPTR hfunc;
+    static void step(void *);
+protected:
+    void draw();
+public:
+    int handle(int);
+    Fl_Free(uchar t,int x,int y,int w,int h,const char *l,FL_HANDLEPTR hdl);
+    ~Fl_Free();
+};
+
+// old event names for compatability:
+#define FL_MOUSE		FL_DRAG
+#define FL_DRAW			100		// NOT USED
+#define FL_STEP			101
+#define FL_FREEMEM		102		// NOT USED
+#define FL_FREEZE		103		// NOT USED
+#define FL_THAW			104		// NOT USED
+
+#endif
+
+//
+// End of "$Id: Fl_Free.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_GIF_Image.H b/Utilities/FLTK/FL/Fl_GIF_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..40a3e692bad5aa489d08f7bafc7962724360d9a5
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_GIF_Image.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_GIF_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// GIF image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_GIF_Image_H
+#define Fl_GIF_Image_H
+#  include "Fl_Pixmap.H"
+
+class FL_EXPORT Fl_GIF_Image : public Fl_Pixmap {
+
+  public:
+
+  Fl_GIF_Image(const char* filename);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_GIF_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Gl_Window.H b/Utilities/FLTK/FL/Fl_Gl_Window.H
new file mode 100644
index 0000000000000000000000000000000000000000..d19e33db44448050dded5732d891bdb3fa654444
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Gl_Window.H
@@ -0,0 +1,96 @@
+//
+// "$Id: Fl_Gl_Window.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// OpenGL header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+#ifndef Fl_Gl_Window_H
+#define Fl_Gl_Window_H
+
+#include "Fl_Window.H"
+
+#ifndef GLContext
+typedef void* GLContext; // actually a GLXContext or HGLDC
+#endif
+
+class Fl_Gl_Choice; // structure to hold result of glXChooseVisual
+
+class FL_EXPORT Fl_Gl_Window : public Fl_Window {
+
+  int mode_;
+  const int *alist;
+  Fl_Gl_Choice *g;
+  GLContext context_;
+  char valid_;
+  char damage1_; // damage() of back buffer
+  virtual void draw_overlay();
+  void init();
+
+  void *overlay;
+  void make_overlay();
+  friend class _Fl_Gl_Overlay;
+
+  static int can_do(int, const int *);
+  int mode(int, const int *);
+
+public:
+
+  void show();
+  void show(int a, char **b) {Fl_Window::show(a,b);}
+  void flush();
+  void hide();
+  void resize(int,int,int,int);
+
+  char valid() const {return valid_;}
+  void valid(char v) {valid_ = v;}
+  void invalidate();
+
+  static int can_do(int m) {return can_do(m,0);}
+  static int can_do(const int *m) {return can_do(0, m);}
+  int can_do() {return can_do(mode_,alist);}
+  Fl_Mode mode() const {return (Fl_Mode)mode_;}
+  int mode(int a) {return mode(a,0);}
+  int mode(const int *a) {return mode(0, a);}
+
+  void* context() const {return context_;}
+  void context(void*, int destroy_flag = 0);
+  void make_current();
+  void swap_buffers();
+  void ortho();
+
+  int can_do_overlay();
+  void redraw_overlay();
+  void hide_overlay();
+  void make_overlay_current();
+
+  ~Fl_Gl_Window();
+  Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();}
+  Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0)
+    : Fl_Window(X,Y,W,H,l) {init();}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Gl_Window.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Group.H b/Utilities/FLTK/FL/Fl_Group.H
new file mode 100644
index 0000000000000000000000000000000000000000..1da36cfe8cc56753bc5b40c0da6039ab9021e9b0
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Group.H
@@ -0,0 +1,107 @@
+//
+// "$Id: Fl_Group.H 4421 2005-07-15 09:34:53Z matt $"
+//
+// Group header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Group_H
+#define Fl_Group_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+class FL_EXPORT Fl_Group : public Fl_Widget {
+
+  Fl_Widget** array_;
+  Fl_Widget* savedfocus_;
+  Fl_Widget* resizable_;
+  int children_;
+  short *sizes_; // remembered initial sizes of children
+
+  int navigation(int);
+  static Fl_Group *current_;
+ 
+  // unimplemented copy ctor and assignment operator
+  Fl_Group(const Fl_Group&);
+  Fl_Group& operator=(const Fl_Group&);
+
+protected:
+
+  void draw();
+  void draw_child(Fl_Widget&) const;
+  void draw_children();
+  void draw_outside_label(const Fl_Widget&) const ;
+  void update_child(Fl_Widget&) const;
+  short* sizes();
+
+public:
+
+  int handle(int);
+  void begin();
+  void end();
+  static Fl_Group *current();
+  static void current(Fl_Group *g);
+
+  int children() const {return children_;}
+  Fl_Widget* child(int n) const {return array()[n];}
+  int find(const Fl_Widget*) const;
+  int find(const Fl_Widget& o) const {return find(&o);}
+  Fl_Widget* const* array() const;
+
+  void resize(int,int,int,int);
+  Fl_Group(int,int,int,int, const char * = 0);
+  virtual ~Fl_Group();
+  void add(Fl_Widget&);
+  void add(Fl_Widget* o) {add(*o);}
+  void insert(Fl_Widget&, int i);
+  void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));}
+  void remove(Fl_Widget&);
+  void remove(Fl_Widget* o) {remove(*o);}
+  void clear();
+
+  void resizable(Fl_Widget& o) {resizable_ = &o;}
+  void resizable(Fl_Widget* o) {resizable_ = o;}
+  Fl_Widget* resizable() const {return resizable_;}
+  void add_resizable(Fl_Widget& o) {resizable_ = &o; add(o);}
+  void init_sizes();
+
+  // back compatability function:
+  void focus(Fl_Widget* o) {o->take_focus();}
+  Fl_Widget* & _ddfdesign_kludge() {return resizable_;}
+  void forms_end();
+};
+
+// dummy class used to end child groups in constructors for complex
+// subclasses of Fl_Group:
+class FL_EXPORT Fl_End {
+public:
+  Fl_End() {Fl_Group::current()->end();}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Group.H 4421 2005-07-15 09:34:53Z matt $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Help_Dialog.H b/Utilities/FLTK/FL/Fl_Help_Dialog.H
new file mode 100644
index 0000000000000000000000000000000000000000..198e2507afcff27c47311594609aee3183cacaf8
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Help_Dialog.H
@@ -0,0 +1,93 @@
+//
+// "$Id: Fl_Help_Dialog.H 4582 2005-09-25 16:54:40Z matt $"
+//
+// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef Fl_Help_Dialog_H
+#define Fl_Help_Dialog_H
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Help_View.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
+
+class FL_EXPORT Fl_Help_Dialog {
+  int index_;
+  int max_;
+  int line_[100];
+  char file_[100][256];
+  int find_pos_;
+public:
+  Fl_Help_Dialog();
+private:
+  Fl_Double_Window *window_;
+  Fl_Help_View *view_;
+  void cb_view__i(Fl_Help_View*, void*);
+  static void cb_view_(Fl_Help_View*, void*);
+  void cb_Close_i(Fl_Button*, void*);
+  static void cb_Close(Fl_Button*, void*);
+  Fl_Button *back_;
+  void cb_back__i(Fl_Button*, void*);
+  static void cb_back_(Fl_Button*, void*);
+  Fl_Button *forward_;
+  void cb_forward__i(Fl_Button*, void*);
+  static void cb_forward_(Fl_Button*, void*);
+  Fl_Button *smaller_;
+  void cb_smaller__i(Fl_Button*, void*);
+  static void cb_smaller_(Fl_Button*, void*);
+  Fl_Button *larger_;
+  void cb_larger__i(Fl_Button*, void*);
+  static void cb_larger_(Fl_Button*, void*);
+  Fl_Input *find_;
+  void cb_find__i(Fl_Input*, void*);
+  static void cb_find_(Fl_Input*, void*);
+public:
+  ~Fl_Help_Dialog();
+  int h();
+  void hide();
+  void load(const char *f);
+  void position(int xx, int yy);
+  void resize(int xx, int yy, int ww, int hh);
+  void show();
+  void show(int argc, char **argv);
+  void textsize(uchar s);
+  uchar textsize();
+  void topline(const char *n);
+  void topline(int n);
+  void value(const char *f);
+  const char * value() const;
+  int visible();
+  int w();
+  int x();
+  int y();
+};
+#endif
+
+//
+// End of "$Id: Fl_Help_Dialog.H 4582 2005-09-25 16:54:40Z matt $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Help_View.H b/Utilities/FLTK/FL/Fl_Help_View.H
new file mode 100644
index 0000000000000000000000000000000000000000..a0f4fd6d2fb55bbda51c0ea3bc861acdcbae7f41
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Help_View.H
@@ -0,0 +1,195 @@
+//
+// "$Id: Fl_Help_View.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Help Viewer widget definitions.
+//
+// Copyright 1997-2005 by Easy Software Products.
+// Image support donated by Matthias Melcher, Copyright 2000.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Help_View_H
+#  define Fl_Help_View_H
+
+//
+// Include necessary header files...
+//
+
+#  include <stdio.h>
+#  include "Fl.H"
+#  include "Fl_Group.H"
+#  include "Fl_Scrollbar.H"
+#  include "fl_draw.H"
+#  include "Fl_Shared_Image.H"
+
+
+//
+// Fl_Help_Func type - link callback function for files...
+//
+
+
+typedef const char *(Fl_Help_Func)(Fl_Widget *, const char *);
+
+
+//
+// Fl_Help_Block structure...
+//
+
+struct Fl_Help_Block
+{
+  const char	*start,		// Start of text
+		*end;		// End of text
+  uchar		border;		// Draw border?
+  Fl_Color	bgcolor;	// Background color
+  int		x,		// Indentation/starting X coordinate
+		y,		// Starting Y coordinate
+		w,		// Width
+		h;		// Height
+  int		line[32];	// Left starting position for each line
+};
+
+//
+// Fl_Help_Link structure...
+//
+
+struct Fl_Help_Link
+{
+  char		filename[192],	// Reference filename
+		name[32];	// Link target (blank if none)
+  int		x,		// X offset of link text
+		y,		// Y offset of link text
+		w,		// Width of link text
+		h;		// Height of link text
+};
+
+//
+// Fl_Help_Target structure...
+//
+
+struct Fl_Help_Target
+{
+  char		name[32];	// Target name
+  int		y;		// Y offset of target
+};
+
+//
+// Fl_Help_View class...
+//
+
+class FL_EXPORT Fl_Help_View : public Fl_Group	//// Help viewer widget
+{
+  enum { RIGHT = -1, CENTER, LEFT };	// Alignments
+
+  char		title_[1024];		// Title string
+  Fl_Color	defcolor_,		// Default text color
+		bgcolor_,		// Background color
+		textcolor_,		// Text color
+		linkcolor_;		// Link color
+  uchar		textfont_,		// Default font for text
+		textsize_;		// Default font size
+  const char	*value_;		// HTML text value
+
+  int		nblocks_,		// Number of blocks/paragraphs
+		ablocks_;		// Allocated blocks
+  Fl_Help_Block	*blocks_;		// Blocks
+
+  int		nfonts_;		// Number of fonts in stack
+  uchar		fonts_[100][2];		// Font stack
+
+  Fl_Help_Func	*link_;			// Link transform function
+
+  int		nlinks_,		// Number of links
+		alinks_;		// Allocated links
+  Fl_Help_Link	*links_;		// Links
+
+  int		ntargets_,		// Number of targets
+		atargets_;		// Allocated targets
+  Fl_Help_Target *targets_;		// Targets
+
+  char		directory_[1024];	// Directory for current file
+  char		filename_[1024];	// Current filename
+  int		topline_,		// Top line in document
+		leftline_,		// Lefthand position
+		size_,			// Total document length
+		hsize_;			// Maximum document width
+  Fl_Scrollbar	scrollbar_,		// Vertical scrollbar for document
+		hscrollbar_;		// Horizontal scrollbar
+
+  Fl_Help_Block	*add_block(const char *s, int xx, int yy, int ww, int hh, uchar border = 0);
+  void		add_link(const char *n, int xx, int yy, int ww, int hh);
+  void		add_target(const char *n, int yy);
+  static int	compare_targets(const Fl_Help_Target *t0, const Fl_Help_Target *t1);
+  int		do_align(Fl_Help_Block *block, int line, int xx, int a, int &l);
+  void		draw();
+  void		format();
+  void		format_table(int *table_width, int *columns, const char *table);
+  int		get_align(const char *p, int a);
+  const char	*get_attr(const char *p, const char *n, char *buf, int bufsize);
+  Fl_Color	get_color(const char *n, Fl_Color c);
+  Fl_Shared_Image *get_image(const char *name, int W, int H);
+  int		get_length(const char *l);
+  int		handle(int);
+
+  void		initfont(uchar &f, uchar &s) { nfonts_ = 0;
+			fl_font(f = fonts_[0][0] = textfont_,
+			        s = fonts_[0][1] = textsize_); }
+  void		pushfont(uchar f, uchar s) { if (nfonts_ < 99) nfonts_ ++;
+			fl_font(fonts_[nfonts_][0] = f,
+			        fonts_[nfonts_][1] = s); }
+  void		popfont(uchar &f, uchar &s) { if (nfonts_ > 0) nfonts_ --;
+			fl_font(f = fonts_[nfonts_][0],
+			        s = fonts_[nfonts_][1]); }
+
+  public:
+
+  Fl_Help_View(int xx, int yy, int ww, int hh, const char *l = 0);
+  ~Fl_Help_View();
+  const char	*directory() const { if (directory_[0]) return (directory_);
+  					else return ((const char *)0); }
+  const char	*filename() const { if (filename_[0]) return (filename_);
+  					else return ((const char *)0); }
+  int		find(const char *s, int p = 0);
+  void		link(Fl_Help_Func *fn) { link_ = fn; }
+  int		load(const char *f);
+  void		resize(int,int,int,int);
+  int		size() const { return (size_); }
+  void		size(int W, int H) { Fl_Widget::size(W, H); }
+  void		textcolor(Fl_Color c) { if (textcolor_ == defcolor_) textcolor_ = c; defcolor_ = c; }
+  Fl_Color	textcolor() const { return (defcolor_); }
+  void		textfont(uchar f) { textfont_ = f; format(); }
+  uchar		textfont() const { return (textfont_); }
+  void		textsize(uchar s) { textsize_ = s; format(); }
+  uchar		textsize() const { return (textsize_); }
+  const char	*title() { return (title_); }
+  void		topline(const char *n);
+  void		topline(int);
+  int		topline() const { return (topline_); }
+  void		leftline(int);
+  int		leftline() const { return (leftline_); }
+  void		value(const char *v);
+  const char	*value() const { return (value_); }
+};
+
+#endif // !Fl_Help_View_H
+
+//
+// End of "$Id: Fl_Help_View.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Hold_Browser.H b/Utilities/FLTK/FL/Fl_Hold_Browser.H
new file mode 100644
index 0000000000000000000000000000000000000000..6286a60bf21c29a63953ef6bbb292ad6997296bc
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Hold_Browser.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Hold_Browser.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Hold browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Hold_Browser_H
+#define Fl_Hold_Browser_H
+
+#include "Fl_Browser.H"
+
+class Fl_Hold_Browser : public Fl_Browser {
+public:
+    Fl_Hold_Browser(int X,int Y,int W,int H,const char *l=0)
+	: Fl_Browser(X,Y,W,H,l) {type(FL_HOLD_BROWSER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Hold_Browser.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Hor_Fill_Slider.H b/Utilities/FLTK/FL/Fl_Hor_Fill_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..a7a87f5ea5f8830550de22dc388970051e950e8a
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Hor_Fill_Slider.H
@@ -0,0 +1,42 @@
+//
+// "$Id: Fl_Hor_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Horizontal fill slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+#ifndef Fl_Hor_Fill_Slider_H
+#define Fl_Hor_Fill_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Hor_Fill_Slider : public Fl_Slider {
+public:
+    Fl_Hor_Fill_Slider(int x,int y,int w,int h,const char *l=0)
+	: Fl_Slider(x,y,w,h,l) {type(FL_HOR_FILL_SLIDER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Hor_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Hor_Nice_Slider.H b/Utilities/FLTK/FL/Fl_Hor_Nice_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..bed75a51c08ccd68c1039447beb1fa721a5dde06
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Hor_Nice_Slider.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Hor_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Horizontal "nice" slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Hor_Nice_Slider_H
+#define Fl_Hor_Nice_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Hor_Nice_Slider : public Fl_Slider {
+public:
+    Fl_Hor_Nice_Slider(int x,int y,int w,int h,const char *l=0)
+	: Fl_Slider(x,y,w,h,l) {type(FL_HOR_NICE_SLIDER); box(FL_FLAT_BOX);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Hor_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Hor_Slider.H b/Utilities/FLTK/FL/Fl_Hor_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..34be6961eb9d0f0d67984e565af95e1d88f527e7
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Hor_Slider.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Hor_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Horizontal slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Hor_Slider_H
+#define Fl_Hor_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Hor_Slider : public Fl_Slider {
+public:
+    Fl_Hor_Slider(int X,int Y,int W,int H,const char *l=0)
+	: Fl_Slider(X,Y,W,H,l) {type(FL_HOR_SLIDER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Hor_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Hor_Value_Slider.H b/Utilities/FLTK/FL/Fl_Hor_Value_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..d499feadfa725ae7dddfd1e932ed7114dbe5474c
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Hor_Value_Slider.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Hor_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Horizontal value slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Hor_Value_Slider_H
+#define Fl_Hor_Value_Slider_H
+
+#include "Fl_Value_Slider.H"
+
+class Fl_Hor_Value_Slider : public Fl_Value_Slider {
+public:
+    Fl_Hor_Value_Slider(int X,int Y,int W,int H,const char *l=0)
+	: Fl_Value_Slider(X,Y,W,H,l) {type(FL_HOR_SLIDER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Hor_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Image.H b/Utilities/FLTK/FL/Fl_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..4d6f052d502cf60fcbd66f7f3ed8fce2cc64dc4e
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Image.H
@@ -0,0 +1,112 @@
+//
+// "$Id: Fl_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Image_H
+#  define Fl_Image_H
+
+#  include "Enumerations.H"
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+struct Fl_Label;
+
+class FL_EXPORT Fl_Image {
+  int w_, h_, d_, ld_, count_;
+  const char * const *data_;
+
+  // Forbid use of copy contructor and assign operator
+  Fl_Image & operator=(const Fl_Image &);
+  Fl_Image(const Fl_Image &);
+
+  protected:
+
+  void w(int W) {w_ = W;}
+  void h(int H) {h_ = H;}
+  void d(int D) {d_ = D;}
+  void ld(int LD) {ld_ = LD;}
+  void data(const char * const *p, int c) {data_ = p; count_ = c;}
+  void draw_empty(int X, int Y);
+
+  static void labeltype(const Fl_Label *lo, int lx, int ly, int lw, int lh, Fl_Align la);
+  static void measure(const Fl_Label *lo, int &lw, int &lh);
+
+  public:
+
+  int w() const {return w_;}
+  int h() const {return h_;}
+  int d() const {return d_;}
+  int ld() const {return ld_;}
+  int count() const {return count_;}
+  const char * const *data() const {return data_;}
+  
+  Fl_Image(int W, int H, int D) {w_ = W; h_ = H; d_ = D; ld_ = 0; count_ = 0; data_ = 0;}
+  virtual ~Fl_Image();
+  virtual Fl_Image *copy(int W, int H);
+  Fl_Image *copy() { return copy(w(), h()); }
+  virtual void color_average(Fl_Color c, float i);
+  void inactive() { color_average(FL_GRAY, .33f); }
+  virtual void desaturate();
+  virtual void label(Fl_Widget*w);
+  virtual void label(Fl_Menu_Item*m);
+  virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0);
+  void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);}
+  virtual void uncache();
+};
+
+class FL_EXPORT Fl_RGB_Image : public Fl_Image {
+  public:
+
+  const uchar *array;
+  int alloc_array; // Non-zero if array was allocated
+
+#if defined(__APPLE__) || defined(WIN32)
+  void *id; // for internal use
+  void *mask; // for internal use (mask bitmap)
+#else
+  unsigned id; // for internal use
+  unsigned mask; // for internal use (mask bitmap)
+#endif // __APPLE__ || WIN32
+
+  Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) :
+    Fl_Image(W,H,D), array(bits), alloc_array(0), id(0), mask(0) {data((const char **)&array, 1); ld(LD);}
+  virtual ~Fl_RGB_Image();
+  virtual Fl_Image *copy(int W, int H);
+  Fl_Image *copy() { return copy(w(), h()); }
+  virtual void color_average(Fl_Color c, float i);
+  virtual void desaturate();
+  virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0);
+  void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);}
+  virtual void label(Fl_Widget*w);
+  virtual void label(Fl_Menu_Item*m);
+  virtual void uncache();
+};
+
+#endif // !Fl_Image_H
+
+//
+// End of "$Id: Fl_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Input.H b/Utilities/FLTK/FL/Fl_Input.H
new file mode 100644
index 0000000000000000000000000000000000000000..7debfddfefe77ec22ab8d5cd37878efd0d6b9a50
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Input.H
@@ -0,0 +1,48 @@
+//
+// "$Id: Fl_Input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Input_H
+#define Fl_Input_H
+
+#include "Fl_Input_.H"
+
+class FL_EXPORT Fl_Input : public Fl_Input_ {
+  int handle_key();
+  int shift_position(int p);
+  int shift_up_down_position(int p);
+  void handle_mouse(int keepmark=0);
+public:
+  void draw();
+  int handle(int);
+  Fl_Input(int,int,int,int,const char * = 0);
+};
+
+#endif 
+
+//
+// End of "$Id: Fl_Input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Input_.H b/Utilities/FLTK/FL/Fl_Input_.H
new file mode 100644
index 0000000000000000000000000000000000000000..0c52ce613b31cb91dc2009d9e3847e294b6b1c6b
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Input_.H
@@ -0,0 +1,145 @@
+//
+// "$Id: Fl_Input_.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Input base class header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Input__H
+#define Fl_Input__H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+#define FL_NORMAL_INPUT		0
+#define FL_FLOAT_INPUT		1
+#define FL_INT_INPUT		2
+#define FL_HIDDEN_INPUT		3
+#define FL_MULTILINE_INPUT	4
+#define FL_SECRET_INPUT		5
+#define FL_INPUT_TYPE		7
+#define FL_INPUT_READONLY	8
+#define FL_NORMAL_OUTPUT	(FL_NORMAL_INPUT | FL_INPUT_READONLY)
+#define FL_MULTILINE_OUTPUT	(FL_MULTILINE_INPUT | FL_INPUT_READONLY)
+#define FL_INPUT_WRAP		16
+#define FL_MULTILINE_INPUT_WRAP	(FL_MULTILINE_INPUT | FL_INPUT_WRAP)
+#define FL_MULTILINE_OUTPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_READONLY | FL_INPUT_WRAP)
+
+class FL_EXPORT Fl_Input_ : public Fl_Widget {
+
+  const char* value_;
+  char* buffer;
+
+  int size_;
+  int bufsize;
+  int position_;
+  int mark_;
+  int xscroll_, yscroll_;
+  int mu_p;
+  int maximum_size_;
+
+  uchar erase_cursor_only;
+  uchar textfont_;
+  uchar textsize_;
+  unsigned textcolor_;
+  unsigned cursor_color_;
+
+  const char* expand(const char*, char*) const;
+  double expandpos(const char*, const char*, const char*, int*) const;
+  void minimal_update(int, int);
+  void minimal_update(int p);
+  void put_in_buffer(int newsize);
+
+  void setfont() const;
+
+protected:
+
+  int word_start(int i) const;
+  int word_end(int i) const;
+  int line_start(int i) const;
+  int line_end(int i) const;
+  void drawtext(int, int, int, int);
+  int up_down_position(int, int keepmark=0);
+  void handle_mouse(int, int, int, int, int keepmark=0);
+  int handletext(int e, int, int, int, int);
+  void maybe_do_callback();
+  int xscroll() const {return xscroll_;}
+  int yscroll() const {return yscroll_;}
+
+public:
+
+  void resize(int, int, int, int);
+
+  Fl_Input_(int, int, int, int, const char* = 0);
+  ~Fl_Input_();
+
+  int value(const char*);
+  int value(const char*, int);
+  int static_value(const char*);
+  int static_value(const char*, int);
+  const char* value() const {return value_;}
+  char index(int i) const {return value_[i];}
+  int size() const {return size_;}
+  void size(int W, int H) { Fl_Widget::size(W, H); }
+  int maximum_size() const {return maximum_size_;}
+  void maximum_size(int m) {maximum_size_ = m;}
+
+  int position() const {return position_;}
+  int mark() const {return mark_;}
+  int position(int p, int m);
+  int position(int p) {return position(p, p);}
+  int mark(int m) {return position(position(), m);}
+  int replace(int, int, const char*, int=0);
+  int cut() {return replace(position(), mark(), 0);}
+  int cut(int n) {return replace(position(), position()+n, 0);}
+  int cut(int a, int b) {return replace(a, b, 0);}
+  int insert(const char* t, int l=0){return replace(position_, mark_, t, l);}
+  int copy(int clipboard);
+  int undo();
+  int copy_cuts();
+
+  Fl_Font textfont() const {return (Fl_Font)textfont_;}
+  void textfont(uchar s) {textfont_ = s;}
+  uchar textsize() const {return textsize_;}
+  void textsize(uchar s) {textsize_ = s;}
+  Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+  void textcolor(unsigned n) {textcolor_ = n;}
+  Fl_Color cursor_color() const {return (Fl_Color)cursor_color_;}
+  void cursor_color(unsigned n) {cursor_color_ = n;}
+
+  int input_type() const {return type() & FL_INPUT_TYPE; }
+  void input_type(int t) { type((uchar)(t | readonly())); }
+  int readonly() const { return type() & FL_INPUT_READONLY; }
+  void readonly(int b) { if (b) type((uchar)(type() | FL_INPUT_READONLY));
+                         else type((uchar)(type() & ~FL_INPUT_READONLY)); }
+  int wrap() const { return type() & FL_INPUT_WRAP; }
+  void wrap(int b) { if (b) type((uchar)(type() | FL_INPUT_WRAP));
+                         else type((uchar)(type() & ~FL_INPUT_WRAP)); }
+};
+
+#endif 
+
+//
+// End of "$Id: Fl_Input_.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Input_Choice.H b/Utilities/FLTK/FL/Fl_Input_Choice.H
new file mode 100644
index 0000000000000000000000000000000000000000..d4acb4462b91c593684090761c038ce189842abf
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Input_Choice.H
@@ -0,0 +1,154 @@
+//
+// "$Id$"
+//
+// An input/chooser widget.
+//            ______________  ____
+//           |              || __ |
+//           | input area   || \/ |
+//           |______________||____|
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+// Copyright 2004 by Greg Ercolano.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Input_Choice_H
+#define Fl_Input_Choice_H
+
+#include <FL/Fl.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/fl_draw.H>
+
+class Fl_Input_Choice : public Fl_Group {
+  // Private class to handle slightly 'special' behavior of menu button
+  class InputMenuButton : public Fl_Menu_Button {
+    void draw() {
+      draw_box(FL_UP_BOX, color());
+      fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor()));
+      int xc = x()+w()/2, yc=y()+h()/2;
+      fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3);
+      if (Fl::focus() == this) draw_focus();
+    }
+  public:
+    InputMenuButton(int x,int y,int w,int h,const char*l=0) : 
+	Fl_Menu_Button(x,y,w,h,l) { box(FL_UP_BOX); }
+  };
+
+  Fl_Input *inp_;
+  InputMenuButton *menu_;
+
+  static void menu_cb(Fl_Widget*, void *data) { 
+    Fl_Input_Choice *o=(Fl_Input_Choice *)data;
+    o->inp_->value(o->menu_->text());
+    o->do_callback();
+  }
+
+  static void inp_cb(Fl_Widget*, void *data) { 
+    Fl_Input_Choice *o=(Fl_Input_Choice *)data;
+    o->do_callback();
+  }
+
+  // Custom resize behavior -- input stretches, menu button doesn't
+  inline int inp_x() { return(x() + Fl::box_dx(box())); }
+  inline int inp_y() { return(y() + Fl::box_dy(box())); }
+  inline int inp_w() { return(w() - Fl::box_dw(box()) - 20); }
+  inline int inp_h() { return(h() - Fl::box_dh(box())); }
+
+  inline int menu_x() { return(x() + w() - 20 - Fl::box_dx(box())); }
+  inline int menu_y() { return(y() + Fl::box_dy(box())); }
+  inline int menu_w() { return(20); }
+  inline int menu_h() { return(h() - Fl::box_dh(box())); }
+
+public:
+  Fl_Input_Choice (int x,int y,int w,int h,const char*l=0) : Fl_Group(x,y,w,h,l) {
+    Fl_Group::box(FL_DOWN_BOX);
+    align(FL_ALIGN_LEFT);				// default like Fl_Input
+    inp_ = new Fl_Input(inp_x(), inp_y(),
+			inp_w(), inp_h());
+    inp_->callback(inp_cb, (void*)this);
+    inp_->box(FL_FLAT_BOX);		// cosmetic
+    menu_ = new InputMenuButton(menu_x(), menu_y(),
+				menu_w(), menu_h());
+    menu_->callback(menu_cb, (void*)this);
+    menu_->box(FL_FLAT_BOX);				// cosmetic
+    end();
+  }
+  void add(const char *s) {
+    menu_->add(s);
+  }
+  void clear() {
+    menu_->clear();
+  }
+  Fl_Boxtype down_box() const {
+    return (menu_->down_box());
+  }
+  void down_box(Fl_Boxtype b) {
+    menu_->down_box(b);
+  }
+  const Fl_Menu_Item *menu() {
+    return (menu_->menu());
+  }
+  void menu(const Fl_Menu_Item *m) {
+    menu_->menu(m);
+  }
+  void resize(int X, int Y, int W, int H) {
+    Fl_Group::resize(X,Y,W,H);
+    inp_->resize(inp_x(), inp_y(), inp_w(), inp_h());
+    menu_->resize(menu_x(), menu_y(), menu_w(), menu_h());
+  }
+  Fl_Color textcolor() const {
+    return (inp_->textcolor());
+  }
+  void textcolor(Fl_Color c) {
+    inp_->textcolor(c);
+  }
+  uchar textfont() const {
+    return (inp_->textfont());
+  }
+  void textfont(uchar f) {
+    inp_->textfont(f);
+  }
+  uchar textsize() const {
+    return (inp_->textsize());
+  }
+  void textsize(uchar s) {
+    inp_->textsize(s);
+  }
+  const char* value() const {
+    return (inp_->value());
+  }
+  void value(const char *val) {
+    inp_->value(val);
+  }
+  void value(int val) {
+    menu_->value(val);
+    inp_->value(menu_->text(val));
+  }
+  Fl_Menu_Button *menubutton() { return menu_; }
+  Fl_Input *input() { return inp_; }
+};
+
+#endif // !Fl_Input_Choice_H
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/FL/Fl_Int_Input.H b/Utilities/FLTK/FL/Fl_Int_Input.H
new file mode 100644
index 0000000000000000000000000000000000000000..641ad1639a6ea6e14bbc1c68bd3440fc2448f7ba
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Int_Input.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Int_Input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Integer input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Int_Input_H
+#define Fl_Int_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Int_Input : public Fl_Input {
+public:
+    Fl_Int_Input(int X,int Y,int W,int H,const char *l = 0)
+	: Fl_Input(X,Y,W,H,l) {type(FL_INT_INPUT);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Int_Input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_JPEG_Image.H b/Utilities/FLTK/FL/Fl_JPEG_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..234c8bbebf1506d239e8b7446603930e72d646de
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_JPEG_Image.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_JPEG_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// JPEG image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_JPEG_Image_H
+#define Fl_JPEG_Image_H
+#  include "Fl_Image.H"
+
+class FL_EXPORT Fl_JPEG_Image : public Fl_RGB_Image {
+
+  public:
+
+  Fl_JPEG_Image(const char* filename);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_JPEG_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Light_Button.H b/Utilities/FLTK/FL/Fl_Light_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..f056a3001d60c81c4dabf16b906a6dfea83a235f
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Light_Button.H
@@ -0,0 +1,45 @@
+//
+// "$Id: Fl_Light_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Lighted button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Light_Button_H
+#define Fl_Light_Button_H
+
+#include "Fl_Button.H"
+
+class FL_EXPORT Fl_Light_Button : public Fl_Button {
+protected:
+    virtual void draw();
+public:
+    virtual int handle(int);
+    Fl_Light_Button(int x,int y,int w,int h,const char *l = 0);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Light_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Line_Dial.H b/Utilities/FLTK/FL/Fl_Line_Dial.H
new file mode 100644
index 0000000000000000000000000000000000000000..301bff9defd42a297268ccb788eef353b2399fc6
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Line_Dial.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Line_Dial.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Line dial header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Line_Dial_H
+#define Fl_Line_Dial_H
+
+#include "Fl_Dial.H"
+
+class Fl_Line_Dial : public Fl_Dial {
+public:
+    Fl_Line_Dial(int x,int y,int w,int h, const char *l = 0)
+	: Fl_Dial(x,y,w,h,l) {type(FL_LINE_DIAL);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Line_Dial.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Menu.H b/Utilities/FLTK/FL/Fl_Menu.H
new file mode 100644
index 0000000000000000000000000000000000000000..9d77980173be6793a93ec5275d5dd8adc93fd065
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Menu.H
@@ -0,0 +1,33 @@
+//
+// "$Id: Fl_Menu.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Old menu header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// this include file is for back compatability only
+#include "Fl_Menu_Item.H"
+
+//
+// End of "$Id: Fl_Menu.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Menu_.H b/Utilities/FLTK/FL/Fl_Menu_.H
new file mode 100644
index 0000000000000000000000000000000000000000..b04e4e93d9f1335cfd07e504fa6b360139bacbfc
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Menu_.H
@@ -0,0 +1,102 @@
+//
+// "$Id: Fl_Menu_.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Menu base class header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Menu__H
+#define Fl_Menu__H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+#include "Fl_Menu_Item.H"
+
+class FL_EXPORT Fl_Menu_ : public Fl_Widget {
+
+  Fl_Menu_Item *menu_;
+  const Fl_Menu_Item *value_;
+
+protected:
+
+  uchar alloc;
+  uchar down_box_;
+  uchar textfont_;
+  uchar textsize_;
+  unsigned textcolor_;
+
+public:
+  Fl_Menu_(int,int,int,int,const char * =0);
+  ~Fl_Menu_();
+
+  int item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem=0) const;
+  const Fl_Menu_Item* picked(const Fl_Menu_Item*);
+  const Fl_Menu_Item* find_item(const char *name);
+
+  const Fl_Menu_Item* test_shortcut() {return picked(menu()->test_shortcut());}
+  void global();
+
+  const Fl_Menu_Item *menu() const {return menu_;}
+  void menu(const Fl_Menu_Item *m);
+  void copy(const Fl_Menu_Item *m, void* user_data = 0);
+  int  add(const char*, int shortcut, Fl_Callback*, void* = 0, int = 0);
+  int  add(const char* a, const char* b, Fl_Callback* c,
+	  void* d = 0, int e = 0) {return add(a,fl_old_shortcut(b),c,d,e);}
+  int  size() const ;
+  void size(int W, int H) { Fl_Widget::size(W, H); }
+  void clear();
+  int  add(const char *);
+  void replace(int,const char *);
+  void remove(int);
+  void shortcut(int i, int s) {menu_[i].shortcut(s);}
+  void mode(int i,int fl) {menu_[i].flags = fl;}
+  int  mode(int i) const {return menu_[i].flags;}
+
+  const Fl_Menu_Item *mvalue() const {return value_;}
+  int value() const {return value_ ? (int)(value_-menu_) : -1;}
+  int value(const Fl_Menu_Item*);
+  int value(int i) {return value(menu_+i);}
+  const char *text() const {return value_ ? value_->text : 0;}
+  const char *text(int i) const {return menu_[i].text;}
+
+  Fl_Font textfont() const {return (Fl_Font)textfont_;}
+  void textfont(uchar c) {textfont_=c;}
+  uchar textsize() const {return textsize_;}
+  void textsize(uchar c) {textsize_=c;}
+  Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+  void textcolor(unsigned c) {textcolor_=c;}
+
+  Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;}
+  void down_box(Fl_Boxtype b) {down_box_ = b;}
+
+  // back compatability:
+  Fl_Color down_color() const {return selection_color();}
+  void down_color(unsigned c) {selection_color(c);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Menu_.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Menu_Bar.H b/Utilities/FLTK/FL/Fl_Menu_Bar.H
new file mode 100644
index 0000000000000000000000000000000000000000..ab240da7a7aae1f0db8acaa9a77c960c0e9aff24
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Menu_Bar.H
@@ -0,0 +1,46 @@
+//
+// "$Id: Fl_Menu_Bar.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Menu bar header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Menu_Bar_H
+#define Fl_Menu_Bar_H
+
+#include "Fl_Menu_.H"
+
+class FL_EXPORT Fl_Menu_Bar : public Fl_Menu_ {
+protected:
+    void draw();
+public:
+    int handle(int);
+    Fl_Menu_Bar(int X, int Y, int W, int H,const char *l=0)
+      : Fl_Menu_(X,Y,W,H,l) {}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Menu_Bar.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Menu_Button.H b/Utilities/FLTK/FL/Fl_Menu_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..39a2665a091207d69d46a0ae34cedaa8dc7191f2
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Menu_Button.H
@@ -0,0 +1,48 @@
+//
+// "$Id: Fl_Menu_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Menu button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Menu_Button_H
+#define Fl_Menu_Button_H
+
+#include "Fl_Menu_.H"
+
+class FL_EXPORT Fl_Menu_Button : public Fl_Menu_ {
+protected:
+  void draw();
+public:
+  // values for type:
+  enum {POPUP1 = 1, POPUP2, POPUP12, POPUP3, POPUP13, POPUP23, POPUP123};
+  int handle(int);
+  const Fl_Menu_Item* popup();
+  Fl_Menu_Button(int,int,int,int,const char * =0);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Menu_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Menu_Item.H b/Utilities/FLTK/FL/Fl_Menu_Item.H
new file mode 100644
index 0000000000000000000000000000000000000000..33e520a6702d774c747c839051652a999ad0e36c
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Menu_Item.H
@@ -0,0 +1,167 @@
+//
+// "$Id: Fl_Menu_Item.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Menu item header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Menu_Item_H
+#define Fl_Menu_Item_H
+
+#  include "Fl_Widget.H"
+#  include "Fl_Image.H"
+
+#  if defined(__APPLE__) && defined(check)
+#    undef check
+#  endif
+
+enum { // values for flags:
+  FL_MENU_INACTIVE = 1,
+  FL_MENU_TOGGLE= 2,
+  FL_MENU_VALUE = 4,
+  FL_MENU_RADIO = 8,
+  FL_MENU_INVISIBLE = 0x10,
+  FL_SUBMENU_POINTER = 0x20,
+  FL_SUBMENU = 0x40,
+  FL_MENU_DIVIDER = 0x80,
+  FL_MENU_HORIZONTAL = 0x100
+};
+
+extern FL_EXPORT int fl_old_shortcut(const char*);
+
+class Fl_Menu_;
+
+struct FL_EXPORT Fl_Menu_Item {
+  const char *text;	// label()
+  int shortcut_;
+  Fl_Callback *callback_;
+  void *user_data_;
+  int flags;
+  uchar labeltype_;
+  uchar labelfont_;
+  uchar labelsize_;
+  unsigned labelcolor_;
+
+  // advance N items, skipping submenus:
+  const Fl_Menu_Item *next(int=1) const;
+  Fl_Menu_Item *next(int i=1) {
+    return (Fl_Menu_Item*)(((const Fl_Menu_Item*)this)->next(i));}
+  const Fl_Menu_Item *first() const { return next(0); }
+  Fl_Menu_Item *first() { return next(0); }
+
+  // methods on menu items:
+  const char* label() const {return text;}
+  void label(const char* a) {text=a;}
+  void label(Fl_Labeltype a,const char* b) {labeltype_ = a; text = b;}
+  Fl_Labeltype labeltype() const {return (Fl_Labeltype)labeltype_;}
+  void labeltype(Fl_Labeltype a) {labeltype_ = a;}
+  Fl_Color labelcolor() const {return (Fl_Color)labelcolor_;}
+  void labelcolor(unsigned a) {labelcolor_ = a;}
+  Fl_Font labelfont() const {return (Fl_Font)labelfont_;}
+  void labelfont(uchar a) {labelfont_ = a;}
+  uchar labelsize() const {return labelsize_;}
+  void labelsize(uchar a) {labelsize_ = a;}
+  Fl_Callback_p callback() const {return callback_;}
+  void callback(Fl_Callback* c, void* p) {callback_=c; user_data_=p;}
+  void callback(Fl_Callback* c) {callback_=c;}
+  void callback(Fl_Callback0*c) {callback_=(Fl_Callback*)c;}
+  void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;}
+  void* user_data() const {return user_data_;}
+  void user_data(void* v) {user_data_ = v;}
+  long argument() const {return (long)user_data_;}
+  void argument(long v) {user_data_ = (void*)v;}
+  int shortcut() const {return shortcut_;}
+  void shortcut(int s) {shortcut_ = s;}
+  int submenu() const {return flags&(FL_SUBMENU|FL_SUBMENU_POINTER);}
+  int checkbox() const {return flags&FL_MENU_TOGGLE;}
+  int radio() const {return flags&FL_MENU_RADIO;}
+  int value() const {return flags&FL_MENU_VALUE;}
+  void set() {flags |= FL_MENU_VALUE;}
+  void clear() {flags &= ~FL_MENU_VALUE;}
+  void setonly();
+  int visible() const {return !(flags&FL_MENU_INVISIBLE);}
+  void show() {flags &= ~FL_MENU_INVISIBLE;}
+  void hide() {flags |= FL_MENU_INVISIBLE;}
+  int active() const {return !(flags&FL_MENU_INACTIVE);}
+  void activate() {flags &= ~FL_MENU_INACTIVE;}
+  void deactivate() {flags |= FL_MENU_INACTIVE;}
+  int activevisible() const {return !(flags&0x11);}
+
+  // compatibility for FLUID so it can set the image of a menu item...
+  void image(Fl_Image* a) {a->label(this);}
+  void image(Fl_Image& a) {a.label(this);}
+
+  // used by menubar:
+  int measure(int* h, const Fl_Menu_*) const;
+  void draw(int x, int y, int w, int h, const Fl_Menu_*, int t=0) const;
+
+  // popup menus without using an Fl_Menu_ widget:
+  const Fl_Menu_Item* popup(
+    int X, int Y,
+    const char *title = 0,
+    const Fl_Menu_Item* picked=0,
+    const Fl_Menu_* = 0) const;
+  const Fl_Menu_Item* pulldown(
+    int X, int Y, int W, int H,
+    const Fl_Menu_Item* picked = 0,
+    const Fl_Menu_* = 0,
+    const Fl_Menu_Item* title = 0,
+    int menubar=0) const;
+  const Fl_Menu_Item* test_shortcut() const;
+  const Fl_Menu_Item* find_shortcut(int *ip=0) const;
+
+  void do_callback(Fl_Widget* o) const {callback_(o, user_data_);}
+  void do_callback(Fl_Widget* o,void* arg) const {callback_(o, arg);}
+  void do_callback(Fl_Widget* o,long arg) const {callback_(o, (void*)arg);}
+
+  // back-compatability, do not use:
+  int checked() const {return flags&FL_MENU_VALUE;}
+  void check() {flags |= FL_MENU_VALUE;}
+  void uncheck() {flags &= ~FL_MENU_VALUE;}
+  int add(const char*, int shortcut, Fl_Callback*, void* =0, int = 0);
+  int add(const char*a, const char* b, Fl_Callback* c,
+	  void* d = 0, int e = 0) {
+    return add(a,fl_old_shortcut(b),c,d,e);}
+  int size() const ;
+};
+
+typedef Fl_Menu_Item Fl_Menu; // back compatability
+
+enum {	// back-compatability enum:
+  FL_PUP_NONE	= 0,
+  FL_PUP_GREY	= FL_MENU_INACTIVE,
+  FL_PUP_GRAY	= FL_MENU_INACTIVE,
+  FL_MENU_BOX	= FL_MENU_TOGGLE,
+  FL_PUP_BOX	= FL_MENU_TOGGLE,
+  FL_MENU_CHECK	= FL_MENU_VALUE,
+  FL_PUP_CHECK	= FL_MENU_VALUE,
+  FL_PUP_RADIO	= FL_MENU_RADIO,
+  FL_PUP_INVISIBLE = FL_MENU_INVISIBLE,
+  FL_PUP_SUBMENU = FL_SUBMENU_POINTER
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Menu_Item.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Menu_Window.H b/Utilities/FLTK/FL/Fl_Menu_Window.H
new file mode 100644
index 0000000000000000000000000000000000000000..1056fb2e0c42b14155a9120237ca733711744722
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Menu_Window.H
@@ -0,0 +1,54 @@
+//
+// "$Id: Fl_Menu_Window.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Menu window header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Menu_Window_H
+#define Fl_Menu_Window_H
+
+#include "Fl_Single_Window.H"
+
+class FL_EXPORT Fl_Menu_Window : public Fl_Single_Window {
+  enum {NO_OVERLAY = 128};
+public:
+  void show();
+  void erase();
+  void flush();
+  void hide();
+  int overlay() {return !(flags()&NO_OVERLAY);}
+  void set_overlay() {clear_flag(NO_OVERLAY);}
+  void clear_overlay() {set_flag(NO_OVERLAY);}
+  ~Fl_Menu_Window();
+  Fl_Menu_Window(int W, int H, const char *l = 0)
+    : Fl_Single_Window(W,H,l) { image(0); }
+  Fl_Menu_Window(int X, int Y, int W, int H, const char *l = 0)
+    : Fl_Single_Window(X,Y,W,H,l) { image(0); }
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Menu_Window.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Multi_Browser.H b/Utilities/FLTK/FL/Fl_Multi_Browser.H
new file mode 100644
index 0000000000000000000000000000000000000000..c1646dc05ae5dbbbff443042d32f28550483291c
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Multi_Browser.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Multi_Browser.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Multi browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Multi_Browser_H
+#define Fl_Multi_Browser_H
+
+#include "Fl_Browser.H"
+
+class Fl_Multi_Browser : public Fl_Browser {
+public:
+    Fl_Multi_Browser(int X,int Y,int W,int H,const char *L=0)
+	: Fl_Browser(X,Y,W,H,L) {type(FL_MULTI_BROWSER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Multi_Browser.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Multi_Label.H b/Utilities/FLTK/FL/Fl_Multi_Label.H
new file mode 100644
index 0000000000000000000000000000000000000000..f4f915112fdb97b3d0d37fd36c4916d3417533cf
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Multi_Label.H
@@ -0,0 +1,47 @@
+//
+// "$Id: Fl_Multi_Label.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Multi-label header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Multi_Label_H
+#define Fl_Multi_Label_H
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+
+struct FL_EXPORT Fl_Multi_Label {
+  const char* labela;
+  const char* labelb;
+  uchar typea;
+  uchar typeb;
+  void label(Fl_Widget*);
+  void label(Fl_Menu_Item*);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Multi_Label.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Multiline_Input.H b/Utilities/FLTK/FL/Fl_Multiline_Input.H
new file mode 100644
index 0000000000000000000000000000000000000000..0d6d1ddd22abc6de1cfa6ea50703ee3dffa890fb
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Multiline_Input.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Multiline_Input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Multiline input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Multiline_Input_H
+#define Fl_Multiline_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Multiline_Input : public Fl_Input {
+public:
+    Fl_Multiline_Input(int X,int Y,int W,int H,const char *l = 0)
+	: Fl_Input(X,Y,W,H,l) {type(FL_MULTILINE_INPUT);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Multiline_Input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Multiline_Output.H b/Utilities/FLTK/FL/Fl_Multiline_Output.H
new file mode 100644
index 0000000000000000000000000000000000000000..6d243587d6103e642855b4c290b682effd7f0539
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Multiline_Output.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Multiline_Output.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Multi line output header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Multiline_Output_H
+#define Fl_Multiline_Output_H
+
+#include "Fl_Output.H"
+
+class Fl_Multiline_Output : public Fl_Output {
+public:
+    Fl_Multiline_Output(int X,int Y,int W,int H,const char *l = 0)
+	: Fl_Output(X,Y,W,H,l) {type(FL_MULTILINE_OUTPUT);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Multiline_Output.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Nice_Slider.H b/Utilities/FLTK/FL/Fl_Nice_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..6a623f9ed094e9dec229b07c38270aa6900f8718
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Nice_Slider.H
@@ -0,0 +1,42 @@
+//
+// "$Id: Fl_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// "Nice" slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+#ifndef Fl_Nice_Slider_H
+#define Fl_Nice_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Nice_Slider : public Fl_Slider {
+public:
+    Fl_Nice_Slider(int x,int y,int w,int h,const char *l=0)
+	: Fl_Slider(x,y,w,h,l) {type(FL_VERT_NICE_SLIDER); box(FL_FLAT_BOX);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Object.H b/Utilities/FLTK/FL/Fl_Object.H
new file mode 100644
index 0000000000000000000000000000000000000000..e2a040452a821dba5dc2f54106a80f72882cb6c1
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Object.H
@@ -0,0 +1,36 @@
+//
+// "$Id: Fl_Object.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Old Fl_Object header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This file is provided for back compatability only.  Please use Fl_Widget
+#ifndef Fl_Object
+#define Fl_Object Fl_Widget
+#endif
+#include "Fl_Widget.H"
+
+//
+// End of "$Id: Fl_Object.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Output.H b/Utilities/FLTK/FL/Fl_Output.H
new file mode 100644
index 0000000000000000000000000000000000000000..23414b4023a8e4e599d6ab04b1bfc66751a4a182
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Output.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Output.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Output header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Output_H
+#define Fl_Output_H
+
+#include "Fl_Input.H"
+
+class Fl_Output : public Fl_Input {
+public:
+  Fl_Output(int X,int Y,int W,int H, const char *l = 0)
+    : Fl_Input(X, Y, W, H, l) {type(FL_NORMAL_OUTPUT);}
+};
+
+#endif 
+
+//
+// End of "$Id: Fl_Output.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Overlay_Window.H b/Utilities/FLTK/FL/Fl_Overlay_Window.H
new file mode 100644
index 0000000000000000000000000000000000000000..bf873d2fbc4208547f3dd714b9535b53deeb1c32
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Overlay_Window.H
@@ -0,0 +1,56 @@
+//
+// "$Id: Fl_Overlay_Window.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Overlay window header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Overlay_Window_H
+#define Fl_Overlay_Window_H
+
+#include "Fl_Double_Window.H"
+
+class FL_EXPORT Fl_Overlay_Window : public Fl_Double_Window {
+  friend class _Fl_Overlay;
+  virtual void draw_overlay() = 0;
+  Fl_Window *overlay_;
+public:
+  void show();
+  void flush();
+  void hide();
+  void resize(int,int,int,int);
+  ~Fl_Overlay_Window();
+  int can_do_overlay();
+  void redraw_overlay();
+  Fl_Overlay_Window(int W, int H, const char *l=0)
+    : Fl_Double_Window(W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); }
+  Fl_Overlay_Window(int X, int Y, int W, int H, const char *l=0)
+    : Fl_Double_Window(X,Y,W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); }
+  void show(int a, char **b) {Fl_Double_Window::show(a,b);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Overlay_Window.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_PNG_Image.H b/Utilities/FLTK/FL/Fl_PNG_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..f11e6239fe88540160ac0ee5cf9a9d5d8d235e8e
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_PNG_Image.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_PNG_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// PNG image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_PNG_Image_H
+#define Fl_PNG_Image_H
+#  include "Fl_Image.H"
+
+class FL_EXPORT Fl_PNG_Image : public Fl_RGB_Image {
+
+  public:
+
+  Fl_PNG_Image(const char* filename);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_PNG_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_PNM_Image.H b/Utilities/FLTK/FL/Fl_PNM_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..314c38484217e69aaf21a36b44bfe56d45769793
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_PNM_Image.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_PNM_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// PNM image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_PNM_Image_H
+#define Fl_PNM_Image_H
+#  include "Fl_Image.H"
+
+class FL_EXPORT Fl_PNM_Image : public Fl_RGB_Image {
+
+  public:
+
+  Fl_PNM_Image(const char* filename);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_PNM_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Pack.H b/Utilities/FLTK/FL/Fl_Pack.H
new file mode 100644
index 0000000000000000000000000000000000000000..8e3c2ba7286adadeb26d0c657b499afb0ab248aa
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Pack.H
@@ -0,0 +1,51 @@
+//
+// "$Id: Fl_Pack.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Pack header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Pack_H
+#define Fl_Pack_H
+
+#include <FL/Fl_Group.H>
+
+class FL_EXPORT Fl_Pack : public Fl_Group {
+  int spacing_;
+public:
+  enum { // values for type(int)
+    VERTICAL = 0,
+    HORIZONTAL = 1
+  };
+  void draw();
+  Fl_Pack(int x,int y,int w ,int h,const char *l = 0);
+  int spacing() const {return spacing_;}
+  void spacing(int i) {spacing_ = i;}
+  uchar horizontal() const {return type();}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Pack.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Pixmap.H b/Utilities/FLTK/FL/Fl_Pixmap.H
new file mode 100644
index 0000000000000000000000000000000000000000..97f1f2695030c9c234956b6cb2d9e0f6b0fdc944
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Pixmap.H
@@ -0,0 +1,80 @@
+//
+// "$Id: Fl_Pixmap.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Pixmap header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Pixmap_H
+#define Fl_Pixmap_H
+#  include "Fl_Image.H"
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+
+// Older C++ compilers don't support the explicit keyword... :(
+#  if defined(__sgi) && !defined(_COMPILER_VERSION)
+#    define explicit
+#  endif // __sgi && !_COMPILER_VERSION
+
+class FL_EXPORT Fl_Pixmap : public Fl_Image {
+  void copy_data();
+  void delete_data();
+  void set_data(const char * const *p);
+
+  protected:
+
+  void measure();
+
+  public:
+
+  int alloc_data; // Non-zero if data was allocated
+#if defined(__APPLE__) || defined(WIN32)
+  void *id; // for internal use
+  void *mask; // for internal use (mask bitmap)
+#else
+  unsigned id; // for internal use
+  unsigned mask; // for internal use (mask bitmap)
+#endif // __APPLE__ || WIN32
+  
+  explicit Fl_Pixmap(char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();}
+  explicit Fl_Pixmap(uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();}
+  explicit Fl_Pixmap(const char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();}
+  explicit Fl_Pixmap(const uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();}
+  virtual ~Fl_Pixmap();
+  virtual Fl_Image *copy(int W, int H);
+  Fl_Image *copy() { return copy(w(), h()); }
+  virtual void color_average(Fl_Color c, float i);
+  virtual void desaturate();
+  virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0);
+  void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);}
+  virtual void label(Fl_Widget*w);
+  virtual void label(Fl_Menu_Item*m);
+  virtual void uncache();
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Pixmap.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Positioner.H b/Utilities/FLTK/FL/Fl_Positioner.H
new file mode 100644
index 0000000000000000000000000000000000000000..dbd147f3772761690605645c5df3e4395810e1ba
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Positioner.H
@@ -0,0 +1,77 @@
+//
+// "$Id: Fl_Positioner.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Positioner header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Positioner_H
+#define Fl_Positioner_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+class FL_EXPORT Fl_Positioner : public Fl_Widget {
+
+  double xmin, ymin;
+  double xmax, ymax;
+  double xvalue_, yvalue_;
+  double xstep_, ystep_;
+
+protected:
+
+  // these allow subclasses to put the dial in a smaller area:
+  void draw(int, int, int, int);
+  int handle(int, int, int, int, int);
+  void draw();
+
+public:
+
+  int handle(int);
+  Fl_Positioner(int x,int y,int w,int h, const char *l=0);
+  double xvalue() const {return xvalue_;}
+  double yvalue() const {return yvalue_;}
+  int xvalue(double);
+  int yvalue(double);
+  int value(double,double);
+  void xbounds(double, double);
+  double xminimum() const {return xmin;}
+  void xminimum(double a) {xbounds(a,xmax);}
+  double xmaximum() const {return xmax;}
+  void xmaximum(double a) {xbounds(xmin,a);}
+  void ybounds(double, double);
+  double yminimum() const {return ymin;}
+  void yminimum(double a) {ybounds(a,ymax);}
+  double ymaximum() const {return ymax;}
+  void ymaximum(double a) {ybounds(ymin,a);}
+  void xstep(double a) {xstep_ = a;}
+  void ystep(double a) {ystep_ = a;}
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Positioner.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Preferences.H b/Utilities/FLTK/FL/Fl_Preferences.H
new file mode 100644
index 0000000000000000000000000000000000000000..b583d2ea51b9f50782ebc83d8c2543444c674024
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Preferences.H
@@ -0,0 +1,169 @@
+//
+// "$Id: Fl_Preferences.H 4458 2005-07-26 07:59:01Z matt $"
+//
+// Preferences definitions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2002-2005 by Matthias Melcher.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Preferences_H
+#  define Fl_Preferences_H
+
+#  ifdef WIN32
+#    include <windows.h>
+#  endif // WIN32
+
+#  include <stdio.h>
+#  include "Fl_Export.H"
+
+
+/**
+ * Preferences are a data tree containing a root, branches and leafs
+ */
+class FL_EXPORT Fl_Preferences 
+{
+
+public:
+
+  enum Root { SYSTEM=0, USER };
+  // enum Type { win32, macos, fltk };
+
+  Fl_Preferences( Root root, const char *vendor, const char *application );
+  Fl_Preferences( const char *path, const char *vendor, const char *application );
+  Fl_Preferences( Fl_Preferences&, const char *group );
+  Fl_Preferences( Fl_Preferences*, const char *group );
+  ~Fl_Preferences();
+
+  int groups();
+  const char *group( int );
+  char groupExists( const char *group );
+  char deleteGroup( const char *group );
+
+  int entries();
+  const char *entry( int );
+  char entryExists( const char *entry );
+  char deleteEntry( const char *entry );
+
+  char set( const char *entry, int value );
+  char set( const char *entry, float value );
+  char set( const char *entry, double value );
+  char set( const char *entry, const char *value );
+  char set( const char *entry, const void *value, int size ); 
+
+  char get( const char *entry, int &value,    int defaultValue );
+  char get( const char *entry, float &value,  float defaultValue );
+  char get( const char *entry, double &value, double defaultValue );
+  char get( const char *entry, char *&value,  const char *defaultValue );
+  char get( const char *entry, char *value,   const char *defaultValue, int maxSize );
+  char get( const char *entry, void *&value,  const void *defaultValue, int defaultSize );
+  char get( const char *entry, void *value,   const void *defaultValue, int defaultSize, int maxSize );
+  int size( const char *entry );
+
+  char getUserdataPath( char *path, int pathlen );
+
+  void flush();
+
+  // char export( const char *filename, Type fileFormat );
+  // char import( const char *filename );
+
+  class FL_EXPORT Name {
+    char *data_;
+  public:
+    Name( unsigned int n );
+    Name( const char *format, ... );
+    operator const char *() { return data_; }
+    ~Name();
+  };
+
+  struct Entry
+  {
+    char *name, *value;
+  };
+
+private:
+
+  // make the following functions unavailable
+  Fl_Preferences(); 
+  Fl_Preferences(const Fl_Preferences&); 
+  Fl_Preferences &operator=(const Fl_Preferences&);
+
+  static char nameBuffer[128];
+
+  class FL_EXPORT Node // a node contains a list to all its entries 
+  {          // and all means to manage the tree structure
+    Node *child_, *next_, *parent_;
+    char *path_;
+    char dirty_;
+  public:
+    Node( const char *path );
+    ~Node();
+    // node methods
+    int write( FILE *f );
+    Node *find( const char *path );
+    Node *search( const char *path, int offset=0 );
+    Node *addChild( const char *path );
+    void setParent( Node *parent );
+    Node *parent() { return parent_; }
+    char remove();
+    char dirty();
+    // entry methods
+    int nChildren();
+    const char *child( int ix );
+    void set( const char *name, const char *value );
+    void set( const char *line );
+    void add( const char *line );
+    const char *get( const char *name );
+    int getEntry( const char *name );
+    char deleteEntry( const char *name );
+    // public values
+    Entry *entry;
+    int nEntry, NEntry;
+    static int lastEntrySet;
+  };
+  friend class Node;
+
+  class FL_EXPORT RootNode  // the root node manages file paths and basic reading and writing
+  {
+    Fl_Preferences *prefs_;
+    char *filename_;
+    char *vendor_, *application_;
+  public:
+    RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application );
+    RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application );
+    ~RootNode();
+    int read();
+    int write();
+    char getPath( char *path, int pathlen );
+  };
+  friend class RootNode;
+
+  Node *node;
+  RootNode *rootNode;
+  
+};
+
+
+#endif // !Fl_Preferences_H
+
+//
+// End of "$Id: Fl_Preferences.H 4458 2005-07-26 07:59:01Z matt $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Progress.H b/Utilities/FLTK/FL/Fl_Progress.H
new file mode 100644
index 0000000000000000000000000000000000000000..836d53ad775f1a1177206b07467c12f4f5ac90a8
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Progress.H
@@ -0,0 +1,70 @@
+//
+// "$Id: Fl_Progress.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Progress bar widget definitions.
+//
+// Copyright 2000-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef _Fl_Progress_H_
+#  define _Fl_Progress_H_
+
+//
+// Include necessary headers.
+//
+
+#include "Fl_Widget.H"
+
+
+//
+// Progress class...
+//
+
+class FL_EXPORT Fl_Progress : public Fl_Widget
+{
+  float	value_,
+	minimum_,
+	maximum_;
+
+  protected:
+
+  virtual void draw();
+
+  public:
+
+  Fl_Progress(int x, int y, int w, int h, const char *l = 0);
+
+  void	maximum(float v) { maximum_ = v; redraw(); }
+  float	maximum() const { return (maximum_); }
+
+  void	minimum(float v) { minimum_ = v; redraw(); }
+  float	minimum() const { return (minimum_); }
+
+  void	value(float v) { value_ = v; redraw(); }
+  float	value() const { return (value_); }
+};
+
+#endif // !_Fl_Progress_H_
+
+//
+// End of "$Id: Fl_Progress.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Radio_Button.H b/Utilities/FLTK/FL/Fl_Radio_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..888a9ac7bd6bc7c9ec401fbd87cddfa5c3cd8951
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Radio_Button.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Radio_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Radio button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Radio_Button_H
+#define Fl_Radio_Button_H
+
+#include "Fl_Button.H"
+
+class Fl_Radio_Button : public Fl_Button {
+public:
+    Fl_Radio_Button(int x,int y,int w,int h,const char *l=0)
+	: Fl_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Radio_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Radio_Light_Button.H b/Utilities/FLTK/FL/Fl_Radio_Light_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..0d6a3ae7eb2f8d2174512517feb4d0a559a5df64
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Radio_Light_Button.H
@@ -0,0 +1,42 @@
+//
+// "$Id: Fl_Radio_Light_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Radio light button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+#ifndef Fl_Radio_Light_Button_H
+#define Fl_Radio_Light_Button_H
+
+#include "Fl_Light_Button.H"
+
+class Fl_Radio_Light_Button : public Fl_Light_Button {
+public:
+    Fl_Radio_Light_Button(int X,int Y,int W,int H,const char *l=0)
+	: Fl_Light_Button(X,Y,W,H,l) {type(FL_RADIO_BUTTON);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Radio_Light_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Radio_Round_Button.H b/Utilities/FLTK/FL/Fl_Radio_Round_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..7e525c518a1d39f5f5f5f765e98fa72c7565ed09
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Radio_Round_Button.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Radio_Round_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Radio round button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Radio_Round_Button_H
+#define Fl_Radio_Round_Button_H
+
+#include "Fl_Round_Button.H"
+
+class Fl_Radio_Round_Button : public Fl_Round_Button {
+public:
+    Fl_Radio_Round_Button(int x,int y,int w,int h,const char *l=0)
+	: Fl_Round_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Radio_Round_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Repeat_Button.H b/Utilities/FLTK/FL/Fl_Repeat_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..5e0b650756b9fbfa9257f002a15b8a2e314c427c
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Repeat_Button.H
@@ -0,0 +1,49 @@
+//
+// "$Id: Fl_Repeat_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Repeat button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Repeat_Button_H
+#define Fl_Repeat_Button_H
+#include "Fl.H"
+#include "Fl_Button.H"
+
+class FL_EXPORT Fl_Repeat_Button : public Fl_Button {
+  static void repeat_callback(void *);
+public:
+  int handle(int);
+  Fl_Repeat_Button(int X,int Y,int W,int H,const char *l=0)
+    : Fl_Button(X,Y,W,H,l) {}
+  void deactivate() {
+    Fl::remove_timeout(repeat_callback,this);
+    Fl_Button::deactivate();
+  }
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Repeat_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Return_Button.H b/Utilities/FLTK/FL/Fl_Return_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..f9cb52a078789f4061bfb869cb28c350d40fc949
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Return_Button.H
@@ -0,0 +1,45 @@
+//
+// "$Id: Fl_Return_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Return button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Return_Button_H
+#define Fl_Return_Button_H
+#include "Fl_Button.H"
+
+class FL_EXPORT Fl_Return_Button : public Fl_Button {
+protected:
+  void draw();
+public:
+  int handle(int);
+  Fl_Return_Button(int X, int Y, int W, int H,const char *l=0)
+    : Fl_Button(X,Y,W,H,l) {}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Return_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Roller.H b/Utilities/FLTK/FL/Fl_Roller.H
new file mode 100644
index 0000000000000000000000000000000000000000..064b150680310476be6f270630144d9f24df1193
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Roller.H
@@ -0,0 +1,47 @@
+//
+// "$Id: Fl_Roller.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Roller header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Roller_H
+#define Fl_Roller_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+class FL_EXPORT Fl_Roller : public Fl_Valuator {
+protected:
+  void draw();
+public:
+  int handle(int);
+  Fl_Roller(int X,int Y,int W,int H,const char* L=0);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Roller.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Round_Button.H b/Utilities/FLTK/FL/Fl_Round_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..c47e92cd121695b90d8711b0084bbcafcf616121
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Round_Button.H
@@ -0,0 +1,42 @@
+//
+// "$Id: Fl_Round_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Round button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Round_Button_H
+#define Fl_Round_Button_H
+
+#include "Fl_Light_Button.H"
+
+class FL_EXPORT Fl_Round_Button : public Fl_Light_Button {
+public:
+  Fl_Round_Button(int x,int y,int w,int h,const char *l = 0);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Round_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Round_Clock.H b/Utilities/FLTK/FL/Fl_Round_Clock.H
new file mode 100644
index 0000000000000000000000000000000000000000..d3b9fb0913ab9506efb491b90de7b531bb71adc4
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Round_Clock.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Round_Clock.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Round clock header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Round_Clock_H
+#define Fl_Round_Clock_H
+
+#include "Fl_Clock.H"
+
+class Fl_Round_Clock : public Fl_Clock {
+public:
+    Fl_Round_Clock(int x,int y,int w,int h, const char *l = 0)
+	: Fl_Clock(x,y,w,h,l) {type(FL_ROUND_CLOCK); box(FL_NO_BOX);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Round_Clock.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Scroll.H b/Utilities/FLTK/FL/Fl_Scroll.H
new file mode 100644
index 0000000000000000000000000000000000000000..0bc3a5bb1530b697cb82cf298dd3d38700eaad8f
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Scroll.H
@@ -0,0 +1,79 @@
+//
+// "$Id: Fl_Scroll.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Scroll header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Scroll_H
+#define Fl_Scroll_H
+
+#include "Fl_Group.H"
+#include "Fl_Scrollbar.H"
+
+class FL_EXPORT Fl_Scroll : public Fl_Group {
+
+  int xposition_, yposition_;
+  int width_, height_;
+  int oldx, oldy;
+  static void hscrollbar_cb(Fl_Widget*, void*);
+  static void scrollbar_cb(Fl_Widget*, void*);
+  void fix_scrollbar_order();
+  static void draw_clip(void*,int,int,int,int);
+  void bbox(int&,int&,int&,int&);
+
+protected:
+
+  void draw();
+
+public:
+
+  Fl_Scrollbar scrollbar;
+  Fl_Scrollbar hscrollbar;
+
+  void resize(int,int,int,int);
+  int handle(int);
+
+  Fl_Scroll(int X,int Y,int W,int H,const char*l=0);
+
+  enum { // values for type()
+    HORIZONTAL = 1,
+    VERTICAL = 2,
+    BOTH = 3,
+    ALWAYS_ON = 4,
+    HORIZONTAL_ALWAYS = 5,
+    VERTICAL_ALWAYS = 6,
+    BOTH_ALWAYS = 7
+  };
+
+  int xposition() const {return xposition_;}
+  int yposition() const {return yposition_;}
+  void position(int, int);
+  void clear();
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Scroll.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Scrollbar.H b/Utilities/FLTK/FL/Fl_Scrollbar.H
new file mode 100644
index 0000000000000000000000000000000000000000..93c75b8503b0afe36ab957adbc861c417ceea99e
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Scrollbar.H
@@ -0,0 +1,60 @@
+//
+// "$Id: Fl_Scrollbar.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Scroll bar header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Scrollbar_H
+#define Fl_Scrollbar_H
+
+#include "Fl_Slider.H"
+
+class FL_EXPORT Fl_Scrollbar : public Fl_Slider {
+
+  int linesize_;
+  int pushed_;
+  static void timeout_cb(void*);
+  void increment_cb();
+protected:
+  void draw();
+
+public:
+
+  Fl_Scrollbar(int x,int y,int w,int h, const char *l = 0);
+  int handle(int);
+
+  int value() {return int(Fl_Slider::value());}
+  int value(int p, int s, int top, int total) {
+    return scrollvalue(p, s, top, total);
+  }
+  int linesize() const {return linesize_;}
+  void linesize(int i) {linesize_ = i;}
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Scrollbar.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Secret_Input.H b/Utilities/FLTK/FL/Fl_Secret_Input.H
new file mode 100644
index 0000000000000000000000000000000000000000..a87bef59db93702deaaebb395d574d286d5b24e3
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Secret_Input.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Secret_Input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Secret input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Secret_Input_H
+#define Fl_Secret_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Secret_Input : public Fl_Input {
+public:
+    Fl_Secret_Input(int X,int Y,int W,int H,const char *l = 0)
+	: Fl_Input(X,Y,W,H,l) {type(FL_SECRET_INPUT);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Secret_Input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Select_Browser.H b/Utilities/FLTK/FL/Fl_Select_Browser.H
new file mode 100644
index 0000000000000000000000000000000000000000..4a8ef921057d078314272a6489c9fb476d4b7d09
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Select_Browser.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Select_Browser.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Select browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Select_Browser_H
+#define Fl_Select_Browser_H
+
+#include "Fl_Browser.H"
+
+class Fl_Select_Browser : public Fl_Browser {
+public:
+    Fl_Select_Browser(int X,int Y,int W,int H,const char *l=0)
+	: Fl_Browser(X,Y,W,H,l) {type(FL_SELECT_BROWSER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Select_Browser.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Shared_Image.H b/Utilities/FLTK/FL/Fl_Shared_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..042b7827d101821f1659fea837e4f13bd0285701
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Shared_Image.H
@@ -0,0 +1,99 @@
+//
+// "$Id: Fl_Shared_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Shared image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Shared_Image_H
+#  define Fl_Shared_Image_H
+
+#  include "Fl_Image.H"
+
+
+// Test function for adding new formats
+typedef Fl_Image *(*Fl_Shared_Handler)(const char *name, uchar *header,
+                                       int headerlen);
+
+// Shared images class. 
+class FL_EXPORT Fl_Shared_Image : public Fl_Image {
+  protected:
+
+  static Fl_Shared_Image **images_;	// Shared images
+  static int	num_images_;		// Number of shared images
+  static int	alloc_images_;		// Allocated shared images
+  static Fl_Shared_Handler *handlers_;	// Additional format handlers
+  static int	num_handlers_;		// Number of format handlers
+  static int	alloc_handlers_;	// Allocated format handlers
+
+  const char	*name_;			// Name of image file
+  int		original_;		// Original image?
+  int		refcount_;		// Number of times this image has been used
+  Fl_Image	*image_;		// The image that is shared
+  int		alloc_image_;		// Was the image allocated?
+
+  static int	compare(Fl_Shared_Image **i0, Fl_Shared_Image **i1);
+
+  // Use get() and release() to load/delete images in memory...
+  Fl_Shared_Image();
+  Fl_Shared_Image(const char *n, Fl_Image *img = 0);
+  virtual ~Fl_Shared_Image();
+  void add();
+  void update();
+
+  public:
+
+  const char	*name() { return name_; }
+  int		refcount() { return refcount_; }
+  void		release();
+  void		reload();
+
+  virtual Fl_Image *copy(int W, int H);
+  Fl_Image *copy() { return copy(w(), h()); }
+  virtual void color_average(Fl_Color c, float i);
+  virtual void desaturate();
+  virtual void draw(int X, int Y, int W, int H, int cx, int cy);
+  void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); }
+  virtual void uncache();
+
+  static Fl_Shared_Image *find(const char *n, int W = 0, int H = 0);
+  static Fl_Shared_Image *get(const char *n, int W = 0, int H = 0);
+  static Fl_Shared_Image **images();
+  static int		num_images();
+  static void		add_handler(Fl_Shared_Handler f);
+  static void		remove_handler(Fl_Shared_Handler f);
+};
+
+//
+// The following function is provided in the fltk_images library and
+// registers all of the "extra" image file formats that are not part
+// of the core FLTK library...
+//
+
+FL_EXPORT extern void fl_register_images();
+
+#endif // !Fl_Shared_Image_H
+
+//
+// End of "$Id: Fl_Shared_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
diff --git a/Utilities/FLTK/FL/Fl_Simple_Counter.H b/Utilities/FLTK/FL/Fl_Simple_Counter.H
new file mode 100644
index 0000000000000000000000000000000000000000..84e07c9b5af7d63134a42b3e2e72a829e18e4e2f
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Simple_Counter.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Simple_Counter.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Simple counter header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Simple_Counter_H
+#define Fl_Simple_Counter_H
+
+#include "Fl_Counter.H"
+
+class Fl_Simple_Counter : public Fl_Counter {
+public:
+    Fl_Simple_Counter(int x,int y,int w,int h, const char *l = 0)
+	: Fl_Counter(x,y,w,h,l) {type(FL_SIMPLE_COUNTER);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Simple_Counter.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Single_Window.H b/Utilities/FLTK/FL/Fl_Single_Window.H
new file mode 100644
index 0000000000000000000000000000000000000000..c68e66e32ceeebe78f5b10722622dc3f242f6e92
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Single_Window.H
@@ -0,0 +1,49 @@
+//
+// "$Id: Fl_Single_Window.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Single-buffered window header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Single_Window_H
+#define Fl_Single_Window_H
+
+#include "Fl_Window.H"
+
+class FL_EXPORT Fl_Single_Window : public Fl_Window {
+public:
+  void show();
+  void show(int a, char **b) {Fl_Window::show(a,b);}
+  void flush();
+  Fl_Single_Window(int W, int H, const char *l=0)
+    : Fl_Window(W,H,l) {}
+  Fl_Single_Window(int X, int Y, int W, int H, const char *l=0)
+    : Fl_Window(X,Y,W,H,l) {}
+  int make_current();
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Single_Window.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Slider.H b/Utilities/FLTK/FL/Fl_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..8a6b93d602808c7aa118673ce539b01af9d46db7
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Slider.H
@@ -0,0 +1,75 @@
+//
+// "$Id: Fl_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Slider_H
+#define Fl_Slider_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+// values for type(), lowest bit indicate horizontal:
+#define FL_VERT_SLIDER		0
+#define FL_HOR_SLIDER		1
+#define FL_VERT_FILL_SLIDER	2
+#define FL_HOR_FILL_SLIDER	3
+#define FL_VERT_NICE_SLIDER	4
+#define FL_HOR_NICE_SLIDER	5
+
+class FL_EXPORT Fl_Slider : public Fl_Valuator {
+
+  float slider_size_;
+  uchar slider_;
+  void _Fl_Slider();
+  void draw_bg(int, int, int, int);
+
+protected:
+
+  // these allow subclasses to put the slider in a smaller area:
+  void draw(int, int, int, int);
+  int handle(int, int, int, int, int);
+
+public:
+
+  void draw();
+  int handle(int);
+  Fl_Slider(int x,int y,int w,int h, const char *l = 0);
+  Fl_Slider(uchar t,int x,int y,int w,int h, const char *l);
+
+  int scrollvalue(int windowtop,int windowsize,int first,int totalsize);
+  void bounds(double a, double b);
+  float slider_size() const {return slider_size_;}
+  void slider_size(double v);
+  Fl_Boxtype slider() const {return (Fl_Boxtype)slider_;}
+  void slider(Fl_Boxtype c) {slider_ = c;}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Spinner.H b/Utilities/FLTK/FL/Fl_Spinner.H
new file mode 100644
index 0000000000000000000000000000000000000000..35a9badfbf7459845f30fe04c964ac43ddea011f
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Spinner.H
@@ -0,0 +1,171 @@
+//
+// "$Id$"
+//
+// Spinner widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Spinner_H
+#  define Fl_Spinner_H
+
+//
+// Include necessary headers...
+//
+
+#  include <FL/Fl_Group.H>
+#  include <FL/Fl_Input.H>
+#  include <FL/Fl_Repeat_Button.H>
+#  include <stdio.h>
+#  include <stdlib.h>
+
+
+//
+// Fl_Spinner widget class...
+//
+
+class Fl_Spinner : public Fl_Group
+{
+  double	value_;			// Current value
+  double	minimum_;		// Minimum value
+  double	maximum_;		// Maximum value
+  double	step_;			// Amount to add/subtract for up/down
+  const char	*format_;		// Format string
+
+  Fl_Input	input_;			// Input field for the value
+  Fl_Repeat_Button
+		up_button_,		// Up button
+		down_button_;		// Down button
+
+  static void	sb_cb(Fl_Widget *w, Fl_Spinner *sb) {
+		  double v;		// New value
+
+		  if (w == &(sb->input_)) {
+		    // Something changed in the input field...
+		    v = atof(sb->input_.value());
+
+		    if (v < sb->minimum_) {
+		      sb->value_ = sb->minimum_;
+		      sb->update();
+		    } else if (v > sb->maximum_) {
+		      sb->value_ = sb->maximum_;
+		      sb->update();
+		    } else sb->value_ = v;
+		  } else if (w == &(sb->up_button_)) {
+		    // Up button pressed...
+		    v = sb->value_ + sb->step_;
+
+		    if (v > sb->maximum_) sb->value_ = sb->minimum_;
+		    else sb->value_ = v;
+
+		    sb->update();
+		  } else if (w == &(sb->down_button_)) {
+		    // Down button pressed...
+		    v = sb->value_ - sb->step_;
+
+		    if (v < sb->minimum_) sb->value_ = sb->maximum_;
+		    else sb->value_ = v;
+
+		    sb->update();
+		  }
+
+		  sb->do_callback();
+		}
+  void		update() {
+		  char s[255];		// Value string
+
+		  sprintf(s, format_, value_);
+		  input_.value(s);
+		}
+
+  public:
+
+		Fl_Spinner(int X, int Y, int W, int H, const char *L = 0)
+		  : Fl_Group(X, Y, W, H, L),
+		    input_(X, Y, W - H / 2 - 2, H),
+		    up_button_(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2, "@-22<"),
+		    down_button_(X + W - H / 2 - 2, Y + H - H / 2,
+		                 H / 2 + 2, H / 2, "@-22>") {
+		  end();
+
+		  value_   = 1.0;
+		  minimum_ = 1.0;
+		  maximum_ = 100.0;
+		  step_    = 1.0;
+		  format_  = "%.0f";
+
+		  align(FL_ALIGN_LEFT);
+
+		  input_.value("1");
+		  input_.type(FL_INT_INPUT);
+		  input_.when(FL_WHEN_CHANGED);
+		  input_.callback((Fl_Callback *)sb_cb, this);
+
+		  up_button_.callback((Fl_Callback *)sb_cb, this);
+
+		  down_button_.callback((Fl_Callback *)sb_cb, this);
+		}
+
+  const char	*format() { return (format_); }
+  void		format(const char *f) { format_ = f; update(); }
+  double	maxinum() const { return (maximum_); }
+  void		maximum(double m) { maximum_ = m; }
+  double	mininum() const { return (minimum_); }
+  void		minimum(double m) { minimum_ = m; }
+  void		range(double a, double b) { minimum_ = a; maximum_ = b; }
+  void		resize(int X, int Y, int W, int H) {
+		  Fl_Group::resize(X,Y,W,H);
+
+		  input_.resize(X, Y, W - H / 2 - 2, H);
+		  up_button_.resize(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2);
+		  down_button_.resize(X + W - H / 2 - 2, Y + H - H / 2,
+		                      H / 2 + 2, H / 2);
+		}
+  double	step() const { return (step_); }
+  void		step(double s) { step_ = s; }
+  Fl_Color	textcolor() const {
+		  return (input_.textcolor());
+		}
+  void		textcolor(Fl_Color c) {
+		  input_.textcolor(c);
+		}
+  uchar		textfont() const {
+		  return (input_.textfont());
+		}
+  void		textfont(uchar f) {
+		  input_.textfont(f);
+		}
+  uchar		textsize() const {
+		  return (input_.textsize());
+		}
+  void		textsize(uchar s) {
+		  input_.textsize(s);
+		}
+  double	value() const { return (value_); }
+  void		value(double v) { value_ = v; update(); }
+};
+
+#endif // !Fl_Spinner_H
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/FL/Fl_Sys_Menu_Bar.H b/Utilities/FLTK/FL/Fl_Sys_Menu_Bar.H
new file mode 100644
index 0000000000000000000000000000000000000000..01f4b60c99f7e60d03fd4329c097711debc2de6e
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Sys_Menu_Bar.H
@@ -0,0 +1,56 @@
+//
+// "$Id: Fl_Sys_Menu_Bar.H 4546 2005-08-29 20:05:38Z matt $"
+//
+// MacOS system menu bar header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Sys_Menu_Bar_H
+#define Fl_Sys_Menu_Bar_H
+
+#include "Fl_Menu_Bar.H"
+
+#ifdef __APPLE__
+
+class FL_EXPORT Fl_Sys_Menu_Bar : public Fl_Menu_Bar {
+protected:
+  void draw();
+public:
+  Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l=0)
+      : Fl_Menu_Bar(x,y,w,h,l) {
+	   deactivate();			// don't let the old area take events
+	  }
+  void menu(const Fl_Menu_Item *m);
+};
+
+#else
+
+typedef Fl_Menu_Bar Fl_Sys_Menu_Bar;
+
+#endif
+
+#endif
+
+//
+// End of "$Id: Fl_Sys_Menu_Bar.H 4546 2005-08-29 20:05:38Z matt $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Tabs.H b/Utilities/FLTK/FL/Fl_Tabs.H
new file mode 100644
index 0000000000000000000000000000000000000000..3145f20c00a5c8f94edad1f30a6a5bdae30313a9
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Tabs.H
@@ -0,0 +1,56 @@
+//
+// "$Id: Fl_Tabs.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Tab header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Tabs_H
+#define Fl_Tabs_H
+
+#include "Fl_Group.H"
+
+class FL_EXPORT Fl_Tabs : public Fl_Group {
+  Fl_Widget *value_;
+  Fl_Widget *push_;
+  int tab_positions(int*, int*);
+  int tab_height();
+  void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0);
+protected:
+  void draw();
+
+public:
+  int handle(int);
+  Fl_Widget *value();
+  int value(Fl_Widget *);
+  Fl_Widget *push() const {return push_;}
+  int push(Fl_Widget *);
+  Fl_Tabs(int,int,int,int,const char * = 0);
+  Fl_Widget *which(int event_x, int event_y);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Tabs.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Text_Buffer.H b/Utilities/FLTK/FL/Fl_Text_Buffer.H
new file mode 100644
index 0000000000000000000000000000000000000000..d2b91f39d8372499a7173753783f76e875c8e7c0
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Text_Buffer.H
@@ -0,0 +1,259 @@
+//
+// "$Id: Fl_Text_Buffer.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Header file for Fl_Text_Buffer class.
+//
+// Copyright 2001-2005 by Bill Spitzak and others.
+// Original code Copyright Mark Edel.  Permission to distribute under
+// the LGPL for the FLTK library granted by Mark Edel.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef FL_TEXT_BUFFER_H
+#define FL_TEXT_BUFFER_H
+
+/* Maximum length in characters of a tab or control character expansion
+   of a single buffer character */
+#define FL_TEXT_MAX_EXP_CHAR_LEN 20
+
+#include "Fl_Export.H"
+
+class FL_EXPORT Fl_Text_Selection {
+  friend class Fl_Text_Buffer;
+
+  public:
+    void set(int start, int end);
+    void set_rectangular(int start, int end, int rectStart, int rectEnd);
+    void update(int pos, int nDeleted, int nInserted);
+    char rectangular() { return mRectangular; }
+    int start() { return mStart; }
+    int end() { return mEnd; }
+    int rect_start() { return mRectStart; }
+    int rect_end() { return mRectEnd; }
+    char selected() { return mSelected; }
+    void selected(char b) { mSelected = b; }
+    int includes(int pos, int lineStartPos, int dispIndex);
+    int position(int* start, int* end);
+    int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd);
+
+
+  protected:
+    char mSelected;
+    char mRectangular;
+    int mStart;
+    int mEnd;
+    int mRectStart;
+    int mRectEnd;
+};
+
+typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
+                                  int nRestyled, const char* deletedText,
+                                  void* cbArg);
+typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg);
+
+class FL_EXPORT Fl_Text_Buffer {
+  public:
+    Fl_Text_Buffer(int requestedSize = 0);
+    ~Fl_Text_Buffer();
+
+    int length() { return mLength; }
+    char* text();
+    void text(const char* text);
+    char* text_range(int start, int end);
+    char character(int pos);
+    char* text_in_rectangle(int start, int end, int rectStart, int rectEnd);
+    void insert(int pos, const char* text);
+    void append(const char* t) { insert(length(), t); }
+    void remove(int start, int end);
+    void replace(int start, int end, const char *text);
+    void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos);
+    int undo(int *cp=0);
+    void canUndo(char flag=1);
+    int insertfile(const char *file, int pos, int buflen = 128*1024);
+    int appendfile(const char *file, int buflen = 128*1024)
+      { return insertfile(file, length(), buflen); }
+    int loadfile(const char *file, int buflen = 128*1024)
+      { select(0, length()); remove_selection(); return appendfile(file, buflen); }
+    int outputfile(const char *file, int start, int end, int buflen = 128*1024);
+    int savefile(const char *file, int buflen = 128*1024)
+      { return outputfile(file, 0, length(), buflen); }
+
+    void insert_column(int column, int startPos, const char* text,
+                       int* charsInserted, int* charsDeleted);
+
+    void replace_rectangular(int start, int end, int rectStart, int rectEnd,
+                             const char* text);
+
+    void overlay_rectangular(int startPos, int rectStart, int rectEnd,
+                             const char* text, int* charsInserted,
+                             int* charsDeleted);
+
+    void remove_rectangular(int start, int end, int rectStart, int rectEnd);
+    void clear_rectangular(int start, int end, int rectStart, int rectEnd);
+    int tab_distance() { return mTabDist; }
+    void tab_distance(int tabDist);
+    void select(int start, int end);
+    int selected() { return mPrimary.selected(); }
+    void unselect();
+    void select_rectangular(int start, int end, int rectStart, int rectEnd);
+    int selection_position(int* start, int* end);
+
+    int selection_position(int* start, int* end, int* isRect, int* rectStart,
+                           int* rectEnd);
+
+    char* selection_text();
+    void remove_selection();
+    void replace_selection(const char* text);
+    void secondary_select(int start, int end);
+    void secondary_unselect();
+
+    void secondary_select_rectangular(int start, int end, int rectStart,
+                                      int rectEnd);
+
+    int secondary_selection_position(int* start, int* end, int* isRect,
+                                     int* rectStart, int* rectEnd);
+
+    char* secondary_selection_text();
+    void remove_secondary_selection();
+    void replace_secondary_selection(const char* text);
+    void highlight(int start, int end);
+    void unhighlight();
+    void highlight_rectangular(int start, int end, int rectStart, int rectEnd);
+
+    int highlight_position(int* start, int* end, int* isRect, int* rectStart,
+                           int* rectEnd);
+
+    char* highlight_text();
+    void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
+    void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
+
+    void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); }
+
+    void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg);
+    void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg);
+
+    void call_predelete_callbacks() { call_predelete_callbacks(0, 0); }
+
+    char* line_text(int pos);
+    int line_start(int pos);
+    int line_end(int pos);
+    int word_start(int pos);
+    int word_end(int pos);
+    int expand_character(int pos, int indent, char *outStr);
+
+    static int expand_character(char c, int indent, char* outStr, int tabDist,
+                                char nullSubsChar);
+
+    static int character_width(char c, int indent, int tabDist, char nullSubsChar);
+    int count_displayed_characters(int lineStartPos, int targetPos);
+    int skip_displayed_characters(int lineStartPos, int nChars);
+    int count_lines(int startPos, int endPos);
+    int skip_lines(int startPos, int nLines);
+    int rewind_lines(int startPos, int nLines);
+    int findchar_forward(int startPos, char searchChar, int* foundPos);
+    int findchar_backward(int startPos, char searchChar, int* foundPos);
+    int findchars_forward(int startPos, const char* searchChars, int* foundPos);
+    int findchars_backward(int startPos, const char* searchChars, int* foundPos);
+
+    int search_forward(int startPos, const char* searchString, int* foundPos,
+                       int matchCase = 0);
+
+    int search_backward(int startPos, const char* searchString, int* foundPos,
+                        int matchCase = 0);
+
+    int substitute_null_characters(char* string, int length);
+    void unsubstitute_null_characters(char* string);
+    char null_substitution_character() { return mNullSubsChar; }
+    Fl_Text_Selection* primary_selection() { return &mPrimary; }
+    Fl_Text_Selection* secondary_selection() { return &mSecondary; }
+    Fl_Text_Selection* highlight_selection() { return &mHighlight; }
+
+  protected:
+    void call_modify_callbacks(int pos, int nDeleted, int nInserted,
+                               int nRestyled, const char* deletedText);
+    void call_predelete_callbacks(int pos, int nDeleted);
+
+    int insert_(int pos, const char* text);
+    void remove_(int start, int end);
+
+    void remove_rectangular_(int start, int end, int rectStart, int rectEnd,
+                             int* replaceLen, int* endPos);
+
+    void insert_column_(int column, int startPos, const char* insText,
+                        int* nDeleted, int* nInserted, int* endPos);
+
+    void overlay_rectangular_(int startPos, int rectStart, int rectEnd,
+                              const char* insText, int* nDeleted,
+                              int* nInserted, int* endPos);
+
+    void redisplay_selection(Fl_Text_Selection* oldSelection,
+                             Fl_Text_Selection* newSelection);
+
+    void move_gap(int pos);
+    void reallocate_with_gap(int newGapStart, int newGapLen);
+    char* selection_text_(Fl_Text_Selection* sel);
+    void remove_selection_(Fl_Text_Selection* sel);
+    void replace_selection_(Fl_Text_Selection* sel, const char* text);
+
+    void rectangular_selection_boundaries(int lineStartPos, int rectStart,
+                                          int rectEnd, int* selStart,
+                                          int* selEnd);
+
+    void update_selections(int pos, int nDeleted, int nInserted);
+
+    Fl_Text_Selection mPrimary; /* highlighted areas */
+    Fl_Text_Selection mSecondary;
+    Fl_Text_Selection mHighlight;
+    int mLength;                /* length of the text in the buffer (the length
+                                   of the buffer itself must be calculated:
+                                   gapEnd - gapStart + length) */
+    char* mBuf;                 /* allocated memory where the text is stored */
+    int mGapStart;              /* points to the first character of the gap */
+    int mGapEnd;                /* points to the first char after the gap */
+    // The hardware tab distance used by all displays for this buffer,
+    // and used in computing offsets for rectangular selection operations.
+    int mTabDist;               /* equiv. number of characters in a tab */
+    int mUseTabs;               /* True if buffer routines are allowed to use
+                                   tabs for padding in rectangular operations */
+    int mNModifyProcs;          /* number of modify-redisplay procs attached */
+    Fl_Text_Modify_Cb*          /* procedures to call when buffer is */
+    mNodifyProcs;               /* modified to redisplay contents */
+    void** mCbArgs;             /* caller arguments for modifyProcs above */
+    int mNPredeleteProcs;	/* number of pre-delete procs attached */
+    Fl_Text_Predelete_Cb*	/* procedure to call before text is deleted */
+	 mPredeleteProcs;	/* from the buffer; at most one is supported. */
+    void **mPredeleteCbArgs;	/* caller argument for pre-delete proc above */
+    int mCursorPosHint;         /* hint for reasonable cursor position after
+                                   a buffer modification operation */
+    char mNullSubsChar;         /* NEdit is based on C null-terminated strings,
+                                   so ascii-nul characters must be substituted
+                                   with something else.  This is the else, but
+                                   of course, things get quite messy when you
+                                   use it */
+    char mCanUndo;		/* if this buffer is used for attributes, it must
+				   not do any undo calls */
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Text_Buffer.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Text_Display.H b/Utilities/FLTK/FL/Fl_Text_Display.H
new file mode 100644
index 0000000000000000000000000000000000000000..e7ef14d3f396027f613e3c7534a1a8abfd0ecf23
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Text_Display.H
@@ -0,0 +1,298 @@
+//
+// "$Id: Fl_Text_Display.H 4502 2005-08-10 23:11:51Z matt $"
+//
+// Header file for Fl_Text_Display class.
+//
+// Copyright 2001-2005 by Bill Spitzak and others.
+// Original code Copyright Mark Edel.  Permission to distribute under
+// the LGPL for the FLTK library granted by Mark Edel.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef FL_TEXT_DISPLAY_H
+#define FL_TEXT_DISPLAY_H
+
+#include "fl_draw.H"
+#include "Fl_Group.H"
+#include "Fl_Widget.H"
+#include "Fl_Scrollbar.H"
+#include "Fl_Text_Buffer.H"
+
+class FL_EXPORT Fl_Text_Display: public Fl_Group {
+  public:
+    enum {
+      NORMAL_CURSOR, CARET_CURSOR, DIM_CURSOR,
+      BLOCK_CURSOR, HEAVY_CURSOR
+    };
+
+    enum {
+      CURSOR_POS, CHARACTER_POS
+    };
+
+    // drag types- they match Fl::event_clicks() so that single clicking to
+    // start a collection selects by character, double clicking selects by
+    // word and triple clicking selects by line.
+    enum {
+      DRAG_CHAR = 0, DRAG_WORD = 1, DRAG_LINE = 2
+    };
+    friend void fl_text_drag_me(int pos, Fl_Text_Display* d);
+
+    typedef void (*Unfinished_Style_Cb)(int, void *);
+
+    // style attributes - currently not implemented!
+    enum {
+      ATTR_NONE = 0,
+      ATTR_UNDERLINE = 1,
+      ATTR_HIDDEN = 2
+    };
+
+    struct Style_Table_Entry {
+      Fl_Color	color;
+      Fl_Font	font;
+      int	size;
+      unsigned	attr;
+    };
+
+    Fl_Text_Display(int X, int Y, int W, int H, const char *l = 0);
+    ~Fl_Text_Display();
+
+    virtual int handle(int e);
+    void buffer(Fl_Text_Buffer* buf);
+    void buffer(Fl_Text_Buffer& buf) { buffer(&buf); }
+    Fl_Text_Buffer* buffer() { return mBuffer; }
+    void redisplay_range(int start, int end);
+    void scroll(int topLineNum, int horizOffset);
+    void insert(const char* text);
+    void overstrike(const char* text);
+    void insert_position(int newPos);
+    int insert_position() { return mCursorPos; }
+    int in_selection(int x, int y);
+    void show_insert_position();
+    int move_right();
+    int move_left();
+    int move_up();
+    int move_down();
+    int count_lines(int start, int end, bool start_pos_is_line_start);
+    int line_start(int pos);
+    int line_end(int pos, bool start_pos_is_line_start);
+    int skip_lines(int startPos, int nLines, bool startPosIsLineStart);
+    int rewind_lines(int startPos, int nLines);
+    void next_word(void);
+    void previous_word(void);
+    void show_cursor(int b = 1);
+    void hide_cursor() { show_cursor(0); }
+    void cursor_style(int style);
+    Fl_Color cursor_color() const {return mCursor_color;}
+    void cursor_color(Fl_Color n) {mCursor_color = n;}
+    int scrollbar_width() { return scrollbar_width_; }
+    Fl_Align scrollbar_align() { return scrollbar_align_; }
+    void scrollbar_width(int W) { scrollbar_width_ = W; }
+    void scrollbar_align(Fl_Align a) { scrollbar_align_ = a; }
+    int word_start(int pos) { return buffer()->word_start(pos); }
+    int word_end(int pos) { return buffer()->word_end(pos); }
+
+    
+    void highlight_data(Fl_Text_Buffer *styleBuffer,
+                        const Style_Table_Entry *styleTable,
+                        int nStyles, char unfinishedStyle,
+                        Unfinished_Style_Cb unfinishedHighlightCB,
+                        void *cbArg);
+
+    int position_style(int lineStartPos, int lineLen, int lineIndex,
+                       int dispIndex);
+
+    Fl_Font textfont() const {return (Fl_Font)textfont_;}
+    void textfont(uchar s) {textfont_ = s;}
+    uchar textsize() const {return textsize_;}
+    void textsize(uchar s) {textsize_ = s;}
+    Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+    void textcolor(unsigned n) {textcolor_ = n;}
+
+    int wrapped_column(int row, int column);
+    int wrapped_row(int row);
+    void wrap_mode(int wrap, int wrap_margin);
+
+    virtual void resize(int X, int Y, int W, int H);
+
+  protected:
+    // Most (all?) of this stuff should only be called from resize() or
+    // draw().
+    // Anything with "vline" indicates thats it deals with currently
+    // visible lines.
+
+    virtual void draw();
+    void draw_text(int X, int Y, int W, int H);
+    void draw_range(int start, int end);
+    void draw_cursor(int, int);
+
+    void draw_string(int style, int x, int y, int toX, const char *string,
+                     int nChars);
+
+    void draw_vline(int visLineNum, int leftClip, int rightClip,
+                    int leftCharIndex, int rightCharIndex);
+
+    void draw_line_numbers(bool clearAll);
+
+    void clear_rect(int style, int x, int y, int width, int height);
+    void display_insert();
+
+    void offset_line_starts(int newTopLineNum);
+
+    void calc_line_starts(int startLine, int endLine);
+
+    void update_line_starts(int pos, int charsInserted, int charsDeleted,
+                            int linesInserted, int linesDeleted, int *scrolled);
+
+    void calc_last_char();
+
+    int position_to_line( int pos, int* lineNum );
+    int string_width(const char* string, int length, int style);
+
+    static void scroll_timer_cb(void*);
+
+    static void buffer_predelete_cb(int pos, int nDeleted, void* cbArg);
+    static void buffer_modified_cb(int pos, int nInserted, int nDeleted,
+                                   int nRestyled, const char* deletedText,
+                                   void* cbArg);
+
+    static void h_scrollbar_cb(Fl_Scrollbar* w, Fl_Text_Display* d);
+    static void v_scrollbar_cb( Fl_Scrollbar* w, Fl_Text_Display* d);
+    void update_v_scrollbar();
+    void update_h_scrollbar();
+    int measure_vline(int visLineNum);
+    int longest_vline();
+    int empty_vlines();
+    int vline_length(int visLineNum);
+    int xy_to_position(int x, int y, int PosType = CHARACTER_POS);
+
+    void xy_to_rowcol(int x, int y, int* row, int* column,
+                      int PosType = CHARACTER_POS);
+
+    int position_to_xy(int pos, int* x, int* y);
+    void maintain_absolute_top_line_number(int state);
+    int get_absolute_top_line_number();
+    void absolute_top_line_number(int oldFirstChar);
+    int maintaining_absolute_top_line_number();
+    void reset_absolute_top_line_number();
+    int position_to_linecol(int pos, int* lineNum, int* column);
+    void scroll_(int topLineNum, int horizOffset);
+
+    void extend_range_for_styles(int* start, int* end);
+
+    void find_wrap_range(const char *deletedText, int pos, int nInserted,
+                           int nDeleted, int *modRangeStart, int *modRangeEnd,
+                           int *linesInserted, int *linesDeleted);
+    void measure_deleted_lines(int pos, int nDeleted);
+    void wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, int maxPos,
+                               int maxLines, bool startPosIsLineStart,
+                               int styleBufOffset, int *retPos, int *retLines,
+                               int *retLineStart, int *retLineEnd,
+                               bool countLastLineMissingNewLine = true);
+    void find_line_end(int pos, bool start_pos_is_line_start, int *lineEnd,
+                         int *nextLineStart);
+    int measure_proportional_character(char c, int colNum, int pos);
+    int wrap_uses_character(int lineEndPos);
+    int range_touches_selection(Fl_Text_Selection *sel, int rangeStart,
+                                 int rangeEnd);
+
+    int damage_range1_start, damage_range1_end;
+    int damage_range2_start, damage_range2_end;
+    int mCursorPos;
+    int mCursorOn;
+    int mCursorOldY;		/* Y pos. of cursor for blanking */
+    int mCursorToHint;		/* Tells the buffer modified callback
+                                   where to move the cursor, to reduce
+                                   the number of redraw calls */
+    int mCursorStyle;           /* One of enum cursorStyles above */
+    int mCursorPreferredCol;    /* Column for vert. cursor movement */
+    int mNVisibleLines;         /* # of visible (displayed) lines */
+    int mNBufferLines;          /* # of newlines in the buffer */
+    Fl_Text_Buffer* mBuffer;    /* Contains text to be displayed */
+    Fl_Text_Buffer* mStyleBuffer; /* Optional parallel buffer containing
+                                     color and font information */
+    int mFirstChar, mLastChar;  /* Buffer positions of first and last
+                                   displayed character (lastChar points
+                                   either to a newline or one character
+                                   beyond the end of the buffer) */
+    int mContinuousWrap;     	  /* Wrap long lines when displaying */
+    int mWrapMargin; 	    	  /* Margin in # of char positions for
+    	    	    	    	    	   wrapping in continuousWrap mode */
+    int* mLineStarts;
+    int mTopLineNum;            /* Line number of top displayed line
+                                   of file (first line of file is 1) */
+    int mAbsTopLineNum;			/* In continuous wrap mode, the line
+    					   number of the top line if the text
+					   were not wrapped (note that this is
+					   only maintained as needed). */
+    int mNeedAbsTopLineNum;	/* Externally settable flag to continue
+    					   maintaining absTopLineNum even if
+					   it isn't needed for line # display */
+    int mHorizOffset;           /* Horizontal scroll pos. in pixels */
+    int mTopLineNumHint;        /* Line number of top displayed line
+                                   of file (first line of file is 1) */
+    int mHorizOffsetHint;       /* Horizontal scroll pos. in pixels */
+    int mNStyles;               /* Number of entries in styleTable */
+    const Style_Table_Entry *mStyleTable; /* Table of fonts and colors for
+                                   coloring/syntax-highlighting */
+    char mUnfinishedStyle;      /* Style buffer entry which triggers
+                                   on-the-fly reparsing of region */
+    Unfinished_Style_Cb mUnfinishedHighlightCB; /* Callback to parse "unfinished" */
+                                /* regions */
+    void* mHighlightCBArg;      /* Arg to unfinishedHighlightCB */
+
+    int mMaxsize;
+
+    int mFixedFontWidth;        /* Font width if all current fonts are
+                                   fixed and match in width, else -1 */
+    int mSuppressResync;		/* Suppress resynchronization of line
+                                           starts during buffer updates */
+    int mNLinesDeleted;			/* Number of lines deleted during
+					   buffer modification (only used
+				           when resynchronization is suppressed) */
+    int mModifyingTabDistance;	/* Whether tab distance is being
+    					   modified */
+
+    Fl_Color mCursor_color;
+
+    Fl_Scrollbar* mHScrollBar;
+    Fl_Scrollbar* mVScrollBar;
+    int scrollbar_width_;
+    Fl_Align scrollbar_align_;
+    int dragPos, dragType, dragging;
+    int display_insert_position_hint;
+    struct { int x, y, w, h; } text_area;
+
+    uchar textfont_;
+    uchar textsize_;
+    unsigned textcolor_;
+
+	 // The following are not presently used from the original NEdit code,
+	 // but are being put here so that future versions of Fl_Text_Display
+	 // can implement line numbers without breaking binary compatibility.
+    int mLineNumLeft, mLineNumWidth;
+				/* Line number margin and width */
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Text_Display.H 4502 2005-08-10 23:11:51Z matt $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Text_Editor.H b/Utilities/FLTK/FL/Fl_Text_Editor.H
new file mode 100644
index 0000000000000000000000000000000000000000..81782f12086e3a965b72b13fba2f9210f62cbec2
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Text_Editor.H
@@ -0,0 +1,110 @@
+//
+// "$Id: Fl_Text_Editor.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Header file for Fl_Text_Editor class.
+//
+// Copyright 2001-2005 by Bill Spitzak and others.
+// Original code Copyright Mark Edel.  Permission to distribute under
+// the LGPL for the FLTK library granted by Mark Edel.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+
+#ifndef FL_TEXT_EDITOR_H
+#define FL_TEXT_EDITOR_H
+
+#include "Fl_Text_Display.H"
+
+// key will match in any state
+#define FL_TEXT_EDITOR_ANY_STATE  (-1L)
+
+class FL_EXPORT Fl_Text_Editor : public Fl_Text_Display {
+  public:
+    typedef int (*Key_Func)(int key, Fl_Text_Editor* editor);
+
+    struct Key_Binding {
+      int          key;
+      int          state;
+      Key_Func     function;
+      Key_Binding* next;
+    };
+
+    Fl_Text_Editor(int X, int Y, int W, int H, const char* l = 0);
+    ~Fl_Text_Editor() { remove_all_key_bindings(); }
+    virtual int handle(int e);
+    void insert_mode(int b) { insert_mode_ = b; }
+    int insert_mode() { return insert_mode_; }
+
+    void add_key_binding(int key, int state, Key_Func f, Key_Binding** list);
+    void add_key_binding(int key, int state, Key_Func f)
+      { add_key_binding(key, state, f, &key_bindings); }
+    void remove_key_binding(int key, int state, Key_Binding** list);
+    void remove_key_binding(int key, int state)
+      { remove_key_binding(key, state, &key_bindings); }
+    void remove_all_key_bindings(Key_Binding** list);
+    void remove_all_key_bindings() { remove_all_key_bindings(&key_bindings); }
+    void add_default_key_bindings(Key_Binding** list);
+    Key_Func bound_key_function(int key, int state, Key_Binding* list);
+    Key_Func bound_key_function(int key, int state)
+      { return bound_key_function(key, state, key_bindings); }
+    void default_key_function(Key_Func f) { default_key_function_ = f; }
+
+    // functions for the built in default bindings
+    static int kf_default(int c, Fl_Text_Editor* e);
+    static int kf_ignore(int c, Fl_Text_Editor* e);
+    static int kf_backspace(int c, Fl_Text_Editor* e);
+    static int kf_enter(int c, Fl_Text_Editor* e);
+    static int kf_move(int c, Fl_Text_Editor* e);
+    static int kf_shift_move(int c, Fl_Text_Editor* e);
+    static int kf_ctrl_move(int c, Fl_Text_Editor* e);
+    static int kf_c_s_move(int c, Fl_Text_Editor* e);
+    static int kf_home(int, Fl_Text_Editor* e);
+    static int kf_end(int c, Fl_Text_Editor* e);
+    static int kf_left(int c, Fl_Text_Editor* e);
+    static int kf_up(int c, Fl_Text_Editor* e);
+    static int kf_right(int c, Fl_Text_Editor* e);
+    static int kf_down(int c, Fl_Text_Editor* e);
+    static int kf_page_up(int c, Fl_Text_Editor* e);
+    static int kf_page_down(int c, Fl_Text_Editor* e);
+    static int kf_insert(int c, Fl_Text_Editor* e);
+    static int kf_delete(int c, Fl_Text_Editor* e);
+    static int kf_copy(int c, Fl_Text_Editor* e);
+    static int kf_cut(int c, Fl_Text_Editor* e);
+    static int kf_paste(int c, Fl_Text_Editor* e);
+    static int kf_select_all(int c, Fl_Text_Editor* e);
+    static int kf_undo(int c, Fl_Text_Editor* e);
+
+  protected:
+    int handle_key();
+    void maybe_do_callback();
+
+    int insert_mode_;
+    Key_Binding* key_bindings;
+    static Key_Binding* global_key_bindings;
+    Key_Func default_key_function_;
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Text_Editor.H 4288 2005-04-16 00:13:17Z mike $".
+//
+
diff --git a/Utilities/FLTK/FL/Fl_Tile.H b/Utilities/FLTK/FL/Fl_Tile.H
new file mode 100644
index 0000000000000000000000000000000000000000..69250f8b9780c77401314fd1cc831e64b2216afc
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Tile.H
@@ -0,0 +1,45 @@
+//
+// "$Id: Fl_Tile.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Tile header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Tile_H
+#define Fl_Tile_H
+
+#include "Fl_Group.H"
+
+class FL_EXPORT Fl_Tile : public Fl_Group {
+public:
+  int handle(int);
+  Fl_Tile(int X,int Y,int W,int H,const char*l=0) : Fl_Group(X,Y,W,H,l) {}
+  void resize(int, int, int, int);
+  void position(int, int, int, int);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Tile.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Tiled_Image.H b/Utilities/FLTK/FL/Fl_Tiled_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..4af8a9d859afc6b7ae7d489fd926af051944cb0d
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Tiled_Image.H
@@ -0,0 +1,59 @@
+//
+// "$Id: Fl_Tiled_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Tiled image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Tiled_Image_H
+#  define Fl_Tiled_Image_H
+
+#  include "Fl_Image.H"
+
+
+// Tiled image class. 
+class FL_EXPORT Fl_Tiled_Image : public Fl_Image {
+  protected:
+
+  Fl_Image	*image_;		// The image that is shared
+  int		alloc_image_;		// Did we allocate this image?
+
+  public:
+
+  Fl_Tiled_Image(Fl_Image *i, int W = 0, int H = 0);
+  virtual ~Fl_Tiled_Image();
+
+  virtual Fl_Image *copy(int W, int H);
+  Fl_Image *copy() { return copy(w(), h()); }
+  virtual void color_average(Fl_Color c, float i);
+  virtual void desaturate();
+  virtual void draw(int X, int Y, int W, int H, int cx, int cy);
+  void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); }
+  Fl_Image *image() { return image_; }
+};
+
+#endif // !Fl_Tiled_Image_H
+
+//
+// End of "$Id: Fl_Tiled_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
diff --git a/Utilities/FLTK/FL/Fl_Timer.H b/Utilities/FLTK/FL/Fl_Timer.H
new file mode 100644
index 0000000000000000000000000000000000000000..765afdbf802e74eecd76a13c434038741f3c7b76
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Timer.H
@@ -0,0 +1,65 @@
+//
+// "$Id: Fl_Timer.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Timer header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Timer_H
+#define Fl_Timer_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type():
+#define FL_NORMAL_TIMER		0
+#define FL_VALUE_TIMER		1
+#define FL_HIDDEN_TIMER		2
+
+class FL_EXPORT Fl_Timer : public Fl_Widget {
+  static void stepcb(void *);
+  void step();
+  char on, direction_;
+  double delay, total;
+  long lastsec,lastusec;
+protected:
+  void draw();
+public:
+  int handle(int);
+  Fl_Timer(uchar t,int x,int y,int w,int h, const char *l);
+  ~Fl_Timer();
+  void value(double);
+  double value() const {return delay>0.0?delay:0.0;}
+  char direction() const {return direction_;}
+  void direction(char d) {direction_ = d;}
+  char suspended() const {return !on;}
+  void suspended(char d);
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Timer.H 4288 2005-04-16 00:13:17Z mike $".
+//
+
diff --git a/Utilities/FLTK/FL/Fl_Toggle_Button.H b/Utilities/FLTK/FL/Fl_Toggle_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..b7764c5c010c87ee3d400d159ffe7357917509ef
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Toggle_Button.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_Toggle_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Toggle button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Toggle_Button_H
+#define Fl_Toggle_Button_H
+
+#include "Fl_Button.H"
+
+class Fl_Toggle_Button : public Fl_Button {
+public:
+    Fl_Toggle_Button(int X,int Y,int W,int H,const char *l=0)
+	: Fl_Button(X,Y,W,H,l) {type(FL_TOGGLE_BUTTON);}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Toggle_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Toggle_Light_Button.H b/Utilities/FLTK/FL/Fl_Toggle_Light_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..be9e8a6f27eb220b007b4d18814e91d9607a4a0c
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Toggle_Light_Button.H
@@ -0,0 +1,37 @@
+//
+// "$Id: Fl_Toggle_Light_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Toggle light button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// provided for back-compatability only
+
+#ifndef Fl_Toggle_Light_Button
+#include "Fl_Light_Button.H"
+#define Fl_Toggle_Light_Button Fl_Light_Button
+#endif
+
+//
+// End of "$Id: Fl_Toggle_Light_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Toggle_Round_Button.H b/Utilities/FLTK/FL/Fl_Toggle_Round_Button.H
new file mode 100644
index 0000000000000000000000000000000000000000..087ad8e5fb671a30568b50299a5b8ccd9c2c4f79
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Toggle_Round_Button.H
@@ -0,0 +1,37 @@
+//
+// "$Id: Fl_Toggle_Round_Button.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Toggle round button header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// provided for back-compatability only
+
+#ifndef Fl_Toggle_Round_Button
+#include "Fl_Round_Button.H"
+#define Fl_Toggle_Round_Button Fl_Round_Button
+#endif
+
+//
+// End of "$Id: Fl_Toggle_Round_Button.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Tooltip.H b/Utilities/FLTK/FL/Fl_Tooltip.H
new file mode 100644
index 0000000000000000000000000000000000000000..28fb69a238de64ab31bcba4229462137668d0922
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Tooltip.H
@@ -0,0 +1,77 @@
+//
+// "$Id: Fl_Tooltip.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Tooltip header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Tooltip_H
+#define Fl_Tooltip_H
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+
+class FL_EXPORT Fl_Tooltip {
+public:
+  static float delay() { return delay_; }
+  static void delay(float f) { delay_ = f; }
+  static float hoverdelay() { return hoverdelay_; }
+  static void hoverdelay(float f) { hoverdelay_ = f; }
+  static int enabled() { return enabled_; }
+  static void enable(int b = 1) { enabled_ = b;}
+  static void disable() { enabled_ = 0; }
+  static void (*enter)(Fl_Widget* w);
+  static void enter_area(Fl_Widget* w, int X, int Y, int W, int H, const char* tip);
+  static void (*exit)(Fl_Widget *w);
+  static Fl_Widget* current() {return widget_;}
+  static void current(Fl_Widget*);
+
+  static int font() { return font_; }
+  static int size() { return size_; }
+  static void font(int i) { font_ = i; }
+  static void size(int s) { size_ = s; }
+  static void color(unsigned c) { color_ = c; }
+  static Fl_Color color() { return (Fl_Color)color_; }
+  static void textcolor(unsigned c) { textcolor_ = c; }
+  static Fl_Color textcolor() { return (Fl_Color)textcolor_; }
+
+  // These should not be public, but Fl_Widget::tooltip() needs them...
+  static void enter_(Fl_Widget* w);
+  static void exit_(Fl_Widget *w);
+
+private:
+  static float delay_;
+  static float hoverdelay_;
+  static int enabled_;
+  static unsigned color_;
+  static unsigned textcolor_;
+  static int font_;
+  static int size_;
+  static Fl_Widget* widget_;
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Tooltip.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Valuator.H b/Utilities/FLTK/FL/Fl_Valuator.H
new file mode 100644
index 0000000000000000000000000000000000000000..b2cd601494dba18919b9e52975582f73d16575bb
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Valuator.H
@@ -0,0 +1,86 @@
+//
+// "$Id: Fl_Valuator.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Valuator header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Valuator_H
+#define Fl_Valuator_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// shared type() values for classes that work in both directions:
+#define FL_VERTICAL		0
+#define FL_HORIZONTAL		1
+
+class FL_EXPORT Fl_Valuator : public Fl_Widget {
+
+  double value_;
+  double previous_value_;
+  double min, max; // truncates to this range *after* rounding
+  double A; int B; // rounds to multiples of A/B, or no rounding if A is zero
+
+protected:
+
+  int horizontal() const {return type()&1;}
+  Fl_Valuator(int X, int Y, int W, int H, const char* L);
+
+  double previous_value() const {return previous_value_;}
+  void handle_push() {previous_value_ = value_;}
+  double softclamp(double);
+  void handle_drag(double newvalue);
+  void handle_release(); // use drag() value
+  virtual void value_damage(); // cause damage() due to value() changing
+  void set_value(double v) {value_ = v;}
+
+public:
+
+  void bounds(double a, double b) {min=a; max=b;}
+  double minimum() const {return min;}
+  void minimum(double a) {min = a;}
+  double maximum() const {return max;}
+  void maximum(double a) {max = a;}
+  void range(double a, double b) {min = a; max = b;}
+  void step(int a) {A = a; B = 1;}
+  void step(double a, int b) {A = a; B = b;}
+  void step(double s);
+  double step() const {return A/B;}
+  void precision(int);
+
+  double value() const {return value_;}
+  int value(double);
+
+  virtual int format(char*);
+  double round(double); // round to nearest multiple of step
+  double clamp(double); // keep in range
+  double increment(double, int); // add n*step to value
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Valuator.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Value_Input.H b/Utilities/FLTK/FL/Fl_Value_Input.H
new file mode 100644
index 0000000000000000000000000000000000000000..78dc2111568465431525e3411f317d182dc31670
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Value_Input.H
@@ -0,0 +1,65 @@
+//
+// "$Id: Fl_Value_Input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Value input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Value_Input_H
+#define Fl_Value_Input_H
+
+#include "Fl_Valuator.H"
+#include "Fl_Input.H"
+
+class FL_EXPORT Fl_Value_Input : public Fl_Valuator {
+public:
+  Fl_Input input;
+private:
+  char soft_;
+  static void input_cb(Fl_Widget*,void*);
+  virtual void value_damage(); // cause damage() due to value() changing
+public:
+  int handle(int);
+  void draw();
+  void resize(int,int,int,int);
+  Fl_Value_Input(int x,int y,int w,int h,const char *l=0);
+
+  void soft(char s) {soft_ = s;}
+  char soft() const {return soft_;}
+
+  Fl_Font textfont() const {return input.textfont();}
+  void textfont(uchar s) {input.textfont(s);}
+  uchar textsize() const {return input.textsize();}
+  void textsize(uchar s) {input.textsize(s);}
+  Fl_Color textcolor() const {return input.textcolor();}
+  void textcolor(unsigned n) {input.textcolor(n);}
+  Fl_Color cursor_color() const {return input.cursor_color();}
+  void cursor_color(unsigned n) {input.cursor_color(n);}
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Value_Input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Value_Output.H b/Utilities/FLTK/FL/Fl_Value_Output.H
new file mode 100644
index 0000000000000000000000000000000000000000..3353e885c44f42297404049444871dc919790d3f
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Value_Output.H
@@ -0,0 +1,58 @@
+//
+// "$Id: Fl_Value_Output.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Value output header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Value_Output_H
+#define Fl_Value_Output_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+class FL_EXPORT Fl_Value_Output : public Fl_Valuator {
+  uchar textfont_, textsize_, soft_;
+  unsigned textcolor_;
+public:
+  int handle(int);
+  void draw();
+  Fl_Value_Output(int x,int y,int w,int h,const char *l=0);
+
+  void soft(uchar s) {soft_ = s;}
+  uchar soft() const {return soft_;}
+
+  Fl_Font textfont() const {return (Fl_Font)textfont_;}
+  void textfont(uchar s) {textfont_ = s;}
+  uchar textsize() const {return textsize_;}
+  void textsize(uchar s) {textsize_ = s;}
+  Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+  void textcolor(unsigned s) {textcolor_ = s;}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Value_Output.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Value_Slider.H b/Utilities/FLTK/FL/Fl_Value_Slider.H
new file mode 100644
index 0000000000000000000000000000000000000000..5162e8a3fab51f9b8ca72a9641fa8ca5759a58e2
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Value_Slider.H
@@ -0,0 +1,52 @@
+//
+// "$Id: Fl_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Value slider header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Value_Slider_H
+#define Fl_Value_Slider_H
+
+#include "Fl_Slider.H"
+
+class FL_EXPORT Fl_Value_Slider : public Fl_Slider {
+    uchar textfont_, textsize_;
+    unsigned textcolor_;
+public:
+    void draw();
+    int handle(int);
+    Fl_Value_Slider(int x,int y,int w,int h, const char *l = 0);
+    Fl_Font textfont() const {return (Fl_Font)textfont_;}
+    void textfont(uchar s) {textfont_ = s;}
+    uchar textsize() const {return textsize_;}
+    void textsize(uchar s) {textsize_ = s;}
+    Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+    void textcolor(unsigned s) {textcolor_ = s;}
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Widget.H b/Utilities/FLTK/FL/Fl_Widget.H
new file mode 100644
index 0000000000000000000000000000000000000000..a86556ca94aab47e3aa2e758b03edf7891986a97
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Widget.H
@@ -0,0 +1,220 @@
+//
+// "$Id: Fl_Widget.H 4421 2005-07-15 09:34:53Z matt $"
+//
+// Widget header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Widget_H
+#define Fl_Widget_H
+
+#include "Enumerations.H"
+
+class Fl_Widget;
+class Fl_Window;
+class Fl_Group;
+class Fl_Image;
+
+typedef void (Fl_Callback )(Fl_Widget*, void*);
+typedef Fl_Callback* Fl_Callback_p; // needed for BORLAND
+typedef void (Fl_Callback0)(Fl_Widget*);
+typedef void (Fl_Callback1)(Fl_Widget*, long);
+
+struct FL_EXPORT Fl_Label {
+  const char* value;
+  Fl_Image* image;
+  Fl_Image* deimage;
+  uchar type;
+  uchar font;
+  uchar size;
+  unsigned color;
+  void draw(int,int,int,int, Fl_Align) const ;
+  void measure(int&, int&) const ;
+};
+
+class FL_EXPORT Fl_Widget {
+  friend class Fl_Group;
+
+  Fl_Group* parent_;
+  Fl_Callback* callback_;
+  void* user_data_;
+  short x_,y_,w_,h_;
+  Fl_Label label_;
+  int flags_;
+  unsigned color_;
+  unsigned color2_;
+  uchar type_;
+  uchar damage_;
+  uchar box_;
+  uchar align_;
+  uchar when_;
+
+  const char *tooltip_;
+
+  // unimplemented copy ctor and assignment operator
+  Fl_Widget(const Fl_Widget &);
+  Fl_Widget& operator=(const Fl_Widget &);
+
+protected:
+
+  Fl_Widget(int,int,int,int,const char* =0);
+
+  void x(int v) {x_ = (short)v;}
+  void y(int v) {y_ = (short)v;}
+  void w(int v) {w_ = (short)v;}
+  void h(int v) {h_ = (short)v;}
+
+  int flags() const {return flags_;}
+  void set_flag(int c) {flags_ |= c;}
+  void clear_flag(int c) {flags_ &= ~c;}
+  enum {INACTIVE=1, INVISIBLE=2, OUTPUT=4, SHORTCUT_LABEL=64,
+        CHANGED=128, VISIBLE_FOCUS=512, COPIED_LABEL = 1024};
+
+  void draw_box() const;
+  void draw_box(Fl_Boxtype, Fl_Color) const;
+  void draw_box(Fl_Boxtype, int,int,int,int, Fl_Color) const;
+  void draw_focus() {draw_focus(box(),x(),y(),w(),h());}
+  void draw_focus(Fl_Boxtype, int,int,int,int) const;
+  void draw_label() const;
+  void draw_label(int, int, int, int) const;
+
+public:
+
+  virtual ~Fl_Widget();
+
+  virtual void draw() = 0;
+  virtual int handle(int);
+  Fl_Group* parent() const {return parent_;}
+  void parent(Fl_Group* p) {parent_ = p;} // for hacks only, Fl_Group::add()
+
+  uchar type() const {return type_;}
+  void type(uchar t) {type_ = t;}
+
+  int x() const {return x_;}
+  int y() const {return y_;}
+  int w() const {return w_;}
+  int h() const {return h_;}
+  virtual void resize(int,int,int,int);
+  int damage_resize(int,int,int,int);
+  void position(int X,int Y) {resize(X,Y,w_,h_);}
+  void size(int W,int H) {resize(x_,y_,W,H);}
+
+  Fl_Align align() const {return (Fl_Align)align_;}
+  void align(uchar a) {align_ = a;}
+  Fl_Boxtype box() const {return (Fl_Boxtype)box_;}
+  void box(Fl_Boxtype a) {box_ = a;}
+  Fl_Color color() const {return (Fl_Color)color_;}
+  void color(unsigned a) {color_ = a;}
+  Fl_Color selection_color() const {return (Fl_Color)color2_;}
+  void selection_color(unsigned a) {color2_ = a;}
+  void color(unsigned a, unsigned b) {color_=a; color2_=b;}
+  const char* label() const {return label_.value;}
+  void label(const char* a);
+  void copy_label(const char* a);
+  void label(Fl_Labeltype a,const char* b) {label_.type = a; label_.value = b;}
+  Fl_Labeltype labeltype() const {return (Fl_Labeltype)label_.type;}
+  void labeltype(Fl_Labeltype a) {label_.type = a;}
+  Fl_Color labelcolor() const {return (Fl_Color)label_.color;}
+  void labelcolor(unsigned a) {label_.color=a;}
+  Fl_Font labelfont() const {return (Fl_Font)label_.font;}
+  void labelfont(uchar a) {label_.font=a;}
+  uchar labelsize() const {return label_.size;}
+  void labelsize(uchar a) {label_.size=a;}
+  Fl_Image* image() {return label_.image;}
+  void image(Fl_Image* a) {label_.image=a;}
+  void image(Fl_Image& a) {label_.image=&a;}
+  Fl_Image* deimage() {return label_.deimage;}
+  void deimage(Fl_Image* a) {label_.deimage=a;}
+  void deimage(Fl_Image& a) {label_.deimage=&a;}
+  const char *tooltip() const {return tooltip_;}
+  void tooltip(const char *t);
+  Fl_Callback_p callback() const {return callback_;}
+  void callback(Fl_Callback* c, void* p) {callback_=c; user_data_=p;}
+  void callback(Fl_Callback* c) {callback_=c;}
+  void callback(Fl_Callback0*c) {callback_=(Fl_Callback*)c;}
+  void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;}
+  void* user_data() const {return user_data_;}
+  void user_data(void* v) {user_data_ = v;}
+  long argument() const {return (long)user_data_;}
+  void argument(long v) {user_data_ = (void*)v;}
+  Fl_When when() const {return (Fl_When)when_;}
+  void when(uchar i) {when_ = i;}
+
+  int visible() const {return !(flags_&INVISIBLE);}
+  int visible_r() const;
+  void show();
+  void hide();
+  void set_visible() {flags_ &= ~INVISIBLE;}
+  void clear_visible() {flags_ |= INVISIBLE;}
+  int active() const {return !(flags_&INACTIVE);}
+  int active_r() const;
+  void activate();
+  void deactivate();
+  int output() const {return (flags_&OUTPUT);}
+  void set_output() {flags_ |= OUTPUT;}
+  void clear_output() {flags_ &= ~OUTPUT;}
+  int takesevents() const {return !(flags_&(INACTIVE|INVISIBLE|OUTPUT));}
+  int changed() const {return flags_&CHANGED;}
+  void set_changed() {flags_ |= CHANGED;}
+  void clear_changed() {flags_ &= ~CHANGED;}
+  int take_focus();
+  void set_visible_focus() { flags_ |= VISIBLE_FOCUS; }
+  void clear_visible_focus() { flags_ &= ~VISIBLE_FOCUS; }
+  void visible_focus(int v) { if (v) set_visible_focus(); else clear_visible_focus(); }
+  int  visible_focus() { return flags_ & VISIBLE_FOCUS; }
+
+  static void default_callback(Fl_Widget*, void*);
+  void do_callback() {callback_(this,user_data_); if (callback_ != default_callback) clear_changed();}
+  void do_callback(Fl_Widget* o,void* arg=0) {callback_(o,arg); if (callback_ != default_callback) clear_changed();}
+  void do_callback(Fl_Widget* o,long arg) {callback_(o,(void*)arg); if (callback_ != default_callback) clear_changed();}
+  int test_shortcut();
+  static int test_shortcut(const char*);
+  int contains(const Fl_Widget*) const ;
+  int inside(const Fl_Widget* o) const {return o ? o->contains(this) : 0;}
+
+  void redraw();
+  void redraw_label();
+  uchar damage() const {return damage_;}
+  void clear_damage(uchar c = 0) {damage_ = c;}
+  void damage(uchar c);
+  void damage(uchar c,int,int,int,int);
+  void draw_label(int, int, int, int, Fl_Align) const;
+  void measure_label(int& xx, int& yy) {label_.measure(xx,yy);}
+
+  Fl_Window* window() const ;
+
+  // back compatability only:
+  Fl_Color color2() const {return (Fl_Color)color2_;}
+  void color2(unsigned a) {color2_ = a;}
+};
+
+// reserved type numbers (necessary for my cheapo RTTI) start here.
+// grep the header files for "RESERVED_TYPE" to find the next available
+// number.
+#define FL_RESERVED_TYPE 100
+
+#endif
+
+//
+// End of "$Id: Fl_Widget.H 4421 2005-07-15 09:34:53Z matt $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Window.H b/Utilities/FLTK/FL/Fl_Window.H
new file mode 100644
index 0000000000000000000000000000000000000000..16a02259e87aa4511bca2b3766c6be4cff55a7db
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Window.H
@@ -0,0 +1,135 @@
+//
+// "$Id: Fl_Window.H 4421 2005-07-15 09:34:53Z matt $"
+//
+// Window header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_Window_H
+#define Fl_Window_H
+
+#include "Fl_Group.H"
+
+#define FL_WINDOW 0xF0	// all subclasses have type() >= this
+#define FL_DOUBLE_WINDOW 0xF1
+
+class Fl_X;
+
+class FL_EXPORT Fl_Window : public Fl_Group {
+
+  friend class Fl_X;
+  Fl_X *i; // points at the system-specific stuff
+
+  const char* iconlabel_;
+  const char* xclass_;
+  const void* icon_;
+  // size_range stuff:
+  short minw, minh, maxw, maxh;
+  uchar dw, dh, aspect, size_range_set;
+  // cursor stuff
+  Fl_Cursor cursor_default;
+  Fl_Color cursor_fg, cursor_bg;
+  void size_range_();
+  // values for flags():
+  enum {
+    FL_MODAL = 64,
+    FL_NOBORDER = 8,
+    FL_FORCE_POSITION = 16,
+    FL_NON_MODAL = 32,
+    FL_OVERRIDE = 256
+  };
+  void _Fl_Window(); // constructor innards
+
+  // unimplemented copy ctor and assignment operator
+  Fl_Window(const Fl_Window&);
+  Fl_Window& operator=(const Fl_Window&);
+
+protected:
+
+  static Fl_Window *current_;
+  virtual void draw();
+  virtual void flush();
+
+public:
+
+  Fl_Window(int,int,int,int, const char* = 0);
+  Fl_Window(int,int, const char* = 0);
+  virtual ~Fl_Window();
+
+  virtual int handle(int);
+
+  virtual void resize(int,int,int,int);
+  void border(int b);
+  void clear_border()	{set_flag(FL_NOBORDER);}
+  int border() const	{return !(flags() & FL_NOBORDER);}
+  void set_override()	{set_flag(FL_NOBORDER|FL_OVERRIDE);}
+  int override() const  { return flags()&FL_OVERRIDE; }
+  void set_modal()	{set_flag(FL_MODAL);}
+  int modal() const	{return flags() & FL_MODAL;}
+  void set_non_modal()	{set_flag(FL_NON_MODAL);}
+  int non_modal() const {return flags() & (FL_NON_MODAL|FL_MODAL);}
+
+  void hotspot(int x, int y, int offscreen = 0);
+  void hotspot(const Fl_Widget*, int offscreen = 0);
+  void hotspot(const Fl_Widget& p, int offscreen = 0) {hotspot(&p,offscreen);}
+  void free_position()	{clear_flag(FL_FORCE_POSITION);}
+  void size_range(int a, int b, int c=0, int d=0, int e=0, int f=0, int g=0) {
+    minw=(short)a; minh=(short)b; maxw=(short)c; maxh=(short)d; dw=(uchar)e; dh=(uchar)f; aspect=(uchar)g; size_range_();}
+
+  const char* label() const	{return Fl_Widget::label();}
+  const char* iconlabel() const	{return iconlabel_;}
+  void label(const char*);
+  void iconlabel(const char*);
+  void label(const char* label, const char* iconlabel);
+  void copy_label(const char* a);
+  const char* xclass() const	{return xclass_;}
+  void xclass(const char* c)	{xclass_ = c;}
+  const void* icon() const	{return icon_;}
+  void icon(const void * ic)	{icon_ = ic;}
+
+  int shown() {return i != 0;}
+  virtual void show();
+  virtual void hide();
+  void show(int, char**);
+  void fullscreen();
+  void fullscreen_off(int,int,int,int);
+  void iconize();
+
+  int x_root() const ;
+  int y_root() const ;
+
+  static Fl_Window *current();
+  void make_current();
+
+  // for back-compatability only:
+  void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
+  void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
+  static void default_callback(Fl_Window*, void* v);
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Window.H 4421 2005-07-15 09:34:53Z matt $".
+//
diff --git a/Utilities/FLTK/FL/Fl_Wizard.H b/Utilities/FLTK/FL/Fl_Wizard.H
new file mode 100644
index 0000000000000000000000000000000000000000..4c39b7ec5920a34517ffe29a79f8c7c0eb46e0a3
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_Wizard.H
@@ -0,0 +1,62 @@
+//
+// "$Id: Fl_Wizard.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Fl_Wizard widget definitions.
+//
+// Copyright 1999-2005 by Easy Software Products.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//
+// Include necessary header files...
+//
+
+#ifndef _Fl_Wizard_H_
+#  define _Fl_Wizard_H_
+
+#  include <FL/Fl_Group.H>
+
+
+//
+// Fl_Wizard class...
+//
+
+class FL_EXPORT Fl_Wizard : public Fl_Group
+{
+  Fl_Widget *value_;
+
+  void draw();
+
+  public:
+
+  Fl_Wizard(int, int, int, int, const char * = 0);
+
+  void		next();
+  void		prev();
+  Fl_Widget	*value();
+  void		value(Fl_Widget *);
+};
+
+#endif // !_Fl_Wizard_H_
+
+//
+// End of "$Id: Fl_Wizard.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_XBM_Image.H b/Utilities/FLTK/FL/Fl_XBM_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..90f94ab9f867e471d969b5db4fdfa96c676485ef
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_XBM_Image.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_XBM_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// XBM image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_XBM_Image_H
+#define Fl_XBM_Image_H
+#  include "Fl_Bitmap.H"
+
+class FL_EXPORT Fl_XBM_Image : public Fl_Bitmap {
+
+  public:
+
+  Fl_XBM_Image(const char* filename);
+};
+
+#endif // !Fl_XBM_Image_H
+
+//
+// End of "$Id: Fl_XBM_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Fl_XPM_Image.H b/Utilities/FLTK/FL/Fl_XPM_Image.H
new file mode 100644
index 0000000000000000000000000000000000000000..9ffb1c1085abe9e27d9f922cbee993b7fbacab33
--- /dev/null
+++ b/Utilities/FLTK/FL/Fl_XPM_Image.H
@@ -0,0 +1,43 @@
+//
+// "$Id: Fl_XPM_Image.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// XPM image header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef Fl_XPM_Image_H
+#define Fl_XPM_Image_H
+#  include "Fl_Pixmap.H"
+
+class FL_EXPORT Fl_XPM_Image : public Fl_Pixmap {
+
+  public:
+
+  Fl_XPM_Image(const char* filename);
+};
+
+#endif // !Fl_XPM_Image
+
+//
+// End of "$Id: Fl_XPM_Image.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/Makefile.in b/Utilities/FLTK/FL/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..9fb8fde8d30a4ba7016499e987688d676e25357b
--- /dev/null
+++ b/Utilities/FLTK/FL/Makefile.in
@@ -0,0 +1,64 @@
+#
+# "$Id: Makefile.in 4288 2005-04-16 00:13:17Z mike $"
+#
+# Header makefile for the Fast Light Tool Kit (FLTK).
+#
+# Copyright 1998-2005 by Bill Spitzak and others.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems on the following page:
+#
+#      http://www.fltk.org/str.php
+#
+
+include ../makeinclude
+
+all:
+
+clean:
+
+depend:
+
+install:
+	echo "Installing include files in $(DESTDIR)$(includedir)..."
+	-$(MKDIR) -p $(DESTDIR)$(includedir)
+	$(RMDIR) $(DESTDIR)$(includedir)/FL
+	$(MKDIR) $(DESTDIR)$(includedir)/FL
+	$(CHMOD) 755 $(DESTDIR)$(includedir)/FL
+	$(CP) ../FL/*.[hHr] $(DESTDIR)$(includedir)/FL
+	$(CHMOD) 644 $(DESTDIR)$(includedir)/FL/*.[hHr]
+@HLINKS@	cd $(DESTDIR)$(includedir)/FL;\
+@HLINKS@	for file in *.H; do\
+@HLINKS@		$(RM) "`basename $$file H`h";\
+@HLINKS@		$(LN) $$file "`basename $$file H`h";\
+@HLINKS@	done
+@HLINKS@	$(RM) $(DESTDIR)$(includedir)/FL/fl_file_chooser.H
+@HLINKS@	$(LN) Fl_File_Chooser.H $(DESTDIR)$(includedir)/FL/fl_file_chooser.H
+@HLINKS@	$(RM) $(DESTDIR)$(includedir)/FL/fl_file_chooser.h
+@HLINKS@	$(LN) Fl_File_Chooser.H $(DESTDIR)$(includedir)/FL/fl_file_chooser.h
+@HLINKS@	$(RM) $(DESTDIR)$(includedir)/Fl
+@HLINKS@	$(LN) FL $(DESTDIR)$(includedir)/Fl
+
+uninstall:
+	echo "Uninstalling include files..."
+	$(RMDIR) $(DESTDIR)$(includedir)/FL
+@HLINKS@	$(RM) $(DESTDIR)$(includedir)/Fl
+
+
+#
+# End of "$Id: Makefile.in 4288 2005-04-16 00:13:17Z mike $".
+#
diff --git a/Utilities/FLTK/FL/dirent.h b/Utilities/FLTK/FL/dirent.h
new file mode 100644
index 0000000000000000000000000000000000000000..93db65619eea010c32ba3ca265eaa05152c6895a
--- /dev/null
+++ b/Utilities/FLTK/FL/dirent.h
@@ -0,0 +1,33 @@
+//
+// "$Id$"
+//
+// Directory header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// this file is for back-compatability only
+#include "filename.H"
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/FL/filename.H b/Utilities/FLTK/FL/filename.H
new file mode 100644
index 0000000000000000000000000000000000000000..df7dd87d13326ef62fdf5fabdcf62a0a4b375158
--- /dev/null
+++ b/Utilities/FLTK/FL/filename.H
@@ -0,0 +1,138 @@
+/*
+ * "$Id: filename.H 4548 2005-08-29 20:16:36Z matt $"
+ *
+ * Filename header file for the Fast Light Tool Kit (FLTK).
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+#ifndef FL_FILENAME_H
+#  define FL_FILENAME_H
+
+#  include "Fl_Export.H"
+
+#  define FL_PATH_MAX 256 /* all buffers are this length */
+
+FL_EXPORT const char *fl_filename_name(const char *);
+FL_EXPORT const char *fl_filename_ext(const char *);
+FL_EXPORT char *fl_filename_setext(char *to, int tolen, const char *ext);
+FL_EXPORT int fl_filename_expand(char *to, int tolen, const char *from);
+FL_EXPORT int fl_filename_absolute(char *to, int tolen, const char *from);
+FL_EXPORT int fl_filename_relative(char *to, int tolen, const char *from);
+FL_EXPORT int fl_filename_match(const char *name, const char *pattern);
+FL_EXPORT int fl_filename_isdir(const char *name);
+
+#  ifdef __cplusplus
+/*
+ * Under WIN32, we include filename.H from numericsort.c; this should probably change...
+ */
+
+inline char *fl_filename_setext(char *to, const char *ext) { return fl_filename_setext(to, FL_PATH_MAX, ext); }
+inline int fl_filename_expand(char *to, const char *from) { return fl_filename_expand(to, FL_PATH_MAX, from); }
+inline int fl_filename_absolute(char *to, const char *from) { return fl_filename_absolute(to, FL_PATH_MAX, from); }
+inline int fl_filename_relative(char *to, const char *from) { return fl_filename_relative(to, FL_PATH_MAX, from); }
+#  endif /* __cplusplus */
+
+
+#  if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
+
+struct dirent {char d_name[1];};
+
+#  elif defined(__APPLE__) && defined(__PROJECTBUILDER__)
+
+/* Apple's ProjectBuilder has the nasty habit of including recursively
+ * down the file tree. To avoid re-including <FL/dirent.h> we must 
+ * directly include the systems math file. (Plus, I could not find a 
+ * predefined macro for ProjectBuilder builds, so we have to define it 
+ * in the project)
+ */
+#    include <sys/types.h>
+#    include "/usr/include/dirent.h"
+
+#  elif defined(__WATCOMC__)
+#    include <sys/types.h>
+#    include <direct.h>
+
+#  else
+/*
+ * WARNING: on some systems (very few nowadays?) <dirent.h> may not exist.
+ * The correct information is in one of these files:
+ *
+ *     #include <sys/ndir.h>
+ *     #include <sys/dir.h>
+ *     #include <ndir.h>
+ *
+ * plus you must do the following #define:
+ *
+ *     #define dirent direct
+ *
+ * It would be best to create a <dirent.h> file that does this...
+ */
+#    include <sys/types.h>
+#    include <dirent.h>
+#  endif
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif /* __cplusplus */
+
+FL_EXPORT int fl_alphasort(struct dirent **, struct dirent **);
+FL_EXPORT int fl_casealphasort(struct dirent **, struct dirent **);
+FL_EXPORT int fl_casenumericsort(struct dirent **, struct dirent **);
+FL_EXPORT int fl_numericsort(struct dirent **, struct dirent **);
+
+typedef int (Fl_File_Sort_F)(struct dirent **, struct dirent **);
+
+#  ifdef __cplusplus
+}
+
+/*
+ * Portable "scandir" function.  Ugly but necessary...
+ */
+
+FL_EXPORT int fl_filename_list(const char *d, struct dirent ***l,
+                               Fl_File_Sort_F *s = fl_numericsort);
+#  endif /* __cplusplus */
+
+/*
+ * FLTK 1.0.x compatibility definitions...
+ */
+
+#  ifdef FLTK_1_0_COMPAT
+#    define filename_absolute	fl_filename_absolute
+#    define filename_expand	fl_filename_expand
+#    define filename_ext	fl_filename_ext
+#    define filename_isdir	fl_filename_isdir
+#    define filename_list	fl_filename_list
+#    define filename_match	fl_filename_match
+#    define filename_name	fl_filename_name
+#    define filename_relative	fl_filename_relative
+#    define filename_setext	fl_filename_setext
+#    define numericsort		fl_numericsort
+#  endif /* FLTK_1_0_COMPAT */
+
+
+#endif /* FL_FILENAME_H */
+
+/*
+ * End of "$Id: filename.H 4548 2005-08-29 20:16:36Z matt $".
+ */
diff --git a/Utilities/FLTK/FL/fl_ask.H b/Utilities/FLTK/FL/fl_ask.H
new file mode 100644
index 0000000000000000000000000000000000000000..f237af11d69f1acb9116b1a361a5e577cd2189a1
--- /dev/null
+++ b/Utilities/FLTK/FL/fl_ask.H
@@ -0,0 +1,81 @@
+//
+// "$Id: fl_ask.H 4279 2005-04-13 19:35:28Z mike $"
+//
+// Standard dialog header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef fl_ask_H
+#  define fl_ask_H
+
+#  include "Enumerations.H"
+
+class Fl_Widget;
+
+enum {
+  FL_BEEP_DEFAULT = 0,
+  FL_BEEP_MESSAGE,
+  FL_BEEP_ERROR,
+  FL_BEEP_QUESTION,
+  FL_BEEP_PASSWORD,
+  FL_BEEP_NOTIFICATION
+};
+
+#  ifdef __GNUC__
+#    define __fl_attr(x) __attribute__ (x)
+#    if __GNUC__ < 3
+#      define __deprecated__
+#    endif // __GNUC__ < 3
+#  else
+#    define __fl_attr(x)
+#  endif // __GNUC__
+
+FL_EXPORT void fl_beep(int type = FL_BEEP_DEFAULT);
+FL_EXPORT void fl_message(const char *,...) __fl_attr((__format__ (__printf__, 1, 2)));
+FL_EXPORT void fl_alert(const char *,...) __fl_attr((__format__ (__printf__, 1, 2)));
+// fl_ask() is deprecated since it uses "Yes" and "No" for the buttons,
+// which does not conform to the current FLTK Human Interface Guidelines.
+// Use fl_choice() instead with the appropriate verbs instead.
+FL_EXPORT int fl_ask(const char *,...) __fl_attr((__format__ (__printf__, 1, 2), __deprecated__));
+FL_EXPORT int fl_choice(const char *q,const char *b0,const char *b1,const char *b2,...) __fl_attr((__format__ (__printf__, 1, 5)));
+FL_EXPORT const char *fl_input(const char *label, const char *deflt = 0, ...) __fl_attr((__format__ (__printf__, 1, 3)));
+FL_EXPORT const char *fl_password(const char *label, const char *deflt = 0, ...) __fl_attr((__format__ (__printf__, 1, 3)));
+
+FL_EXPORT Fl_Widget *fl_message_icon();
+extern FL_EXPORT Fl_Font fl_message_font_;
+extern FL_EXPORT unsigned char fl_message_size_;
+inline void fl_message_font(unsigned char f,unsigned char s) {
+  fl_message_font_ = (Fl_Font)f; fl_message_size_ = s;}
+
+// pointers you can use to change FLTK to a foreign language:
+extern FL_EXPORT const char* fl_no;
+extern FL_EXPORT const char* fl_yes;
+extern FL_EXPORT const char* fl_ok;
+extern FL_EXPORT const char* fl_cancel;
+extern FL_EXPORT const char* fl_close;
+
+#endif // !fl_ask_H
+
+//
+// End of "$Id: fl_ask.H 4279 2005-04-13 19:35:28Z mike $".
+//
diff --git a/Utilities/FLTK/FL/fl_draw.H b/Utilities/FLTK/FL/fl_draw.H
new file mode 100644
index 0000000000000000000000000000000000000000..ba5d71054a467e3f3c5ec5cbaa4fc0fb87a1f73a
--- /dev/null
+++ b/Utilities/FLTK/FL/fl_draw.H
@@ -0,0 +1,200 @@
+//
+// "$Id: fl_draw.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Portable drawing function header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef fl_draw_H
+#define fl_draw_H
+
+#include "Enumerations.H"  // for the color names
+
+// Image class...
+class Fl_Image;
+
+// Label flags...
+FL_EXPORT extern char fl_draw_shortcut;
+
+// Colors:
+FL_EXPORT void	fl_color(Fl_Color); // select indexed color
+inline void fl_color(int c) {fl_color((Fl_Color)c);} // for back compatability
+FL_EXPORT void	fl_color(uchar, uchar, uchar); // select actual color
+extern FL_EXPORT Fl_Color fl_color_;
+inline Fl_Color fl_color() {return fl_color_;}
+
+// clip:
+FL_EXPORT void fl_push_clip(int x, int y, int w, int h);
+#define fl_clip fl_push_clip
+FL_EXPORT void fl_push_no_clip();
+FL_EXPORT void fl_pop_clip();
+FL_EXPORT int fl_not_clipped(int x, int y, int w, int h);
+FL_EXPORT int fl_clip_box(int, int, int, int, int& x, int& y, int& w, int& h);
+
+// points:
+FL_EXPORT void fl_point(int x, int y);
+
+// line type:
+FL_EXPORT void fl_line_style(int style, int width=0, char* dashes=0);
+enum {
+  FL_SOLID	= 0,
+  FL_DASH	= 1,
+  FL_DOT	= 2,
+  FL_DASHDOT	= 3,
+  FL_DASHDOTDOT	= 4,
+
+  FL_CAP_FLAT	= 0x100,
+  FL_CAP_ROUND	= 0x200,
+  FL_CAP_SQUARE	= 0x300,
+
+  FL_JOIN_MITER	= 0x1000,
+  FL_JOIN_ROUND	= 0x2000,
+  FL_JOIN_BEVEL	= 0x3000
+};
+
+// rectangles tweaked to exactly fill the pixel rectangle:
+FL_EXPORT void fl_rect(int x, int y, int w, int h);
+inline void fl_rect(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rect(x,y,w,h);}
+FL_EXPORT void fl_rectf(int x, int y, int w, int h);
+inline void fl_rectf(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rectf(x,y,w,h);}
+
+// line segments:
+FL_EXPORT void fl_line(int,int, int,int);
+FL_EXPORT void fl_line(int,int, int,int, int,int);
+
+// closed line segments:
+FL_EXPORT void fl_loop(int,int, int,int, int,int);
+FL_EXPORT void fl_loop(int,int, int,int, int,int, int,int);
+
+// filled polygons
+FL_EXPORT void fl_polygon(int,int, int,int, int,int);
+FL_EXPORT void fl_polygon(int,int, int,int, int,int, int,int);
+
+// draw rectilinear lines, horizontal segment first:
+FL_EXPORT void fl_xyline(int x, int y, int x1);
+FL_EXPORT void fl_xyline(int x, int y, int x1, int y2);
+FL_EXPORT void fl_xyline(int x, int y, int x1, int y2, int x3);
+
+// draw rectilinear lines, vertical segment first:
+FL_EXPORT void fl_yxline(int x, int y, int y1);
+FL_EXPORT void fl_yxline(int x, int y, int y1, int x2);
+FL_EXPORT void fl_yxline(int x, int y, int y1, int x2, int y3);
+
+// circular lines and pie slices (code in fl_arci.C):
+FL_EXPORT void fl_arc(int x, int y, int w, int h, double a1, double a2);
+FL_EXPORT void fl_pie(int x, int y, int w, int h, double a1, double a2);
+FL_EXPORT void fl_chord(int x, int y, int w, int h, double a1, double a2); // nyi
+
+// scalable drawing code (code in fl_vertex.C and fl_arc.C):
+FL_EXPORT void fl_push_matrix();
+FL_EXPORT void fl_pop_matrix();
+FL_EXPORT void fl_scale(double x, double y);
+FL_EXPORT void fl_scale(double x);
+FL_EXPORT void fl_translate(double x, double y);
+FL_EXPORT void fl_rotate(double d);
+FL_EXPORT void fl_mult_matrix(double a, double b, double c, double d, double x,double y);
+FL_EXPORT void fl_begin_points();
+FL_EXPORT void fl_begin_line();
+FL_EXPORT void fl_begin_loop();
+FL_EXPORT void fl_begin_polygon();
+FL_EXPORT void fl_vertex(double x, double y);
+FL_EXPORT void fl_curve(double, double, double, double, double, double, double, double);
+FL_EXPORT void fl_arc(double x, double y, double r, double start, double a);
+FL_EXPORT void fl_circle(double x, double y, double r);
+FL_EXPORT void fl_end_points();
+FL_EXPORT void fl_end_line();
+FL_EXPORT void fl_end_loop();
+FL_EXPORT void fl_end_polygon();
+FL_EXPORT void fl_begin_complex_polygon();
+FL_EXPORT void fl_gap();
+FL_EXPORT void fl_end_complex_polygon();
+// get and use transformed positions:
+FL_EXPORT double fl_transform_x(double x, double y);
+FL_EXPORT double fl_transform_y(double x, double y);
+FL_EXPORT double fl_transform_dx(double x, double y);
+FL_EXPORT double fl_transform_dy(double x, double y);
+FL_EXPORT void fl_transformed_vertex(double x, double y);
+
+// current font:
+FL_EXPORT void fl_font(int face, int size);
+extern FL_EXPORT int fl_font_;
+inline int fl_font() {return fl_font_;}
+extern FL_EXPORT int fl_size_;
+inline int fl_size() {return fl_size_;}
+
+// information you can get about the current font:
+FL_EXPORT int   fl_height();	// using "size" should work ok
+inline int fl_height(int, int size) {return size;}
+FL_EXPORT int   fl_descent();
+FL_EXPORT double fl_width(const char*);
+FL_EXPORT double fl_width(const char*, int n);
+FL_EXPORT double fl_width(uchar);
+
+// draw using current font:
+FL_EXPORT void fl_draw(const char*, int x, int y);
+FL_EXPORT void fl_draw(const char*, int n, int x, int y);
+FL_EXPORT void fl_measure(const char*, int& x, int& y, int draw_symbols = 1);
+FL_EXPORT void fl_draw(const char*, int,int,int,int, Fl_Align, Fl_Image* img=0,
+                       int draw_symbols = 1);
+FL_EXPORT void fl_draw(const char*, int,int,int,int, Fl_Align,
+	               void (*callthis)(const char *, int n, int x, int y),
+		       Fl_Image* img=0, int draw_symbols = 1);
+
+// boxtypes:
+FL_EXPORT void fl_frame(const char* s, int x, int y, int w, int h);
+FL_EXPORT void fl_frame2(const char* s, int x, int y, int w, int h);
+FL_EXPORT void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color);
+
+// images:
+FL_EXPORT void fl_draw_image(const uchar*, int,int,int,int, int delta=3, int ldelta=0);
+FL_EXPORT void fl_draw_image_mono(const uchar*, int,int,int,int, int delta=1, int ld=0);
+typedef void (*Fl_Draw_Image_Cb)(void*,int,int,int,uchar*);
+FL_EXPORT void fl_draw_image(Fl_Draw_Image_Cb, void*, int,int,int,int, int delta=3);
+FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb, void*, int,int,int,int, int delta=1);
+FL_EXPORT void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b);
+
+FL_EXPORT uchar *fl_read_image(uchar *p, int x,int y, int w, int h, int alpha=0);
+
+// pixmaps:
+FL_EXPORT int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color=FL_GRAY);
+FL_EXPORT int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h);
+FL_EXPORT int fl_draw_pixmap(const char* const* data, int x,int y,Fl_Color=FL_GRAY);
+FL_EXPORT int fl_measure_pixmap(const char* const* data, int &w, int &h);
+
+// other:
+FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
+                         void (*draw_area)(void*, int,int,int,int), void* data);
+FL_EXPORT const char* fl_shortcut_label(int);
+FL_EXPORT void fl_overlay_rect(int,int,int,int);
+FL_EXPORT void fl_overlay_clear();
+FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
+
+// XForms symbols:
+FL_EXPORT int fl_draw_symbol(const char* label,int x,int y,int w,int h, Fl_Color);
+FL_EXPORT int fl_add_symbol(const char* name, void (*drawit)(Fl_Color), int scalable);
+
+#endif
+
+//
+// End of "$Id: fl_draw.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/fl_message.H b/Utilities/FLTK/FL/fl_message.H
new file mode 100644
index 0000000000000000000000000000000000000000..dd66272ee440298d808cf8f32d5f29d9d650152b
--- /dev/null
+++ b/Utilities/FLTK/FL/fl_message.H
@@ -0,0 +1,32 @@
+//
+// "$Id: fl_message.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Standard message header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include "fl_ask.H"
+
+//
+// End of "$Id: fl_message.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/fl_show_colormap.H b/Utilities/FLTK/FL/fl_show_colormap.H
new file mode 100644
index 0000000000000000000000000000000000000000..baaa2b708bd2b7f292693686e4e706b10f7d485e
--- /dev/null
+++ b/Utilities/FLTK/FL/fl_show_colormap.H
@@ -0,0 +1,37 @@
+//
+// "$Id: fl_show_colormap.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Colormap picker header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef fl_show_colormap_H
+#define fl_show_colormap_H
+
+FL_EXPORT Fl_Color fl_show_colormap(Fl_Color oldcol);
+
+#endif
+
+//
+// End of "$Id: fl_show_colormap.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/fl_show_input.H b/Utilities/FLTK/FL/fl_show_input.H
new file mode 100644
index 0000000000000000000000000000000000000000..3773f99aca331bb613f6ff75f92e4b9a1e9ae8eb
--- /dev/null
+++ b/Utilities/FLTK/FL/fl_show_input.H
@@ -0,0 +1,32 @@
+//
+// "$Id: fl_show_input.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Standard input dialog header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include "fl_ask.H"
+
+//
+// End of "$Id: fl_show_input.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/forms.H b/Utilities/FLTK/FL/forms.H
new file mode 100644
index 0000000000000000000000000000000000000000..dabbea367779dbb7a7e448bb7f908c0d5f82de35
--- /dev/null
+++ b/Utilities/FLTK/FL/forms.H
@@ -0,0 +1,844 @@
+//
+// "$Id: forms.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Forms emulation header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef __FORMS_H__
+#define __FORMS_H__
+
+#include "Fl.H"
+#include "Fl_Group.H"
+#include "Fl_Window.H"
+#include "fl_draw.H"
+
+typedef Fl_Widget FL_OBJECT;
+typedef Fl_Window FL_FORM;
+
+////////////////////////////////////////////////////////////////
+// Random constants & symbols defined by forms.h file:
+
+#ifndef NULL
+#define NULL 0
+#endif
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define FL_ON		1
+#define FL_OK		1
+#define FL_VALID	1
+#define FL_PREEMPT	1
+#define FL_AUTO		2
+#define FL_WHEN_NEEDED	FL_AUTO
+#define FL_OFF		0
+#define FL_NONE		0
+#define FL_CANCEL	0
+#define FL_INVALID	0
+#define FL_IGNORE	-1
+#define FL_CLOSE	-2
+
+#define FL_LCOL		FL_BLACK
+#define FL_COL1		FL_GRAY
+#define FL_MCOL		FL_LIGHT1
+#define FL_LEFT_BCOL	FL_LIGHT3 // 53 is better match
+#define FL_TOP_BCOL	FL_LIGHT2 // 51
+#define FL_BOTTOM_BCOL	FL_DARK2  // 40
+#define FL_RIGHT_BCOL	FL_DARK3  // 36
+#define FL_INACTIVE	FL_INACTIVE_COLOR
+#define FL_INACTIVE_COL	FL_INACTIVE_COLOR
+#define FL_FREE_COL1	FL_FREE_COLOR
+#define FL_FREE_COL2	((Fl_Color)(FL_FREE_COLOR+1))
+#define FL_FREE_COL3	((Fl_Color)(FL_FREE_COLOR+2))
+#define FL_FREE_COL4	((Fl_Color)(FL_FREE_COLOR+3))
+#define FL_FREE_COL5	((Fl_Color)(FL_FREE_COLOR+4))
+#define FL_FREE_COL6	((Fl_Color)(FL_FREE_COLOR+5))
+#define FL_FREE_COL7	((Fl_Color)(FL_FREE_COLOR+6))
+#define FL_FREE_COL8	((Fl_Color)(FL_FREE_COLOR+7))
+#define FL_FREE_COL9	((Fl_Color)(FL_FREE_COLOR+8))
+#define FL_FREE_COL10	((Fl_Color)(FL_FREE_COLOR+9))
+#define FL_FREE_COL11	((Fl_Color)(FL_FREE_COLOR+10))
+#define FL_FREE_COL12	((Fl_Color)(FL_FREE_COLOR+11))
+#define FL_FREE_COL13	((Fl_Color)(FL_FREE_COLOR+12))
+#define FL_FREE_COL14	((Fl_Color)(FL_FREE_COLOR+13))
+#define FL_FREE_COL15	((Fl_Color)(FL_FREE_COLOR+14))
+#define FL_FREE_COL16	((Fl_Color)(FL_FREE_COLOR+15))
+#define FL_TOMATO	((Fl_Color)(131))
+#define FL_INDIANRED	((Fl_Color)(164))
+#define FL_SLATEBLUE	((Fl_Color)(195))
+#define FL_DARKGOLD	((Fl_Color)(84))
+#define FL_PALEGREEN	((Fl_Color)(157))
+#define FL_ORCHID	((Fl_Color)(203))
+#define FL_DARKCYAN	((Fl_Color)(189))
+#define FL_DARKTOMATO	((Fl_Color)(113))
+#define FL_WHEAT	((Fl_Color)(174))
+
+#define FL_ALIGN_BESIDE	FL_ALIGN_INSIDE
+
+#define FL_PUP_TOGGLE	2 // FL_MENU_TOGGLE
+#define FL_PUP_INACTIVE 1 // FL_MENU_INACTIVE
+#define FL_NO_FRAME	FL_NO_BOX
+#define FL_ROUNDED3D_UPBOX 	FL_ROUND_UP_BOX
+#define FL_ROUNDED3D_DOWNBOX	FL_ROUND_DOWN_BOX
+#define FL_OVAL3D_UPBOX		FL_ROUND_UP_BOX
+#define FL_OVAL3D_DOWNBOX	FL_ROUND_DOWN_BOX
+
+#define FL_MBUTTON1	1
+#define FL_LEFTMOUSE	1
+#define FL_MBUTTON2	2
+#define FL_MIDDLEMOUSE	2
+#define FL_MBUTTON3	3
+#define FL_RIGHTMOUSE	3
+#define FL_MBUTTON4	4
+#define FL_MBUTTON5	5
+
+#define FL_INVALID_STYLE 255
+#define FL_NORMAL_STYLE	FL_HELVETICA
+#define FL_BOLD_STYLE	FL_HELVETICA_BOLD
+#define FL_ITALIC_STYLE	FL_HELVETICA_ITALIC
+#define FL_BOLDITALIC_STYLE FL_HELVETICA_BOLD_ITALIC
+#define FL_FIXED_STYLE	FL_COURIER
+#define FL_FIXEDBOLD_STYLE FL_COURIER_BOLD
+#define FL_FIXEDITALIC_STYLE FL_COURIER_ITALIC
+#define FL_FIXEDBOLDITALIC_STYLE FL_COURIER_BOLD_ITALIC
+#define FL_TIMES_STYLE	FL_TIMES
+#define FL_TIMESBOLD_STYLE FL_TIMES_BOLD
+#define FL_TIMESITALIC_STYLE FL_TIMES_ITALIC
+#define FL_TIMESBOLDITALIC_STYLE FL_TIMES_BOLD_ITALIC
+
+// hacks to change the labeltype() when passed to fl_set_object_lstyle():
+#define FL_SHADOW_STYLE		(FL_SHADOW_LABEL<<8)
+#define FL_ENGRAVED_STYLE	(FL_ENGRAVED_LABEL<<8)
+#define FL_EMBOSSED_STYLE	(FL_EMBOSSED_LABEL<<0)
+
+// size values are different from XForms, match older Forms:
+#define FL_TINY_SIZE	8
+#define FL_SMALL_SIZE	11 // 10
+//#define FL_NORMAL_SIZE	14 // 12
+#define FL_MEDIUM_SIZE	18 // 14
+#define FL_LARGE_SIZE	24 // 18
+#define FL_HUGE_SIZE	32 // 24
+#define FL_DEFAULT_SIZE	FL_SMALL_SIZE
+#define FL_TINY_FONT	FL_TINY_SIZE
+#define FL_SMALL_FONT	FL_SMALL_SIZE
+#define FL_NORMAL_FONT	FL_NORMAL_SIZE
+#define FL_MEDIUM_FONT	FL_MEDIUM_SIZE
+#define FL_LARGE_FONT	FL_LARGE_SIZE
+#define FL_HUGE_FONT	FL_HUGE_SIZE
+#define FL_NORMAL_FONT1	FL_SMALL_FONT
+#define FL_NORMAL_FONT2	FL_NORMAL_FONT
+#define FL_DEFAULT_FONT	FL_SMALL_FONT
+
+#define FL_RETURN_END_CHANGED	FL_WHEN_RELEASE
+#define FL_RETURN_CHANGED	FL_WHEN_CHANGED
+#define FL_RETURN_END		FL_WHEN_RELEASE_ALWAYS
+#define FL_RETURN_ALWAYS	(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED)
+
+#define FL_BOUND_WIDTH	3
+
+typedef int FL_Coord;
+typedef int FL_COLOR;
+
+////////////////////////////////////////////////////////////////
+// fltk interaction:
+
+#define FL_CMD_OPT void
+extern FL_EXPORT void fl_initialize(int*, char*[], const char*, FL_CMD_OPT*, int);
+inline void fl_finish() {}
+
+typedef void (*FL_IO_CALLBACK) (int, void*);
+inline void fl_add_io_callback(int fd, short w, FL_IO_CALLBACK cb, void* v) {
+  Fl::add_fd(fd,w,cb,v);}
+inline void fl_remove_io_callback(int fd, short, FL_IO_CALLBACK) {
+  Fl::remove_fd(fd);} // removes all the callbacks!
+
+// type of callback is different and no "id" number is returned:
+inline void fl_add_timeout(long msec, void (*cb)(void*), void* v) {
+  Fl::add_timeout(msec*.001, cb, v);}
+inline void fl_remove_timeout(int) {}
+
+// type of callback is different!
+inline void fl_set_idle_callback(void (*cb)()) {Fl::set_idle(cb);}
+
+FL_EXPORT Fl_Widget* fl_do_forms(void);
+FL_EXPORT Fl_Widget* fl_check_forms();
+inline Fl_Widget* fl_do_only_forms(void) {return fl_do_forms();}
+inline Fl_Widget* fl_check_only_forms(void) {return fl_check_forms();}
+
+// because of new redraw behavior, these are no-ops:
+inline void fl_freeze_object(Fl_Widget*) {}
+inline void fl_unfreeze_object(Fl_Widget*) {}
+inline void fl_freeze_form(Fl_Window*) {}
+inline void fl_unfreeze_form(Fl_Window*) {}
+inline void fl_freeze_all_forms() {}
+inline void fl_unfreeze_all_forms() {}
+
+inline void fl_set_focus_object(Fl_Window*, Fl_Widget* o) {Fl::focus(o);}
+inline void fl_reset_focus_object(Fl_Widget* o) {Fl::focus(o);}
+#define fl_set_object_focus fl_set_focus_object
+
+// void fl_set_form_atclose(Fl_Window*w,int (*cb)(Fl_Window*,void*),void* v)
+// void fl_set_atclose(int (*cb)(Fl_Window*,void*),void*)
+// fl_set_form_atactivate/atdeactivate not implemented!
+
+////////////////////////////////////////////////////////////////
+// Fl_Widget:
+
+inline void fl_set_object_boxtype(Fl_Widget* o, Fl_Boxtype a) {o->box(a);}
+inline void fl_set_object_lsize(Fl_Widget* o,int s) {o->labelsize(s);}
+inline void fl_set_object_lstyle(Fl_Widget* o,int a) {
+  o->labelfont((uchar)a); o->labeltype((Fl_Labeltype)(a>>8));}
+inline void fl_set_object_lcol(Fl_Widget* o, unsigned a) {o->labelcolor(a);}
+#define fl_set_object_lcolor  fl_set_object_lcol
+inline void fl_set_object_lalign(Fl_Widget* o, Fl_Align a) {o->align(a);}
+#define fl_set_object_align fl_set_object_lalign
+inline void fl_set_object_color(Fl_Widget* o,unsigned a,unsigned b) {o->color(a,b);}
+inline void fl_set_object_label(Fl_Widget* o, const char* a) {o->label(a); o->redraw();}
+inline void fl_set_object_position(Fl_Widget*o,int x,int y) {o->position(x,y);}
+inline void fl_set_object_size(Fl_Widget* o, int w, int h) {o->size(w,h);}
+inline void fl_set_object_geometry(Fl_Widget* o,int x,int y,int w,int h) {o->resize(x,y,w,h);}
+
+inline void fl_get_object_geometry(Fl_Widget* o,int*x,int*y,int*w,int*h) {
+  *x = o->x(); *y = o->y(); *w = o->w(); *h = o->h();}
+inline void fl_get_object_position(Fl_Widget* o,int*x,int*y) {
+  *x = o->x(); *y = o->y();}
+
+typedef void (*Forms_CB)(Fl_Widget*, long);
+inline void fl_set_object_callback(Fl_Widget*o,Forms_CB c,long a) {o->callback(c,a);}
+#define fl_set_call_back      fl_set_object_callback
+inline void fl_call_object_callback(Fl_Widget* o) {o->do_callback();}
+inline void fl_trigger_object(Fl_Widget* o) {o->do_callback();}
+inline void fl_set_object_return(Fl_Widget* o, int v) {
+  o->when((Fl_When)(v|FL_WHEN_RELEASE));}
+
+inline void fl_redraw_object(Fl_Widget* o) {o->redraw();}
+inline void fl_show_object(Fl_Widget* o) {o->show();}
+inline void fl_hide_object(Fl_Widget* o) {o->hide();}
+inline void fl_free_object(Fl_Widget* x) {delete x;}
+inline void fl_delete_object(Fl_Widget* o) {((Fl_Group*)(o->parent()))->remove(*o);}
+inline void fl_activate_object(Fl_Widget* o) {o->activate();}
+inline void fl_deactivate_object(Fl_Widget* o) {o->deactivate();}
+
+inline void fl_add_object(Fl_Window* f, Fl_Widget* x) {f->add(x);}
+inline void fl_insert_object(Fl_Widget* o, Fl_Widget* b) {
+    ((Fl_Group*)(b->parent()))->insert(*o,b);}
+
+inline Fl_Window* FL_ObjWin(Fl_Widget* o) {return o->window();}
+
+////////////////////////////////////////////////////////////////
+// things that appered in the demos a lot that I don't emulate, but
+// I did not want to edit out of all the demos...
+
+inline int fl_get_border_width() {return 3;}
+inline void fl_set_border_width(int) {}
+inline void fl_set_object_dblbuffer(Fl_Widget*, int) {}
+inline void fl_set_form_dblbuffer(Fl_Window*, int) {}
+
+////////////////////////////////////////////////////////////////
+// Fl_Window:
+
+inline void fl_free_form(Fl_Window* x) {delete x;}
+inline void fl_redraw_form(Fl_Window* f) {f->redraw();}
+
+inline Fl_Window* fl_bgn_form(Fl_Boxtype b,int w,int h) {
+  Fl_Window* g = new Fl_Window(w,h,0);
+  g->box(b);
+  return g;
+}
+FL_EXPORT void fl_end_form();
+inline void fl_addto_form(Fl_Window* f) {f->begin();}
+inline Fl_Group* fl_bgn_group() {return new Fl_Group(0,0,0,0,0);}
+inline void fl_end_group() {Fl_Group::current()->forms_end();}
+inline void fl_addto_group(Fl_Widget* o) {((Fl_Group* )o)->begin();}
+#define resizebox _ddfdesign_kludge()
+
+inline void fl_scale_form(Fl_Window* f, double x, double y) {
+  f->resizable(f); f->size(int(f->w()*x),int(f->h()*y));}
+inline void fl_set_form_position(Fl_Window* f,int x,int y) {f->position(x,y);}
+inline void fl_set_form_size(Fl_Window* f, int w, int h) {f->size(w,h);}
+inline void fl_set_form_geometry(Fl_Window* f,int x,int y,int w,int h) {
+  f->resize(x,y,w,h);}
+#define fl_set_initial_placement fl_set_form_geometry
+inline void fl_adjust_form_size(Fl_Window*) {}
+
+FL_EXPORT void fl_show_form(Fl_Window* f,int p,int b,const char* n);
+enum {	// "p" argument values:
+  FL_PLACE_FREE = 0,	// make resizable
+  FL_PLACE_MOUSE = 1,	// mouse centered on form
+  FL_PLACE_CENTER = 2,	// center of the screen
+  FL_PLACE_POSITION = 4,// fixed position, resizable
+  FL_PLACE_SIZE = 8,	// fixed size, normal fltk behavior
+  FL_PLACE_GEOMETRY =16,// fixed size and position
+  FL_PLACE_ASPECT = 32,	// keep aspect ratio (ignored)
+  FL_PLACE_FULLSCREEN=64,// fill screen
+  FL_PLACE_HOTSPOT = 128,// enables hotspot
+  FL_PLACE_ICONIC = 256,// iconic (ignored)
+  FL_FREE_SIZE=(1<<14),	// force resizable
+  FL_FIX_SIZE =(1<<15)	// force off resizable
+};
+#define FL_PLACE_FREE_CENTER (FL_PLACE_CENTER|FL_FREE_SIZE)
+#define FL_PLACE_CENTERFREE  (FL_PLACE_CENTER|FL_FREE_SIZE)
+enum {	// "b" arguement values:
+  FL_NOBORDER = 0,
+  FL_FULLBORDER,
+  FL_TRANSIENT
+//FL_MODAL = (1<<8)	// not implemented yet in Forms
+};
+inline void fl_set_form_hotspot(Fl_Window* w,int x,int y) {w->hotspot(x,y);}
+inline void fl_set_form_hotobject(Fl_Window* w, Fl_Widget* o) {w->hotspot(o);}
+extern FL_EXPORT char fl_flip;	// in forms.C
+inline void fl_flip_yorigin() {fl_flip = 1;}
+
+#define fl_prepare_form_window fl_show_form
+inline void fl_show_form_window(Fl_Window*) {}
+
+inline void fl_raise_form(Fl_Window* f) {f->show();}
+
+inline void fl_hide_form(Fl_Window* f) {f->hide();}
+inline void fl_pop_form(Fl_Window* f) {f->show();}
+
+extern FL_EXPORT char fl_modal_next; // in forms.C
+inline void fl_activate_all_forms() {}
+inline void fl_deactivate_all_forms() {fl_modal_next = 1;}
+inline void fl_deactivate_form(Fl_Window*w) {w->deactivate();}
+inline void fl_activate_form(Fl_Window*w) {w->activate();}
+
+inline void fl_set_form_title(Fl_Window* f, const char* s) {f->label(s);}
+inline void fl_title_form(Fl_Window* f, const char* s) {f->label(s);}
+
+typedef void (*Forms_FormCB)(Fl_Widget*);
+inline void fl_set_form_callback(Fl_Window* f,Forms_FormCB c) {f->callback(c);}
+#define fl_set_form_call_back fl_set_form_callback
+
+inline void fl_init() {}
+FL_EXPORT void fl_set_graphics_mode(int,int);
+
+inline int fl_form_is_visible(Fl_Window* f) {return f->visible();}
+
+inline int fl_mouse_button() {return Fl::event_button();}
+#define fl_mousebutton fl_mouse_button
+
+#define fl_free       free
+#define fl_malloc     malloc
+#define fl_calloc     calloc
+#define fl_realloc    realloc
+
+////////////////////////////////////////////////////////////////
+// Drawing functions.  Only usable inside an Fl_Free object?
+
+inline void fl_drw_box(Fl_Boxtype b,int x,int y,int w,int h,Fl_Color bgc,int=3) {
+    fl_draw_box(b,x,y,w,h,bgc);}
+inline void fl_drw_frame(Fl_Boxtype b,int x,int y,int w,int h,Fl_Color bgc,int=3) {
+    fl_draw_box(b,x,y,w,h,bgc);}
+
+inline void fl_drw_text(Fl_Align align, int x, int y, int w, int h,
+		  Fl_Color fgcolor, int size, Fl_Font style,
+		  const char* s) {
+  fl_font(style,size);
+  fl_color(fgcolor);
+  fl_draw(s,x,y,w,h,align);
+}
+
+// this does not work except for CENTER...
+inline void fl_drw_text_beside(Fl_Align align, int x, int y, int w, int h,
+		  Fl_Color fgcolor, int size, Fl_Font style,
+		  const char* s) {
+  fl_font(style,size);
+  fl_color(fgcolor);
+  fl_draw(s,x,y,w,h,align);
+}
+
+inline void fl_set_font_name(Fl_Font n,const char* s) {Fl::set_font(n,s);}
+
+inline void fl_mapcolor(Fl_Color c, uchar r, uchar g, uchar b) {Fl::set_color(c,r,g,b);}
+
+#define fl_set_clipping(x,y,w,h) fl_clip(x,y,w,h)
+#define fl_unset_clipping() fl_pop_clip()
+
+////////////////////////////////////////////////////////////////
+// Forms classes:
+
+inline Fl_Widget* fl_add_new(Fl_Widget* p) {return p;}
+inline Fl_Widget* fl_add_new(uchar t,Fl_Widget* p) {p->type(t); return p;}
+
+#define forms_constructor(type,name) \
+inline type* name(uchar t,int x,int y,int w,int h,const char* l) { \
+ return (type*)(fl_add_new(t, new type(x,y,w,h,l)));}
+#define forms_constructort(type,name) \
+inline type* name(uchar t,int x,int y,int w,int h,const char* l) { \
+ return (type*)(fl_add_new(new type(t,x,y,w,h,l)));}
+#define forms_constructorb(type,name) \
+inline type* name(Fl_Boxtype t,int x,int y,int w,int h,const char* l) { \
+ return (type*)(fl_add_new(new type(t,x,y,w,h,l)));}
+
+#include "Fl_FormsBitmap.H"
+#define FL_NORMAL_BITMAP FL_NO_BOX
+forms_constructorb(Fl_FormsBitmap, fl_add_bitmap)
+inline void fl_set_bitmap_data(Fl_Widget* o, int w, int h, const uchar* b) {
+    ((Fl_FormsBitmap*)o)->set(w,h,b);
+}
+
+#include "Fl_FormsPixmap.H"
+#define FL_NORMAL_PIXMAP FL_NO_BOX
+forms_constructorb(Fl_FormsPixmap, fl_add_pixmap)
+inline void fl_set_pixmap_data(Fl_Widget* o, char*const* b) {
+    ((Fl_FormsPixmap*)o)->set(b);
+}
+//inline void fl_set_pixmap_file(Fl_Widget*, const char*);
+inline void fl_set_pixmap_align(Fl_Widget* o,Fl_Align a,int,int) {o->align(a);}
+//inline void fl_set_pixmap_colorcloseness(int, int, int);
+
+#include "Fl_Box.H"
+forms_constructorb(Fl_Box, fl_add_box)
+
+#include "Fl_Browser.H"
+forms_constructor(Fl_Browser, fl_add_browser)
+
+inline void fl_clear_browser(Fl_Widget* o) {
+    ((Fl_Browser*)o)->clear();}
+inline void fl_add_browser_line(Fl_Widget* o, const char* s) {
+    ((Fl_Browser*)o)->add(s);}
+inline void fl_addto_browser(Fl_Widget* o, const char* s) {
+    ((Fl_Browser*)o)->add(s);} /* should also scroll to bottom */
+//inline void fl_addto_browser_chars(Fl_Widget*, const char*)
+//#define fl_append_browser fl_addto_browser_chars
+inline void fl_insert_browser_line(Fl_Widget* o, int n, const char* s) {
+    ((Fl_Browser*)o)->insert(n,s);}
+inline void fl_delete_browser_line(Fl_Widget* o, int n) {
+    ((Fl_Browser*)o)->remove(n);}
+inline void fl_replace_browser_line(Fl_Widget* o, int n, const char* s) {
+    ((Fl_Browser*)o)->replace(n,s);}
+inline char* fl_get_browser_line(Fl_Widget* o, int n) {
+    return (char*)(((Fl_Browser*)o)->text(n));}
+inline int fl_load_browser(Fl_Widget* o, const char* f) {
+    return ((Fl_Browser*)o)->load(f);}
+inline void fl_select_browser_line(Fl_Widget* o, int n) {
+    ((Fl_Browser*)o)->select(n,1);}
+inline void fl_deselect_browser_line(Fl_Widget* o, int n) {
+    ((Fl_Browser*)o)->select(n,0);}
+inline void fl_deselect_browser(Fl_Widget* o) {
+    ((Fl_Browser*)o)->deselect();}
+inline int fl_isselected_browser_line(Fl_Widget* o, int n) {
+    return ((Fl_Browser*)o)->selected(n);}
+inline int fl_get_browser_topline(Fl_Widget* o) {
+    return ((Fl_Browser*)o)->topline();}
+inline int fl_get_browser(Fl_Widget* o) {
+    return ((Fl_Browser*)o)->value();}
+inline int fl_get_browser_maxline(Fl_Widget* o) {
+    return ((Fl_Browser*)o)->size();}
+//linline int fl_get_browser_screenlines(Fl_Widget*);
+inline void fl_set_browser_topline(Fl_Widget* o, int n) {
+    ((Fl_Browser*)o)->topline(n);}
+inline void fl_set_browser_fontsize(Fl_Widget* o, int s) {
+    ((Fl_Browser*)o)->textsize(s);}
+inline void fl_set_browser_fontstyle(Fl_Widget* o, Fl_Font s) {
+    ((Fl_Browser*)o)->textfont(s);}
+inline void fl_set_browser_specialkey(Fl_Widget* o, char c) {
+    ((Fl_Browser*)o)->format_char(c);}
+//inline void fl_set_browser_vscrollbar(Fl_Widget*, int);
+//inline void fl_set_browser_hscrollbar(Fl_Widget*, int);
+//inline void fl_set_browser_leftslider(Fl_Widget*, int);
+//#define fl_set_browser_leftscrollbar fl_set_browser_leftslider
+//inline void fl_set_browser_line_selectable(Fl_Widget*, int, int);
+//inline void fl_get_browser_dimension(Fl_Widget*,int*,int*,int*,int*);
+//inline void fl_set_browser_dblclick_callback(Fl_Widget*,FL_CALLBACKPTR,long);
+//inline void fl_set_browser_xoffset(Fl_Widget*, FL_Coord);
+//inline void fl_set_browser_scrollbarsize(Fl_Widget*, int, int);
+inline void fl_setdisplayed_browser_line(Fl_Widget* o, int n, int i) {
+    ((Fl_Browser*)o)->display(n,i);}
+inline int fl_isdisplayed_browser_line(Fl_Widget* o, int n) {
+    return ((Fl_Browser*)o)->displayed(n);}
+
+#include "Fl_Button.H"
+
+#define FL_NORMAL_BUTTON	0
+#define FL_TOUCH_BUTTON		4
+#define FL_INOUT_BUTTON		5
+#define FL_RETURN_BUTTON	6
+#define FL_HIDDEN_RET_BUTTON	7
+#define FL_PUSH_BUTTON		FL_TOGGLE_BUTTON
+#define FL_MENU_BUTTON		9
+
+FL_EXPORT Fl_Button* fl_add_button(uchar t,int x,int y,int w,int h,const char* l);
+inline int fl_get_button(Fl_Widget* b) {return ((Fl_Button*)b)->value();}
+inline void fl_set_button(Fl_Widget* b, int v) {((Fl_Button*)b)->value(v);}
+inline int fl_get_button_numb(Fl_Widget*) {return Fl::event_button();}
+inline void fl_set_button_shortcut(Fl_Widget* b, const char* s,int=0) {
+    ((Fl_Button*)b)->shortcut(s);}
+//#define fl_set_object_shortcut(b,s) fl_set_button_shortcut(b,s)
+
+#include "Fl_Light_Button.H"
+forms_constructor(Fl_Light_Button, fl_add_lightbutton)
+
+#include "Fl_Round_Button.H"
+forms_constructor(Fl_Round_Button, fl_add_roundbutton)
+forms_constructor(Fl_Round_Button, fl_add_round3dbutton)
+
+#include "Fl_Check_Button.H"
+forms_constructor(Fl_Check_Button, fl_add_checkbutton)
+
+inline Fl_Widget* fl_add_bitmapbutton(int t,int x,int y,int w,int h,const char* l) {Fl_Widget* o = fl_add_button(t,x,y,w,h,l); return o;}
+inline void fl_set_bitmapbutton_data(Fl_Widget* o,int a,int b,uchar* c) {
+  (new Fl_Bitmap(c,a,b))->label(o);}  // does not delete old Fl_Bitmap!
+
+inline Fl_Widget* fl_add_pixmapbutton(int t,int x,int y,int w,int h,const char* l) {Fl_Widget* o = fl_add_button(t,x,y,w,h,l); return o;}
+inline void fl_set_pixmapbutton_data(Fl_Widget* o, const char*const* c) {
+  (new Fl_Pixmap(c))->label(o);}  // does not delete old Fl_Pixmap!
+
+// Fl_Canvas object not yet implemented!
+
+#include "Fl_Chart.H"
+
+forms_constructor(Fl_Chart, fl_add_chart)
+inline void fl_clear_chart(Fl_Widget* o) {
+  ((Fl_Chart*)o)->clear();}
+inline void fl_add_chart_value(Fl_Widget* o,double v,const char* s,uchar c){
+  ((Fl_Chart*)o)->add(v,s,c);}
+inline void fl_insert_chart_value(Fl_Widget* o, int i, double v, const char* s, uchar c) {
+  ((Fl_Chart*)o)->insert(i,v,s,c);}
+inline void fl_replace_chart_value(Fl_Widget* o, int i, double v, const char* s, uchar c) {
+  ((Fl_Chart*)o)->replace(i,v,s,c);}
+inline void fl_set_chart_bounds(Fl_Widget* o, double a, double b) {
+  ((Fl_Chart*)o)->bounds(a,b);}
+inline void fl_set_chart_maxnumb(Fl_Widget* o, int v) {
+  ((Fl_Chart*)o)->maxsize(v);}
+inline void fl_set_chart_autosize(Fl_Widget* o, int v) {
+  ((Fl_Chart*)o)->autosize(v);}
+inline void fl_set_chart_lstyle(Fl_Widget* o, Fl_Font v) {
+  ((Fl_Chart*)o)->textfont(v);}
+inline void fl_set_chart_lsize(Fl_Widget* o, int v) {
+  ((Fl_Chart*)o)->textsize(v);}
+inline void fl_set_chart_lcolor(Fl_Widget* o, unsigned v) {
+  ((Fl_Chart*)o)->textcolor(v);}
+#define fl_set_chart_lcol   fl_set_chart_lcolor
+
+#include "Fl_Choice.H"
+
+#define FL_NORMAL_CHOICE	0
+#define FL_NORMAL_CHOICE2	0
+#define FL_DROPLIST_CHOICE	0
+
+forms_constructor(Fl_Choice, fl_add_choice)
+inline void fl_clear_choice(Fl_Widget* o) {
+    ((Fl_Choice*)o)->clear();}
+inline void fl_addto_choice(Fl_Widget* o, const char* s) {
+    ((Fl_Choice*)o)->add(s);}
+inline void fl_replace_choice(Fl_Widget* o, int i, const char* s) {
+    ((Fl_Choice*)o)->replace(i-1,s);}
+inline void fl_delete_choice(Fl_Widget* o, int i) {
+    ((Fl_Choice*)o)->remove(i-1);}
+inline void fl_set_choice(Fl_Widget* o, int i) {
+    ((Fl_Choice*)o)->value(i-1);}
+// inline void fl_set_choice_text(Fl_Widget*, const char*);
+inline int fl_get_choice(Fl_Widget* o) {
+    return ((Fl_Choice*)o)->value()+1;}
+// inline const char* fl_get_choice_item_text(Fl_Widget*, int);
+// inline int fl_get_choice_maxitems(Fl_Widget*);
+inline const char* fl_get_choice_text(Fl_Widget* o) {
+    return ((Fl_Choice*)o)->text();}
+inline void fl_set_choice_fontsize(Fl_Widget* o, int x) {
+    ((Fl_Choice*)o)->textsize(x);}
+inline void fl_set_choice_fontstyle(Fl_Widget* o, Fl_Font x) {
+    ((Fl_Choice*)o)->textfont(x);}
+// inline void fl_set_choice_item_mode(Fl_Widget*, int, unsigned);
+// inline void fl_set_choice_item_shortcut(Fl_Widget*, int, const char*);
+
+#include "Fl_Clock.H"
+forms_constructort(Fl_Clock, fl_add_clock)
+inline void fl_get_clock(Fl_Widget* o, int* h, int* m, int* s) {
+    *h = ((Fl_Clock*)o)->hour();
+    *m = ((Fl_Clock*)o)->minute();
+    *s = ((Fl_Clock*)o)->second();
+}
+
+#include "Fl_Counter.H"
+forms_constructor(Fl_Counter, fl_add_counter)
+inline void fl_set_counter_value(Fl_Widget* o, double v) {
+    ((Fl_Counter*)o)->value(v);}
+inline void fl_set_counter_bounds(Fl_Widget* o, double a, double b) {
+    ((Fl_Counter*)o)->bounds(a,b);}
+inline void fl_set_counter_step(Fl_Widget* o, double a, double b) {
+    ((Fl_Counter*)o)->step(a,b);}
+inline void fl_set_counter_precision(Fl_Widget* o, int v) {
+    ((Fl_Counter*)o)->precision(v);}
+inline void fl_set_counter_return(Fl_Widget* o, int v) {
+    ((Fl_Counter*)o)->when((Fl_When)(v|FL_WHEN_RELEASE));}
+inline double fl_get_counter_value(Fl_Widget* o) {
+    return ((Fl_Counter*)o)->value();}
+inline void fl_get_counter_bounds(Fl_Widget* o, float* a, float* b) {
+  *a = float(((Fl_Counter*)o)->minimum());
+  *b = float(((Fl_Counter*)o)->maximum());
+}
+//inline void fl_set_counter_filter(Fl_Widget*,const char* (*)(Fl_Widget*,double,int));
+
+// Cursor stuff cannot be emulated because it uses X stuff
+inline void fl_set_cursor(Fl_Window* w, Fl_Cursor c) {w->cursor(c);}
+#define FL_INVISIBLE_CURSOR FL_CURSOR_NONE
+#define FL_DEFAULT_CURSOR FL_CURSOR_DEFAULT
+
+#include "Fl_Dial.H"
+
+#define FL_DIAL_COL1 FL_GRAY
+#define FL_DIAL_COL2 37
+
+forms_constructor(Fl_Dial, fl_add_dial)
+inline void fl_set_dial_value(Fl_Widget* o, double v) {
+  ((Fl_Dial*)o)->value(v);}
+inline double fl_get_dial_value(Fl_Widget* o) {
+  return ((Fl_Dial*)o)->value();}
+inline void fl_set_dial_bounds(Fl_Widget* o, double a, double b) {
+  ((Fl_Dial*)o)->bounds(a, b);}
+inline void fl_get_dial_bounds(Fl_Widget* o, float* a, float* b) {
+  *a = float(((Fl_Dial*)o)->minimum());
+  *b = float(((Fl_Dial*)o)->maximum());
+}
+inline void fl_set_dial_return(Fl_Widget* o, int i) {
+  ((Fl_Dial*)o)->when((Fl_When)(i|FL_WHEN_RELEASE));}
+inline void fl_set_dial_angles(Fl_Widget* o, int a, int b) {
+  ((Fl_Dial*)o)->angles((short)a, (short)b);}
+//inline void fl_set_dial_cross(Fl_Widget* o, int);
+// inline void fl_set_dial_direction(Fl_Widget* o, uchar d) {
+//   ((Fl_Dial*)o)->direction(d);}
+inline void fl_set_dial_step(Fl_Widget* o, double v) {
+  ((Fl_Dial*)o)->step(v);}
+
+// Frames:
+
+inline Fl_Widget* fl_add_frame(Fl_Boxtype i,int x,int y,int w,int h,const char* l) {
+  return fl_add_box(i,x-3,y-3,w+6,h+6,l);}
+
+// labelframe nyi
+inline Fl_Widget* fl_add_labelframe(Fl_Boxtype i,int x,int y,int w,int h,const char* l) {
+  Fl_Widget* o = fl_add_box(i,x-3,y-3,w+6,h+6,l);
+  o->align(FL_ALIGN_TOP_LEFT);
+  return o;
+}
+
+#include "Fl_Free.H"
+inline Fl_Free*
+fl_add_free(int t,double x,double y,double w,double h,const char* l,
+	    FL_HANDLEPTR hdl) {
+ return (Fl_Free*)(fl_add_new(
+   new Fl_Free(t,int(x),int(y),int(w),int(h),l,hdl)));
+}
+
+#include "fl_ask.H"
+#include "fl_show_colormap.H"
+
+inline int fl_show_question(const char* c, int = 0) {return fl_choice("%s",fl_no,fl_yes,0L,c);}
+FL_EXPORT void fl_show_message(const char *,const char *,const char *);
+FL_EXPORT void fl_show_alert(const char *,const char *,const char *,int=0);
+FL_EXPORT int fl_show_question(const char *,const char *,const char *);
+inline const char *fl_show_input(const char *l,const char*d=0) {return fl_input(l,d);}
+FL_EXPORT /*const*/ char *fl_show_simple_input(const char *label, const char *deflt = 0);
+FL_EXPORT int fl_show_choice(
+    const char *m1,
+    const char *m2,
+    const char *m3,
+    int numb,
+    const char *b0,
+    const char *b1,
+    const char *b2);
+
+inline void fl_set_goodies_font(uchar a, uchar b) {fl_message_font(a,b);}
+#define fl_show_messages fl_message
+inline int fl_show_choices(const char* c,int n,const char* b1,const char* b2,
+			   const char* b3, int) {
+  return fl_show_choice(0,c,0,n,b1,b2,b3);
+}
+
+#include "filename.H"
+#include "Fl_File_Chooser.H"
+inline int do_matching(char* a, const char* b) {return fl_filename_match(a,b);}
+
+// Forms-compatable file chooser (implementation in fselect.C):
+FL_EXPORT char* fl_show_file_selector(const char* message,const char* dir,
+			    const char* pat,const char* fname);
+FL_EXPORT char*	fl_get_directory();
+FL_EXPORT char*	fl_get_pattern();
+FL_EXPORT char*	fl_get_filename();
+
+#include "Fl_Input.H"
+forms_constructor(Fl_Input, fl_add_input)
+inline void fl_set_input(Fl_Widget* o, const char* v) {
+    ((Fl_Input*)o)->value(v);}
+inline void fl_set_input_return(Fl_Widget* o, int x) {
+    ((Fl_Input*)o)->when((Fl_When)(x | FL_WHEN_RELEASE));}
+inline void fl_set_input_color(Fl_Widget* o, unsigned a, unsigned b) {
+    ((Fl_Input*)o)->textcolor(a);
+    ((Fl_Input*)o)->cursor_color(b);
+}
+// inline void fl_set_input_scroll(Fl_Widget*, int);
+inline void fl_set_input_cursorpos(Fl_Widget* o, int x, int /*y*/) {
+  ((Fl_Input*)o)->position(x);}
+// inline void fl_set_input_selected(Fl_Widget*, int);
+// inline void fl_set_input_selected_range(Fl_Widget*, int, int);
+// inline void fl_set_input_maxchars(Fl_Widget*, int);
+// inline void fl_set_input_format(Fl_Widget*, int, int);
+// inline void fl_set_input_hscrollbar(Fl_Widget*, int);
+// inline void fl_set_input_vscrollbar(Fl_Widget*, int);
+// inline void fl_set_input_xoffset(Fl_Widget*, int);
+// inline void fl_set_input_topline(Fl_Widget*, int);
+// inline void fl_set_input_scrollbarsize(Fl_Widget*, int, int);
+// inline int fl_get_input_topline(Fl_Widget*);
+// inline int fl_get_input_screenlines(Fl_Widget*);
+inline int fl_get_input_cursorpos(Fl_Widget* o, int*x, int*y) {
+  *x = ((Fl_Input*)o)->position(); *y = 0; return *x;}
+// inline int fl_get_input_numberoflines(Fl_Widget*);
+// inline void fl_get_input_format(Fl_Widget*, int*, int*);
+inline const char* fl_get_input(Fl_Widget* o) {return ((Fl_Input*)o)->value();}
+
+#include "Fl_Menu_Button.H"
+
+// types are not implemented, they all act like FL_PUSH_MENU:
+#define FL_TOUCH_MENU		0
+#define FL_PUSH_MENU		1
+#define FL_PULLDOWN_MENU	2
+forms_constructor(Fl_Menu_Button, fl_add_menu)
+
+inline void fl_clear_menu(Fl_Widget* o) {
+    ((Fl_Menu_Button*)o)->clear();}
+inline void fl_set_menu(Fl_Widget* o, const char* s) {
+    ((Fl_Menu_Button*)o)->clear(); ((Fl_Menu_Button*)o)->add(s);}
+inline void fl_addto_menu(Fl_Widget* o, const char* s) {
+    ((Fl_Menu_Button*)o)->add(s);}
+inline void fl_replace_menu_item(Fl_Widget* o, int i, const char* s) {
+    ((Fl_Menu_Button*)o)->replace(i-1,s);}
+inline void fl_delete_menu_item(Fl_Widget* o, int i) {
+    ((Fl_Menu_Button*)o)->remove(i-1);}
+inline void fl_set_menu_item_shortcut(Fl_Widget* o, int i, const char* s) {
+    ((Fl_Menu_Button*)o)->shortcut(i-1,fl_old_shortcut(s));}
+inline void fl_set_menu_item_mode(Fl_Widget* o, int i, long x) {
+    ((Fl_Menu_Button*)o)->mode(i-1,x);}
+inline void fl_show_menu_symbol(Fl_Widget*, int ) {
+/*    ((Fl_Menu_Button*)o)->show_menu_symbol(i); */}
+// inline void fl_set_menu_popup(Fl_Widget*, int);
+inline int fl_get_menu(Fl_Widget* o) {
+    return ((Fl_Menu_Button*)o)->value()+1;}
+inline const char* fl_get_menu_item_text(Fl_Widget* o, int i) {
+    return ((Fl_Menu_Button*)o)->text(i);}
+inline int fl_get_menu_maxitems(Fl_Widget* o) {
+    return ((Fl_Menu_Button*)o)->size();}
+inline int fl_get_menu_item_mode(Fl_Widget* o, int i) {
+    return ((Fl_Menu_Button*)o)->mode(i);}
+inline const char* fl_get_menu_text(Fl_Widget* o) {
+    return ((Fl_Menu_Button*)o)->text();}
+
+#include "Fl_Positioner.H"
+#define FL_NORMAL_POSITIONER	0
+forms_constructor(Fl_Positioner, fl_add_positioner)
+inline void fl_set_positioner_xvalue(Fl_Widget* o, double v) {
+    ((Fl_Positioner*)o)->xvalue(v);}
+inline double fl_get_positioner_xvalue(Fl_Widget* o) {
+    return ((Fl_Positioner*)o)->xvalue();}
+inline void fl_set_positioner_xbounds(Fl_Widget* o, double a, double b) {
+    ((Fl_Positioner*)o)->xbounds(a,b);}
+inline void fl_get_positioner_xbounds(Fl_Widget* o, float* a, float* b) {
+  *a = float(((Fl_Positioner*)o)->xminimum());
+  *b = float(((Fl_Positioner*)o)->xmaximum());
+}
+inline void fl_set_positioner_yvalue(Fl_Widget* o, double v) {
+    ((Fl_Positioner*)o)->yvalue(v);}
+inline double fl_get_positioner_yvalue(Fl_Widget* o) {
+    return ((Fl_Positioner*)o)->yvalue();}
+inline void fl_set_positioner_ybounds(Fl_Widget* o, double a, double b) {
+    ((Fl_Positioner*)o)->ybounds(a,b);}
+inline void fl_get_positioner_ybounds(Fl_Widget* o, float* a, float* b) {
+  *a = float(((Fl_Positioner*)o)->yminimum());
+  *b = float(((Fl_Positioner*)o)->ymaximum());
+}
+inline void fl_set_positioner_xstep(Fl_Widget* o, double v) {
+    ((Fl_Positioner*)o)->xstep(v);}
+inline void fl_set_positioner_ystep(Fl_Widget* o, double v) {
+    ((Fl_Positioner*)o)->ystep(v);}
+inline void fl_set_positioner_return(Fl_Widget* o, int v) {
+    ((Fl_Positioner*)o)->when((Fl_When)(v|FL_WHEN_RELEASE));}
+
+#include "Fl_Slider.H"
+
+#define FL_HOR_BROWSER_SLIDER FL_HOR_SLIDER
+#define FL_VERT_BROWSER_SLIDER FL_VERT_SLIDER
+
+forms_constructort(Fl_Slider, fl_add_slider)
+#define FL_SLIDER_COL1 FL_GRAY
+inline void fl_set_slider_value(Fl_Widget* o, double v) {
+    ((Fl_Slider*)o)->value(v);}
+inline double fl_get_slider_value(Fl_Widget* o) {
+    return ((Fl_Slider*)o)->value();}
+inline void fl_set_slider_bounds(Fl_Widget* o, double a, double b) {
+    ((Fl_Slider*)o)->bounds(a, b);}
+inline void fl_get_slider_bounds(Fl_Widget* o, float* a, float* b) {
+  *a = float(((Fl_Slider*)o)->minimum());
+  *b = float(((Fl_Slider*)o)->maximum());
+}
+inline void fl_set_slider_return(Fl_Widget* o, int i) {
+    ((Fl_Slider*)o)->when((Fl_When)(i|FL_WHEN_RELEASE));}
+inline void fl_set_slider_step(Fl_Widget* o, double v) {
+    ((Fl_Slider*)o)->step(v);}
+// inline void fl_set_slider_increment(Fl_Widget* o, double v, double);
+inline void fl_set_slider_size(Fl_Widget* o, double v) {
+    ((Fl_Slider*)o)->slider_size(v);}
+
+#include "Fl_Value_Slider.H"
+forms_constructor(Fl_Value_Slider, fl_add_valslider)
+
+inline void fl_set_slider_precision(Fl_Widget* o, int i) {
+    ((Fl_Value_Slider*)o)->precision(i);}
+// filter function!
+
+// The forms text object was the same as an Fl_Box except it inverted the
+// meaning of FL_ALIGN_INSIDE.  Implementation in forms.cxx
+class FL_EXPORT Fl_FormsText : public Fl_Widget {
+protected:
+    void draw();
+public:
+    Fl_FormsText(Fl_Boxtype b, int X, int Y, int W, int H, const char* l=0)
+	: Fl_Widget(X,Y,W,H,l) {box(b); align(FL_ALIGN_LEFT);}
+};
+#define FL_NORMAL_TEXT FL_NO_BOX
+forms_constructorb(Fl_FormsText, fl_add_text)
+
+#include "Fl_Timer.H"
+forms_constructort(Fl_Timer, fl_add_timer)
+inline void fl_set_timer(Fl_Widget* o, double v) {((Fl_Timer*)o)->value(v);}
+inline double fl_get_timer(Fl_Widget* o) {return ((Fl_Timer*)o)->value();}
+inline void fl_suspend_timer(Fl_Widget* o) {((Fl_Timer*)o)->suspended(1);}
+inline void fl_resume_timer(Fl_Widget* o) {((Fl_Timer*)o)->suspended(0);}
+inline void fl_set_timer_countup(Fl_Widget* o,char d) {((Fl_Timer*)o)->direction(d);}
+void fl_gettime(long* sec, long* usec);
+
+// Fl_XYPlot nyi
+
+
+// stuff from DDForms:
+
+inline int fl_double_click() {return Fl::event_clicks();}
+inline void fl_draw() {Fl::flush();}
+
+#endif	/* define __FORMS_H__ */
+
+//
+// End of "$Id: forms.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/gl.h b/Utilities/FLTK/FL/gl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4bd40cd071f966a99448cfc736f86b031b33e136
--- /dev/null
+++ b/Utilities/FLTK/FL/gl.h
@@ -0,0 +1,87 @@
+//
+// "$Id$"
+//
+// OpenGL header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// You must include this instead of GL/gl.h to get the Microsoft
+// APIENTRY stuff included (from <windows.h>) prior to the OpenGL
+// header files.
+//
+// This file also provides "missing" OpenGL functions, and
+// gl_start() and gl_finish() to allow OpenGL to be used in any window
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef FL_gl_H
+#  define FL_gl_H
+
+#  include "Enumerations.H" // for color names
+#  ifdef WIN32
+#    include <windows.h>
+#  endif
+#  ifndef APIENTRY
+#    if defined(__CYGWIN__)
+#      define APIENTRY __attribute__ ((__stdcall__))
+#    else
+#      define APIENTRY
+#    endif
+#  endif
+
+#  ifdef __APPLE__
+#    include <OpenGL/gl.h>
+#  else
+#    include <GL/gl.h>
+#  endif
+
+FL_EXPORT void gl_start();
+FL_EXPORT void gl_finish();
+
+FL_EXPORT void gl_color(Fl_Color);
+inline void gl_color(int c) {gl_color((Fl_Color)c);} // back compatability
+
+FL_EXPORT void gl_rect(int x,int y,int w,int h);
+inline void gl_rectf(int x,int y,int w,int h) {glRecti(x,y,x+w,y+h);}
+
+FL_EXPORT void gl_font(int fontid, int size);
+FL_EXPORT int  gl_height();
+FL_EXPORT int  gl_descent();
+FL_EXPORT double gl_width(const char *);
+FL_EXPORT double gl_width(const char *, int n);
+FL_EXPORT double gl_width(uchar);
+
+FL_EXPORT void gl_draw(const char*);
+FL_EXPORT void gl_draw(const char*, int n);
+FL_EXPORT void gl_draw(const char*, int x, int y);
+FL_EXPORT void gl_draw(const char*, float x, float y);
+FL_EXPORT void gl_draw(const char*, int n, int x, int y);
+FL_EXPORT void gl_draw(const char*, int n, float x, float y);
+FL_EXPORT void gl_draw(const char*, int x, int y, int w, int h, Fl_Align);
+FL_EXPORT void gl_measure(const char*, int& x, int& y);
+
+FL_EXPORT void gl_draw_image(const uchar *, int x,int y,int w,int h, int d=3, int ld=0);
+
+#endif // !FL_gl_H
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/FL/gl2opengl.h b/Utilities/FLTK/FL/gl2opengl.h
new file mode 100644
index 0000000000000000000000000000000000000000..b89614e0fbfb23ab6859e5fe4638f60295c33587
--- /dev/null
+++ b/Utilities/FLTK/FL/gl2opengl.h
@@ -0,0 +1,35 @@
+/*	gl.h
+
+	GL to OpenGL translator.
+	If you include this, you might be able to port old GL programs.
+	There are also much better emulators available on the net.
+
+*/
+
+#include <FL/gl.h>
+#include "gl_draw.H"
+
+inline void clear() {glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);}
+#define RGBcolor(r,g,b) glColor3ub(r,g,b)
+#define bgnline() glBegin(GL_LINE_STRIP)
+#define bgnpolygon() glBegin(GL_POLYGON)
+#define bgnclosedline() glBegin(GL_LINE_LOOP)
+#define endline() glEnd()
+#define endpolygon() glEnd()
+#define endclosedline() glEnd()
+#define v2f(v) glVertex2fv(v)
+#define v2s(v) glVertex2sv(v)
+#define cmov(x,y,z) glRasterPos3f(x,y,z)
+#define charstr(s) gl_draw(s)
+#define fmprstr(s) gl_draw(s)
+typedef float Matrix[4][4];
+inline void pushmatrix() {glPushMatrix();}
+inline void popmatrix() {glPopMatrix();}
+inline void multmatrix(Matrix m) {glMultMatrixf((float *)m);}
+inline void color(int n) {glIndexi(n);}
+inline void rect(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);}
+inline void rectf(int x,int y,int r,int t) {glRectf(x,y,r+1,t+1);}
+inline void recti(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);}
+inline void rectfi(int x,int y,int r,int t) {glRecti(x,y,r+1,t+1);}
+inline void rects(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);}
+inline void rectfs(int x,int y,int r,int t) {glRects(x,y,r+1,t+1);}
diff --git a/Utilities/FLTK/FL/gl_draw.H b/Utilities/FLTK/FL/gl_draw.H
new file mode 100644
index 0000000000000000000000000000000000000000..09c99d053a355050e0ee26ba4ac749ee4d4d23e7
--- /dev/null
+++ b/Utilities/FLTK/FL/gl_draw.H
@@ -0,0 +1,35 @@
+//
+// "$Id: gl_draw.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// OpenGL header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include "gl.h"
+
+extern FL_EXPORT void gl_remove_displaylist_fonts();
+
+
+//
+// End of "$Id: gl_draw.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/glut.H b/Utilities/FLTK/FL/glut.H
new file mode 100644
index 0000000000000000000000000000000000000000..f05169585d0223bfdb9c146305518a22f6461fb5
--- /dev/null
+++ b/Utilities/FLTK/FL/glut.H
@@ -0,0 +1,476 @@
+//
+// "$Id: glut.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// GLUT emulation header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Emulation of GLUT using fltk.
+
+// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996:
+// "This program is freely distributable without licensing fees  and is
+// provided without guarantee or warrantee expressed or  implied. This
+// program is -not- in the public domain."
+
+// Although I have copied the GLUT API, none of my code is based on
+// any GLUT implementation details and is therefore covered by the LGPL.
+
+// FLTK does not include the GLUT drawing functions (such as
+// glutWireTeapot()) or the stroke fonts but the declarations for the
+// drawing functions are included here because otherwise there is no
+// way to get them along with this.  To use them you will have to
+// link in the original GLUT library, put -lglut *after* -lfltk.
+
+// Commented out lines indicate parts of GLUT that are not emulated.
+
+#ifndef __glut_h__
+#  define __glut_h__
+
+#  include "gl.h"
+//#  include <GL/glu.h>
+
+////////////////////////////////////////////////////////////////
+// GLUT is emulated using this window class and these static variables
+// (plus several more static variables hidden in glut.C):
+
+#  include "Fl.H"
+#  include "Fl_Gl_Window.H"
+
+class FL_EXPORT Fl_Glut_Window : public Fl_Gl_Window {
+  void _init();
+  int mouse_down;
+protected:
+  void draw();
+  void draw_overlay();
+  int handle(int);
+public: // so the inline functions work
+  int number;
+  int menu[3];
+  void make_current();
+  void (*display)();
+  void (*overlaydisplay)();
+  void (*reshape)(int w, int h);
+  void (*keyboard)(uchar, int x, int y);
+  void (*mouse)(int b, int state, int x, int y);
+  void (*motion)(int x, int y);
+  void (*passivemotion)(int x, int y);
+  void (*entry)(int);
+  void (*visibility)(int);
+  void (*special)(int, int x, int y);
+  Fl_Glut_Window(int w, int h, const char *);
+  Fl_Glut_Window(int x, int y, int w, int h, const char *);
+  ~Fl_Glut_Window();
+};
+
+extern FL_EXPORT Fl_Glut_Window *glut_window;	// the current window
+extern FL_EXPORT int glut_menu;			// the current menu
+
+// function pointers that are not per-window:
+extern FL_EXPORT void (*glut_idle_function)();
+extern FL_EXPORT void (*glut_menustate_function)(int);
+extern FL_EXPORT void (*glut_menustatus_function)(int,int,int);
+
+////////////////////////////////////////////////////////////////
+
+//#  define GLUT_API_VERSION This does not match any version of GLUT exactly...
+
+FL_EXPORT void glutInit(int *argcp, char **argv); // creates first window
+
+FL_EXPORT void glutInitDisplayMode(unsigned int mode);
+// the FL_ symbols have the same value as the GLUT ones:
+#  define GLUT_RGB	FL_RGB
+#  define GLUT_RGBA	FL_RGB
+#  define GLUT_INDEX	FL_INDEX
+#  define GLUT_SINGLE	FL_SINGLE
+#  define GLUT_DOUBLE	FL_DOUBLE
+#  define GLUT_ACCUM	FL_ACCUM
+#  define GLUT_ALPHA	FL_ALPHA
+#  define GLUT_DEPTH	FL_DEPTH
+#  define GLUT_STENCIL	FL_STENCIL
+#  define GLUT_MULTISAMPLE FL_MULTISAMPLE
+#  define GLUT_STEREO	FL_STEREO
+// #  define GLUT_LUMINANCE		512
+
+FL_EXPORT void glutInitWindowPosition(int x, int y);
+
+FL_EXPORT void glutInitWindowSize(int w, int h);
+
+FL_EXPORT void glutMainLoop();
+
+FL_EXPORT int glutCreateWindow(char *title);
+
+FL_EXPORT int glutCreateSubWindow(int win, int x, int y, int width, int height);
+
+FL_EXPORT void glutDestroyWindow(int win);
+
+inline void glutPostRedisplay() {glut_window->redraw();}
+
+FL_EXPORT void glutSwapBuffers();
+
+inline int glutGetWindow() {return glut_window->number;}
+
+FL_EXPORT void glutSetWindow(int win);
+
+inline void glutSetWindowTitle(char *t) {glut_window->label(t);}
+
+inline void glutSetIconTitle(char *t) {glut_window->iconlabel(t);}
+
+inline void glutPositionWindow(int x, int y) {glut_window->position(x,y);}
+
+inline void glutReshapeWindow(int w, int h) {glut_window->size(w,h);}
+
+inline void glutPopWindow() {glut_window->show();}
+
+//inline void glutPushWindow();
+
+inline void glutIconifyWindow() {glut_window->iconize();}
+
+inline void glutShowWindow() {glut_window->show();}
+
+inline void glutHideWindow() {glut_window->hide();}
+
+inline void glutFullScreen() {glut_window->fullscreen();}
+
+inline void glutSetCursor(Fl_Cursor cursor) {glut_window->cursor(cursor);}
+// notice that the numeric values are different than glut:
+#  define GLUT_CURSOR_RIGHT_ARROW		((Fl_Cursor)2)
+#  define GLUT_CURSOR_LEFT_ARROW		((Fl_Cursor)67)
+#  define GLUT_CURSOR_INFO			FL_CURSOR_HAND
+#  define GLUT_CURSOR_DESTROY			((Fl_Cursor)45)
+#  define GLUT_CURSOR_HELP			FL_CURSOR_HELP
+#  define GLUT_CURSOR_CYCLE			((Fl_Cursor)26)
+#  define GLUT_CURSOR_SPRAY			((Fl_Cursor)63)
+#  define GLUT_CURSOR_WAIT			FL_CURSOR_WAIT
+#  define GLUT_CURSOR_TEXT			FL_CURSOR_INSERT
+#  define GLUT_CURSOR_CROSSHAIR			FL_CURSOR_CROSS
+#  define GLUT_CURSOR_UP_DOWN			FL_CURSOR_NS
+#  define GLUT_CURSOR_LEFT_RIGHT		FL_CURSOR_WE
+#  define GLUT_CURSOR_TOP_SIDE			FL_CURSOR_N
+#  define GLUT_CURSOR_BOTTOM_SIDE		FL_CURSOR_S
+#  define GLUT_CURSOR_LEFT_SIDE			FL_CURSOR_W
+#  define GLUT_CURSOR_RIGHT_SIDE		FL_CURSOR_E
+#  define GLUT_CURSOR_TOP_LEFT_CORNER		FL_CURSOR_NW
+#  define GLUT_CURSOR_TOP_RIGHT_CORNER		FL_CURSOR_NE
+#  define GLUT_CURSOR_BOTTOM_RIGHT_CORNER	FL_CURSOR_SE
+#  define GLUT_CURSOR_BOTTOM_LEFT_CORNER	FL_CURSOR_SW
+#  define GLUT_CURSOR_INHERIT			FL_CURSOR_DEFAULT
+#  define GLUT_CURSOR_NONE			FL_CURSOR_NONE
+#  define GLUT_CURSOR_FULL_CROSSHAIR		FL_CURSOR_CROSS
+
+//inline void glutWarpPointer(int x, int y);
+
+inline void glutEstablishOverlay() {glut_window->make_overlay_current();}
+
+inline void glutRemoveOverlay() {glut_window->hide_overlay();}
+
+inline void glutUseLayer(GLenum layer) {
+  layer ? glut_window->make_overlay_current() : glut_window->make_current();}
+enum {GLUT_NORMAL, GLUT_OVERLAY};
+
+inline void glutPostOverlayRedisplay() {glut_window->redraw_overlay();}
+
+inline void glutShowOverlay() {glut_window->redraw_overlay();}
+
+inline void glutHideOverlay() {glut_window->hide_overlay();}
+
+FL_EXPORT int glutCreateMenu(void (*)(int));
+
+FL_EXPORT void glutDestroyMenu(int menu);
+
+inline int glutGetMenu() {return glut_menu;}
+
+inline void glutSetMenu(int m) {glut_menu = m;}
+
+FL_EXPORT void glutAddMenuEntry(char *label, int value);
+
+FL_EXPORT void glutAddSubMenu(char *label, int submenu);
+
+FL_EXPORT void glutChangeToMenuEntry(int item, char *label, int value);
+
+FL_EXPORT void glutChangeToSubMenu(int item, char *label, int submenu);
+
+FL_EXPORT void glutRemoveMenuItem(int item);
+
+inline void glutAttachMenu(int b) {glut_window->menu[b] = glut_menu;}
+
+inline void glutDetachMenu(int b) {glut_window->menu[b] = 0;}
+
+inline void glutDisplayFunc(void (*f)()) {glut_window->display = f;}
+
+inline void glutReshapeFunc(void (*f)(int w, int h)) {glut_window->reshape=f;}
+
+inline void glutKeyboardFunc(void (*f)(uchar key, int x, int y)) {
+  glut_window->keyboard = f;}
+
+inline void glutMouseFunc(void (*f)(int b, int state, int x, int y)) {
+  glut_window->mouse = f;}
+#  define GLUT_LEFT_BUTTON		0
+#  define GLUT_MIDDLE_BUTTON		1
+#  define GLUT_RIGHT_BUTTON		2
+#  define GLUT_DOWN			0
+#  define GLUT_UP			1
+
+inline void glutMotionFunc(void (*f)(int x, int y)) {glut_window->motion= f;}
+
+inline void glutPassiveMotionFunc(void (*f)(int x, int y)) {
+  glut_window->passivemotion= f;}
+
+inline void glutEntryFunc(void (*f)(int s)) {glut_window->entry = f;}
+enum {GLUT_LEFT, GLUT_ENTERED};
+
+inline void glutVisibilityFunc(void (*f)(int s)) {glut_window->visibility=f;}
+enum {GLUT_NOT_VISIBLE, GLUT_VISIBLE};
+
+inline void glutIdleFunc(void (*f)()) {Fl::set_idle(f);}
+
+// Warning: this cast may not work on all machines:
+inline void glutTimerFunc(unsigned int msec, void (*f)(int), int value) {
+  Fl::add_timeout(msec*.001, (void (*)(void *))f, (void *)value);
+}
+
+inline void glutMenuStateFunc(void (*f)(int state)) {
+  glut_menustate_function = f;}
+
+inline void glutMenuStatusFunc(void (*f)(int status, int x, int y)) {
+  glut_menustatus_function = f;}
+enum {GLUT_MENU_NOT_IN_USE, GLUT_MENU_IN_USE};
+
+inline void glutSpecialFunc(void (*f)(int key, int x, int y)) {
+  glut_window->special = f;}
+#  define GLUT_KEY_F1			1
+#  define GLUT_KEY_F2			2
+#  define GLUT_KEY_F3			3
+#  define GLUT_KEY_F4			4
+#  define GLUT_KEY_F5			5
+#  define GLUT_KEY_F6			6
+#  define GLUT_KEY_F7			7
+#  define GLUT_KEY_F8			8
+#  define GLUT_KEY_F9			9
+#  define GLUT_KEY_F10			10
+#  define GLUT_KEY_F11			11
+#  define GLUT_KEY_F12			12
+// WARNING: Different values than GLUT uses:
+#  define GLUT_KEY_LEFT			FL_Left
+#  define GLUT_KEY_UP			FL_Up
+#  define GLUT_KEY_RIGHT		FL_Right
+#  define GLUT_KEY_DOWN			FL_Down
+#  define GLUT_KEY_PAGE_UP		FL_Page_Up
+#  define GLUT_KEY_PAGE_DOWN		FL_Page_Down
+#  define GLUT_KEY_HOME			FL_Home
+#  define GLUT_KEY_END			FL_End
+#  define GLUT_KEY_INSERT		FL_Insert
+
+//inline void glutSpaceballMotionFunc(void (*)(int x, int y, int z));
+
+//inline void glutSpaceballRotateFunc(void (*)(int x, int y, int z));
+
+//inline void glutSpaceballButtonFunc(void (*)(int button, int state));
+
+//inline void glutButtonBoxFunc(void (*)(int button, int state));
+
+//inline void glutDialsFunc(void (*)(int dial, int value));
+
+//inline void glutTabletMotionFunc(void (*)(int x, int y));
+
+//inline void glutTabletButtonFunc(void (*)(int button, int state, int x, int y));
+
+inline void glutOverlayDisplayFunc(void (*f)()) {
+  glut_window->overlaydisplay = f;}
+
+//inline void glutWindowStatusFunc(void (*)(int state));
+//enum {GLUT_HIDDEN, GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED,
+//	GLUT_FULLY_COVERED};
+
+//inline void glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
+
+//inline GLfloat glutGetColor(int ndx, int component);
+//#define GLUT_RED			0
+//#define GLUT_GREEN			1
+//#define GLUT_BLUE			2
+
+//inline void glutCopyColormap(int win);
+
+// Warning: values are changed from GLUT!
+// Also relies on the GL_ symbols having values greater than 100
+int glutGet(GLenum type);
+enum {
+  GLUT_RETURN_ZERO = 0,
+  GLUT_WINDOW_X,
+  GLUT_WINDOW_Y,
+  GLUT_WINDOW_WIDTH,
+  GLUT_WINDOW_HEIGHT,
+  GLUT_WINDOW_PARENT,
+//GLUT_WINDOW_NUM_CHILDREN,
+//GLUT_WINDOW_CURSOR,
+  GLUT_SCREEN_WIDTH,
+  GLUT_SCREEN_HEIGHT,
+//GLUT_SCREEN_WIDTH_MM,
+//GLUT_SCREEN_HEIGHT_MM,
+  GLUT_MENU_NUM_ITEMS,
+  GLUT_DISPLAY_MODE_POSSIBLE,
+  GLUT_INIT_WINDOW_X,
+  GLUT_INIT_WINDOW_Y,
+  GLUT_INIT_WINDOW_WIDTH,
+  GLUT_INIT_WINDOW_HEIGHT,
+  GLUT_INIT_DISPLAY_MODE,
+//GLUT_ELAPSED_TIME,
+  GLUT_WINDOW_BUFFER_SIZE
+};
+
+#  define GLUT_WINDOW_STENCIL_SIZE	GL_STENCIL_BITS
+#  define GLUT_WINDOW_DEPTH_SIZE	GL_DEPTH_BITS
+#  define GLUT_WINDOW_RED_SIZE		GL_RED_BITS
+#  define GLUT_WINDOW_GREEN_SIZE	GL_GREEN_BITS
+#  define GLUT_WINDOW_BLUE_SIZE		GL_BLUE_BITS
+#  define GLUT_WINDOW_ALPHA_SIZE	GL_ALPHA_BITS
+#  define GLUT_WINDOW_ACCUM_RED_SIZE	GL_ACCUM_RED_BITS
+#  define GLUT_WINDOW_ACCUM_GREEN_SIZE	GL_ACCUM_GREEN_BITS
+#  define GLUT_WINDOW_ACCUM_BLUE_SIZE	GL_ACCUM_BLUE_BITS
+#  define GLUT_WINDOW_ACCUM_ALPHA_SIZE	GL_ACCUM_ALPHA_BITS
+#  define GLUT_WINDOW_DOUBLEBUFFER	GL_DOUBLEBUFFER
+#  define GLUT_WINDOW_RGBA		GL_RGBA
+#  define GLUT_WINDOW_COLORMAP_SIZE	GL_INDEX_BITS
+#  ifdef GL_SAMPLES_SGIS
+#    define GLUT_WINDOW_NUM_SAMPLES	GL_SAMPLES_SGIS
+#  else
+#    define GLUT_WINDOW_NUM_SAMPLES	GLUT_RETURN_ZERO
+#  endif
+#  define GLUT_WINDOW_STEREO		GL_STEREO
+
+//int glutDeviceGet(GLenum type);
+//#define GLUT_HAS_KEYBOARD		600
+//#define GLUT_HAS_MOUSE		601
+//#define GLUT_HAS_SPACEBALL		602
+//#define GLUT_HAS_DIAL_AND_BUTTON_BOX	603
+//#define GLUT_HAS_TABLET		604
+//#define GLUT_NUM_MOUSE_BUTTONS	605
+//#define GLUT_NUM_SPACEBALL_BUTTONS	606
+//#define GLUT_NUM_BUTTON_BOX_BUTTONS	607
+//#define GLUT_NUM_DIALS		608
+//#define GLUT_NUM_TABLET_BUTTONS	609
+
+// WARNING: these values are different than GLUT uses:
+#  define GLUT_ACTIVE_SHIFT               FL_SHIFT
+#  define GLUT_ACTIVE_CTRL                FL_CTRL
+#  define GLUT_ACTIVE_ALT                 FL_ALT
+inline int glutGetModifiers() {return Fl::event_state() & (GLUT_ACTIVE_SHIFT | GLUT_ACTIVE_CTRL | GLUT_ACTIVE_ALT);}
+
+int glutLayerGet(GLenum);
+#  define GLUT_OVERLAY_POSSIBLE		800
+//#define GLUT_LAYER_IN_USE		801
+//#define GLUT_HAS_OVERLAY		802
+#  define GLUT_TRANSPARENT_INDEX		803
+#  define GLUT_NORMAL_DAMAGED		804
+#  define GLUT_OVERLAY_DAMAGED		805
+
+//inline int glutVideoResizeGet(GLenum param);
+//#define GLUT_VIDEO_RESIZE_POSSIBLE	900
+//#define GLUT_VIDEO_RESIZE_IN_USE	901
+//#define GLUT_VIDEO_RESIZE_X_DELTA	902
+//#define GLUT_VIDEO_RESIZE_Y_DELTA	903
+//#define GLUT_VIDEO_RESIZE_WIDTH_DELTA	904
+//#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905
+//#define GLUT_VIDEO_RESIZE_X		906
+//#define GLUT_VIDEO_RESIZE_Y		907
+//#define GLUT_VIDEO_RESIZE_WIDTH	908
+//#define GLUT_VIDEO_RESIZE_HEIGHT	909
+
+//inline void glutSetupVideoResizing();
+
+//inline void glutStopVideoResizing();
+
+//inline void glutVideoResize(int x, int y, int width, int height);
+
+//inline void glutVideoPan(int x, int y, int width, int height);
+
+////////////////////////////////////////////////////////////////
+// Emulated GLUT drawing functions:
+
+// Font argument must be a void* for compatability, so...
+extern FL_EXPORT struct Glut_Bitmap_Font {uchar font; int size;}
+  glutBitmap9By15, glutBitmap8By13, glutBitmapTimesRoman10,
+  glutBitmapTimesRoman24, glutBitmapHelvetica10, glutBitmapHelvetica12,
+  glutBitmapHelvetica18;
+#  define GLUT_BITMAP_9_BY_15             (&glutBitmap9By15)
+#  define GLUT_BITMAP_8_BY_13             (&glutBitmap8By13)
+#  define GLUT_BITMAP_TIMES_ROMAN_10      (&glutBitmapTimesRoman10)
+#  define GLUT_BITMAP_TIMES_ROMAN_24      (&glutBitmapTimesRoman24)
+#  define GLUT_BITMAP_HELVETICA_10        (&glutBitmapHelvetica10)
+#  define GLUT_BITMAP_HELVETICA_12        (&glutBitmapHelvetica12)
+#  define GLUT_BITMAP_HELVETICA_18        (&glutBitmapHelvetica18)
+
+FL_EXPORT void glutBitmapCharacter(void *font, int character);
+FL_EXPORT int glutBitmapWidth(void *font, int character);
+
+////////////////////////////////////////////////////////////////
+// GLUT drawing functions.  These are NOT emulated but you can
+// link in the glut library to get them.  This assumes the object
+// files in GLUT remain as they currently are so that there are
+// not symbol conflicts with the above.
+
+extern "C" {
+
+extern int APIENTRY glutExtensionSupported(char *name);
+
+/* Stroke font constants (use these in GLUT program). */
+#  ifdef WIN32
+#    define GLUT_STROKE_ROMAN		((void*)0)
+#    define GLUT_STROKE_MONO_ROMAN	((void*)1)
+#  else
+extern void *glutStrokeRoman;
+#    define GLUT_STROKE_ROMAN		(&glutStrokeRoman)
+extern void *glutStrokeMonoRoman;
+#    define GLUT_STROKE_MONO_ROMAN	(&glutStrokeMonoRoman)
+#  endif
+
+/* GLUT font sub-API */
+extern void APIENTRY glutStrokeCharacter(void *font, int character);
+extern int APIENTRY glutStrokeWidth(void *font, int character);
+
+/* GLUT pre-built models sub-API */
+extern void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
+extern void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
+extern void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+extern void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+extern void APIENTRY glutWireCube(GLdouble size);
+extern void APIENTRY glutSolidCube(GLdouble size);
+extern void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+extern void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+extern void APIENTRY glutWireDodecahedron();
+extern void APIENTRY glutSolidDodecahedron();
+extern void APIENTRY glutWireTeapot(GLdouble size);
+extern void APIENTRY glutSolidTeapot(GLdouble size);
+extern void APIENTRY glutWireOctahedron();
+extern void APIENTRY glutSolidOctahedron();
+extern void APIENTRY glutWireTetrahedron();
+extern void APIENTRY glutSolidTetrahedron();
+extern void APIENTRY glutWireIcosahedron();
+extern void APIENTRY glutSolidIcosahedron();
+
+}
+
+#endif                  /* !__glut_h__ */
+
+//
+// End of "$Id: glut.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/FL/mac.H b/Utilities/FLTK/FL/mac.H
new file mode 100644
index 0000000000000000000000000000000000000000..11ee29a53d78a5534961b3546e60daf7e5663fd9
--- /dev/null
+++ b/Utilities/FLTK/FL/mac.H
@@ -0,0 +1,135 @@
+//
+// "$Id: mac.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Mac header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Do not directly include this file, instead use <FL/x.H>.  It will
+// include this file if "__APPLE__" is defined.  This is to encourage
+// portability of even the system-specific code...
+
+#ifndef Fl_X_H
+#  error "Never use <FL/mac.H> directly; include <FL/x.H> instead."
+#endif // !Fl_X_H
+
+// Standard MacOS Carbon API includes...
+#include <Carbon/Carbon.h>
+
+// Now make some fixes to the headers...
+#undef check			// Dunno where this comes from...
+
+// Some random X equivalents
+typedef WindowPtr Window;
+struct XPoint { int x, y; };
+struct XRectangle {int x, y, width, height;};
+typedef RgnHandle Fl_Region;
+void fl_clip_region(Fl_Region);
+inline Fl_Region XRectangleRegion(int x, int y, int w, int h) {
+  Fl_Region R = NewRgn();
+  SetRectRgn(R, x, y, x+w, y+h);
+  return R;
+}
+inline void XDestroyRegion(Fl_Region r) {
+  DisposeRgn(r);
+}
+
+#  define XDestroyWindow(a,b) DisposeWindow(b)
+#  define XMapWindow(a,b) ShowWindow(b)
+#  define XUnmapWindow(a,b) HideWindow(b)
+
+#  include "Fl_Window.H"
+
+// This object contains all mac-specific stuff about a window:
+// WARNING: this object is highly subject to change!
+class Fl_X 
+{
+public:
+  Window xid;              // Mac WindowPtr
+  GWorldPtr other_xid;     // pointer for offscreen bitmaps (doublebuffer)
+  Fl_Window *w;            // FLTK window for 
+  Fl_Region region;
+  Fl_Region subRegion;     // region for this specific subwindow
+  Fl_X *next;              // linked tree to support subwindows
+  Fl_X *xidChildren, *xidNext; // more subwindow tree
+  int wait_for_expose;
+  CursHandle cursor;
+  static Fl_X* first;
+  static Fl_X* i(const Fl_Window* w) {return w->i;}
+  static int fake_X_wm(const Fl_Window*,int&,int&,int&,int&,int&);
+  static void make(Fl_Window*);
+  void flush();
+  // Quartz additions:
+  CGContextRef gc;                 // graphics context (NULL when using QD)
+  static ATSUTextLayout atsu_layout; // windows share a global font
+  static ATSUStyle      atsu_style;
+  static void q_fill_context();    // fill a Quartz context with current FLTK state
+  static void q_clear_clipping();  // remove all clipping from a Quartz context
+  static void q_release_context(Fl_X *x=0); // free all resources associated with fl_gc
+  static void q_begin_image(CGRect&, int x, int y, int w, int h);
+  static void q_end_image();
+};
+
+inline Window fl_xid(const Fl_Window*w) 
+{
+  return Fl_X::i(w)->xid;
+}
+
+extern CursHandle fl_default_cursor;
+
+extern struct Fl_XMap {
+  RGBColor rgb;
+  ulong pen;
+} *fl_current_xmap;
+
+extern FL_EXPORT void *fl_display;
+extern FL_EXPORT Window fl_window;
+extern FL_EXPORT CGContextRef fl_gc;
+extern FL_EXPORT Handle fl_system_menu;
+extern FL_EXPORT class Fl_Sys_Menu_Bar *fl_sys_menu_bar;
+
+typedef GWorldPtr Fl_Offscreen;
+
+extern Fl_Offscreen fl_create_offscreen(int w, int h);
+extern void fl_copy_offscreen(int x,int y,int w,int h, Fl_Offscreen gWorld, int srcx,int srcy);
+extern void fl_delete_offscreen(Fl_Offscreen gWorld);
+extern void fl_begin_offscreen(Fl_Offscreen gWorld);
+extern void fl_end_offscreen();
+
+typedef GWorldPtr Fl_Bitmask; // Carbon requires a 1-bit GWorld instead of a BitMap
+
+extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data);
+extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data);
+extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm);
+
+extern void fl_open_display();
+
+// Register a function for opening files via the finder...
+extern void fl_open_callback(void (*cb)(const char *));
+
+extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b);
+
+//
+// End of "$Id: mac.H 4288 2005-04-16 00:13:17Z mike $".
+//
+
diff --git a/Utilities/FLTK/FL/mac.r b/Utilities/FLTK/FL/mac.r
new file mode 100644
index 0000000000000000000000000000000000000000..3d71f2ebbf6d90817e31cf4bc663eaa42f231a12
--- /dev/null
+++ b/Utilities/FLTK/FL/mac.r
@@ -0,0 +1,13 @@
+data 'MBAR' (128) {
+	$"0001 0080"                                          /* ...� */
+};
+
+data 'MENU' (128, "Apple") {
+	$"0080 0000 0000 0000 0000 FFFF FFFB 0114"            /* .�........����.. */
+	$"0A41 626F 7574 2046 4C54 4B00 0000 0001"            /* �About FLTK..... */
+	$"2D00 0000 0000"                                     /* -..... */
+};
+
+data 'carb' (0) {
+};
+
diff --git a/Utilities/FLTK/FL/math.h b/Utilities/FLTK/FL/math.h
new file mode 100644
index 0000000000000000000000000000000000000000..891da4bf79c364f00bd9e861c3521f6a84451d2d
--- /dev/null
+++ b/Utilities/FLTK/FL/math.h
@@ -0,0 +1,72 @@
+//
+// "$Id$"
+//
+// Math header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef fl_math_h
+#  define fl_math_h
+
+// Apple's ProjectBuilder has the nasty habit of including recursively
+// down the file tree. To avoid re-including <FL/math.h> we must 
+// directly include the systems math file. (Plus, I could not find a 
+// predefined macro for ProjectBuilder builds, so we have to define it 
+// in the project)
+#  if defined(__APPLE__) && defined(__PROJECTBUILDER__)
+#    include "/usr/include/math.h"
+#  else
+#    include <math.h>
+#  endif
+
+#  ifdef __EMX__
+#    include <float.h>
+#  endif
+
+
+#  ifndef M_PI
+#    define M_PI            3.14159265358979323846
+#    define M_PI_2          1.57079632679489661923
+#    define M_PI_4          0.78539816339744830962
+#    define M_1_PI          0.31830988618379067154
+#    define M_2_PI          0.63661977236758134308
+#  endif // !M_PI
+
+#  ifndef M_SQRT2
+#    define M_SQRT2         1.41421356237309504880
+#    define M_SQRT1_2       0.70710678118654752440
+#  endif // !M_SQRT2
+
+#  if (defined(WIN32) || defined(CRAY)) && !defined(__MINGW32__) && !defined(__MWERKS__)
+
+inline double rint(double v) {return floor(v+.5);}
+inline double copysign(double a, double b) {return b<0 ? -a : a;}
+
+#  endif // (WIN32 || CRAY) && !__MINGW32__ && !__MWERKS__
+
+#endif // !fl_math_h
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/FL/win32.H b/Utilities/FLTK/FL/win32.H
new file mode 100644
index 0000000000000000000000000000000000000000..439c181e4f93a9c52a25db8a65b2cf6c87fd17c5
--- /dev/null
+++ b/Utilities/FLTK/FL/win32.H
@@ -0,0 +1,151 @@
+//
+// "$Id: win32.H 4569 2005-09-15 07:41:17Z matt $"
+//
+// WIN32 header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Do not directly include this file, instead use <FL/x.H>.  It will
+// include this file if WIN32 is defined.  This is to encourage
+// portability of even the system-specific code...
+
+#ifndef Fl_X_H
+#  error "Never use <FL/win32.H> directly; include <FL/x.H> instead."
+#endif // !Fl_X_H
+
+#include <windows.h>
+// In some of the distributions, the gcc header files are missing some stuff:
+#ifndef LPMINMAXINFO
+#define LPMINMAXINFO MINMAXINFO*
+#endif
+#ifndef VK_LWIN
+#define VK_LWIN 0x5B
+#define VK_RWIN 0x5C
+#define VK_APPS 0x5D
+#endif
+
+// some random X equivalents
+typedef HWND Window;
+typedef POINT XPoint;
+struct XRectangle {int x, y, width, height;};
+typedef HRGN Fl_Region;
+FL_EXPORT void fl_clip_region(Fl_Region);
+inline Fl_Region XRectangleRegion(int x, int y, int w, int h) {
+    return CreateRectRgn(x,y,x+w,y+h);
+}
+inline void XDestroyRegion(Fl_Region r) {DeleteObject(r);}
+inline void XClipBox(Fl_Region r,XRectangle* rect) {
+    RECT win_rect; GetRgnBox(r,&win_rect);
+    rect->x=win_rect.left;
+    rect->y=win_rect.top;
+    rect->width=win_rect.right-win_rect.left;
+    rect->height=win_rect.bottom-win_rect.top;
+}
+#define XDestroyWindow(a,b) DestroyWindow(b)
+#define XMapWindow(a,b) ShowWindow(b, SW_RESTORE)
+#define XUnmapWindow(a,b) ShowWindow(b, SW_HIDE)
+
+#include "Fl_Window.H"
+// this object contains all win32-specific stuff about a window:
+// Warning: this object is highly subject to change!
+class FL_EXPORT Fl_X {
+public:
+  // member variables - add new variables only at the end of this block
+  Window xid;
+  HBITMAP other_xid; // for double-buffered windows
+  Fl_Window* w;
+  Fl_Region region;
+  Fl_X *next;
+  int wait_for_expose;
+  HDC private_dc; // used for OpenGL
+  HCURSOR cursor;
+  HDC saved_hdc;  // saves the handle of the DC currently loaded
+  // static variables, static functions and member functions
+  static Fl_X* first;
+  static Fl_X* i(const Fl_Window* w) {return w->i;}
+  static int fake_X_wm(const Fl_Window* w,int &X, int &Y,
+		                 int &bt,int &bx,int &by);
+  void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
+  void flush() {w->flush();}
+  void set_minmax(LPMINMAXINFO minmax);
+  void mapraise();
+  static Fl_X* make(Fl_Window*);
+};
+extern FL_EXPORT HCURSOR fl_default_cursor;
+extern FL_EXPORT UINT fl_wake_msg;
+inline Window fl_xid(const Fl_Window*w) {Fl_X *temp = Fl_X::i(w); return temp ? temp->xid : 0;}
+FL_EXPORT Fl_Window* fl_find(Window xid);
+extern FL_EXPORT char fl_override_redirect; // hack into Fl_Window::make_xid()
+extern FL_EXPORT int fl_background_pixel;  // hack into Fl_Window::make_xid()
+
+// most recent fl_color() or fl_rgbcolor() points at one of these:
+extern FL_EXPORT struct Fl_XMap {
+  COLORREF rgb;	// this should be the type the RGB() macro returns
+  HPEN pen;	// pen, 0 if none created yet
+  int brush;	// ref to solid brush, 0 if none created yet
+} *fl_current_xmap;
+inline COLORREF fl_RGB() {return fl_current_xmap->rgb;}
+inline HPEN fl_pen() {return fl_current_xmap->pen;}
+FL_EXPORT HBRUSH fl_brush(); // allocates a brush if necessary
+FL_EXPORT HBRUSH fl_brush_action(int); // now does the real work
+
+extern FL_EXPORT HINSTANCE fl_display;
+extern FL_EXPORT Window fl_window;
+extern FL_EXPORT HDC fl_gc;
+extern FL_EXPORT HPALETTE fl_palette; // non-zero only on 8-bit displays!
+extern FL_EXPORT HDC fl_GetDC(Window);
+extern FL_EXPORT MSG fl_msg;
+extern FL_EXPORT void fl_release_dc(HWND w, HDC dc);
+extern FL_EXPORT void fl_save_dc( HWND w, HDC dc);
+
+// off-screen pixmaps: create, destroy, draw into, copy to window
+typedef HBITMAP Fl_Offscreen;
+#define fl_create_offscreen(w, h) CreateCompatibleBitmap(fl_gc, w, h)
+
+extern FL_EXPORT HDC fl_makeDC(HBITMAP);
+
+#define fl_begin_offscreen(b) \
+  HDC _sgc=fl_gc; Window _sw=fl_window; \
+  fl_gc=fl_makeDC(b); int _savedc = SaveDC(fl_gc); fl_window=(HWND)b; fl_push_no_clip()
+
+#define fl_end_offscreen() \
+  fl_pop_clip(); RestoreDC(fl_gc, _savedc); DeleteDC(fl_gc); fl_window=_sw; fl_gc = _sgc
+
+FL_EXPORT void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy);
+#define fl_delete_offscreen(bitmap) DeleteObject(bitmap);
+
+// Bitmap masks
+typedef HBITMAP Fl_Bitmask;
+
+extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data);
+extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data);
+extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm);
+
+// Dummy function to register a function for opening files via the window manager...
+inline void fl_open_callback(void (*)(const char *)) {}
+
+extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b);
+
+//
+// End of "$Id: win32.H 4569 2005-09-15 07:41:17Z matt $".
+//
diff --git a/Utilities/FLTK/FL/x.H b/Utilities/FLTK/FL/x.H
new file mode 100644
index 0000000000000000000000000000000000000000..91642c22085060cd200cc5e7605bf493172c1cd1
--- /dev/null
+++ b/Utilities/FLTK/FL/x.H
@@ -0,0 +1,147 @@
+//
+// "$Id: x.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// X11 header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// These are internal fltk symbols that are necessary or useful for
+// calling Xlib.  You should include this file if (and ONLY if) you
+// need to call Xlib directly.  These symbols may not exist on non-X
+// systems.
+
+#ifndef Fl_X_H
+#  define Fl_X_H
+
+#  include "Enumerations.H"
+
+#  ifdef WIN32
+#    include "win32.H"
+#  elif defined(__APPLE__)
+#    include "mac.H"
+#  else
+#    if defined(_ABIN32) || defined(_ABI64) // fix for broken SGI Irix X .h files
+#      pragma set woff 3322
+#    endif
+#    include <X11/Xlib.h>
+#    include <X11/Xutil.h>
+#    if defined(_ABIN32) || defined(_ABI64)
+#      pragma reset woff 3322
+#    endif
+#    include <X11/Xatom.h>
+#    include "Fl_Window.H"
+
+// Mirror X definition of Region to Fl_Region, for portability...
+typedef Region Fl_Region;
+
+FL_EXPORT void fl_open_display();
+FL_EXPORT void fl_open_display(Display*);
+FL_EXPORT void fl_close_display();
+
+// constant info about the X server connection:
+extern FL_EXPORT Display *fl_display;
+extern FL_EXPORT Window fl_message_window;
+extern FL_EXPORT int fl_screen;
+extern FL_EXPORT XVisualInfo *fl_visual;
+extern FL_EXPORT Colormap fl_colormap;
+
+// drawing functions:
+extern FL_EXPORT GC fl_gc;
+extern FL_EXPORT Window fl_window;
+extern FL_EXPORT XFontStruct* fl_xfont;
+FL_EXPORT ulong fl_xpixel(Fl_Color i);
+FL_EXPORT ulong fl_xpixel(uchar r, uchar g, uchar b);
+FL_EXPORT void fl_clip_region(Fl_Region);
+FL_EXPORT Fl_Region fl_clip_region();
+FL_EXPORT Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx
+
+// feed events into fltk:
+FL_EXPORT int fl_handle(const XEvent&);
+
+// you can use these in Fl::add_handler() to look at events:
+extern FL_EXPORT const XEvent* fl_xevent;
+extern FL_EXPORT ulong fl_event_time;
+
+// off-screen pixmaps: create, destroy, draw into, copy to window:
+typedef ulong Fl_Offscreen;
+#define fl_create_offscreen(w,h) \
+  XCreatePixmap(fl_display, fl_window, w, h, fl_visual->depth)
+// begin/end are macros that save the old state in local variables:
+#    define fl_begin_offscreen(pixmap) \
+  Window _sw=fl_window; fl_window=pixmap; fl_push_no_clip()
+#    define fl_end_offscreen() \
+  fl_pop_clip(); fl_window = _sw
+
+#    define fl_copy_offscreen(x,y,w,h,pixmap,srcx,srcy) \
+  XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y)
+#    define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap)
+
+// Bitmap masks
+typedef ulong Fl_Bitmask;
+
+extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data);
+extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data);
+extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm);
+
+// this object contains all X-specific stuff about a window:
+// Warning: this object is highly subject to change!  It's definition
+// is only here so that fl_xid can be declared inline:
+class FL_EXPORT Fl_X {
+public:
+  Window xid;
+  Window other_xid;
+  Fl_Window *w;
+  Fl_Region region;
+  Fl_X *next;
+  char wait_for_expose;
+  char backbuffer_bad; // used for XDBE
+  static Fl_X* first;
+  static Fl_X* i(const Fl_Window* wi) {return wi->i;}
+  void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
+  void sendxjunk();
+  static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap);
+  static Fl_X* set_xid(Fl_Window*, Window);
+  // kludges to get around protection:
+  void flush() {w->flush();}
+  static void x(Fl_Window* wi, int X) {wi->x(X);}
+  static void y(Fl_Window* wi, int Y) {wi->y(Y);}
+};
+
+// convert xid <-> Fl_Window:
+inline Window fl_xid(const Fl_Window*w) {return Fl_X::i(w)->xid;}
+FL_EXPORT Fl_Window* fl_find(Window xid);
+
+extern FL_EXPORT char fl_override_redirect; // hack into Fl_X::make_xid()
+extern FL_EXPORT int fl_background_pixel;  // hack into Fl_X::make_xid()
+
+// Dummy function to register a function for opening files via the window manager...
+inline void fl_open_callback(void (*)(const char *)) {}
+
+extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b);
+
+#  endif
+#endif
+
+//
+// End of "$Id: x.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/GL/glut.h b/Utilities/FLTK/GL/glut.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c57f0700e16407ef201cd8a71389461483ca842
--- /dev/null
+++ b/Utilities/FLTK/GL/glut.h
@@ -0,0 +1,30 @@
+//
+// "$Id$"
+//
+// GLUT compatibility header for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org".
+//
+
+#include <FL/glut.H>
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/README b/Utilities/FLTK/README
new file mode 100755
index 0000000000000000000000000000000000000000..1732a6bb8e59a46c0bed0af915a3efd1482e750a
--- /dev/null
+++ b/Utilities/FLTK/README
@@ -0,0 +1,29 @@
+FLTK modifications:
+---------------------
+
+Add following line:
+#include <FL/Fl.H>
+For:
+Fl_Overlay_Window.cxx
+Fl_grab.cxx
+Fl_own_colormap.cxx
+Fl_visual.cxx
+fl_rect.cxx
+
+src/flstring.h
+
+
+Add following line:
+#include "fltk-config.h"
+For:
+Fl_get_system_colors.cxx
+fl_draw_image.cxx
+fl_draw_pixmap.cxx
+filename_list.cxx
+src/flstring.h
+
+
+CMakeLists.txt: rename config.h file name as following:
+config.h -> fltk-config.h
+# In CMake/FLTKConfig.cmake.in add line
+SET(FLTK_PLATFORM_DEPENDENT_LIBS "@FLTK_PLATFORM_DEPENDENT_LIBS@")
diff --git a/Utilities/FLTK/configh.cmake.in b/Utilities/FLTK/configh.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..35aade4aae133afe09e401589c36d9703ae5cc92
--- /dev/null
+++ b/Utilities/FLTK/configh.cmake.in
@@ -0,0 +1,265 @@
+/*
+ * "$Id: configh.cmake.in 4454 2005-07-24 18:41:30Z matt $"
+ *
+ * Configuration file for the Fast Light Tool Kit (FLTK).
+ * @configure_input@
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems to "fltk-bugs@fltk.org".
+ */
+
+/*
+ * Where to find files...
+ */
+
+#define FLTK_DATADIR	"@FLTK_DATADIR@"
+#define FLTK_DOCDIR	"@FLTK_DOCDIR@"
+
+/*
+ * BORDER_WIDTH:
+ *
+ * Thickness of FL_UP_BOX and FL_DOWN_BOX.  Current 1,2, and 3 are
+ * supported.
+ *
+ * 3 is the historic FLTK look.
+ * 2 is the default and looks like Microsoft Windows, KDE, and Qt.
+ * 1 is a plausible future evolution...
+ *
+ * Note that this may be simulated at runtime by redefining the boxtypes
+ * using Fl::set_boxtype().
+ */
+
+#define BORDER_WIDTH 2
+
+/*
+ * HAVE_GL:
+ *
+ * Do you have OpenGL? Set this to 0 if you don't have or plan to use
+ * OpenGL, and FLTK will be smaller.
+ */
+
+#define HAVE_GL @HAVE_GL@
+
+/*
+ * HAVE_GL_GLU_H:
+ *
+ * Do you have the OpenGL Utility Library header file?
+ * (many broken Mesa RPMs do not...)
+ */
+
+#cmakedefine HAVE_GL_GLU_H @HAVE_GL_GLU_H@
+
+/*
+ * USE_COLORMAP:
+ *
+ * Setting this to zero will save a good deal of code (especially for
+ * fl_draw_image), but FLTK will only work on TrueColor visuals.
+ */
+
+#define USE_COLORMAP 1
+
+/*
+ * USE_XFT
+ *
+ * Use the new Xft library to draw anti-aliased text.
+ */
+
+#define USE_XFT 0
+
+/*
+ * HAVE_XDBE:
+ *
+ * Do we have the X double-buffer extension?
+ */
+
+#define HAVE_XDBE 0
+
+/*
+ * USE_XDBE:
+ *
+ * Actually try to use the double-buffer extension?
+ */
+
+#define USE_XDBE HAVE_XDBE
+
+/*
+ * USE_QUARTZ:
+ *
+ * Use Quartz instead of Quickdraw on Apple Mac OS X machines.
+ * FLTK was originally ported to Quickdraw which is no longer 
+ * supported by Apple. If USE_QUARTZ is defined, FLTK will be
+ * compiled using Quartz instead. This flag has no meaning on
+ * other operating systems.
+ */
+
+#cmakedefine FLTK_APPLE
+#ifdef FLTK_APPLE
+  #cmakedefine FLTK_QUARTZ
+  #ifdef FLTK_QUARTZ
+    #define USE_QUARTZ 1
+    #define __APPLE_QUARTZ__
+    #undef __APPLE_QD__
+  #else
+    #define USE_QUARTZ 0
+    #undef __APPLE_QUARTZ__
+    #define __APPLE_QD__
+  #endif
+#endif
+
+/*
+ * HAVE_OVERLAY:
+ *
+ * Use the X overlay extension?  FLTK will try to use an overlay
+ * visual for Fl_Overlay_Window, the Gl_Window overlay, and for the
+ * menus.  Setting this to zero will remove a substantial amount of
+ * code from FLTK.  Overlays have only been tested on SGI servers!
+ */
+
+#define HAVE_OVERLAY 0
+
+/*
+ * HAVE_GL_OVERLAY:
+ *
+ * It is possible your GL has an overlay even if X does not.  If so,
+ * set this to 1.
+ */
+
+#define HAVE_GL_OVERLAY HAVE_OVERLAY
+
+/*
+ * WORDS_BIGENDIAN:
+ *
+ * Byte order of your machine: 1 = big-endian, 0 = little-endian.
+ */
+
+#define WORDS_BIGENDIAN 0
+
+/*
+ * U16, U32, U64:
+ *
+ * Types used by fl_draw_image.  One of U32 or U64 must be defined.
+ * U16 is optional but FLTK will work better with it!
+ */
+
+#cmakedefine U16 @U16@
+#cmakedefine U32 @U32@
+#cmakedefine U64 @U64@
+
+/*
+ * HAVE_DIRENT_H, HAVE_SYS_NDIR_H, HAVE_SYS_DIR_H, HAVE_NDIR_H, HAVE_SCANDIR:
+ *
+ * Where is <dirent.h> (used only by fl_file_chooser and scandir).
+ */
+
+#cmakedefine HAVE_DIRENT_H @HAVE_DIRENT_H@
+#cmakedefine HAVE_SYS_NDIR_H @HAVE_SYS_NDIR_H@
+#cmakedefine HAVE_SYS_DIR_H @HAVE_SYS_DIR_H@
+#cmakedefine HAVE_NDIR_H @HAVE_NDIR_H@
+#cmakedefine HAVE_SCANDIR @HAVE_SCANDIR@
+
+/*
+ * Possibly missing sprintf-style functions:
+ */
+
+#cmakedefine HAVE_VSNPRINTF @HAVE_VSNPRINTF@
+#cmakedefine HAVE_SNPRINTF @HAVE_SNPRINTF@
+
+/*
+ * String functions and headers...
+ */
+
+#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@
+#cmakedefine HAVE_STRCASECMP @HAVE_STRCASECMP@
+#cmakedefine HAVE_STRLCAT @HAVE_STRLCAT@
+#cmakedefine HAVE_STRLCPY @HAVE_STRLCPY@
+
+/*
+ * 'locale' functions
+ */
+
+#cmakedefine HAVE_LOCALE_H @HAVE_LOCALE_H@
+#cmakedefine HAVE_LOCALECONV @HAVE_LOCALECONV@
+
+/*
+ * HAVE_SYS_SELECT_H:
+ *
+ * Whether or not select() call has its own header file.
+ */
+
+#cmakedefine HAVE_SYS_SELECT_H @HAVE_SYS_SELECT_H@
+
+/*
+ * HAVE_SYS_STDTYPES_H:
+ *
+ * Whether or not we have the <sys/stdtypes.h> header file.
+ */
+
+#cmakedefine HAVE_SYS_STDTYPES_H @HAVE_SYS_STDTYPES_H@
+
+/*
+ * USE_POLL:
+ *
+ * Use the poll() call provided on Linux and Irix instead of select()
+ */
+
+#define USE_POLL 0
+
+/*
+ * Do we have various image libraries?
+ */
+
+#cmakedefine HAVE_LIBPNG @HAVE_LIBPNG@
+#cmakedefine HAVE_LIBZ @HAVE_LIBZ@
+#cmakedefine HAVE_LIBJPEG @HAVE_LIBJPEG@
+
+/*
+ * Which header file do we include for libpng?
+ */
+
+#cmakedefine HAVE_PNG_H @HAVE_PNG_H@
+#cmakedefine HAVE_LIBPNG_PNG_H @HAVE_LIBPNG_PNG_H@
+
+/*
+ * Do we have the png_xyz() functions?
+ */
+
+#cmakedefine HAVE_PNG_GET_VALID @HAVE_PNG_GET_VALID@
+#cmakedefine HAVE_PNG_SET_TRNS_TO_ALPHA @HAVE_PNG_SET_TRNS_TO_ALPHA@
+
+/*
+ * Do we have POSIX threading?
+ */
+
+#cmakedefine CMAKE_USE_PTHREADS
+#ifdef CMAKE_USE_PTHREADS
+#define HAVE_PTHREAD 1
+#else
+#define HAVE_PTHREAD 0
+#endif
+
+#cmakedefine CMAKE_HAVE_PTHREAD_H
+#ifdef CMAKE_HAVE_PTHREAD_H
+#define HAVE_PTHREAD_H 1
+#else
+#define HAVE_PTHREAD_H 0
+#endif
+
+/*
+ * End of "$Id: configh.cmake.in 4454 2005-07-24 18:41:30Z matt $".
+ */
diff --git a/Utilities/FLTK/configh.in b/Utilities/FLTK/configh.in
new file mode 100644
index 0000000000000000000000000000000000000000..6211cb6a8283d8acf341d78c4ab7d17c3994ff20
--- /dev/null
+++ b/Utilities/FLTK/configh.in
@@ -0,0 +1,284 @@
+/*
+ * "$Id: configh.in 4702 2005-12-14 00:39:55Z mike $"
+ *
+ * Configuration file for the Fast Light Tool Kit (FLTK).
+ * @configure_input@
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+/*
+ * Where to find files...
+ */
+
+#define FLTK_DATADIR	""
+#define FLTK_DOCDIR	""
+
+/*
+ * BORDER_WIDTH:
+ *
+ * Thickness of FL_UP_BOX and FL_DOWN_BOX.  Current 1,2, and 3 are
+ * supported.
+ *
+ * 3 is the historic FLTK look.
+ * 2 is the default and looks like Microsoft Windows, KDE, and Qt.
+ * 1 is a plausible future evolution...
+ *
+ * Note that this may be simulated at runtime by redefining the boxtypes
+ * using Fl::set_boxtype().
+ */
+
+#define BORDER_WIDTH 2
+
+/*
+ * HAVE_GL:
+ *
+ * Do you have OpenGL? Set this to 0 if you don't have or plan to use
+ * OpenGL, and FLTK will be smaller.
+ */
+
+#define HAVE_GL 0
+
+/*
+ * HAVE_GL_GLU_H:
+ *
+ * Do you have the OpenGL Utility Library header file?
+ * (many broken Mesa RPMs do not...)
+ */
+
+#undef HAVE_GL_GLU_H
+
+/*
+ * USE_COLORMAP:
+ *
+ * Setting this to zero will save a good deal of code (especially for
+ * fl_draw_image), but FLTK will only work on TrueColor visuals.
+ */
+
+#define USE_COLORMAP 1
+
+/*
+ * HAVE_XINERAMA
+ *
+ * Do we have the Xinerama library to support multi-head displays?
+ */
+
+#define HAVE_XINERAMA 0
+
+/*
+ * USE_XFT
+ *
+ * Use the new Xft library to draw anti-aliased text.
+ */
+
+#define USE_XFT 0
+
+/*
+ * HAVE_XDBE:
+ *
+ * Do we have the X double-buffer extension?
+ */
+
+#define HAVE_XDBE 0
+
+/*
+ * USE_XDBE:
+ *
+ * Actually try to use the double-buffer extension?
+ */
+
+#define USE_XDBE HAVE_XDBE
+
+/*
+ * USE_QUARTZ:
+ *
+ * Use Quartz instead of Quickdraw on Apple Mac OS X machines.
+ * FLTK was originally ported to Quickdraw which is no longer 
+ * supported by Apple. If USE_QUARTZ is defined, FLTK will be
+ * compiled using Quartz instead. This flag has no meaning on
+ * other operating systems.
+ */
+
+#define USE_QUARTZ 0
+#undef __APPLE_QUARTZ__
+#undef __APPLE_QD__
+
+/*
+ * HAVE_OVERLAY:
+ *
+ * Use the X overlay extension?  FLTK will try to use an overlay
+ * visual for Fl_Overlay_Window, the Gl_Window overlay, and for the
+ * menus.  Setting this to zero will remove a substantial amount of
+ * code from FLTK.  Overlays have only been tested on SGI servers!
+ */
+
+#define HAVE_OVERLAY 0
+
+/*
+ * HAVE_GL_OVERLAY:
+ *
+ * It is possible your GL has an overlay even if X does not.  If so,
+ * set this to 1.
+ */
+
+#define HAVE_GL_OVERLAY HAVE_OVERLAY
+
+/*
+ * WORDS_BIGENDIAN:
+ *
+ * Byte order of your machine: 1 = big-endian, 0 = little-endian.
+ */
+
+#define WORDS_BIGENDIAN 0
+
+/*
+ * U16, U32, U64:
+ *
+ * Types used by fl_draw_image.  One of U32 or U64 must be defined.
+ * U16 is optional but FLTK will work better with it!
+ */
+
+#undef U16
+#undef U32
+#undef U64
+
+/*
+ * HAVE_DIRENT_H, HAVE_SYS_NDIR_H, HAVE_SYS_DIR_H, HAVE_NDIR_H, HAVE_SCANDIR:
+ *
+ * Where is <dirent.h> (used only by fl_file_chooser and scandir).
+ */
+
+#undef HAVE_DIRENT_H
+#undef HAVE_SYS_NDIR_H
+#undef HAVE_SYS_DIR_H
+#undef HAVE_NDIR_H
+#undef HAVE_SCANDIR
+
+/*
+ * Possibly missing sprintf-style functions:
+ */
+
+#undef HAVE_VSNPRINTF
+#undef HAVE_SNPRINTF
+
+/*
+ * String functions and headers...
+ */
+
+#undef HAVE_STRINGS_H
+#undef HAVE_STRCASECMP
+#undef HAVE_STRLCAT
+#undef HAVE_STRLCPY
+
+/*
+ * Do we have POSIX locale support?
+ */
+
+#undef HAVE_LOCALE_H
+#undef HAVE_LOCALECONV
+
+/*
+ * HAVE_SYS_SELECT_H:
+ *
+ * Whether or not select() call has its own header file.
+ */
+
+#undef HAVE_SYS_SELECT_H
+
+/*
+ * HAVE_SYS_STDTYPES_H:
+ *
+ * Whether or not we have the <sys/stdtypes.h> header file.
+ */
+
+#undef HAVE_SYS_STDTYPES_H
+
+/*
+ * USE_POLL:
+ *
+ * Use the poll() call provided on Linux and Irix instead of select()
+ */
+
+#define USE_POLL 0
+
+/*
+ * Do we have various image libraries?
+ */
+
+#undef HAVE_LIBPNG
+#undef HAVE_LIBZ
+#undef HAVE_LIBJPEG
+
+/*
+ * Which header file do we include for libpng?
+ */
+
+#undef HAVE_PNG_H
+#undef HAVE_LIBPNG_PNG_H
+
+/*
+ * Do we have the png_xyz() functions?
+ */
+
+#undef HAVE_PNG_GET_VALID
+#undef HAVE_PNG_SET_TRNS_TO_ALPHA
+
+/*
+ * Do we have POSIX threading?
+ */
+
+#undef HAVE_PTHREAD
+#undef HAVE_PTHREAD_H
+
+/*
+ * Do we have the ALSA library?
+ */
+
+#undef HAVE_ALSA_ASOUNDLIB_H
+
+/*
+ * Do we have the long long type?
+ */
+
+#undef HAVE_LONG_LONG
+
+#ifdef HAVE_LONG_LONG
+#  define FLTK_LLFMT	"%lld"
+#  define FLTK_LLCAST	(long long)
+#else
+#  define FLTK_LLFMT	"%ld"
+#  define FLTK_LLCAST	(long)
+#endif /* HAVE_LONG_LONG */
+
+/*
+ * Do we have the strtoll() function?
+ */
+
+#undef HAVE_STRTOLL
+
+#ifndef HAVE_STRTOLL
+#  define strtoll(nptr,endptr,base) strtol((nptr), (endptr), (base))
+#endif /* !HAVE_STRTOLL */
+
+/*
+ * End of "$Id: configh.in 4702 2005-12-14 00:39:55Z mike $".
+ */
diff --git a/Utilities/FLTK/configure b/Utilities/FLTK/configure
new file mode 100755
index 0000000000000000000000000000000000000000..80c4ded851b38a34a82c97d2b54141f151a20d73
--- /dev/null
+++ b/Utilities/FLTK/configure
@@ -0,0 +1,12583 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="src/Fl.cxx"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS FL_MAJOR_VERSION FL_MINOR_VERSION FL_PATCH_VERSION FL_API_VERSION OPTIM FLLIBNAME GLDEMOS GLLIBNAME IMGLIBNAME LIBEXT LIBNAME LINKFLTK LINKFLTKFORMS LINKFLTKGL LINKFLTKIMG DSOCOMMAND DSOLINK DSONAME FLDSONAME GLDSONAME IMGDSONAME SHAREDSUFFIX LINKSHARED FLUID CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX NROFF GROFF HTMLDOC RANLIB ac_ct_RANLIB AR LIBCOMMAND CPP EGREP LARGEFILE AUDIOLIBS IMAGELIBS JPEG JPEGINC PNG PNGINC ZLIB ZLIBINC X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS FTCONFIG GLLIB HLINKS POSTBUILD THREADS INSTALL_DESKTOP UNINSTALL_DESKTOP CAT1EXT CAT3EXT CAT6EXT MAKEDEPEND LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+X features:
+  --x-includes=DIR    X include files are in DIR
+  --x-libraries=DIR   X library files are in DIR
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-cygwin         use the CygWin libraries default=no
+  --enable-debug          turn on debugging default=no
+  --enable-gl             turn on OpenGL support default=yes
+  --enable-shared         turn on shared libraries default=no
+  --enable-threads        enable multi-threading support
+  --enable-quartz         use Quartz instead of Quickdraw (default=no)
+  --disable-largefile     omit support for large files
+  --enable-localjpeg      use local JPEG library, default=auto
+  --enable-localzlib      use local ZLIB library, default=auto
+  --enable-localpng       use local PNG library, default=auto
+  --enable-xinerama       turn on Xinerama support default=no
+  --enable-xft            turn on Xft support default=no
+  --enable-xdbe           turn on Xdbe support default=no
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-optim="flags"    use custom optimization flags
+  --with-links            make header links for common misspellings
+  --with-x                use the X Window System
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FL_MAJOR_VERSION=1
+FL_MINOR_VERSION=1
+FL_PATCH_VERSION=7
+FL_API_VERSION=${FL_MAJOR_VERSION}.${FL_MINOR_VERSION}
+
+
+
+
+
+
+uname=`uname`
+uversion=`uname -r | sed -e '1,$s/[^0-9]//g'`
+if test "x$uname" = xIRIX64; then
+    uname="IRIX"
+fi
+if test "x$uname" = x; then
+    # MingW doesn't provide any output when uname is run, even with "-s"...
+    uname="CYGWIN"
+fi
+
+CFLAGS="${CFLAGS:=}"
+CPPFLAGS="${CPPFLAGS:=}"
+CXXFLAGS="${CXXFLAGS:=}"
+OPTIM="${OPTIM:=}"
+
+
+
+case $uname in
+    CYGWIN* | MINGW*)
+        # Handle Cygwin option *first*, before all other tests.
+	# Check whether --enable-cygwin or --disable-cygwin was given.
+if test "${enable_cygwin+set}" = set; then
+  enableval="$enable_cygwin"
+
+fi;
+	if test x$enable_cygwin != xyes; then
+	    CFLAGS="$CFLAGS -mno-cygwin"
+	    CPPFLAGS="$CPPFLAGS -mno-cygwin"
+	    CXXFLAGS="$CXXFLAGS -mno-cygwin"
+	    LDFLAGS="$LDFLAGS -mno-cygwin"
+	fi
+	;;
+esac
+
+LINKFLTK="../lib/libfltk.a"
+LINKFLTKFORMS="../lib/libfltk_forms.a"
+LINKFLTKGL="../lib/libfltk_gl.a"
+LINKFLTKIMG="../lib/libfltk_images.a"
+GLDEMOS="gldemos"
+
+LIBEXT=".a"
+LIBNAME="../lib/libfltk.a"
+FLLIBNAME="../lib/libfltk_forms.a"
+GLLIBNAME="../lib/libfltk_gl.a"
+IMGLIBNAME="../lib/libfltk_images.a"
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval="$enable_debug"
+
+fi;
+if test x$enable_debug = xyes; then
+    DEBUGFLAG="-g "
+else
+    DEBUGFLAG=""
+fi
+
+# Check whether --enable-gl or --disable-gl was given.
+if test "${enable_gl+set}" = set; then
+  enableval="$enable_gl"
+
+fi;
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+
+fi;
+if test x$enable_shared = xyes; then
+    PICFLAG=1
+    SHAREDSUFFIX=""
+    FLUID="fluid-shared"
+
+    case $uname in
+	Darwin*)
+            DSONAME="libfltk.$FL_API_VERSION.dylib"
+            FLDSONAME="libfltk_forms.$FL_API_VERSION.dylib"
+            GLDSONAME="libfltk_gl.$FL_API_VERSION.dylib"
+            IMGDSONAME="libfltk_images.$FL_API_VERSION.dylib"
+	    DSOCOMMAND="\$(CC) $DSOFLAGS -dynamiclib -lc -o"
+	    ;;
+
+	SunOS* | UNIX_S*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+	    DSOCOMMAND="\$(CXX) -h \$@ \$(LDLIBS) -G $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib"; then
+		    DSOLINK="-R$libdir"
+            fi
+	    ;;
+	HP-UX*)
+            DSONAME="libfltk.sl.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.sl.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.sl.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.sl.$FL_API_VERSION"
+	    DSOCOMMAND="ld -b -z +h \$@ $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	IRIX*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@,-set_version,sgi1.1 \$(LDLIBS) -shared $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/usr/lib32" -a "x$libdir" != "x/usr/lib64"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	OSF1*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@ \$(LDLIBS) -shared $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/usr/lib32"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	Linux* | *BSD*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@ \$(LDLIBS) -shared -fPIC $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	AIX*)
+            DSONAME="libfltk_s.a"
+            FLDSONAME="libfltk_forms_s.a"
+            GLDSONAME="libfltk_gl_s.a"
+            IMGDSONAME="libfltk_images_s.a"
+            DSOCOMMAND="\$(CXX) -Wl,-bexpall,-bM:SRE,-bnoentry -o"
+            SHAREDSUFFIX="_s"
+            ;;
+        CYGWIN* | MINGW*)
+	    PICFLAG=0
+	    if test x$enable_cygwin != xyes; then
+		DSONAME="mgwfltknox-$FL_API_VERSION.dll"
+		FLDSONAME="mgwfltknox_forms-$FL_API_VERSION.dll"
+		GLDSONAME="mgwfltknox_gl-$FL_API_VERSION.dll"
+		IMGDSONAME="mgwfltknox_images-$FL_API_VERSION.dll"
+	    else
+		DSONAME="cygfltknox-$FL_API_VERSION.dll"
+		FLDSONAME="cygfltknox_forms-$FL_API_VERSION.dll"
+		GLDSONAME="cygfltknox_gl-$FL_API_VERSION.dll"
+		IMGDSONAME="cygfltknox_images-$FL_API_VERSION.dll"
+	    fi
+	    DSOCOMMAND="\$(CXX) -shared -Wl,--whole-archive -Wl,--export-all-symbols -Wl,--enable-auto-import -o \$@"
+	    ;;
+	*)
+            { echo "$as_me:$LINENO: WARNING: Shared libraries may not be supported.  Trying -shared option with compiler." >&5
+echo "$as_me: WARNING: Shared libraries may not be supported.  Trying -shared option with compiler." >&2;}
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@ \$(LDLIBS) -shared $DEBUGFLAG -o"
+	    ;;
+    esac
+
+    LINKSHARED="-L../src -lfltk_images$SHAREDSUFFIX -lfltk_forms$SHAREDSUFFIX -lfltk$SHAREDSUFFIX"
+else
+    DSOCOMMAND="echo"
+    DSOLINK=""
+    DSONAME=""
+    FLDSONAME=""
+    GLDSONAME=""
+    IMGDSONAME=""
+    PICFLAG=0
+    SHAREDSUFFIX=""
+    FLUID="fluid"
+    LINKSHARED="../lib/libfltk_images.a ../lib/libfltk_forms.a ../lib/libfltk.a"
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-threads or --disable-threads was given.
+if test "${enable_threads+set}" = set; then
+  enableval="$enable_threads"
+
+fi;
+
+
+# Check whether --with-optim or --without-optim was given.
+if test "${with_optim+set}" = set; then
+  withval="$with_optim"
+
+fi;
+
+case $uname in
+    Darwin*)
+        # Check whether --enable-quartz or --disable-quartz was given.
+if test "${enable_quartz+set}" = set; then
+  enableval="$enable_quartz"
+
+fi;
+        if test "x$enable_quartz" = "xyes"; then
+            cat >>confdefs.h <<\_ACEOF
+#define USE_QUARTZ 1
+_ACEOF
+
+            cat >>confdefs.h <<\_ACEOF
+#define __APPLE_QUARTZ__ 1
+_ACEOF
+
+        else
+            cat >>confdefs.h <<\_ACEOF
+#define __APPLE_QD__ 1
+_ACEOF
+
+        fi
+        ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Extract the first word of "nroff", so it can be a program name with args.
+set dummy nroff; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_NROFF+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $NROFF in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+NROFF=$ac_cv_path_NROFF
+
+if test -n "$NROFF"; then
+  echo "$as_me:$LINENO: result: $NROFF" >&5
+echo "${ECHO_T}$NROFF" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test "x$NROFF" = "x:"; then
+    # Extract the first word of "groff", so it can be a program name with args.
+set dummy groff; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GROFF+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GROFF in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GROFF="$GROFF" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+GROFF=$ac_cv_path_GROFF
+
+if test -n "$GROFF"; then
+  echo "$as_me:$LINENO: result: $GROFF" >&5
+echo "${ECHO_T}$GROFF" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    if test "x$GROFF" = "x:"; then
+        NROFF="echo"
+    else
+        NROFF="$GROFF -T ascii"
+    fi
+fi
+# Extract the first word of "htmldoc", so it can be a program name with args.
+set dummy htmldoc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_HTMLDOC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $HTMLDOC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_HTMLDOC="$HTMLDOC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_HTMLDOC="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+HTMLDOC=$ac_cv_path_HTMLDOC
+
+if test -n "$HTMLDOC"; then
+  echo "$as_me:$LINENO: result: $HTMLDOC" >&5
+echo "${ECHO_T}$HTMLDOC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+# Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $AR in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_AR="$AR" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+AR=$ac_cv_path_AR
+
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+if test "x$AR" = "x:"; then
+    { { echo "$as_me:$LINENO: error: Configure could not find the library archiver" >&5
+echo "$as_me: error: Configure could not find the library archiver" >&2;}
+   { (exit aborting.); exit aborting.; }; }
+fi
+
+if test "x$RANLIB" != "x:"; then
+    LIBCOMMAND="$AR cr"
+else
+    LIBCOMMAND="$AR crs"
+fi
+
+
+
+
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for short" >&5
+echo $ECHO_N "checking for short... $ECHO_C" >&6
+if test "${ac_cv_type_short+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((short *) 0)
+  return 0;
+if (sizeof (short))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_short=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_short=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5
+echo "${ECHO_T}$ac_cv_type_short" >&6
+
+echo "$as_me:$LINENO: checking size of short" >&5
+echo $ECHO_N "checking size of short... $ECHO_C" >&6
+if test "${ac_cv_sizeof_short+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_short" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_short=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (short)); }
+unsigned long ulongval () { return (long) (sizeof (short)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (short))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (short))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (short))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_short=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_short=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5
+echo "${ECHO_T}$ac_cv_sizeof_short" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for int" >&5
+echo $ECHO_N "checking for int... $ECHO_C" >&6
+if test "${ac_cv_type_int+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((int *) 0)
+  return 0;
+if (sizeof (int))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
+echo "${ECHO_T}$ac_cv_type_int" >&6
+
+echo "$as_me:$LINENO: checking size of int" >&5
+echo $ECHO_N "checking size of int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_int" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_int=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (int)); }
+unsigned long ulongval () { return (long) (sizeof (int)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (int))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (int))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (int))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_int=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_int=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+  return 0;
+if (sizeof (long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+if test $ac_cv_sizeof_short -eq 2; then
+    cat >>confdefs.h <<\_ACEOF
+#define U16 unsigned short
+_ACEOF
+
+fi
+if test $ac_cv_sizeof_int -eq 4; then
+    cat >>confdefs.h <<\_ACEOF
+#define U32 unsigned
+_ACEOF
+
+else
+    if test $ac_cv_sizeof_long -eq 4; then
+        cat >>confdefs.h <<\_ACEOF
+#define U32 unsigned long
+_ACEOF
+
+    fi
+fi
+if test $ac_cv_sizeof_int -eq 8; then
+    cat >>confdefs.h <<\_ACEOF
+#define U64 unsigned
+_ACEOF
+
+else
+    if test $ac_cv_sizeof_long -eq 8; then
+        cat >>confdefs.h <<\_ACEOF
+#define U64 unsigned long
+_ACEOF
+
+    fi
+fi
+
+
+echo "$as_me:$LINENO: checking whether the compiler recognizes bool as a built-in type" >&5
+echo $ECHO_N "checking whether the compiler recognizes bool as a built-in type... $ECHO_C" >&6
+if test "${ac_cv_cxx_bool+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+	ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+	    int f(int  x){return 1;}
+	    int f(char x){return 1;}
+	    int f(bool x){return 1;}
+
+int
+main ()
+{
+
+	    bool b = true;
+	    return f(b);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_cxx_bool=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_cxx_bool=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+	ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_bool" >&5
+echo "${ECHO_T}$ac_cv_cxx_bool" >&6
+
+if test "$ac_cv_cxx_bool" != yes; then
+    CXXFLAGS="-Dbool=char -Dfalse=0 -Dtrue=1 $CXXFLAGS"
+fi
+
+
+
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in dir; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+else
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in x; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+fi
+
+if test "${ac_cv_header_sys_select_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/select.h" >&5
+echo $ECHO_N "checking for sys/select.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_select_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_select_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_select_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/select.h usability" >&5
+echo $ECHO_N "checking sys/select.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/select.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/select.h presence" >&5
+echo $ECHO_N "checking sys/select.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/select.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/select.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/select.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/select.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/select.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/select.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/select.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/select.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/select.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/select.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/select.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/select.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/select.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/select.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/select.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/select.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/select.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for sys/select.h" >&5
+echo $ECHO_N "checking for sys/select.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_select_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_select_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_select_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_select_h" >&6
+
+fi
+if test $ac_cv_header_sys_select_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_SELECT_H 1
+_ACEOF
+
+fi
+
+
+if test "${ac_cv_header_sys_stdtypes_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/stdtypes.h" >&5
+echo $ECHO_N "checking for sys/stdtypes.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_stdtypes_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_stdtypes_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_stdtypes_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/stdtypes.h usability" >&5
+echo $ECHO_N "checking sys/stdtypes.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/stdtypes.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/stdtypes.h presence" >&5
+echo $ECHO_N "checking sys/stdtypes.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stdtypes.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/stdtypes.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/stdtypes.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/stdtypes.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/stdtypes.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/stdtypes.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/stdtypes.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/stdtypes.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/stdtypes.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/stdtypes.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for sys/stdtypes.h" >&5
+echo $ECHO_N "checking for sys/stdtypes.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_stdtypes_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_stdtypes_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_stdtypes_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_stdtypes_h" >&6
+
+fi
+if test $ac_cv_header_sys_stdtypes_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_SELECT_H 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for scandir" >&5
+echo $ECHO_N "checking for scandir... $ECHO_C" >&6
+if test "${ac_cv_func_scandir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define scandir to an innocuous variant, in case <limits.h> declares scandir.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define scandir innocuous_scandir
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char scandir (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef scandir
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char scandir ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_scandir) || defined (__stub___scandir)
+choke me
+#else
+char (*f) () = scandir;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != scandir;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_scandir=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_scandir=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_scandir" >&5
+echo "${ECHO_T}$ac_cv_func_scandir" >&6
+if test $ac_cv_func_scandir = yes; then
+  if test "x$uname" = xSunOS -o "x$uname" = xQNX; then
+        { echo "$as_me:$LINENO: WARNING: Not using $uname scandir emulation function." >&5
+echo "$as_me: WARNING: Not using $uname scandir emulation function." >&2;}
+    else
+        cat >>confdefs.h <<\_ACEOF
+#define HAVE_SCANDIR 1
+_ACEOF
+
+    fi
+fi
+
+echo "$as_me:$LINENO: checking for vsnprintf" >&5
+echo $ECHO_N "checking for vsnprintf... $ECHO_C" >&6
+if test "${ac_cv_func_vsnprintf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define vsnprintf to an innocuous variant, in case <limits.h> declares vsnprintf.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define vsnprintf innocuous_vsnprintf
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char vsnprintf (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef vsnprintf
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char vsnprintf ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_vsnprintf) || defined (__stub___vsnprintf)
+choke me
+#else
+char (*f) () = vsnprintf;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != vsnprintf;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_vsnprintf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_vsnprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_vsnprintf" >&5
+echo "${ECHO_T}$ac_cv_func_vsnprintf" >&6
+if test $ac_cv_func_vsnprintf = yes; then
+
+    case "$uname" in
+    	HP-UX*)
+	    if test "$uversion" = "1020"; then
+	        { echo "$as_me:$LINENO: WARNING: Not using built-in vsnprintf function because you are running HP-UX 10.20." >&5
+echo "$as_me: WARNING: Not using built-in vsnprintf function because you are running HP-UX 10.20." >&2;}
+	    else
+        	cat >>confdefs.h <<\_ACEOF
+#define HAVE_VSNPRINTF 1
+_ACEOF
+
+	    fi
+	    ;;
+
+    	OSF1*)
+	    if test "$uversion" = "40"; then
+                { echo "$as_me:$LINENO: WARNING: Not using built-in vsnprintf function because you are running Tru64 4.0." >&5
+echo "$as_me: WARNING: Not using built-in vsnprintf function because you are running Tru64 4.0." >&2;}
+	    else
+        	cat >>confdefs.h <<\_ACEOF
+#define HAVE_VSNPRINTF 1
+_ACEOF
+
+	    fi
+	    ;;
+
+        *)
+            cat >>confdefs.h <<\_ACEOF
+#define HAVE_VSNPRINTF 1
+_ACEOF
+
+	    ;;
+    esac
+fi
+
+echo "$as_me:$LINENO: checking for snprintf" >&5
+echo $ECHO_N "checking for snprintf... $ECHO_C" >&6
+if test "${ac_cv_func_snprintf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define snprintf to an innocuous variant, in case <limits.h> declares snprintf.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define snprintf innocuous_snprintf
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char snprintf (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef snprintf
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char snprintf ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_snprintf) || defined (__stub___snprintf)
+choke me
+#else
+char (*f) () = snprintf;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != snprintf;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_snprintf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_snprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_snprintf" >&5
+echo "${ECHO_T}$ac_cv_func_snprintf" >&6
+if test $ac_cv_func_snprintf = yes; then
+
+    case "$uname" in
+    	HP-UX*)
+	    if test "$uversion" = "1020"; then
+	        { echo "$as_me:$LINENO: WARNING: Not using built-in snprintf function because you are running HP-UX 10.20." >&5
+echo "$as_me: WARNING: Not using built-in snprintf function because you are running HP-UX 10.20." >&2;}
+	    else
+        	cat >>confdefs.h <<\_ACEOF
+#define HAVE_SNPRINTF 1
+_ACEOF
+
+	    fi
+	    ;;
+
+    	OSF1*)
+	    if test "$uversion" = "40"; then
+                { echo "$as_me:$LINENO: WARNING: Not using built-in snprintf function because you are running Tru64 4.0." >&5
+echo "$as_me: WARNING: Not using built-in snprintf function because you are running Tru64 4.0." >&2;}
+	    else
+        	cat >>confdefs.h <<\_ACEOF
+#define HAVE_SNPRINTF 1
+_ACEOF
+
+	    fi
+	    ;;
+
+        *)
+            cat >>confdefs.h <<\_ACEOF
+#define HAVE_SNPRINTF 1
+_ACEOF
+
+	    ;;
+    esac
+fi
+
+if test "${ac_cv_header_strings_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for strings.h" >&5
+echo $ECHO_N "checking for strings.h... $ECHO_C" >&6
+if test "${ac_cv_header_strings_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_strings_h" >&5
+echo "${ECHO_T}$ac_cv_header_strings_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking strings.h usability" >&5
+echo $ECHO_N "checking strings.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <strings.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking strings.h presence" >&5
+echo $ECHO_N "checking strings.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <strings.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: strings.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: strings.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: strings.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: strings.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: strings.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: strings.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: strings.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: strings.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: strings.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: strings.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: strings.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: strings.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: strings.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: strings.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: strings.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: strings.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for strings.h" >&5
+echo $ECHO_N "checking for strings.h... $ECHO_C" >&6
+if test "${ac_cv_header_strings_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_strings_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_strings_h" >&5
+echo "${ECHO_T}$ac_cv_header_strings_h" >&6
+
+fi
+if test $ac_cv_header_strings_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRINGS_H 1
+_ACEOF
+
+fi
+
+
+
+
+
+for ac_func in strcasecmp strlcat strlcpy
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+if test "${ac_cv_header_locale_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for locale.h" >&5
+echo $ECHO_N "checking for locale.h... $ECHO_C" >&6
+if test "${ac_cv_header_locale_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5
+echo "${ECHO_T}$ac_cv_header_locale_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking locale.h usability" >&5
+echo $ECHO_N "checking locale.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <locale.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking locale.h presence" >&5
+echo $ECHO_N "checking locale.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <locale.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: locale.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: locale.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: locale.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: locale.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: locale.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: locale.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: locale.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: locale.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: locale.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: locale.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: locale.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: locale.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for locale.h" >&5
+echo $ECHO_N "checking for locale.h... $ECHO_C" >&6
+if test "${ac_cv_header_locale_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_locale_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5
+echo "${ECHO_T}$ac_cv_header_locale_h" >&6
+
+fi
+if test $ac_cv_header_locale_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_LOCALE_H 1
+_ACEOF
+
+fi
+
+
+
+for ac_func in localeconv
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+echo "$as_me:$LINENO: checking for library containing pow" >&5
+echo $ECHO_N "checking for library containing pow... $ECHO_C" >&6
+if test "${ac_cv_search_pow+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_pow=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pow ();
+int
+main ()
+{
+pow ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_pow="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_pow" = no; then
+  for ac_lib in m; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pow ();
+int
+main ()
+{
+pow ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_pow="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_pow" >&5
+echo "${ECHO_T}$ac_cv_search_pow" >&6
+if test "$ac_cv_search_pow" != no; then
+  test "$ac_cv_search_pow" = "none required" || LIBS="$ac_cv_search_pow $LIBS"
+
+fi
+
+
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+  enableval="$enable_largefile"
+
+fi;
+if test "$enable_largefile" != no; then
+
+  echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+     	 # IRIX 6.2 and later do not support large files by default,
+     	 # so use the C compiler's -n32 option if that helps.
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+     	 rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+     	 CC="$CC -n32"
+     	 rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_largefile_CC=' -n32'; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+	 break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
+
+  echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  ac_cv_sys_file_offset_bits=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_file_offset_bits=64; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
+if test "$ac_cv_sys_file_offset_bits" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+
+fi
+rm -f conftest*
+  echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_large_files+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  ac_cv_sys_large_files=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_large_files=1; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6
+if test "$ac_cv_sys_large_files" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+
+fi
+rm -f conftest*
+fi
+
+
+LARGEFILE=""
+if test x$enable_largefile != xno; then
+	LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
+
+	if test $ac_cv_sys_large_files = 1; then
+		LARGEFILE="$LARGEFILE -D_LARGE_FILES"
+	fi
+
+	if test $ac_cv_sys_file_offset_bits = 64; then
+		LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64"
+	fi
+fi
+
+
+echo "$as_me:$LINENO: checking for long long int" >&5
+echo $ECHO_N "checking for long long int... $ECHO_C" >&6
+if test "${ac_cv_c_long_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$GCC" = yes; then
+		ac_cv_c_long_long=yes
+	else
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+long long int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_long_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_long_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+	fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_long_long" >&5
+echo "${ECHO_T}$ac_cv_c_long_long" >&6
+
+if test $ac_cv_c_long_long = yes; then
+	cat >>confdefs.h <<\_ACEOF
+#define HAVE_LONG_LONG 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for strtoll" >&5
+echo $ECHO_N "checking for strtoll... $ECHO_C" >&6
+if test "${ac_cv_func_strtoll+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define strtoll to an innocuous variant, in case <limits.h> declares strtoll.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define strtoll innocuous_strtoll
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char strtoll (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef strtoll
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strtoll ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_strtoll) || defined (__stub___strtoll)
+choke me
+#else
+char (*f) () = strtoll;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != strtoll;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_strtoll=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_strtoll=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_strtoll" >&5
+echo "${ECHO_T}$ac_cv_func_strtoll" >&6
+if test $ac_cv_func_strtoll = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRTOLL 1
+_ACEOF
+
+fi
+
+
+AUDIOLIBS=""
+
+case $uname in
+    CYGWIN* | MINGW*)
+		AUDIOLIBS="-lwinmm"
+	;;
+
+    Darwin*)
+	AUDIOLIBS="-framework CoreAudio"
+	;;
+
+    *)
+	if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5
+echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking alsa/asoundlib.h usability" >&5
+echo $ECHO_N "checking alsa/asoundlib.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <alsa/asoundlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking alsa/asoundlib.h presence" >&5
+echo $ECHO_N "checking alsa/asoundlib.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <alsa/asoundlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5
+echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_alsa_asoundlib_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6
+
+fi
+if test $ac_cv_header_alsa_asoundlib_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALSA_ASOUNDLIB_H 1
+_ACEOF
+
+	    AUDIOLIBS="-lasound"
+fi
+
+
+        ;;
+esac
+
+
+
+SAVELIBS="$LIBS"
+IMAGELIBS=""
+
+
+
+# Check whether --enable-localjpeg or --disable-localjpeg was given.
+if test "${enable_localjpeg+set}" = set; then
+  enableval="$enable_localjpeg"
+  if test x$enable_localjpeg = xyes; then
+	ac_cv_lib_jpeg_jpeg_CreateCompress=no
+    fi
+fi;
+
+echo "$as_me:$LINENO: checking for jpeg_CreateCompress in -ljpeg" >&5
+echo $ECHO_N "checking for jpeg_CreateCompress in -ljpeg... $ECHO_C" >&6
+if test "${ac_cv_lib_jpeg_jpeg_CreateCompress+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljpeg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char jpeg_CreateCompress ();
+int
+main ()
+{
+jpeg_CreateCompress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_jpeg_jpeg_CreateCompress=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_jpeg_jpeg_CreateCompress=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_jpeg_CreateCompress" >&5
+echo "${ECHO_T}$ac_cv_lib_jpeg_jpeg_CreateCompress" >&6
+if test $ac_cv_lib_jpeg_jpeg_CreateCompress = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBJPEG 1
+_ACEOF
+
+    JPEGINC=""
+    JPEG=""
+    IMAGELIBS="-ljpeg $IMAGELIBS"
+else
+  if test x$enable_localjpeg = xno; then
+	JPEGINC=""
+	JPEG=""
+    else
+	cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBJPEG 1
+_ACEOF
+
+	JPEGINC="-I../jpeg"
+	JPEG="jpeg"
+	IMAGELIBS="-lfltk_jpeg $IMAGELIBS"
+    fi
+fi
+
+
+# Check whether --enable-localzlib or --disable-localzlib was given.
+if test "${enable_localzlib+set}" = set; then
+  enableval="$enable_localzlib"
+  if test x$enable_localzlib = xyes; then
+	ac_cv_lib_z_gzgets=no
+    fi
+fi;
+
+echo "$as_me:$LINENO: checking for gzgets in -lz" >&5
+echo $ECHO_N "checking for gzgets in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_gzgets+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gzgets ();
+int
+main ()
+{
+gzgets ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_z_gzgets=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_gzgets=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzgets" >&5
+echo "${ECHO_T}$ac_cv_lib_z_gzgets" >&6
+if test $ac_cv_lib_z_gzgets = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+    ZLIBINC=""
+    ZLIB=""
+    LIBS="-lz $LIBS"
+    IMAGELIBS="-lz $IMAGELIBS"
+else
+  if test x$enable_localzlib = xno; then
+	ZLIBINC=""
+	ZLIB=""
+    else
+        cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+	ZLIBINC="-I../zlib"
+	ZLIB="zlib"
+	LIBS="-lfltk_z $LIBS"
+	IMAGELIBS="-lfltk_z $IMAGELIBS"
+    fi
+fi
+
+
+# Check whether --enable-localpng or --disable-localpng was given.
+if test "${enable_localpng+set}" = set; then
+  enableval="$enable_localpng"
+  if test x$enable_localpng = xyes; then
+	ac_cv_lib_png_png_set_tRNS_to_alpha=no
+    fi
+fi;
+
+echo "$as_me:$LINENO: checking for png_set_tRNS_to_alpha in -lpng" >&5
+echo $ECHO_N "checking for png_set_tRNS_to_alpha in -lpng... $ECHO_C" >&6
+if test "${ac_cv_lib_png_png_set_tRNS_to_alpha+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char png_set_tRNS_to_alpha ();
+int
+main ()
+{
+png_set_tRNS_to_alpha ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_png_png_set_tRNS_to_alpha=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_png_png_set_tRNS_to_alpha=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_set_tRNS_to_alpha" >&5
+echo "${ECHO_T}$ac_cv_lib_png_png_set_tRNS_to_alpha" >&6
+if test $ac_cv_lib_png_png_set_tRNS_to_alpha = yes; then
+
+    PNGINC=""
+    PNG=""
+    IMAGELIBS="-lpng $IMAGELIBS"
+    cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBPNG 1
+_ACEOF
+
+    if test "${ac_cv_header_png_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for png.h" >&5
+echo $ECHO_N "checking for png.h... $ECHO_C" >&6
+if test "${ac_cv_header_png_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5
+echo "${ECHO_T}$ac_cv_header_png_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking png.h usability" >&5
+echo $ECHO_N "checking png.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <png.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking png.h presence" >&5
+echo $ECHO_N "checking png.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <png.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: png.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: png.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: png.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: png.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: png.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: png.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: png.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: png.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: png.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: png.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: png.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: png.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for png.h" >&5
+echo $ECHO_N "checking for png.h... $ECHO_C" >&6
+if test "${ac_cv_header_png_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_png_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5
+echo "${ECHO_T}$ac_cv_header_png_h" >&6
+
+fi
+if test $ac_cv_header_png_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PNG_H 1
+_ACEOF
+
+fi
+
+
+else
+
+    if test x$enable_localpng = xno; then
+        PNGINC=""
+        PNG=""
+    else
+	cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBPNG 1
+_ACEOF
+
+        cat >>confdefs.h <<\_ACEOF
+#define HAVE_PNG_H 1
+_ACEOF
+
+        PNGINC="-I../png"
+        PNG="png"
+        IMAGELIBS="-lfltk_png $IMAGELIBS"
+    fi
+fi
+
+
+
+
+
+
+
+
+
+LIBS="$SAVELIBS"
+
+
+
+have_pthread=no
+
+if test "x$enable_threads" = xyes; then
+    if test "${ac_cv_header_pthread_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for pthread.h" >&5
+echo $ECHO_N "checking for pthread.h... $ECHO_C" >&6
+if test "${ac_cv_header_pthread_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_pthread_h" >&5
+echo "${ECHO_T}$ac_cv_header_pthread_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking pthread.h usability" >&5
+echo $ECHO_N "checking pthread.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <pthread.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking pthread.h presence" >&5
+echo $ECHO_N "checking pthread.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <pthread.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: pthread.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: pthread.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pthread.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: pthread.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: pthread.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: pthread.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pthread.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: pthread.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pthread.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: pthread.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pthread.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: pthread.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pthread.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: pthread.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pthread.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: pthread.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for pthread.h" >&5
+echo $ECHO_N "checking for pthread.h... $ECHO_C" >&6
+if test "${ac_cv_header_pthread_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_pthread_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_pthread_h" >&5
+echo "${ECHO_T}$ac_cv_header_pthread_h" >&6
+
+fi
+if test $ac_cv_header_pthread_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PTHREAD_H 1
+_ACEOF
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
+echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_create ();
+int
+main ()
+{
+pthread_create ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread_pthread_create=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_create=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6
+if test $ac_cv_lib_pthread_pthread_create = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+  LIBS="-lpthread $LIBS"
+
+fi
+
+
+    if test "x$ac_cv_lib_pthread_pthread_create" = xyes -a x$ac_cv_header_pthread_h = xyes; then
+        have_pthread=yes
+    else
+                echo "$as_me:$LINENO: checking for pthread_create using -pthread" >&5
+echo $ECHO_N "checking for pthread_create using -pthread... $ECHO_C" >&6
+	SAVELIBS="$LIBS"
+	LIBS="-pthread $LIBS"
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_create(0, 0, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  LIBS="-pthread $SAVELIBS"
+            have_pthread=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+LIBS="$SAVELIBS"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+        echo "$as_me:$LINENO: result: $have_pthread" >&5
+echo "${ECHO_T}$have_pthread" >&6
+    fi
+fi
+
+HLINKS=
+POSTBUILD=:
+THREADS=
+
+
+# Check whether --with-links or --without-links was given.
+if test "${with_links+set}" = set; then
+  withval="$with_links"
+
+fi;
+
+INSTALL_DESKTOP=""
+UNINSTALL_DESKTOP=""
+
+case $uname in
+    CYGWIN* | MINGW*)
+		CFLAGS="-mwindows -DWIN32 $CFLAGS"
+	CXXFLAGS="-mwindows -DWIN32 $CXXFLAGS"
+	LDFLAGS="-mwindows $LDFLAGS"
+	LIBS="$LIBS -lole32 -luuid -lcomctl32 -lwsock32"
+	OPTIM="$OPTIM"
+
+	if test x$enable_gl != xno; then
+	    if test "${ac_cv_header_GL_gl_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for GL/gl.h" >&5
+echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_gl_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking GL/gl.h usability" >&5
+echo $ECHO_N "checking GL/gl.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <GL/gl.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking GL/gl.h presence" >&5
+echo $ECHO_N "checking GL/gl.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <GL/gl.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: GL/gl.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: GL/gl.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: GL/gl.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: GL/gl.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: GL/gl.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for GL/gl.h" >&5
+echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_gl_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_GL_gl_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6
+
+fi
+if test $ac_cv_header_GL_gl_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_GL 1
+_ACEOF
+
+		GLLIB="-lopengl32"
+fi
+
+
+	    if test "${ac_cv_header_GL_glu_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for GL/glu.h" >&5
+echo $ECHO_N "checking for GL/glu.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_glu_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_glu_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_glu_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking GL/glu.h usability" >&5
+echo $ECHO_N "checking GL/glu.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <GL/glu.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking GL/glu.h presence" >&5
+echo $ECHO_N "checking GL/glu.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <GL/glu.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: GL/glu.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: GL/glu.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: GL/glu.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: GL/glu.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: GL/glu.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: GL/glu.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: GL/glu.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: GL/glu.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for GL/glu.h" >&5
+echo $ECHO_N "checking for GL/glu.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_glu_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_GL_glu_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_glu_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_glu_h" >&6
+
+fi
+if test $ac_cv_header_GL_glu_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_GL_GLU_H 1
+_ACEOF
+
+		GLLIB="-lglu32 $GLLIB"
+fi
+
+
+	else
+	    LINKFLTKGL=""
+	    GLLIBNAME=""
+	    GLDSONAME=""
+	    GLDEMOS=""
+	fi
+
+	if test "x$enable_threads" = xyes; then
+	    if test x$have_pthread = xyes; then
+		cat >>confdefs.h <<\_ACEOF
+#define HAVE_PTHREAD 1
+_ACEOF
+
+	    fi
+
+	    THREADS="threads.exe"
+        fi
+
+	# Don't make symlinks since Windows is not case sensitive.
+	if test "x$with_links" != xyes; then
+		HLINKS="#"
+	fi
+	;;
+
+    Darwin*)
+        # MacOS X uses Carbon for graphics...
+        LIBS="$LIBS -framework Carbon -framework ApplicationServices"
+
+	if test x$have_pthread = xyes; then
+	    cat >>confdefs.h <<\_ACEOF
+#define HAVE_PTHREAD 1
+_ACEOF
+
+	    THREADS="threads"
+	fi
+
+	if test x$enable_gl != xno; then
+            cat >>confdefs.h <<\_ACEOF
+#define HAVE_GL 1
+_ACEOF
+
+            cat >>confdefs.h <<\_ACEOF
+#define HAVE_GL_GLU_H 1
+_ACEOF
+
+            GLLIB="-framework AGL -framework OpenGL"
+        else
+	    LINKFLTKGL=""
+	    GLLIBNAME=""
+	    GLDSONAME=""
+	    GLDEMOS=""
+        fi
+
+	# Don't make symlinks because HFS+ is not case sensitive...
+	if test "x$with_links" != xyes; then
+		HLINKS="#"
+	fi
+
+	# Add a postbuild step after linking applications
+	POSTBUILD="/Developer/Tools/Rez -t APPL -o"
+
+	# Install/Uninstall FLUID application
+	INSTALL_DESKTOP="install-osx"
+	UNINSTALL_DESKTOP="uninstall-osx"
+	;;
+
+    *)
+	# All others are UNIX/X11...
+	if test x$have_pthread = xyes; then
+	    cat >>confdefs.h <<\_ACEOF
+#define HAVE_PTHREAD 1
+_ACEOF
+
+	    THREADS="threads"
+	fi
+
+		echo "$as_me:$LINENO: checking for X" >&5
+echo $ECHO_N "checking for X... $ECHO_C" >&6
+
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+  withval="$with_x"
+
+fi;
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+    # Both variables are already set.
+    have_x=yes
+  else
+    if test "${ac_cv_have_x+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=no ac_x_libraries=no
+rm -fr conftest.dir
+if mkdir conftest.dir; then
+  cd conftest.dir
+  # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+  cat >Imakefile <<'_ACEOF'
+acfindx:
+	@echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+_ACEOF
+  if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl; do
+      if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+	 test -f $ac_im_libdir/libX11.$ac_extension; then
+	ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case $ac_im_incroot in
+	/usr/include) ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
+    esac
+    case $ac_im_usrlibdir in
+	/usr/lib | /lib) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
+    esac
+  fi
+  cd ..
+  rm -fr conftest.dir
+fi
+
+# Standard set of common directories for X headers.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ac_x_header_dirs='
+/usr/X11/include
+/usr/X11R6/include
+/usr/X11R5/include
+/usr/X11R4/include
+
+/usr/include/X11
+/usr/include/X11R6
+/usr/include/X11R5
+/usr/include/X11R4
+
+/usr/local/X11/include
+/usr/local/X11R6/include
+/usr/local/X11R5/include
+/usr/local/X11R4/include
+
+/usr/local/include/X11
+/usr/local/include/X11R6
+/usr/local/include/X11R5
+/usr/local/include/X11R4
+
+/usr/X386/include
+/usr/x386/include
+/usr/XFree86/include/X11
+
+/usr/include
+/usr/local/include
+/usr/unsupported/include
+/usr/athena/include
+/usr/local/x11r5/include
+/usr/lpp/Xamples/include
+
+/usr/openwin/include
+/usr/openwin/share/include'
+
+if test "$ac_x_includes" = no; then
+  # Guess where to find include files, by looking for Intrinsic.h.
+  # First, try using that file with no special directory specified.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Intrinsic.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  for ac_dir in $ac_x_header_dirs; do
+  if test -r "$ac_dir/X11/Intrinsic.h"; then
+    ac_x_includes=$ac_dir
+    break
+  fi
+done
+fi
+rm -f conftest.err conftest.$ac_ext
+fi # $ac_x_includes = no
+
+if test "$ac_x_libraries" = no; then
+  # Check for the libraries.
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS=$LIBS
+  LIBS="-lXt $LIBS"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Intrinsic.h>
+int
+main ()
+{
+XtMalloc (0)
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  LIBS=$ac_save_LIBS
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+LIBS=$ac_save_LIBS
+for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+do
+  # Don't even attempt the hair of trying to link an X program!
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/libXt.$ac_extension; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi # $ac_x_libraries = no
+
+if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then
+  # Didn't find X anywhere.  Cache the known absence of X.
+  ac_cv_have_x="have_x=no"
+else
+  # Record where we found X for the cache.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+
+  fi
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  echo "$as_me:$LINENO: result: $have_x" >&5
+echo "${ECHO_T}$have_x" >&6
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+  echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5
+echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6
+fi
+
+if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+
+cat >>confdefs.h <<\_ACEOF
+#define X_DISPLAY_MISSING 1
+_ACEOF
+
+  X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+  if test -n "$x_includes"; then
+    X_CFLAGS="$X_CFLAGS -I$x_includes"
+  fi
+
+  # It would also be nice to do this for all -L options, not just this one.
+  if test -n "$x_libraries"; then
+    X_LIBS="$X_LIBS -L$x_libraries"
+    # For Solaris; some versions of Sun CC require a space after -R and
+    # others require no space.  Words are not sufficient . . . .
+    case `(uname -sr) 2>/dev/null` in
+    "SunOS 5"*)
+      echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5
+echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&6
+      ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries"
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_R_nospace=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_R_nospace=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+      if test $ac_R_nospace = yes; then
+	echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+	X_LIBS="$X_LIBS -R$x_libraries"
+      else
+	LIBS="$ac_xsave_LIBS -R $x_libraries"
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_R_space=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_R_space=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+	if test $ac_R_space = yes; then
+	  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+	  X_LIBS="$X_LIBS -R $x_libraries"
+	else
+	  echo "$as_me:$LINENO: result: neither works" >&5
+echo "${ECHO_T}neither works" >&6
+	fi
+      fi
+      LIBS=$ac_xsave_LIBS
+    esac
+  fi
+
+  # Check for system-dependent libraries X programs must link with.
+  # Do this before checking for the system-independent R6 libraries
+  # (-lICE), since we may need -lsocket or whatever for X linking.
+
+  if test "$ISC" = yes; then
+    X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+  else
+    # Martyn Johnson says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And Karl Berry says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char XOpenDisplay ();
+int
+main ()
+{
+XOpenDisplay ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5
+echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6
+if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dnet_ntoa ();
+int
+main ()
+{
+dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dnet_dnet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dnet_dnet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6
+if test $ac_cv_lib_dnet_dnet_ntoa = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5
+echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6
+if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet_stub  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dnet_ntoa ();
+int
+main ()
+{
+dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dnet_stub_dnet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dnet_stub_dnet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6
+if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+fi
+
+    fi
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+    LIBS="$ac_xsave_LIBS"
+
+    # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4)
+    # needs -lnsl.
+    # The nsl library prevents programs from opening the X display
+    # on Irix 5.2, according to T.E. Dickey.
+    # The functions gethostbyname, getservbyname, and inet_addr are
+    # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
+    echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+char (*f) () = gethostbyname;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gethostbyname;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
+
+    if test $ac_cv_func_gethostbyname = no; then
+      echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+fi
+
+      if test $ac_cv_lib_nsl_gethostbyname = no; then
+	echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5
+echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6
+if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bsd_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bsd_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6
+if test $ac_cv_lib_bsd_gethostbyname = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
+fi
+
+      fi
+    fi
+
+    # lieder@skyler.mavd.honeywell.com says without -lsocket,
+    # socket/setsockopt and other routines are undefined under SCO ODT
+    # 2.0.  But -lsocket is broken on IRIX 5.2 (and is not necessary
+    # on later versions), says Simon Leinen: it contains gethostby*
+    # variants that don't use the name server (or something).  -lsocket
+    # must be given before -lnsl if both are needed.  We assume that
+    # if connect needs -lnsl, so does gethostbyname.
+    echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+
+    if test $ac_cv_func_connect = no; then
+      echo "$as_me:$LINENO: checking for connect in -lsocket" >&5
+echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+int
+main ()
+{
+connect ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6
+if test $ac_cv_lib_socket_connect = yes; then
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+fi
+
+    fi
+
+    # Guillermo Gomez says -lposix is necessary on A/UX.
+    echo "$as_me:$LINENO: checking for remove" >&5
+echo $ECHO_N "checking for remove... $ECHO_C" >&6
+if test "${ac_cv_func_remove+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define remove to an innocuous variant, in case <limits.h> declares remove.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define remove innocuous_remove
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char remove (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef remove
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char remove ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+char (*f) () = remove;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != remove;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_remove=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_remove=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5
+echo "${ECHO_T}$ac_cv_func_remove" >&6
+
+    if test $ac_cv_func_remove = no; then
+      echo "$as_me:$LINENO: checking for remove in -lposix" >&5
+echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6
+if test "${ac_cv_lib_posix_remove+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lposix  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char remove ();
+int
+main ()
+{
+remove ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_posix_remove=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_posix_remove=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5
+echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6
+if test $ac_cv_lib_posix_remove = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    echo "$as_me:$LINENO: checking for shmat" >&5
+echo $ECHO_N "checking for shmat... $ECHO_C" >&6
+if test "${ac_cv_func_shmat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shmat to an innocuous variant, in case <limits.h> declares shmat.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shmat innocuous_shmat
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shmat (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef shmat
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shmat ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+char (*f) () = shmat;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shmat;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_shmat=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shmat=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5
+echo "${ECHO_T}$ac_cv_func_shmat" >&6
+
+    if test $ac_cv_func_shmat = no; then
+      echo "$as_me:$LINENO: checking for shmat in -lipc" >&5
+echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6
+if test "${ac_cv_lib_ipc_shmat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lipc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shmat ();
+int
+main ()
+{
+shmat ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ipc_shmat=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ipc_shmat=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5
+echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6
+if test $ac_cv_lib_ipc_shmat = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+fi
+
+    fi
+  fi
+
+  # Check for libraries that X11R6 Xt/Xaw programs need.
+  ac_save_LDFLAGS=$LDFLAGS
+  test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+  # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+  # check for ICE first), but we must link in the order -lSM -lICE or
+  # we get undefined symbols.  So assume we have SM if we have ICE.
+  # These have to be linked with before -lX11, unlike the other
+  # libraries we check for below, so use a different variable.
+  # John Interrante, Karl Berry
+  echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5
+echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6
+if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char IceConnectionNumber ();
+int
+main ()
+{
+IceConnectionNumber ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ICE_IceConnectionNumber=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ICE_IceConnectionNumber=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
+echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6
+if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+fi
+
+  LDFLAGS=$ac_save_LDFLAGS
+
+fi
+
+
+	if test x$no_x = xyes; then
+	    { { echo "$as_me:$LINENO: error: Configure could not find required X11 libraries" >&5
+echo "$as_me: error: Configure could not find required X11 libraries" >&2;}
+   { (exit aborting.); exit aborting.; }; }
+	fi
+
+	if test "x$X_PRE_LIBS" != x; then
+	    { echo "$as_me:$LINENO: WARNING: Ignoring libraries \"$X_PRE_LIBS\" requested by configure." >&5
+echo "$as_me: WARNING: Ignoring libraries \"$X_PRE_LIBS\" requested by configure." >&2;}
+	fi
+
+	LIBS="$LIBS -lXext -lX11 $X_EXTRA_LIBS"
+	CFLAGS="$CFLAGS $X_CFLAGS"
+	CXXFLAGS="$CXXFLAGS $X_CFLAGS"
+	LDFLAGS="$X_LIBS $LDFLAGS"
+
+	if test "x$x_includes" != x; then
+	    ac_cpp="$ac_cpp -I$x_includes"
+	fi
+
+		GLLIB=
+
+	if test x$enable_gl != xno; then
+	    echo "$as_me:$LINENO: checking for library containing dlopen" >&5
+echo $ECHO_N "checking for library containing dlopen... $ECHO_C" >&6
+if test "${ac_cv_search_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_dlopen=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_dlopen="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_dlopen" = no; then
+  for ac_lib in dl; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_dlopen="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_dlopen" >&5
+echo "${ECHO_T}$ac_cv_search_dlopen" >&6
+if test "$ac_cv_search_dlopen" != no; then
+  test "$ac_cv_search_dlopen" = "none required" || LIBS="$ac_cv_search_dlopen $LIBS"
+
+fi
+
+	    if test "${ac_cv_header_GL_gl_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for GL/gl.h" >&5
+echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_gl_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking GL/gl.h usability" >&5
+echo $ECHO_N "checking GL/gl.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <GL/gl.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking GL/gl.h presence" >&5
+echo $ECHO_N "checking GL/gl.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <GL/gl.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: GL/gl.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: GL/gl.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: GL/gl.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: GL/gl.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: GL/gl.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for GL/gl.h" >&5
+echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_gl_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_GL_gl_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6
+
+fi
+if test $ac_cv_header_GL_gl_h = yes; then
+  echo "$as_me:$LINENO: checking for glXMakeCurrent in -lGL" >&5
+echo $ECHO_N "checking for glXMakeCurrent in -lGL... $ECHO_C" >&6
+if test "${ac_cv_lib_GL_glXMakeCurrent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lGL \
+		    -lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char glXMakeCurrent ();
+int
+main ()
+{
+glXMakeCurrent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_GL_glXMakeCurrent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_GL_glXMakeCurrent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_GL_glXMakeCurrent" >&5
+echo "${ECHO_T}$ac_cv_lib_GL_glXMakeCurrent" >&6
+if test $ac_cv_lib_GL_glXMakeCurrent = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_GL 1
+_ACEOF
+ GLLIB="-lGL"
+else
+  \
+		    echo "$as_me:$LINENO: checking for glXMakeCurrent in -lMesaGL" >&5
+echo $ECHO_N "checking for glXMakeCurrent in -lMesaGL... $ECHO_C" >&6
+if test "${ac_cv_lib_MesaGL_glXMakeCurrent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lMesaGL \
+			-lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char glXMakeCurrent ();
+int
+main ()
+{
+glXMakeCurrent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_MesaGL_glXMakeCurrent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_MesaGL_glXMakeCurrent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_MesaGL_glXMakeCurrent" >&5
+echo "${ECHO_T}$ac_cv_lib_MesaGL_glXMakeCurrent" >&6
+if test $ac_cv_lib_MesaGL_glXMakeCurrent = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_GL 1
+_ACEOF
+ GLLIB=" -lMesaGL"
+fi
+
+fi
+
+
+fi
+
+
+	    if test "${ac_cv_header_GL_glu_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for GL/glu.h" >&5
+echo $ECHO_N "checking for GL/glu.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_glu_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_glu_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_glu_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking GL/glu.h usability" >&5
+echo $ECHO_N "checking GL/glu.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <GL/glu.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking GL/glu.h presence" >&5
+echo $ECHO_N "checking GL/glu.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <GL/glu.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: GL/glu.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: GL/glu.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: GL/glu.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: GL/glu.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: GL/glu.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: GL/glu.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: GL/glu.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: GL/glu.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: GL/glu.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for GL/glu.h" >&5
+echo $ECHO_N "checking for GL/glu.h... $ECHO_C" >&6
+if test "${ac_cv_header_GL_glu_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_GL_glu_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_GL_glu_h" >&5
+echo "${ECHO_T}$ac_cv_header_GL_glu_h" >&6
+
+fi
+if test $ac_cv_header_GL_glu_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_GL_GLU_H 1
+_ACEOF
+
+		if test x$ac_cv_lib_GL_glXMakeCurrent = xyes; then
+		    GLLIB="-lGLU $GLLIB"
+		fi
+		if test x$ac_cv_lib_MesaGL_glXMakeCurrent = xyes; then
+		    GLLIB="-lMesaGLU $GLLIB"
+		fi
+
+fi
+
+
+
+	    if test x$ac_cv_lib_GL_glXMakeCurrent != xyes -a x$ac_cv_lib_MesaGL_glXMakeCurrent != xyes; then
+		    LINKFLTKGL=""
+		    GLLIBNAME=""
+		    GLDSONAME=""
+		    GLDEMOS=""
+	    fi
+	else
+	    LINKFLTKGL=""
+	    GLLIBNAME=""
+	    GLDSONAME=""
+	    GLDEMOS=""
+	fi
+
+	        # Check whether --enable-xinerama or --disable-xinerama was given.
+if test "${enable_xinerama+set}" = set; then
+  enableval="$enable_xinerama"
+
+fi;
+
+	if test x$enable_xinerama = xyes; then
+	    echo "$as_me:$LINENO: checking for XineramaIsActive in -lXinerama" >&5
+echo $ECHO_N "checking for XineramaIsActive in -lXinerama... $ECHO_C" >&6
+if test "${ac_cv_lib_Xinerama_XineramaIsActive+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXinerama  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char XineramaIsActive ();
+int
+main ()
+{
+XineramaIsActive ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xinerama_XineramaIsActive=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xinerama_XineramaIsActive=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xinerama_XineramaIsActive" >&5
+echo "${ECHO_T}$ac_cv_lib_Xinerama_XineramaIsActive" >&6
+if test $ac_cv_lib_Xinerama_XineramaIsActive = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_XINERAMA 1
+_ACEOF
+
+		    LIBS="-lXinerama $LIBS"
+fi
+
+	fi
+
+	        # Check whether --enable-xft or --disable-xft was given.
+if test "${enable_xft+set}" = set; then
+  enableval="$enable_xft"
+
+fi;
+
+	if test x$enable_xft = xyes; then
+            # Extract the first word of "freetype-config", so it can be a program name with args.
+set dummy freetype-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_FTCONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $FTCONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_FTCONFIG="$FTCONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_FTCONFIG="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+FTCONFIG=$ac_cv_path_FTCONFIG
+
+if test -n "$FTCONFIG"; then
+  echo "$as_me:$LINENO: result: $FTCONFIG" >&5
+echo "${ECHO_T}$FTCONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+	    if test "x$FTCONFIG" != "x:"; then
+	        CPPFLAGS="`$FTCONFIG --cflags` $CPPFLAGS"
+	        CXXFLAGS="`$FTCONFIG --cflags` $CXXFLAGS"
+
+		if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for X11/Xft/Xft.h" >&5
+echo $ECHO_N "checking for X11/Xft/Xft.h... $ECHO_C" >&6
+if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_X11_Xft_Xft_h" >&5
+echo "${ECHO_T}$ac_cv_header_X11_Xft_Xft_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking X11/Xft/Xft.h usability" >&5
+echo $ECHO_N "checking X11/Xft/Xft.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <X11/Xft/Xft.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking X11/Xft/Xft.h presence" >&5
+echo $ECHO_N "checking X11/Xft/Xft.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xft/Xft.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: X11/Xft/Xft.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for X11/Xft/Xft.h" >&5
+echo $ECHO_N "checking for X11/Xft/Xft.h... $ECHO_C" >&6
+if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_X11_Xft_Xft_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_X11_Xft_Xft_h" >&5
+echo "${ECHO_T}$ac_cv_header_X11_Xft_Xft_h" >&6
+
+fi
+if test $ac_cv_header_X11_Xft_Xft_h = yes; then
+  echo "$as_me:$LINENO: checking for XftDrawCreate in -lXft" >&5
+echo $ECHO_N "checking for XftDrawCreate in -lXft... $ECHO_C" >&6
+if test "${ac_cv_lib_Xft_XftDrawCreate+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXft  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char XftDrawCreate ();
+int
+main ()
+{
+XftDrawCreate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xft_XftDrawCreate=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xft_XftDrawCreate=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xft_XftDrawCreate" >&5
+echo "${ECHO_T}$ac_cv_lib_Xft_XftDrawCreate" >&6
+if test $ac_cv_lib_Xft_XftDrawCreate = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define USE_XFT 1
+_ACEOF
+
+			LIBS="-lXft $LIBS"
+fi
+
+fi
+
+
+	    fi
+	fi
+
+	        # Check whether --enable-xdbe or --disable-xdbe was given.
+if test "${enable_xdbe+set}" = set; then
+  enableval="$enable_xdbe"
+
+fi;
+
+	if test x$enable_xdbe = xyes; then
+	    echo "$as_me:$LINENO: checking for X11/extensions/Xdbe.h" >&5
+echo $ECHO_N "checking for X11/extensions/Xdbe.h... $ECHO_C" >&6
+if test "${ac_cv_header_X11_extensions_Xdbe_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+
+#include <X11/extensions/Xdbe.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_X11_extensions_Xdbe_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_X11_extensions_Xdbe_h=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_X11_extensions_Xdbe_h" >&5
+echo "${ECHO_T}$ac_cv_header_X11_extensions_Xdbe_h" >&6
+if test $ac_cv_header_X11_extensions_Xdbe_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_XDBE 1
+_ACEOF
+
+fi
+
+
+	fi
+
+		echo "$as_me:$LINENO: checking for X overlay visuals" >&5
+echo $ECHO_N "checking for X overlay visuals... $ECHO_C" >&6
+if test "${ac_cv_have_overlay+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if xprop -root 2>/dev/null | grep -c "SERVER_OVERLAY_VISUALS" >/dev/null; then
+        	ac_cv_have_overlay=yes
+	    else
+        	ac_cv_have_overlay=no
+	    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_overlay" >&5
+echo "${ECHO_T}$ac_cv_have_overlay" >&6
+
+        if test x$ac_cv_have_overlay = xyes; then
+	    cat >>confdefs.h <<\_ACEOF
+#define HAVE_OVERLAY 1
+_ACEOF
+
+	fi
+
+	# Make symlinks since UNIX/Linux is case sensitive.
+	if test "x$with_links" = xno; then
+		HLINKS="#"
+	fi
+
+	# Install/Uninstall FLUID application support files
+	INSTALL_DESKTOP="install-linux"
+	UNINSTALL_DESKTOP="uninstall-linux"
+	;;
+esac
+
+
+
+
+
+
+
+
+
+
+case "$uname" in
+    *BSD* | Darwin*)
+	# *BSD
+	CAT1EXT=0
+	CAT3EXT=0
+	CAT6EXT=0
+	;;
+    IRIX*)
+	# SGI IRIX
+	CAT1EXT=z
+	CAT3EXT=z
+	CAT6EXT=z
+	;;
+    *)
+	# All others
+	CAT1EXT=1
+	CAT3EXT=3
+	CAT6EXT=3
+	;;
+esac
+
+
+
+
+
+if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr"; then
+    case "$uname" in
+        *BSD* | Darwin* | Linux*)
+            # *BSD, Darwin, and Linux
+            mandir="\${prefix}/share/man"
+            ;;
+        IRIX*)
+            # SGI IRIX
+            mandir="\${prefix}/share/catman"
+            ;;
+    esac
+fi
+
+if test "$prefix" = NONE; then
+    prefix=/usr/local
+fi
+
+if test "$exec_prefix" = NONE; then
+    exec_prefix="\${prefix}"
+fi
+
+if test "$uname" = "IRIX" -a $uversion -ge 62 -a "$libdir" = "\${exec_prefix}/lib" -a "$exec_prefix" = "\${prefix}" -a "$prefix" = "/usr"; then
+    libdir="/usr/lib32"
+fi
+
+MAKEDEPEND="\$(CXX) -M"
+
+
+
+if test -n "$GCC"; then
+    # Show all standard warnings + unused variables, conversion errors,
+    # and inlining problems when compiling...
+    OPTIM="-Wall -Wunused -Wno-format-y2k $OPTIM"
+
+    # The following additional warnings are useful for tracking down problems...
+    #OPTIM="-Wshadow -Wconversion $OPTIM"
+
+    # Set the default compiler optimizations...
+    if test -z "$DEBUGFLAG"; then
+    	#
+	# Note: Can't use -fomit-frame-pointer - prevents tools like
+	#       libsafe from working!
+        #
+	#       Don't use -fforce-mem, -fforce-addr, or -fcaller-saves.
+	#       They all seem to make either no difference or enlarge
+	#       the code by a few hundred bytes.
+        #
+	#       "-Os" seems to be the best compromise between speed and
+	#       code size.  "-O3" and higher seem to make no effective
+	#       difference in the speed of the code, but does bloat the
+	#       library 10+%.
+	#
+
+        if test "x$with_optim" != x; then
+	    OPTIM="$with_optim $OPTIM"
+	else
+            OPTIM="-Os $OPTIM"
+	fi
+    fi
+
+    # Generate position-independent code when needed...
+    if test $PICFLAG = 1; then
+    	OPTIM="$OPTIM -fPIC"
+    fi
+
+    # See if GCC supports -fno-exceptions...
+    echo "$as_me:$LINENO: checking if GCC supports -fno-exceptions" >&5
+echo $ECHO_N "checking if GCC supports -fno-exceptions... $ECHO_C" >&6
+    OLDCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -fno-exceptions"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  OPTIM="$OPTIM -fno-exceptions"
+	echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    CFLAGS="$OLDCFLAGS"
+
+    # See if we are running Solaris; if so, try the -fpermissive option...
+    # This option is required on some versions of Solaris to work around
+    # bugs in the X headers up through Solaris 7.
+    #
+    # Unlike the other compiler/optimization settings, this one is placed
+    # in CFLAGS and CXXFLAGS so that fltk-config will provide the option
+    # to clients - otherwise client apps will not compile properly...
+    if test "$uname" = SunOS; then
+	echo "$as_me:$LINENO: checking if GCC supports -fpermissive" >&5
+echo $ECHO_N "checking if GCC supports -fpermissive... $ECHO_C" >&6
+
+	OLDCFLAGS="$CFLAGS"
+	CFLAGS="$CFLAGS -fpermissive"
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  CXXFLAGS="$CXXFLAGS -fpermissive"
+	    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+CFLAGS="$OLDCFLAGS"
+	    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+else
+    case "$uname" in
+        IRIX*)
+	    # Running some flavor of IRIX; see which version and
+	    # set things up according...
+	    if test "$uversion" -ge 62; then
+	        # We are running IRIX 6.2 or higher; uncomment the following
+		# lines if you don't have IDO 7.2 or higher:
+		#
+		#     CXX="CC -n32 -mips3"
+		#     CC="cc -n32 -mips3"
+		#     LD="ld -n32 -mips3"
+		#     MAKEDEPEND="CC -M"
+
+		if test "x`grep abi=n32 /etc/compiler.defaults`" = x; then
+			{ echo "$as_me:$LINENO: WARNING: FOR BEST RESULTS BEFORE COMPILING: setenv SGI_ABI \"-n32 -mips3\"" >&5
+echo "$as_me: WARNING: FOR BEST RESULTS BEFORE COMPILING: setenv SGI_ABI \"-n32 -mips3\"" >&2;}
+		fi
+
+        	OPTIM="-fullwarn $OPTIM"
+	    fi
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-O2 $OPTIM"
+		    if test $uversion -gt 62; then
+        	        OPTIM="-OPT:Olimit=4000 $OPTIM"
+	            fi
+		fi
+	    fi
+	    ;;
+	HP-UX*)
+	    # Running HP-UX; these options should work for the HP compilers.
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="+O2 $OPTIM"
+		fi
+	    fi
+
+            if test "x$with_optim" = x; then
+		OPTIM="$OPTIM +DAportable"
+            fi
+
+	    if test $PICFLAG = 1; then
+		OPTIM="+z $OPTIM"
+	    fi
+
+	    OPTIM="$OPTIM +W336,501,736,740,749,829"
+	    ;;
+	OSF1*)
+	    # Running Digital/Tru64 UNIX; these options should work for the
+	    # Digital/Compaq/NewHP compilers.
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-O2 $OPTIM"
+		fi
+	    fi
+	    ;;
+	SunOS*)
+	    # Solaris
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-xO3 $OPTIM"
+		fi
+	    fi
+
+	    if test $PICFLAG = 1; then
+		OPTIM="-KPIC $OPTIM"
+	    fi
+	    ;;
+	AIX*)
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-O2 $OPTIM"
+		fi
+	    fi
+
+	    { echo "$as_me:$LINENO: WARNING: The AIX C and C++ compilers are known not to correctly compile the FLTK library." >&5
+echo "$as_me: WARNING: The AIX C and C++ compilers are known not to correctly compile the FLTK library." >&2;}
+	    ;;
+	*)
+	    # Running some other operating system; inform the user they
+	    # should contribute the necessary options to fltk-bugs@fltk.org...
+	    { echo "$as_me:$LINENO: WARNING: Building FLTK with default compiler optimizations" >&5
+echo "$as_me: WARNING: Building FLTK with default compiler optimizations" >&2;}
+	    { echo "$as_me:$LINENO: WARNING: Contact fltk-bugs@fltk.org with uname and compiler options." >&5
+echo "$as_me: WARNING: Contact fltk-bugs@fltk.org with uname and compiler options." >&2;}
+	    ;;
+    esac
+fi
+
+OPTIM="$DEBUGFLAG $OPTIM"
+
+if test x$prefix = xNONE; then
+    cat >>confdefs.h <<_ACEOF
+#define FLTK_DOCDIR "/usr/local/share/doc/fltk"
+_ACEOF
+
+else
+    cat >>confdefs.h <<_ACEOF
+#define FLTK_DOCDIR "$prefix/share/doc/fltk"
+_ACEOF
+
+fi
+
+if test x$prefix = xNONE; then
+    cat >>confdefs.h <<_ACEOF
+#define FLTK_DATADIR "/usr/local/share/fltk"
+_ACEOF
+
+else
+    cat >>confdefs.h <<_ACEOF
+#define FLTK_DATADIR "$prefix/share/fltk"
+_ACEOF
+
+fi
+
+          ac_config_headers="$ac_config_headers config.h:configh.in"
+
+                                        ac_config_files="$ac_config_files makeinclude fltk.list fltk-config FL/Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "makeinclude" ) CONFIG_FILES="$CONFIG_FILES makeinclude" ;;
+  "fltk.list" ) CONFIG_FILES="$CONFIG_FILES fltk.list" ;;
+  "fltk-config" ) CONFIG_FILES="$CONFIG_FILES fltk-config" ;;
+  "FL/Makefile" ) CONFIG_FILES="$CONFIG_FILES FL/Makefile" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h:configh.in" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@FL_MAJOR_VERSION@,$FL_MAJOR_VERSION,;t t
+s,@FL_MINOR_VERSION@,$FL_MINOR_VERSION,;t t
+s,@FL_PATCH_VERSION@,$FL_PATCH_VERSION,;t t
+s,@FL_API_VERSION@,$FL_API_VERSION,;t t
+s,@OPTIM@,$OPTIM,;t t
+s,@FLLIBNAME@,$FLLIBNAME,;t t
+s,@GLDEMOS@,$GLDEMOS,;t t
+s,@GLLIBNAME@,$GLLIBNAME,;t t
+s,@IMGLIBNAME@,$IMGLIBNAME,;t t
+s,@LIBEXT@,$LIBEXT,;t t
+s,@LIBNAME@,$LIBNAME,;t t
+s,@LINKFLTK@,$LINKFLTK,;t t
+s,@LINKFLTKFORMS@,$LINKFLTKFORMS,;t t
+s,@LINKFLTKGL@,$LINKFLTKGL,;t t
+s,@LINKFLTKIMG@,$LINKFLTKIMG,;t t
+s,@DSOCOMMAND@,$DSOCOMMAND,;t t
+s,@DSOLINK@,$DSOLINK,;t t
+s,@DSONAME@,$DSONAME,;t t
+s,@FLDSONAME@,$FLDSONAME,;t t
+s,@GLDSONAME@,$GLDSONAME,;t t
+s,@IMGDSONAME@,$IMGDSONAME,;t t
+s,@SHAREDSUFFIX@,$SHAREDSUFFIX,;t t
+s,@LINKSHARED@,$LINKSHARED,;t t
+s,@FLUID@,$FLUID,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@NROFF@,$NROFF,;t t
+s,@GROFF@,$GROFF,;t t
+s,@HTMLDOC@,$HTMLDOC,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@AR@,$AR,;t t
+s,@LIBCOMMAND@,$LIBCOMMAND,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LARGEFILE@,$LARGEFILE,;t t
+s,@AUDIOLIBS@,$AUDIOLIBS,;t t
+s,@IMAGELIBS@,$IMAGELIBS,;t t
+s,@JPEG@,$JPEG,;t t
+s,@JPEGINC@,$JPEGINC,;t t
+s,@PNG@,$PNG,;t t
+s,@PNGINC@,$PNGINC,;t t
+s,@ZLIB@,$ZLIB,;t t
+s,@ZLIBINC@,$ZLIBINC,;t t
+s,@X_CFLAGS@,$X_CFLAGS,;t t
+s,@X_PRE_LIBS@,$X_PRE_LIBS,;t t
+s,@X_LIBS@,$X_LIBS,;t t
+s,@X_EXTRA_LIBS@,$X_EXTRA_LIBS,;t t
+s,@FTCONFIG@,$FTCONFIG,;t t
+s,@GLLIB@,$GLLIB,;t t
+s,@HLINKS@,$HLINKS,;t t
+s,@POSTBUILD@,$POSTBUILD,;t t
+s,@THREADS@,$THREADS,;t t
+s,@INSTALL_DESKTOP@,$INSTALL_DESKTOP,;t t
+s,@UNINSTALL_DESKTOP@,$UNINSTALL_DESKTOP,;t t
+s,@CAT1EXT@,$CAT1EXT,;t t
+s,@CAT3EXT@,$CAT3EXT,;t t
+s,@CAT6EXT@,$CAT6EXT,;t t
+s,@MAKEDEPEND@,$MAKEDEPEND,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+chmod +x fltk-config
+
diff --git a/Utilities/FLTK/configure.in b/Utilities/FLTK/configure.in
new file mode 100644
index 0000000000000000000000000000000000000000..5165f84cf77054ed9054e09a411caa889aca457e
--- /dev/null
+++ b/Utilities/FLTK/configure.in
@@ -0,0 +1,1005 @@
+dnl -*- sh -*-
+dnl the "configure" script is made from this by running GNU "autoconf"
+dnl
+dnl "$Id: configure.in 4756 2006-01-15 18:36:16Z mike $"
+dnl
+dnl Configuration script for the Fast Light Tool Kit (FLTK).
+dnl
+dnl Copyright 1998-2006 by Bill Spitzak and others.
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Library General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2 of the License, or (at your option) any later version.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Library General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Library General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+dnl USA.
+dnl
+dnl Please report all bugs and problems on the following page:
+dnl
+dnl      http://www.fltk.org/str.php
+dnl
+
+dnl We need at least autoconf 2.13...
+AC_PREREQ(2.13)
+
+dnl Required file in package...
+AC_INIT(src/Fl.cxx)
+
+dnl FLTK library versions...
+FL_MAJOR_VERSION=1
+FL_MINOR_VERSION=1
+FL_PATCH_VERSION=7
+FL_API_VERSION=${FL_MAJOR_VERSION}.${FL_MINOR_VERSION}
+
+AC_SUBST(FL_MAJOR_VERSION)
+AC_SUBST(FL_MINOR_VERSION)
+AC_SUBST(FL_PATCH_VERSION)
+AC_SUBST(FL_API_VERSION)
+
+dnl Get the operating system and version number...
+uname=`uname`
+uversion=`uname -r | sed -e '1,$s/[[^0-9]]//g'`
+if test "x$uname" = xIRIX64; then
+    uname="IRIX"
+fi
+if test "x$uname" = x; then
+    # MingW doesn't provide any output when uname is run, even with "-s"...
+    uname="CYGWIN"
+fi
+
+dnl Don't automatically add "-g" to compiler options...
+CFLAGS="${CFLAGS:=}"
+CPPFLAGS="${CPPFLAGS:=}"
+CXXFLAGS="${CXXFLAGS:=}"
+OPTIM="${OPTIM:=}"
+
+AC_SUBST(OPTIM)
+
+dnl OS-specific pre-tests...
+case $uname in
+    CYGWIN* | MINGW*)
+        # Handle Cygwin option *first*, before all other tests.
+	AC_ARG_ENABLE(cygwin, [  --enable-cygwin         use the CygWin libraries [default=no]])
+	if test x$enable_cygwin != xyes; then
+	    CFLAGS="$CFLAGS -mno-cygwin"
+	    CPPFLAGS="$CPPFLAGS -mno-cygwin"
+	    CXXFLAGS="$CXXFLAGS -mno-cygwin"
+	    LDFLAGS="$LDFLAGS -mno-cygwin"
+	fi
+	;;
+esac
+
+dnl Define the libraries and link options we'll need.
+LINKFLTK="../lib/libfltk.a"
+LINKFLTKFORMS="../lib/libfltk_forms.a"
+LINKFLTKGL="../lib/libfltk_gl.a"
+LINKFLTKIMG="../lib/libfltk_images.a"
+GLDEMOS="gldemos"
+
+LIBEXT=".a"
+LIBNAME="../lib/libfltk.a"
+FLLIBNAME="../lib/libfltk_forms.a"
+GLLIBNAME="../lib/libfltk_gl.a"
+IMGLIBNAME="../lib/libfltk_images.a"
+
+AC_SUBST(FLLIBNAME)
+AC_SUBST(GLDEMOS)
+AC_SUBST(GLLIBNAME)
+AC_SUBST(IMGLIBNAME)
+AC_SUBST(LIBEXT)
+AC_SUBST(LIBNAME)
+AC_SUBST(LINKFLTK)
+AC_SUBST(LINKFLTKFORMS)
+AC_SUBST(LINKFLTKGL)
+AC_SUBST(LINKFLTKIMG)
+
+dnl Handle compile-time options...
+AC_ARG_ENABLE(debug, [  --enable-debug          turn on debugging [default=no]])
+if test x$enable_debug = xyes; then
+    DEBUGFLAG="-g "
+else
+    DEBUGFLAG=""
+fi
+
+AC_ARG_ENABLE(gl, [  --enable-gl             turn on OpenGL support [default=yes]])
+
+AC_ARG_ENABLE(shared, [  --enable-shared         turn on shared libraries [default=no]])
+if test x$enable_shared = xyes; then
+    PICFLAG=1
+    SHAREDSUFFIX=""
+    FLUID="fluid-shared"
+
+    case $uname in
+	Darwin*)
+            DSONAME="libfltk.$FL_API_VERSION.dylib"
+            FLDSONAME="libfltk_forms.$FL_API_VERSION.dylib"
+            GLDSONAME="libfltk_gl.$FL_API_VERSION.dylib"
+            IMGDSONAME="libfltk_images.$FL_API_VERSION.dylib"
+	    DSOCOMMAND="\$(CC) $DSOFLAGS -dynamiclib -lc -o"
+	    ;;
+
+	SunOS* | UNIX_S*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+	    DSOCOMMAND="\$(CXX) -h \$@ \$(LDLIBS) -G $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib"; then
+		    DSOLINK="-R$libdir"
+            fi
+	    ;;
+	HP-UX*)
+            DSONAME="libfltk.sl.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.sl.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.sl.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.sl.$FL_API_VERSION"
+	    DSOCOMMAND="ld -b -z +h \$@ $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	IRIX*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@,-set_version,sgi1.1 \$(LDLIBS) -shared $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/usr/lib32" -a "x$libdir" != "x/usr/lib64"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	OSF1*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@ \$(LDLIBS) -shared $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/usr/lib32"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	Linux* | *BSD*)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@ \$(LDLIBS) -shared -fPIC $DEBUGFLAG -o"
+	    if test "x$libdir" != "x/usr/lib"; then
+		    DSOLINK="-Wl,-rpath,$libdir"
+            fi
+	    ;;
+	AIX*)
+            DSONAME="libfltk_s.a"
+            FLDSONAME="libfltk_forms_s.a"
+            GLDSONAME="libfltk_gl_s.a"
+            IMGDSONAME="libfltk_images_s.a"
+            DSOCOMMAND="\$(CXX) -Wl,-bexpall,-bM:SRE,-bnoentry -o"
+            SHAREDSUFFIX="_s"
+            ;;
+        CYGWIN* | MINGW*)
+	    PICFLAG=0
+	    if test x$enable_cygwin != xyes; then
+		DSONAME="mgwfltknox-$FL_API_VERSION.dll"
+		FLDSONAME="mgwfltknox_forms-$FL_API_VERSION.dll"
+		GLDSONAME="mgwfltknox_gl-$FL_API_VERSION.dll"
+		IMGDSONAME="mgwfltknox_images-$FL_API_VERSION.dll"
+	    else
+		DSONAME="cygfltknox-$FL_API_VERSION.dll"
+		FLDSONAME="cygfltknox_forms-$FL_API_VERSION.dll"
+		GLDSONAME="cygfltknox_gl-$FL_API_VERSION.dll"
+		IMGDSONAME="cygfltknox_images-$FL_API_VERSION.dll"
+	    fi
+	    DSOCOMMAND="\$(CXX) -shared -Wl,--whole-archive -Wl,--export-all-symbols -Wl,--enable-auto-import -o \$@"
+	    ;;
+	*)
+            AC_MSG_WARN(Shared libraries may not be supported.  Trying -shared option with compiler.)
+            DSONAME="libfltk.so.$FL_API_VERSION"
+            FLDSONAME="libfltk_forms.so.$FL_API_VERSION"
+            GLDSONAME="libfltk_gl.so.$FL_API_VERSION"
+            IMGDSONAME="libfltk_images.so.$FL_API_VERSION"
+            DSOCOMMAND="\$(CXX) -Wl,-soname,\$@ \$(LDLIBS) -shared $DEBUGFLAG -o"
+	    ;;
+    esac
+
+    LINKSHARED="-L../src -lfltk_images$SHAREDSUFFIX -lfltk_forms$SHAREDSUFFIX -lfltk$SHAREDSUFFIX"
+else
+    DSOCOMMAND="echo"
+    DSOLINK=""
+    DSONAME=""
+    FLDSONAME=""
+    GLDSONAME=""
+    IMGDSONAME=""
+    PICFLAG=0
+    SHAREDSUFFIX=""
+    FLUID="fluid"
+    LINKSHARED="../lib/libfltk_images.a ../lib/libfltk_forms.a ../lib/libfltk.a"
+fi
+
+AC_SUBST(DSOCOMMAND)
+AC_SUBST(DSOLINK)
+AC_SUBST(DSONAME)
+AC_SUBST(FLDSONAME)
+AC_SUBST(GLDSONAME)
+AC_SUBST(IMGDSONAME)
+AC_SUBST(SHAREDSUFFIX)
+AC_SUBST(LINKSHARED)
+AC_SUBST(FLUID)
+
+AC_ARG_ENABLE(threads, [  --enable-threads        enable multi-threading support])
+
+AC_ARG_WITH(optim, [  --with-optim="flags"    use custom optimization flags])
+
+case $uname in
+    Darwin*)
+        AC_ARG_ENABLE(quartz, [  --enable-quartz         use Quartz instead of Quickdraw (default=no)])
+        if test "x$enable_quartz" = "xyes"; then
+            AC_DEFINE(USE_QUARTZ, 1)
+            AC_DEFINE(__APPLE_QUARTZ__)
+        else
+            AC_DEFINE(__APPLE_QD__)
+        fi
+        ;;
+esac
+
+dnl Find commands...
+AC_PROG_CC
+AC_PROG_CXX
+dnl AC_PROG_INSTALL
+AC_PATH_PROG(NROFF,nroff)
+if test "x$NROFF" = "x:"; then
+    AC_PATH_PROG(GROFF,groff)
+    if test "x$GROFF" = "x:"; then
+        NROFF="echo"
+    else
+        NROFF="$GROFF -T ascii"
+    fi
+fi
+AC_PATH_PROG(HTMLDOC,htmldoc)
+
+dnl How do we make libraries?
+AC_PROG_RANLIB
+AC_PATH_PROG(AR, ar)
+
+if test "x$AR" = "x:"; then
+    AC_MSG_ERROR(Configure could not find the library archiver, aborting.)
+fi
+
+if test "x$RANLIB" != "x:"; then
+    LIBCOMMAND="$AR cr"
+else
+    LIBCOMMAND="$AR crs"
+fi
+
+AC_SUBST(LIBCOMMAND)
+
+dnl Architecture checks...
+AC_C_BIGENDIAN
+
+AC_CHECK_SIZEOF(short, 2)
+AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(long, 4)
+if test $ac_cv_sizeof_short -eq 2; then
+    AC_DEFINE(U16,unsigned short)
+fi
+if test $ac_cv_sizeof_int -eq 4; then
+    AC_DEFINE(U32,unsigned)
+else
+    if test $ac_cv_sizeof_long -eq 4; then
+        AC_DEFINE(U32,unsigned long)
+    fi
+fi
+if test $ac_cv_sizeof_int -eq 8; then
+    AC_DEFINE(U64,unsigned)
+else
+    if test $ac_cv_sizeof_long -eq 8; then
+        AC_DEFINE(U64,unsigned long)
+    fi
+fi
+
+dnl Does the C++ compiler support the bool type?
+AC_CACHE_CHECK(whether the compiler recognizes bool as a built-in type,
+    ac_cv_cxx_bool,[
+	AC_LANG_SAVE
+	AC_LANG_CPLUSPLUS
+	AC_TRY_COMPILE([
+	    int f(int  x){return 1;}
+	    int f(char x){return 1;}
+	    int f(bool x){return 1;}
+	],[
+	    bool b = true;
+	    return f(b);
+	], ac_cv_cxx_bool=yes, ac_cv_cxx_bool=no)
+	AC_LANG_RESTORE
+    ])
+
+if test "$ac_cv_cxx_bool" != yes; then
+    CXXFLAGS="-Dbool=char -Dfalse=0 -Dtrue=1 $CXXFLAGS"
+fi
+
+dnl Standard headers and functions...
+AC_HEADER_DIRENT
+AC_CHECK_HEADER(sys/select.h,AC_DEFINE(HAVE_SYS_SELECT_H))
+AC_CHECK_HEADER(sys/stdtypes.h,AC_DEFINE(HAVE_SYS_SELECT_H))
+AC_CHECK_FUNC(scandir,
+    if test "x$uname" = xSunOS -o "x$uname" = xQNX; then
+        AC_MSG_WARN(Not using $uname scandir emulation function.)
+    else
+        AC_DEFINE(HAVE_SCANDIR)
+    fi)
+AC_CHECK_FUNC(vsnprintf,[
+    case "$uname" in
+    	HP-UX*)
+	    if test "$uversion" = "1020"; then
+	        AC_MSG_WARN(Not using built-in vsnprintf function because you are running HP-UX 10.20.)
+	    else
+        	AC_DEFINE(HAVE_VSNPRINTF)
+	    fi
+	    ;;
+
+    	OSF1*)
+	    if test "$uversion" = "40"; then
+                AC_MSG_WARN(Not using built-in vsnprintf function because you are running Tru64 4.0.)
+	    else
+        	AC_DEFINE(HAVE_VSNPRINTF)
+	    fi
+	    ;;
+
+        *)
+            AC_DEFINE(HAVE_VSNPRINTF)
+	    ;;
+    esac])
+AC_CHECK_FUNC(snprintf,[
+    case "$uname" in
+    	HP-UX*)
+	    if test "$uversion" = "1020"; then
+	        AC_MSG_WARN(Not using built-in snprintf function because you are running HP-UX 10.20.)
+	    else
+        	AC_DEFINE(HAVE_SNPRINTF)
+	    fi
+	    ;;
+
+    	OSF1*)
+	    if test "$uversion" = "40"; then
+                AC_MSG_WARN(Not using built-in snprintf function because you are running Tru64 4.0.)
+	    else
+        	AC_DEFINE(HAVE_SNPRINTF)
+	    fi
+	    ;;
+
+        *)
+            AC_DEFINE(HAVE_SNPRINTF)
+	    ;;
+    esac])
+AC_CHECK_HEADER(strings.h, AC_DEFINE(HAVE_STRINGS_H))
+AC_CHECK_FUNCS(strcasecmp strlcat strlcpy)
+
+AC_CHECK_HEADER(locale.h, AC_DEFINE(HAVE_LOCALE_H))
+AC_CHECK_FUNCS(localeconv)
+
+dnl FLTK library uses math library functions...
+AC_SEARCH_LIBS(pow, m)
+
+dnl Check for largefile support...
+AC_SYS_LARGEFILE
+
+dnl Define largefile options as needed...
+LARGEFILE=""
+if test x$enable_largefile != xno; then
+	LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
+
+	if test $ac_cv_sys_large_files = 1; then
+		LARGEFILE="$LARGEFILE -D_LARGE_FILES"
+	fi
+
+	if test $ac_cv_sys_file_offset_bits = 64; then
+		LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64"
+	fi
+fi
+AC_SUBST(LARGEFILE)
+
+dnl Check for "long long" support...
+AC_CACHE_CHECK(for long long int, ac_cv_c_long_long,
+	[if test "$GCC" = yes; then
+		ac_cv_c_long_long=yes
+	else
+		AC_TRY_COMPILE(,[long long int i;],
+			ac_cv_c_long_long=yes,
+			ac_cv_c_long_long=no)
+	fi])
+
+if test $ac_cv_c_long_long = yes; then
+	AC_DEFINE(HAVE_LONG_LONG)
+fi
+
+AC_CHECK_FUNC(strtoll, AC_DEFINE(HAVE_STRTOLL))
+
+dnl Check for audio libraries...
+AUDIOLIBS=""
+
+case $uname in
+    CYGWIN* | MINGW*)
+	dnl Cygwin environment...
+	AUDIOLIBS="-lwinmm"
+	;;
+
+    Darwin*)
+	AUDIOLIBS="-framework CoreAudio"
+	;;
+
+    *)
+	AC_CHECK_HEADER(alsa/asoundlib.h,
+	    AC_DEFINE(HAVE_ALSA_ASOUNDLIB_H)
+	    AUDIOLIBS="-lasound")
+        ;;
+esac
+
+AC_SUBST(AUDIOLIBS)
+
+dnl Check for image libraries...
+SAVELIBS="$LIBS"
+IMAGELIBS=""
+
+AC_SUBST(IMAGELIBS)
+
+AC_ARG_ENABLE(localjpeg, [  --enable-localjpeg      use local JPEG library, default=auto],
+    [if test x$enable_localjpeg = xyes; then
+	ac_cv_lib_jpeg_jpeg_CreateCompress=no
+    fi])
+
+AC_CHECK_LIB(jpeg,jpeg_CreateCompress,
+    AC_DEFINE(HAVE_LIBJPEG)
+    JPEGINC=""
+    JPEG=""
+    IMAGELIBS="-ljpeg $IMAGELIBS",
+    if test x$enable_localjpeg = xno; then
+	JPEGINC=""
+	JPEG=""
+    else
+	AC_DEFINE(HAVE_LIBJPEG)
+	JPEGINC="-I../jpeg"
+	JPEG="jpeg"
+	IMAGELIBS="-lfltk_jpeg $IMAGELIBS"
+    fi)
+
+AC_ARG_ENABLE(localzlib, [  --enable-localzlib      use local ZLIB library, default=auto],
+    [if test x$enable_localzlib = xyes; then
+	ac_cv_lib_z_gzgets=no
+    fi])
+
+AC_CHECK_LIB(z,gzgets,
+    AC_DEFINE(HAVE_LIBZ)
+    ZLIBINC=""
+    ZLIB=""
+    LIBS="-lz $LIBS"
+    IMAGELIBS="-lz $IMAGELIBS",
+    if test x$enable_localzlib = xno; then
+	ZLIBINC=""
+	ZLIB=""
+    else
+        AC_DEFINE(HAVE_LIBZ)
+	ZLIBINC="-I../zlib"
+	ZLIB="zlib"
+	LIBS="-lfltk_z $LIBS"
+	IMAGELIBS="-lfltk_z $IMAGELIBS"
+    fi)
+
+AC_ARG_ENABLE(localpng, [  --enable-localpng       use local PNG library, default=auto],
+    [if test x$enable_localpng = xyes; then
+	ac_cv_lib_png_png_set_tRNS_to_alpha=no
+    fi])
+
+AC_CHECK_LIB(png,png_set_tRNS_to_alpha, [
+    PNGINC=""
+    PNG=""
+    IMAGELIBS="-lpng $IMAGELIBS"
+    AC_DEFINE(HAVE_LIBPNG)
+    AC_CHECK_HEADER(png.h, AC_DEFINE(HAVE_PNG_H))],[
+    if test x$enable_localpng = xno; then
+        PNGINC=""
+        PNG=""
+    else
+	AC_DEFINE(HAVE_LIBPNG)
+        AC_DEFINE(HAVE_PNG_H)
+        PNGINC="-I../png"
+        PNG="png"
+        IMAGELIBS="-lfltk_png $IMAGELIBS"
+    fi])
+
+AC_SUBST(JPEG)
+AC_SUBST(JPEGINC)
+AC_SUBST(PNG)
+AC_SUBST(PNGINC)
+AC_SUBST(ZLIB)
+AC_SUBST(ZLIBINC)
+
+dnl Restore original LIBS settings...
+LIBS="$SAVELIBS"
+
+dnl See if we need a .exe extension on executables...
+AC_EXEEXT
+
+dnl Check for pthreads for multi-threaded apps...
+have_pthread=no
+
+if test "x$enable_threads" = xyes; then
+    AC_CHECK_HEADER(pthread.h, AC_DEFINE(HAVE_PTHREAD_H))
+    AC_CHECK_LIB(pthread, pthread_create)
+
+    if test "x$ac_cv_lib_pthread_pthread_create" = xyes -a x$ac_cv_header_pthread_h = xyes; then
+        have_pthread=yes
+    else
+        dnl *BSD uses -pthread option...
+        AC_MSG_CHECKING([for pthread_create using -pthread])
+	SAVELIBS="$LIBS"
+	LIBS="-pthread $LIBS"
+        AC_TRY_LINK([#include <pthread.h>],
+	    [pthread_create(0, 0, 0, 0);],
+            LIBS="-pthread $SAVELIBS"
+            have_pthread=yes,
+	    LIBS="$SAVELIBS")
+        AC_MSG_RESULT([$have_pthread])
+    fi
+fi
+
+dnl Define OS-specific stuff...
+HLINKS=
+POSTBUILD=:
+THREADS=
+
+AC_ARG_WITH(links, [  --with-links            make header links for common misspellings])
+
+INSTALL_DESKTOP=""
+UNINSTALL_DESKTOP=""
+
+case $uname in
+    CYGWIN* | MINGW*)
+	dnl Cygwin environment...
+	CFLAGS="-mwindows -DWIN32 $CFLAGS"
+	CXXFLAGS="-mwindows -DWIN32 $CXXFLAGS"
+	LDFLAGS="-mwindows $LDFLAGS"
+	LIBS="$LIBS -lole32 -luuid -lcomctl32 -lwsock32"
+	OPTIM="$OPTIM"
+
+	if test x$enable_gl != xno; then
+	    AC_CHECK_HEADER(GL/gl.h,
+	        AC_DEFINE(HAVE_GL)
+		GLLIB="-lopengl32")
+	    AC_CHECK_HEADER(GL/glu.h,
+        	AC_DEFINE(HAVE_GL_GLU_H)
+		GLLIB="-lglu32 $GLLIB")
+	else
+	    LINKFLTKGL=""
+	    GLLIBNAME=""
+	    GLDSONAME=""
+	    GLDEMOS=""
+	fi
+
+	if test "x$enable_threads" = xyes; then
+	    if test x$have_pthread = xyes; then
+		AC_DEFINE(HAVE_PTHREAD)
+	    fi
+
+	    THREADS="threads.exe"
+        fi
+
+	# Don't make symlinks since Windows is not case sensitive.
+	if test "x$with_links" != xyes; then
+		HLINKS="#"
+	fi
+	;;
+
+    Darwin*)
+        # MacOS X uses Carbon for graphics...
+        LIBS="$LIBS -framework Carbon -framework ApplicationServices"
+
+	if test x$have_pthread = xyes; then
+	    AC_DEFINE(HAVE_PTHREAD)
+	    THREADS="threads"
+	fi
+
+	if test x$enable_gl != xno; then
+            AC_DEFINE(HAVE_GL)
+            AC_DEFINE(HAVE_GL_GLU_H)
+            GLLIB="-framework AGL -framework OpenGL"
+        else
+	    LINKFLTKGL=""
+	    GLLIBNAME=""
+	    GLDSONAME=""
+	    GLDEMOS=""
+        fi
+
+	# Don't make symlinks because HFS+ is not case sensitive...
+	if test "x$with_links" != xyes; then
+		HLINKS="#"
+	fi
+
+	# Add a postbuild step after linking applications
+	POSTBUILD="/Developer/Tools/Rez -t APPL -o"
+
+	# Install/Uninstall FLUID application
+	INSTALL_DESKTOP="install-osx"
+	UNINSTALL_DESKTOP="uninstall-osx"
+	;;
+
+    *)
+	# All others are UNIX/X11...
+	if test x$have_pthread = xyes; then
+	    AC_DEFINE(HAVE_PTHREAD)
+	    THREADS="threads"
+	fi
+
+	dnl Check for X11...
+	AC_PATH_XTRA
+
+	if test x$no_x = xyes; then
+	    AC_MSG_ERROR(Configure could not find required X11 libraries, aborting.)
+	fi
+
+	if test "x$X_PRE_LIBS" != x; then
+	    AC_MSG_WARN(Ignoring libraries \"$X_PRE_LIBS\" requested by configure.)
+	fi
+
+	LIBS="$LIBS -lXext -lX11 $X_EXTRA_LIBS"
+	CFLAGS="$CFLAGS $X_CFLAGS"
+	CXXFLAGS="$CXXFLAGS $X_CFLAGS"
+	LDFLAGS="$X_LIBS $LDFLAGS"
+
+	if test "x$x_includes" != x; then
+	    ac_cpp="$ac_cpp -I$x_includes"
+	fi
+
+	dnl Check for OpenGL unless disabled...
+	GLLIB=
+
+	if test x$enable_gl != xno; then
+	    AC_SEARCH_LIBS(dlopen, dl)
+	    AC_CHECK_HEADER(GL/gl.h,
+		AC_CHECK_LIB(GL, glXMakeCurrent, AC_DEFINE(HAVE_GL) GLLIB="-lGL", \
+		    AC_CHECK_LIB(MesaGL,glXMakeCurrent, AC_DEFINE(HAVE_GL) GLLIB=" -lMesaGL",,\
+			-lm), \
+		    -lm)
+	    )
+	    AC_CHECK_HEADER(GL/glu.h,
+        	AC_DEFINE(HAVE_GL_GLU_H)
+		if test x$ac_cv_lib_GL_glXMakeCurrent = xyes; then
+		    GLLIB="-lGLU $GLLIB"
+		fi
+		if test x$ac_cv_lib_MesaGL_glXMakeCurrent = xyes; then
+		    GLLIB="-lMesaGLU $GLLIB"
+		fi
+	    )
+
+	    if test x$ac_cv_lib_GL_glXMakeCurrent != xyes -a x$ac_cv_lib_MesaGL_glXMakeCurrent != xyes; then
+		    LINKFLTKGL=""
+		    GLLIBNAME=""
+		    GLDSONAME=""
+		    GLDEMOS=""
+	    fi
+	else
+	    LINKFLTKGL=""
+	    GLLIBNAME=""
+	    GLDSONAME=""
+	    GLDEMOS=""
+	fi
+
+	dnl Check for Xinerama support unless disabled...
+        AC_ARG_ENABLE(xinerama, [  --enable-xinerama       turn on Xinerama support [default=no]])
+
+	if test x$enable_xinerama = xyes; then
+	    AC_CHECK_LIB(Xinerama,XineramaIsActive,
+		    AC_DEFINE(HAVE_XINERAMA)
+		    LIBS="-lXinerama $LIBS")
+	fi
+
+	dnl Check for the Xft library unless disabled...
+        AC_ARG_ENABLE(xft, [  --enable-xft            turn on Xft support [default=no]])
+
+	if test x$enable_xft = xyes; then
+            AC_PATH_PROG(FTCONFIG,freetype-config)
+
+	    if test "x$FTCONFIG" != "x:"; then
+	        CPPFLAGS="`$FTCONFIG --cflags` $CPPFLAGS"
+	        CXXFLAGS="`$FTCONFIG --cflags` $CXXFLAGS"
+
+		AC_CHECK_HEADER(X11/Xft/Xft.h,
+		    AC_CHECK_LIB(Xft, XftDrawCreate,
+	        	AC_DEFINE(USE_XFT)
+			LIBS="-lXft $LIBS"))
+	    fi
+	fi
+
+	dnl Check for the Xdbe extension unless disabled...
+        AC_ARG_ENABLE(xdbe, [  --enable-xdbe           turn on Xdbe support [default=no]])
+
+	if test x$enable_xdbe = xyes; then
+	    AC_CHECK_HEADER(X11/extensions/Xdbe.h, AC_DEFINE(HAVE_XDBE),,
+	        [#include <X11/Xlib.h>])
+	fi
+
+	dnl Check for overlay visuals...
+	AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay,
+	    if xprop -root 2>/dev/null | grep -c "SERVER_OVERLAY_VISUALS" >/dev/null; then
+        	ac_cv_have_overlay=yes
+	    else
+        	ac_cv_have_overlay=no
+	    fi)
+
+        if test x$ac_cv_have_overlay = xyes; then
+	    AC_DEFINE(HAVE_OVERLAY)
+	fi
+
+	# Make symlinks since UNIX/Linux is case sensitive.
+	if test "x$with_links" = xno; then
+		HLINKS="#"
+	fi
+
+	# Install/Uninstall FLUID application support files
+	INSTALL_DESKTOP="install-linux"
+	UNINSTALL_DESKTOP="uninstall-linux"
+	;;
+esac
+
+AC_SUBST(GLDEMOS)
+AC_SUBST(GLLIB)
+AC_SUBST(HLINKS)
+AC_SUBST(POSTBUILD)
+AC_SUBST(THREADS)
+
+AC_SUBST(INSTALL_DESKTOP)
+AC_SUBST(UNINSTALL_DESKTOP)
+
+dnl Figure out the appropriate formatted man page extension...
+case "$uname" in
+    *BSD* | Darwin*)
+	# *BSD
+	CAT1EXT=0
+	CAT3EXT=0
+	CAT6EXT=0
+	;;
+    IRIX*)
+	# SGI IRIX
+	CAT1EXT=z
+	CAT3EXT=z
+	CAT6EXT=z
+	;;
+    *)
+	# All others
+	CAT1EXT=1
+	CAT3EXT=3
+	CAT6EXT=3
+	;;
+esac
+
+AC_SUBST(CAT1EXT)
+AC_SUBST(CAT3EXT)
+AC_SUBST(CAT6EXT)
+
+dnl Fix "mandir" variable...
+if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr"; then
+    case "$uname" in
+        *BSD* | Darwin* | Linux*)
+            # *BSD, Darwin, and Linux
+            mandir="\${prefix}/share/man"
+            ;;
+        IRIX*)
+            # SGI IRIX
+            mandir="\${prefix}/share/catman"
+            ;;
+    esac
+fi
+
+dnl Fix "libdir" variable...
+if test "$prefix" = NONE; then
+    prefix=/usr/local
+fi
+
+if test "$exec_prefix" = NONE; then
+    exec_prefix="\${prefix}"
+fi
+
+if test "$uname" = "IRIX" -a $uversion -ge 62 -a "$libdir" = "\${exec_prefix}/lib" -a "$exec_prefix" = "\${prefix}" -a "$prefix" = "/usr"; then
+    libdir="/usr/lib32"
+fi
+
+dnl Define the command used to update the dependencies (this option
+dnl mainly for FLTK core developers - not necessary for users)
+MAKEDEPEND="\$(CXX) -M"
+AC_SUBST(MAKEDEPEND)
+
+dnl Add warnings to compiler switches:
+dnl do this last so messing with switches does not break tests
+
+if test -n "$GCC"; then
+    # Show all standard warnings + unused variables, conversion errors,
+    # and inlining problems when compiling...
+    OPTIM="-Wall -Wunused -Wno-format-y2k $OPTIM"
+
+    # The following additional warnings are useful for tracking down problems...
+    #OPTIM="-Wshadow -Wconversion $OPTIM"
+
+    # Set the default compiler optimizations...
+    if test -z "$DEBUGFLAG"; then
+    	#
+	# Note: Can't use -fomit-frame-pointer - prevents tools like
+	#       libsafe from working!
+        #
+	#       Don't use -fforce-mem, -fforce-addr, or -fcaller-saves.
+	#       They all seem to make either no difference or enlarge
+	#       the code by a few hundred bytes.
+        #
+	#       "-Os" seems to be the best compromise between speed and
+	#       code size.  "-O3" and higher seem to make no effective
+	#       difference in the speed of the code, but does bloat the
+	#       library 10+%.
+	#
+
+        if test "x$with_optim" != x; then
+	    OPTIM="$with_optim $OPTIM"
+	else
+            OPTIM="-Os $OPTIM"
+	fi
+    fi
+
+    # Generate position-independent code when needed...
+    if test $PICFLAG = 1; then
+    	OPTIM="$OPTIM -fPIC"
+    fi
+
+    # See if GCC supports -fno-exceptions...
+    AC_MSG_CHECKING(if GCC supports -fno-exceptions)
+    OLDCFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -fno-exceptions"
+    AC_TRY_COMPILE(,,
+	OPTIM="$OPTIM -fno-exceptions"
+	AC_MSG_RESULT(yes),
+	AC_MSG_RESULT(no))
+    CFLAGS="$OLDCFLAGS"
+
+    # See if we are running Solaris; if so, try the -fpermissive option...
+    # This option is required on some versions of Solaris to work around
+    # bugs in the X headers up through Solaris 7.
+    #
+    # Unlike the other compiler/optimization settings, this one is placed
+    # in CFLAGS and CXXFLAGS so that fltk-config will provide the option
+    # to clients - otherwise client apps will not compile properly...
+    if test "$uname" = SunOS; then
+	AC_MSG_CHECKING(if GCC supports -fpermissive)
+
+	OLDCFLAGS="$CFLAGS"
+	CFLAGS="$CFLAGS -fpermissive"
+	AC_TRY_COMPILE(,,
+	    CXXFLAGS="$CXXFLAGS -fpermissive"
+	    AC_MSG_RESULT(yes),
+	    CFLAGS="$OLDCFLAGS"
+	    AC_MSG_RESULT(no))
+    fi
+else
+    case "$uname" in
+        IRIX*)
+	    # Running some flavor of IRIX; see which version and
+	    # set things up according...
+	    if test "$uversion" -ge 62; then
+	        # We are running IRIX 6.2 or higher; uncomment the following
+		# lines if you don't have IDO 7.2 or higher:
+		#
+		#     CXX="CC -n32 -mips3"
+		#     CC="cc -n32 -mips3"
+		#     LD="ld -n32 -mips3"
+		#     MAKEDEPEND="CC -M"
+
+		if test "x`grep abi=n32 /etc/compiler.defaults`" = x; then
+			AC_MSG_WARN(FOR BEST RESULTS BEFORE COMPILING: setenv SGI_ABI \"-n32 -mips3\")
+		fi
+
+        	OPTIM="-fullwarn $OPTIM"
+	    fi
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-O2 $OPTIM"
+		    if test $uversion -gt 62; then
+        	        OPTIM="-OPT:Olimit=4000 $OPTIM"
+	            fi
+		fi
+	    fi
+	    ;;
+	HP-UX*)
+	    # Running HP-UX; these options should work for the HP compilers.
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="+O2 $OPTIM"
+		fi
+	    fi
+
+            if test "x$with_optim" = x; then
+		OPTIM="$OPTIM +DAportable"
+            fi
+
+	    if test $PICFLAG = 1; then
+		OPTIM="+z $OPTIM"
+	    fi
+
+	    OPTIM="$OPTIM +W336,501,736,740,749,829"
+	    ;;
+	OSF1*)
+	    # Running Digital/Tru64 UNIX; these options should work for the
+	    # Digital/Compaq/NewHP compilers.
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-O2 $OPTIM"
+		fi
+	    fi
+	    ;;
+	SunOS*)
+	    # Solaris
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-xO3 $OPTIM"
+		fi
+	    fi
+
+	    if test $PICFLAG = 1; then
+		OPTIM="-KPIC $OPTIM"
+	    fi
+	    ;;
+	AIX*)
+	    if test -z "$DEBUGFLAG"; then
+        	if test "x$with_optim" != x; then
+		    OPTIM="$with_optim $OPTIM"
+		else
+        	    OPTIM="-O2 $OPTIM"
+		fi
+	    fi
+
+	    AC_MSG_WARN(The AIX C and C++ compilers are known not to correctly compile the FLTK library.)
+	    ;;
+	*)
+	    # Running some other operating system; inform the user they
+	    # should contribute the necessary options to fltk-bugs@fltk.org...
+	    AC_MSG_WARN(Building FLTK with default compiler optimizations)
+	    AC_MSG_WARN(Contact fltk-bugs@fltk.org with uname and compiler options.)
+	    ;;
+    esac
+fi
+
+OPTIM="$DEBUGFLAG $OPTIM"
+
+dnl Define the FLTK documentation directory...
+if test x$prefix = xNONE; then
+    AC_DEFINE_UNQUOTED(FLTK_DOCDIR, "/usr/local/share/doc/fltk")
+else
+    AC_DEFINE_UNQUOTED(FLTK_DOCDIR, "$prefix/share/doc/fltk")
+fi
+
+dnl Define the FLTK data directory...
+if test x$prefix = xNONE; then
+    AC_DEFINE_UNQUOTED(FLTK_DATADIR, "/usr/local/share/fltk")
+else
+    AC_DEFINE_UNQUOTED(FLTK_DATADIR, "$prefix/share/fltk")
+fi
+
+dnl Write all of the files...
+AC_CONFIG_HEADER(config.h:configh.in)
+AC_OUTPUT(makeinclude fltk.list fltk-config FL/Makefile)
+
+dnl Make sure the fltk-config script is executable...
+chmod +x fltk-config
+
+dnl
+dnl End of "$Id: configure.in 4756 2006-01-15 18:36:16Z mike $".
+dnl
diff --git a/Utilities/FLTK/fltk-config.in b/Utilities/FLTK/fltk-config.in
new file mode 100755
index 0000000000000000000000000000000000000000..b7b3e80128c4e2f1feb4b4bc7ca0f366f79d1ac8
--- /dev/null
+++ b/Utilities/FLTK/fltk-config.in
@@ -0,0 +1,308 @@
+#!/bin/sh
+#
+# "$Id: fltk-config.in 4689 2005-12-07 20:13:12Z mike $"
+# 
+# FLTK configuration utility.
+#
+# Copyright 2000-2005 by Bill Spitzak and others.
+# Original version Copyright 2000 by James Dean Palmer
+# Adapted by Vincent Penne and Michael Sweet
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems on the following page:
+#
+#      http://www.fltk.org/str.php
+#
+
+MAJOR_VERSION=@FL_MAJOR_VERSION@
+MINOR_VERSION=@FL_MINOR_VERSION@
+PATCH_VERSION=@FL_PATCH_VERSION@
+VERSION="$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION"
+APIVERSION="$MAJOR_VERSION.$MINOR_VERSION"
+
+### BEGIN fltk-config
+selfdir=`dirname $0`
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+exec_prefix_set=no
+bindir=@bindir@
+includedir=@includedir@
+libdir=@libdir@
+srcdir=@srcdir@
+
+# compiler names
+CC="@CC@"
+CXX="@CXX@"
+
+# post-process command (only needed for MacOS)
+POSTBUILD="@POSTBUILD@"
+
+# flags for C++ compiler:
+CFLAGS="@CFLAGS@"
+CXXFLAGS="@CXXFLAGS@"
+LDFLAGS="@LDFLAGS@"
+LDLIBS="@LIBS@"
+
+# Check for local invocation, and update paths accordingly...
+if test -f "$selfdir/FL/Fl_Window.H"; then
+	bindir="$selfdir/fluid"
+	includedir="$selfdir"
+	libdir="$selfdir/lib"
+
+	if test -f "$libdir/libfltk_jpeg.a"; then
+		CFLAGS="-I$includedir/jpeg $CFLAGS"
+		CXXFLAGS="-I$includedir/jpeg $CXXFLAGS"
+	fi
+
+	if test -f "$libdir/libfltk_z.a"; then
+		CFLAGS="-I$includedir/zlib $CFLAGS"
+		CXXFLAGS="-I$includedir/zlib $CXXFLAGS"
+	fi
+
+	if test -f "$libdir/libfltk_png.a"; then
+		CFLAGS="-I$includedir/png $CFLAGS"
+		CXXFLAGS="-I$includedir/png $CXXFLAGS"
+	fi
+fi
+
+if test -d $includedir/FL/images; then
+	CFLAGS="-I$includedir/FL/images $CFLAGS"
+	CXXFLAGS="-I$includedir/FL/images $CXXFLAGS"
+fi
+
+# libraries to link with:
+LIBNAME="@LIBNAME@"
+DSONAME="@DSONAME@"
+DSOLINK="@DSOLINK@"
+IMAGELIBS="@IMAGELIBS@"
+SHAREDSUFFIX="@SHAREDSUFFIX@"
+
+usage ()
+{
+    echo "Usage: fltk-config [OPTIONS]
+Options:
+	[--version]
+	[--api-version]
+
+Options telling what we are doing:
+	[--use-gl]        use GL
+	[--use-images]    use extra image formats (PNG, JPEG)
+	[--use-glut]      use glut compatibility layer
+	[--use-forms]     use forms compatibility layer
+
+Options telling what information we request:
+	[--cc]            return C compiler used to compile FLTK
+	[--cxx]           return C++ compiler used to compile FLTK
+	[--cflags]        return flags to compile C using FLTK
+	[--cxxflags]      return flags to compile C++ using FLTK
+	[--ldflags]       return flags to link against FLTK
+	[--ldstaticflags] return flags to link against static FLTK library
+                                          even if there are DSOs installed
+	[--libs]          return FLTK libraries full path for dependencies
+
+Option to compile and link an application:
+	[-g]              compile the program with debugging information
+	[--compile program.cxx]
+        [--post program]
+"
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+no_plugins=no
+compile=
+post=
+debug=
+
+# Parse command line options
+while test $# -gt 0 
+do
+    case "$1" in
+	-*=*) 
+	    optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
+	    ;;
+	*)
+	    optarg=
+	    ;;
+    esac
+
+    case $1 in
+	--version)
+	    echo $VERSION
+	    ;;
+	--api-version)
+	    echo $APIVERSION
+	    ;;
+	--cc)
+	    echo $CC
+	    ;;
+	--cxx)
+	    echo $CXX
+	    ;;
+	--use-gl | --use-glut)
+	    use_gl=yes
+	    ;;
+	--use-forms)
+	    use_forms=yes
+	    ;;
+	--use-images)
+	    use_images=yes
+	    ;;
+	--cflags)
+	    echo_cflags=yes
+	    ;;
+	--cxxflags)
+	    echo_cxxflags=yes
+	    ;;
+	--ldflags)
+	    echo_ldflags=yes
+	    ;;
+	--ldstaticflags)
+	    echo_ldstaticflags=yes
+	    ;;
+	--libs)
+	    echo_libs=yes
+	    ;;
+	-g)
+	    debug=-g
+	    ;;
+	--compile)
+	    compile=$2
+	    post=$2
+	    shift
+	    ;;
+	--post)
+	    post=$2
+	    shift
+	    ;;
+	*)
+	    echo_help=yes
+	    ;;
+    esac
+    shift
+done
+
+if test "$includedir" != /usr/include; then
+    includes=-I$includedir
+else
+    includes=
+fi
+
+if test "$libdir" != /usr/lib -a "$libdir" != /usr/lib32; then
+    libs=-L$libdir
+else
+    libs=
+fi
+
+# Calculate needed libraries
+LDSTATIC="$libdir/libfltk.a $LDLIBS"
+LDLIBS="-lfltk$SHAREDSUFFIX $LDLIBS"
+LIBS="$libdir/libfltk.a"
+
+if test x$use_forms = xyes; then
+    LDLIBS="-lfltk_forms$SHAREDSUFFIX $LDLIBS"
+    LDSTATIC="$libdir/libfltk_forms.a $LDSTATIC"
+    LIBS="$LIBS $libdir/libfltk_forms.a"
+fi
+if test x$use_gl = xyes; then
+    LDLIBS="-lfltk_gl$SHAREDSUFFIX @GLLIB@ $LDLIBS"
+    LDSTATIC="$libdir/libfltk_gl.a @GLLIB@ $LDSTATIC"
+    LIBS="$LIBS $libdir/libfltk_gl.a"
+fi
+if test x$use_images = xyes; then
+    LDLIBS="-lfltk_images$SHAREDSUFFIX $IMAGELIBS $LDLIBS"
+    LDSTATIC="$libdir/libfltk_images.a $IMAGELIBS $LDSTATIC"
+fi
+
+LDLIBS="$DSOLINK $LDFLAGS $libs $LDLIBS"
+LDSTATIC="$LDFLAGS $libs $LDSTATIC"
+
+# Answer to user requests
+if test -n "$echo_help"; then
+    usage 1
+fi
+
+if test -n "$compile"; then
+    case $compile in
+        *.cxx)
+            prog=`basename $compile .cxx`
+	    ;;
+        *.cpp)
+            prog=`basename $compile .cpp`
+	    ;;
+        *.cc)
+            prog=`basename $compile .cc`
+	    ;;
+        *.C)
+            prog=`basename $compile .C`
+	    ;;
+	*)
+	    echo "ERROR: Unknown/bad C++ source file extension on \"$compile\"!"
+	    exit 1
+	    ;;
+    esac
+	    
+    post=$prog
+
+    echo $CXX $includes $CXXFLAGS $debug -o $prog $compile $LDSTATIC
+    $CXX $includes $CXXFLAGS $debug -o $prog $compile $LDSTATIC
+fi
+
+if test -n "$post" -a "$POSTBUILD" != ":"; then
+    echo $POSTBUILD $post $includedir/FL/mac.r
+    $POSTBUILD $post $includedir/FL/mac.r
+fi
+
+if test "$echo_cflags" = "yes"; then
+    echo $includes $CFLAGS
+fi
+
+if test "$echo_cxxflags" = "yes"; then
+    echo $includes $CXXFLAGS
+fi
+
+if test "$echo_ldflags" = "yes"; then
+    my_libs=
+    libdirs=$libs
+
+    for i in $LDLIBS ; do
+	if test $i != -L$libdir ; then
+	    if test -z "$my_libs" ; then
+		my_libs="$i"
+	    else
+		my_libs="$my_libs $i"
+	    fi
+	fi
+    done
+    echo $libdirs $my_libs
+fi
+
+if test "$echo_ldstaticflags" = "yes"; then
+    echo $LDSTATIC
+fi
+
+if test "$echo_libs" = "yes"; then
+    echo $LIBS
+fi
+
+#
+# End of "$Id: fltk-config.in 4689 2005-12-07 20:13:12Z mike $".
+#
diff --git a/Utilities/FLTK/fltk.list.in b/Utilities/FLTK/fltk.list.in
new file mode 100644
index 0000000000000000000000000000000000000000..2678e68281860aa6d1f26f23c54c9ec5d8f998ab
--- /dev/null
+++ b/Utilities/FLTK/fltk.list.in
@@ -0,0 +1,404 @@
+#
+# "$Id: fltk.list.in 4761 2006-01-15 20:33:10Z mike $"
+#
+# EPM product list file for the Fast Light Tool Kit (FLTK).
+#
+# (EPM can be found at http://www.easysw.com/epm/)
+#
+# Copyright 1998-2006 by Bill Spitzak and others.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems on the following page:
+#
+#      http://www.fltk.org/str.php
+#
+
+%product Fast Light Tool Kit (FLTK)
+%copyright 1998-2006 by Bill Spitzak and others.
+%vendor FLTK Development Team
+%license COPYING
+%readme README
+%version @FL_MAJOR_VERSION@.@FL_MINOR_VERSION@.@FL_PATCH_VERSION@
+%description The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a
+%description cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11),
+%description Microsoft(r) Windows(r), and MacOS(r) X.  FLTK provides modern
+%description GUI functionality without the bloat and supports 3D graphics via
+%description OpenGL(r) and its built-in GLUT emulation.
+
+$prefix=@prefix@
+$exec_prefix=@exec_prefix@
+$bindir=@bindir@
+$datadir=@datadir@
+$includedir=@includedir@
+$libdir=@libdir@
+$mandir=@mandir@
+$docdir=$(datadir)/doc/fltk
+
+$CAT1EXT=@CAT1EXT@
+$CAT3EXT=@CAT3EXT@
+$CAT6EXT=@CAT6EXT@
+
+$DSONAME=@DSONAME@
+$FLDSONAME=@FLDSONAME@
+$FLLIBNAME=@FLLIBNAME@
+$GLDSONAME=@GLDSONAME@
+$GLLIBNAME=@GLLIBNAME@
+$FLUID=@FLUID@
+$JPEG=@JPEG@
+$PNG=@PNG@
+$ZLIB=@ZLIB@
+
+%if DSONAME
+%system aix
+f 0555 root sys $libdir/libfltk_s.a src/libfltk_s.a nostrip()
+%system hpux
+f 0555 root sys $libdir/libfltk.sl.@FL_API_VERSION@ src/libfltk.sl.@FL_API_VERSION@ nostrip()
+%system darwin
+f 0555 root sys $libdir/libfltk.@FL_API_VERSION@.dylib src/libfltk.@FL_API_VERSION@.dylib nostrip()
+%system !aix !darwin !hpux
+f 0555 root sys $libdir/libfltk.so.@FL_API_VERSION@ src/libfltk.so.@FL_API_VERSION@ nostrip()
+%system all
+
+%system aix
+f 0555 root sys $libdir/libfltk_forms_s.a src/libfltk_forms_s.a nostrip()
+%system hpux
+f 0555 root sys $libdir/libfltk_forms.sl.@FL_API_VERSION@ src/libfltk_forms.sl.@FL_API_VERSION@ nostrip()
+%system darwin
+f 0555 root sys $libdir/libfltk_forms.@FL_API_VERSION@.dylib src/libfltk_forms.@FL_API_VERSION@.dylib nostrip()
+%system !aix !darwin !hpux
+f 0555 root sys $libdir/libfltk_forms.so.@FL_API_VERSION@ src/libfltk_forms.so.@FL_API_VERSION@ nostrip()
+%system all
+
+%system aix
+f 0555 root sys $libdir/libfltk_images_s.a src/libfltk_images_s.a nostrip()
+%system hpux
+f 0555 root sys $libdir/libfltk_images.sl.@FL_API_VERSION@ src/libfltk_images.sl.@FL_API_VERSION@ nostrip()
+%system darwin
+f 0555 root sys $libdir/libfltk_images.@FL_API_VERSION@.dylib src/libfltk_images.@FL_API_VERSION@.dylib nostrip()
+%system !aix !darwin !hpux
+f 0555 root sys $libdir/libfltk_images.so.@FL_API_VERSION@ src/libfltk_images.so.@FL_API_VERSION@ nostrip()
+%system all
+%endif
+
+%if GLDSONAME
+%system aix
+f 0555 root sys $libdir/libfltk_gl_s.a src/libfltk_gl_s.a nostrip()
+%system hpux
+f 0555 root sys $libdir/libfltk_gl.sl.@FL_API_VERSION@ src/libfltk_gl.sl.@FL_API_VERSION@ nostrip()
+%system darwin
+f 0555 root sys $libdir/libfltk_gl.@FL_API_VERSION@.dylib src/libfltk_gl.@FL_API_VERSION@.dylib nostrip()
+%system !aix !darwin !hpux
+f 0555 root sys $libdir/libfltk_gl.so.@FL_API_VERSION@ src/libfltk_gl.so.@FL_API_VERSION@ nostrip()
+%system all
+%endif
+
+
+%subpackage devel
+%description FLTK Development Environment
+%description Install fltk-devel if you need to develop FLTK applications. 
+%description You'll need to install the fltk package if you plan to run
+%description dynamically linked applications.
+
+%system darwin
+f 0444 root sys $includedir/FL/mac.r FL/mac.r
+l 0444 root sys /usr/include/gcc/darwin/3.1/g++-v3/FL $includedir/FL
+
+d 0555 root sys /Applications/fluid.app -
+d 0555 root sys /Applications/fluid.app/Contents -
+f 0444 root sys /Applications/fluid.app/Contents/Info.plist fluid/fluid.app/Contents/Info.plist
+f 0444 root sys /Applications/fluid.app/Contents/PkgInfo fluid/fluid.app/Contents/PkgInfo
+d 0555 root sys /Applications/fluid.app/Contents/MacOS -
+l 0555 root sys /Applications/fluid.app/Contents/MacOS/fluid $bindir/fluid
+d 0555 root sys /Applications/fluid.app/Contents/Resources -
+f 0444 root sys /Applications/fluid.app/Contents/Resources/fluid.icns fluid/fluid.app/Contents/Resources/fluid.icns
+%postinstall $bindir/fltk-config --post $bindir/fluid
+%postremove /bin/rm -rf /Applications/fluid.app
+
+%system !darwin
+f 0444 root sys /usr/share/applnk/Development/fluid.desktop fluid/fluid.desktop
+f 0444 root sys /usr/share/icons/hicolor/16x16/apps/fluid.png fluid/icons/fluid-16.png
+f 0444 root sys /usr/share/icons/hicolor/32x32/apps/fluid.png fluid/icons/fluid-32.png
+f 0444 root sys /usr/share/icons/hicolor/48x48/apps/fluid.png fluid/icons/fluid-48.png
+f 0444 root sys /usr/share/icons/hicolor/64x64/apps/fluid.png fluid/icons/fluid-64.png
+f 0444 root sys /usr/share/icons/hicolor/128x128/apps/fluid.png fluid/icons/fluid-128.png
+f 0444 root sys /usr/share/mimelnk/application/x-fluid.desktop fluid/x-fluid.desktop
+
+%system all
+
+# FLUID
+f 0555 root sys $bindir/fluid fluid/$FLUID
+f 0555 root sys $bindir/fltk-config fltk-config
+
+# Man pages
+f 0444 root sys $mandir/cat1/fluid.$CAT1EXT documentation/fluid.$CAT1EXT
+f 0444 root sys $mandir/cat1/fltk-config.$CAT1EXT documentation/fltk-config.$CAT1EXT
+f 0444 root sys $mandir/cat3/fltk.$CAT3EXT documentation/fltk.$CAT3EXT
+f 0444 root sys $mandir/man1/fluid.1 documentation/fluid.man
+f 0444 root sys $mandir/man1/fltk-config.1 documentation/fltk-config.man
+f 0444 root sys $mandir/man3/fltk.3 documentation/fltk.man
+
+# Library files
+f 0444 root sys $libdir/libfltk.a lib/libfltk.a
+f 0444 root sys $libdir/libfltk_forms.a lib/libfltk_forms.a
+f 0444 root sys $libdir/libfltk_images.a lib/libfltk_images.a
+%if GLLIBNAME
+f 0444 root sys $libdir/libfltk_gl.a lib/libfltk_gl.a
+%endif
+
+%if JPEG
+f 0444 root sys $libdir/libfltk_jpeg.a lib/libfltk_jpeg.a
+%endif
+
+%if PNG
+f 0444 root sys $libdir/libfltk_png.a lib/libfltk_png.a
+%endif
+
+%if ZLIB
+f 0444 root sys $libdir/libfltk_z.a lib/libfltk_z.a
+%endif
+
+%if DSONAME
+%system hpux
+l 0000 root sys $libdir/libfltk.sl libfltk.sl.@FL_API_VERSION@
+%system darwin
+l 0000 root sys $libdir/libfltk.dylib libfltk.@FL_API_VERSION@.dylib
+%system !aix !darwin !hpux
+l 0000 root sys $libdir/libfltk.so libfltk.so.@FL_API_VERSION@
+%system all
+
+%system hpux
+l 0000 root sys $libdir/libfltk_forms.sl libfltk_forms.sl.@FL_API_VERSION@
+%system darwin
+l 0000 root sys $libdir/libfltk_forms.dylib libfltk_forms.@FL_API_VERSION@.dylib
+%system !aix !darwin !hpux
+l 0000 root sys $libdir/libfltk_forms.so libfltk_forms.so.@FL_API_VERSION@
+%system all
+
+%system hpux
+l 0000 root sys $libdir/libfltk_images.sl libfltk_images.sl.@FL_API_VERSION@
+%system darwin
+l 0000 root sys $libdir/libfltk_images.dylib libfltk_images.@FL_API_VERSION@.dylib
+%system !aix !darwin !hpux
+l 0000 root sys $libdir/libfltk_images.so libfltk_images.so.@FL_API_VERSION@
+%system all
+%endif
+
+%if GLDSONAME
+%system hpux
+l 0000 root sys $libdir/libfltk_gl.sl libfltk_gl.sl.@FL_API_VERSION@
+%system darwin
+l 0000 root sys $libdir/libfltk_gl.dylib libfltk_gl.@FL_API_VERSION@.dylib
+%system !aix !darwin !hpux
+l 0000 root sys $libdir/libfltk_gl.so libfltk_gl.so.@FL_API_VERSION@
+%system all
+%endif
+
+# Header files
+f 0444 root sys $includedir/FL/ FL/*.[hH]
+
+%if JPEG
+f 0444 root sys $includedir/FL/images/jconfig.h jpeg/jconfig.h
+f 0444 root sys $includedir/FL/images/jerror.h jpeg/jerror.h
+f 0444 root sys $includedir/FL/images/jmorecfg.h jpeg/jmorecfg.h
+f 0444 root sys $includedir/FL/images/jpeglib.h jpeg/jpeglib.h
+%endif
+
+%if PNG
+f 0444 root sys $includedir/FL/images/png.h png/png.h
+f 0444 root sys $includedir/FL/images/pngconf.h png/pngconf.h
+%endif
+
+%if ZLIB
+f 0444 root sys $includedir/FL/images/zconf.h zlib/zconf.h
+f 0444 root sys $includedir/FL/images/zlib.h zlib/zlib.h
+f 0444 root sys $includedir/FL/images/zutil.h zlib/zutil.h
+%endif
+
+%system !darwin
+# Symlinks to handle common case problems...
+l 0000 root sys $includedir/Fl FL
+l 0000 root sys $includedir/FL/Enumerations.h Enumerations.H
+l 0000 root sys $includedir/FL/Fl.h Fl.H
+l 0000 root sys $includedir/FL/Fl_Adjuster.h Fl_Adjuster.H
+l 0000 root sys $includedir/FL/Fl_Bitmap.h Fl_Bitmap.H
+l 0000 root sys $includedir/FL/Fl_BMP_Image.h Fl_BMP_Image.H
+l 0000 root sys $includedir/FL/Fl_Box.h Fl_Box.H
+l 0000 root sys $includedir/FL/Fl_Browser.h Fl_Browser.H
+l 0000 root sys $includedir/FL/Fl_Browser_.h Fl_Browser_.H
+l 0000 root sys $includedir/FL/Fl_Button.h Fl_Button.H
+l 0000 root sys $includedir/FL/Fl_Chart.h Fl_Chart.H
+l 0000 root sys $includedir/FL/Fl_Check_Browser.h Fl_Check_Browser.H
+l 0000 root sys $includedir/FL/Fl_Check_Button.h Fl_Check_Button.H
+l 0000 root sys $includedir/FL/Fl_Choice.h Fl_Choice.H
+l 0000 root sys $includedir/FL/Fl_Clock.h Fl_Clock.H
+l 0000 root sys $includedir/FL/Fl_Color_Chooser.h Fl_Color_Chooser.H
+l 0000 root sys $includedir/FL/Fl_Counter.h Fl_Counter.H
+l 0000 root sys $includedir/FL/Fl_Dial.h Fl_Dial.H
+l 0000 root sys $includedir/FL/Fl_Double_Window.h Fl_Double_Window.H
+l 0000 root sys $includedir/FL/Fl_File_Browser.h Fl_File_Browser.H
+l 0000 root sys $includedir/FL/Fl_File_Chooser.h Fl_File_Chooser.H
+l 0000 root sys $includedir/FL/Fl_File_Icon.h Fl_File_Icon.H
+l 0000 root sys $includedir/FL/Fl_Fill_Dial.h Fl_Fill_Dial.H
+l 0000 root sys $includedir/FL/Fl_Fill_Slider.h Fl_Fill_Slider.H
+l 0000 root sys $includedir/FL/Fl_Float_Input.h Fl_Float_Input.H
+l 0000 root sys $includedir/FL/Fl_FormsBitmap.h Fl_FormsBitmap.H
+l 0000 root sys $includedir/FL/Fl_FormsPixmap.h Fl_FormsPixmap.H
+l 0000 root sys $includedir/FL/Fl_Free.h Fl_Free.H
+l 0000 root sys $includedir/FL/Fl_GIF_Image.h Fl_GIF_Image.H
+l 0000 root sys $includedir/FL/Fl_Gl_Window.h Fl_Gl_Window.H
+l 0000 root sys $includedir/FL/Fl_Group.h Fl_Group.H
+l 0000 root sys $includedir/FL/Fl_Help_Dialog.h Fl_Help_Dialog.H
+l 0000 root sys $includedir/FL/Fl_Help_View.h Fl_Help_View.H
+l 0000 root sys $includedir/FL/Fl_Hold_Browser.h Fl_Hold_Browser.H
+l 0000 root sys $includedir/FL/Fl_Hor_Fill_Slider.h Fl_Hor_Fill_Slider.H
+l 0000 root sys $includedir/FL/Fl_Hor_Nice_Slider.h Fl_Hor_Nice_Slider.H
+l 0000 root sys $includedir/FL/Fl_Hor_Slider.h Fl_Hor_Slider.H
+l 0000 root sys $includedir/FL/Fl_Hor_Value_Slider.h Fl_Hor_Value_Slider.H
+l 0000 root sys $includedir/FL/Fl_Image.h Fl_Image.H
+l 0000 root sys $includedir/FL/Fl_JPEG_Image.h Fl_JPEG_Image.H
+l 0000 root sys $includedir/FL/Fl_Input.h Fl_Input.H
+l 0000 root sys $includedir/FL/Fl_Input_.h Fl_Input_.H
+l 0000 root sys $includedir/FL/Fl_Input_Choice.h Fl_Input_Choice.H
+l 0000 root sys $includedir/FL/Fl_Int_Input.h Fl_Int_Input.H
+l 0000 root sys $includedir/FL/Fl_Light_Button.h Fl_Light_Button.H
+l 0000 root sys $includedir/FL/Fl_Line_Dial.h Fl_Line_Dial.H
+l 0000 root sys $includedir/FL/Fl_Menu.h Fl_Menu.H
+l 0000 root sys $includedir/FL/Fl_Menu_.h Fl_Menu_.H
+l 0000 root sys $includedir/FL/Fl_Menu_Bar.h Fl_Menu_Bar.H
+l 0000 root sys $includedir/FL/Fl_Menu_Button.h Fl_Menu_Button.H
+l 0000 root sys $includedir/FL/Fl_Menu_Item.h Fl_Menu_Item.H
+l 0000 root sys $includedir/FL/Fl_Menu_Window.h Fl_Menu_Window.H
+l 0000 root sys $includedir/FL/Fl_Multi_Browser.h Fl_Multi_Browser.H
+l 0000 root sys $includedir/FL/Fl_Multi_Label.h Fl_Multi_Label.H
+l 0000 root sys $includedir/FL/Fl_Multiline_Input.h Fl_Multiline_Input.H
+l 0000 root sys $includedir/FL/Fl_Multiline_Output.h Fl_Multiline_Output.H
+l 0000 root sys $includedir/FL/Fl_Nice_Slider.h Fl_Nice_Slider.H
+l 0000 root sys $includedir/FL/Fl_Object.h Fl_Object.H
+l 0000 root sys $includedir/FL/Fl_Output.h Fl_Output.H
+l 0000 root sys $includedir/FL/Fl_Overlay_Window.h Fl_Overlay_Window.H
+l 0000 root sys $includedir/FL/Fl_Pack.h Fl_Pack.H
+l 0000 root sys $includedir/FL/Fl_Pixmap.h Fl_Pixmap.H
+l 0000 root sys $includedir/FL/Fl_PNG_Image.h Fl_PNG_Image.H
+l 0000 root sys $includedir/FL/Fl_PNM_Image.h Fl_PNM_Image.H
+l 0000 root sys $includedir/FL/Fl_Positioner.h Fl_Positioner.H
+l 0000 root sys $includedir/FL/Fl_Progress.h Fl_Progress.H
+l 0000 root sys $includedir/FL/Fl_Radio_Button.h Fl_Radio_Button.H
+l 0000 root sys $includedir/FL/Fl_Radio_Light_Button.h Fl_Radio_Light_Button.H
+l 0000 root sys $includedir/FL/Fl_Radio_Round_Button.h Fl_Radio_Round_Button.H
+l 0000 root sys $includedir/FL/Fl_Repeat_Button.h Fl_Repeat_Button.H
+l 0000 root sys $includedir/FL/Fl_Return_Button.h Fl_Return_Button.H
+l 0000 root sys $includedir/FL/Fl_Roller.h Fl_Roller.H
+l 0000 root sys $includedir/FL/Fl_Round_Button.h Fl_Round_Button.H
+l 0000 root sys $includedir/FL/Fl_Round_Clock.h Fl_Round_Clock.H
+l 0000 root sys $includedir/FL/Fl_Scroll.h Fl_Scroll.H
+l 0000 root sys $includedir/FL/Fl_Scrollbar.h Fl_Scrollbar.H
+l 0000 root sys $includedir/FL/Fl_Secret_Input.h Fl_Secret_Input.H
+l 0000 root sys $includedir/FL/Fl_Select_Browser.h Fl_Select_Browser.H
+l 0000 root sys $includedir/FL/Fl_Simple_Counter.h Fl_Simple_Counter.H
+l 0000 root sys $includedir/FL/Fl_Single_Window.h Fl_Single_Window.H
+l 0000 root sys $includedir/FL/Fl_Slider.h Fl_Slider.H
+l 0000 root sys $includedir/FL/Fl_Spinner.h Fl_Spinner.H
+l 0000 root sys $includedir/FL/Fl_Tabs.h Fl_Tabs.H
+l 0000 root sys $includedir/FL/Fl_Tile.h Fl_Tile.H
+l 0000 root sys $includedir/FL/Fl_Timer.h Fl_Timer.H
+l 0000 root sys $includedir/FL/Fl_Toggle_Button.h Fl_Toggle_Button.H
+l 0000 root sys $includedir/FL/Fl_Toggle_Light_Button.h Fl_Toggle_Light_Button.H
+l 0000 root sys $includedir/FL/Fl_Toggle_Round_Button.h Fl_Toggle_Round_Button.H
+l 0000 root sys $includedir/FL/Fl_Tooltip.h Fl_Tooltip.H
+l 0000 root sys $includedir/FL/Fl_Valuator.h Fl_Valuator.H
+l 0000 root sys $includedir/FL/Fl_Value_Input.h Fl_Value_Input.H
+l 0000 root sys $includedir/FL/Fl_Value_Output.h Fl_Value_Output.H
+l 0000 root sys $includedir/FL/Fl_Value_Slider.h Fl_Value_Slider.H
+l 0000 root sys $includedir/FL/Fl_Widget.h Fl_Widget.H
+l 0000 root sys $includedir/FL/Fl_Window.h Fl_Window.H
+l 0000 root sys $includedir/FL/Fl_XBM_Image.h Fl_XBM_Image.H
+l 0000 root sys $includedir/FL/Fl_XPM_Image.h Fl_XPM_Image.H
+l 0000 root sys $includedir/FL/filename.h filename.H
+l 0000 root sys $includedir/FL/fl_ask.h fl_ask.H
+l 0000 root sys $includedir/FL/fl_draw.h fl_draw.H
+l 0000 root sys $includedir/FL/fl_file_chooser.h Fl_File_Chooser.H
+l 0000 root sys $includedir/FL/fl_file_chooser.H Fl_File_Chooser.H
+l 0000 root sys $includedir/FL/fl_message.h fl_message.H
+l 0000 root sys $includedir/FL/fl_show_colormap.h fl_show_colormap.H
+l 0000 root sys $includedir/FL/fl_show_input.h fl_show_input.H
+l 0000 root sys $includedir/FL/forms.h forms.H
+l 0000 root sys $includedir/FL/gl_draw.h gl_draw.H
+l 0000 root sys $includedir/FL/glut.h glut.H
+l 0000 root sys $includedir/FL/win32.h win32.H
+l 0000 root sys $includedir/FL/x.h x.H
+%system all
+
+# Documentation
+d 0555 root sys $docdir -
+f 0444 root sys $docdir/ documentation/*.gif
+f 0444 root sys $docdir/ documentation/*.html
+f 0444 root sys $docdir/ documentation/*.jpg
+f 0444 root sys $docdir/COPYING COPYING
+f 0444 root sys $docdir/CHANGES CHANGES
+
+# Examples
+d 0555 root sys $docdir/examples
+f 0444 root sys $docdir/examples/config.h config.h
+f 0444 root sys $docdir/examples/ test/*.cxx
+f 0444 root sys $docdir/examples/ test/*.fl
+f 0444 root sys $docdir/examples/ test/*.h
+
+%subpackage games
+%description FLTK Games
+%description Install fltk-games to play checkers or Sudoku on your computer.
+
+%system darwin
+d 0555 root sys /Applications/checkers.app -
+d 0555 root sys /Applications/checkers.app/Contents -
+f 0444 root sys /Applications/checkers.app/Contents/Info.plist test/checkers.app/Contents/Info.plist
+f 0444 root sys /Applications/checkers.app/Contents/PkgInfo test/checkers.app/Contents/PkgInfo
+d 0555 root sys /Applications/checkers.app/Contents/MacOS -
+f 0555 root sys /Applications/checkers.app/Contents/MacOS/checkers test/checkers
+d 0555 root sys /Applications/checkers.app/Contents/Resources -
+f 0444 root sys /Applications/checkers.app/Contents/Resources/checkers.icns test/checkers.app/Contents/Resources/checkers.icns
+%postremove /bin/rm -rf /Applications/checkers.app
+
+d 0555 root sys /Applications/sudoku.app -
+d 0555 root sys /Applications/sudoku.app/Contents -
+f 0444 root sys /Applications/sudoku.app/Contents/Info.plist test/sudoku.app/Contents/Info.plist
+f 0444 root sys /Applications/sudoku.app/Contents/PkgInfo test/sudoku.app/Contents/PkgInfo
+d 0555 root sys /Applications/sudoku.app/Contents/MacOS -
+f 0555 root sys /Applications/sudoku.app/Contents/MacOS/sudoku test/sudoku
+d 0555 root sys /Applications/sudoku.app/Contents/Resources -
+f 0444 root sys /Applications/sudoku.app/Contents/Resources/sudoku.icns test/sudoku.app/Contents/Resources/sudoku.icns
+%postremove /bin/rm -rf /Applications/sudoku.app
+
+%system !darwin
+f 0555 root sys $bindir/checkers test/checkers
+f 0444 root sys /usr/share/applnk/Games/checkers.desktop test/checkers.desktop
+f 0444 root sys /usr/share/icons/hicolor/32x32/apps/checkers.png checkers/checkers-32.png
+f 0444 root sys /usr/share/icons/hicolor/128x128/apps/checkers.png checkers/checkers-128.png
+
+f 0555 root sys $bindir/sudoku test/sudoku
+f 0444 root sys /usr/share/applnk/Games/sudoku.desktop test/sudoku.desktop
+f 0444 root sys /usr/share/icons/hicolor/32x32/apps/sudoku.png sudoku/sudoku-32.png
+f 0444 root sys /usr/share/icons/hicolor/128x128/apps/sudoku.png sudoku/sudoku-128.png
+
+%system all
+f 0444 root sys $mandir/cat6/checkers.$CAT6EXT documentation/checkers.$CAT6EXT
+f 0444 root sys $mandir/cat6/sudoku.$CAT6EXT documentation/sudoku.$CAT6EXT
+f 0444 root sys $mandir/man6/checkers.6 documentation/checkers.man
+f 0444 root sys $mandir/man6/sudoku.6 documentation/sudoku.man
+
+#
+# End of "$Id: fltk.list.in 4761 2006-01-15 20:33:10Z mike $".
+#
diff --git a/Utilities/FLTK/fltk.spec b/Utilities/FLTK/fltk.spec
new file mode 100644
index 0000000000000000000000000000000000000000..ce4d72fe6a977938f1bdfd943d997939800587ba
--- /dev/null
+++ b/Utilities/FLTK/fltk.spec
@@ -0,0 +1,143 @@
+#
+# "$Id: fltk.spec.in 4756 2006-01-15 18:36:16Z mike $"
+#
+# RPM spec file for FLTK.
+#
+# Copyright 1998-2006 by Bill Spitzak and others.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems on the following page:
+#
+#      http://www.fltk.org/str.php
+#
+
+%define version 1.1.7
+%define release 1
+%define prefix /usr
+
+Summary: Fast Light Tool Kit (FLTK)
+Name: fltk
+Version: %{version}
+Release: %{release}
+License: LGPL
+Group: System Environment/Libraries
+Source: ftp://ftp.easysw.com/pub/fltk/1.1.7/fltk-1.1.7-source.tar.bz2
+URL: http://www.fltk.org/
+Packager: FLTK Developer <fltk@fltk.org>
+# use BuildRoot so as not to disturb the version already installed
+BuildRoot: /var/tmp/fltk-%{PACKAGE_VERSION}
+
+%description
+The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a
+cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11),
+Microsoft(r) Windows(r), and MacOS(r) X.  FLTK provides modern
+GUI functionality without the bloat and supports 3D graphics via
+OpenGL(r) and its built-in GLUT emulation.
+
+%package devel
+Summary: FLTK Development Environment
+Group: Development/Libraries
+
+%description devel
+Install fltk-devel if you need to develop FLTK applications. 
+You'll need to install the fltk package if you plan to run
+dynamically linked applications.
+
+%package games
+Summary: FLTK Games
+Group: Games
+
+%description games
+Install fltk-games to play checkers or Sudoku on your computer.
+
+%prep
+%setup
+
+%build
+CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --mandir=%{_mandir} --enable-shared --enable-xft --enable-xdbe --enable-xinerama
+
+# If we got this far, all prerequisite libraries must be here.
+make
+
+%install
+# these lines just make sure the directory structure in the
+# RPM_BUILD_ROOT exists
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+
+make -e DESTDIR=$RPM_BUILD_ROOT install install-desktop
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%dir %{prefix}/lib
+%{prefix}/lib/libfltk*.so.*
+
+%files devel
+%defattr(-,root,root)
+
+%dir %{prefix}/bin
+%{prefix}/bin/fltk-config
+%{prefix}/bin/fluid
+
+%dir %{prefix}/include/FL
+%{prefix}/include/FL/*
+%{prefix}/include/Fl
+
+%dir %{prefix}/lib
+%{prefix}/lib/libfltk*.so
+%{prefix}/lib/libfltk*.a
+
+%dir %{_mandir}
+%{_mandir}/cat1/*
+%{_mandir}/cat3/*
+%{_mandir}/man1/*
+%{_mandir}/man3/*
+
+%dir %{prefix}/share/doc/fltk
+%{prefix}/share/doc/fltk/*
+
+%dir %{prefix}/share/applnk
+%{prefix}/share/applnk/Development/*
+
+%dir %{prefix}/share/icons
+%{prefix}/share/icons/hicolor/*/apps/fluid.png
+
+%dir %{prefix}/share/mimelnk
+%{prefix}/share/mimelnk/*
+
+%files games
+%dir %{prefix}/bin
+%{prefix}/bin/checkers
+%{prefix}/bin/sudoku
+
+%dir %{_mandir}
+%{_mandir}/cat6/*
+%{_mandir}/man6/*
+
+%dir %{prefix}/share/applnk
+%{prefix}/share/applnk/Games/*
+
+%dir %{prefix}/share/icons
+%{prefix}/share/icons/hicolor/*/apps/checkers.png
+%{prefix}/share/icons/hicolor/*/apps/sudoku.png
+
+#
+# End of "$Id: fltk.spec.in 4756 2006-01-15 18:36:16Z mike $".
+#
diff --git a/Utilities/FLTK/fltk.spec.in b/Utilities/FLTK/fltk.spec.in
new file mode 100644
index 0000000000000000000000000000000000000000..97273d36b6eef31ca111aa4d3eddf327972e1362
--- /dev/null
+++ b/Utilities/FLTK/fltk.spec.in
@@ -0,0 +1,143 @@
+#
+# "$Id: fltk.spec.in 4756 2006-01-15 18:36:16Z mike $"
+#
+# RPM spec file for FLTK.
+#
+# Copyright 1998-2006 by Bill Spitzak and others.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems on the following page:
+#
+#      http://www.fltk.org/str.php
+#
+
+%define version @VERSION@
+%define release @RELEASE@
+%define prefix /usr
+
+Summary: Fast Light Tool Kit (FLTK)
+Name: fltk
+Version: %{version}
+Release: %{release}
+License: LGPL
+Group: System Environment/Libraries
+Source: ftp://ftp.fltk.org/pub/fltk/%{version}/fltk-%{version}-source.tar.gz
+URL: http://www.fltk.org/
+Packager: FLTK Developer <fltk@fltk.org>
+# use BuildRoot so as not to disturb the version already installed
+BuildRoot: /var/tmp/fltk-%{PACKAGE_VERSION}
+
+%description
+The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a
+cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11),
+Microsoft(r) Windows(r), and MacOS(r) X.  FLTK provides modern
+GUI functionality without the bloat and supports 3D graphics via
+OpenGL(r) and its built-in GLUT emulation.
+
+%package devel
+Summary: FLTK Development Environment
+Group: Development/Libraries
+
+%description devel
+Install fltk-devel if you need to develop FLTK applications. 
+You'll need to install the fltk package if you plan to run
+dynamically linked applications.
+
+%package games
+Summary: FLTK Games
+Group: Games
+
+%description games
+Install fltk-games to play checkers or Sudoku on your computer.
+
+%prep
+%setup
+
+%build
+CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --mandir=%{_mandir} --enable-shared --enable-xft --enable-xdbe --enable-xinerama
+
+# If we got this far, all prerequisite libraries must be here.
+make
+
+%install
+# these lines just make sure the directory structure in the
+# RPM_BUILD_ROOT exists
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+
+make -e DESTDIR=$RPM_BUILD_ROOT install install-desktop
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%dir %{prefix}/lib
+%{prefix}/lib/libfltk*.so.*
+
+%files devel
+%defattr(-,root,root)
+
+%dir %{prefix}/bin
+%{prefix}/bin/fltk-config
+%{prefix}/bin/fluid
+
+%dir %{prefix}/include/FL
+%{prefix}/include/FL/*
+%{prefix}/include/Fl
+
+%dir %{prefix}/lib
+%{prefix}/lib/libfltk*.so
+%{prefix}/lib/libfltk*.a
+
+%dir %{_mandir}
+%{_mandir}/cat1/*
+%{_mandir}/cat3/*
+%{_mandir}/man1/*
+%{_mandir}/man3/*
+
+%dir %{prefix}/share/doc/fltk
+%{prefix}/share/doc/fltk/*
+
+%dir %{prefix}/share/applnk
+%{prefix}/share/applnk/Development/*
+
+%dir %{prefix}/share/icons
+%{prefix}/share/icons/hicolor/*/apps/fluid.png
+
+%dir %{prefix}/share/mimelnk
+%{prefix}/share/mimelnk/*
+
+%files games
+%dir %{prefix}/bin
+%{prefix}/bin/checkers
+%{prefix}/bin/sudoku
+
+%dir %{_mandir}
+%{_mandir}/cat6/*
+%{_mandir}/man6/*
+
+%dir %{prefix}/share/applnk
+%{prefix}/share/applnk/Games/*
+
+%dir %{prefix}/share/icons
+%{prefix}/share/icons/hicolor/*/apps/checkers.png
+%{prefix}/share/icons/hicolor/*/apps/sudoku.png
+
+#
+# End of "$Id: fltk.spec.in 4756 2006-01-15 18:36:16Z mike $".
+#
diff --git a/Utilities/FLTK/fltk.xpm b/Utilities/FLTK/fltk.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..c0c232c167c0cf8ade0427450278113f57a5e898
--- /dev/null
+++ b/Utilities/FLTK/fltk.xpm
@@ -0,0 +1,225 @@
+/* XPM */
+static char * fltk_xpm[] = {
+"229 70 152 2",
+"  	c None",
+". 	c #000066",
+"+ 	c #68689A",
+"@ 	c #9292AF",
+"# 	c #232377",
+"$ 	c #CCCCCC",
+"% 	c #31317E",
+"& 	c #7878A2",
+"* 	c #5D5D95",
+"= 	c #1F1F76",
+"- 	c #31317F",
+"; 	c #11116F",
+"> 	c #B4B4C0",
+", 	c #ADADBC",
+"' 	c #4C4C8C",
+") 	c #595993",
+"! 	c #3A3A83",
+"~ 	c #7373A0",
+"{ 	c #51518E",
+"] 	c #A1A1B6",
+"^ 	c #49498B",
+"/ 	c #8989AA",
+"( 	c #020267",
+"_ 	c #050568",
+": 	c #444488",
+"< 	c #71719F",
+"[ 	c #1A1A73",
+"} 	c #5E5E95",
+"| 	c #9E9EB5",
+"1 	c #252578",
+"2 	c #A4A4B8",
+"3 	c #666699",
+"4 	c #2B2B7C",
+"5 	c #8383A7",
+"6 	c #10106E",
+"7 	c #6D6D9D",
+"8 	c #0B0B6B",
+"9 	c #CBCBCB",
+"0 	c #010166",
+"a 	c #7979A2",
+"b 	c #6E6E9D",
+"c 	c #0A0A6B",
+"d 	c #7676A1",
+"e 	c #C9C9CA",
+"f 	c #2A2A7B",
+"g 	c #9696B1",
+"h 	c #6A6A9B",
+"i 	c #262679",
+"j 	c #49498A",
+"k 	c #C2C2C7",
+"l 	c #47478A",
+"m 	c #BCBCC4",
+"n 	c #424287",
+"o 	c #4A4A8B",
+"p 	c #C5C5C9",
+"q 	c #454588",
+"r 	c #BBBBC3",
+"s 	c #434388",
+"t 	c #69699B",
+"u 	c #535390",
+"v 	c #5B5B93",
+"w 	c #73739F",
+"x 	c #CACACB",
+"y 	c #8888AA",
+"z 	c #050569",
+"A 	c #7F7FA5",
+"B 	c #7575A0",
+"C 	c #8C8CAC",
+"D 	c #8A8AAB",
+"E 	c #13136F",
+"F 	c #09096B",
+"G 	c #C8C8CA",
+"H 	c #040468",
+"I 	c #7474A0",
+"J 	c #8F8FAD",
+"K 	c #12126F",
+"L 	c #08086A",
+"M 	c #70709E",
+"N 	c #C7C7CA",
+"O 	c #0D0D6C",
+"P 	c #07076A",
+"Q 	c #8B8BAC",
+"R 	c #8787AA",
+"S 	c #6F6F9D",
+"T 	c #0F0F6E",
+"U 	c #7575A1",
+"V 	c #8787A9",
+"W 	c #CBCBCC",
+"X 	c #11116E",
+"Y 	c #7777A2",
+"Z 	c #8585A9",
+"` 	c #8B8BAB",
+" .	c #8383A8",
+"..	c #030367",
+"+.	c #070769",
+"@.	c #8484A8",
+"#.	c #0F0F6D",
+"$.	c #0D0D6D",
+"%.	c #0C0C6C",
+"&.	c #8181A7",
+"*.	c #ABABBC",
+"=.	c #B5B5C0",
+"-.	c #1E1E75",
+";.	c #A3A3B7",
+">.	c #242478",
+",.	c #A8A8BA",
+"'.	c #141470",
+").	c #A5A5B8",
+"!.	c #252579",
+"~.	c #A5A5B9",
+"{.	c #191973",
+"].	c #B5B5C1",
+"^.	c #161671",
+"/.	c #B7B7C1",
+"(.	c #A3A3B8",
+"_.	c #212177",
+":.	c #B2B2BF",
+"<.	c #B0B0BE",
+"[.	c #232378",
+"}.	c #AEAEBD",
+"|.	c #B6B6C1",
+"1.	c #212176",
+"2.	c #C3C3C8",
+"3.	c #ABABBB",
+"4.	c #151570",
+"5.	c #414186",
+"6.	c #BBBBC4",
+"7.	c #B9B9C2",
+"8.	c #1D1D75",
+"9.	c #464689",
+"0.	c #BFBFC6",
+"a.	c #A7A7B9",
+"b.	c #28287A",
+"c.	c #010167",
+"d.	c #BDBDC5",
+"e.	c #B9B9C3",
+"f.	c #454589",
+"g.	c #BDBDC4",
+"h.	c #A9A9BB",
+"i.	c #414187",
+"j.	c #C0C0C6",
+"k.	c #27277A",
+"l.	c #3E3E85",
+"m.	c #A6A6B9",
+"n.	c #C3C3C7",
+"o.	c #151571",
+"p.	c #030368",
+"q.	c #0B0B6C",
+"r.	c #B1B1BF",
+"s.	c #404086",
+"t.	c #C7C7C9",
+"u.	c #0E0E6D",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ : < @ @ @ @ @ @ @ @ @ @ @ @ [ . . . . . . . . . . . . . . . . . . . . . t @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . . c w x $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ y z . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . 0 B $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ C z . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . h $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ D E . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . F < G $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ y F . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . H I $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ J . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . 7 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ y K . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . L M N $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 9 / O . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . P I $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ Q . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . M $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ R 6 . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . z S N $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 9 D T . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . F U $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ y . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ & * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * = $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ^ * * * * * * * * * * * * * * * * * * * * * * * * 2 $ $ $ $ $ $ $ $ $ $ $ $ $ 3 * * * * * * * * * * * * * * * * * * * * * * * 4 | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . ~ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ V O . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . ( 7 G $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ W C X . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . 8 Y $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ Z . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . d $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ R F . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . 7 x $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ` ; . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . 8 & 9 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $  .... . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . 0 a $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ / _ . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ y ; . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 c d e $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 5 +.. . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ f & $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ D . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ g $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ Z 6 . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 9 @.c . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ R . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ @.#.. . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ > , , , , , , , , , , , , , , , , , , , , , , , , , , , ' . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ x Z $.. . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ @.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ @.%.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 9 V #.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ &.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ @.L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ *.$.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ =.-.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ;.>.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ,.'.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ > [ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ).!.. . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ~.{.. . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ > , , , , , , , , , , , , , , , , , , , , , , , , , , , ' . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ].^.. . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ,.!.. . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ h $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 2 -.. . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ i j k $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ /.X . . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . l m $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ *.1 . . . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . n $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ (._.. . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . o p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ :.; . . . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . q r $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ <.[.. . . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . s G $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 2 >.. . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . o x $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ }.K . . . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . n r $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ |.1.. . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . q 2.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ).i . . . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . l $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 3.4.. . . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . 0 5.6.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 7.8.. . . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ( . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . 9.0.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ a.b.. . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . : $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ,.[ . . . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . c.n d.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ e.{.. . . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . f.g.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ h.b.. . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . i.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ a.= . . . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . c.: j.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ r '.. . . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . : r $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ , k.. . . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . l.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ m.[.. . . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . . q n.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ |.o.. . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . . . n e.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ r.i . . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . . . . s.N $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ m.i . . ",
+". . @ $ $ $ $ $ $ $ $ $ $ $ $ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ _ . . . . . . . . . . . . . . . . . . . . 5 $ $ $ $ $ $ $ $ $ $ $ $ $ 6 . . . . . . . . . . . . . . . . . . . . . . . . | $ $ $ $ $ $ $ $ $ $ $ $ 1 . . . . . . . . . . . . . . . . . . . . . . q t.$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ r.T . ",
+". . + @ @ @ @ @ @ @ @ @ @ @ @ [.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ p.. . . . . . . . . . . . . . . . . . . . } @ @ @ @ @ @ @ @ @ @ @ @ @ q.. . . . . . . . . . . . . . . . . . . . . . . . < @ @ @ @ @ @ @ @ @ @ @ @ [ . . . . . . . . . . . . . . . . . . . . . . . s.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ u.. ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/Utilities/FLTK/fluid/CMakeLists.txt b/Utilities/FLTK/fluid/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..347f258dc53c2e53c3a173ed31fc85e40f381e19
--- /dev/null
+++ b/Utilities/FLTK/fluid/CMakeLists.txt
@@ -0,0 +1,30 @@
+SET(CPPFILES
+	CodeEditor.cxx
+	Fl_Function_Type.cxx
+	Fl_Group_Type.cxx
+	Fl_Menu_Type.cxx
+	Fl_Type.cxx
+	Fl_Widget_Type.cxx
+	Fl_Window_Type.cxx
+	Fluid_Image.cxx
+	about_panel.cxx
+	align_widget.cxx
+	alignment_panel.cxx
+	code.cxx
+	factory.cxx
+	file.cxx
+	fluid.cxx
+	function_panel.cxx
+	template_panel.cxx
+	undo.cxx
+	widget_panel.cxx
+)
+
+
+ADD_EXECUTABLE(fluid ${CPPFILES})
+INSTALL_TARGETS(/bin fluid)
+TARGET_LINK_LIBRARIES(fluid fltk fltk_images fltk_forms ${FLTK_PLATFORM_DEPENDENT_LIBS})
+IF(OPENGL_FOUND)
+	TARGET_LINK_LIBRARIES(fluid fltk_gl)
+ENDIF(OPENGL_FOUND)
+
diff --git a/Utilities/FLTK/fluid/CodeEditor.cxx b/Utilities/FLTK/fluid/CodeEditor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..af1e0c8acb9b4b839573baff0e98132019f9ef03
--- /dev/null
+++ b/Utilities/FLTK/fluid/CodeEditor.cxx
@@ -0,0 +1,411 @@
+//
+// "$Id$"
+//
+// Code editor widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//
+// Include necessary headers...
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "CodeEditor.h"
+
+
+Fl_Text_Display::Style_Table_Entry CodeEditor::
+		styletable[] = {	// Style table
+		  { FL_FOREGROUND_COLOR, FL_COURIER,        11 }, // A - Plain
+		  { FL_DARK_GREEN,       FL_COURIER_ITALIC, 11 }, // B - Line comments
+		  { FL_DARK_GREEN,       FL_COURIER_ITALIC, 11 }, // C - Block comments
+		  { FL_BLUE,             FL_COURIER,        11 }, // D - Strings
+		  { FL_DARK_RED,         FL_COURIER,        11 }, // E - Directives
+		  { FL_DARK_RED,         FL_COURIER_BOLD,   11 }, // F - Types
+		  { FL_BLUE,             FL_COURIER_BOLD,   11 }  // G - Keywords
+		};
+const char * const CodeEditor::
+		code_keywords[] = {	// Sorted list of C/C++ keywords...
+		  "and",
+		  "and_eq",
+		  "asm",
+		  "bitand",
+		  "bitor",
+		  "break",
+		  "case",
+		  "catch",
+		  "compl",
+		  "continue",
+		  "default",
+		  "delete",
+		  "do",
+		  "else",
+		  "false",
+		  "for",
+		  "goto",
+		  "if",
+		  "new",
+		  "not",
+		  "not_eq",
+		  "operator",
+		  "or",
+		  "or_eq",
+		  "return",
+		  "switch",
+		  "template",
+		  "this",
+		  "throw",
+		  "true",
+		  "try",
+		  "while",
+		  "xor",
+		  "xor_eq"
+		};
+const char * const CodeEditor::
+		code_types[] = {	// Sorted list of C/C++ types...
+		  "auto",
+		  "bool",
+		  "char",
+		  "class",
+		  "const",
+		  "const_cast",
+		  "double",
+		  "dynamic_cast",
+		  "enum",
+		  "explicit",
+		  "extern",
+		  "float",
+		  "friend",
+		  "inline",
+		  "int",
+		  "long",
+		  "mutable",
+		  "namespace",
+		  "private",
+		  "protected",
+		  "public",
+		  "register",
+		  "short",
+		  "signed",
+		  "sizeof",
+		  "static",
+		  "static_cast",
+		  "struct",
+		  "template",
+		  "typedef",
+		  "typename",
+		  "union",
+		  "unsigned",
+		  "virtual",
+		  "void",
+		  "volatile"
+		};
+
+
+// 'compare_keywords()' - Compare two keywords...
+int CodeEditor::compare_keywords(const void *a, const void *b) {
+  return (strcmp(*((const char **)a), *((const char **)b)));
+}
+
+// 'style_parse()' - Parse text and produce style data.
+void CodeEditor::style_parse(const char *text, char *style, int length) {
+  char		current;
+  int		col;
+  int		last;
+  char		buf[255],
+		*bufptr;
+  const char	*temp;
+
+  // Style letters:
+  //
+  // A - Plain
+  // B - Line comments
+  // C - Block comments
+  // D - Strings
+  // E - Directives
+  // F - Types
+  // G - Keywords
+
+  for (current = *style, col = 0, last = 0; length > 0; length --, text ++) {
+    if (current == 'B' || current == 'F' || current == 'G') current = 'A';
+    if (current == 'A') {
+      // Check for directives, comments, strings, and keywords...
+      if (col == 0 && *text == '#') {
+        // Set style to directive
+        current = 'E';
+      } else if (strncmp(text, "//", 2) == 0) {
+        current = 'B';
+	for (; length > 0 && *text != '\n'; length --, text ++) *style++ = 'B';
+
+        if (length == 0) break;
+      } else if (strncmp(text, "/*", 2) == 0) {
+        current = 'C';
+      } else if (strncmp(text, "\\\"", 2) == 0) {
+        // Quoted quote...
+	*style++ = current;
+	*style++ = current;
+	text ++;
+	length --;
+	col += 2;
+	continue;
+      } else if (*text == '\"') {
+        current = 'D';
+      } else if (!last && (islower(*text) || *text == '_')) {
+        // Might be a keyword...
+	for (temp = text, bufptr = buf;
+	     (islower(*temp) || *temp == '_') && bufptr < (buf + sizeof(buf) - 1);
+	     *bufptr++ = *temp++);
+
+        if (!islower(*temp) && *temp != '_') {
+	  *bufptr = '\0';
+
+          bufptr = buf;
+
+	  if (bsearch(&bufptr, code_types,
+	              sizeof(code_types) / sizeof(code_types[0]),
+		      sizeof(code_types[0]), compare_keywords)) {
+	    while (text < temp) {
+	      *style++ = 'F';
+	      text ++;
+	      length --;
+	      col ++;
+	    }
+
+	    text --;
+	    length ++;
+	    last = 1;
+	    continue;
+	  } else if (bsearch(&bufptr, code_keywords,
+	                     sizeof(code_keywords) / sizeof(code_keywords[0]),
+		             sizeof(code_keywords[0]), compare_keywords)) {
+	    while (text < temp) {
+	      *style++ = 'G';
+	      text ++;
+	      length --;
+	      col ++;
+	    }
+
+	    text --;
+	    length ++;
+	    last = 1;
+	    continue;
+	  }
+	}
+      }
+    } else if (current == 'C' && strncmp(text, "*/", 2) == 0) {
+      // Close a C comment...
+      *style++ = current;
+      *style++ = current;
+      text ++;
+      length --;
+      current = 'A';
+      col += 2;
+      continue;
+    } else if (current == 'D') {
+      // Continuing in string...
+      if (strncmp(text, "\\\"", 2) == 0) {
+        // Quoted end quote...
+	*style++ = current;
+	*style++ = current;
+	text ++;
+	length --;
+	col += 2;
+	continue;
+      } else if (*text == '\"') {
+        // End quote...
+	*style++ = current;
+	col ++;
+	current = 'A';
+	continue;
+      }
+    }
+
+    // Copy style info...
+    if (current == 'A' && (*text == '{' || *text == '}')) *style++ = 'G';
+    else *style++ = current;
+    col ++;
+
+    last = isalnum(*text) || *text == '_' || *text == '.';
+
+    if (*text == '\n') {
+      // Reset column and possibly reset the style
+      col = 0;
+      if (current == 'B' || current == 'E') current = 'A';
+    }
+  }
+}
+
+// 'style_unfinished_cb()' - Update unfinished styles.
+void CodeEditor::style_unfinished_cb(int, void*) { }
+
+// 'style_update()' - Update the style buffer...
+void CodeEditor::style_update(int pos, int nInserted, int nDeleted,
+                              int /*nRestyled*/, const char * /*deletedText*/,
+                              void *cbArg) {
+  CodeEditor	*editor = (CodeEditor *)cbArg;
+  int		start,				// Start of text
+		end;				// End of text
+  char		last,				// Last style on line
+		*style,				// Style data
+		*text;				// Text data
+
+
+  // If this is just a selection change, just unselect the style buffer...
+  if (nInserted == 0 && nDeleted == 0) {
+    editor->mStyleBuffer->unselect();
+    return;
+  }
+
+  // Track changes in the text buffer...
+  if (nInserted > 0) {
+    // Insert characters into the style buffer...
+    style = new char[nInserted + 1];
+    memset(style, 'A', nInserted);
+    style[nInserted] = '\0';
+
+    editor->mStyleBuffer->replace(pos, pos + nDeleted, style);
+    delete[] style;
+  } else {
+    // Just delete characters in the style buffer...
+    editor->mStyleBuffer->remove(pos, pos + nDeleted);
+  }
+
+  // Select the area that was just updated to avoid unnecessary
+  // callbacks...
+  editor->mStyleBuffer->select(pos, pos + nInserted - nDeleted);
+
+  // Re-parse the changed region; we do this by parsing from the
+  // beginning of the line of the changed region to the end of
+  // the line of the changed region...  Then we check the last
+  // style character and keep updating if we have a multi-line
+  // comment character...
+  start = editor->mBuffer->line_start(pos);
+  end   = editor->mBuffer->line_end(pos + nInserted);
+  text  = editor->mBuffer->text_range(start, end);
+  style = editor->mStyleBuffer->text_range(start, end);
+  if (start==end)
+    last = 0;
+  else
+    last  = style[end - start - 1];
+
+  style_parse(text, style, end - start);
+
+  editor->mStyleBuffer->replace(start, end, style);
+  editor->redisplay_range(start, end);
+
+  if (start==end || last != style[end - start - 1]) {
+    // The last character on the line changed styles, so reparse the
+    // remainder of the buffer...
+    free(text);
+    free(style);
+
+    end   = editor->mBuffer->length();
+    text  = editor->mBuffer->text_range(start, end);
+    style = editor->mStyleBuffer->text_range(start, end);
+
+    style_parse(text, style, end - start);
+
+    editor->mStyleBuffer->replace(start, end, style);
+    editor->redisplay_range(start, end);
+  }
+
+  free(text);
+  free(style);
+}
+
+int CodeEditor::auto_indent(int, CodeEditor* e) {
+  if (e->buffer()->selected()) {
+    e->insert_position(e->buffer()->primary_selection()->start());
+    e->buffer()->remove_selection();
+  }
+
+  int pos = e->insert_position();
+  int start = e->line_start(pos);
+  char *text = e->buffer()->text_range(start, pos);
+  char *ptr;
+
+  for (ptr = text; isspace(*ptr); ptr ++);
+  *ptr = '\0';  
+  if (*text) {
+    // use only a single 'insert' call to avoid redraw issues
+    int n = strlen(text);
+    char *b = (char*)malloc(n+2);
+    *b = '\n';
+    strcpy(b+1, text);
+    e->insert(b);
+    free(b);
+  } else {
+    e->insert("\n");
+  }
+  e->show_insert_position();
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+
+  free(text);
+
+  return 1;
+}
+
+// Create a CodeEditor widget...
+CodeEditor::CodeEditor(int X, int Y, int W, int H, const char *L) :
+  Fl_Text_Editor(X, Y, W, H, L) {
+  buffer(new Fl_Text_Buffer);
+
+  char *style = new char[mBuffer->length() + 1];
+  char *text = mBuffer->text();
+
+  memset(style, 'A', mBuffer->length());
+  style[mBuffer->length()] = '\0';
+
+  highlight_data(new Fl_Text_Buffer(mBuffer->length()), styletable,
+                 sizeof(styletable) / sizeof(styletable[0]),
+		 'A', style_unfinished_cb, this);
+
+  style_parse(text, style, mBuffer->length());
+
+  mStyleBuffer->text(style);
+  delete[] style;
+  free(text);
+
+  mBuffer->add_modify_callback(style_update, this);
+  add_key_binding(FL_Enter, FL_TEXT_EDITOR_ANY_STATE,
+                  (Fl_Text_Editor::Key_Func)auto_indent);
+}
+
+// Destroy a CodeEditor widget...
+CodeEditor::~CodeEditor() {
+  Fl_Text_Buffer *buf = mStyleBuffer;
+  mStyleBuffer = 0;
+  delete buf;
+
+  buf = mBuffer;
+  buffer(0);
+  delete buf;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/CodeEditor.h b/Utilities/FLTK/fluid/CodeEditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..04c51bd09585c821b9c1934c48387b91fa513c1c
--- /dev/null
+++ b/Utilities/FLTK/fluid/CodeEditor.h
@@ -0,0 +1,77 @@
+//
+// "$Id$"
+//
+// Code editor widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef CodeEditor_h
+#  define CodeEditor_h
+
+//
+// Include necessary headers...
+//
+
+#  include <stdio.h>
+#  include <stdlib.h>
+#  include <string.h>
+#  include <ctype.h>
+#  include <FL/Fl.H>
+#  include <FL/Fl_Text_Buffer.H>
+#  include <FL/Fl_Text_Editor.H>
+
+
+class CodeEditor : public Fl_Text_Editor {
+  static Fl_Text_Display::Style_Table_Entry styletable[];
+  static const char * const code_keywords[];
+  static const char * const code_types[];
+
+
+  // 'compare_keywords()' - Compare two keywords...
+  static int compare_keywords(const void *a, const void *b);
+
+  // 'style_parse()' - Parse text and produce style data.
+  static void style_parse(const char *text, char *style, int length);
+
+  // 'style_unfinished_cb()' - Update unfinished styles.
+  static void style_unfinished_cb(int, void*);
+
+  // 'style_update()' - Update the style buffer...
+  static void style_update(int pos, int nInserted, int nDeleted,
+                           int /*nRestyled*/, const char * /*deletedText*/,
+                           void *cbArg);
+
+  static int auto_indent(int, CodeEditor* e);
+
+  public:
+
+  CodeEditor(int X, int Y, int W, int H, const char *L=0);
+  ~CodeEditor();
+  int top_line() { return get_absolute_top_line_number(); }
+};
+
+#endif // !CodeEditor_h
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Function_Type.cxx b/Utilities/FLTK/fluid/Fl_Function_Type.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..77391abc1c4764da966ca1437296c10b8792d3a9
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Function_Type.cxx
@@ -0,0 +1,1091 @@
+//
+// "$Id$"
+//
+// C function type code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Preferences.H>
+#include <FL/Fl_File_Chooser.H>
+#include "Fl_Type.h"
+#include <FL/fl_show_input.H>
+#include "../src/flstring.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int i18n_type;
+extern const char* i18n_include;
+extern const char* i18n_function;
+extern const char* i18n_file;
+extern const char* i18n_set;
+extern char i18n_program[];
+
+////////////////////////////////////////////////////////////////
+// quick check of any C code for legality, returns an error message
+
+static char buffer[128]; // for error messages
+
+// check a quoted string ending in either " or ' or >:
+const char *_q_check(const char * & c, int type) {
+  for (;;) switch (*c++) {
+  case '\0':
+    sprintf(buffer,"missing %c",type);
+    return buffer;
+  case '\\':
+    if (*c) c++;
+    break;
+  default:
+    if (*(c-1) == type) return 0;
+  }
+}
+
+// check normal code, match braces and parenthesis:
+const char *_c_check(const char * & c, int type) {
+  const char *d;
+  for (;;) switch (*c++) {
+  case 0:
+    if (!type) return 0;
+    sprintf(buffer, "missing %c", type);
+    return buffer;
+  case '/':
+    // Skip comments as needed...
+    if (*c == '/') {
+      while (*c != '\n' && *c) c++;
+    } else if (*c == '*') {
+      c++;
+      while ((*c != '*' || c[1] != '/') && *c) c++;
+      if (*c == '*') c+=2;
+      else {
+        return "missing '*/'";
+      }
+    }
+    break;
+  case '#':
+    // treat cpp directives as a comment:
+    while (*c != '\n' && *c) c++;
+    break;
+  case '{':
+    if (type==')') goto UNEXPECTED;
+    d = _c_check(c,'}');
+    if (d) return d;
+    break;
+  case '(':
+    d = _c_check(c,')');
+    if (d) return d;
+    break;
+  case '\"':
+    d = _q_check(c,'\"');
+    if (d) return d;
+    break;
+  case '\'':
+    d = _q_check(c,'\'');
+    if (d) return d;
+    break;
+  case '}':
+  case ')':
+  UNEXPECTED:
+    if (type == *(c-1)) return 0;
+    sprintf(buffer, "unexpected %c", *(c-1));
+    return buffer;
+  }
+}
+
+const char *c_check(const char *c, int type) {
+  return _c_check(c,type);
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl_Function_Type::is_public() const {return public_;}
+
+Fl_Type *Fl_Function_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_decl_block()) p = p->parent;
+  Fl_Function_Type *o = new Fl_Function_Type();
+  o->name("make_window()");
+  o->return_type = 0;
+  o->add(p);
+  o->factory = this;
+  o->public_ = 1;
+  o->cdecl_ = 0;
+  return o;
+}
+
+void Fl_Function_Type::write_properties() {
+  Fl_Type::write_properties();
+  if (!public_) write_string("private");
+  if (cdecl_) write_string("C");
+  if (return_type) {
+    write_string("return_type");
+    write_word(return_type);
+  }
+}
+
+void Fl_Function_Type::read_property(const char *c) {
+  if (!strcmp(c,"private")) {
+    public_ = 0;
+  } else if (!strcmp(c,"C")) {
+    cdecl_ = 1;
+  } else if (!strcmp(c,"return_type")) {
+    storestring(read_word(),return_type);
+  } else {
+    Fl_Type::read_property(c);
+  }
+}
+
+#include "function_panel.h"
+#include <FL/fl_ask.H>
+
+void Fl_Function_Type::open() {
+  if (!function_panel) make_function_panel();
+  f_return_type_input->static_value(return_type);
+  f_name_input->static_value(name());
+  f_public_button->value(public_);
+  f_c_button->value(cdecl_);
+  function_panel->show();
+  const char* message = 0;
+  for (;;) { // repeat as long as there are errors
+    if (message) fl_alert(message);
+    for (;;) {
+      Fl_Widget* w = Fl::readqueue();
+      if (w == f_panel_cancel) goto BREAK2;
+      else if (w == f_panel_ok) break;
+      else if (!w) Fl::wait();
+    }
+    const char*c = f_name_input->value();
+    while (isspace(*c)) c++;
+    message = c_check(c); if (message) continue;
+    const char *d = c;
+    for (; *d != '('; d++) if (isspace(*d) || !*d) break;
+    if (*c && *d != '(') {
+      message = "must be name(arguments), try again:"; continue;
+    }
+    int mod = 0;
+    c = f_return_type_input->value();
+    message = c_check(c); if (message) continue;
+    name(f_name_input->value());
+    storestring(c, return_type);
+    if (public_ != f_public_button->value()) {
+      mod = 1;
+      public_ = f_public_button->value();
+    }
+    if (cdecl_ != f_c_button->value()) {
+      mod = 1;
+      cdecl_ = f_c_button->value();
+    }
+    if (mod) set_modflag(1);
+    break;
+  }
+ BREAK2:
+  function_panel->hide();
+}
+
+Fl_Function_Type Fl_Function_type;
+
+extern const char* subclassname(Fl_Type*);
+
+void Fl_Function_Type::write_code1() {
+  constructor=0;
+  havewidgets = 0;
+  Fl_Type *child;
+  for (child = next; child && child->level > level; child = child->next)
+    if (child->is_widget()) {
+      havewidgets = 1;
+      break;
+    }
+  write_c("\n");
+  if (ismain())
+    write_c("int main(int argc, char **argv) {\n");
+  else {
+    const char* rtype = return_type;
+    const char* star = "";
+    // from matt: let the user type "static " at the start of type
+    // in order to declare a static method;
+    int is_static = 0;
+    int is_virtual = 0;
+    if (rtype) {
+      if (!strcmp(rtype,"static")) {is_static = 1; rtype = 0;}
+      else if (!strncmp(rtype, "static ",7)) {is_static = 1; rtype += 7;}
+      if (!strcmp(rtype, "virtual")) {is_virtual = 1; rtype = 0;}
+      else if (!strncmp(rtype, "virtual ",8)) {is_virtual = 1; rtype += 8;}
+    }
+    if (!rtype) {
+      if (havewidgets) {
+	rtype = subclassname(child);
+	star = "*";
+      } else rtype = "void";
+    }
+
+    const char* k = class_name(0);
+    if (k) {
+      write_public(public_);
+      if (name()[0] == '~')
+	constructor = 1;
+      else {
+	size_t n = strlen(k);
+	if (!strncmp(name(), k, n) && name()[n] == '(') constructor = 1;
+      }
+      write_h("  ");
+      if (is_static) write_h("static ");
+      if (is_virtual) write_h("virtual ");
+      if (!constructor) {
+        write_h("%s%s ", rtype, star);
+	write_c("%s%s ", rtype, star);
+      }
+
+      // if this is a subclass, only write_h() the part before the ':'
+      char s[1024], *sptr = s;
+      char *nptr = (char *)name();
+
+      while (*nptr) {
+        if (*nptr == ':') {
+	  if (nptr[1] != ':') break;
+	  // Copy extra ":" for "class::member"...
+          *sptr++ = *nptr++;
+        }	  
+        *sptr++ = *nptr++;
+      }
+      *sptr = '\0';
+
+      write_h("%s;\n", s);
+      // skip all function default param. init in body:
+      int skips=0,skipc=0;
+      int nc=0,plevel=0;
+      for (sptr=s,nptr=(char*)name(); *nptr; nc++,nptr++) {
+	if (!skips && *nptr=='(') plevel++;
+	else if (!skips && *nptr==')') plevel--;
+	if ( *nptr=='"' &&  !(nc &&  *(nptr-1)=='\\') ) 
+	  skips = skips ? 0 : 1;
+	else if(!skips && *nptr=='\'' &&  !(nc &&  *(nptr-1)=='\\'))
+	  skipc = skipc ? 0 : 1;
+	if(!skips && !skipc && plevel==1 && *nptr =='=' && 
+	   !(nc && *(nptr-1)=='\'') ) // ignore '=' case 
+	  while(*++nptr  && (skips || skipc || (*nptr!=',' && *nptr!=')' || plevel!=1) )) {
+	    if ( *nptr=='"' &&  *(nptr-1)!='\\' ) 
+	      skips = skips ? 0 : 1;
+	    else if(!skips && *nptr=='\'' &&  *(nptr-1)!='\\')
+	      skipc = skipc ? 0 : 1;
+	    if (!skips && !skipc && *nptr=='(') plevel++;
+	    else if (!skips && *nptr==')') plevel--;
+	  }
+
+	if (sptr < (s + sizeof(s) - 1))	*sptr++ = *nptr;
+      }
+      *sptr = '\0';
+ 
+      write_c("%s::%s {\n", k, s);
+    } else {
+      if (public_) {
+	if (cdecl_)
+	  write_h("extern \"C\" { %s%s %s; }\n", rtype, star, name());
+	else
+	  write_h("%s%s %s;\n", rtype, star, name());
+      }
+      else write_c("static ");
+
+      // write everything but the default parameters (if any)
+      char s[1024], *sptr;
+      char *nptr;
+      int skips=0,skipc=0;
+      int nc=0,plevel=0;
+      for (sptr=s,nptr=(char*)name(); *nptr; nc++,nptr++) {
+	if (!skips && *nptr=='(') plevel++;
+	else if (!skips && *nptr==')') plevel--;
+	if ( *nptr=='"' &&  !(nc &&  *(nptr-1)=='\\') ) 
+	  skips = skips ? 0 : 1;
+	else if(!skips && *nptr=='\'' &&  !(nc &&  *(nptr-1)=='\\'))
+	  skipc = skipc ? 0 : 1;
+	if(!skips && !skipc && plevel==1 && *nptr =='=' && 
+	   !(nc && *(nptr-1)=='\'') ) // ignore '=' case 
+	  while(*++nptr  && (skips || skipc || (*nptr!=',' && *nptr!=')' || plevel!=1) )) {
+	    if ( *nptr=='"' &&  *(nptr-1)!='\\' ) 
+	      skips = skips ? 0 : 1;
+	    else if(!skips && *nptr=='\'' &&  *(nptr-1)!='\\')
+	      skipc = skipc ? 0 : 1;
+	    if (!skips && !skipc && *nptr=='(') plevel++;
+	    else if (!skips && *nptr==')') plevel--;
+	  }
+
+	if (sptr < (s + sizeof(s) - 1))	*sptr++ = *nptr;
+      }
+      *sptr = '\0';
+ 
+      write_c("%s%s %s {\n", rtype, star, s);
+    }
+  }
+  if (havewidgets) write_c("  %s* w;\n",subclassname(child));
+  indentation += 2;
+}
+
+void Fl_Function_Type::write_code2() {
+  if (ismain()) {
+    if (havewidgets) write_c("  w->show(argc, argv);\n");
+    write_c("  return Fl::run();\n");
+  } else if (havewidgets && !constructor && !return_type)
+    write_c("  return w;\n");
+  write_c("}\n");
+  indentation = 0;
+}
+
+int Fl_Function_Type::has_signature(const char *rtype, const char *sig) const {
+  if (!return_type) return 0;
+  if (!name()) return 0;
+  if (   strcmp(return_type, rtype)==0 
+      && fl_filename_match(name(), sig)) {
+    return 1;
+  }
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Type *Fl_Code_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_code_block()) p = p->parent;
+  if (!p) {
+    fl_message("Please select a function");
+    return 0;
+  }
+  Fl_Code_Type *o = new Fl_Code_Type();
+  o->name("printf(\"Hello, World!\\n\");");
+  o->add(p);
+  o->factory = this;
+  return o;
+}
+
+void Fl_Code_Type::open() {
+  if (!code_panel) make_code_panel();
+  const char *text = name();
+  code_input->buffer()->text( text ? text : "" );
+  code_panel->show();
+  const char* message = 0;
+  for (;;) { // repeat as long as there are errors
+    if (message) fl_alert(message);
+    for (;;) {
+      Fl_Widget* w = Fl::readqueue();
+      if (w == code_panel_cancel) goto BREAK2;
+      else if (w == code_panel_ok) break;
+      else if (!w) Fl::wait();
+    }
+    char*c = code_input->buffer()->text();
+    message = c_check(c); if (message) continue;
+    name(c);
+    free(c);
+    break;
+  }
+ BREAK2:
+  code_panel->hide();
+}
+
+Fl_Code_Type Fl_Code_type;
+
+void Fl_Code_Type::write_code1() {
+  const char* c = name();
+  if (!c) return;
+  write_c("%s%s\n", indent(), c);
+}
+
+void Fl_Code_Type::write_code2() {}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Type *Fl_CodeBlock_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_code_block()) p = p->parent;
+  if (!p) {
+    fl_message("Please select a function");
+    return 0;
+  }
+  Fl_CodeBlock_Type *o = new Fl_CodeBlock_Type();
+  o->name("if (test())");
+  o->after = 0;
+  o->add(p);
+  o->factory = this;
+  return o;
+}
+
+void Fl_CodeBlock_Type::write_properties() {
+  Fl_Type::write_properties();
+  if (after) {
+    write_string("after");
+    write_word(after);
+  }
+}
+
+void Fl_CodeBlock_Type::read_property(const char *c) {
+  if (!strcmp(c,"after")) {
+    storestring(read_word(),after);
+  } else {
+    Fl_Type::read_property(c);
+  }
+}
+
+void Fl_CodeBlock_Type::open() {
+  if (!codeblock_panel) make_codeblock_panel();
+  code_before_input->static_value(name());
+  code_after_input->static_value(after);
+  codeblock_panel->show();
+  const char* message = 0;
+  for (;;) { // repeat as long as there are errors
+    if (message) fl_alert(message);
+    for (;;) {
+      Fl_Widget* w = Fl::readqueue();
+      if (w == codeblock_panel_cancel) goto BREAK2;
+      else if (w == codeblock_panel_ok) break;
+      else if (!w) Fl::wait();
+    }
+    const char*c = code_before_input->value();
+    message = c_check(c); if (message) continue;
+    name(c);
+    c = code_after_input->value();
+    message = c_check(c); if (message) continue;
+    storestring(c, after);
+    break;
+  }
+ BREAK2:
+  codeblock_panel->hide();
+}
+
+Fl_CodeBlock_Type Fl_CodeBlock_type;
+
+void Fl_CodeBlock_Type::write_code1() {
+  const char* c = name();
+  write_c("%s%s {\n", indent(), c ? c : "");
+  indentation += 2;
+}
+
+void Fl_CodeBlock_Type::write_code2() {
+  indentation += 2;
+  if (after) write_c("%s} %s\n", indent(), after);
+  else write_c("%s}\n", indent());
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl_Decl_Type::is_public() const 
+{
+ Fl_Type *p = parent;
+ while (p && !p->is_decl_block()) p = p->parent;
+ if(p && p->is_public() && public_)
+   return public_;
+ else if(!p)
+   return public_;
+ return 0;
+}
+
+Fl_Type *Fl_Decl_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_decl_block()) p = p->parent;
+  Fl_Decl_Type *o = new Fl_Decl_Type();
+  o->public_ = 0;
+  o->name("int x;");
+  o->add(p);
+  o->factory = this;
+  return o;
+}
+
+void Fl_Decl_Type::write_properties() {
+  Fl_Type::write_properties();
+  if (public_) write_string("public");
+}
+
+void Fl_Decl_Type::read_property(const char *c) {
+  if (!strcmp(c,"public")) {
+    public_ = 1;
+  } else {
+    Fl_Type::read_property(c);
+  }
+}
+
+void Fl_Decl_Type::open() {
+  if (!decl_panel) make_decl_panel();
+  decl_input->static_value(name());
+  decl_public_button->value(public_);
+  decl_panel->show();
+  const char* message = 0;
+  for (;;) { // repeat as long as there are errors
+    if (message) fl_alert(message);
+    for (;;) {
+      Fl_Widget* w = Fl::readqueue();
+      if (w == decl_panel_cancel) goto BREAK2;
+      else if (w == decl_panel_ok) break;
+      else if (!w) Fl::wait();
+    }
+    const char*c = decl_input->value();
+    while (isspace(*c)) c++;
+    message = c_check(c&&c[0]=='#' ? c+1 : c);
+    if (message) continue;
+    name(c);
+    if (public_!=decl_public_button->value()) {
+      set_modflag(1);
+      public_ = decl_public_button->value();
+    }
+    break;
+  }
+ BREAK2:
+  decl_panel->hide();
+}
+
+Fl_Decl_Type Fl_Decl_type;
+
+void Fl_Decl_Type::write_code1() {
+  const char* c = name();
+  if (!c) return;
+  // handle putting #include, extern, using or typedef into decl:
+  if (!isalpha(*c) && *c != '~'
+      || !strncmp(c,"extern",6) && isspace(c[6])
+      || !strncmp(c,"class",5) && isspace(c[5])
+      || !strncmp(c,"typedef",7) && isspace(c[7])
+      || !strncmp(c,"using",5) && isspace(c[5])
+      || !strncmp(c,"FL_EXPORT",9) && isspace(c[9])
+//    || !strncmp(c,"struct",6) && isspace(c[6])
+      ) {
+    if (public_)
+      write_h("%s\n", c);
+    else
+      write_c("%s\n", c);
+    return;
+  }
+  // lose all trailing semicolons so I can add one:
+  const char* e = c+strlen(c);
+  while (e>c && e[-1]==';') e--;
+  if (class_name(1)) {
+    write_public(public_);
+    write_h("  %.*s;\n", (int)(e-c), c);
+  } else {
+    if (public_) {
+      write_h("extern %.*s;\n", (int)(e-c), c);
+      write_c("%.*s;\n", (int)(e-c), c);
+    } else {
+      write_c("static %.*s;\n", (int)(e-c), c);
+    }
+  }
+}
+
+void Fl_Decl_Type::write_code2() {}
+
+////////////////////////////////////////////////////////////////
+
+int Fl_DeclBlock_Type::is_public() const {return public_;}
+
+Fl_Type *Fl_DeclBlock_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_decl_block()) p = p->parent;
+  Fl_DeclBlock_Type *o = new Fl_DeclBlock_Type();
+  o->name("#if 1");
+  o->public_ = 0;
+  o->after = strdup("#endif");
+  o->add(p);
+  o->factory = this;
+  return o;
+}
+
+void Fl_DeclBlock_Type::write_properties() {
+  Fl_Type::write_properties();
+  if (public_) write_string("public");
+  write_string("after");
+  write_word(after);
+}
+
+void Fl_DeclBlock_Type::read_property(const char *c) {
+  if(!strcmp(c,"public")) {
+    public_ = 1;
+  } else  if (!strcmp(c,"after")) {
+    storestring(read_word(),after);
+  } else {
+    Fl_Type::read_property(c);
+  }
+}
+
+void Fl_DeclBlock_Type::open() {
+  if (!declblock_panel) make_declblock_panel();
+  decl_before_input->static_value(name());
+  declblock_public_button->value(public_);
+  decl_after_input->static_value(after);
+  declblock_panel->show();
+  const char* message = 0;
+  for (;;) { // repeat as long as there are errors
+    if (message) fl_alert(message);
+    for (;;) {
+      Fl_Widget* w = Fl::readqueue();
+      if (w == declblock_panel_cancel) goto BREAK2;
+      else if (w == declblock_panel_ok) break;
+      else if (!w) Fl::wait();
+    }
+    const char*c = decl_before_input->value();
+    while (isspace(*c)) c++;
+    message = c_check(c&&c[0]=='#' ? c+1 : c);
+    if (message) continue;
+    name(c);
+    c = decl_after_input->value();
+    while (isspace(*c)) c++;
+    message = c_check(c&&c[0]=='#' ? c+1 : c);
+    if (message) continue;
+    storestring(c,after);
+    if (public_ != declblock_public_button->value()) {
+      set_modflag(1);
+      public_ = declblock_public_button->value();
+    }
+    break;
+  }
+ BREAK2:
+  declblock_panel->hide();
+}
+
+Fl_DeclBlock_Type Fl_DeclBlock_type;
+
+void Fl_DeclBlock_Type::write_code1() {
+  const char* c = name();
+  if (public_)
+     write_h("%s\n", c);
+  write_c("%s\n", c);
+}
+
+void Fl_DeclBlock_Type::write_code2() {
+  const char* c = after;
+  if (public_)
+     write_h("%s\n", c);
+  write_c("%s\n", c);
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Type *Fl_Comment_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_code_block()) p = p->parent;
+  Fl_Comment_Type *o = new Fl_Comment_Type();
+  o->in_c_ = 1;
+  o->in_h_ = 1;
+  o->style_ = 0;
+  o->name("my comment");
+  o->add(p);
+  o->factory = this;
+  o->title_buf[0] = 0;
+  return o;
+}
+
+void Fl_Comment_Type::write_properties() {
+  Fl_Type::write_properties();
+  if (in_c_) write_string("in_source"); else write_string("not_in_source"); 
+  if (in_h_) write_string("in_header"); else write_string("not_in_header");
+}
+
+void Fl_Comment_Type::read_property(const char *c) {
+  if (!strcmp(c,"in_source")) {
+    in_c_ = 1;
+  } else if (!strcmp(c,"not_in_source")) {
+    in_c_ = 0;
+  } else if (!strcmp(c,"in_header")) {
+    in_h_ = 1;
+  } else if (!strcmp(c,"not_in_header")) {
+    in_h_ = 0;
+  } else {
+    Fl_Type::read_property(c);
+  }
+}
+
+#include "comments.h"
+
+static void load_comments_preset(Fl_Preferences &menu) {
+  static const char * const predefined_comment[] = {
+    "GNU Public License/GPL Header",  "GNU Public License/GPL Footer",
+    "GNU Public License/LGPL Header", "GNU Public License/LGPL Footer",
+    "FLTK/Header", "FLTK/Footer" };
+  int i;
+  menu.set("n", 6);
+  Fl_Preferences db(Fl_Preferences::USER, "fltk.org", "fluid_comments");
+  for (i=0; i<6; i++) {
+    menu.set(Fl_Preferences::Name(i), predefined_comment[i]);
+    db.set(predefined_comment[i], comment_text[i]);
+  }
+}
+
+void Fl_Comment_Type::open() {
+  if (!comment_panel) make_comment_panel();
+  const char *text = name();
+  {
+    int i=0, n=0;
+    Fl_Preferences menu(Fl_Preferences::USER, "fltk.org", "fluid_comments_menu");
+    comment_predefined->clear();
+    comment_predefined->add("_Edit/Add current comment...");
+    comment_predefined->add("_Edit/Remove last selection...");
+    menu.get("n", n, -1);
+    if (n==-1) load_comments_preset(menu);
+    menu.get("n", n, 0);
+    for (i=0;i<n;i++) {
+      char *text;
+      menu.get(Fl_Preferences::Name(i), text, "");
+      comment_predefined->add(text);
+      free(text);
+    }
+  }
+  comment_input->buffer()->text( text ? text : "" );
+  comment_in_source->value(in_c_);
+  comment_in_header->value(in_h_);
+  comment_panel->show();
+  const char* message = 0;
+  char itempath[256]; itempath[0] = 0;
+  int last_selected_item = 0;
+  for (;;) { // repeat as long as there are errors
+    if (message) fl_alert(message);
+    for (;;) {
+      Fl_Widget* w = Fl::readqueue();
+      if (w == comment_panel_cancel) goto BREAK2;
+      else if (w == comment_panel_ok) break;
+      else if (w == comment_predefined) {
+        if (comment_predefined->value()==1) {
+          // add the current comment to the database
+          const char *xname = fl_input(
+            "Please enter a name to reference the current\ncomment in your database.\n\n"
+            "Use forward slashes '/' to create submenus.", 
+            "My Comment");
+          if (xname) {
+            char *name = strdup(xname);
+            for (char*s=name;*s;s++) if (*s==':') *s = ';';
+            int n;
+            Fl_Preferences db(Fl_Preferences::USER, "fltk.org", "fluid_comments");
+            db.set(name, comment_input->buffer()->text());
+            Fl_Preferences menu(Fl_Preferences::USER, "fltk.org", "fluid_comments_menu");
+            menu.get("n", n, 0);
+            menu.set(Fl_Preferences::Name(n), name);
+            menu.set("n", ++n);
+            comment_predefined->add(name);
+            free(name);
+          }
+        } else if (comment_predefined->value()==2) {
+          // remove the last selected comment from the database
+          if (itempath[0]==0 || last_selected_item==0) {
+            fl_message("Please select an entry form this menu first.");
+          } else if (fl_choice("Are you sure that you want to delete the entry\n"
+	                       "\"%s\"\nfrom the database?", "Cancel", "Delete",
+			       NULL, itempath)) {
+            Fl_Preferences db(Fl_Preferences::USER, "fltk.org", "fluid_comments");
+            db.deleteEntry(itempath);
+            comment_predefined->remove(last_selected_item);
+            Fl_Preferences menu(Fl_Preferences::USER, "fltk.org", "fluid_comments_menu");
+            int i, n;
+            for (i=4, n=0; i<comment_predefined->size(); i++) {
+              const Fl_Menu_Item *mi = comment_predefined->menu()+i;
+              if (comment_predefined->item_pathname(itempath, 255, mi)==0) {
+                if (itempath[0]=='/') memmove(itempath, itempath+1, 255);
+                if (itempath[0]) menu.set(Fl_Preferences::Name(n++), itempath);
+              }
+            }
+            menu.set("n", n);
+          }
+        } else {
+          // load the selected comment from the database
+          if (comment_predefined->item_pathname(itempath, 255)==0) {
+            if (itempath[0]=='/') memmove(itempath, itempath+1, 255);
+            Fl_Preferences db(Fl_Preferences::USER, "fltk.org", "fluid_comments");
+            char *text; 
+            db.get(itempath, text, "(no text found in data base)");
+            comment_input->buffer()->text(text);
+            free(text);
+            last_selected_item = comment_predefined->value();
+          }
+        }
+      }
+      else if (w == comment_load) {
+        // load a comment from disk
+	fl_file_chooser_ok_label("Use File");
+        const char *fname = fl_file_chooser("Pick a comment", 0L, 0L);
+	fl_file_chooser_ok_label(NULL);
+        if (fname) {
+          if (comment_input->buffer()->loadfile(fname)) {
+            fl_alert("Error loading file\n%s", fname);
+          }
+        }
+      }
+      else if (!w) Fl::wait();
+    }
+    char*c = comment_input->buffer()->text();
+    name(c);
+    free(c);
+    int mod = 0;
+    if (in_c_ != comment_in_source->value()) {
+      in_c_ = comment_in_source->value();
+      mod = 1;
+    }
+    if (in_h_ != comment_in_header->value()) {
+      in_h_ = comment_in_header->value();
+      mod = 1;
+    }
+    if (mod) set_modflag(1);
+    break;
+  }
+ BREAK2:
+  title_buf[0] = 0;
+  comment_panel->hide();
+}
+
+const char *Fl_Comment_Type::title() {
+  const char* n = name(); 
+  if (!n || !*n) return type_name();
+  if (title_buf[0]==0) {
+    const char *s = n;
+    char *d = title_buf;
+    int i = 50;
+    while (--i > 0) {
+      char n = *s++;
+      if (n==0) break;
+      if (n=='\r') { *d++ = '\\'; *d++ = 'r'; i--; }
+      else if (n=='\n') { *d++ = '\\'; *d++ = 'n'; i--; }
+      else if (n<32) { *d++ = '^'; *d++ = 'A'+n; i--; }
+      else *d++ = n;
+    }
+    if (i<=0) { *d++ = '.'; *d++ = '.'; *d++ = '.'; }
+    *d++ = 0;
+  }
+  return title_buf;
+}
+
+Fl_Comment_Type Fl_Comment_type;
+
+void Fl_Comment_Type::write_code1() {
+  const char* c = name();
+  if (!c) return;
+  if (!in_c_ && !in_h_) return;
+  // find out if there is already a valid comment:
+  const char *s = c;
+  while (isspace(*s)) s++;
+  // if this seems to be a C style comment, copy the block as is
+  // (it's up to the user to correctly close the comment)
+  if (s[0]=='/' && s[1]=='*') {
+    if (in_h_) write_h("%s\n", c);
+    if (in_c_) write_c("%s\n", c);
+    return;
+  }
+  // copy the comment line by line, add the double slash if needed
+  char *txt = strdup(c);
+  char *b = txt, *e = txt;
+  for (;;) {
+    // find the end of the line and set it to NUL
+    while (*e && *e!='\n') e++;
+    char eol = *e;
+    *e = 0;
+    // check if there is a C++ style comment at the beginning of the line
+    char *s = b;
+    while (isspace(*s)) s++;
+    if (s!=e && ( s[0]!='/' || s[1]!='/') ) {
+      // if no comment marker was found, we add one ourselves
+      if (in_h_) write_h("// ");
+      if (in_c_) write_c("// ");
+    }
+    // now copy the rest of the line
+    if (in_h_) write_h("%s\n", b);
+    if (in_c_) write_c("%s\n", b);
+    if (eol==0) break;
+    *e++ = eol;
+    b = e;
+  }
+}
+
+void Fl_Comment_Type::write_code2() {}
+
+////////////////////////////////////////////////////////////////
+
+const char* Fl_Type::class_name(const int need_nest) const {
+  Fl_Type* p = parent;
+  while (p) {
+    if (p->is_class()) {
+      // see if we are nested in another class, we must fully-qualify name:
+      // this is lame but works...
+      const char* q = 0;
+      if(need_nest) q=p->class_name(need_nest);
+      if (q) {
+	static char s[256];
+	if (q != s) strlcpy(s, q, sizeof(s));
+	strlcat(s, "::", sizeof(s));
+	strlcat(s, p->name(), sizeof(s));
+	return s;
+      }
+      return p->name();
+    }
+    p = p->parent;
+  }
+  return 0;
+}
+
+/**
+ * If this Type resides inside a class, this function returns the class type, or null.
+ */
+const Fl_Class_Type *Fl_Type::is_in_class() const {
+  Fl_Type* p = parent;
+  while (p) {
+    if (p->is_class()) {
+      return (Fl_Class_Type*)p;
+    }
+    p = p->parent;
+  }
+  return 0;
+}
+
+int Fl_Class_Type::is_public() const {return public_;}
+
+void Fl_Class_Type::prefix(const char*p) {
+  free((void*) class_prefix);
+  class_prefix=strdup(p ? p : "" );
+}
+
+Fl_Type *Fl_Class_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_decl_block()) p = p->parent;
+  Fl_Class_Type *o = new Fl_Class_Type();
+  o->name("UserInterface");
+  o->class_prefix=0;
+  o->subclass_of = 0;
+  o->public_ = 1;
+  o->add(p);
+  o->factory = this;
+  return o;
+}
+
+void Fl_Class_Type::write_properties() {
+  Fl_Type::write_properties();
+  if (subclass_of) {
+    write_string(":");
+    write_word(subclass_of);
+  }
+  if (!public_) write_string("private");
+}
+
+void Fl_Class_Type::read_property(const char *c) {
+  if (!strcmp(c,"private")) {
+    public_ = 0;
+  } else if (!strcmp(c,":")) {
+    storestring(read_word(), subclass_of);
+  } else {
+    Fl_Type::read_property(c);
+  }
+}
+
+void Fl_Class_Type::open() {
+  if (!class_panel) make_class_panel();
+  char fullname[1024]="";
+  if (prefix() && strlen(prefix())) 
+    sprintf(fullname,"%s %s",prefix(),name());
+  else 
+    strcpy(fullname, name());
+  c_name_input->static_value(fullname);
+  c_subclass_input->static_value(subclass_of);
+  c_public_button->value(public_);
+  class_panel->show();
+  const char* message = 0;
+
+  char *na=0,*pr=0,*p=0; // name and prefix substrings
+
+  for (;;) { // repeat as long as there are errors
+    if (message) fl_alert(message);
+    for (;;) {
+      Fl_Widget* w = Fl::readqueue();
+      if (w == c_panel_cancel) goto BREAK2;
+      else if (w == c_panel_ok) break;
+      else if (!w) Fl::wait();
+    }
+    const char*c = c_name_input->value();
+    char *s = strdup(c);
+    size_t len = strlen(s);
+    if (!*s) goto OOPS;
+    p = (char*) (s+len-1);
+    while (p>=s && isspace(*p)) *(p--)='\0';
+    if (p<s) goto OOPS;
+    while (p>=s && is_id(*p)) p--;
+    if ( (p<s && !is_id(*(p+1))) || !*(p+1) ) {
+      OOPS: message = "class name must be C++ identifier";
+      free((void*)s);
+      continue;
+    }
+    na=p+1; // now we have the name
+    if(p>s) *p--='\0';
+    while (p>=s && isspace(*p)) *(p--)='\0';
+    while (p>=s && is_id(*p))   p--;
+    if (p<s)                    p++;
+    if (is_id(*p) && p<na)      pr=p; // prefix detected
+    c = c_subclass_input->value();
+    message = c_check(c); 
+    if (message) { free((void*)s);continue;}
+    name(na);
+    prefix(pr);
+    free((void*)s);
+    storestring(c, subclass_of);
+    if (public_ != c_public_button->value()) {
+      public_ = c_public_button->value();
+      set_modflag(1);
+    }
+    break;
+  }
+ BREAK2:
+  class_panel->hide();
+}
+
+Fl_Class_Type Fl_Class_type;
+
+static Fl_Class_Type *current_class;
+extern Fl_Widget_Class_Type *current_widget_class;
+extern int varused_test;
+void write_public(int state) {
+  if ((!current_class && !current_widget_class) || varused_test) return;
+  if (current_class && current_class->write_public_state == state) return;
+  if (current_widget_class && current_widget_class->write_public_state == state) return;
+  if (current_class) current_class->write_public_state = state;
+  if (current_widget_class) current_widget_class->write_public_state = state;
+  write_h(state ? "public:\n" : "private:\n");
+}
+
+void Fl_Class_Type::write_code1() {
+  parent_class = current_class;
+  current_class = this;
+  write_public_state = 0;
+  if (prefix() && strlen(prefix()))
+      write_h("\nclass %s %s ", prefix(), name());
+  else
+      write_h("\nclass %s ", name());
+  if (subclass_of) write_h(": %s ", subclass_of);
+  write_h("{\n");
+}
+
+void Fl_Class_Type::write_code2() {
+  write_h("};\n");
+  current_class = parent_class;
+}
+
+/**
+ * Return 1 if this class contains a function with the given signature.
+ */
+int Fl_Class_Type::has_function(const char *rtype, const char *sig) const {
+  Fl_Type *child;
+  for (child = next; child && child->level > level; child = child->next) {
+    if (child->level == level+1 && strcmp(child->type_name(), "Function")==0) {
+      const Fl_Function_Type *fn = (const Fl_Function_Type*)child;
+      if (fn->has_signature(rtype, sig))
+        return 1;
+    }
+  }
+  return 0;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Group_Type.cxx b/Utilities/FLTK/fluid/Fl_Group_Type.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f80652bfb26135d7697a6b71f8ee8af6e69eaa79
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Group_Type.cxx
@@ -0,0 +1,307 @@
+//
+// "$Id$"
+//
+// Fl_Group object code for the Fast Light Tool Kit (FLTK).
+//
+// Object describing an Fl_Group and links to Fl_Window_Type.C and
+// the Fl_Tabs widget, with special stuff to select tab items and
+// insure that only one is visible.
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/fl_message.H>
+#include "Fl_Widget_Type.h"
+#include "../src/flstring.h"
+
+// Override group's resize behavior to do nothing to children:
+void igroup::resize(int X, int Y, int W, int H) {
+  Fl_Widget::resize(X,Y,W,H);
+  redraw();
+}
+
+Fl_Group_Type Fl_Group_type;	// the "factory"
+
+Fl_Type *Fl_Group_Type::make() {
+  return Fl_Widget_Type::make();
+}
+
+void fix_group_size(Fl_Type *tt) {
+  if (!tt || !tt->is_group()) return;
+  Fl_Group_Type* t = (Fl_Group_Type*)tt;
+  int X = t->o->x();
+  int Y = t->o->y();
+  int R = X+t->o->w();
+  int B = Y+t->o->h();
+  for (Fl_Type *nn = t->next; nn && nn->level > t->level; nn = nn->next) {
+    if (!nn->is_widget() || nn->is_menu_item()) continue;
+    Fl_Widget_Type* n = (Fl_Widget_Type*)nn;
+    int x = n->o->x();	if (x < X) X = x;
+    int y = n->o->y();	if (y < Y) Y = y;
+    int r = x+n->o->w();if (r > R) R = r;
+    int b = y+n->o->h();if (b > B) B = b;
+  }
+  t->o->resize(X,Y,R-X,B-Y);
+}
+
+extern int force_parent;
+
+void group_cb(Fl_Widget *, void *) {
+  // Find the current widget:
+  Fl_Type *qq = Fl_Type::current;
+  while (qq && (!qq->is_widget() || qq->is_menu_item())) qq = qq->parent;
+  if (!qq || qq->level < 1 || (qq->level == 1 && !strcmp(qq->type_name(), "widget_class"))) {
+    fl_message("Please select widgets to group");
+    return;
+  }
+  Fl_Widget_Type* q = (Fl_Widget_Type*)qq;
+  force_parent = 1;
+  Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make());
+  n->move_before(q);
+  n->o->resize(q->o->x(),q->o->y(),q->o->w(),q->o->h());
+  for (Fl_Type *t = Fl_Type::first; t;) {
+    if (t->level != n->level || t == n || !t->selected) {
+      t = t->next; continue;}
+    Fl_Type *nxt = t->remove();
+    t->add(n);
+    t = nxt;
+  }
+  fix_group_size(n);
+}
+
+void ungroup_cb(Fl_Widget *, void *) {
+  // Find the group:
+  Fl_Type *q = Fl_Type::current;
+  while (q && (!q->is_widget() || q->is_menu_item())) q = q->parent;
+  if (q) q = q->parent;
+  if (!q || q->level < 1 || (q->level == 1 && !strcmp(q->type_name(), "widget_class"))) {
+    fl_message("Please select widgets in a group");
+    return;
+  }
+  Fl_Type* n;
+  for (n = q->next; n && n->level > q->level; n = n->next) {
+    if (n->level == q->level+1 && !n->selected) {
+      fl_message("Please select all widgets in group");
+      return;
+    }
+  }
+  for (n = q->next; n && n->level > q->level;) {
+    Fl_Type *nxt = n->remove();
+    n->insert(q);
+    n = nxt;
+  }
+  delete q;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+
+void Fl_Group_Type::write_code1() {
+  Fl_Widget_Type::write_code1();
+}
+
+void Fl_Group_Type::write_code2() {
+  write_extra_code();
+  write_c("%so->end();\n", indent());
+  if (resizable()) write_c("%sFl_Group::current()->resizable(o);\n", indent());
+  write_block_close();
+}
+
+////////////////////////////////////////////////////////////////
+
+const char pack_type_name[] = "Fl_Pack";
+
+Fl_Menu_Item pack_type_menu[] = {
+  {"HORIZONTAL", 0, 0, (void*)Fl_Pack::HORIZONTAL},
+  {"VERTICAL", 0, 0, (void*)Fl_Pack::VERTICAL},
+  {0}};
+
+Fl_Pack_Type Fl_Pack_type;	// the "factory"
+
+////////////////////////////////////////////////////////////////
+
+const char tabs_type_name[] = "Fl_Tabs";
+
+// Override group's resize behavior to do nothing to children:
+void itabs::resize(int X, int Y, int W, int H) {
+  Fl_Widget::resize(X,Y,W,H);
+  redraw();
+}
+
+Fl_Tabs_Type Fl_Tabs_type;	// the "factory"
+
+// This is called when user clicks on a widget in the window.  See
+// if it is a tab title, and adjust visibility and return new selection:
+// If none, return o unchanged:
+
+Fl_Type* Fl_Tabs_Type::click_test(int x, int y) {
+  Fl_Tabs *t = (Fl_Tabs*)o;
+  Fl_Widget *a = t->which(x,y);
+  if (!a) return 0; // didn't click on tab
+  // okay, run the tabs ui until they let go of mouse:
+  t->handle(FL_PUSH);
+  Fl::pushed(t);
+  while (Fl::pushed()==t) Fl::wait();
+  return (Fl_Type*)(t->value()->user_data());
+}
+
+////////////////////////////////////////////////////////////////
+
+const char wizard_type_name[] = "Fl_Wizard";
+
+// Override group's resize behavior to do nothing to children:
+void iwizard::resize(int X, int Y, int W, int H) {
+  Fl_Widget::resize(X,Y,W,H);
+  redraw();
+}
+
+Fl_Wizard_Type Fl_Wizard_type;	// the "factory"
+
+// This is called when o is created.  If it is in the tab group make
+// sure it is visible:
+
+void Fl_Group_Type::add_child(Fl_Type* cc, Fl_Type* before) {
+  Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+  Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+  ((Fl_Group*)o)->insert(*(c->o), b);
+  o->redraw();
+}
+
+void Fl_Tabs_Type::add_child(Fl_Type* c, Fl_Type* before) {
+  Fl_Group_Type::add_child(c, before);
+}
+
+// This is called when o is deleted.  If it is in the tab group make
+// sure it is not visible:
+
+void Fl_Group_Type::remove_child(Fl_Type* cc) {
+  Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+  ((Fl_Group*)o)->remove(c->o);
+  o->redraw();
+}
+
+void Fl_Tabs_Type::remove_child(Fl_Type* cc) {
+  Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+  Fl_Tabs *t = (Fl_Tabs*)o;
+  if (t->value() == c->o) t->value(0);
+  Fl_Group_Type::remove_child(c);
+}
+
+// move, don't change selected value:
+
+void Fl_Group_Type::move_child(Fl_Type* cc, Fl_Type* before) {
+  Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+  Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+  ((Fl_Group*)o)->remove(c->o);
+  ((Fl_Group*)o)->insert(*(c->o), b);
+  o->redraw();
+}
+
+////////////////////////////////////////////////////////////////
+// live mode support
+
+Fl_Widget *Fl_Group_Type::enter_live_mode(int top) {
+  Fl_Group *grp = new Fl_Group(o->x(), o->y(), o->w(), o->h());
+  live_widget = grp;
+  if (live_widget) {
+    copy_properties();
+    Fl_Type *n;
+    for (n = next; n && n->level > level; n = n->next) {
+      if (n->level == level+1)
+        n->enter_live_mode();
+    }
+    grp->end();
+  }
+  return live_widget;
+}
+
+Fl_Widget *Fl_Tabs_Type::enter_live_mode(int top) {
+  Fl_Tabs *grp = new Fl_Tabs(o->x(), o->y(), o->w(), o->h());
+  live_widget = grp;
+  if (live_widget) {
+    copy_properties();
+    Fl_Type *n;
+    for (n = next; n && n->level > level; n = n->next) {
+      if (n->level == level+1)
+        n->enter_live_mode();
+    }
+    grp->end();
+  }
+  grp->value(((Fl_Tabs*)o)->value());
+  return live_widget;
+}
+
+void Fl_Group_Type::leave_live_mode() {
+}
+
+/**
+ * copy all properties from the edit widget to the live widget
+ */
+void Fl_Group_Type::copy_properties() {
+  Fl_Widget_Type::copy_properties();
+}
+
+////////////////////////////////////////////////////////////////
+// some other group subclasses that fluid does not treat specially:
+
+#include <FL/Fl_Scroll.H>
+
+const char scroll_type_name[] = "Fl_Scroll";
+
+Fl_Menu_Item scroll_type_menu[] = {
+  {"BOTH", 0, 0, 0/*(void*)Fl_Scroll::BOTH*/},
+  {"HORIZONTAL", 0, 0, (void*)Fl_Scroll::HORIZONTAL},
+  {"VERTICAL", 0, 0, (void*)Fl_Scroll::VERTICAL},
+  {"HORIZONTAL_ALWAYS", 0, 0, (void*)Fl_Scroll::HORIZONTAL_ALWAYS},
+  {"VERTICAL_ALWAYS", 0, 0, (void*)Fl_Scroll::VERTICAL_ALWAYS},
+  {"BOTH_ALWAYS", 0, 0, (void*)Fl_Scroll::BOTH_ALWAYS},
+  {0}};
+
+Fl_Scroll_Type Fl_Scroll_type;	// the "factory"
+
+void Fl_Scroll_Type::copy_properties() {
+  Fl_Group_Type::copy_properties();
+  Fl_Scroll *s = (Fl_Scroll*)o, *d = (Fl_Scroll*)live_widget;
+  d->position(s->xposition(), s->yposition());
+  d->type(s->type()); // TODO: get this flag from Fl_Scroll_Type!
+  d->scrollbar.align(s->scrollbar.align());
+  d->hscrollbar.align(s->hscrollbar.align());
+}
+
+////////////////////////////////////////////////////////////////
+
+const char tile_type_name[] = "Fl_Tile";
+
+Fl_Tile_Type Fl_Tile_type;	// the "factory"
+
+void Fl_Tile_Type::copy_properties() {
+  Fl_Group_Type::copy_properties();
+  // no additional properties
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Menu_Type.cxx b/Utilities/FLTK/fluid/Fl_Menu_Type.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5d329507232b87688cbbdf88a29b15133c1bfc43
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Menu_Type.cxx
@@ -0,0 +1,578 @@
+//
+// "$Id$"
+//
+// Menu item code for the Fast Light Tool Kit (FLTK).
+//
+// Menu items are kludged by making a phony Fl_Box widget so the normal
+// widget panel can be used to control them.
+//
+// This file also contains code to make Fl_Menu_Button, Fl_Menu_Bar,
+// etc widgets.
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include "Fl_Widget_Type.h"
+#include "alignment_panel.h"
+#include <FL/fl_message.H>
+#include <FL/Fl_Menu_.H>
+#include <FL/Fl_Button.H>
+#include "../src/flstring.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+Fl_Menu_Item menu_item_type_menu[] = {
+  {"Normal",0,0,(void*)0},
+  {"Toggle",0,0,(void*)FL_MENU_BOX},
+  {"Radio",0,0,(void*)FL_MENU_RADIO},
+  {0}};
+
+extern int reading_file;
+extern int force_parent;
+extern int i18n_type;
+extern const char* i18n_include;
+extern const char* i18n_function;
+extern const char* i18n_file;
+extern const char* i18n_set;
+
+static char submenuflag;
+
+void Fl_Input_Choice_Type::build_menu() {
+  Fl_Input_Choice* w = (Fl_Input_Choice*)o;
+  // count how many Fl_Menu_Item structures needed:
+  int n = 0;
+  Fl_Type* q;
+  for (q = next; q && q->level > level; q = q->next) {
+    if (q->is_parent()) n++; // space for null at end of submenu
+    n++;
+  }
+  if (!n) {
+    if (menusize) delete[] (Fl_Menu_Item*)(w->menu());
+    w->menu(0);
+    menusize = 0;
+  } else {
+    n++; // space for null at end of menu
+    if (menusize<n) {
+      if (menusize) delete[] (Fl_Menu_Item*)(w->menu());
+      menusize = n+10;
+      w->menu(new Fl_Menu_Item[menusize]);
+    }
+    // fill them all in:
+    Fl_Menu_Item* m = (Fl_Menu_Item*)(w->menu());
+    int lvl = level+1;
+    for (q = next; q && q->level > level; q = q->next) {
+      Fl_Menu_Item_Type* i = (Fl_Menu_Item_Type*)q;
+      if (i->o->image()) i->o->image()->label(m);
+      else {
+        m->label(i->o->label() ? i->o->label() : "(nolabel)");
+        m->labeltype(i->o->labeltype());
+      }
+      m->shortcut(((Fl_Button*)(i->o))->shortcut());
+      m->callback(0,(void*)i);
+      m->flags = i->flags();
+      m->labelfont(i->o->labelfont());
+      m->labelsize(i->o->labelsize());
+      m->labelcolor(i->o->labelcolor());
+      if (q->is_parent()) {lvl++; m->flags |= FL_SUBMENU;}
+      m++;
+      int l1 =
+	(q->next && q->next->is_menu_item()) ? q->next->level : level;
+      while (lvl > l1) {m->label(0); m++; lvl--;}
+      lvl = l1;
+    }
+  }
+  o->redraw();
+}
+
+
+Fl_Type *Fl_Menu_Item_Type::make() {
+  // Find the current menu item:
+  Fl_Type* q = Fl_Type::current;
+  Fl_Type* p = q;
+  if (p) {
+    if (force_parent && q->is_menu_item() || !q->is_parent()) p = p->parent;
+  }
+  force_parent = 0;
+  if (!p || !(p->is_menu_button() || p->is_menu_item() && p->is_parent())) {
+    fl_message("Please select a menu to add to");
+    return 0;
+  }
+  if (!o) {
+    o = new Fl_Button(0,0,100,20); // create template widget
+    o->labelsize(Fl_Widget_Type::default_size);
+  }
+
+  Fl_Menu_Item_Type* t = submenuflag ? new Fl_Submenu_Type() : new Fl_Menu_Item_Type();
+  t->o = new Fl_Button(0,0,100,20);
+  t->factory = this;
+  t->add(p);
+  if (!reading_file) t->label(submenuflag ? "submenu" : "item");
+  return t;
+}
+
+Fl_Type *Fl_Submenu_Type::make() {
+  submenuflag = 1;
+  Fl_Type* t = Fl_Menu_Item_Type::make();
+  submenuflag = 0;
+  return t;
+}
+
+Fl_Menu_Item_Type Fl_Menu_Item_type;
+Fl_Submenu_Type Fl_Submenu_type;
+
+////////////////////////////////////////////////////////////////
+// Writing the C code:
+
+// test functions in Fl_Widget_Type.C:
+int is_name(const char *c);
+const char *array_name(Fl_Widget_Type *o);
+int isdeclare(const char *c);
+
+// Search backwards to find the parent menu button and return it's name.
+// Also put in i the index into the button's menu item array belonging
+// to this menu item.
+const char* Fl_Menu_Item_Type::menu_name(int& i) {
+  i = 0;
+  Fl_Type* t = prev;
+  while (t && t->is_menu_item()) {
+    // be sure to count the {0} that ends a submenu:
+    if (t->level > t->next->level) i += (t->level - t->next->level);
+    // detect empty submenu:
+    else if (t->level == t->next->level && t->is_parent()) i++;
+    t = t->prev;
+    i++;
+  }
+  return unique_id(t, "menu", t->name(), t->label());
+}
+
+#include "Fluid_Image.h"
+
+void Fl_Menu_Item_Type::write_static() {
+  if (callback() && is_name(callback()))
+    write_declare("extern void %s(Fl_Menu_*, %s);", callback(),
+                  user_data_type() ? user_data_type() : "void*");
+  for (int n=0; n < NUM_EXTRA_CODE; n++) {
+    if (extra_code(n) && isdeclare(extra_code(n)))
+      write_declare("%s", extra_code(n));
+  }
+  if (callback() && !is_name(callback())) {
+    // see if 'o' or 'v' used, to prevent unused argument warnings:
+    int use_o = 0;
+    int use_v = 0;
+    const char *d;
+    for (d = callback(); *d;) {
+      if (*d == 'o' && !is_id(d[1])) use_o = 1;
+      if (*d == 'v' && !is_id(d[1])) use_v = 1;
+      do d++; while (is_id(*d));
+      while (*d && !is_id(*d)) d++;
+    }
+    const char* cn = callback_name();
+    const char* k = class_name(1);
+    if (k) {
+      write_c("\nvoid %s::%s_i(Fl_Menu_*", k, cn);
+    } else {
+      write_c("\nstatic void %s(Fl_Menu_*", cn);
+    }
+    if (use_o) write_c(" o");
+    const char* ut = user_data_type() ? user_data_type() : "void*";
+    write_c(", %s", ut);
+    if (use_v) write_c(" v");
+    write_c(") {\n  %s", callback());
+    if (*(d-1) != ';') {
+      const char *p = strrchr(callback(), '\n');
+      if (p) p ++;
+      else p = callback();
+      // Only add trailing semicolon if the last line is not a preprocessor
+      // statement...
+      if (*p != '#' && *p) write_c(";");
+    }
+    write_c("\n}\n");
+    if (k) {
+      write_c("void %s::%s(Fl_Menu_* o, %s v) {\n", k, cn, ut);
+      write_c("  ((%s*)(o->", k);
+      Fl_Type* t = parent; while (t->is_menu_item()) t = t->parent;
+      for (t = t->parent; t && t->is_widget() && !is_class(); t = t->parent) write_c("parent()->");
+      write_c("user_data()))->%s_i(o,v);\n}\n", cn);
+    }
+  }
+  if (image) {
+    if (image->written != write_number) {
+      image->write_static();
+      image->written = write_number;
+    }
+  }
+  if (next && next->is_menu_item()) return;
+  // okay, when we hit last item in the menu we have to write the
+  // entire array out:
+  const char* k = class_name(1);
+  if (k) {
+    int i; write_c("\nFl_Menu_Item %s::%s[] = {\n", k, menu_name(i));
+  } else {
+    int i; write_c("\nFl_Menu_Item %s[] = {\n", menu_name(i));
+  }
+  Fl_Type* t = prev; while (t && t->is_menu_item()) t = t->prev;
+  for (Fl_Type* q = t->next; q && q->is_menu_item(); q = q->next) {
+    ((Fl_Menu_Item_Type*)q)->write_item();
+    int thislevel = q->level; if (q->is_parent()) thislevel++;
+    int nextlevel =
+      (q->next && q->next->is_menu_item()) ? q->next->level : t->level+1;
+    while (thislevel > nextlevel) {write_c(" {0,0,0,0,0,0,0,0,0},\n"); thislevel--;}
+  }
+  write_c(" {0,0,0,0,0,0,0,0,0}\n};\n");
+
+  if (k) {
+    // Write menu item variables...
+    t = prev; while (t && t->is_menu_item()) t = t->prev;
+    for (Fl_Type* q = t->next; q && q->is_menu_item(); q = q->next) {
+      const char *c = array_name((Fl_Menu_Item_Type *)q);
+      if (c) {
+      int i; const char* n = ((Fl_Menu_Item_Type *)q)->menu_name(i);
+      write_c("Fl_Menu_Item* %s::%s = %s::%s + %d;\n", k, c, k, n, i);
+      }
+    }
+  }
+}
+
+int Fl_Menu_Item_Type::flags() {
+  int i = o->type();
+  if (((Fl_Button*)o)->value()) i |= FL_MENU_VALUE;
+  if (!o->active()) i |= FL_MENU_INACTIVE;
+  if (!o->visible()) i |= FL_MENU_INVISIBLE;
+  if (is_parent()) {
+    if (user_data() == NULL) i |= FL_SUBMENU;
+    else i |= FL_SUBMENU_POINTER;
+  }
+  if (hotspot()) i |= FL_MENU_DIVIDER;
+  return i;
+}
+
+void Fl_Menu_Item_Type::write_item() {
+  static const char * const labeltypes[] = {
+    "FL_NORMAL_LABEL",
+    "FL_NO_LABEL",
+    "FL_SHADOW_LABEL",
+    "FL_ENGRAVED_LABEL",
+    "FL_EMBOSSED_LABEL",
+    "FL_MULTI_LABEL",
+    "FL_ICON_LABEL",
+    "FL_IMAGE_LABEL"
+  };
+
+  write_c(" {");
+  if (image) write_c("0");
+  else if (label()) {
+    switch (i18n_type) {
+    case 0 : /* None */
+        write_cstring(label());
+        break;
+    case 1 : /* GNU gettext */
+        write_c("%s(", i18n_function);
+        write_cstring(label());
+	write_c(")");
+        break;
+    case 2 : /* POSIX catgets */
+        write_c("catgets(%s,%s,%d,", i18n_file[0] ? i18n_file : "_catalog",
+	        i18n_set, msgnum());
+        write_cstring(label());
+	write_c(")");
+        break;
+    }
+  }
+  else write_c("\"\"");
+  if (((Fl_Button*)o)->shortcut())
+    write_c(", 0x%x, ", ((Fl_Button*)o)->shortcut());
+  else
+    write_c(", 0, ");
+  if (callback()) {
+    const char* k = is_name(callback()) ? 0 : class_name(1);
+    if (k) {
+      write_c(" (Fl_Callback*)%s::%s,", k, callback_name());
+    } else {
+      write_c(" (Fl_Callback*)%s,", callback_name());
+    }
+  } else
+    write_c(" 0,");
+  if (user_data())
+    write_c(" (void*)(%s),", user_data());
+  else
+    write_c(" 0,");
+  write_c(" %d, %s, %d, %d, %d", flags(),
+	  labeltypes[o->labeltype()], o->labelfont(), o->labelsize(), o->labelcolor());
+  write_c("},\n");
+}
+
+void Fl_Menu_Item_Type::write_code1() {
+  int i; const char* mname = menu_name(i);
+  if (!prev->is_menu_item()) {
+    // for first menu item, declare the array
+    if (class_name(1))
+      write_h("  static Fl_Menu_Item %s[];\n", mname);
+    else
+      write_h("extern Fl_Menu_Item %s[];\n", mname);
+  }
+
+  const char *c = array_name(this);
+  if (c) {
+    if (class_name(1)) {
+      write_public(public_);
+      write_h("  static Fl_Menu_Item *%s;\n", c);
+    } else
+      write_h("#define %s (%s+%d)\n", c, mname, i);
+  }
+
+  if (callback()) {
+    if (!is_name(callback()) && class_name(1)) {
+      const char* cn = callback_name();
+      const char* ut = user_data_type() ? user_data_type() : "void*";
+      write_public(0);
+      write_h("  void %s_i(Fl_Menu_*, %s);\n", cn, ut);
+      write_h("  static void %s(Fl_Menu_*, %s);\n", cn, ut);
+    }
+  }
+
+  int init = 0;
+  if (image) {
+    write_c(" {Fl_Menu_Item* o = &%s[%d];\n", mname, i);
+    init = 1;
+    image->write_code();
+  }
+  for (int n=0; n < NUM_EXTRA_CODE; n++)
+    if (extra_code(n) && !isdeclare(extra_code(n))) {
+      if (!init) {
+	init = 1;
+	write_c("%s{ Fl_Menu_Item* o = &%s[%d];\n", indent(), mname, i);
+      }
+      write_c("%s  %s\n", indent(), extra_code(n));
+    }
+  if (init) write_c("%s}\n",indent());
+}
+
+void Fl_Menu_Item_Type::write_code2() {}
+
+////////////////////////////////////////////////////////////////
+// This is the base class for widgets that contain a menu (ie
+// subclasses of Fl_Menu_.
+// This is a parent widget and menu items can be added as
+// children.  An actual array of Fl_Menu_Items is kept parallel
+// with the child objects and updated as they change.
+
+void Fl_Menu_Type::build_menu() {
+  Fl_Menu_* w = (Fl_Menu_*)o;
+  // count how many Fl_Menu_Item structures needed:
+  int n = 0;
+  Fl_Type* q;
+  for (q = next; q && q->level > level; q = q->next) {
+    if (q->is_parent()) n++; // space for null at end of submenu
+    n++;
+  }
+  if (!n) {
+    if (menusize) delete[] (Fl_Menu_Item*)(w->menu());
+    w->menu(0);
+    menusize = 0;
+  } else {
+    n++; // space for null at end of menu
+    if (menusize<n) {
+      if (menusize) delete[] (Fl_Menu_Item*)(w->menu());
+      menusize = n+10;
+      w->menu(new Fl_Menu_Item[menusize]);
+    }
+    // fill them all in:
+    Fl_Menu_Item* m = (Fl_Menu_Item*)(w->menu());
+    int lvl = level+1;
+    for (q = next; q && q->level > level; q = q->next) {
+      Fl_Menu_Item_Type* i = (Fl_Menu_Item_Type*)q;
+      if (i->o->image()) i->o->image()->label(m);
+      else {
+        m->label(i->o->label() ? i->o->label() : "(nolabel)");
+        m->labeltype(i->o->labeltype());
+      }
+      m->shortcut(((Fl_Button*)(i->o))->shortcut());
+      m->callback(0,(void*)i);
+      m->flags = i->flags();
+      m->labelfont(i->o->labelfont());
+      m->labelsize(i->o->labelsize());
+      m->labelcolor(i->o->labelcolor());
+      if (q->is_parent()) {lvl++; m->flags |= FL_SUBMENU;}
+      m++;
+      int l1 =
+	(q->next && q->next->is_menu_item()) ? q->next->level : level;
+      while (lvl > l1) {m->label(0); m++; lvl--;}
+      lvl = l1;
+    }
+  }
+  o->redraw();
+}
+
+Fl_Type* Fl_Menu_Type::click_test(int, int) {
+  if (selected) return 0; // let user move the widget
+  Fl_Menu_* w = (Fl_Menu_*)o;
+  if (!menusize) return 0;
+  const Fl_Menu_Item* save = w->mvalue();
+  w->value((Fl_Menu_Item*)0);
+  Fl::pushed(w);
+  w->handle(FL_PUSH);
+  const Fl_Menu_Item* m = w->mvalue();
+  if (m) {
+    // restore the settings of toggles & radio items:
+    if (m->flags & (FL_MENU_RADIO | FL_MENU_TOGGLE)) build_menu();
+    return (Fl_Type*)(m->user_data());
+  }
+  w->value(save);
+  return this;
+}
+
+void Fl_Menu_Type::write_code2() {
+  if (next && next->is_menu_item())
+    write_c("%so->menu(%s);\n", indent(),
+	    unique_id(this, "menu", name(), label()));
+  Fl_Widget_Type::write_code2();
+}
+
+void Fl_Menu_Type::copy_properties() {
+  Fl_Widget_Type::copy_properties();
+  Fl_Menu_ *s = (Fl_Menu_*)o, *d = (Fl_Menu_*)live_widget;
+  d->menu(s->menu());
+  d->down_box(s->down_box());
+  d->textcolor(s->textcolor());
+  d->textfont(s->textfont());
+  d->textsize(s->textsize());
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Menu_Button.H>
+Fl_Menu_Item button_type_menu[] = {
+  {"normal",0,0,(void*)0},
+  {"popup1",0,0,(void*)Fl_Menu_Button::POPUP1},
+  {"popup2",0,0,(void*)Fl_Menu_Button::POPUP2},
+  {"popup3",0,0,(void*)Fl_Menu_Button::POPUP3},
+  {"popup12",0,0,(void*)Fl_Menu_Button::POPUP12},
+  {"popup23",0,0,(void*)Fl_Menu_Button::POPUP23},
+  {"popup13",0,0,(void*)Fl_Menu_Button::POPUP13},
+  {"popup123",0,0,(void*)Fl_Menu_Button::POPUP123},
+  {0}};
+
+Fl_Menu_Button_Type Fl_Menu_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item dummymenu[] = {{"CHOICE"},{0}};
+
+Fl_Choice_Type Fl_Choice_type;
+
+Fl_Input_Choice_Type Fl_Input_Choice_type;
+
+void Fl_Input_Choice_Type::copy_properties() {
+  Fl_Widget_Type::copy_properties();
+  Fl_Input_Choice *s = (Fl_Input_Choice*)o, *d = (Fl_Input_Choice*)live_widget;
+  d->menu(s->menu());
+  d->down_box(s->down_box());
+  d->textcolor(s->textcolor());
+  d->textfont(s->textfont());
+  d->textsize(s->textsize());
+}
+
+Fl_Type* Fl_Input_Choice_Type::click_test(int, int) {
+  if (selected) return 0; // let user move the widget
+  Fl_Menu_* w = ((Fl_Input_Choice*)o)->menubutton();
+  if (!menusize) return 0;
+  const Fl_Menu_Item* save = w->mvalue();
+  w->value((Fl_Menu_Item*)0);
+  Fl::pushed(w);
+  w->handle(FL_PUSH);
+  const Fl_Menu_Item* m = w->mvalue();
+  if (m) {
+    // restore the settings of toggles & radio items:
+    if (m->flags & (FL_MENU_RADIO | FL_MENU_TOGGLE)) build_menu();
+    return (Fl_Type*)(m->user_data());
+  }
+  w->value(save);
+  return this;
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Bar_Type Fl_Menu_Bar_type;
+
+////////////////////////////////////////////////////////////////
+// Shortcut entry item in panel:
+
+#include <FL/Fl_Output.H>
+#include "Shortcut_Button.h"
+#include <FL/fl_draw.H>
+
+void Shortcut_Button::draw() {
+  if (value()) draw_box(FL_DOWN_BOX, (Fl_Color)9);
+  else draw_box(FL_UP_BOX, FL_WHITE);
+  fl_font(FL_HELVETICA,14); fl_color(FL_FOREGROUND_COLOR);
+  fl_draw(fl_shortcut_label(svalue),x()+6,y(),w(),h(),FL_ALIGN_LEFT);
+}
+
+int Shortcut_Button::handle(int e) {
+  when(0); type(FL_TOGGLE_BUTTON);
+  if (e == FL_KEYBOARD) {
+    if (!value()) return 0;
+    int v = Fl::event_text()[0];
+    if (v > 32 && v < 0x7f || v > 0xa0 && v <= 0xff) {
+      if (isupper(v)) {
+        v = tolower(v);
+        v |= FL_SHIFT;
+      }
+      v = v | Fl::event_state()&(FL_META|FL_ALT|FL_CTRL);
+    } else {
+      v = Fl::event_state()&(FL_META|FL_ALT|FL_CTRL|FL_SHIFT) | Fl::event_key();
+      if (v == FL_BackSpace && svalue) v = 0;
+    }
+    if (v != svalue) {svalue = v; set_changed(); redraw(); do_callback(); }
+    return 1;
+  } else if (e == FL_UNFOCUS) {
+    int c = changed(); value(0); if (c) set_changed();
+    return 1;
+  } else if (e == FL_FOCUS) {
+    return value();
+  } else {
+    int r = Fl_Button::handle(e);
+    if (e == FL_RELEASE && value() && Fl::focus() != this) take_focus();
+    return r;
+  }
+}
+  
+void shortcut_in_cb(Shortcut_Button* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_button()) {i->hide(); return;}
+    i->show();
+    i->svalue = ((Fl_Button*)(current_widget->o))->shortcut();
+    i->redraw();
+  } else {
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_button()) {
+	Fl_Button* b = (Fl_Button*)(((Fl_Widget_Type*)o)->o);
+	b->shortcut(i->svalue);
+	if (o->is_menu_item()) ((Fl_Widget_Type*)o)->redraw();
+      }
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Type.cxx b/Utilities/FLTK/fluid/Fl_Type.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..92e1c807cc45643551ac6dac06f674cc0d75e032
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Type.cxx
@@ -0,0 +1,866 @@
+//
+// "$Id$"
+//
+// Widget type code for the Fast Light Tool Kit (FLTK).
+//
+// Each object described by Fluid is one of these objects.  They
+// are all stored in a double-linked list.
+//
+// They "type" of the object is covered by the virtual functions.
+// There will probably be a lot of these virtual functions.
+//
+// The type browser is also a list of these objects, but they
+// are "factory" instances, not "real" ones.  These objects exist
+// only so the "make" method can be called on them.  They are
+// not in the linked list and are not written to files or
+// copied or otherwise examined.
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Browser_.H>
+#include <FL/fl_draw.H>
+#include <stdlib.h>
+#include "../src/flstring.h"
+#include <stdio.h>
+
+#include "Fl_Type.h"
+#include "undo.h"
+
+#include <FL/Fl_Pixmap.H>
+#include "pixmaps/lock.xpm"
+//#include "pixmaps/unlock.xpm"
+
+static Fl_Pixmap	lock_pixmap(lock_xpm);
+//static Fl_Pixmap	unlock_pixmap(unlock_xpm);
+
+#include "pixmaps/flWindow.xpm"
+#include "pixmaps/flButton.xpm"
+#include "pixmaps/flCheckButton.xpm"
+#include "pixmaps/flRoundButton.xpm"
+#include "pixmaps/flBox.xpm"
+#include "pixmaps/flGroup.xpm"
+#include "pixmaps/flFunction.xpm"
+#include "pixmaps/flCode.xpm"
+#include "pixmaps/flCodeBlock.xpm"
+#include "pixmaps/flComment.xpm"
+#include "pixmaps/flDeclaration.xpm"
+#include "pixmaps/flDeclarationBlock.xpm"
+#include "pixmaps/flClass.xpm"
+#include "pixmaps/flTabs.xpm"
+#include "pixmaps/flInput.xpm"
+#include "pixmaps/flChoice.xpm"
+#include "pixmaps/flMenuitem.xpm"
+#include "pixmaps/flMenubar.xpm"
+#include "pixmaps/flSubmenu.xpm"
+#include "pixmaps/flScroll.xpm"
+#include "pixmaps/flTile.xpm"
+#include "pixmaps/flWizard.xpm"
+#include "pixmaps/flPack.xpm"
+#include "pixmaps/flReturnButton.xpm"
+#include "pixmaps/flLightButton.xpm"
+#include "pixmaps/flRepeatButton.xpm"
+#include "pixmaps/flMenuButton.xpm"
+#include "pixmaps/flOutput.xpm"
+#include "pixmaps/flTextDisplay.xpm"
+#include "pixmaps/flTextEdit.xpm"
+#include "pixmaps/flFileInput.xpm"
+#include "pixmaps/flBrowser.xpm"
+#include "pixmaps/flCheckBrowser.xpm"
+#include "pixmaps/flFileBrowser.xpm"
+#include "pixmaps/flClock.xpm"
+#include "pixmaps/flHelp.xpm"
+#include "pixmaps/flProgress.xpm"
+#include "pixmaps/flSlider.xpm"
+#include "pixmaps/flScrollBar.xpm"
+#include "pixmaps/flValueSlider.xpm"
+#include "pixmaps/flAdjuster.xpm"
+#include "pixmaps/flCounter.xpm"
+#include "pixmaps/flDial.xpm"
+#include "pixmaps/flRoller.xpm"
+#include "pixmaps/flValueInput.xpm"
+#include "pixmaps/flValueOutput.xpm"
+#include "pixmaps/flSpinner.xpm"
+#include "pixmaps/flWidgetClass.xpm"
+
+static Fl_Pixmap	window_pixmap(flWindow_xpm);
+static Fl_Pixmap	button_pixmap(flButton_xpm);
+static Fl_Pixmap	checkbutton_pixmap(flCheckButton_xpm);
+static Fl_Pixmap	roundbutton_pixmap(flRoundButton_xpm);
+static Fl_Pixmap	box_pixmap(flBox_xpm);
+static Fl_Pixmap	group_pixmap(flGroup_xpm);
+static Fl_Pixmap	function_pixmap(flFunction_xpm);
+static Fl_Pixmap	code_pixmap(flCode_xpm);
+static Fl_Pixmap	codeblock_pixmap(flCodeBlock_xpm);
+static Fl_Pixmap	comment_pixmap(flComment_xpm);
+static Fl_Pixmap	declaration_pixmap(flDeclaration_xpm);
+static Fl_Pixmap	declarationblock_pixmap(flDeclarationBlock_xpm);
+static Fl_Pixmap	class_pixmap(flClass_xpm);
+static Fl_Pixmap	tabs_pixmap(flTabs_xpm);
+static Fl_Pixmap	input_pixmap(flInput_xpm);
+static Fl_Pixmap	choice_pixmap(flChoice_xpm);
+static Fl_Pixmap	menuitem_pixmap(flMenuitem_xpm);
+static Fl_Pixmap	menubar_pixmap(flMenubar_xpm);
+static Fl_Pixmap	submenu_pixmap(flSubmenu_xpm);
+static Fl_Pixmap	scroll_pixmap(flScroll_xpm);
+static Fl_Pixmap	tile_pixmap(flTile_xpm);
+static Fl_Pixmap	wizard_pixmap(flWizard_xpm);
+static Fl_Pixmap	pack_pixmap(flPack_xpm);
+static Fl_Pixmap	returnbutton_pixmap(flReturnButton_xpm);
+static Fl_Pixmap	lightbutton_pixmap(flLightButton_xpm);
+static Fl_Pixmap	repeatbutton_pixmap(flRepeatButton_xpm);
+static Fl_Pixmap	menubutton_pixmap(flMenuButton_xpm);
+static Fl_Pixmap	output_pixmap(flOutput_xpm);
+static Fl_Pixmap	textdisplay_pixmap(flTextDisplay_xpm);
+static Fl_Pixmap	textedit_pixmap(flTextEdit_xpm);
+static Fl_Pixmap	fileinput_pixmap(flFileInput_xpm);
+static Fl_Pixmap	browser_pixmap(flBrowser_xpm);
+static Fl_Pixmap	checkbrowser_pixmap(flCheckBrowser_xpm);
+static Fl_Pixmap	filebrowser_pixmap(flFileBrowser_xpm);
+static Fl_Pixmap	clock_pixmap(flClock_xpm);
+static Fl_Pixmap	help_pixmap(flHelp_xpm);
+static Fl_Pixmap	progress_pixmap(flProgress_xpm);
+static Fl_Pixmap	slider_pixmap(flSlider_xpm);
+static Fl_Pixmap	scrollbar_pixmap(flScrollBar_xpm);
+static Fl_Pixmap	valueslider_pixmap(flValueSlider_xpm);
+static Fl_Pixmap	adjuster_pixmap(flAdjuster_xpm);
+static Fl_Pixmap	counter_pixmap(flCounter_xpm);
+static Fl_Pixmap	dial_pixmap(flDial_xpm);
+static Fl_Pixmap	roller_pixmap(flRoller_xpm);
+static Fl_Pixmap	valueinput_pixmap(flValueInput_xpm);
+static Fl_Pixmap	valueoutput_pixmap(flValueOutput_xpm);
+static Fl_Pixmap	spinner_pixmap(flSpinner_xpm);
+static Fl_Pixmap	widgetclass_pixmap(flWidgetClass_xpm);
+
+Fl_Pixmap *pixmap[] = { 0, &window_pixmap, &button_pixmap, &checkbutton_pixmap, &roundbutton_pixmap, /* 0..4 */
+ &box_pixmap, &group_pixmap, &function_pixmap, &code_pixmap, &codeblock_pixmap, &declaration_pixmap, /* 5..10 */ 
+ &declarationblock_pixmap, &class_pixmap, &tabs_pixmap, &input_pixmap, &choice_pixmap,               /* 11..15 */
+ &menuitem_pixmap, &menubar_pixmap, &submenu_pixmap, &scroll_pixmap, &tile_pixmap, &wizard_pixmap,   /* 16..21 */
+ &pack_pixmap, &returnbutton_pixmap, &lightbutton_pixmap, &repeatbutton_pixmap, &menubutton_pixmap,  /* 22..26 */
+ &output_pixmap, &textdisplay_pixmap, &textedit_pixmap, &fileinput_pixmap, &browser_pixmap,          /* 27..32 */
+ &checkbrowser_pixmap, &filebrowser_pixmap, &clock_pixmap, &help_pixmap, &progress_pixmap,	     /* 33..36 */
+ &slider_pixmap, &scrollbar_pixmap, &valueslider_pixmap, &adjuster_pixmap, &counter_pixmap,          /* 37..41 */
+ &dial_pixmap, &roller_pixmap, &valueinput_pixmap, &valueoutput_pixmap, &comment_pixmap,             /* 42..46 */
+ &spinner_pixmap, &widgetclass_pixmap /* 47..48 */ };
+
+////////////////////////////////////////////////////////////////
+
+class Widget_Browser : public Fl_Browser_ {
+  friend class Fl_Type;
+
+  // required routines for Fl_Browser_ subclass:
+  void *item_first() const ;
+  void *item_next(void *) const ;
+  void *item_prev(void *) const ;
+  int item_selected(void *) const ;
+  void item_select(void *,int);
+  int item_width(void *) const ;
+  int item_height(void *) const ;
+  void item_draw(void *,int,int,int,int) const ;
+  int incr_height() const ;
+
+public:	
+
+  int handle(int);
+  void callback();
+  Widget_Browser(int,int,int,int,const char * =0);
+};
+
+static Widget_Browser *widget_browser;
+Fl_Widget *make_widget_browser(int x,int y,int w,int h) {
+  return (widget_browser = new Widget_Browser(x,y,w,h));
+}
+
+void select(Fl_Type *o, int v) {
+  widget_browser->select(o,v,1);
+  //  Fl_Type::current = o;
+}
+
+void select_only(Fl_Type *o) {
+  widget_browser->select_only(o,1);
+}
+
+void deselect() {
+  widget_browser->deselect();
+  //Fl_Type::current = 0; // this breaks the paste & merge functions
+}
+
+Fl_Type *Fl_Type::first;
+Fl_Type *Fl_Type::last;
+
+static void Widget_Browser_callback(Fl_Widget *o,void *) {
+  ((Widget_Browser *)o)->callback();
+}
+
+Widget_Browser::Widget_Browser(int X,int Y,int W,int H,const char*l)
+: Fl_Browser_(X,Y,W,H,l) {
+  type(FL_MULTI_BROWSER);
+  Fl_Widget::callback(Widget_Browser_callback);
+  when(FL_WHEN_RELEASE);
+}
+
+void *Widget_Browser::item_first() const {return Fl_Type::first;}
+
+void *Widget_Browser::item_next(void *l) const {return ((Fl_Type*)l)->next;}
+
+void *Widget_Browser::item_prev(void *l) const {return ((Fl_Type*)l)->prev;}
+
+int Widget_Browser::item_selected(void *l) const {return ((Fl_Type*)l)->new_selected;}
+
+void Widget_Browser::item_select(void *l,int v) {((Fl_Type*)l)->new_selected = v;}
+
+int Widget_Browser::item_height(void *l) const {
+  return ((Fl_Type *)l)->visible ? textsize()+2 : 0;
+}
+
+int Widget_Browser::incr_height() const {return textsize()+2;}
+
+static Fl_Type* pushedtitle;
+
+// Generate a descriptive text for this item, to put in browser & window titles
+const char* Fl_Type::title() {
+  const char* c = name(); if (c) return c;
+  return type_name();
+}
+
+extern const char* subclassname(Fl_Type*);
+
+void Widget_Browser::item_draw(void *v, int X, int Y, int, int) const {
+  Fl_Type *l = (Fl_Type *)v;
+  X += 3 + 18 + l->level * 12;
+  if (l->new_selected) fl_color(fl_contrast(FL_FOREGROUND_COLOR,FL_SELECTION_COLOR));
+  else fl_color(FL_FOREGROUND_COLOR);
+  Fl_Pixmap *pm = pixmap[l->pixmapID()];
+  if (pm) pm->draw(X-18, Y);
+  if (l->is_public() == 0) lock_pixmap.draw(X - 17, Y);
+  else if (l->is_public() > 0) ; //unlock_pixmap.draw(X - 17, Y);
+  if (l->is_parent()) {
+    if (!l->next || l->next->level <= l->level) {
+      if (l->open_!=(l==pushedtitle)) {
+	fl_loop(X,Y+7,X+5,Y+12,X+10,Y+7);
+      } else {
+	fl_loop(X+2,Y+2,X+7,Y+7,X+2,Y+12);
+      }
+    } else {
+      if (l->open_!=(l==pushedtitle)) {
+	fl_polygon(X,Y+7,X+5,Y+12,X+10,Y+7);
+      } else {
+	fl_polygon(X+2,Y+2,X+7,Y+7,X+2,Y+12);
+      }
+    }
+    X += 10;
+  }
+  if (l->is_widget() || l->is_class()) {
+    const char* c = subclassname(l);
+    if (!strncmp(c,"Fl_",3)) c += 3;
+    fl_font(textfont(), textsize());
+    fl_draw(c, X, Y+13);
+    X += int(fl_width(c)+fl_width('n'));
+    c = l->name();
+    if (c) {
+      fl_font(textfont()|FL_BOLD, textsize());
+      fl_draw(c, X, Y+13);
+    } else if ((c=l->label())) {
+      char buf[50]; char* p = buf;
+      *p++ = '"';
+      for (int i = 20; i--;) {
+	if (! (*c & -32)) break;
+	*p++ = *c++;
+      }
+      if (*c) {strcpy(p,"..."); p+=3;}
+      *p++ = '"';
+      *p = 0;
+      fl_draw(buf, X, Y+13);
+    }
+  } else {
+    const char* c = l->title();
+    char buf[60]; char* p = buf;
+    for (int i = 55; i--;) {
+      if (! (*c & -32)) break;
+      *p++ = *c++;
+    }
+    if (*c) {strcpy(p,"..."); p+=3;}
+    *p = 0;
+    fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize());
+    fl_draw(buf, X, Y+13);
+  }
+}
+
+int Widget_Browser::item_width(void *v) const {
+  Fl_Type *l = (Fl_Type *)v;
+
+  if (!l->visible) return 0;
+
+  int W = 3 + 16 + 18 + l->level*10;
+  if (l->is_parent()) W += 10;
+
+  if (l->is_widget() || l->is_class()) {
+    const char* c = l->type_name();
+    if (!strncmp(c,"Fl_",3)) c += 3;
+    fl_font(textfont(), textsize());
+    W += int(fl_width(c) + fl_width('n'));
+    c = l->name();
+    if (c) {
+      fl_font(textfont()|FL_BOLD, textsize());
+      W += int(fl_width(c));
+    } else if ((c=l->label())) {
+      char buf[50]; char* p = buf;
+      *p++ = '"';
+      for (int i = 20; i--;) {
+	if (! (*c & -32)) break;
+	*p++ = *c++;
+      }
+      if (*c) {strcpy(p,"..."); p+=3;}
+      *p++ = '"';
+      *p = 0;
+      W += int(fl_width(buf));
+    }
+  } else {
+    const char* c = l->title();
+    char buf[60]; char* p = buf;
+    for (int i = 55; i--;) {
+      if (! (*c & -32)) break;
+      *p++ = *c++;
+    }
+    if (*c) {strcpy(p,"..."); p+=3;}
+    *p = 0;
+    fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize());
+    W += int(fl_width(buf));
+  }
+
+  return W;
+}
+
+void redraw_browser() {
+  widget_browser->redraw();
+}
+
+void Widget_Browser::callback() {
+  selection_changed((Fl_Type*)selection());
+}
+
+int Widget_Browser::handle(int e) {
+  static Fl_Type *title;
+  Fl_Type *l;
+  int X,Y,W,H; bbox(X,Y,W,H);
+  switch (e) {
+  case FL_PUSH:
+    if (!Fl::event_inside(X,Y,W,H)) break;
+    l = (Fl_Type*)find_item(Fl::event_y());
+    if (l) {
+      X += 12*l->level + 18 - hposition();
+      if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) {
+	title = pushedtitle = l;
+	redraw_line(l);
+	return 1;
+      }
+    }
+    break;
+  case FL_DRAG:
+    if (!title) break;
+    l = (Fl_Type*)find_item(Fl::event_y());
+    if (l) {
+      X += 12*l->level + 18 - hposition();
+      if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) ;
+      else l = 0;
+    }
+    if (l != pushedtitle) {
+      if (pushedtitle) redraw_line(pushedtitle);
+      if (l) redraw_line(l);
+      pushedtitle = l;
+    }
+    return 1;
+  case FL_RELEASE:
+    if (!title) {
+      l = (Fl_Type*)find_item(Fl::event_y());
+      if (l && l->new_selected && (Fl::event_clicks() || Fl::event_state(FL_CTRL)))
+	l->open();
+      break;
+    }
+    l = pushedtitle;
+    title = pushedtitle = 0;
+    if (l) {
+      if (l->open_) {
+	l->open_ = 0;
+	for (Fl_Type*k = l->next; k&&k->level>l->level; k = k->next)
+	  k->visible = 0;
+      } else {
+	l->open_ = 1;
+	for (Fl_Type*k=l->next; k&&k->level>l->level;) {
+	  k->visible = 1;
+	  if (k->is_parent() && !k->open_) {
+	    Fl_Type *j;
+	    for (j = k->next; j && j->level>k->level; j = j->next);
+	    k = j;
+	  } else
+	    k = k->next;
+	}
+      }
+      redraw();
+    }
+    return 1;
+  }
+  return Fl_Browser_::handle(e);
+}
+
+Fl_Type::Fl_Type() {
+  factory = 0;
+  parent = 0;
+  next = prev = 0;
+  selected = new_selected = 0;
+  visible = 0;
+  name_ = 0;
+  label_ = 0;
+  user_data_ = 0;
+  user_data_type_ = 0;
+  callback_ = 0;
+  rtti = 0;
+  level = 0;
+  code_line = header_line = -1;
+  code_line_end = header_line_end = -1;
+}
+
+static void fixvisible(Fl_Type *p) {
+  Fl_Type *t = p;
+  for (;;) {
+    if (t->parent) t->visible = t->parent->visible && t->parent->open_;
+    else t->visible = 1;
+    t = t->next;
+    if (!t || t->level <= p->level) break;
+  }
+}
+
+// turn a click at x,y on this into the actual picked object:
+Fl_Type* Fl_Type::click_test(int,int) {return 0;}
+void Fl_Type::add_child(Fl_Type*, Fl_Type*) {}
+void Fl_Type::move_child(Fl_Type*, Fl_Type*) {}
+void Fl_Type::remove_child(Fl_Type*) {}
+
+// add a list of widgets as a new child of p:
+void Fl_Type::add(Fl_Type *p) {
+  if (p && parent == p) return;
+  undo_checkpoint();
+  parent = p;
+  Fl_Type *end = this;
+  while (end->next) end = end->next;
+  Fl_Type *q;
+  int newlevel;
+  if (p) {
+    for (q = p->next; q && q->level > p->level; q = q->next);
+    newlevel = p->level+1;
+  } else {
+    q = 0;
+    newlevel = 0;
+  }
+  for (Fl_Type *t = this->next; t; t = t->next) t->level += (newlevel-level);
+  level = newlevel;
+  if (q) {
+    prev = q->prev;
+    prev->next = this;
+    q->prev = end;
+    end->next = q;
+  } else if (first) {
+    prev = last;
+    prev->next = this;
+    end->next = 0;
+    last = end;
+  } else {
+    first = this;
+    last = end;
+    prev = end->next = 0;
+  }
+  if (p) p->add_child(this,0);
+  open_ = 1;
+  fixvisible(this);
+  set_modflag(1);
+  widget_browser->redraw();
+}
+
+// add to a parent before another widget:
+void Fl_Type::insert(Fl_Type *g) {
+  Fl_Type *end = this;
+  while (end->next) end = end->next;
+  parent = g->parent;
+  int newlevel = g->level;
+  visible = g->visible;
+  for (Fl_Type *t = this->next; t; t = t->next) t->level += newlevel-level;
+  level = newlevel;
+  prev = g->prev;
+  if (prev) prev->next = this; else first = this;
+  end->next = g;
+  g->prev = end;
+  fixvisible(this);
+  if (parent) parent->add_child(this, g);
+  widget_browser->redraw();
+}
+
+// Return message number for I18N...
+int
+Fl_Type::msgnum() {
+  int		count;
+  Fl_Type	*p;
+
+  for (count = 0, p = this; p;) {
+    if (p->label()) count ++;
+    if (p != this && p->is_widget() && ((Fl_Widget_Type *)p)->tooltip()) count ++;
+
+    if (p->prev) p = p->prev;
+    else p = p->parent;
+  }
+
+  return count;
+}
+
+
+// delete from parent:
+Fl_Type *Fl_Type::remove() {
+  Fl_Type *end = this;
+  for (;;) {
+    if (!end->next || end->next->level <= level) break;
+    end = end->next;
+  }
+  if (prev) prev->next = end->next;
+  else first = end->next;
+  if (end->next) end->next->prev = prev;
+  else last = prev;
+  Fl_Type *r = end->next;
+  prev = end->next = 0;
+  if (parent) parent->remove_child(this);
+  parent = 0;
+  widget_browser->redraw();
+  selection_changed(0);
+  return r;
+}
+
+// update a string member:
+int storestring(const char *n, const char * & p, int nostrip) {
+  if (n == p) return 0;
+  undo_checkpoint();
+  int length = 0;
+  if (n) { // see if blank, strip leading & trailing blanks
+    if (!nostrip) while (isspace(*n)) n++;
+    const char *e = n + strlen(n);
+    if (!nostrip) while (e > n && isspace(*(e-1))) e--;
+    length = e-n;
+    if (!length) n = 0;
+  }    
+  if (n == p) return 0;
+  if (n && p && !strncmp(n,p,length) && !p[length]) return 0;
+  if (p) free((void *)p);
+  if (!n || !*n) {
+    p = 0;
+  } else {
+    char *q = (char *)malloc(length+1);
+    strlcpy(q,n,length+1);
+    p = q;
+  }
+  set_modflag(1);
+  return 1;
+}
+
+void Fl_Type::name(const char *n) {
+  int nostrip = is_comment();
+  if (storestring(n,name_,nostrip)) {
+    if (visible) widget_browser->redraw();
+  }
+}
+
+void Fl_Type::label(const char *n) {
+  if (storestring(n,label_,1)) {
+    setlabel(label_);
+    if (visible && !name_) widget_browser->redraw();
+  }
+}
+
+void Fl_Type::callback(const char *n) {
+  storestring(n,callback_);
+}
+
+void Fl_Type::user_data(const char *n) {
+  storestring(n,user_data_);
+}
+
+void Fl_Type::user_data_type(const char *n) {
+  storestring(n,user_data_type_);
+}
+
+void Fl_Type::open() {
+  printf("Open of '%s' is not yet implemented\n",type_name());
+}
+
+void Fl_Type::setlabel(const char *) {}
+
+Fl_Type::~Fl_Type() {
+  // warning: destructor only works for widgets that have been add()ed.
+  if (widget_browser) widget_browser->deleting(this);
+  if (prev) prev->next = next; else first = next;
+  if (next) next->prev = prev; else last = prev;
+  if (current == this) current = 0;
+  if (parent) parent->remove_child(this);
+}
+
+int Fl_Type::is_parent() const {return 0;}
+int Fl_Type::is_widget() const {return 0;}
+int Fl_Type::is_valuator() const {return 0;}
+int Fl_Type::is_button() const {return 0;}
+int Fl_Type::is_menu_item() const {return 0;}
+int Fl_Type::is_menu_button() const {return 0;}
+int Fl_Type::is_group() const {return 0;}
+int Fl_Type::is_window() const {return 0;}
+int Fl_Type::is_code_block() const {return 0;}
+int Fl_Type::is_decl_block() const {return 0;}
+int Fl_Type::is_comment() const {return 0;}
+int Fl_Type::is_class() const {return 0;}
+int Fl_Type::is_public() const {return 1;}
+
+int Fl_Code_Type::is_public()const { return -1; }
+int Fl_CodeBlock_Type::is_public()const { return -1; }
+
+
+////////////////////////////////////////////////////////////////
+
+Fl_Type *in_this_only; // set if menu popped-up in window
+
+void select_all_cb(Fl_Widget *,void *) {
+  Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0;
+  if (in_this_only) {
+    Fl_Type *t = p;
+    for (; t && t != in_this_only; t = t->parent);
+    if (t != in_this_only) p = in_this_only;
+  }
+  for (;;) {
+    if (p) {
+      int foundany = 0;
+      for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) {
+	if (!t->new_selected) {widget_browser->select(t,1,0); foundany = 1;}
+      }
+      if (foundany) break;
+      p = p->parent;
+    } else {
+      for (Fl_Type *t = Fl_Type::first; t; t = t->next)
+	widget_browser->select(t,1,0);
+      break;
+    }
+  }
+  selection_changed(p);
+}
+
+void select_none_cb(Fl_Widget *,void *) {
+  Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0;
+  if (in_this_only) {
+    Fl_Type *t = p;
+    for (; t && t != in_this_only; t = t->parent);
+    if (t != in_this_only) p = in_this_only;
+  }
+  for (;;) {
+    if (p) {
+      int foundany = 0;
+      for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) {
+	if (t->new_selected) {widget_browser->select(t,0,0); foundany = 1;}
+      }
+      if (foundany) break;
+      p = p->parent;
+    } else {
+      for (Fl_Type *t = Fl_Type::first; t; t = t->next)
+	widget_browser->select(t,0,0);
+      break;
+    }
+  }
+  selection_changed(p);
+}
+
+static void delete_children(Fl_Type *p) {
+  Fl_Type *f;
+  for (f = p; f && f->next && f->next->level > p->level; f = f->next);
+  for (; f != p; ) {
+    Fl_Type *g = f->prev;
+    delete f;
+    f = g;
+  }
+}
+
+void delete_all(int selected_only) {
+  for (Fl_Type *f = Fl_Type::first; f;) {
+    if (f->selected || !selected_only) {
+      delete_children(f);
+      Fl_Type *g = f->next;
+      delete f;
+      f = g;
+    } else f = f->next;
+  }
+  if(!selected_only)    include_H_from_C=1;
+
+  selection_changed(0);
+}
+
+// move f (and it's children) into list before g:
+// returns pointer to whatever is after f & children
+void Fl_Type::move_before(Fl_Type* g) {
+  if (level != g->level) printf("move_before levels don't match! %d %d\n",
+				level, g->level);
+  Fl_Type* n;
+  for (n = next; n && n->level > level; n = n->next);
+  if (n == g) return;
+  Fl_Type *l = n ? n->prev : Fl_Type::last;
+  prev->next = n;
+  if (n) n->prev = prev; else Fl_Type::last = prev;
+  prev = g->prev;
+  l->next = g;
+  if (prev) prev->next = this; else Fl_Type::first = this;
+  g->prev = l;
+  if (parent && is_widget()) parent->move_child(this,g);
+  widget_browser->redraw();
+}
+
+// move selected widgets in their parent's list:
+void earlier_cb(Fl_Widget*,void*) {
+  Fl_Type *f;
+  int mod = 0;
+  for (f = Fl_Type::first; f; ) {
+    Fl_Type* nxt = f->next;
+    if (f->selected) {
+      Fl_Type* g;
+      for (g = f->prev; g && g->level > f->level; g = g->prev);
+      if (g && g->level == f->level && !g->selected) {
+        f->move_before(g);
+        mod = 1;
+      }
+    }
+    f = nxt;
+  }
+  if (mod) set_modflag(1);
+}
+
+void later_cb(Fl_Widget*,void*) {
+  Fl_Type *f;
+  int mod = 0;
+  for (f = Fl_Type::last; f; ) {
+    Fl_Type* prv = f->prev;
+    if (f->selected) {
+      Fl_Type* g;
+      for (g = f->next; g && g->level > f->level; g = g->next);
+      if (g && g->level == f->level && !g->selected) {
+        g->move_before(f);
+        mod = 1;
+      }
+    }
+    f = prv;
+  }
+  if (mod) set_modflag(1);
+}
+
+////////////////////////////////////////////////////////////////
+
+// write a widget and all it's children:
+void Fl_Type::write() {
+    write_indent(level);
+    write_word(type_name());
+    
+    if (is_class()) {
+      const char * p = 	((Fl_Class_Type*)this)->prefix();
+      if (p &&	strlen(p))
+	write_word(p);
+    }
+
+    write_word(name());
+    write_open(level);
+    write_properties();
+    write_close(level);
+    if (!is_parent()) return;
+    // now do children:
+    write_open(level);
+    Fl_Type *child;
+    for (child = next; child && child->level > level; child = child->next)
+	if (child->level == level+1) child->write();
+    write_close(level);
+}
+
+void Fl_Type::write_properties() {
+  // repeat this for each attribute:
+  if (label()) {
+    write_indent(level+1);
+    write_word("label");
+    write_word(label());
+  }
+  if (user_data()) {
+    write_indent(level+1);
+    write_word("user_data");
+    write_word(user_data());
+  }
+  if (user_data_type()) {
+    write_word("user_data_type");
+    write_word(user_data_type());
+  }
+  if (callback()) {
+    write_indent(level+1);
+    write_word("callback");
+    write_word(callback());
+  }
+  if (is_parent() && open_) write_word("open");
+  if (selected) write_word("selected");
+}
+
+void Fl_Type::read_property(const char *c) {
+  if (!strcmp(c,"label"))
+    label(read_word());
+  else if (!strcmp(c,"user_data"))
+    user_data(read_word());
+  else if (!strcmp(c,"user_data_type"))
+    user_data_type(read_word());
+  else if (!strcmp(c,"callback"))
+    callback(read_word());
+  else if (!strcmp(c,"open"))
+    open_ = 1;
+  else if (!strcmp(c,"selected"))
+    select(this,1);
+  else
+    read_error("Unknown property \"%s\"", c);
+}
+
+int Fl_Type::read_fdesign(const char*, const char*) {return 0;}
+
+/**
+ * Build widgets and dataset needed in live mode.
+ * \return a widget pointer that the live mode initiator can 'show()'
+ * \see leave_live_mode()
+ */
+Fl_Widget *Fl_Type::enter_live_mode(int top) {
+  return 0L;
+}
+
+/**
+ * Release all resources created when enetring live mode.
+ * \see enter_live_mode()
+ */
+void Fl_Type::leave_live_mode() {
+}
+
+/**
+ * Copy all needed properties for this tye into the live object.
+ */
+void Fl_Type::copy_properties() {
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Type.h b/Utilities/FLTK/fluid/Fl_Type.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe9d65351bba1edae635f27ae79a2d6ea3887e77
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Type.h
@@ -0,0 +1,764 @@
+//
+// "$Id$"
+//
+// Widget type header file for the Fast Light Tool Kit (FLTK).
+//
+// Each object described by Fluid is one of these objects.  They
+// are all stored in a double-linked list.
+//
+// There is also a single "factory" instance of each type of this.
+// The method "make()" is called on this factory to create a new
+// instance of this object.  It could also have a "copy()" function,
+// but it was easier to implement this by using the file read/write
+// that is needed to save the setup anyways.
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu.H>
+#include "Fluid_Image.h"
+#include <FL/fl_draw.H>
+
+void set_modflag(int mf);
+
+class Fl_Type {
+
+  friend class Widget_Browser;
+  friend Fl_Widget *make_type_browser(int,int,int,int,const char *l=0);
+  friend class Fl_Window_Type;
+  virtual void setlabel(const char *); // virtual part of label(char*)
+
+protected:
+
+  Fl_Type();
+
+  const char *name_;
+  const char *label_;
+  const char *callback_;
+  const char *user_data_;
+  const char *user_data_type_;
+
+public:	// things that should not be public:
+
+  Fl_Type *parent; // parent, which is previous in list
+  char new_selected; // browser highlight
+  char selected; // copied here by selection_changed()
+  char open_;	// state of triangle in browser
+  char visible; // true if all parents are open
+  char rtti;	// hack because I have no rtti, this is 0 for base class
+  int level;	// number of parents over this
+  static Fl_Type *first, *last; // linked list of all objects
+  Fl_Type *next, *prev;	// linked list of all objects
+
+  Fl_Type *factory;
+  const char *callback_name();
+
+  int code_line, header_line;
+  int code_line_end, header_line_end;
+
+public:
+
+  virtual ~Fl_Type();
+  virtual Fl_Type *make() = 0;
+
+  void add(Fl_Type *parent); // add as new child
+  void insert(Fl_Type *n); // insert into list before n
+  Fl_Type* remove();	// remove from list
+  void move_before(Fl_Type*); // move before a sibling
+
+  virtual const char *title(); // string for browser
+  virtual const char *type_name() = 0; // type for code output
+
+  const char *name() const {return name_;}
+  void name(const char *);
+  const char *label() const {return label_;}
+  void label(const char *);
+  const char *callback() const {return callback_;}
+  void callback(const char *);
+  const char *user_data() const {return user_data_;}
+  void user_data(const char *);
+  const char *user_data_type() const {return user_data_type_;}
+  void user_data_type(const char *);
+
+  virtual Fl_Type* click_test(int,int);
+  virtual void add_child(Fl_Type*, Fl_Type* beforethis);
+  virtual void move_child(Fl_Type*, Fl_Type* beforethis);
+  virtual void remove_child(Fl_Type*);
+
+  static Fl_Type *current;  // most recently picked object
+  virtual void open();	// what happens when you double-click
+
+  // read and write data to a saved file:
+  void write();
+  virtual void write_properties();
+  virtual void read_property(const char *);
+  virtual int read_fdesign(const char*, const char*);
+
+  // write code, these are called in order:
+  virtual void write_static(); // write static stuff to .c file
+  virtual void write_code1(); // code and .h before children
+  virtual void write_code2(); // code and .h after children
+
+  // live mode
+  virtual Fl_Widget *enter_live_mode(int top=0); // build wdgets needed for live mode
+  virtual void leave_live_mode(); // free allocated resources
+  virtual void copy_properties(); // copy properties from this type into a potetial live object
+
+  // get message number for I18N
+  int msgnum();
+
+  // fake rtti:
+  virtual int is_parent() const;
+  virtual int is_widget() const;
+  virtual int is_button() const;
+  virtual int is_valuator() const;
+  virtual int is_menu_item() const;
+  virtual int is_menu_button() const;
+  virtual int is_group() const;
+  virtual int is_window() const;
+  virtual int is_code_block() const;
+  virtual int is_decl_block() const;
+  virtual int is_comment() const;
+  virtual int is_class() const;
+  virtual int is_public() const;
+
+  virtual int pixmapID() { return 0; }
+
+  const char* class_name(const int need_nest) const;
+  const class Fl_Class_Type* is_in_class() const;
+};
+
+class Fl_Function_Type : public Fl_Type {
+  const char* return_type;
+  char public_, cdecl_, constructor, havewidgets;
+public:
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void open();
+  int ismain() {return name_ == 0;}
+  virtual const char *type_name() {return "Function";}
+  virtual const char *title() {
+    return name() ? name() : "main()";
+  }
+  int is_parent() const {return 1;}
+  int is_code_block() const {return 1;}
+  virtual int is_public() const;
+  int pixmapID() { return 7; }
+  void write_properties();
+  void read_property(const char *);
+  int has_signature(const char *, const char*) const;
+};
+
+class Fl_Code_Type : public Fl_Type {
+public:
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void open();
+  virtual const char *type_name() {return "code";}
+  int is_code_block() const {return 0;}
+  int pixmapID() { return 8; }
+  virtual int is_public() const;
+};
+
+class Fl_CodeBlock_Type : public Fl_Type {
+  const char* after;
+public:
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void open();
+  virtual const char *type_name() {return "codeblock";}
+  int is_code_block() const {return 1;}
+  int is_parent() const {return 1;}
+  virtual int is_public() const;
+  int pixmapID() { return 9; }
+  void write_properties();
+  void read_property(const char *);
+};
+
+class Fl_Decl_Type : public Fl_Type {
+  char public_;
+public:
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void open();
+  virtual const char *type_name() {return "decl";}
+  void write_properties();
+  void read_property(const char *);
+  virtual int is_public() const;
+  int pixmapID() { return 10; }
+};
+
+class Fl_DeclBlock_Type : public Fl_Type {
+  const char* after;
+  char public_;
+public:
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void open();
+  virtual const char *type_name() {return "declblock";}
+  void write_properties();
+  void read_property(const char *);
+  int is_parent() const {return 1;}
+  int is_decl_block() const {return 1;}
+  virtual int is_public() const;
+  int pixmapID() { return 11; }
+};
+
+class Fl_Comment_Type : public Fl_Type {
+  char in_c_, in_h_, style_;
+  char title_buf[64];
+public:
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void open();
+  virtual const char *type_name() {return "comment";}
+  virtual const char *title(); // string for browser
+  void write_properties();
+  void read_property(const char *);
+  virtual int is_public() const { return 1; }
+  virtual int is_comment() const { return 1; }
+  int pixmapID() { return 46; }
+};
+
+class Fl_Class_Type : public Fl_Type {
+  const char* subclass_of;
+  char public_;
+public:
+  // state variables for output:
+  char write_public_state; // true when public: has been printed
+  Fl_Class_Type* parent_class; // save class if nested
+//
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void open();
+  virtual const char *type_name() {return "class";}
+  int is_parent() const {return 1;}
+  int is_decl_block() const {return 1;}
+  int is_class() const {return 1;}
+  virtual int is_public() const;
+  int pixmapID() { return 12; }
+  void write_properties();
+  void read_property(const char *);
+
+  // class prefix attribute access
+  void prefix(const char* p);
+  const char*  prefix() const {return class_prefix;}
+  int has_function(const char*, const char*) const;
+private:
+  const char* class_prefix;
+};
+
+#define NUM_EXTRA_CODE 4
+
+class Fl_Widget_Type : public Fl_Type {
+  virtual Fl_Widget *widget(int,int,int,int) = 0;
+  virtual Fl_Widget_Type *_make() = 0; // virtual constructor
+  virtual void setlabel(const char *);
+
+  const char *extra_code_[NUM_EXTRA_CODE];
+  const char *subclass_;
+  const char *tooltip_;
+  const char *image_name_;
+  const char *inactive_name_;
+  uchar hotspot_;
+
+protected:
+
+  void write_static();
+  void write_code1();
+  void write_widget_code();
+  void write_extra_code();
+  void write_block_close();
+  void write_code2();
+  void write_color(const char*, Fl_Color);
+  Fl_Widget *live_widget;
+
+public:
+  static int default_size;
+
+  const char *xclass; // junk string, used for shortcut
+  Fl_Widget *o;
+  int public_;
+
+  Fluid_Image *image;
+  void setimage(Fluid_Image *);
+  Fluid_Image *inactive;
+  void setinactive(Fluid_Image *);
+
+  Fl_Widget_Type();
+  Fl_Type *make();
+  void open();
+
+  const char *extra_code(int n) const {return extra_code_[n];}
+  void extra_code(int n,const char *);
+  const char *subclass() const {return subclass_;}
+  void subclass(const char *);
+  const char *tooltip() const {return tooltip_;}
+  void tooltip(const char *);
+  const char *image_name() const {return image_name_;}
+  void image_name(const char *);
+  const char *inactive_name() const {return inactive_name_;}
+  void inactive_name(const char *);
+  uchar hotspot() const {return hotspot_;}
+  void hotspot(uchar v) {hotspot_ = v;}
+  uchar resizable() const;
+  void resizable(uchar v);
+
+  virtual int textstuff(int what, Fl_Font &, int &, Fl_Color &);
+  virtual Fl_Menu_Item *subtypes();
+
+  virtual int is_widget() const;
+  virtual int is_public() const;
+
+  virtual void write_properties();
+  virtual void read_property(const char *);
+  virtual int read_fdesign(const char*, const char*);
+
+  virtual Fl_Widget *enter_live_mode(int top=0);
+  virtual void leave_live_mode();
+  virtual void copy_properties();
+
+  virtual void ideal_size(int &w, int &h);
+  virtual void ideal_spacing(int &x, int &y);
+
+  ~Fl_Widget_Type();
+  void redraw();
+};
+
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Pack.H>
+#include <FL/Fl_Wizard.H>
+
+class igroup : public Fl_Group {
+public:
+  void resize(int,int,int,int);
+  void full_resize(int X, int Y, int W, int H) { Fl_Group::resize(X, Y, W, H); }
+  igroup(int X,int Y,int W,int H) : Fl_Group(X,Y,W,H) {Fl_Group::current(0);}
+};
+
+class itabs : public Fl_Tabs {
+public:
+  void resize(int,int,int,int);
+  void full_resize(int X, int Y, int W, int H) { Fl_Group::resize(X, Y, W, H); }
+  itabs(int X,int Y,int W,int H) : Fl_Tabs(X,Y,W,H) {}
+};
+
+class iwizard : public Fl_Wizard {
+public:
+  void resize(int,int,int,int);
+  void full_resize(int X, int Y, int W, int H) { Fl_Group::resize(X, Y, W, H); }
+  iwizard(int X,int Y,int W,int H) : Fl_Wizard(X,Y,W,H) {}
+};
+
+class Fl_Group_Type : public Fl_Widget_Type {
+public:
+  virtual const char *type_name() {return "Fl_Group";}
+  Fl_Widget *widget(int X,int Y,int W,int H) {
+    igroup *g = new igroup(X,Y,W,H); Fl_Group::current(0); return g;}
+  Fl_Widget_Type *_make() {return new Fl_Group_Type();}
+  Fl_Type *make();
+  void write_code1();
+  void write_code2();
+  void add_child(Fl_Type*, Fl_Type*);
+  void move_child(Fl_Type*, Fl_Type*);
+  void remove_child(Fl_Type*);
+  int is_parent() const {return 1;}
+  int is_group() const {return 1;}
+  int pixmapID() { return 6; }
+
+  virtual Fl_Widget *enter_live_mode(int top=0);
+  virtual void leave_live_mode();
+  virtual void copy_properties();
+};
+
+extern const char pack_type_name[];
+extern Fl_Menu_Item pack_type_menu[];
+
+class Fl_Pack_Type : public Fl_Group_Type {
+  Fl_Menu_Item *subtypes() {return pack_type_menu;}
+public:
+  virtual const char *type_name() {return pack_type_name;}
+  Fl_Widget_Type *_make() {return new Fl_Pack_Type();}
+  int pixmapID() { return 22; }
+  void copy_properties();
+};
+
+extern const char tabs_type_name[];
+
+class Fl_Tabs_Type : public Fl_Group_Type {
+public:
+  virtual void ideal_spacing(int &x, int &y) {
+     x = 10;
+     fl_font(o->labelfont(), o->labelsize());
+     y = fl_height() + o->labelsize() - 6;
+  }
+  virtual const char *type_name() {return tabs_type_name;}
+  Fl_Widget *widget(int X,int Y,int W,int H) {
+    itabs *g = new itabs(X,Y,W,H); Fl_Group::current(0); return g;}
+  Fl_Widget_Type *_make() {return new Fl_Tabs_Type();}
+  Fl_Type* click_test(int,int);
+  void add_child(Fl_Type*, Fl_Type*);
+  void remove_child(Fl_Type*);
+  int pixmapID() { return 13; }
+  Fl_Widget *enter_live_mode(int top=0);
+};
+
+extern const char scroll_type_name[];
+extern Fl_Menu_Item scroll_type_menu[];
+
+class Fl_Scroll_Type : public Fl_Group_Type {
+  Fl_Menu_Item *subtypes() {return scroll_type_menu;}
+public:
+  virtual const char *type_name() {return scroll_type_name;}
+  Fl_Widget_Type *_make() {return new Fl_Scroll_Type();}
+  int pixmapID() { return 19; }
+  void copy_properties();
+};
+
+extern const char tile_type_name[];
+
+class Fl_Tile_Type : public Fl_Group_Type {
+public:
+  virtual const char *type_name() {return tile_type_name;}
+  Fl_Widget_Type *_make() {return new Fl_Tile_Type();}
+  int pixmapID() { return 20; }
+  void copy_properties();
+};
+
+extern const char wizard_type_name[];
+
+class Fl_Wizard_Type : public Fl_Group_Type {
+public:
+  virtual const char *type_name() {return wizard_type_name;}
+  Fl_Widget *widget(int X,int Y,int W,int H) {
+    iwizard *g = new iwizard(X,Y,W,H); Fl_Group::current(0); return g;}
+  Fl_Widget_Type *_make() {return new Fl_Wizard_Type();}
+  int pixmapID() { return 21; }
+};
+
+extern Fl_Menu_Item window_type_menu[];
+
+class Fl_Window_Type : public Fl_Widget_Type {
+protected:
+
+  Fl_Menu_Item* subtypes() {return window_type_menu;}
+
+  friend class Overlay_Window;
+  int mx,my;		// mouse position during dragging
+  int x1,y1;		// initial position of selection box
+  int bx,by,br,bt;	// bounding box of selection before snapping
+  int sx,sy,sr,st;	// bounding box of selection after snapping to guides
+  int dx,dy;
+  int drag;		// which parts of bbox are being moved
+  int numselected;	// number of children selected
+  enum {LEFT=1,RIGHT=2,BOTTOM=4,TOP=8,DRAG=16,BOX=32};
+  void draw_overlay();
+  void newdx();
+  void newposition(Fl_Widget_Type *,int &x,int &y,int &w,int &h);
+  int handle(int);
+  virtual void setlabel(const char *);
+  void write_code1();
+  void write_code2();
+  Fl_Widget_Type *_make() {return 0;} // we don't call this
+  Fl_Widget *widget(int,int,int,int) {return 0;}
+  int recalc;		// set by fix_overlay()
+  void moveallchildren();
+  int pixmapID() { return 1; }
+
+public:
+
+  Fl_Window_Type() { drag = dx = dy = 0; sr_min_w = sr_min_h = sr_max_w = sr_max_h = 0; }
+  uchar modal, non_modal;
+
+  Fl_Type *make();
+  virtual const char *type_name() {return "Fl_Window";}
+
+  void open();
+
+  void fix_overlay();			// Update the bounding box, etc
+  uchar *read_image(int &ww, int &hh);	// Read an image of the window
+
+  virtual void write_properties();
+  virtual void read_property(const char *);
+  virtual int read_fdesign(const char*, const char*);
+
+  void add_child(Fl_Type*, Fl_Type*);
+  void move_child(Fl_Type*, Fl_Type*);
+  void remove_child(Fl_Type*);
+
+  int is_parent() const {return 1;}
+  int is_group() const {return 1;}
+  int is_window() const {return 1;}
+
+  Fl_Widget *enter_live_mode(int top=0);
+  void leave_live_mode();
+  void copy_properties();
+
+  int sr_min_w, sr_min_h, sr_max_w, sr_max_h;
+};
+
+class Fl_Widget_Class_Type : private Fl_Window_Type {
+public:
+  Fl_Widget_Class_Type() {
+    write_public_state = 0;
+    wc_relative = 0;
+  }
+  // state variables for output:
+  char write_public_state; // true when public: has been printed
+  char wc_relative; // if true, reposition all child widgets in an Fl_Group
+
+  virtual void write_properties();
+  virtual void read_property(const char *);
+
+  void write_code1();
+  void write_code2();
+  Fl_Type *make();
+  virtual const char *type_name() {return "widget_class";}
+  int pixmapID() { return 48; }
+  int is_parent() const {return 1;}
+  int is_decl_block() const {return 1;}
+  int is_class() const {return 1;}
+};
+
+
+extern Fl_Menu_Item menu_item_type_menu[];
+
+class Fl_Menu_Item_Type : public Fl_Widget_Type {
+public:
+  Fl_Menu_Item* subtypes() {return menu_item_type_menu;}
+  const char* type_name() {return "MenuItem";}
+  Fl_Type* make();
+  int is_menu_item() const {return 1;}
+  int is_button() const {return 1;} // this gets shortcut to work
+  Fl_Widget* widget(int,int,int,int) {return 0;}
+  Fl_Widget_Type* _make() {return 0;}
+  const char* menu_name(int& i);
+  int flags();
+  void write_static();
+  void write_item();
+  void write_code1();
+  void write_code2();
+  int pixmapID() { return 16; }
+};
+
+class Fl_Submenu_Type : public Fl_Menu_Item_Type {
+public:
+  Fl_Menu_Item* subtypes() {return 0;}
+  const char* type_name() {return "Submenu";}
+  int is_parent() const {return 1;}
+  int is_button() const {return 0;} // disable shortcut
+  Fl_Type* make();
+  // changes to submenu must propagate up so build_menu is called
+  // on the parent Fl_Menu_Type:
+  void add_child(Fl_Type*a, Fl_Type*b) {parent->add_child(a,b);}
+  void move_child(Fl_Type*a, Fl_Type*b) {parent->move_child(a,b);}
+  void remove_child(Fl_Type*a) {parent->remove_child(a);}
+  int pixmapID() { return 18; }
+};
+
+
+#include <FL/Fl_Menu_.H>
+class Fl_Menu_Type : public Fl_Widget_Type {
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+    Fl_Menu_ *myo = (Fl_Menu_*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+    switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+    }
+    return 1;
+  }
+public:
+  int is_menu_button() const {return 1;}
+  int is_parent() const {return 1;}
+  int menusize;
+  virtual void build_menu();
+  Fl_Menu_Type() : Fl_Widget_Type() {menusize = 0;}
+  ~Fl_Menu_Type() {
+    if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Menu_*)o)->menu());
+  }
+  void add_child(Fl_Type*, Fl_Type*) {build_menu();}
+  void move_child(Fl_Type*, Fl_Type*) {build_menu();}
+  void remove_child(Fl_Type*) {build_menu();}
+  Fl_Type* click_test(int x, int y);
+  void write_code2();
+  void copy_properties();
+};
+
+extern Fl_Menu_Item button_type_menu[];
+
+#include <FL/Fl_Menu_Button.H>
+class Fl_Menu_Button_Type : public Fl_Menu_Type {
+  Fl_Menu_Item *subtypes() {return button_type_menu;}
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Widget_Type::ideal_size(w, h);
+    w += 2 * ((o->labelsize() - 3) & ~1) + o->labelsize() - 4;
+    h = (h / 5) * 5;
+    if (h < 15) h = 15;
+    if (w < (15 + h)) w = 15 + h;
+  }
+  virtual const char *type_name() {return "Fl_Menu_Button";}
+  Fl_Widget *widget(int X,int Y,int W,int H) {
+    return new Fl_Menu_Button(X,Y,W,H,"menu");}
+  Fl_Widget_Type *_make() {return new Fl_Menu_Button_Type();}
+  int pixmapID() { return 26; }
+};
+
+extern Fl_Menu_Item dummymenu[];
+
+#include <FL/Fl_Choice.H>
+class Fl_Choice_Type : public Fl_Menu_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Widget_Type::ideal_size(w, h);
+    int w1 = o->h() - Fl::box_dh(o->box());
+    if (w1 > 20) w1 = 20;
+    w1 = (w1 - 4) / 3;
+    if (w1 < 1) w1 = 1;
+    w += 2 * w1 + o->labelsize() - 4;
+    h = (h / 5) * 5;
+    if (h < 15) h = 15;
+    if (w < (15 + h)) w = 15 + h;
+  }
+  virtual const char *type_name() {return "Fl_Choice";}
+  Fl_Widget *widget(int X,int Y,int W,int H) {
+    Fl_Choice *myo = new Fl_Choice(X,Y,W,H,"choice:");
+    myo->menu(dummymenu);
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Choice_Type();}
+  int pixmapID() { return 15; }
+};
+
+#include <FL/Fl_Input_Choice.H>
+class Fl_Input_Choice_Type : public Fl_Menu_Type {
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+    Fl_Input_Choice *myo = (Fl_Input_Choice*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+    switch (w) {
+    case 4:
+    case 0: f = (Fl_Font)myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+    }
+    return 1;
+  }
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Input_Choice *myo = (Fl_Input_Choice *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h = fl_height() + myo->textsize() - 6;
+    w = o->w() - 20 - Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + 20 + Fl::box_dw(o->box());
+    if (h < 15) h = 15;
+    if (w < (15 + h)) w = 15 + h;
+  }
+  virtual const char *type_name() {return "Fl_Input_Choice";}
+  virtual Fl_Type* click_test(int,int);
+  Fl_Widget *widget(int X,int Y,int W,int H) {
+    Fl_Input_Choice *myo = new Fl_Input_Choice(X,Y,W,H,"input choice:");
+    myo->menu(dummymenu);
+    myo->value("input");
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Input_Choice_Type();}
+  virtual void build_menu();
+  int pixmapID() { return 15; }
+  void copy_properties();
+};
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Menu_Bar.H>
+class Fl_Menu_Bar_Type : public Fl_Menu_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    w = o->window()->w();
+    h = ((o->labelsize() + Fl::box_dh(o->box()) + 4) / 5) * 5;
+    if (h < 15) h = 15;
+  }
+  virtual const char *type_name() {return "Fl_Menu_Bar";}
+  Fl_Widget *widget(int X,int Y,int W,int H) {return new Fl_Menu_Bar(X,Y,W,H);}
+  Fl_Widget_Type *_make() {return new Fl_Menu_Bar_Type();}
+  int pixmapID() { return 17; }
+};
+// object list operations:
+Fl_Widget *make_widget_browser(int X,int Y,int W,int H);
+extern int modflag;
+void delete_all(int selected_only=0);
+void selection_changed(Fl_Type* new_current);
+
+// file operations:
+#  ifdef __GNUC__
+#    define __fl_attr(x) __attribute__ (x)
+#  else
+#    define __fl_attr(x)
+#  endif // __GNUC__
+
+void write_word(const char *);
+void write_string(const char *,...) __fl_attr((__format__ (__printf__, 1, 2)));
+int write_file(const char *, int selected_only = 0);
+int write_code(const char *cfile, const char *hfile);
+int write_strings(const char *sfile);
+
+int write_declare(const char *, ...) __fl_attr((__format__ (__printf__, 1, 2)));
+int is_id(char);
+const char* unique_id(void* o, const char*, const char*, const char*);
+void write_c(const char*, ...) __fl_attr((__format__ (__printf__, 1, 2)));
+void write_h(const char*, ...) __fl_attr((__format__ (__printf__, 1, 2)));
+void write_cstring(const char *);
+void write_cstring(const char *,int length);
+void write_cdata(const char *,int length);
+void write_indent(int n);
+void write_open(int);
+void write_close(int n);
+extern int write_number;
+extern int write_sourceview;
+void write_public(int state); // writes pubic:/private: as needed
+extern int indentation;
+extern const char* indent();
+
+int read_file(const char *, int merge);
+const char *read_word(int wantbrace = 0);
+void read_error(const char *format, ...);
+
+// check legality of c code (sort of) and return error:
+const char *c_check(const char *c, int type = 0);
+
+// replace a string pointer with new value, strips leading/trailing blanks:
+int storestring(const char *n, const char * & p, int nostrip=0);
+
+extern int include_H_from_C;
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Widget_Type.cxx b/Utilities/FLTK/fluid/Fl_Widget_Type.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3cd8e1a3427b2d6a0e78a7bd3ae043c00d24021e
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Widget_Type.cxx
@@ -0,0 +1,2537 @@
+//
+// "$Id$"
+//
+// Widget type code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Input.H>
+#include "Fl_Widget_Type.h"
+#include "alignment_panel.h"
+#include <FL/fl_message.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Window.H>
+#include "../src/flstring.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+// Make an Fl_Widget_Type subclass instance.
+// It figures out the automatic size and parent of the new widget,
+// creates the Fl_Widget (by calling the virtual function _make),
+// adds it to the Fl_Widget hierarchy, creates a new Fl_Type
+// instance, sets the widget pointers, and makes all the display
+// update correctly...
+
+extern int reading_file;
+int force_parent;
+extern int gridx;
+extern int gridy;
+extern int i18n_type;
+extern const char* i18n_include;
+extern const char* i18n_function;
+extern const char* i18n_file;
+extern const char* i18n_set;
+
+int Fl_Widget_Type::default_size = FL_NORMAL_SIZE;
+
+int Fl_Widget_Type::is_widget() const {return 1;}
+int Fl_Widget_Type::is_public() const {return public_;}
+
+const char* subclassname(Fl_Type* l) {
+  if (l->is_widget()) {
+    Fl_Widget_Type* p = (Fl_Widget_Type*)l;
+    const char* c = p->subclass();
+    if (c) return c;
+    if (l->is_class()) return "Fl_Group";
+    if (p->o->type() == FL_WINDOW+1) return "Fl_Double_Window";
+  }
+  return l->type_name();
+}
+
+// Return the ideal widget size...
+void
+Fl_Widget_Type::ideal_size(int &w, int &h) {
+  h = o->labelsize();
+  o->measure_label(w, h);
+
+  w += Fl::box_dw(o->box());
+  h += Fl::box_dh(o->box());
+
+  if (w < 15) w = 15;
+  if (h < 15) h = 15;
+}
+
+// Return the ideal widget spacing...
+void
+Fl_Widget_Type::ideal_spacing(int &x, int &y) {
+  if (o->labelsize() < 10)
+    x = y = 0;
+  else if (o->labelsize() < 14)
+    x = y = 5;
+  else
+    x = y = 10;
+}
+
+Fl_Type *Fl_Widget_Type::make() {
+  // Find the current widget, or widget to copy:
+  Fl_Type *qq = Fl_Type::current;
+  while (qq && (!qq->is_widget() || qq->is_menu_item())) qq = qq->parent;
+  if (!qq) {
+    fl_message("Please select a widget");
+    return 0;
+  }
+  Fl_Widget_Type* q = (Fl_Widget_Type*)qq;
+  // find the parent widget:
+  Fl_Widget_Type* p = q;
+  if ((force_parent || !p->is_group()) && p->parent->is_widget())
+    p = (Fl_Widget_Type*)(p->parent);
+  force_parent = 0;
+
+  // Figure out a border between widget and window:
+  int B = p->o->w()/2; if (p->o->h()/2 < B) B = p->o->h()/2; if (B>25) B = 25;
+
+  int ULX,ULY; // parent's origin in window
+  if (!p->is_window()) { // if it is a group, add corner
+    ULX = p->o->x(); ULY = p->o->y();
+  } else {
+    ULX = ULY = 0;
+  }
+
+  // Figure out a position and size for the widget
+  int X,Y,W,H;
+  if (is_group()) {	// fill the parent with the widget
+    X = ULX+B;
+    W = p->o->w()-B;
+    Y = ULY+B;
+    H = p->o->h()-B;
+  } else if (q != p) {	// copy position and size of current widget
+    W = q->o->w();
+    H = q->o->h();
+    X = q->o->x()+W;
+    Y = q->o->y();
+    if (X+W > ULX+p->o->w()) {
+      X = q->o->x();
+      Y = q->o->y()+H;
+      if (Y+H > ULY+p->o->h()) Y = ULY+B;
+    }
+  } else {	// just make it small and square...
+    X = ULX+B;
+    Y = ULY+B;
+    W = H = B;
+  }
+
+  // satisfy the grid requirements (otherwise it edits really strangely):
+  if (gridx>1) {
+    X = (X/gridx)*gridx;
+    W = ((W-1)/gridx+1)*gridx;
+  }
+  if (gridy>1) {
+    Y = (Y/gridy)*gridy;
+    H = ((H-1)/gridy+1)*gridy;
+  }
+
+  // Construct the Fl_Type:
+  Fl_Widget_Type *t = _make();
+  if (!o) o = widget(0,0,100,100); // create template widget
+  t->factory = this;
+  // Construct the Fl_Widget:
+  t->o = widget(X,Y,W,H);
+  if (reading_file) t->o->label(0);
+  else if (t->o->label()) t->label(t->o->label()); // allow editing
+  t->o->user_data((void*)t);
+  // Put it in the parent:
+  //  ((Fl_Group *)(p->o))->add(t->o); (done by Fl_Type::add())
+  // add to browser:
+  t->add(p);
+  t->redraw();
+  return t;
+}
+
+#include "Fluid_Image.h"
+
+void Fl_Widget_Type::setimage(Fluid_Image *i) {
+  if (i == image || is_window()) return;
+  if (image) image->decrement();
+  if (i) i->increment();
+  image = i;
+  if (i) i->image(o);
+  else o->image(0);
+  redraw();
+}
+
+void Fl_Widget_Type::setinactive(Fluid_Image *i) {
+  if (i == inactive || is_window()) return;
+  if (inactive) inactive->decrement();
+  if (i) i->increment();
+  inactive = i;
+  if (i) i->deimage(o);
+  else o->deimage(0);
+  redraw();
+}
+
+void Fl_Widget_Type::setlabel(const char *n) {
+  o->label(n);
+  redraw();
+}
+
+Fl_Widget_Type::Fl_Widget_Type() {
+  for (int n=0; n<NUM_EXTRA_CODE; n++) {extra_code_[n] = 0; subclass_ = 0;}
+  hotspot_ = 0;
+  tooltip_ = 0;
+  image_name_ = 0;
+  inactive_name_ = 0;
+  image = 0;
+  inactive = 0;
+  xclass = 0;
+  o = 0;
+  public_ = 1;
+}
+
+Fl_Widget_Type::~Fl_Widget_Type() {
+  if (o) {
+    o->hide();
+    if (o->parent()) ((Fl_Group*)o->parent())->remove(*o);
+    delete o;
+  }
+}
+
+void Fl_Widget_Type::extra_code(int m,const char *n) {
+  storestring(n,extra_code_[m]);
+}
+
+extern void redraw_browser();
+void Fl_Widget_Type::subclass(const char *n) {
+  if (storestring(n,subclass_) && visible)
+    redraw_browser();
+}
+
+void Fl_Widget_Type::tooltip(const char *n) {
+  storestring(n,tooltip_);
+  o->tooltip(n);
+}
+
+void Fl_Widget_Type::image_name(const char *n) {
+  setimage(Fluid_Image::find(n));
+  storestring(n,image_name_);
+}
+
+void Fl_Widget_Type::inactive_name(const char *n) {
+  setinactive(Fluid_Image::find(n));
+  storestring(n,inactive_name_);
+}
+
+void Fl_Widget_Type::redraw() {
+  Fl_Type *t = this;
+  if (is_menu_item()) {
+    // find the menu button that parents this menu:
+    do t = t->parent; while (t && t->is_menu_item());
+    // kludge to cause build_menu to be called again:
+    t->add_child(0,0);
+  } else {
+    while (t->parent && t->parent->is_widget()) t = t->parent;
+    ((Fl_Widget_Type*)t)->o->redraw();
+  }
+}
+
+// the recursive part sorts all children, returns pointer to next:
+Fl_Type *sort(Fl_Type *parent) {
+  Fl_Type *f,*n=0;
+  for (f = parent ? parent->next : Fl_Type::first; ; f = n) {
+    if (!f || parent && f->level <= parent->level) return f;
+    n = sort(f);
+    if (!f->selected || (!f->is_widget() || f->is_menu_item())) continue;
+    Fl_Widget* fw = ((Fl_Widget_Type*)f)->o;
+    Fl_Type *g; // we will insert before this
+    for (g = parent->next; g != f; g = g->next) {
+      if (!g->selected || g->level > f->level) continue;
+      Fl_Widget* gw = ((Fl_Widget_Type*)g)->o;
+      if (gw->y() > fw->y()) break;
+      if (gw->y() == fw->y() && gw->x() > fw->x()) break;
+    }
+    if (g != f) f->move_before(g);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+// The control panels!
+
+#include "widget_panel.h"
+#include <FL/fl_show_colormap.H>
+
+static Fl_Window *the_panel;
+
+// All the callbacks use the argument to indicate whether to load or store.
+// This avoids the need for pointers to all the widgets, and keeps the
+// code localized in the callbacks.
+// A value of LOAD means to load.  The hope is that this will not collide
+// with any actual useful values for the argument.  I also use this to
+// initialized parts of the widget that are nyi by fluid.
+
+Fl_Widget_Type *current_widget; // one of the selected ones
+static int numselected; // number selected
+static int haderror;
+
+void name_cb(Fl_Input* o, void *v) {
+  if (v == LOAD) {
+    static char buf[1024];
+    if (numselected != 1) {
+      snprintf(buf, sizeof(buf), "Widget Properties (%d widgets)", numselected);
+      o->hide();
+    } else {
+      o->static_value(current_widget->name());
+      o->show();
+      snprintf(buf, sizeof(buf), "%s Properties", current_widget->title());
+    }
+
+    the_panel->label(buf);
+  } else {
+    if (numselected == 1) {
+      current_widget->name(o->value());
+      // I don't update window title, as it probably is being closed
+      // and wm2 (a window manager) barfs if you retitle and then
+      // hide a window:
+      // ((Fl_Window*)(o->parent()->parent()->parent()))->label(current_widget->title());
+    }
+  }
+}
+
+void name_public_cb(Fl_Light_Button* i, void* v) {
+  if (v == LOAD) {
+    i->value(current_widget->public_);
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	((Fl_Widget_Type*)o)->public_ = i->value();
+	mod = 1;
+      }
+    }
+    if (mod) {
+      set_modflag(1);
+      redraw_browser();
+    }
+  }
+}    
+
+static char* oldlabel;
+static unsigned oldlabellen;
+
+void label_cb(Fl_Input* i, void *v) {
+  if (v == LOAD) {
+    i->static_value(current_widget->label());
+    if (strlen(i->value()) >= oldlabellen) {
+      oldlabellen = strlen(i->value())+128;
+      oldlabel = (char*)realloc(oldlabel,oldlabellen);
+    }
+    strcpy(oldlabel,i->value());
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        o->label(i->value());
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+static Fl_Input *image_input;
+
+void image_cb(Fl_Input* i, void *v) {
+  if (v == LOAD) {
+    image_input = i;
+    if (current_widget->is_widget() && !current_widget->is_window()) {
+      i->activate();
+      i->static_value(((Fl_Widget_Type*)current_widget)->image_name());
+    } else i->deactivate();
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        ((Fl_Widget_Type*)o)->image_name(i->value());
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void image_browse_cb(Fl_Button* b, void *v) {
+  if (v == LOAD) {
+    if (current_widget->is_widget() && !current_widget->is_window())
+      b->activate();
+    else 
+      b->deactivate();
+  } else {
+    int mod = 0;
+    if (ui_find_image(image_input->value())) {
+      image_input->value(ui_find_image_name);
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+	if (o->selected && o->is_widget()) {
+	  ((Fl_Widget_Type*)o)->image_name(ui_find_image_name);
+	  mod = 1;
+	}
+      }
+      if (mod) set_modflag(1);
+    }
+  }
+}
+
+static Fl_Input *inactive_input;
+
+void inactive_cb(Fl_Input* i, void *v) {
+  if (v == LOAD) {
+    inactive_input = i;
+    if (current_widget->is_widget() && !current_widget->is_window()) {
+      i->activate();
+      i->static_value(((Fl_Widget_Type*)current_widget)->inactive_name());
+    } else i->deactivate();
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        ((Fl_Widget_Type*)o)->inactive_name(i->value());
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void inactive_browse_cb(Fl_Button* b, void *v) {
+  if (v == LOAD) {
+    if (current_widget->is_widget() && !current_widget->is_window()) 
+      b->activate();
+    else 
+      b->deactivate();
+  } else {
+    int mod = 0;
+    if (ui_find_image(inactive_input->value())) {
+      inactive_input->value(ui_find_image_name);
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+	if (o->selected && o->is_widget()) {
+	  ((Fl_Widget_Type*)o)->inactive_name(ui_find_image_name);
+	  mod = 1;
+	}
+      }
+      if (mod) set_modflag(1);
+    }
+  }
+}
+
+void tooltip_cb(Fl_Input* i, void *v) {
+  if (v == LOAD) {
+    if (current_widget->is_widget()) {
+      i->activate();
+      i->static_value(((Fl_Widget_Type*)current_widget)->tooltip());
+    } else i->deactivate();
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        ((Fl_Widget_Type*)o)->tooltip(i->value());
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+Fl_Value_Input *x_input, *y_input, *w_input, *h_input;
+
+void x_cb(Fl_Value_Input *i, void *v) {
+  if (v == LOAD) {
+    x_input = i;
+    if (current_widget->is_widget()) {
+      i->value(((Fl_Widget_Type *)current_widget)->o->x());
+      x_input->activate();
+    } else x_input->deactivate();
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	w->resize((int)i->value(), w->y(), w->w(), w->h());
+	if (w->window()) w->window()->redraw();
+	if (o->is_window()) {
+          ((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
+                                       gridx, gridy, 0);
+	}
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void y_cb(Fl_Value_Input *i, void *v) {
+  if (v == LOAD) {
+    y_input = i;
+    if (current_widget->is_widget()) {
+      i->value(((Fl_Widget_Type *)current_widget)->o->y());
+      y_input->activate();
+    } else y_input->deactivate();
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	w->resize(w->x(), (int)i->value(), w->w(), w->h());
+	if (w->window()) w->window()->redraw();
+	if (o->is_window()) {
+          ((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
+                                       gridx, gridy, 0);
+	}
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void w_cb(Fl_Value_Input *i, void *v) {
+  if (v == LOAD) {
+    w_input = i;
+    if (current_widget->is_widget()) {
+      i->value(((Fl_Widget_Type *)current_widget)->o->w());
+      w_input->activate();
+    } else w_input->deactivate();
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	w->resize(w->x(), w->y(), (int)i->value(), w->h());
+	if (w->window()) w->window()->redraw();
+	if (o->is_window()) {
+          ((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
+                                       gridx, gridy, 0);
+	}
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void h_cb(Fl_Value_Input *i, void *v) {
+  if (v == LOAD) {
+    h_input = i;
+    if (current_widget->is_widget()) {
+      i->value(((Fl_Widget_Type *)current_widget)->o->h());
+      h_input->activate();
+    } else h_input->deactivate();
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	w->resize(w->x(), w->y(), w->w(), (int)i->value());
+	if (w->window()) w->window()->redraw();
+	if (o->is_window()) {
+          ((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
+                                       gridx, gridy, 0);
+	}
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void wc_relative_cb(Fl_Light_Button *i, void *v) {
+  if (v == LOAD) {
+    if (!strcmp(current_widget->type_name(), "widget_class")) {
+      i->show();
+      i->value(((Fl_Widget_Class_Type *)current_widget)->wc_relative);
+    } else {
+      i->hide();
+    }
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && !strcmp(current_widget->type_name(), "widget_class")) {
+        Fl_Widget_Class_Type *t = (Fl_Widget_Class_Type *)o;
+        t->wc_relative = i->value();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// turn number to string or string to number for saving to file:
+// does not work for hierarchial menus!
+
+const char *item_name(Fl_Menu_Item* m, int i) {
+  if (m) {
+    while (m->label()) {
+      if (m->argument() == i) return m->label();
+      m++;
+    }
+  }
+  static char buffer[20];
+  sprintf(buffer, "%d", i);
+  return buffer;
+}
+int item_number(Fl_Menu_Item* m, const char* i) {
+  if (m && i) {
+    if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
+    while (m->label()) {
+      if (!strcmp(m->label(), i)) return int(m->argument());
+      m++;
+    }
+  }
+  return atoi(i);
+}
+
+#define ZERO_ENTRY 1000
+
+Fl_Menu_Item boxmenu[] = {
+{"NO_BOX",0,0,(void *)ZERO_ENTRY},
+{"boxes",0,0,0,FL_SUBMENU},
+{"UP_BOX",0,0,(void *)FL_UP_BOX},
+{"DOWN_BOX",0,0,(void *)FL_DOWN_BOX},
+{"FLAT_BOX",0,0,(void *)FL_FLAT_BOX},
+{"BORDER_BOX",0,0,(void *)FL_BORDER_BOX},
+{"THIN_UP_BOX",0,0,(void *)FL_THIN_UP_BOX},
+{"THIN_DOWN_BOX",0,0,(void *)FL_THIN_DOWN_BOX},
+{"ENGRAVED_BOX",0,0,(void *)FL_ENGRAVED_BOX},
+{"EMBOSSED_BOX",0,0,(void *)FL_EMBOSSED_BOX},
+{"ROUND_UP_BOX",0,0,(void *)FL_ROUND_UP_BOX},
+{"ROUND_DOWN_BOX",0,0,(void *)FL_ROUND_DOWN_BOX},
+{"DIAMOND_UP_BOX",0,0,(void *)FL_DIAMOND_UP_BOX},
+{"DIAMOND_DOWN_BOX",0,0,(void *)FL_DIAMOND_DOWN_BOX},
+{"SHADOW_BOX",0,0,(void *)FL_SHADOW_BOX},
+{"ROUNDED_BOX",0,0,(void *)FL_ROUNDED_BOX},
+{"RSHADOW_BOX",0,0,(void *)FL_RSHADOW_BOX},
+{"RFLAT_BOX",0,0,(void *)FL_RFLAT_BOX},
+{"OVAL_BOX",0,0,(void *)FL_OVAL_BOX},
+{"OSHADOW_BOX",0,0,(void *)FL_OSHADOW_BOX},
+{"OFLAT_BOX",0,0,(void *)FL_OFLAT_BOX},
+{"PLASTIC_UP_BOX",0,0,(void *)FL_PLASTIC_UP_BOX},
+{"PLASTIC_DOWN_BOX",0,0,(void *)FL_PLASTIC_DOWN_BOX},
+{"PLASTIC_THIN_UP_BOX",0,0,(void *)FL_PLASTIC_THIN_UP_BOX},
+{"PLASTIC_THIN_DOWN_BOX",0,0,(void *)FL_PLASTIC_THIN_DOWN_BOX},
+{0},
+{"frames",0,0,0,FL_SUBMENU},
+{"UP_FRAME",0,0,(void *)FL_UP_FRAME},
+{"DOWN_FRAME",0,0,(void *)FL_DOWN_FRAME},
+{"THIN_UP_FRAME",0,0,(void *)FL_THIN_UP_FRAME},
+{"THIN_DOWN_FRAME",0,0,(void *)FL_THIN_DOWN_FRAME},
+{"ENGRAVED_FRAME",0,0,(void *)FL_ENGRAVED_FRAME},
+{"EMBOSSED_FRAME",0,0,(void *)FL_EMBOSSED_FRAME},
+{"BORDER_FRAME",0,0,(void *)FL_BORDER_FRAME},
+{"SHADOW_FRAME",0,0,(void *)FL_SHADOW_FRAME},
+{"ROUNDED_FRAME",0,0,(void *)FL_ROUNDED_FRAME},
+{"OVAL_FRAME",0,0,(void *)FL_OVAL_FRAME},
+{"PLASTIC_UP_FRAME",0,0,(void *)FL_PLASTIC_UP_FRAME},
+{"PLASTIC_DOWN_FRAME",0,0,(void *)FL_PLASTIC_DOWN_FRAME},
+{0},
+{0}};
+
+const char *boxname(int i) {
+  if (!i) i = ZERO_ENTRY;
+  for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+    if (boxmenu[j].argument() == i) return boxmenu[j].label();
+  return 0;
+}
+
+int boxnumber(const char *i) {
+  if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
+  for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+    if (boxmenu[j].label() && !strcmp(boxmenu[j].label(), i)) {
+      return int(boxmenu[j].argument());
+    }
+  return 0;
+}
+
+void box_cb(Fl_Choice* i, void *v) {
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate();
+    int n = current_widget->o->box(); if (!n) n = ZERO_ENTRY;
+    for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+      if (boxmenu[j].argument() == n) {i->value(j); break;}
+  } else {
+    int mod = 0;
+    int m = i->value();
+    int n = int(boxmenu[m].argument());
+    if (!n) return; // should not happen
+    if (n == ZERO_ENTRY) n = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+        q->o->box((Fl_Boxtype)n);
+        q->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void down_box_cb(Fl_Choice* i, void *v) {
+  if (v == LOAD) {
+    int n;
+    if (current_widget->is_button() && !current_widget->is_menu_item())
+      n = ((Fl_Button*)(current_widget->o))->down_box();
+    else if (!strcmp(current_widget->type_name(), "Fl_Input_Choice"))
+      n = ((Fl_Input_Choice*)(current_widget->o))->down_box();
+    else if (current_widget->is_menu_button())
+      n = ((Fl_Menu_*)(current_widget->o))->down_box();
+    else {
+      i->deactivate(); return;
+    }
+    i->activate();
+    if (!n) n = ZERO_ENTRY;
+    for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+      if (boxmenu[j].argument() == n) {i->value(j); break;}
+  } else {
+    int mod = 0;
+    int m = i->value();
+    int n = int(boxmenu[m].argument());
+    if (!n) return; // should not happen
+    if (n == ZERO_ENTRY) n = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected) {
+	if (o->is_button() && !o->is_menu_item()) {
+	  Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+          ((Fl_Button*)(q->o))->down_box((Fl_Boxtype)n);
+          if (((Fl_Button*)(q->o))->value()) q->redraw();
+	} else if (!strcmp(o->type_name(), "Fl_Input_Choice")) {
+	  Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	  ((Fl_Input_Choice*)(q->o))->down_box((Fl_Boxtype)n);
+	} else if (o->is_menu_button()) {
+	  Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+          ((Fl_Menu_*)(q->o))->down_box((Fl_Boxtype)n);
+	}
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item whenmenu[] = {
+  {"Never",0,0,(void*)ZERO_ENTRY},
+  {"Release",0,0,(void*)FL_WHEN_RELEASE},
+  {"Changed",0,0,(void*)FL_WHEN_CHANGED},
+  {"Enter key",0,0,(void*)FL_WHEN_ENTER_KEY},
+  //{"Release or Enter",0,0,(void*)(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE)},
+  {0}};
+
+static Fl_Menu_Item whensymbolmenu[] = {
+  {"FL_WHEN_NEVER",0,0,(void*)(FL_WHEN_NEVER)},
+  {"FL_WHEN_CHANGED",0,0,(void*)(FL_WHEN_CHANGED)},
+  {"FL_WHEN_RELEASE",0,0,(void*)(FL_WHEN_RELEASE)},
+  {"FL_WHEN_RELEASE_ALWAYS",0,0,(void*)(FL_WHEN_RELEASE_ALWAYS)},
+  {"FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_ENTER_KEY)},
+  {"FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)(FL_WHEN_ENTER_KEY_ALWAYS)},
+  {0}};
+
+void when_cb(Fl_Choice* i, void *v) {
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate();
+    int n = current_widget->o->when() & (~FL_WHEN_NOT_CHANGED);
+    if (!n) n = ZERO_ENTRY;
+    for (int j = 0; j < int(sizeof(whenmenu)/sizeof(*whenmenu)); j++)
+      if (whenmenu[j].argument() == n) {i->value(j); break;}
+  } else {
+    int mod = 0;
+    int m = i->value();
+    int n = int(whenmenu[m].argument());
+    if (!n) return; // should not happen
+    if (n == ZERO_ENTRY) n = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->o->when(n|(q->o->when()&FL_WHEN_NOT_CHANGED));
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void when_button_cb(Fl_Light_Button* i, void *v) {
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate();
+    i->value(current_widget->o->when()&FL_WHEN_NOT_CHANGED);
+  } else {
+    int mod = 0;
+    int n = i->value() ? FL_WHEN_NOT_CHANGED : 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->o->when(n|(q->o->when()&~FL_WHEN_NOT_CHANGED));
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+uchar Fl_Widget_Type::resizable() const {
+  if (is_window()) return ((Fl_Window*)o)->resizable() != 0;
+  Fl_Group* p = (Fl_Group*)o->parent();
+  if (p) return p->resizable() == o;
+  else return 0;
+}
+
+void Fl_Widget_Type::resizable(uchar v) {
+  if (v) {
+    if (resizable()) return;
+    if (is_window()) ((Fl_Window*)o)->resizable(o);
+    else {
+      Fl_Group* p = (Fl_Group*)o->parent();
+      if (p) p->resizable(o);
+    }
+  } else {
+    if (!resizable()) return;
+    if (is_window()) {
+      ((Fl_Window*)o)->resizable(0);
+    } else {
+      Fl_Group* p = (Fl_Group*)o->parent();
+      if (p) p->resizable(0);
+    }
+  }
+}
+
+void resizable_cb(Fl_Light_Button* i,void* v) {
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;}
+    if (numselected > 1) {i->deactivate(); return;}
+    i->activate();
+    i->value(current_widget->resizable());
+  } else {
+    current_widget->resizable(i->value());
+    set_modflag(1);
+  }
+}
+
+void hotspot_cb(Fl_Light_Button* i,void* v) {
+  if (v == LOAD) {
+    if (numselected > 1) {i->deactivate(); return;}
+    if (current_widget->is_menu_item()) i->label("divider");
+    else i->label("hotspot");
+    i->activate();
+    i->value(current_widget->hotspot());
+  } else {
+    current_widget->hotspot(i->value());
+    if (current_widget->is_menu_item()) {current_widget->redraw(); return;}
+    if (i->value()) {
+      Fl_Type *p = current_widget->parent;
+      if (!p || !p->is_widget()) return;
+      while (!p->is_window()) p = p->parent;
+      for (Fl_Type *o = p->next; o && o->level > p->level; o = o->next) {
+	if (o->is_widget() && o != current_widget)
+	  ((Fl_Widget_Type*)o)->hotspot(0);
+      }
+    }
+    set_modflag(1);
+  }
+}
+
+void visible_cb(Fl_Light_Button* i, void* v) {
+  if (v == LOAD) {
+    i->value(current_widget->o->visible());
+    if (current_widget->is_window()) i->deactivate();
+    else i->activate();
+  } else {
+    int mod = 0;
+    int n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	n ? q->o->show() : q->o->hide();
+	q->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void active_cb(Fl_Light_Button* i, void* v) {
+  if (v == LOAD) {
+    i->value(current_widget->o->active());
+    if (current_widget->is_window()) i->deactivate();
+    else i->activate();
+  } else {
+    int mod = 0;
+    int n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	n ? q->o->activate() : q->o->deactivate();
+	q->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item fontmenu[] = {
+{"Helvetica"},
+{"Helvetica bold"},
+{"Helvetica italic"},
+{"Helvetica bold italic"},
+{"Courier"},
+{"Courier bold"},
+{"Courier italic"},
+{"Courier bold italic"},
+{"Times"},
+{"Times bold"},
+{"Times italic"},
+{"Times bold italic"},
+{"Symbol"},
+{"Terminal"},
+{"Terminal Bold"},
+{"Zapf Dingbats"},
+{0}};
+
+void labelfont_cb(Fl_Choice* i, void *v) {
+  if (v == LOAD) {
+    int n = current_widget->o->labelfont();
+    if (n > 15) n = 0;
+    i->value(n);
+  } else {
+    int mod = 0;
+    int n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->o->labelfont(n);
+	q->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void labelsize_cb(Fl_Value_Input* i, void *v) {
+  int n;
+  if (v == LOAD) {
+    n = current_widget->o->labelsize();
+  } else {
+    int mod = 0;
+    n = int(i->value());
+    if (n <= 0) n = Fl_Widget_Type::default_size;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->o->labelsize(n);
+	q->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+  i->value(n);
+}
+
+extern const char *ui_find_image_name;
+
+Fl_Menu_Item labeltypemenu[] = {
+  {"NORMAL_LABEL",0,0,(void*)0},
+  {"SHADOW_LABEL",0,0,(void*)FL_SHADOW_LABEL},
+  {"ENGRAVED_LABEL",0,0,(void*)FL_ENGRAVED_LABEL},
+  {"EMBOSSED_LABEL",0,0,(void*)FL_EMBOSSED_LABEL},
+  {"NO_LABEL",0,0,(void*)(FL_NO_LABEL)},
+{0}};
+
+void labeltype_cb(Fl_Choice* i, void *v) {
+  if (v == LOAD) {
+    int n;
+    n = current_widget->o->labeltype();
+    i->when(FL_WHEN_RELEASE);
+    for (int j = 0; j < int(sizeof(labeltypemenu)/sizeof(*labeltypemenu)); j++)
+      if (labeltypemenu[j].argument() == n) {i->value(j); break;}
+  } else {
+    int mod = 0;
+    int m = i->value();
+    int n = int(labeltypemenu[m].argument());
+    if (n<0) return; // should not happen
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* p = (Fl_Widget_Type*)o;
+	p->o->labeltype((Fl_Labeltype)n);
+	p->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+void color_cb(Fl_Button* i, void *v) {
+  Fl_Color c = current_widget->o->color();
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate();
+  } else {
+    int mod = 0;
+    Fl_Color d = fl_show_colormap(c);
+    if (d == c) return;
+    c = d;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->o->color(c); q->o->redraw();
+        if (q->parent && q->parent->type_name() == tabs_type_name) {
+          if (q->o->parent()) q->o->parent()->redraw();
+        }
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+  i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
+}
+
+void color2_cb(Fl_Button* i, void *v) {
+  Fl_Color c = current_widget->o->selection_color();
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate();
+  } else {
+    int mod = 0;
+    Fl_Color d = fl_show_colormap(c);
+    if (d == c) return;
+    c = d;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->o->selection_color(c); q->o->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+  i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
+}
+
+void labelcolor_cb(Fl_Button* i, void *v) {
+  Fl_Color c = current_widget->o->labelcolor();
+  if (v != LOAD) {
+    int mod = 0;
+    Fl_Color d = fl_show_colormap(c);
+    if (d == c) return;
+    c = d;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->o->labelcolor(c); q->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+  i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
+}
+
+static Fl_Button* relative(Fl_Widget* o, int i) {
+  Fl_Group* g = (Fl_Group*)(o->parent());
+  return (Fl_Button*)(g->child(g->find(*o)+i));
+}
+
+static Fl_Menu_Item alignmenu[] = {
+  {"FL_ALIGN_CENTER",0,0,(void*)(FL_ALIGN_CENTER)},
+  {"FL_ALIGN_TOP",0,0,(void*)(FL_ALIGN_TOP)},
+  {"FL_ALIGN_BOTTOM",0,0,(void*)(FL_ALIGN_BOTTOM)},
+  {"FL_ALIGN_LEFT",0,0,(void*)(FL_ALIGN_LEFT)},
+  {"FL_ALIGN_RIGHT",0,0,(void*)(FL_ALIGN_RIGHT)},
+  {"FL_ALIGN_INSIDE",0,0,(void*)(FL_ALIGN_INSIDE)},
+  {"FL_ALIGN_CLIP",0,0,(void*)(FL_ALIGN_CLIP)},
+  {"FL_ALIGN_WRAP",0,0,(void*)(FL_ALIGN_WRAP)},
+  {"FL_ALIGN_TEXT_OVER_IMAGE",0,0,(void*)(FL_ALIGN_TEXT_OVER_IMAGE)},
+  {"FL_ALIGN_TOP_LEFT",0,0,(void*)(FL_ALIGN_TOP_LEFT)},
+  {"FL_ALIGN_TOP_RIGHT",0,0,(void*)(FL_ALIGN_TOP_RIGHT)},
+  {"FL_ALIGN_BOTTOM_LEFT",0,0,(void*)(FL_ALIGN_BOTTOM_LEFT)},
+  {"FL_ALIGN_BOTTOM_RIGHT",0,0,(void*)(FL_ALIGN_BOTTOM_RIGHT)},
+  {"FL_ALIGN_LEFT_TOP",0,0,(void*)(FL_ALIGN_LEFT_TOP)},
+  {"FL_ALIGN_RIGHT_TOP",0,0,(void*)(FL_ALIGN_RIGHT_TOP)},
+  {"FL_ALIGN_LEFT_BOTTOM",0,0,(void*)(FL_ALIGN_LEFT_BOTTOM)},
+  {"FL_ALIGN_RIGHT_BOTTOM",0,0,(void*)(FL_ALIGN_RIGHT_BOTTOM)},
+{0}};
+
+void align_cb(Fl_Button* i, void *v) {
+  int b = int(long(i->user_data()));
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate();
+    i->value(current_widget->o->align() & b);
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	int x = q->o->align();
+	int y;
+	if (i->value()) {
+	  y = x | b;
+	  if (b == FL_ALIGN_LEFT || b == FL_ALIGN_TOP) {
+	    Fl_Button *b1 = relative(i,+1);
+	    b1->clear();
+	    y = y & ~(b1->argument());
+	  }
+	  if (b == FL_ALIGN_RIGHT || b == FL_ALIGN_BOTTOM) {
+	    Fl_Button *b1 = relative(i,-1);
+	    b1->clear();
+	    y = y & ~(b1->argument());
+	  }
+	} else {
+	  y = x & ~b;
+	}
+	if (x != y) {
+          q->o->align(y);
+	  q->redraw();
+	  mod = 1;
+	}
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+void callback_cb(CodeEditor* i, void *v) {
+  if (v == LOAD) {
+    const char *cbtext = current_widget->callback();
+    i->buffer()->text( cbtext ? cbtext : "" );
+  } else {
+    int mod = 0;
+    char *c = i->buffer()->text();
+    const char *d = c_check(c);
+    if (d) {
+      fl_message("Error in callback: %s",d);
+      if (i->window()) i->window()->make_current();
+      haderror = 1;
+    }
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected) {
+        o->callback(c);
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+    free(c);
+  }
+}
+
+void user_data_cb(Fl_Input *i, void *v) {
+  if (v == LOAD) {
+    i->static_value(current_widget->user_data());
+  } else {
+    int mod = 0;
+    const char *c = i->value();
+    const char *d = c_check(c);
+    if (d) {fl_message("Error in user_data: %s",d); haderror = 1; return;}
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected) {
+        o->user_data(c);
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void user_data_type_cb(Fl_Input *i, void *v) {
+  static const char *dflt = "void*";
+  if (v == LOAD) {
+    const char *c = current_widget->user_data_type();
+    if (!c) c = dflt;
+    i->static_value(c);
+  } else {
+    int mod = 0;
+    const char *c = i->value();
+    const char *d = c_check(c);
+    if (!*c) i->value(dflt);
+    else if (!strcmp(c,dflt)) c = 0;
+    if (!d) {
+      if (c && *c && c[strlen(c)-1] != '*' && strcmp(c,"long"))
+	d = "must be pointer or long";
+    }
+    if (d) {fl_message("Error in type: %s",d); haderror = 1; return;}
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected) {
+        o->user_data_type(c);
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+// "v_attributes" let user type in random code for attribute settings:
+
+void v_input_cb(Fl_Input* i, void* v) {
+  int n = int(long(i->user_data()));
+  if (v == LOAD) {
+    i->static_value(current_widget->extra_code(n));
+  } else {
+    int mod = 0;
+    const char *c = i->value();
+    const char *d = c_check(c&&c[0]=='#' ? c+1 : c);
+    if (d) {fl_message("Error in %s: %s",i->label(),d); haderror = 1; return;}
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type *t = (Fl_Widget_Type*)o;
+	t->extra_code(n,c);
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void subclass_cb(Fl_Input* i, void* v) {
+  if (v == LOAD) {
+    if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate();
+    i->static_value(current_widget->subclass());
+  } else {
+    int mod = 0;
+    const char *c = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type *t = (Fl_Widget_Type*)o;
+	t->subclass(c);
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// textstuff: set textfont, textsize, textcolor attributes:
+
+// default widget returns 0 to indicate not-implemented:
+int Fl_Widget_Type::textstuff(int, Fl_Font&, int&, Fl_Color&) {return 0;}
+
+void textfont_cb(Fl_Choice* i, void* v) {
+  Fl_Font n; int s; Fl_Color c;
+  if (v == LOAD) {
+    if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
+    i->activate();
+    if (n > 15) n = FL_HELVETICA;
+    i->value(n);
+  } else {
+    int mod = 0;
+    n = (Fl_Font)i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->textstuff(1,n,s,c);
+	q->o->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void textsize_cb(Fl_Value_Input* i, void* v) {
+  Fl_Font n; int s; Fl_Color c;
+  if (v == LOAD) {
+    if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
+    i->activate();
+  } else {
+    int mod = 0;
+    s = int(i->value());
+    if (s <= 0) s = Fl_Widget_Type::default_size;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->textstuff(2,n,s,c);
+	q->o->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+  i->value(s);
+}
+
+void textcolor_cb(Fl_Button* i, void* v) {
+  Fl_Font n; int s; Fl_Color c;
+  if (v == LOAD) {
+    if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
+    i->activate();
+  } else {
+    int mod = 0;
+    c = i->color();
+    Fl_Color d = fl_show_colormap(c);
+    if (d == c) return;
+    c = d;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	q->textstuff(3,n,s,c); q->o->redraw();
+	mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+  i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
+}
+
+////////////////////////////////////////////////////////////////
+// Kludges to the panel for subclasses:
+
+void min_w_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) {i->parent()->hide(); return;}
+    i->parent()->show();
+    i->value(((Fl_Window_Type*)current_widget)->sr_min_w);
+  } else {
+    int mod = 0;
+    int n = (int)i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_window()) {
+        ((Fl_Window_Type*)current_widget)->sr_min_w = n;
+        mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void min_h_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) return;
+    i->value(((Fl_Window_Type*)current_widget)->sr_min_h);
+  } else {
+    int mod = 0;
+    int n = (int)i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_window()) {
+        ((Fl_Window_Type*)current_widget)->sr_min_h = n;
+        mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void max_w_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) return;
+    i->value(((Fl_Window_Type*)current_widget)->sr_max_w);
+  } else {
+    int mod = 0;
+    int n = (int)i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_window()) {
+        ((Fl_Window_Type*)current_widget)->sr_max_w = n;
+        mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void max_h_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) return;
+    i->value(((Fl_Window_Type*)current_widget)->sr_max_h);
+  } else {
+    int mod = 0;
+    int n = (int)i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_window()) {
+        ((Fl_Window_Type*)current_widget)->sr_max_h = n;
+        mod = 1;
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void set_min_size_cb(Fl_Button*, void* v) {
+  if (v == LOAD) {
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_window()) {
+        Fl_Window_Type *win = (Fl_Window_Type*)current_widget;
+        win->sr_min_w = win->o->w();
+        win->sr_min_h = win->o->h();
+        mod = 1;
+      }
+    }
+    propagate_load(the_panel, LOAD);
+    if (mod) set_modflag(1);
+  }
+}
+
+void set_max_size_cb(Fl_Button*, void* v) {
+  if (v == LOAD) {
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_window()) {
+        Fl_Window_Type *win = (Fl_Window_Type*)current_widget;
+        win->sr_max_w = win->o->w();
+        win->sr_max_h = win->o->h();
+        mod = 1;
+      }
+    }
+    propagate_load(the_panel, LOAD);
+    if (mod) set_modflag(1);
+  }
+}
+
+void slider_size_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (current_widget->is_window()) 
+      i->parent()->hide(); 
+    else
+      i->parent()->show();
+    if (current_widget->is_valuator()!=2) {i->deactivate(); return;}
+    i->activate();
+    i->value(((Fl_Slider*)(current_widget->o))->slider_size());
+  } else {
+    int mod = 0;
+    double n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	if (q->is_valuator()==2) {
+	  ((Fl_Slider*)(q->o))->slider_size(n);
+	  q->o->redraw();
+	  mod = 1;
+	}
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void min_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_valuator()) {i->deactivate(); return;}
+    i->activate();
+    i->value(((Fl_Valuator*)(current_widget->o))->minimum());
+  } else {
+    int mod = 0;
+    double n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	if (q->is_valuator()) {
+	  ((Fl_Valuator*)(q->o))->minimum(n);
+	  q->o->redraw();
+	  mod = 1;
+	}
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void max_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_valuator()) {i->deactivate(); return;}
+    i->activate();
+    i->value(((Fl_Valuator*)(current_widget->o))->maximum());
+  } else {
+    int mod = 0;
+    double n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	if (q->is_valuator()) {
+	  ((Fl_Valuator*)(q->o))->maximum(n);
+	  q->o->redraw();
+	  mod = 1;
+	}
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void step_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_valuator()) {i->deactivate(); return;}
+    i->activate();
+    i->value(((Fl_Valuator*)(current_widget->o))->step());
+  } else {
+    int mod = 0;
+    double n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+        if (q->is_valuator()) {
+	        ((Fl_Valuator*)(q->o))->step(n);
+	        q->o->redraw();
+	        mod = 1;
+        }
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+void value_cb(Fl_Value_Input* i, void* v) {
+  if (v == LOAD) {
+    if (current_widget->is_valuator()) {
+      i->activate();
+      i->value(((Fl_Valuator*)(current_widget->o))->value());
+    } else if (current_widget->is_button()) {
+      i->activate();
+      i->value(((Fl_Button*)(current_widget->o))->value());
+    } else 
+      i->deactivate();
+  } else {
+    int mod = 0;
+    double n = i->value();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+	Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+	if (q->is_valuator()) {
+	  ((Fl_Valuator*)(q->o))->value(n);
+	  mod = 1;
+	} else if (q->is_button()) {
+	  ((Fl_Button*)(q->o))->value(n != 0);
+	  if (q->is_menu_item()) q->redraw();
+	  mod = 1;
+	}
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// subtypes:
+
+Fl_Menu_Item *Fl_Widget_Type::subtypes() {return 0;}
+
+void subtype_cb(Fl_Choice* i, void* v) {
+  if (v == LOAD) {
+    Fl_Menu_Item* m = current_widget->subtypes();
+    if (!m) {i->deactivate(); return;}
+    i->menu(m);
+    int j;
+    for (j = 0;; j++) {
+      if (!m[j].text) {j = 0; break;}
+      if (m[j].argument() == current_widget->o->type()) break;
+    }
+    i->value(j);
+    i->activate();
+    i->redraw();
+  } else {
+    int mod = 0;
+    int n = int(i->mvalue()->argument());
+    Fl_Menu_Item* m = current_widget->subtypes();
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+        if (q->subtypes()==m) {
+	        q->o->type(n);
+	        q->redraw();
+	        mod = 1;
+        }
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+void propagate_load(Fl_Group* g, void* v) {
+  if (v == LOAD) {
+    Fl_Widget*const* a = g->array();
+    for (int i=g->children(); i--;) {
+      Fl_Widget* o = *a++;
+      o->do_callback(o,LOAD);
+    }
+  }
+}
+
+void set_cb(Fl_Button*, void*) {
+  haderror = 0;
+  Fl_Widget*const* a = the_panel->array();
+  for (int i=the_panel->children(); i--;) {
+    Fl_Widget* o = *a++;
+    if (o->changed()) {
+      o->do_callback();
+      if (haderror) return;
+      o->clear_changed();
+    }
+  }
+}
+
+void ok_cb(Fl_Return_Button* o, void* v) {
+  set_cb(o,v);
+  if (!haderror) the_panel->hide();
+}
+
+void revert_cb(Fl_Button*, void*) {
+  // We have to revert all dynamically changing fields:
+  // but for now only the first label works...
+  if (numselected == 1) current_widget->label(oldlabel);
+  propagate_load(the_panel, LOAD);
+}
+
+void cancel_cb(Fl_Button* o, void* v) {
+  revert_cb(o,v);
+  the_panel->hide();
+}
+
+void toggle_overlays(Fl_Widget *,void *); // in Fl_Window_Type.cxx
+void overlay_cb(Fl_Button*o,void *v) {
+  toggle_overlays(o,v);
+}
+
+void leave_live_mode_cb(Fl_Widget*, void*);
+
+void live_mode_cb(Fl_Button*o,void *v) {
+  /// \todo live mode should end gracefully when the application quits
+  ///       or when the user closes the live widget
+  static Fl_Type *live_type = 0L;
+  static Fl_Widget *live_widget = 0L;
+  static Fl_Window *live_window = 0L;
+  // if 'o' is 0, we must quit live mode
+  if (!o) {
+    o = wLiveMode;
+    o->value(0);
+  }
+  if (o->value()) {
+    if (numselected == 1) {
+      live_widget = current_widget->enter_live_mode(1);
+      if (live_widget) {
+        live_type = current_widget;
+        Fl_Group::current(0);
+        int w = live_widget->w();
+        int h = live_widget->h();
+        live_window = new Fl_Double_Window(w+20, h+55, "Fluid Live Mode Widget");
+        live_window->box(FL_FLAT_BOX);
+        live_window->color(FL_GREEN);
+        Fl_Group *rsz = new Fl_Group(0, h+20, 130, 35);
+        rsz->box(FL_NO_BOX);
+        Fl_Box *rsz_dummy = new Fl_Box(110, h+20, 1, 25);
+        rsz_dummy->box(FL_NO_BOX);
+        rsz->resizable(rsz_dummy);
+        Fl_Button *btn = new Fl_Button(10, h+20, 100, 25, "Exit Live Mode");
+        btn->labelsize(12);
+        btn->callback(leave_live_mode_cb);
+        live_widget->position(10, 10);
+        live_window->add(live_widget);
+        live_window->resizable(live_widget);
+        live_window->set_modal(); // block all other UI
+        live_window->callback(leave_live_mode_cb);
+        if (current_widget->is_window()) {
+          Fl_Window_Type *w = (Fl_Window_Type*)current_widget;
+          int mw = w->sr_min_w; if (mw>0) mw += 20;
+          int mh = w->sr_min_h; if (mh>0) mh += 55;
+          int MW = w->sr_max_w; if (MW>0) MW += 20; 
+          int MH = w->sr_max_h; if (MH>2) MH += 55;
+          if (mw || mh || MW || MH)
+            live_window->size_range(mw, mh, MW, MH);
+        }
+        live_window->show();
+      } else o->value(0);
+    } else o->value(0);
+  } else {
+    if (live_type)
+      live_type->leave_live_mode();
+    if (live_window) {
+      live_window->hide();
+      Fl::delete_widget(live_window);
+    }
+    live_type = 0L;
+    live_widget = 0L;
+    live_window = 0L;
+  }
+}
+
+// update the panel according to current widget set:
+static void load_panel() {
+  if (!the_panel) return;
+
+  // find all the Fl_Widget subclasses currently selected:
+  numselected = 0;
+  current_widget = 0;
+  if (Fl_Type::current) {
+    if (Fl_Type::current->is_widget())
+      current_widget=(Fl_Widget_Type*)Fl_Type::current;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->is_widget() && o->selected) {
+	numselected++;
+	if (!current_widget) current_widget = (Fl_Widget_Type*)o;
+      }
+    }
+  }
+  if (numselected)
+    propagate_load(the_panel, LOAD);
+  else
+    the_panel->hide();
+}
+
+// This is called when user double-clicks an item, open or update the panel:
+void Fl_Widget_Type::open() {
+  if (!the_panel) the_panel = make_widget_panel();
+  load_panel();
+  if (numselected) the_panel->show();
+}
+
+Fl_Type *Fl_Type::current;
+
+extern void redraw_overlays();
+extern void redraw_browser();
+extern void update_sourceview_position();
+
+// Called when ui changes what objects are selected:
+// p is selected object, null for all deletions (we must throw away
+// old panel in that case, as the object may no longer exist)
+void selection_changed(Fl_Type *p) {
+  // store all changes to the current selected objects:
+  if (p && the_panel && the_panel->visible()) {
+    set_cb(0,0);
+    // if there was an error, we try to leave the selected set unchanged:
+    if (haderror) {
+      Fl_Type *q = 0;
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+	o->new_selected = o->selected;
+	if (!q && o->selected) q = o;
+      }
+      if (!p || !p->selected) p = q;
+      Fl_Type::current = p;
+      redraw_browser();
+      return;
+    }
+  }
+  // update the selected flags to new set:
+  Fl_Type *q = 0;
+  for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+    o->selected = o->new_selected;
+    if (!q && o->selected) q = o;
+  }
+  if (!p || !p->selected) p = q;
+  Fl_Type::current = p;
+  redraw_overlays();
+  // load the panel with the new settings:
+  load_panel();
+  // update the source viewer to show the code for the selected object
+  update_sourceview_position();
+}
+
+////////////////////////////////////////////////////////////////
+// Writing the C code:
+
+// test to see if user named a function, or typed in code:
+int is_name(const char *c) {
+  for (; *c; c++) if (ispunct(*c) && *c!='_' && *c!=':') return 0;
+  return 1;
+}
+
+// Test to see if name() is an array entry.  If so, and this is the
+// highest number, return name[num+1].  Return null if not the highest
+// number or a field or function.  Return name() if not an array entry.
+const char *array_name(Fl_Widget_Type *o) {
+  const char *c = o->name();
+  if (!c) return 0;
+  const char *d;
+  for (d = c; *d != '['; d++) {
+    if (!*d) return c;
+    if (ispunct(*d) && *d!='_') return 0;
+  }
+  int num = atoi(d+1);
+  int sawthis = 0;
+  Fl_Type *t = o->prev;
+  Fl_Type *tp = o;
+  const char *cn = o->class_name(1);
+  for (; t && t->class_name(1) == cn; tp = t, t = t->prev);
+  for (t = tp; t && t->class_name(1) == cn; t = t->next) {
+    if (t == o) {sawthis=1; continue;}
+    const char *e = t->name();
+    if (!e) continue;
+    if (strncmp(c,e,d-c)) continue;
+    int n1 = atoi(e+(d-c)+1);
+    if (n1 > num || n1==num && sawthis) return 0;
+  }
+  static char buffer[128];
+  // MRS: we want strncpy() here...
+  strncpy(buffer,c,d-c+1);
+  snprintf(buffer+(d-c+1),sizeof(buffer) - (d-c+1), "%d]",num+1);
+  return buffer;
+}
+
+// Test to see if extra code is a declaration:
+int isdeclare(const char *c) {
+  while (isspace(*c)) c++;
+  if (*c == '#') return 1;
+  if (!strncmp(c,"extern",6)) return 1;
+  if (!strncmp(c,"typedef",7)) return 1;
+  if (!strncmp(c,"using",5)) return 1;
+  return 0;
+}
+
+void Fl_Widget_Type::write_static() {
+  const char* t = subclassname(this);
+  if (!subclass() || is_class()) write_declare("#include <FL/%s.H>", t);
+  for (int n=0; n < NUM_EXTRA_CODE; n++) {
+    if (extra_code(n) && isdeclare(extra_code(n)))
+      write_declare("%s", extra_code(n));
+  }
+  if (callback() && is_name(callback())) {
+    int write_extern_declaration = 1;
+    const Fl_Class_Type *cc = is_in_class();
+    if (cc) {
+      char buf[1024]; snprintf(buf, 1023, "%s(*)",  callback());
+      if (cc->has_function("static void", buf))
+        write_extern_declaration = 0;
+    }
+    if (write_extern_declaration)
+      write_declare("extern void %s(%s*, %s);", callback(), t,
+		    user_data_type() ? user_data_type() : "void*");
+  }
+  const char* k = class_name(1);
+  const char* c = array_name(this);
+  if (c && !k && !is_class()) {
+    write_c("\n");
+    if (!public_) write_c("static ");
+    else write_h("extern %s *%s;\n", t, c);
+    if (strchr(c, '[') == NULL) write_c("%s *%s=(%s *)0;\n", t, c, t);
+    else write_c("%s *%s={(%s *)0};\n", t, c, t);
+  }
+  if (callback() && !is_name(callback())) {
+    // see if 'o' or 'v' used, to prevent unused argument warnings:
+    int use_o = 0;
+    int use_v = 0;
+    const char *d;
+    for (d = callback(); *d;) {
+      if (*d == 'o' && !is_id(d[1])) use_o = 1;
+      if (*d == 'v' && !is_id(d[1])) use_v = 1;
+      do d++; while (is_id(*d));
+      while (*d && !is_id(*d)) d++;
+    }
+    const char* cn = callback_name();
+    if (k) {
+      write_c("\nvoid %s::%s_i(%s*", k, cn, t);
+    } else {
+      write_c("\nstatic void %s(%s*", cn, t);
+    }
+    if (use_o) write_c(" o");
+    const char* ut = user_data_type() ? user_data_type() : "void*";
+    write_c(", %s", ut);
+    if (use_v) write_c(" v");
+    write_c(") {\n  %s", callback());
+    if (*(d-1) != ';') {
+      const char *p = strrchr(callback(), '\n');
+      if (p) p ++;
+      else p = callback();
+      // Only add trailing semicolon if the last line is not a preprocessor
+      // statement...
+      if (*p != '#' && *p) write_c(";");
+    }
+    write_c("\n}\n");
+    if (k) {
+      write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t, ut);
+      write_c("  ((%s*)(o", k);
+      Fl_Type *q = 0;
+      for (Fl_Type* p = parent; p && p->is_widget(); q = p, p = p->parent)
+	write_c("->parent()");
+      if (!q || strcmp(q->type_name(), "widget_class"))
+        write_c("->user_data()");
+      write_c("))->%s_i(o,v);\n}\n", cn);
+    }
+  }
+  if (image) {
+    if (image->written != write_number) {
+      image->write_static();
+      image->written = write_number;
+    }
+  }
+  if (inactive) {
+    if (inactive->written != write_number) {
+      inactive->write_static();
+      inactive->written = write_number;
+    }
+  }
+}
+
+const char *Fl_Type::callback_name() {
+  if (is_name(callback())) return callback();
+  return unique_id(this, "cb", name(), label());
+}
+
+extern int varused_test, varused;
+  
+void Fl_Widget_Type::write_code1() {
+  const char* t = subclassname(this);
+  const char *c = array_name(this);
+  if (c) {
+    if (class_name(1)) {
+      write_public(public_);
+      write_h("  %s *%s;\n", t, c);
+    }
+  }
+  if (class_name(1) && callback() && !is_name(callback())) {
+    const char* cn = callback_name();
+    const char* ut = user_data_type() ? user_data_type() : "void*";
+    write_public(0);
+    write_h("  void %s_i(%s*, %s);\n", cn, t, ut);
+    write_h("  static void %s(%s*, %s);\n", cn, t, ut);
+  }
+  // figure out if local variable will be used (prevent compiler warnings):
+  if (is_parent())
+    varused = 1;
+  else {
+    varused_test = 1; varused = 0;
+    write_widget_code();
+    varused_test = 0;
+    for (int n=0; n < NUM_EXTRA_CODE; n++)
+      if (extra_code(n) && !isdeclare(extra_code(n))) varused = 1;
+  }
+  write_c(indent());
+  if (varused) write_c("{ %s* o = ", t);
+  if (name()) write_c("%s = ", name());
+  if (is_window()) {
+    // Handle special case where user is faking a Fl_Group type as a window,
+    // there is no 2-argument constructor in that case:
+    if (!strstr(t, "Window"))
+      write_c("new %s(0, 0, %d, %d", t, o->w(), o->h());
+    else
+      write_c("new %s(%d, %d", t, o->w(), o->h());
+  } else {
+    write_c("new %s(%d, %d, %d, %d", t, o->x(), o->y(), o->w(), o->h());
+  }
+  if (label() && *label()) {
+    write_c(", ");
+    switch (i18n_type) {
+    case 0 : /* None */
+        write_cstring(label());
+        break;
+    case 1 : /* GNU gettext */
+        write_c("%s(", i18n_function);
+        write_cstring(label());
+	write_c(")");
+        break;
+    case 2 : /* POSIX catgets */
+        write_c("catgets(%s,%s,%d,", i18n_file[0] ? i18n_file : "_catalog",
+	        i18n_set, msgnum());
+        write_cstring(label());
+	write_c(")");
+        break;
+    }
+  }
+  write_c(");\n");
+  indentation += 2;
+
+  if (is_window()) write_c("%sw = o;\n",indent());
+  if (varused) write_widget_code();
+}
+
+void Fl_Widget_Type::write_color(const char* field, Fl_Color color) {
+  const char* color_name = 0;
+  switch (color) {
+  case FL_FOREGROUND_COLOR:	color_name = "FL_FOREGROUND_COLOR";	break;
+  case FL_BACKGROUND2_COLOR:	color_name = "FL_BACKGROUND2_COLOR";	break;
+  case FL_INACTIVE_COLOR:	color_name = "FL_INACTIVE_COLOR";	break;
+  case FL_SELECTION_COLOR:	color_name = "FL_SELECTION_COLOR";	break;
+  case FL_GRAY0:		color_name = "FL_GRAY0";		break;
+  case FL_DARK3:		color_name = "FL_DARK3";		break;
+  case FL_DARK2:		color_name = "FL_DARK2";		break;
+  case FL_DARK1:		color_name = "FL_DARK1";		break;
+  case FL_BACKGROUND_COLOR:	color_name = "FL_BACKGROUND_COLOR";	break;
+  case FL_LIGHT1:		color_name = "FL_LIGHT1";		break;
+  case FL_LIGHT2:		color_name = "FL_LIGHT2";		break;
+  case FL_LIGHT3:		color_name = "FL_LIGHT3";		break;
+  case FL_BLACK:		color_name = "FL_BLACK";		break;
+  case FL_RED:			color_name = "FL_RED";			break;
+  case FL_GREEN:		color_name = "FL_GREEN";		break;
+  case FL_YELLOW:		color_name = "FL_YELLOW";		break;
+  case FL_BLUE:			color_name = "FL_BLUE";			break;
+  case FL_MAGENTA:		color_name = "FL_MAGENTA";		break;
+  case FL_CYAN:			color_name = "FL_CYAN";			break;
+  case FL_DARK_RED:		color_name = "FL_DARK_RED";		break;
+  case FL_DARK_GREEN:		color_name = "FL_DARK_GREEN";		break;
+  case FL_DARK_YELLOW:		color_name = "FL_DARK_YELLOW";		break;
+  case FL_DARK_BLUE:		color_name = "FL_DARK_BLUE";		break;
+  case FL_DARK_MAGENTA:		color_name = "FL_DARK_MAGENTA";		break;
+  case FL_DARK_CYAN:		color_name = "FL_DARK_CYAN";		break;
+  case FL_WHITE:		color_name = "FL_WHITE";		break;
+  }
+  if (color_name) {
+    write_c("%so->%s(%s);\n", indent(), field, color_name);
+  } else {
+    write_c("%so->%s((Fl_Color)%d);\n", indent(), field, color);
+  }
+}
+
+// this is split from write_code1() for Fl_Window_Type:
+void Fl_Widget_Type::write_widget_code() {
+  Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
+  if (tooltip() && *tooltip()) {
+    write_c("%so->tooltip(",indent());
+    switch (i18n_type) {
+    case 0 : /* None */
+        write_cstring(tooltip());
+        break;
+    case 1 : /* GNU gettext */
+        write_c("%s(", i18n_function);
+        write_cstring(tooltip());
+	write_c(")");
+        break;
+    case 2 : /* POSIX catgets */
+        write_c("catgets(%s,%s,%d,", i18n_file[0] ? i18n_file : "_catalog",
+	        i18n_set, msgnum() + 1);
+        write_cstring(tooltip());
+	write_c(")");
+        break;
+    }
+    write_c(");\n");
+  }
+
+  if (o->type() != tplate->type() && !is_window())
+    write_c("%so->type(%d);\n", indent(), o->type());
+  if (o->box() != tplate->box() || subclass())
+    write_c("%so->box(FL_%s);\n", indent(), boxname(o->box()));
+  if (is_button()) {
+    Fl_Button* b = (Fl_Button*)o;
+    if (b->down_box()) write_c("%so->down_box(FL_%s);\n", indent(),
+			       boxname(b->down_box()));
+    if (b->value()) write_c("%so->value(1);\n", indent());
+    if (b->shortcut())
+      write_c("%so->shortcut(0x%x);\n", indent(), b->shortcut());
+  } else if (!strcmp(type_name(), "Fl_Input_Choice")) {
+    Fl_Input_Choice* b = (Fl_Input_Choice*)o;
+    if (b->down_box()) write_c("%so->down_box(FL_%s);\n", indent(),
+			       boxname(b->down_box()));
+  } else if (is_menu_button()) {
+    Fl_Menu_* b = (Fl_Menu_*)o;
+    if (b->down_box()) write_c("%so->down_box(FL_%s);\n", indent(),
+			       boxname(b->down_box()));
+  }
+  if (o->color() != tplate->color() || subclass())
+    write_color("color", o->color());
+  if (o->selection_color() != tplate->selection_color() || subclass())
+    write_color("selection_color", o->selection_color());
+  if (image) image->write_code();
+  if (inactive) inactive->write_code(1);
+  if (o->labeltype() != tplate->labeltype() || subclass())
+    write_c("%so->labeltype(FL_%s);\n", indent(),
+	    item_name(labeltypemenu, o->labeltype()));
+  if (o->labelfont() != tplate->labelfont() || subclass())
+    write_c("%so->labelfont(%d);\n", indent(), o->labelfont());
+  if (o->labelsize() != tplate->labelsize() || subclass())
+    write_c("%so->labelsize(%d);\n", indent(), o->labelsize());
+  if (o->labelcolor() != tplate->labelcolor() || subclass())
+    write_color("labelcolor", o->labelcolor());
+  if (is_valuator()) {
+    Fl_Valuator* v = (Fl_Valuator*)o;
+    Fl_Valuator* f = (Fl_Valuator*)(tplate);
+    if (v->minimum()!=f->minimum())
+      write_c("%so->minimum(%g);\n", indent(), v->minimum());
+    if (v->maximum()!=f->maximum())
+      write_c("%so->maximum(%g);\n", indent(), v->maximum());
+    if (v->step()!=f->step())
+      write_c("%so->step(%g);\n", indent(), v->step());
+    if (v->value())
+      write_c("%so->value(%g);\n", indent(), v->value());
+    if (is_valuator()==2) {
+      double x = ((Fl_Slider*)v)->slider_size();
+      double y = ((Fl_Slider*)f)->slider_size();
+      if (x != y) write_c("%so->slider_size(%g);\n", indent(), x);
+    }
+  }
+  {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
+    Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c);
+    if (f != ff) write_c("%so->textfont(%d);\n", indent(), f);
+    if (s != fs) write_c("%so->textsize(%d);\n", indent(), s);
+    if (c != fc) write_c("%so->textcolor(%d);\n",indent(), c);
+  }}
+  const char* ud = user_data();
+  if (class_name(1) && !parent->is_widget()) ud = "this";
+  if (callback()) {
+    write_c("%so->callback((Fl_Callback*)%s", indent(), callback_name());
+    if (ud)
+      write_c(", (void*)(%s));\n", ud);
+    else
+      write_c(");\n");
+  } else if (ud) {
+    write_c("%so->user_data((void*)(%s));\n", indent(), ud);
+  }
+  if (o->align() != tplate->align() || subclass()) {
+    int i = o->align();
+    write_c("%so->align(%s", indent(),
+	    item_name(alignmenu, i & ~FL_ALIGN_INSIDE));
+    if (i & FL_ALIGN_INSIDE) write_c("|FL_ALIGN_INSIDE");
+    write_c(");\n");
+  }
+  if (o->when() != tplate->when() || subclass())
+    write_c("%so->when(%s);\n", indent(),item_name(whensymbolmenu, o->when()));
+  if (!o->visible() && o->parent())
+    write_c("%so->hide();\n", indent());
+  if (!o->active())
+    write_c("%so->deactivate();\n", indent());
+  if (!is_group() && resizable())
+    write_c("%sFl_Group::current()->resizable(o);\n",indent());
+  if (hotspot())
+    write_c("%sw->hotspot(o);\n", indent());
+}
+
+void Fl_Widget_Type::write_extra_code() {
+  for (int n=0; n < NUM_EXTRA_CODE; n++)
+    if (extra_code(n) && !isdeclare(extra_code(n)))
+      write_c("%s%s\n", indent(), extra_code(n));
+}
+
+void Fl_Widget_Type::write_block_close() {
+  indentation -= 2;
+  if (is_parent() || varused) write_c("%s}\n", indent());
+}
+
+void Fl_Widget_Type::write_code2() {
+  write_extra_code();
+  write_block_close();
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Widget_Type::write_properties() {
+  Fl_Type::write_properties();
+  write_indent(level+1);
+  if (!public_) write_string("private");
+  if (tooltip() && *tooltip()) {
+    write_string("tooltip");
+    write_word(tooltip());
+  }
+  if (image_name() && *image_name()) {
+    write_string("image");
+    write_word(image_name());
+  }
+  if (inactive_name() && *inactive_name()) {
+    write_string("deimage");
+    write_word(inactive_name());
+  }
+  write_string("xywh {%d %d %d %d}", o->x(), o->y(), o->w(), o->h());
+  Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
+  if (o->type() != tplate->type() || is_window()) {
+    write_string("type");
+    write_word(item_name(subtypes(), o->type()));
+  }
+  if (o->box() != tplate->box()) {
+    write_string("box"); write_word(boxname(o->box()));}
+  if (is_button()) {
+    Fl_Button* b = (Fl_Button*)o;
+    if (b->down_box()) {
+      write_string("down_box"); write_word(boxname(b->down_box()));}
+    if (b->shortcut()) write_string("shortcut 0x%x", b->shortcut());
+    if (b->value()) write_string("value 1");
+  } else if (!strcmp(type_name(), "Fl_Input_Choice")) {
+    Fl_Input_Choice* b = (Fl_Input_Choice*)o;
+    if (b->down_box()) {
+      write_string("down_box"); write_word(boxname(b->down_box()));}
+  } else if (is_menu_button()) {
+    Fl_Menu_* b = (Fl_Menu_*)o;
+    if (b->down_box()) {
+      write_string("down_box"); write_word(boxname(b->down_box()));}
+  }
+  if (o->color()!=tplate->color())
+    write_string("color %d", o->color());
+  if (o->selection_color()!=tplate->selection_color())
+    write_string("selection_color %d", o->selection_color());
+  if (o->labeltype()!=tplate->labeltype()) {
+    write_string("labeltype");
+    write_word(item_name(labeltypemenu, o->labeltype()));
+  }
+  if (o->labelfont()!=tplate->labelfont())
+    write_string("labelfont %d", o->labelfont());
+  if (o->labelsize()!=tplate->labelsize())
+    write_string("labelsize %d", o->labelsize());
+  if (o->labelcolor()!=tplate->labelcolor())
+    write_string("labelcolor %d", o->labelcolor());
+  if (o->align()!=tplate->align())
+    write_string("align %d", o->align());
+  if (o->when() != tplate->when())
+    write_string("when %d", o->when());
+  if (is_valuator()) {
+    Fl_Valuator* v = (Fl_Valuator*)o;
+    Fl_Valuator* f = (Fl_Valuator*)(tplate);
+    if (v->minimum()!=f->minimum()) write_string("minimum %g",v->minimum());
+    if (v->maximum()!=f->maximum()) write_string("maximum %g",v->maximum());
+    if (v->step()!=f->step()) write_string("step %g",v->step());
+    if (v->value()!=0.0) write_string("value %g",v->value());
+    if (is_valuator()==2) {
+      double x = ((Fl_Slider*)v)->slider_size();
+      double y = ((Fl_Slider*)f)->slider_size();
+      if (x != y) write_string("slider_size %g", x);
+    }
+  }
+  {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
+    Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c);
+    if (f != ff) write_string("textfont %d", f);
+    if (s != fs) write_string("textsize %d", s);
+    if (c != fc) write_string("textcolor %d", c);
+  }}
+  if (!o->visible()) write_string("hide");
+  if (!o->active()) write_string("deactivate");
+  if (resizable()) write_string("resizable");
+  if (hotspot()) write_string(is_menu_item() ? "divider" : "hotspot");
+  for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n)) {
+    write_indent(level+1);
+    write_string("code%d",n);
+    write_word(extra_code(n));
+  }
+  if (subclass()) {
+    write_indent(level+1);
+    write_string("class");
+    write_word(subclass());
+  }
+}
+
+int pasteoffset;
+
+void Fl_Widget_Type::read_property(const char *c) {
+  int x,y,w,h; Fl_Font f; int s; Fl_Color cc;
+  if (!strcmp(c,"private")) {
+    public_ = 0;
+  } else if (!strcmp(c,"xywh")) {
+    if (sscanf(read_word(),"%d %d %d %d",&x,&y,&w,&h) == 4) {
+      x += pasteoffset;
+      y += pasteoffset;
+      o->resize(x,y,w,h);
+    }
+  } else if (!strcmp(c,"tooltip")) {
+    tooltip(read_word());
+  } else if (!strcmp(c,"image")) {
+    image_name(read_word());
+  } else if (!strcmp(c,"deimage")) {
+    inactive_name(read_word());
+  } else if (!strcmp(c,"type")) {
+    o->type(item_number(subtypes(), read_word()));
+  } else if (!strcmp(c,"box")) {
+    const char* value = read_word();
+    if ((x = boxnumber(value))) {
+      if (x == ZERO_ENTRY) x = 0;
+      o->box((Fl_Boxtype)x);
+    } else if (sscanf(value,"%d",&x) == 1) o->box((Fl_Boxtype)x);
+  } else if (is_button() && !strcmp(c,"down_box")) {
+    const char* value = read_word();
+    if ((x = boxnumber(value))) {
+      if (x == ZERO_ENTRY) x = 0;
+      ((Fl_Button*)o)->down_box((Fl_Boxtype)x);
+    }
+  } else if (!strcmp(type_name(), "Fl_Input_Choice") && !strcmp(c,"down_box")) {
+    const char* value = read_word();
+    if ((x = boxnumber(value))) {
+      if (x == ZERO_ENTRY) x = 0;
+      ((Fl_Input_Choice*)o)->down_box((Fl_Boxtype)x);
+    }
+  } else if (is_menu_button() && !strcmp(c,"down_box")) {
+    const char* value = read_word();
+    if ((x = boxnumber(value))) {
+      if (x == ZERO_ENTRY) x = 0;
+      ((Fl_Menu_*)o)->down_box((Fl_Boxtype)x);
+    }
+  } else if (is_button() && !strcmp(c,"value")) {
+    const char* value = read_word();
+    ((Fl_Button*)o)->value(atoi(value));
+  } else if (!strcmp(c,"color")) {
+    int n = sscanf(read_word(),"%d %d",&x,&y);
+    if (n == 2) { // back compatability...
+      if (x != 47) o->color(x);
+      o->selection_color(y);
+    } else {
+      o->color(x);
+    }
+  } else if (!strcmp(c,"selection_color")) {
+    if (sscanf(read_word(),"%d",&x)) o->selection_color(x);
+  } else if (!strcmp(c,"labeltype")) {
+    c = read_word();
+    if (!strcmp(c,"image")) {
+      Fluid_Image *i = Fluid_Image::find(label());
+      if (!i) read_error("Image file '%s' not found", label());
+      else setimage(i);
+      image_name(label());
+      label("");
+    } else {
+      o->labeltype((Fl_Labeltype)item_number(labeltypemenu,c));
+    }
+  } else if (!strcmp(c,"labelfont")) {
+    if (sscanf(read_word(),"%d",&x) == 1) o->labelfont(x);
+  } else if (!strcmp(c,"labelsize")) {
+    if (sscanf(read_word(),"%d",&x) == 1) o->labelsize(x);
+  } else if (!strcmp(c,"labelcolor")) {
+    if (sscanf(read_word(),"%d",&x) == 1) o->labelcolor(x);
+  } else if (!strcmp(c,"align")) {
+    if (sscanf(read_word(),"%d",&x) == 1) o->align(x);
+  } else if (!strcmp(c,"when")) {
+    if (sscanf(read_word(),"%d",&x) == 1) o->when(x);
+  } else if (!strcmp(c,"minimum") && is_valuator()) {
+    ((Fl_Valuator*)o)->minimum(strtod(read_word(),0));
+  } else if (!strcmp(c,"maximum") && is_valuator()) {
+    ((Fl_Valuator*)o)->maximum(strtod(read_word(),0));
+  } else if (!strcmp(c,"step") && is_valuator()) {
+    ((Fl_Valuator*)o)->step(strtod(read_word(),0));
+  } else if (!strcmp(c,"value") && is_valuator()) {
+    ((Fl_Valuator*)o)->value(strtod(read_word(),0));
+  } else if ((!strcmp(c,"slider_size")||!strcmp(c,"size"))&&is_valuator()==2) {
+    ((Fl_Slider*)o)->slider_size(strtod(read_word(),0));
+  } else if (!strcmp(c,"textfont")) {
+    if (sscanf(read_word(),"%d",&x) == 1) {f=(Fl_Font)x; textstuff(1,f,s,cc);}
+  } else if (!strcmp(c,"textsize")) {
+    if (sscanf(read_word(),"%d",&x) == 1) {s=x; textstuff(2,f,s,cc);}
+  } else if (!strcmp(c,"textcolor")) {
+    if (sscanf(read_word(),"%d",&x) == 1) {cc=(Fl_Color)x;textstuff(3,f,s,cc);}
+  } else if (!strcmp(c,"hide")) {
+    o->hide();
+  } else if (!strcmp(c,"deactivate")) {
+    o->deactivate();
+  } else if (!strcmp(c,"resizable")) {
+    resizable(1);
+  } else if (!strcmp(c,"hotspot") || !strcmp(c, "divider")) {
+    hotspot(1);
+  } else if (!strcmp(c,"class")) {
+    subclass(read_word());
+  } else if (is_button() && !strcmp(c,"shortcut")) {
+    ((Fl_Button*)o)->shortcut(strtol(read_word(),0,0));
+  } else {
+    if (!strncmp(c,"code",4)) {
+      int n = atoi(c+4);
+      if (n >= 0 && n <= NUM_EXTRA_CODE) {
+	extra_code(n,read_word());
+	return;
+      }
+    }
+    Fl_Type::read_property(c);
+  }
+}
+
+Fl_Menu_Item boxmenu1[] = {
+  // these extra ones are for looking up fdesign saved strings:
+  {"NO_FRAME",		0,0,(void *)FL_NO_BOX},
+  {"ROUNDED3D_UPBOX",	0,0,(void *)_FL_ROUND_UP_BOX},
+  {"ROUNDED3D_DOWNBOX",	0,0,(void *)_FL_ROUND_DOWN_BOX},
+  {"OVAL3D_UPBOX",	0,0,(void *)_FL_ROUND_UP_BOX},
+  {"OVAL3D_DOWNBOX",	0,0,(void *)_FL_ROUND_DOWN_BOX},
+  {"0",			0,0,(void *)ZERO_ENTRY},
+  {"1",			0,0,(void *)FL_UP_BOX},
+  {"2",			0,0,(void *)FL_DOWN_BOX},
+  {"3",			0,0,(void *)FL_FLAT_BOX},
+  {"4",			0,0,(void *)FL_BORDER_BOX},
+  {"5",			0,0,(void *)FL_SHADOW_BOX},
+  {"6",			0,0,(void *)FL_FRAME_BOX},
+  {"7",			0,0,(void *)FL_ROUNDED_BOX},
+  {"8",			0,0,(void *)FL_RFLAT_BOX},
+  {"9",			0,0,(void *)FL_RSHADOW_BOX},
+  {"10",		0,0,(void *)FL_UP_FRAME},
+  {"11",		0,0,(void *)FL_DOWN_FRAME},
+{0}};
+
+extern int fdesign_flip;
+int lookup_symbol(const char *, int &, int numberok = 0);
+
+int Fl_Widget_Type::read_fdesign(const char* propname, const char* value) {
+  int v;
+  if (!strcmp(propname,"box")) {
+    float x,y,w,h;
+    if (sscanf(value,"%f %f %f %f",&x,&y,&w,&h) == 4) {
+      if (fdesign_flip) {
+	Fl_Type *p;
+	for (p = parent; p && !p->is_window(); p = p->parent);
+	if (p && p->is_widget()) y = ((Fl_Widget_Type*)p)->o->h()-(y+h);
+      }	  
+      x += pasteoffset;
+      y += pasteoffset;
+      o->resize(int(x),int(y),int(w),int(h));
+    }
+  } else if (!strcmp(propname,"label")) {
+    label(value);
+  } else if (!strcmp(propname,"name")) {
+    this->name(value);
+  } else if (!strcmp(propname,"callback")) {
+    callback(value); user_data_type("long");
+  } else if (!strcmp(propname,"argument")) {
+    user_data(value);
+  } else if (!strcmp(propname,"shortcut")) {
+    if (value[0]) {
+      char buf[128]; sprintf(buf,"o->shortcut(\"%s\");",value);
+      extra_code(0,buf);
+    }
+  } else if (!strcmp(propname,"style")) {
+    if (!strncmp(value,"FL_NORMAL",9)) return 1;
+    if (!lookup_symbol(value,v,1)) return 0;
+    o->labelfont(v); o->labeltype((Fl_Labeltype)(v>>8));
+  } else if (!strcmp(propname,"size")) {
+    if (!lookup_symbol(value,v,1)) return 0;
+    o->labelsize(v);
+  } else if (!strcmp(propname,"type")) {
+    if (!strncmp(value,"NORMAL",6)) return 1;
+    if (lookup_symbol(value,v,1)) {o->type(v); return 1;}
+    if (!strcmp(value+strlen(value)-5,"FRAME")) goto TRY_BOXTYPE;
+    if (!strcmp(value+strlen(value)-3,"BOX")) goto TRY_BOXTYPE;
+    return 0;
+  } else if (!strcmp(propname,"lcol")) {
+    if (!lookup_symbol(value,v,1)) return 0;
+    o->labelcolor(v);
+  } else if (!strcmp(propname,"return")) {
+    if (!lookup_symbol(value,v,0)) return 0;
+    o->when(v|FL_WHEN_RELEASE);
+  } else if (!strcmp(propname,"alignment")) {
+    if (!lookup_symbol(value,v)) {
+      // convert old numeric values:
+      int v1 = atoi(value); if (v1 <= 0 && strcmp(value,"0")) return 0;
+      v = 0;
+      if (v1 >= 5) {v = FL_ALIGN_INSIDE; v1 -= 5;}
+      switch (v1) {
+      case 0: v += FL_ALIGN_TOP; break;
+      case 1: v += FL_ALIGN_BOTTOM; break;
+      case 2: v += FL_ALIGN_LEFT; break;
+      case 3: v += FL_ALIGN_RIGHT; break;
+      case 4: v += FL_ALIGN_CENTER; break;
+      default: return 0;
+      }
+    }
+    o->align(v);
+  } else if (!strcmp(propname,"resizebox")) {
+    resizable(1);
+  } else if (!strcmp(propname,"colors")) {
+    char* p = (char*)value;
+    while (*p != ' ') {if (!*p) return 0; p++;}
+    *p = 0;
+    int v1;
+    if (!lookup_symbol(value,v,1) || !lookup_symbol(p+1,v1,1)) {
+      *p=' '; return 0;}
+    o->color(v,v1);
+  } else if (!strcmp(propname,"resize")) {
+    return !strcmp(value,"FL_RESIZE_ALL");
+  } else if (!strcmp(propname,"gravity")) {
+    return !strcmp(value,"FL_NoGravity FL_NoGravity");
+  } else if (!strcmp(propname,"boxtype")) {
+  TRY_BOXTYPE:
+    int x = boxnumber(value);
+    if (!x) {x = item_number(boxmenu1, value); if (x < 0) return 0;}
+    if (x == ZERO_ENTRY) {
+      x = 0;
+      if (o->box() != ((Fl_Widget_Type*)factory)->o->box()) return 1; // kludge for frame
+    }
+    o->box((Fl_Boxtype)x);
+  } else {
+    return 0;
+  }
+  return 1;
+}
+
+void leave_live_mode_cb(Fl_Widget*, void*) {
+  live_mode_cb(0, 0);
+}
+
+Fl_Widget *Fl_Widget_Type::enter_live_mode(int top) {
+  live_widget = widget(o->x(), o->y(), o->w(), o->h());
+  if (live_widget)
+    copy_properties();
+  return live_widget;
+}
+
+void Fl_Widget_Type::leave_live_mode() {
+}
+
+/**
+ * copy all properties from the edit widget to the live widget
+ */
+void Fl_Widget_Type::copy_properties() {
+  if (!live_widget) 
+    return;
+
+  // copy all attributes common to all widget types
+  Fl_Widget *w = live_widget;
+  w->label(o->label());
+  w->tooltip(tooltip());
+  w->type(o->type());
+  w->box(o->box());
+  w->color(o->color());
+  w->selection_color(o->selection_color());
+  w->labeltype(o->labeltype());
+  w->labelfont(o->labelfont());
+  w->labelsize(o->labelsize());
+  w->labelcolor(o->labelcolor());
+  w->align(o->align());
+
+  // copy all attributes specific to widgets derived from Fl_Button
+  if (is_button()) {
+    Fl_Button* d = (Fl_Button*)live_widget, *s = (Fl_Button*)o;
+    d->down_box(s->down_box());
+    d->shortcut(s->shortcut());
+    d->value(s->value());
+  }
+
+  // copy all attributes specific to Fl_Valuator and derived classes
+  if (is_valuator()) {
+    Fl_Valuator* d = (Fl_Valuator*)live_widget, *s = (Fl_Valuator*)o;
+    d->minimum(s->minimum());
+    d->maximum(s->maximum());
+    d->step(s->step());
+    d->value(s->value());
+    if (is_valuator()==2) {
+      Fl_Slider *d = (Fl_Slider*)live_widget, *s = (Fl_Slider*)o;
+      d->slider_size(s->slider_size());
+    }
+  }
+ 
+/* TODO: implement this
+  {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
+    Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c);
+    if (f != ff) write_string("textfont %d", f);
+    if (s != fs) write_string("textsize %d", s);
+    if (c != fc) write_string("textcolor %d", c);
+  }}*/
+
+  if (!o->visible()) 
+    w->hide();
+  if (!o->active()) 
+    w->deactivate();
+  if (resizable() && w->parent()) 
+    w->parent()->resizable(o);
+}
+
+void Fl_Pack_Type::copy_properties()
+{
+  Fl_Group_Type::copy_properties();
+  Fl_Pack *d = (Fl_Pack*)live_widget, *s =(Fl_Pack*)o;
+  d->spacing(s->spacing());
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Widget_Type.h b/Utilities/FLTK/fluid/Fl_Widget_Type.h
new file mode 100644
index 0000000000000000000000000000000000000000..487a2cc5e1e451799b05d741eccdd0f1c166c40d
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Widget_Type.h
@@ -0,0 +1,42 @@
+//
+// "$Id$"
+//
+// Widget type header file for the Fast Light Tool Kit (FLTK).
+//
+// Type for creating all subclasses of Fl_Widget
+// This should have the widget pointer in it, but it is still in the
+// Fl_Type base class.
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include "Fl_Type.h"
+
+struct Fl_Menu_Item;
+class Fluid_Image;
+
+void* const LOAD = (void *)9831;
+extern Fl_Widget_Type *current_widget; // one of the selected ones
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fl_Window_Type.cxx b/Utilities/FLTK/fluid/Fl_Window_Type.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..050324d05977b10a28f1d376f2675e022c06721b
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fl_Window_Type.cxx
@@ -0,0 +1,1504 @@
+//
+// "$Id$"
+//
+// Window type code for the Fast Light Tool Kit (FLTK).
+//
+// The widget describing an Fl_Window.  This is also all the code
+// for interacting with the overlay, which allows the user to
+// select, move, and resize the children widgets.
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Overlay_Window.H>
+#include <FL/fl_message.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Round_Button.H>
+#include "Fl_Widget_Type.h"
+#include "undo.h"
+#include <math.h>
+#include <stdlib.h>
+#include "alignment_panel.h"
+#include <stdio.h>
+
+extern int gridx;
+extern int gridy;
+extern int snap;
+extern int show_guides;
+
+int include_H_from_C = 1;
+extern int i18n_type;
+extern const char* i18n_include;
+extern const char* i18n_function;
+extern const char* i18n_file;
+extern const char* i18n_set;
+
+extern Fl_Preferences	fluid_prefs;
+
+inline int fl_min(int a, int b) { return (a < b ? a : b); } 
+
+#include "widget_panel.h"
+
+// Update the XYWH values in the widget panel...
+static void update_xywh() {
+  if (current_widget && current_widget->is_widget()) {
+    widget_x_input->value(((Fl_Widget_Type *)current_widget)->o->x());
+    widget_y_input->value(((Fl_Widget_Type *)current_widget)->o->y());
+    widget_w_input->value(((Fl_Widget_Type *)current_widget)->o->w());
+    widget_h_input->value(((Fl_Widget_Type *)current_widget)->o->h());
+  }
+}
+
+void guides_cb(Fl_Check_Button *i, long) {
+  show_guides = i->value();
+  fluid_prefs.set("show_guides", show_guides);
+
+  for (Fl_Type *p = Fl_Type::first; p; p = p->next) {
+    if (p->is_window()) {
+      Fl_Window_Type *w = (Fl_Window_Type *)p;
+      ((Fl_Overlay_Window *)(w->o))->redraw_overlay();
+    }
+  }
+}
+
+void grid_cb(Fl_Input *i, long v) {
+  int n = atoi(i->value());
+  if (n < 0) n = 0;
+  switch (v) {
+    case 1:
+      gridx = n;
+      fluid_prefs.set("gridx", n);
+      break;
+    case 2:
+      gridy = n;
+      fluid_prefs.set("gridy", n);
+      break;
+    case 3:
+      snap = n;
+      fluid_prefs.set("snap", n);
+      break;
+  }
+
+  // Next go through all of the windows in the project and set the
+  // stepping for resizes...
+  Fl_Type *p;
+  Fl_Window_Type *w;
+
+  for (p = Fl_Type::first; p; p = p->next) {
+    if (p->is_window()) {
+      w = (Fl_Window_Type *)p;
+      ((Fl_Window *)(w->o))->size_range(gridx, gridy,
+                                        Fl::w(), Fl::h(),
+                                        gridx, gridy, 0);
+    }
+  }
+}
+
+// Set default widget sizes...
+void default_widget_size_cb(Fl_Round_Button *b, long size) {
+  // Update the "normal" text size of new widgets...
+  b->setonly();
+  Fl_Widget_Type::default_size = size;
+  fluid_prefs.set("widget_size", Fl_Widget_Type::default_size);
+}
+
+
+void i18n_type_cb(Fl_Choice *c, void *) {
+  undo_checkpoint();
+
+  switch (i18n_type = c->value()) {
+  case 0 : /* None */
+      i18n_include_input->hide();
+      i18n_file_input->hide();
+      i18n_set_input->hide();
+      i18n_function_input->hide();
+      break;
+  case 1 : /* GNU gettext */
+      i18n_include_input->value("<libintl.h>");
+      i18n_include = i18n_include_input->value();
+      i18n_function_input->value("gettext");
+      i18n_function = i18n_function_input->value();
+      i18n_include_input->show();
+      i18n_file_input->hide();
+      i18n_set_input->hide();
+      i18n_function_input->show();
+      break;
+  case 2 : /* POSIX cat */
+      i18n_include_input->value("<nl_types.h>");
+      i18n_file_input->value("");
+      i18n_file = i18n_file_input->value();
+      i18n_set_input->value("1");
+      i18n_set = i18n_set_input->value();
+      i18n_include_input->show();
+      i18n_include = i18n_include_input->value();
+      i18n_file_input->show();
+      i18n_set_input->show();
+      i18n_function_input->hide();
+      break;
+  }
+
+  set_modflag(1);
+}
+
+void i18n_text_cb(Fl_Input *i, void *) {
+  undo_checkpoint();
+
+  if (i == i18n_function_input)
+    i18n_function = i->value();
+  else if (i == i18n_file_input)
+    i18n_file = i->value();
+  else if (i == i18n_set_input)
+    i18n_set = i->value();
+  else if (i == i18n_include_input)
+    i18n_include = i->value();
+
+  set_modflag(1);
+}
+
+extern const char* header_file_name;
+extern const char* code_file_name;
+
+void show_project_cb(Fl_Widget *, void *) {
+  if(project_window==0) make_project_window();
+  include_H_from_C_button->value(include_H_from_C);
+  header_file_input->value(header_file_name);
+  code_file_input->value(code_file_name);
+  i18n_type_chooser->value(i18n_type);
+  i18n_function_input->value(i18n_function);
+  i18n_file_input->value(i18n_file);
+  i18n_set_input->value(i18n_set);
+  i18n_include_input->value(i18n_include);
+  switch (i18n_type) {
+  case 0 : /* None */
+      i18n_include_input->hide();
+      i18n_file_input->hide();
+      i18n_set_input->hide();
+      i18n_function_input->hide();
+      break;
+  case 1 : /* GNU gettext */
+      i18n_include_input->show();
+      i18n_file_input->hide();
+      i18n_set_input->hide();
+      i18n_function_input->show();
+      break;
+  case 2 : /* POSIX cat */
+      i18n_include_input->show();
+      i18n_file_input->show();
+      i18n_set_input->show();
+      i18n_function_input->hide();
+      break;
+  }
+  project_window->hotspot(project_window);
+  project_window->show();
+}
+
+void show_grid_cb(Fl_Widget *, void *) {
+  char buf[128];
+  sprintf(buf,"%d",gridx); horizontal_input->value(buf);
+  sprintf(buf,"%d",gridy); vertical_input->value(buf);
+  sprintf(buf,"%d",snap); snap_input->value(buf);
+  guides_toggle->value(show_guides);
+  int s = Fl_Widget_Type::default_size;
+  if (s<=8) def_widget_size[0]->setonly();
+  else if (s<=11) def_widget_size[1]->setonly();
+  else if (s<=14) def_widget_size[2]->setonly();
+  else if (s<=18) def_widget_size[3]->setonly();
+  else if (s<=24) def_widget_size[4]->setonly();
+  else if (s<=32) def_widget_size[5]->setonly();
+  grid_window->hotspot(grid_window);
+  grid_window->show();
+}
+
+void show_settings_cb(Fl_Widget *, void *) {
+  settings_window->hotspot(settings_window);
+  settings_window->show();
+}
+
+void header_input_cb(Fl_Input* i, void*) {
+  if (header_file_name && strcmp(header_file_name, i->value()))
+    set_modflag(1);
+  header_file_name = i->value();
+}
+void code_input_cb(Fl_Input* i, void*) {
+  if (code_file_name && strcmp(code_file_name, i->value()))
+    set_modflag(1);
+  code_file_name = i->value();
+}
+
+void include_H_from_C_button_cb(Fl_Light_Button* b, void*) {
+  if (include_H_from_C != b->value()) {
+    set_modflag(1);
+    include_H_from_C = b->value();
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item window_type_menu[] = {
+  {"Single",0,0,(void*)FL_WINDOW},
+  {"Double",0,0,(void*)(FL_WINDOW+1)},
+  {0}};
+
+static int overlays_invisible;
+
+// The following Fl_Widget is used to simulate the windows.  It has
+// an overlay for the fluid ui, and special-cases the FL_NO_BOX.
+
+class Overlay_Window : public Fl_Overlay_Window {
+  void draw();
+  void draw_overlay();
+public:
+  Fl_Window_Type *window;
+  int handle(int);
+  Overlay_Window(int W,int H) : Fl_Overlay_Window(W,H) {Fl_Group::current(0);}
+  void resize(int,int,int,int);
+  uchar *read_image(int &ww, int &hh);
+};
+void Overlay_Window::draw() {
+  const int CHECKSIZE = 8;
+  // see if box is clear or a frame or rounded:
+  if ((damage()&FL_DAMAGE_ALL) &&
+      (!box() || (box()>=4&&!(box()&2)) || box()>=_FL_ROUNDED_BOX)) {
+    // if so, draw checkerboard so user can see what areas are clear:
+    for (int Y = 0; Y < h(); Y += CHECKSIZE) 
+      for (int X = 0; X < w(); X += CHECKSIZE) {
+	fl_color(((Y/(2*CHECKSIZE))&1) != ((X/(2*CHECKSIZE))&1) ?
+		 FL_WHITE : FL_BLACK);
+	fl_rectf(X,Y,CHECKSIZE,CHECKSIZE);
+      }
+  }
+  Fl_Overlay_Window::draw();
+}
+
+extern Fl_Window *main_window;
+
+// Read an image of the overlay window
+uchar *Overlay_Window::read_image(int &ww, int &hh) {
+  // Create an off-screen buffer for the window...
+  main_window->make_current();
+
+  ww = w();
+  hh = h();
+
+  Fl_Offscreen offscreen = fl_create_offscreen(ww, hh);
+  uchar *pixels;
+
+  // Redraw the window into the offscreen buffer...
+  fl_begin_offscreen(offscreen);
+
+  if (!shown()) image(Fl::scheme_bg_);
+
+  redraw();
+  draw();
+
+  // Read the screen image...
+  pixels = fl_read_image(0, 0, 0, ww, hh);
+
+  fl_end_offscreen();
+
+  // Cleanup and return...
+  fl_delete_offscreen(offscreen);
+
+  return pixels;
+}
+
+void Overlay_Window::draw_overlay() {
+  window->draw_overlay();
+}
+int Overlay_Window::handle(int e) {
+  return window->handle(e);
+}
+
+Fl_Type *Fl_Window_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_code_block()) p = p->parent;
+  if (!p) {
+    fl_message("Please select a function");
+    return 0;
+  }
+  Fl_Window_Type *myo = new Fl_Window_Type();
+  if (!this->o) {// template widget
+    this->o = new Fl_Window(100,100);
+    Fl_Group::current(0);
+  }
+  // Set the size ranges for this window; in order to avoid opening the
+  // X display we use an arbitrary maximum size...
+  ((Fl_Window *)(this->o))->size_range(gridx, gridy,
+                                       3072, 2048,
+                                       gridx, gridy, 0);
+  myo->factory = this;
+  myo->drag = 0;
+  myo->numselected = 0;
+  Overlay_Window *w = new Overlay_Window(100,100);
+  w->window = myo;
+  myo->o = w;
+  myo->add(p);
+  myo->modal = 0;
+  myo->non_modal = 0;
+  return myo;
+}
+
+void Fl_Window_Type::add_child(Fl_Type* cc, Fl_Type* before) {
+  if (!cc->is_widget()) return;
+  Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+  Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+  ((Fl_Window*)o)->insert(*(c->o), b);
+  o->redraw();
+}
+
+void Fl_Window_Type::remove_child(Fl_Type* cc) {
+  Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+  ((Fl_Window*)o)->remove(c->o);
+  o->redraw();
+}
+
+void Fl_Window_Type::move_child(Fl_Type* cc, Fl_Type* before) {
+  Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+  ((Fl_Window*)o)->remove(c->o);
+  Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+  ((Fl_Window*)o)->insert(*(c->o), b);
+  o->redraw();
+}
+
+////////////////////////////////////////////////////////////////
+
+// Double-click on window widget shows the window, or if already shown,
+// it shows the control panel.
+void Fl_Window_Type::open() {
+  Overlay_Window *w = (Overlay_Window *)o;
+  if (w->shown()) {
+    w->show();
+    Fl_Widget_Type::open();
+  } else {
+    Fl_Widget *p = w->resizable();
+    if (!p) w->resizable(w);
+    w->show();
+    w->resizable(p);
+  }
+
+  w->image(Fl::scheme_bg_);
+  w->size_range(gridx, gridy, Fl::w(), Fl::h(), gridx, gridy, 0);
+}
+
+// Read an image of the window
+uchar *Fl_Window_Type::read_image(int &ww, int &hh) {
+  Overlay_Window *w = (Overlay_Window *)o;
+
+  // Read the screen image...
+  return (w->read_image(ww, hh));
+}
+
+
+// control panel items:
+
+void modal_cb(Fl_Light_Button* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) {i->hide(); return;}
+    i->show();
+    i->value(((Fl_Window_Type *)current_widget)->modal);
+  } else {
+    ((Fl_Window_Type *)current_widget)->modal = i->value();
+    set_modflag(1);
+  }
+}
+
+void non_modal_cb(Fl_Light_Button* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) {i->hide(); return;}
+    i->show();
+    i->value(((Fl_Window_Type *)current_widget)->non_modal);
+  } else {
+    ((Fl_Window_Type *)current_widget)->non_modal = i->value();
+    set_modflag(1);
+  }
+}
+
+void border_cb(Fl_Light_Button* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) {i->hide(); return;}
+    i->show();
+    i->value(((Fl_Window*)(current_widget->o))->border());
+  } else {
+    ((Fl_Window*)(current_widget->o))->border(i->value());
+    set_modflag(1);
+  }
+}
+
+void xclass_cb(Fl_Input* i, void* v) {
+  if (v == LOAD) {
+    if (!current_widget->is_window()) {
+      i->hide(); 
+      i->parent()->hide(); // hides the "X Class:" label as well
+      return;
+    }
+    i->show();
+    i->parent()->show();
+    i->value(((Fl_Widget_Type *)current_widget)->xclass);
+  } else {
+    int mod = 0;
+    for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+      if (o->selected && o->is_widget()) {
+        mod = 1;
+	Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+	if (w->is_window() || w->is_button())
+	  storestring(i->value(),w->xclass);
+	if (w->is_window()) ((Fl_Window*)(w->o))->xclass(w->xclass);
+	else if (w->is_menu_item()) w->redraw();
+      }
+    }
+    if (mod) set_modflag(1);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Window_Type::setlabel(const char *n) {
+  if (o) ((Fl_Window *)o)->label(n);
+}
+
+// make() is called on this widget when user picks window off New menu:
+Fl_Window_Type Fl_Window_type;
+
+// Resize from window manager...
+void Overlay_Window::resize(int X,int Y,int W,int H) {
+  Fl_Widget* t = resizable(); resizable(0);
+  Fl_Overlay_Window::resize(X,Y,W,H);
+  resizable(t);
+  update_xywh();
+}
+
+// calculate actual move by moving mouse position (mx,my) to
+// nearest multiple of gridsize, and snap to original position
+void Fl_Window_Type::newdx() {
+  int mydx, mydy;
+  if (Fl::event_state(FL_ALT) || !snap) {
+    mydx = mx-x1;
+    mydy = my-y1;
+
+    if (abs(mydx) < 2 && abs(mydy) < 2) mydx = mydy = 0;
+  } else {
+    int dx0 = mx-x1;
+    int ix = (drag&RIGHT) ? br : bx;
+    mydx = gridx ? ((ix+dx0+gridx/2)/gridx)*gridx - ix : dx0;
+    if (dx0 > snap) {
+      if (mydx < 0) mydx = 0;
+    } else if (dx0 < -snap) {
+      if (mydx > 0) mydx = 0;
+    } else 
+      mydx = 0;
+    int dy0 = my-y1;
+    int iy = (drag&BOTTOM) ? by : bt;
+    mydy = gridy ? ((iy+dy0+gridy/2)/gridy)*gridy - iy : dy0;
+    if (dy0 > snap) {
+      if (mydy < 0) mydy = 0;
+    } else if (dy0 < -snap) {
+      if (mydy > 0) mydy = 0;
+    } else 
+      mydy = 0;
+  }
+
+  if (!(drag & (DRAG | BOX | LEFT | RIGHT))) {
+    mydx = 0;
+    dx = 0;
+  }
+
+  if (!(drag & (DRAG | BOX | TOP | BOTTOM))) {
+    mydy = 0;
+    dy = 0;
+  }
+
+  if (dx != mydx || dy != mydy) {
+    dx = mydx; dy = mydy;
+    ((Overlay_Window *)o)->redraw_overlay();
+  }
+}
+
+// Move a widget according to dx and dy calculated above
+void Fl_Window_Type::newposition(Fl_Widget_Type *myo,int &X,int &Y,int &R,int &T) {
+  X = myo->o->x();
+  Y = myo->o->y();
+  R = X+myo->o->w();
+  T = Y+myo->o->h();
+  if (!drag) return;
+  if (drag&DRAG) {
+    X += dx;
+    Y += dy;
+    R += dx;
+    T += dy;
+  } else {
+    if (drag&LEFT) if (X==bx) X += dx; else if (X<bx+dx) X = bx+dx;
+    if (drag&TOP) if (Y==by) Y += dy; else if (Y<by+dy) Y = by+dy;
+    if (drag&RIGHT) if (R==br) R += dx; else if (R>br+dx) R = br+dx;
+    if (drag&BOTTOM) if (T==bt) T += dy; else if (T>bt+dx) T = bt+dx;
+  }
+  if (R<X) {int n = X; X = R; R = n;}
+  if (T<Y) {int n = Y; Y = T; T = n;}
+}
+
+// draw a vertical arrow pointing toward y2
+static void draw_v_arrow(int x, int y1, int y2) {
+  int dy = (y1>y2) ? -1 : 1 ;
+  fl_yxline(x, y1, y2);
+  fl_xyline(x-4, y2, x+4);
+  fl_line(x-2, y2-dy*5, x, y2-dy);
+  fl_line(x+2, y2-dy*5, x, y2-dy);
+}
+
+static void draw_h_arrow(int x1, int y, int x2) {
+  int dx = (x1>x2) ? -1 : 1 ;
+  fl_xyline(x1, y, x2);
+  fl_yxline(x2, y-4, y+4);
+  fl_line(x2-dx*5, y-2, x2-dx, y);
+  fl_line(x2-dx*5, y+2, x2-dx, y);
+}
+
+static void draw_top_brace(const Fl_Widget *w) {
+  fl_yxline(w->x(), w->y()-2, w->y()+6);
+  fl_yxline(w->x()+w->w()-1, w->y()-2, w->y()+6);
+  fl_xyline(w->x()-2, w->y(), w->x()+w->w()+1);
+}
+
+static void draw_left_brace(const Fl_Widget *w) {
+  fl_xyline(w->x()-2, w->y(), w->x()+6);
+  fl_xyline(w->x()-2, w->y()+w->h()-1, w->x()+6);
+  fl_yxline(w->x(), w->y()-2, w->y()+w->h()+1);
+}
+
+static void draw_right_brace(const Fl_Widget *w) {
+  int xx = w->x() + w->w() - 1;
+  fl_xyline(xx-6, w->y(), xx+2);
+  fl_xyline(xx-6, w->y()+w->h()-1, xx+2);
+  fl_yxline(xx, w->y()-2, w->y()+w->h()+1);
+}
+
+static void draw_bottom_brace(const Fl_Widget *w) {
+  int yy = w->y() + w->h() - 1;
+  fl_yxline(w->x(), yy-6, yy+2);
+  fl_yxline(w->x()+w->w()-1, yy-6, yy+2);
+  fl_xyline(w->x()-2, yy, w->x()+w->w()+1);
+}
+
+static void draw_height(int x, int y, int b, Fl_Align a) {
+  char buf[16];
+  int h = b - y;
+  sprintf(buf, "%d", h);
+  fl_font(FL_HELVETICA, 9);
+  int lw = (int)fl_width(buf);
+  int lx;
+
+  b --;
+  if (h < 30) {
+    // Move height to the side...
+    if (a == FL_ALIGN_LEFT) lx = x - lw - 2;
+    else lx = x + 2;
+
+    fl_yxline(x, y, b);
+  } else {
+    // Put height inside the arrows...
+    lx = x - lw / 2;
+
+    fl_yxline(x, y, y + (h - 11) / 2);
+    fl_yxline(x, y + (h + 11) / 2, b);
+  }
+
+  // Draw the height...
+  fl_draw(buf, lx, y + (h + 9) / 2);
+
+  // Draw the arrowheads...
+  fl_line(x-2, y+5, x, y+1, x+2, y+5);
+  fl_line(x-2, b-5, x, b-1, x+2, b-5);
+
+  // Draw the end lines...
+  fl_xyline(x - 4, y, x + 4);
+  fl_xyline(x - 4, b, x + 4);
+}
+
+static void draw_width(int x, int y, int r, Fl_Align a) {
+  char buf[16];
+  int w = r-x;
+  sprintf(buf, "%d", w);
+  fl_font(FL_HELVETICA, 9);
+  int lw = (int)fl_width(buf);
+  int ly = y + 4;
+
+  r --;
+
+  if (lw > (w - 20)) {
+    // Move width above/below the arrows...
+    if (a == FL_ALIGN_TOP) ly -= 10;
+    else ly += 10;
+
+    fl_xyline(x, y, r);
+  } else {
+    // Put width inside the arrows...
+    fl_xyline(x, y, x + (w - lw - 2) / 2);
+    fl_xyline(x + (w + lw + 2) / 2, y, r);
+  }
+
+  // Draw the width...
+  fl_draw(buf, x + (w - lw) / 2, ly);
+
+  // Draw the arrowheads...
+  fl_line(x+5, y-2, x+1, y, x+5, y+2);
+  fl_line(r-5, y-2, r-1, y, r-5, y+2);
+
+  // Draw the end lines...
+  fl_yxline(x, y - 4, y + 4);
+  fl_yxline(r, y - 4, y + 4);
+}
+
+void Fl_Window_Type::draw_overlay() {
+  if (recalc) {
+    bx = o->w(); by = o->h(); br = 0; bt = 0;
+    numselected = 0;
+    for (Fl_Type *q=next; q && q->level>level; q=q->next)
+      if (q->selected && q->is_widget() && !q->is_menu_item()) {
+	numselected++;
+	Fl_Widget_Type* myo = (Fl_Widget_Type*)q;
+	if (myo->o->x() < bx) bx = myo->o->x();
+	if (myo->o->y() < by) by = myo->o->y();
+	if (myo->o->x()+myo->o->w() > br) br = myo->o->x()+myo->o->w();
+	if (myo->o->y()+myo->o->h() > bt) bt = myo->o->y()+myo->o->h();
+      }
+    recalc = 0;
+    sx = bx; sy = by; sr = br; st = bt;
+  }
+  fl_color(FL_RED);
+  if (drag==BOX && (x1 != mx || y1 != my)) {
+    int x = x1; int r = mx; if (x > r) {x = mx; r = x1;}
+    int y = y1; int b = my; if (y > b) {y = my; b = y1;}
+    fl_rect(x,y,r-x,b-y);
+  }
+  if (overlays_invisible && !drag) return;
+  if (selected) fl_rect(0,0,o->w(),o->h());
+  if (!numselected) return;
+  int mybx,myby,mybr,mybt;
+  int mysx,mysy,mysr,myst;
+  mybx = mysx = o->w(); myby = mysy = o->h(); mybr = mysr = 0; mybt = myst = 0;
+  Fl_Type *selection = 0L; // used to store the one selected widget (if n==1)
+  for (Fl_Type *q=next; q && q->level>level; q = q->next)
+    if (q->selected && q->is_widget() && !q->is_menu_item()) {
+      selection = q;
+      Fl_Widget_Type* myo = (Fl_Widget_Type*)q;
+      int x,y,r,t;
+      newposition(myo,x,y,r,t);
+      if (!show_guides || !drag || numselected != 1) fl_rect(x,y,r-x,t-y);
+      if (x < mysx) mysx = x;
+      if (y < mysy) mysy = y;
+      if (r > mysr) mysr = r;
+      if (t > myst) myst = t;
+      if (!(myo->o->align() & FL_ALIGN_INSIDE)) {
+        // Adjust left/right/top/bottom for top/bottom labels...
+	int ww, hh;
+	ww = (myo->o->align() & FL_ALIGN_WRAP) ? myo->o->w() : 0;
+	hh = myo->o->labelsize();
+	myo->o->measure_label(ww, hh);
+	if (myo->o->align() & FL_ALIGN_TOP) y -= hh;
+	else if (myo->o->align() & FL_ALIGN_BOTTOM) t += hh;
+	else if (myo->o->align() & FL_ALIGN_LEFT) x -= ww + 4;
+	else if (myo->o->align() & FL_ALIGN_RIGHT) r += ww + 4;
+      }
+      if (x < mybx) mybx = x;
+      if (y < myby) myby = y;
+      if (r > mybr) mybr = r;
+      if (t > mybt) mybt = t;
+    }
+  if (selected) return;
+
+  if (show_guides && drag) {
+    // draw overlays for UI Guideline distances
+    // - check for distance to the window edge
+    //    * FLTK suggests 10 pixels from the edge
+    int d;
+    int xsp, ysp;
+    int mybx_bak = mybx, myby_bak = myby, mybr_bak = mybr, mybt_bak = mybt;
+    Fl_Widget_Type *mysel = (Fl_Widget_Type *)selection;
+
+
+    ideal_spacing(xsp, ysp);
+
+    if (drag) {
+      // Check top spacing...
+      if (abs(d = myby - ysp) < 3) {
+	dy -= d;
+	if (drag & DRAG) mybt -= d;
+	myby -= d;
+	draw_v_arrow(mybx+5, myby, 0);
+      }
+
+      // Check bottom spacing...
+      if (abs(d = o->h() - mybt - ysp) < 3) {
+	dy += d;
+	if (drag & DRAG) myby += d;
+	mybt += d;
+	draw_v_arrow(mybx+5, mybt, o->h());
+      }
+
+      // Check left spacing...
+      if (abs(d = mybx - xsp) < 3) {
+        dx -= d;
+	if (drag & DRAG) mybr -= d;
+	mybx -= d;
+	draw_h_arrow(mybx, myby+5, 0);
+      }
+
+      // Check right spacing...
+      if (abs(d = o->w() - mybr - xsp) < 3) {
+	dx += d;
+	if (drag & DRAG) mybx += d;
+	mybr += d;
+	draw_h_arrow(mybr, myby+5, o->w());
+      }
+    }
+
+    if (numselected==1 && selection && !(drag & DRAG)) {
+      // Check ideal sizes
+      int x,y,r,t;
+      newposition(mysel,x,y,r,t);
+      int w = r-x;
+      int h = t-y;
+      int iw = w, ih = h;
+
+      mysel->ideal_size(iw, ih);
+
+      if (drag & (TOP | BOTTOM)) {
+	// Check height
+	if (abs(d = ih - h) < 5) {
+          // Resize height
+	  if (drag & TOP) {
+	    myby -= d;
+	    y -= d;
+	    dy -= d;
+	  } else {
+	    mybt += d;
+	    t += d;
+	    dy += d;
+	  }
+	}
+
+	// Draw height guide
+	draw_height(x < 50 ? x+10 : x-10, y, t,
+	            x < 50 ? FL_ALIGN_RIGHT : FL_ALIGN_LEFT);
+      }
+
+      if (drag & (LEFT | RIGHT)) {
+	// Check width
+	if (abs(d = iw - w) < 5) {
+          // Resize width
+          if (drag & LEFT) {
+	    mybx -= d;
+	    x -= d;
+	    dx -= d;
+	  } else {
+	    mybr += d;
+	    r += d;
+	    dx += d;
+	  }
+	}
+
+	// Draw width guide
+	draw_width(x, y < 50 ? y+10 : y-10, r,
+	           y < 50 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP);
+      }
+    }
+
+    // Check spacing and alignment between individual widgets
+    if (drag && selection->is_widget()) {
+      for (Fl_Type *q=next; q && q->level>level; q = q->next)
+	if (q != selection && q->is_widget()) {
+          Fl_Widget_Type *qw = (Fl_Widget_Type*)q;
+          // Only check visible widgets...
+	  if (!qw->o->visible_r()) continue;
+
+          // Get bounding box of widget...
+	  int qx = qw->o->x();
+	  int qr = qw->o->x() + qw->o->w();
+	  int qy = qw->o->y();
+	  int qt = qw->o->y() + qw->o->h();
+
+	  if (!(qw->o->align() & FL_ALIGN_INSIDE)) {
+            // Adjust top/bottom for top/bottom labels...
+	    int ww, hh;
+	    ww = qw->o->w();
+	    hh = qw->o->labelsize();
+	    qw->o->measure_label(ww, hh);
+	    if (qw->o->align() & FL_ALIGN_TOP) qy -= hh;
+	    if (qw->o->align() & FL_ALIGN_BOTTOM) qt += hh;
+	  }
+
+          // Do horizontal alignment when the widget is within 25
+	  // pixels vertically...
+	  if (fl_min(abs(qy - mysel->o->y() - mysel->o->h()),
+	             abs(mysel->o->y() - qt)) < 25) {
+            // Align to left of other widget...
+            if ((drag & (LEFT | DRAG)) && abs(d = mybx - qx) < 3) {
+	      dx += d;
+              mybx += d;
+	      if (drag & DRAG) mybr += d;
+
+	      draw_left_brace(qw->o);
+	    }
+
+            // Align to right of other widget...
+            if ((drag & (RIGHT | DRAG)) &&
+	        abs(d = qr - mybr) < 3) {
+	      dx += d;
+              if (drag & DRAG) mybx += d;
+	      mybr += d;
+
+	      draw_right_brace(qw->o);
+	    }
+          }
+
+          // Align to top of other widget...
+          if ((drag & (TOP | DRAG)) && abs(d = myby - qy) < 3) {
+	    dy += d;
+            myby += d;
+	    if (drag & DRAG) mybt += d;
+
+	    draw_top_brace(qw->o);
+	  }
+
+          // Align to bottom of other widget...
+          if ((drag & (BOTTOM | DRAG)) && abs(d = qt - mybt) < 3) {
+	    dy += d;
+            if (drag & DRAG) myby += d;
+	    mybt += d;
+
+	    draw_bottom_brace(qw->o);
+	  }
+
+          // Check spacing between widgets
+	  if (mysel->is_group()) mysel->ideal_spacing(xsp, ysp);
+          else qw->ideal_spacing(xsp, ysp);
+
+          if ((qt)>=myby && qy<=mybt) {
+            if (drag & (LEFT | DRAG)) {
+	      // Compare left of selected to left of current
+	      if (abs(d = qx - mybx - xsp) >= 3)
+	        d = qx - mybx + xsp;
+
+	      if (abs(d) < 3) {
+		dx += d;
+        	mybx += d;
+		if (drag & DRAG) mybr += d;
+
+        	// Draw left arrow
+		draw_h_arrow(mybx, (myby+mybt)/2, qx);
+              }
+
+	      // Compare left of selected to right of current
+              if (abs(d = qr - mybx - xsp) >= 3)
+	        d = qr - mybx + xsp;
+
+	      if (abs(d) < 3) {
+		dx += d;
+        	mybx += d;
+		if (drag & DRAG) mybr += d;
+
+        	// Draw left arrow
+		draw_h_arrow(mybx, (myby+mybt)/2, qr);
+              }
+	    }
+
+            if (drag & (RIGHT | DRAG)) {
+	      // Compare right of selected to left of current
+	      if (abs(d = qx - mybr - xsp) >= 3)
+	        d = qx - mybr + xsp;
+
+	      if (abs(d) < 3) {
+		dx += d;
+        	if (drag & DRAG) mybx += d;
+		mybr += d;
+
+        	// Draw right arrow
+		draw_h_arrow(mybr, (myby+mybt)/2, qx);
+              }
+
+	      // Compare right of selected to right of current
+              if (abs(d = qr - mybr + xsp) >= 3)
+	        d = qr - mybr - xsp;
+
+              if (abs(d) < 3) {
+		dx += d;
+        	if (drag & DRAG) mybx += d;
+		mybr += d;
+
+        	// Draw right arrow
+		draw_h_arrow(mybr, (myby+mybt)/2, qr);
+              }
+            }
+	  }
+
+          if (qr>=mybx && qx<=mybr) {
+            // Compare top of selected to top of current
+            if (drag & (TOP | DRAG)) {
+	      if (abs(d = qy - myby - ysp) >= 3)
+	        d = qy - myby + ysp;
+
+	      if (abs(d) < 3) {
+		dy += d;
+		myby += d;
+		if (drag & DRAG) mybt += d;
+
+		// Draw up arrow...
+		draw_v_arrow((mybx+mybr)/2, myby, qy);
+              }
+
+              // Compare top of selected to bottom of current
+              if (abs(d = qt - myby - ysp) >= 3)
+                d = qt - myby + ysp;
+
+              if (abs(d) < 3) {
+		dy += d;
+		myby += d;
+		if (drag & DRAG) mybt += d;
+
+		// Draw up arrow...
+		draw_v_arrow((mybx+mybr)/2, myby, qt);
+              }
+	    }
+
+	    // Compare bottom of selected to top of current
+            if (drag & (BOTTOM | DRAG)) {
+	      if (abs(d = qy - mybt - ysp) >= 3)
+	        d = qy - mybt + ysp;
+
+	      if (abs(d) < 3) {
+		dy += d;
+		if (drag & DRAG) myby += d;
+		mybt += d;
+
+		// Draw down arrow...
+		draw_v_arrow((mybx+mybr)/2, mybt, qy);
+              }
+
+	      // Compare bottom of selected to bottom of current
+              if (abs(d = qt - mybt - ysp) >= 3)
+                d = qt - mybt + ysp;
+
+              if (abs(d) < 3) {
+		dy += d;
+		if (drag & DRAG) myby += d;
+		mybt += d;
+
+		// Draw down arrow...
+		draw_v_arrow((mybx+mybr)/2, mybt, qt);
+              }
+	    }
+          }
+	}
+    }
+    mysx += mybx-mybx_bak; mysr += mybr-mybr_bak;
+    mysy += myby-myby_bak; myst += mybt-mybt_bak;
+  }
+  // align the snapping selection box with the box we draw.
+  sx = mysx; sy = mysy; sr = mysr; st = myst;
+
+  // Draw selection box + resize handles...
+  // draw box including all labels
+  fl_line_style(FL_DOT);
+  fl_rect(mybx,myby,mybr-mybx,mybt-myby);
+  fl_line_style(FL_SOLID);
+  // draw box excluding labels
+  fl_rect(mysx,mysy,mysr-mysx,myst-mysy);
+  fl_rectf(mysx,mysy,5,5);
+  fl_rectf(mysr-5,mysy,5,5);
+  fl_rectf(mysr-5,myst-5,5,5);
+  fl_rectf(mysx,myst-5,5,5);
+}
+
+extern Fl_Menu_Item Main_Menu[];
+
+// Calculate new bounding box of selected widgets:
+void Fl_Window_Type::fix_overlay() {
+  Main_Menu[40].label("Hide O&verlays");
+  overlays_invisible = 0;
+  recalc = 1;
+  ((Overlay_Window *)(this->o))->redraw_overlay();
+}
+
+// do that for every window (when selected set changes):
+void redraw_overlays() {
+  for (Fl_Type *o=Fl_Type::first; o; o=o->next)
+    if (o->is_window()) ((Fl_Window_Type*)o)->fix_overlay();
+}
+
+void toggle_overlays(Fl_Widget *,void *) {
+  overlays_invisible = !overlays_invisible;
+
+  if (overlays_invisible) Main_Menu[40].label("Show O&verlays");
+  else Main_Menu[40].label("Hide O&verlays");
+
+  for (Fl_Type *o=Fl_Type::first; o; o=o->next)
+    if (o->is_window()) {
+      Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+      ((Overlay_Window*)(w->o))->redraw_overlay();
+    }
+}
+
+extern void select(Fl_Type *,int);
+extern void select_only(Fl_Type *);
+extern void deselect();
+extern Fl_Type* in_this_only;
+extern void fix_group_size(Fl_Type *t);
+
+extern Fl_Menu_Item Main_Menu[];
+extern Fl_Menu_Item New_Menu[];
+
+// move the selected children according to current dx,dy,drag state:
+void Fl_Window_Type::moveallchildren()
+{
+  undo_checkpoint();
+  Fl_Type *i;
+  for (i=next; i && i->level>level;) {
+    if (i->selected && i->is_widget() && !i->is_menu_item()) {
+      Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+      int x,y,r,t;
+      newposition(myo,x,y,r,t);
+      myo->o->resize(x,y,r-x,t-y);
+      // move all the children, whether selected or not:
+      Fl_Type* p;
+      for (p = myo->next; p && p->level>myo->level; p = p->next)
+	if (p->is_widget() && !p->is_menu_item()) {
+	  Fl_Widget_Type* myo2 = (Fl_Widget_Type*)p;
+	  int X,Y,R,T;
+	  newposition(myo2,X,Y,R,T);
+	  myo2->o->resize(X,Y,R-X,T-Y);
+	}
+      i = p;
+    } else {
+      i = i->next;
+    }
+  }
+  for (i=next; i && i->level>level; i=i->next) 
+    fix_group_size(i);
+  o->redraw();
+  recalc = 1;
+  ((Overlay_Window *)(this->o))->redraw_overlay();
+  set_modflag(1);
+  dx = dy = 0;
+
+  update_xywh();
+}
+
+int Fl_Window_Type::handle(int event) {
+  static Fl_Type* selection;
+  switch (event) {
+  case FL_PUSH:
+    x1 = mx = Fl::event_x();
+    y1 = my = Fl::event_y();
+    drag = dx = dy = 0;
+    // test for popup menu:
+    if (Fl::event_button() >= 3) {
+      in_this_only = this; // modifies how some menu items work.
+      static const Fl_Menu_Item* myprev;
+      const Fl_Menu_Item* m = New_Menu->popup(mx,my,"New",myprev);
+      if (m && m->callback()) {myprev = m; m->do_callback(this->o);}
+      in_this_only = 0;
+      return 1;
+    }
+    // find the innermost item clicked on:
+    selection = this;
+    {for (Fl_Type* i=next; i && i->level>level; i=i->next)
+      if (i->is_widget() && !i->is_menu_item()) {
+      Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+      for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent())
+	if (!o1->visible()) goto CONTINUE2;
+      if (Fl::event_inside(myo->o)) selection = myo;
+    CONTINUE2:;
+    }}
+    // see if user grabs edges of selected region:
+    if (numselected && !(Fl::event_state(FL_SHIFT)) &&
+	mx<=br+snap && mx>=bx-snap && my<=bt+snap && my>=by-snap) {
+      int snap1 = snap>5 ? snap : 5;
+      int w1 = (br-bx)/4; if (w1 > snap1) w1 = snap1;
+      if (mx>=br-w1) drag |= RIGHT;
+      else if (mx<bx+w1) drag |= LEFT;
+      w1 = (bt-by)/4; if (w1 > snap1) w1 = snap1;
+      if (my<=by+w1) drag |= TOP;
+      else if (my>bt-w1) drag |= BOTTOM;
+      if (!drag) drag = DRAG;
+    }
+    // do object-specific selection of other objects:
+    {Fl_Type* t = selection->click_test(mx, my);
+    if (t) {
+      //if (t == selection) return 1; // indicates mouse eaten w/o change
+      if (Fl::event_state(FL_SHIFT)) {
+	Fl::event_is_click(0);
+	select(t, !t->selected);
+      } else {
+	deselect();
+	select(t, 1);
+	if (t->is_menu_item()) t->open();
+      }
+      selection = t;
+      drag = 0;
+    } else {
+      if (!drag) drag = BOX; // if all else fails, start a new selection region
+    }}
+    return 1;
+
+  case FL_DRAG:
+    if (!drag) return 0;
+    mx = Fl::event_x();
+    my = Fl::event_y();
+    newdx();
+    return 1;
+
+  case FL_RELEASE:
+    if (!drag) return 0;
+    mx = Fl::event_x();
+    my = Fl::event_y();
+    if (drag != BOX && (dx || dy || !Fl::event_is_click())) {
+      if (dx || dy) moveallchildren();
+    } else if ((Fl::event_clicks() || Fl::event_state(FL_CTRL))) {
+      Fl_Widget_Type::open();
+    } else {
+      if (mx<x1) {int t = x1; x1 = mx; mx = t;}
+      if (my<y1) {int t = y1; y1 = my; my = t;}
+      int n = 0;
+      int toggle = Fl::event_state(FL_SHIFT);
+      // clear selection on everything:
+      if (!toggle) deselect(); else Fl::event_is_click(0);
+      // select everything in box:
+      for (Fl_Type*i=next; i&&i->level>level; i=i->next)
+	if (i->is_widget() && !i->is_menu_item()) {
+	Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+	for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent())
+	  if (!o1->visible()) goto CONTINUE;
+	if (Fl::event_inside(myo->o)) selection = myo;
+	if (myo->o->x()>=x1 && myo->o->y()>y1 &&
+	    myo->o->x()+myo->o->w()<mx && myo->o->y()+myo->o->h()<my) {
+	  n++;
+	  select(myo, toggle ? !myo->selected : 1);
+	}
+      CONTINUE:;
+      }
+      // if nothing in box, select what was clicked on:
+      if (!n) {
+	select(selection, toggle ? !selection->selected : 1);
+      }
+    }
+    drag = 0;
+    ((Overlay_Window *)o)->redraw_overlay();
+    return 1;
+
+  case FL_KEYBOARD: {
+
+    int backtab = 0;
+    switch (Fl::event_key()) {
+
+    case FL_Escape:
+      ((Fl_Window*)o)->hide();
+      return 1;
+
+    case 0xFE20: // backtab
+      backtab = 1;
+    case FL_Tab: {
+      if (Fl::event_state(FL_SHIFT)) backtab = 1;
+      // find current child:
+      Fl_Type *i = Fl_Type::current;
+      while (i && (!i->is_widget() || i->is_menu_item())) i = i->parent;
+      if (!i) return 0;
+      Fl_Type *p = i->parent;
+      while (p && p != this) p = p->parent;
+      if (!p || !p->is_widget()) {
+	i = next; if (!i || i->level <= level) return 0;
+      }
+      p = i;
+      for (;;) {
+	i = backtab ? i->prev : i->next;
+	if (!i || i->level <= level) {i = p; break;}
+	if (i->is_widget() && !i->is_menu_item()) break;
+      }
+      deselect(); select(i,1);
+      return 1;}
+
+    case FL_Left:  dx = -1; dy = 0; goto ARROW;
+    case FL_Right: dx = +1; dy = 0; goto ARROW;
+    case FL_Up:    dx = 0; dy = -1; goto ARROW;
+    case FL_Down:  dx = 0; dy = +1; goto ARROW;
+    ARROW:
+      // for some reason BOTTOM/TOP are swapped... should be fixed...
+      drag = (Fl::event_state(FL_SHIFT)) ? (RIGHT|TOP) : DRAG;
+      if (Fl::event_state(FL_CTRL)) {dx *= gridx; dy *= gridy;}
+      moveallchildren();
+      drag = 0;
+      return 1;
+
+    case 'o':
+      toggle_overlays(0, 0);
+      break;
+
+    default:
+      return 0;
+    }}
+
+  case FL_SHORTCUT: {
+    in_this_only = this; // modifies how some menu items work.
+    const Fl_Menu_Item* m = Main_Menu->test_shortcut();
+    if (m && m->callback()) m->do_callback(this->o);
+    in_this_only = 0;
+    return (m != 0);}
+
+  default:
+    return 0;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "../src/flstring.h"
+
+void Fl_Window_Type::write_code1() {
+  Fl_Widget_Type::write_code1();
+}
+
+void Fl_Window_Type::write_code2() {
+  write_extra_code();
+  if (modal) write_c("%so->set_modal();\n", indent());
+  else if (non_modal) write_c("%so->set_non_modal();\n", indent());
+  if (!((Fl_Window*)o)->border()) write_c("%so->clear_border();\n", indent());
+  if (xclass) {
+    write_c("%so->xclass(", indent());
+    write_cstring(xclass);
+    write_c(");\n");
+  }
+  if (sr_max_w || sr_max_h) {
+    write_c("%so->size_range(%d, %d, %d, %d);\n", indent(), sr_min_w, sr_min_h, sr_max_w, sr_max_h);
+  } else if (sr_min_w || sr_min_h) {
+    write_c("%so->size_range(%d, %d);\n", indent(), sr_min_w, sr_min_h);
+  }
+  write_c("%so->end();\n", indent());
+  if (((Fl_Window*)o)->resizable() == o)
+    write_c("%so->resizable(o);\n", indent());
+  write_block_close();
+}
+
+void Fl_Window_Type::write_properties() {
+  Fl_Widget_Type::write_properties();
+  if (modal) write_string("modal");
+  else if (non_modal) write_string("non_modal");
+  if (!((Fl_Window*)o)->border()) write_string("noborder");
+  if (xclass) {write_string("xclass"); write_word(xclass);}
+  if (sr_min_w || sr_min_h || sr_max_w || sr_max_h)
+    write_string("size_range {%d %d %d %d}", sr_min_w, sr_min_h, sr_max_w, sr_max_h);
+  if (o->visible()) write_string("visible");
+}
+
+extern int pasteoffset;
+void Fl_Window_Type::read_property(const char *c) {
+  if (!strcmp(c,"modal")) {
+    modal = 1;
+  } else if (!strcmp(c,"non_modal")) {
+    non_modal = 1;
+  } else if (!strcmp(c, "visible")) {
+    if (Fl::first_window()) open(); // only if we are using user interface
+  } else if (!strcmp(c,"noborder")) {
+    ((Fl_Window*)o)->border(0);
+  } else if (!strcmp(c,"xclass")) {
+    storestring(read_word(),xclass);
+    ((Fl_Window*)o)->xclass(xclass);
+  } else if (!strcmp(c,"size_range")) {
+    int mw, mh, MW, MH;
+    if (sscanf(read_word(),"%d %d %d %d",&mw,&mh,&MW,&MH) == 4) {
+      sr_min_w = mw; sr_min_h = mh; sr_max_w = MW; sr_max_h = MH;
+    }
+  } else if (!strcmp(c,"xywh")) {
+    Fl_Widget_Type::read_property(c);
+    pasteoffset = 0; // make it not apply to contents
+  } else {
+    Fl_Widget_Type::read_property(c);
+  }
+}
+
+int Fl_Window_Type::read_fdesign(const char* propname, const char* value) {
+  int x;
+  o->box(FL_NO_BOX); // because fdesign always puts an Fl_Box next
+  if (!strcmp(propname,"Width")) {
+    if (sscanf(value,"%d",&x) == 1) o->size(x,o->h());
+  } else if (!strcmp(propname,"Height")) {
+    if (sscanf(value,"%d",&x) == 1) o->size(o->w(),x);
+  } else if (!strcmp(propname,"NumberofWidgets")) {
+    return 1; // we can figure out count from file
+  } else if (!strcmp(propname,"border")) {
+    if (sscanf(value,"%d",&x) == 1) ((Fl_Window*)o)->border(x);
+  } else if (!strcmp(propname,"title")) {
+    label(value);
+  } else {
+    return Fl_Widget_Type::read_fdesign(propname,value);
+  }
+  return 1;
+}
+
+///////////////////////////////////////////////////////////////////////
+
+Fl_Widget_Class_Type Fl_Widget_Class_type;
+Fl_Widget_Class_Type *current_widget_class = 0;
+
+Fl_Type *Fl_Widget_Class_Type::make() {
+  Fl_Type *p = Fl_Type::current;
+  while (p && !p->is_decl_block()) p = p->parent;
+  Fl_Widget_Class_Type *myo = new Fl_Widget_Class_Type();
+  myo->name("UserInterface");
+
+  if (!this->o) {// template widget
+    this->o = new Fl_Window(100,100);
+    Fl_Group::current(0);
+  }
+  // Set the size ranges for this window; in order to avoid opening the
+  // X display we use an arbitrary maximum size...
+  ((Fl_Window *)(this->o))->size_range(gridx, gridy,
+                                       3072, 2048,
+                                       gridx, gridy, 0);
+  myo->factory = this;
+  myo->drag = 0;
+  myo->numselected = 0;
+  Overlay_Window *w = new Overlay_Window(100,100);
+  w->window = myo;
+  myo->o = w;
+  myo->add(p);
+  myo->modal = 0;
+  myo->non_modal = 0;
+  myo->wc_relative = 0;
+
+  return myo;
+}
+
+void Fl_Widget_Class_Type::write_properties() {
+  Fl_Window_Type::write_properties();
+  if (wc_relative) write_string("position_relative");
+}
+
+void Fl_Widget_Class_Type::read_property(const char *c) {
+  if (!strcmp(c,"position_relative")) {
+    wc_relative = 1;
+  } else {
+    Fl_Window_Type::read_property(c);
+  }
+}
+
+void Fl_Widget_Class_Type::write_code1() {
+#if 0
+  Fl_Widget_Type::write_code1();
+#endif // 0
+
+  current_widget_class = this;
+  write_public_state = 1;
+
+  const char *c = subclass();
+  if (!c) c = "Fl_Group";
+
+  write_h("\nclass %s : public %s {\n", name(), c);
+  if (!strcmp(c, "Fl_Window") ||
+      !strcmp(c, "Fl_Double_Window") ||
+      !strcmp(c, "Fl_Gl_Window") ||
+      !strcmp(c, "Fl_Overlay_Window")) {
+    write_h("  void _%s();\n", name());
+    write_h("public:\n");
+    write_h("  %s(int X, int Y, int W, int H, const char *L = 0);\n", name());
+    write_h("  %s(int W, int H, const char *L = 0);\n", name());
+
+    write_c("%s::%s(int X, int Y, int W, int H, const char *L)\n", name(), name());
+    write_c("  : %s(X, Y, W, H, L) {\n", c);
+    write_c("  _%s();\n", name());
+    write_c("}\n\n");
+
+    write_c("%s::%s(int W, int H, const char *L)\n", name(), name());
+    write_c("  : %s(0, 0, W, H, L) {\n", c);
+    write_c("  clear_flag(16);\n");
+    write_c("  _%s();\n", name());
+    write_c("}\n\n");
+
+    write_c("void %s::_%s() {\n", name(), name());
+    write_c("  %s *w = this;\n", name());
+  } else {
+    write_h("public:\n");
+    write_h("  %s(int X, int Y, int W, int H, const char *L = 0);\n", name());
+
+    write_c("%s::%s(int X, int Y, int W, int H, const char *L)\n", name(), name());
+    if (wc_relative)
+      write_c("  : %s(0, 0, W, H, L) {\n", c);
+    else
+      write_c("  : %s(X, Y, W, H, L) {\n", c);
+  }
+
+  write_c("  %s *o = this;\n", name());
+
+  write_widget_code();
+}
+
+void Fl_Widget_Class_Type::write_code2() {
+  write_extra_code();
+  if (wc_relative) write_c("%sposition(X, Y);\n", indent());
+  if (modal) write_c("%sset_modal();\n", indent());
+  else if (non_modal) write_c("%sset_non_modal();\n", indent());
+  if (!((Fl_Window*)o)->border()) write_c("%sclear_border();\n", indent());
+  if (xclass) {
+    write_c("%sxclass(", indent());
+    write_cstring(xclass);
+    write_c(");\n");
+  }
+  write_c("%send();\n", indent());
+  if (((Fl_Window*)o)->resizable() == o)
+    write_c("%sresizable(this);\n", indent());
+  write_c("}\n");
+}
+
+////////////////////////////////////////////////////////////////
+// live mode support
+
+Fl_Widget *Fl_Window_Type::enter_live_mode(int top) {
+  Fl_Window *win = new Fl_Window(o->x(), o->y(), o->w(), o->h());
+  live_widget = win;
+  if (live_widget) {
+    copy_properties();
+    Fl_Type *n;
+    for (n = next; n && n->level > level; n = n->next) {
+      if (n->level == level+1)
+        n->enter_live_mode();
+    }
+    win->end();
+  }
+  return live_widget;
+}
+
+void Fl_Window_Type::leave_live_mode() {
+}
+
+/**
+ * copy all properties from the edit widget to the live widget
+ */
+void Fl_Window_Type::copy_properties() {
+  Fl_Widget_Type::copy_properties();
+  /// \todo copy resizing constraints over
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fluid_Image.cxx b/Utilities/FLTK/fluid/Fluid_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fba6a9f9c294ecd2164ae0d3b2dc211c278fdc23
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fluid_Image.cxx
@@ -0,0 +1,229 @@
+//
+// "$Id$"
+//
+// Pixmap label support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include "Fl_Type.h"
+#include "Fluid_Image.h"
+#include "../src/flstring.h"
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <FL/filename.H>
+
+extern void goto_source_dir(); // in fluid.C
+extern void leave_source_dir(); // in fluid.C
+
+void Fluid_Image::image(Fl_Widget *o) {
+  if (o->window() != o) o->image(img);
+}
+
+void Fluid_Image::deimage(Fl_Widget *o) {
+  if (o->window() != o) o->deimage(img);
+}
+
+static int pixmap_header_written = 0;
+static int bitmap_header_written = 0;
+static int image_header_written = 0;
+
+void Fluid_Image::write_static() {
+  if (!img) return;
+  if (img->count() > 1) {
+    // Write Pixmap data...
+    write_c("\n");
+    if (pixmap_header_written != write_number) {
+      write_c("#include <FL/Fl_Pixmap.H>\n");
+      pixmap_header_written = write_number;
+    }
+    write_c("static const char *%s[] = {\n",
+	    unique_id(this, "idata", fl_filename_name(name()), 0));
+    write_cstring(img->data()[0], strlen(img->data()[0]));
+
+    int i;
+    int ncolors, chars_per_color;
+    sscanf(img->data()[0], "%*d%*d%d%d", &ncolors, &chars_per_color);
+
+    if (ncolors < 0) {
+      write_c(",\n");
+      write_cstring(img->data()[1], ncolors * -4);
+      i = 2;
+    } else {
+      for (i = 1; i <= ncolors; i ++) {
+        write_c(",\n");
+        write_cstring(img->data()[i], strlen(img->data()[i]));
+      }
+    }
+    for (; i < img->count(); i ++) {
+      write_c(",\n");
+      write_cstring(img->data()[i], img->w() * chars_per_color);
+    }
+    write_c("\n};\n");
+    write_c("static Fl_Pixmap %s(%s);\n",
+	    unique_id(this, "image", fl_filename_name(name()), 0),
+	    unique_id(this, "idata", fl_filename_name(name()), 0));
+  } else if (img->d() == 0) {
+    // Write Bitmap data...
+    write_c("\n");
+    if (bitmap_header_written != write_number) {
+      write_c("#include <FL/Fl_Bitmap.H>\n");
+      bitmap_header_written = write_number;
+    }
+    write_c("static unsigned char %s[] =\n",
+	    unique_id(this, "idata", fl_filename_name(name()), 0));
+    write_cdata(img->data()[0], ((img->w() + 7) / 8) * img->h());
+    write_c(";\n");
+    write_c("static Fl_Bitmap %s(%s, %d, %d);\n",
+	    unique_id(this, "image", fl_filename_name(name()), 0),
+	    unique_id(this, "idata", fl_filename_name(name()), 0),
+	    img->w(), img->h());
+  } else {
+    // Write image data...
+    write_c("\n");
+    if (image_header_written != write_number) {
+      write_c("#include <FL/Fl_Image.H>\n");
+      image_header_written = write_number;
+    }
+    write_c("static unsigned char %s[] =\n",
+	    unique_id(this, "idata", fl_filename_name(name()), 0));
+    write_cdata(img->data()[0], (img->w() * img->d() + img->ld()) * img->h());
+    write_c(";\n");
+    write_c("static Fl_RGB_Image %s(%s, %d, %d, %d, %d);\n",
+	    unique_id(this, "image", fl_filename_name(name()), 0),
+	    unique_id(this, "idata", fl_filename_name(name()), 0),
+	    img->w(), img->h(), img->d(), img->ld());
+  }
+}
+
+void Fluid_Image::write_code(int inactive) {
+  if (!img) return;
+  write_c("%so->%s(%s);\n", indent(), inactive ? "deimage" : "image",
+	  unique_id(this, "image", fl_filename_name(name()), 0));
+}
+
+
+////////////////////////////////////////////////////////////////
+
+static Fluid_Image** images = 0; // sorted list
+static int numimages = 0;
+static int tablesize = 0;
+
+Fluid_Image* Fluid_Image::find(const char *iname) {
+  if (!iname || !*iname) return 0;
+
+  // first search to see if it exists already:
+  int a = 0;
+  int b = numimages;
+  while (a < b) {
+    int c = (a+b)/2;
+    int i = strcmp(iname,images[c]->name_);
+    if (i < 0) b = c;
+    else if (i > 0) a = c+1;
+    else return images[c];
+  }
+
+  // no, so now see if the file exists:
+
+  goto_source_dir();
+  FILE *f = fopen(iname,"rb");
+  if (!f) {
+    read_error("%s : %s",iname,strerror(errno));
+    leave_source_dir();
+    return 0;
+  }
+  fclose(f);
+
+  Fluid_Image *ret = new Fluid_Image(iname);
+
+  if (!ret->img || !ret->img->w() || !ret->img->h()) {
+    delete ret;
+    ret = 0;
+    read_error("%s : unrecognized image format", iname);
+  }
+  leave_source_dir();
+  if (!ret) return 0;
+
+  // make a new entry in the table:
+  numimages++;
+  if (numimages > tablesize) {
+    tablesize = tablesize ? 2*tablesize : 16;
+    if (images) images = (Fluid_Image**)realloc(images, tablesize*sizeof(Fluid_Image*));
+    else images = (Fluid_Image**)malloc(tablesize*sizeof(Fluid_Image*));
+  }
+  for (b = numimages-1; b > a; b--) images[b] = images[b-1];
+  images[a] = ret;
+
+  return ret;
+}
+
+Fluid_Image::Fluid_Image(const char *iname) {
+  name_ = strdup(iname);
+  written = 0;
+  refcount = 0;
+  img = Fl_Shared_Image::get(iname);
+}
+
+void Fluid_Image::increment() {
+  ++refcount;
+}
+
+void Fluid_Image::decrement() {
+  --refcount;
+  if (refcount > 0) return;
+  delete this;
+}
+
+Fluid_Image::~Fluid_Image() {
+  int a;
+  if (images) {
+    for (a = 0;; a++) if (images[a] == this) break;
+    numimages--;
+    for (; a < numimages; a++) images[a] = images[a+1];
+  }
+  if (img) img->release();
+  free((void*)name_);
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_File_Chooser.H>
+
+const char *ui_find_image_name;
+Fluid_Image *ui_find_image(const char *oldname) {
+  goto_source_dir();
+  fl_file_chooser_ok_label("Use Image");
+  const char *name = fl_file_chooser("Image?","Image Files (*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm})",oldname,1);
+  fl_file_chooser_ok_label(NULL);
+  ui_find_image_name = name;
+  Fluid_Image *ret = (name && *name) ? Fluid_Image::find(name) : 0;
+  leave_source_dir();
+  return ret;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Fluid_Image.h b/Utilities/FLTK/fluid/Fluid_Image.h
new file mode 100644
index 0000000000000000000000000000000000000000..128c61ffeec0e794b819e532c9ec84502175781f
--- /dev/null
+++ b/Utilities/FLTK/fluid/Fluid_Image.h
@@ -0,0 +1,66 @@
+//
+// "$Id$"
+//
+// Image header file for the Fast Light Tool Kit (FLTK).
+//
+// This class stores the image labels for widgets in fluid.  This is
+// not a class in FLTK itself, and will produce different types of
+// code depending on what the image type is.
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef FLUID_IMAGE_H
+#  define FLUID_IMAGE_H
+
+#  include <FL/Fl_Shared_Image.H>
+
+
+class Fluid_Image {
+  const char *name_;
+  int refcount;
+  Fl_Shared_Image *img;
+protected:
+  Fluid_Image(const char *name); // no public constructor
+  ~Fluid_Image(); // no public destructor
+public:
+  int written;
+  static Fluid_Image* find(const char *);
+  void decrement(); // reference counting & automatic free
+  void increment();
+  void image(Fl_Widget *); // set the image of this widget
+  void deimage(Fl_Widget *); // set the deimage of this widget
+  void write_static();
+  void write_code(int inactive = 0);
+  const char *name() const {return name_;}
+};
+
+// pop up file chooser and return a legal image selected by user,
+// or zero for any errors:
+Fluid_Image *ui_find_image(const char *);
+extern const char *ui_find_image_name;
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/Makefile b/Utilities/FLTK/fluid/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..18f4716680b941019da808496e263811a3ab3658
--- /dev/null
+++ b/Utilities/FLTK/fluid/Makefile
@@ -0,0 +1,137 @@
+#
+# "$Id: Makefile 4759 2006-01-15 19:26:08Z mike $"
+#
+# FLUID makefile for the Fast Light Tool Kit (FLTK).
+#
+# Copyright 1998-2005 by Bill Spitzak and others.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems on the following page:
+#
+#      http://www.fltk.org/str.php
+#
+
+CPPFILES = \
+	CodeEditor.cxx \
+	Fl_Function_Type.cxx \
+	Fl_Group_Type.cxx \
+	Fl_Menu_Type.cxx \
+	Fl_Type.cxx \
+	Fl_Widget_Type.cxx \
+	Fl_Window_Type.cxx \
+	Fluid_Image.cxx \
+	about_panel.cxx \
+	align_widget.cxx \
+	alignment_panel.cxx \
+	code.cxx \
+	factory.cxx \
+	file.cxx \
+	fluid.cxx \
+	function_panel.cxx \
+	template_panel.cxx \
+	undo.cxx \
+	widget_panel.cxx
+
+################################################################
+
+OBJECTS = $(CPPFILES:.cxx=.o)
+
+include ../makeinclude
+
+all:	$(FLUID) fluid$(EXEEXT)
+
+fluid$(EXEEXT):		$(OBJECTS) ../lib/$(LIBNAME) ../lib/$(FLLIBNAME) \
+			../lib/$(IMGLIBNAME)
+	echo Linking $@...
+	$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LINKFLTKFORMS) $(LINKFLTKIMG) $(LDLIBS)
+	$(POSTBUILD) $@ ../FL/mac.r
+	$(CP) $@ fluid.app/Contents/MacOS
+
+fluid-shared$(EXEEXT):	$(OBJECTS) ../src/$(DSONAME) ../src/$(FLDSONAME) \
+			../src/$(IMGDSONAME)
+	echo Linking $@...
+	$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LINKSHARED) $(LDLIBS)
+	$(POSTBUILD) $@ ../FL/mac.r
+
+clean:
+	-$(RM) *.o core.* *~ *.bck *.bck
+	-$(RM) core fluid$(EXEEXT) fluid-shared$(EXEEXT)
+
+depend:	$(CPPFILES)
+	makedepend -Y -I.. -f makedepend $(CPPFILES)
+
+# Automatically generated dependencies...
+include makedepend
+
+install: all
+	echo "Installing FLUID in $(DESTDIR)$(bindir)..."
+	-$(MKDIR) $(DESTDIR)$(bindir)
+	$(CP) $(FLUID) $(DESTDIR)$(bindir)/fluid$(EXEEXT)
+	$(STRIP) $(DESTDIR)$(bindir)/fluid$(EXEEXT)
+	$(DESTDIR)$(bindir)/fltk-config --post $(DESTDIR)$(bindir)/fluid$(EXEEXT)
+	$(CHMOD) 755 $(DESTDIR)$(bindir)/fluid$(EXEEXT)
+
+install-linux:
+	-$(MKDIR) $(DESTDIR)/usr/share/applnk/Development
+	$(CP) fluid.desktop  $(DESTDIR)/usr/share/applnk/Development
+	for size in 16 32 48 64 128; do \
+		if test ! -d $(DESTDIR)/usr/share/icons/hicolor/$${size}x$${size}/apps; then \
+			$(MKDIR) $(DESTDIR)/usr/share/icons/hicolor/$${size}x$${size}/apps; \
+		fi; \
+		$(CP) icons/fluid-$$size.png $(DESTDIR)/usr/share/icons/hicolor/$${size}x$${size}/apps/fluid.png; \
+	done
+	-$(MKDIR) $(DESTDIR)/usr/share/mimelnk/application
+	$(CP) x-fluid.desktop  $(DESTDIR)/usr/share/mimelnk/application
+
+install-osx:
+	-$(MKDIR) $(DESTDIR)/Applications/fluid.app
+	-$(MKDIR) $(DESTDIR)/Applications/fluid.app/Contents
+	$(CP) fluid.app/Contents/Info.plist $(DESTDIR)/Applications/fluid.app/Contents/Info.plist
+	$(CP) fluid.app/Contents/PkgInfo $(DESTDIR)/Applications/fluid.app/Contents/PkgInfo
+	-$(MKDIR) $(DESTDIR)/Applications/fluid.app/Contents/MacOS
+	$(LN) $(bindir)/fluid $(DESTDIR)/Application/fluid.app/Contents/MacOS/fluid
+	-$(MKDIR) $(DESTDIR)/Applications/fluid.app/Contents/Resources
+	$(CP) fluid.app/Contents/Resources/fluid.icns $(DESTDIR)/Applications/fluid.app/Contents/Resources
+
+uninstall:
+	$(RM) $(DESTDIR)$(bindir)/fluid$(EXEEXT)
+
+uninstall-linux:
+	$(RM) $(DESTDIR)/usr/share/applnk/Development/fluid.desktop
+	$(RM) $(DESTDIR)/usr/share/icons/hicolor/*/fluid.png
+	$(RM) $(DESTDIR)/usr/share/mimelnk/application/x-fluid.desktop
+
+uninstall-osx:
+	$(RM) -r $(DESTDIR)/Applications/fluid.app
+
+
+#
+# Note: The rebuild target can only be used if you have the original .fl
+#       files.  This is normally only used by the FLTK maintainers...
+#
+
+rebuild:
+	./fluid -c about_panel.fl
+	./fluid -c alignment_panel.fl
+	./fluid -c function_panel.fl
+	./fluid -c print_panel.fl
+	./fluid -c template_panel.fl
+	./fluid -c widget_panel.fl
+
+#
+# End of "$Id: Makefile 4759 2006-01-15 19:26:08Z mike $".
+#
diff --git a/Utilities/FLTK/fluid/Shortcut_Button.h b/Utilities/FLTK/fluid/Shortcut_Button.h
new file mode 100644
index 0000000000000000000000000000000000000000..82e40e185d669eb6e28243fe24114675d4fc6c1e
--- /dev/null
+++ b/Utilities/FLTK/fluid/Shortcut_Button.h
@@ -0,0 +1,41 @@
+//
+// "$Id$"
+//
+// Shortcut header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl_Button.H>
+
+class Shortcut_Button : public Fl_Button {
+public:
+  int svalue;
+  int handle(int);
+  void draw();
+  Shortcut_Button(int X,int Y,int W,int H, const char* l = 0) :
+    Fl_Button(X,Y,W,H,l) {svalue = 0;}
+};
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/about_panel.cxx b/Utilities/FLTK/fluid/about_panel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fd559c7506550ecff931cfb007bbb41797989eb3
--- /dev/null
+++ b/Utilities/FLTK/fluid/about_panel.cxx
@@ -0,0 +1,308 @@
+//
+// "$Id$"
+//
+// About dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "about_panel.h"
+void show_help(const char *name);
+
+Fl_Double_Window *about_panel=(Fl_Double_Window *)0;
+
+#include <FL/Fl_Pixmap.H>
+static const char *idata_fluid[] = {
+"96 96 32 1",
+" \tc None",
+".\tc #000100",
+"+\tc #031F3F",
+"@\tc #00366C",
+"#\tc #2E302D",
+"$\tc #0058AC",
+"%\tc #0060BF",
+"&\tc #4E504D",
+"*\tc #14659F",
+"=\tc #006DDC",
+"-\tc #2C7087",
+";\tc #0080FF",
+">\tc #407B74",
+",\tc #0F85F9",
+"\'\tc #268CCD",
+")\tc #7C7E7B",
+"!\tc #2D92EC",
+"~\tc #4498A9",
+"{\tc #2F94FE",
+"]\tc #5BA18C",
+"^\tc #6BA674",
+"/\tc #7DAD62",
+"(\tc #93BD53",
+"_\tc #A4A6A2",
+":\tc #6CB6FF",
+"<\tc #ABCC3F",
+"[\tc #C4DA2A",
+"}\tc #CACCC9",
+"|\tc #DCE913",
+"1\tc #BBDEFF",
+"2\tc #FDFE00",
+"3\tc #FDFFFC",
+"                                                                             \
+                   ",
+"                                                                             \
+                   ",
+"                                                                             \
+                   ",
+"                                           ...........                       \
+                   ",
+"                                     ......................                  \
+                   ",
+"                                    ........................                 \
+                   ",
+"                                    ........#&#&#&#&##......                 \
+                   ",
+"                                    ....)__}33333333333}_...                 \
+                   ",
+"                                    ...&33333333333333333...                 \
+                   ",
+"                                    ...#33311133333333333...                 \
+                   ",
+"                                    ...&33!,{,;:333333333...                 \
+                   ",
+"                                    ...&3:,{{{{,13333333}...                 \
+                   ",
+"                                    ...&3!{{!{{,13333333}...                 \
+                   ",
+"                                    ...&3:!{{!{;13333333}...                 \
+                   ",
+"                                    ...&3{{{{{{;133333333...                 \
+                   ",
+"                                    ...&31,{{{;,33333333}...                 \
+                   ",
+"                                    ...&331{{{:133333333}...                 \
+                   ",
+"                                    ...&3333333333333333_...                 \
+                   ",
+"                                    ...&3333333333333333}...                 \
+                   ",
+"                                    ...&3333333333333333_...                 \
+                   ",
+"                                    ...&3333333333333333}...                 \
+                   ",
+"                                    ...&3333333333333333_...                 \
+                   ",
+"                                    ...&3333333333333333}...                 \
+                   ",
+"                                    ...&3333333333333333_...                 \
+                   ",
+"                                    ...&3333333331!,,;:3}...                 \
+                   ",
+"                                    ...&333333333{{{{{;:_...                 \
+                   ",
+"                                    ...&333333331,{!{!{{}...                 \
+                   ",
+"                                    ...&333333331{{{{{{,_...                 \
+                   ",
+"                                    ...)333333331{{!{{{{_...                 \
+                   ",
+"                                    ...)333333333{{{!{;:_...                 \
+                   ",
+"                                    ...)3333333331{;;;:3_...                 \
+                   ",
+"                                    ...)3333333333331333_...                 \
+                   ",
+"                                    ...)3333333333333333_...                 \
+                   ",
+"                                    ...)3333333333333333_...                 \
+                   ",
+"                                    ..._3333333333333333_...                 \
+                   ",
+"                                    ..._3333333333333333_...                 \
+                   ",
+"                                    ..._3333333333333333_...                 \
+                   ",
+"                                    ..._3333333333333333}....                \
+                   ",
+"                                   ...._33333333333333333#...                \
+                   ",
+"                                  ....&333333333333333333_....               \
+                   ",
+"                                 ....&33333333333333333333)....              \
+                   ",
+"                                 ....333333333333333333333}&....             \
+                   ",
+"                                ...._33333333333333333333333....             \
+                   ",
+"                               ....&333333333331:11333333333_....            \
+                   ",
+"                              ....#33333333333:,,,;:333333333&....           \
+                   ",
+"                              ....}3333333333:,!{{{;1333333333&....          \
+                   ",
+"                             ....}33333333333{{{!{{,!3333333333....          \
+                   ",
+"                            ....)333333333333{{{{!{{{3333333333_....         \
+                   ",
+"                           ....#3333333333333!{{{{{,:33333333333&....        \
+                   ",
+"                           ...._33333333333331{{!{,;1333333333333#....       \
+                   ",
+"                          ...._333333333333333:;,;,13333333333333_....       \
+                   ",
+"                         ...._333333333333333333113333333333333333_....      \
+                   ",
+"                        ....&33333333333333333333333333331::1333333&....     \
+                   ",
+"                        ...._333333333333333333333333333{,{{;{133333#...     \
+                   ",
+"                       ...._3333333333333333333333333331,{!{{,:33333}....    \
+                   ",
+"                      ....&3333333333133333333333333333:{{{{{{:333333)....   \
+                   ",
+"                      ...#333333331{,,;:333333333333333:{!{!{{:3333333&....  \
+                   ",
+"                     ....}33333333,{{{{;:333333333333331,{!{{;:33333333#...  \
+                   ",
+"                    ...._333333331,!{!{{,333333333333333{,{{;{1333333333.... \
+                   ",
+"                   ....&3333333331{{{{{{{3333333333333333::::33333333333)....\
+                   ",
+"                  ....+!:::::::::{{{{!{{;::::::::::::::::::::::::::!:::::+...\
+.                  ",
+"                  ...+=;;;;;;;;;;;;{{{{;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;=...\
+.                  ",
+"                 ....%;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%..\
+..                 ",
+"                ....@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;$.\
+...                ",
+"                ...+%;;;;;;!!!;;;;;,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!=;;;+\
+....               ",
+"               ....%;;;;;!([<|^~]^([%;;;;;;;;;;;;;;;;;,(<\'=;;;;;;;!^/<[|\'=;\
+;=+...               ",
+"              ....$;;;;;\'|2>]22<|22[%=;;;;;;;;;;;;;;;;^22[%=;;;;;;!][22|%=;;\
+;$....              ",
+"             ....@;;;;;;[2[%^2|*[22(%=;;;;;;;;;;;;;;;,/22|$=;;;;;;;;<22<%=;;;\
+;$....             ",
+"            ....+=;;;;;~22^$%]~$|22>%=;;;;;;;;;;;;;;;;\'||^%=;;;;;;;,[22^$=;;\
+;;;+....            ",
+"            ....%;;;;;,[22-%===\'22|*==;;;;;;;;;;;;;;;;;;=%=;;;;;;;;\'22|*%=;\
+;;;;=+...            ",
+"           ....$;;;;;;!22|$%;,;^22<$=;;;;;;;;;;;;;;;;;;===;;;;;;;;;^22|$==;;;\
+;;;%....           ",
+"          ....@;;;;;\'](22[^]=;;<22^$==!~]/~=;!]]~;;;;{\'~]==;;;;~<<]<22($=;;\
+;;;;;;@....          ",
+"         ....@;;;;;;]<|22|[<%;!|22-%\'[2222*=;/22(%;~|222(=;;;!<2|^[222>$=;;;\
+;;;;;;+....         ",
+"         ....=;;;;;;;,[22>$===~22|$==,[22[%=;[22]%=,!|22]%=;![2|*%]22|*==;;;;\
+;;;;;%+...         ",
+"        ....@;;;;;;;;!|22*$=;;/22($=;,[22/$=\'222*%=;!|22-%;;<22>%=]22[$%;;;;\
+;;;;;;;=....        ",
+"       ....@;;;;;;;;;~22[*==;;[22>%=;\'22|-%,^22[$=;,~22[$%;]22<$%=(22/$=;;;;\
+;;;;;;;;@....       ",
+"      ....+;;;;;;;;;;^22<$=;;!222*$=;]22[$==[22/$=;;(22/$=![22]$=;|22-%=;;;;;\
+;;;;;;;;+...       ",
+"      ....;;;;;;;;;;;<22^%=;;]22[$=;;(22/$=~222-%=;;[22>%=]22|$%;~22|$==;;;;;\
+;;;;;;;;;....      ",
+"     ....%;;;;;;;;;;;|22-%=;;(22/$=;{|22-%=<22|$%;;\'22|*%;<22<$==(22<$=;=;;;\
+;;;;;;;;;;$....     ",
+"    ....+;;;;;;;;;;;!222$==;,|22>%=;~22|$=]|22($=;;]22[$%,|22^%=!|22^$=;;;;;;\
+;;;;;;;;;;@....    ",
+"   ....+=;;;;;;;;;;;~22[$%;;\'22|*-/;]22($*[<22^$^=;(22/$(-222>$=(222->~;;;;;\
+;;;;;;;;;;;=+....   ",
+"   ...+;;;;;;;;;;;;;(22/$=;;]22|*<\'=(22/*[~[22>(]=;|22>//=|22/$^(|2|-[%=;;;;\
+;;;;;;;;;;;;=....   ",
+"  ....$;;;;;;;;;;;;;<22>%=;;]222|>==(222|^=|22|<%=;|222<%=(222|<-222|-==;;;;;\
+;;;;;;;;;;;;$....  ",
+" ....@;;;;;;;;;;;;;!|2|$=;;;\'[2[>%=;\'|2[]%=/2|/$==;^2|(*%=!(2|($%<2[-%=;;;;\
+;;;;;;;;;;;;;;;@.... ",
+"....@;;;;;;;;;;;;;;\'22($%;;;;=%%==;;;=%%%==;=%%==;;;=%===;;==%%====%%=,;;;;;\
+;;;;;;;;;;;;;;;+... ",
+"...+=;;;;;;;;;;!\'=,]22-%=;;;;;;==;=;;;===;=;;===;;;;;===;;;;=;=,;;,=;=;;;;;;\
+;;;;;;;;;;;;;;;=....",
+"...+;;;;;;;;;;;[2^=<2<$==;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\
+;;;;;;;;;;;;;;;+...",
+"...+;;;;;;;;;;;22(\'2|*%=;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\
+;;;;;;;;;;;;;;;;+...",
+"...+;;;;;;;;;;;^|<[[-%=;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\
+;;;;;;;;;;;;;;;+...",
+"...+;;;;;;;;;;;;*~*%===;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\
+;;;;;;;;;;;;;;;@...",
+"...+;;;;;;;;;;;;;====;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\
+;;;;;;;;;;;;;;;+...",
+"....$=;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\
+;;;;;;;;;;;;;=$....",
+" .....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\
++++++++++++++..... ",
+" ............................................................................\
+.................  ",
+"  ...........................................................................\
+.................  ",
+"     ........................................................................\
+..............     "
+};
+static Fl_Pixmap image_fluid(idata_fluid);
+
+static void cb_View(Fl_Button*, void*) {
+  show_help("license.html");
+}
+
+static void cb_Close(Fl_Return_Button* o, void*) {
+  ((Fl_Window*)(o->parent()))->hide();
+}
+
+Fl_Double_Window* make_about_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = about_panel = new Fl_Double_Window(315, 175, "About FLUID");
+    w = o;
+    o->color(FL_LIGHT1);
+    o->selection_color(FL_DARK1);
+    w->hotspot(o);
+    { Fl_Box* o = new Fl_Box(10, 10, 115, 120);
+      o->image(image_fluid);
+    }
+    { Fl_Box* o = new Fl_Box(135, 10, 170, 69, "FLTK User\nInterface Designer\nVersion 1.1.7");
+      o->color((Fl_Color)12);
+      o->selection_color(FL_DARK1);
+      o->labelfont(1);
+      o->labelsize(18);
+      o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
+    }
+    { Fl_Box* o = new Fl_Box(135, 89, 170, 42, "Copyright 1998-2006 by\nBill Spitzak and others");
+      o->align(132|FL_ALIGN_INSIDE);
+    }
+    { Fl_Button* o = new Fl_Button(89, 141, 123, 25, "View License...");
+      o->labelcolor(FL_DARK_BLUE);
+      o->callback((Fl_Callback*)cb_View);
+    }
+    { Fl_Return_Button* o = new Fl_Return_Button(222, 141, 83, 25, "Close");
+      o->callback((Fl_Callback*)cb_Close);
+    }
+    o->set_non_modal();
+    o->end();
+  }
+  return w;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/about_panel.fl b/Utilities/FLTK/fluid/about_panel.fl
new file mode 100644
index 0000000000000000000000000000000000000000..e068ba64dd454bf03b665a6e415f1a1516b090b1
--- /dev/null
+++ b/Utilities/FLTK/fluid/about_panel.fl
@@ -0,0 +1,74 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {.h} 
+code_name {.cxx}
+comment {//
+// "$Id: about_panel.fl 4748 2006-01-15 02:26:54Z mike $"
+//
+// About dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {selected in_source in_header
+} 
+
+decl {void show_help(const char *name);} {public
+} 
+
+Function {make_about_panel()} {open
+} {
+  Fl_Window about_panel {
+    label {About FLUID} open
+    xywh {391 113 315 175} type Double color 50 selection_color 47 hotspot non_modal visible
+  } {
+    Fl_Box {} {
+      image {icons/fluid-96.xpm} xywh {10 10 115 120}
+    }
+    Fl_Box {} {
+      label {FLTK User
+Interface Designer
+Version 1.1.7}
+      xywh {135 10 170 69} color 12 selection_color 47 labelfont 1 labelsize 18 align 21
+    }
+    Fl_Box {} {
+      label {Copyright 1998-2006 by
+Bill Spitzak and others}
+      xywh {135 89 170 42} align 148
+    }
+    Fl_Button {} {
+      label {View License...}
+      callback {show_help("license.html");}
+      xywh {89 141 123 25} labelcolor 136
+    }
+    Fl_Return_Button {} {
+      label Close
+      callback {((Fl_Window*)(o->parent()))->hide();}
+      xywh {222 141 83 25}
+    }
+  }
+} 
+
+comment {
+//
+// End of "$Id: about_panel.fl 4748 2006-01-15 02:26:54Z mike $".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/fluid/about_panel.h b/Utilities/FLTK/fluid/about_panel.h
new file mode 100644
index 0000000000000000000000000000000000000000..829d6a1c62547296eae6eac125816dab7b38e94d
--- /dev/null
+++ b/Utilities/FLTK/fluid/about_panel.h
@@ -0,0 +1,44 @@
+//
+// "$Id$"
+//
+// About dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef about_panel_h
+#define about_panel_h
+#include <FL/Fl.H>
+extern void show_help(const char *name);
+#include <FL/Fl_Double_Window.H>
+extern Fl_Double_Window *about_panel;
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+Fl_Double_Window* make_about_panel();
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/align_widget.cxx b/Utilities/FLTK/fluid/align_widget.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5d44028fd68a91ef85f62431a0f5009cb46ef36c
--- /dev/null
+++ b/Utilities/FLTK/fluid/align_widget.cxx
@@ -0,0 +1,541 @@
+//
+// "$Id$"
+//
+// Alignment code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include "Fl_Widget_Type.h"
+#include "undo.h"
+
+/**
+ * the first behaviour always uses the first selected widget as a reference
+ * the second behaviour uses the largest widget (most extreme positions) as
+ * a reference.
+ */
+#define BREAK_ON_FIRST break
+//#define BREAK_ON_FIRST
+
+void align_widget_cb(Fl_Widget*, long how) 
+{
+  const int max = 32768, min = -32768;
+  int left, right, top, bot, wdt, hgt, n;
+  Fl_Type *o;
+  int changed = 0;
+  switch ( how )
+  {
+  //---- align
+  case 10: // align left
+    left = max;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->x()<left)
+	  left = w->x();
+	BREAK_ON_FIRST;
+      }
+    if (left!=max)
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize(left, w->y(), w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize(left, w->y(), w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    break;
+  case 11: // align h.center
+    left = max; right = min;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->x()<left)
+	  left = w->x();
+	if (w->x()+w->w()>right)
+	  right = w->x()+w->w();
+	BREAK_ON_FIRST;
+      }
+    if (left!=max)
+    {
+      int center2 = left+right;
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize((center2-w->w())/2, w->y(), w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize((center2-w->w())/2, w->y(), w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    }
+    break;
+  case 12: // align right
+    right = min;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->x()+w->w()>right)
+	  right = w->x()+w->w();
+	BREAK_ON_FIRST;
+      }
+    if (right!=min)
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize(right-w->w(), w->y(), w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize(right-w->w(), w->y(), w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    break;
+  case 13: // align top
+    top = max;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->y()<top)
+	  top = w->y();
+	BREAK_ON_FIRST;
+      }
+    if (top!=max)
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize(w->x(), top, w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize(w->x(), top, w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    break;
+  case 14: // align v.center
+    top = max; bot = min;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->y()<top)
+	  top = w->y();
+	if (w->y()+w->h()>bot)
+	  bot = w->y()+w->h();
+	BREAK_ON_FIRST;
+      }
+    if (top!=max)
+    {
+      int center2 = top+bot;
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize(w->x(), (center2-w->h())/2, w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize(w->x(), (center2-w->h())/2, w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    }
+    break;
+  case 15: // align bottom
+    bot = min;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->y()+w->h()>bot)
+	  bot = w->y()+w->h();
+	BREAK_ON_FIRST;
+      }
+    if (bot!=min)
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize( w->x(), bot-w->h(), w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize( w->x(), bot-w->h(), w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    break;
+  //---- space evently
+  case 20: // space evenly across
+    left = max; right = min; wdt = 0, n = 0;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->x()<left)
+	  left = w->x();
+	if (w->x()+w->w()>right)
+	  right = w->x()+w->w();
+	wdt += w->w();
+	n++;
+      }
+    wdt = (right-left)-wdt;
+    n--;
+    if (n>0)
+    {
+      int cnt = 0, wsum = 0;
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize(left+wsum+wdt*cnt/n, w->y(), w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize(left+wsum+wdt*cnt/n, w->y(), w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	  cnt++;
+	  wsum += w->w();
+	}
+    }
+    break;
+  case 21: // space evenly down
+    top = max; bot = min; hgt = 0, n = 0;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->y()<top)
+	  top = w->y();
+	if (w->y()+w->h()>bot)
+	  bot = w->y()+w->h();
+	hgt += w->h();
+	n++;
+      }
+    hgt = (bot-top)-hgt;
+    n--;
+    if (n>0)
+    {
+      int cnt = 0, hsum = 0;
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize(w->x(), top+hsum+hgt*cnt/n, w->w(), w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize(w->x(), top+hsum+hgt*cnt/n, w->w(), w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	  cnt++;
+	  hsum += w->h();
+	}
+    }
+    break;
+  //---- make same size
+  case 30: // same width
+    wdt = min;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->w()>wdt)
+	  wdt = w->w();
+	BREAK_ON_FIRST;
+      }
+    if (wdt!=min)
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize(w->x(), w->y(), wdt, w->h());
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize(w->x(), w->y(), wdt, w->h());
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    break;
+  case 31: // same height
+    hgt = min;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->h()>hgt)
+	  hgt = w->h();
+	BREAK_ON_FIRST;
+      }
+    if (hgt!=min)
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize( w->x(), w->y(), w->w(), hgt);
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize( w->x(), w->y(), w->w(), hgt);
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    break;
+  case 32: // same size
+    hgt = min; wdt = min;
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget())
+      {
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	if (w->w()>wdt)
+	  wdt = w->w();
+	if (w->h()>hgt)
+	  hgt = w->h();
+	BREAK_ON_FIRST;
+      }
+    if (hgt!=min)
+      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+	if (o->selected && o->is_widget())
+	{
+	  if (!changed) {
+	    changed = 1;
+	    set_modflag(1);
+	    undo_checkpoint();
+	  }
+
+	  Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	  if (o->next && o->next->level > o->level && !o->next->selected &&
+	      !o->is_menu_button()) {
+	    // When resizing a group, make sure we also move the children...
+	    ((igroup *)w)->full_resize( w->x(), w->y(), wdt, hgt);
+	  } else {
+	    // Otherwise, just do the widget...
+	    w->resize( w->x(), w->y(), wdt, hgt);
+	  }
+	  w->redraw();
+	  if (w->window()) w->window()->redraw();
+	}
+    break;
+  //---- center in group
+  case 40: // center hor
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget() && o->parent)
+      {
+	if (!changed) {
+	  changed = 1;
+	  set_modflag(1);
+	  undo_checkpoint();
+	}
+
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
+	int center2;
+
+	if (w->window() == p) center2 = p->w();
+	else center2 = 2*p->x()+p->w();
+
+	if (o->next && o->next->level > o->level && !o->next->selected &&
+	    !o->is_menu_button() && !o->is_menu_button()) {
+	  // When resizing a group, make sure we also move the children...
+	  ((igroup *)w)->full_resize((center2-w->w())/2, w->y(), w->w(), w->h());
+	} else {
+	  // Otherwise, just do the widget...
+	  w->resize((center2-w->w())/2, w->y(), w->w(), w->h());
+	}
+	w->redraw();
+	if (w->window()) w->window()->redraw();
+      }
+    break;
+  case 41: // center vert
+    for (o = Fl_Type::first; o; o = o->next)
+      if (o->selected && o->is_widget() && o->parent)
+      {
+	if (!changed) {
+	  changed = 1;
+	  set_modflag(1);
+	  undo_checkpoint();
+	}
+
+	Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+	Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
+	int center2;
+
+	if (w->window() == p) center2 = p->h();
+	else center2 = 2*p->y()+p->h();
+
+	if (o->next && o->next->level > o->level && !o->next->selected &&
+	    !o->is_menu_button()) {
+	  // When resizing a group, make sure we also move the children...
+	  ((igroup *)w)->full_resize(w->x(), (center2-w->h())/2, w->w(), w->h());
+	} else {
+	  // Otherwise, just do the widget...
+	  w->resize(w->x(), (center2-w->h())/2, w->w(), w->h());
+	}
+	set_modflag(1);
+	w->redraw();
+	if (w->window()) w->window()->redraw();
+      }
+    break;
+  }
+}
+
+
+// Set sizes of selected widgets...
+void widget_size_cb(Fl_Widget *, long size) {
+  // Update any selected widgets...
+  int changed = 0;
+  for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+    if (o->selected && o->is_widget()) {
+      if (!changed) {
+	changed = 1;
+	set_modflag(1);
+	undo_checkpoint();
+      }
+
+      Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+      w->labelsize(size);
+      Fl_Font f;
+      int s = (int)size;
+      Fl_Color c;
+      ((Fl_Widget_Type *)o)->textstuff(2, f, s, c);
+
+      w->redraw();
+      // since this may be a major change, the whole window should be redrawn
+      if (w->window()) w->window()->redraw();
+    }
+  }
+}
+
+
+//
+// End of "$Id$".
+//
+
diff --git a/Utilities/FLTK/fluid/alignment_panel.cxx b/Utilities/FLTK/fluid/alignment_panel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b0e0892761aa89072e33a30952d727e26b600e31
--- /dev/null
+++ b/Utilities/FLTK/fluid/alignment_panel.cxx
@@ -0,0 +1,506 @@
+//
+// "$Id$"
+//
+// Setting and shell dialogs for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "alignment_panel.h"
+
+Fl_Double_Window *project_window=(Fl_Double_Window *)0;
+
+static void cb_Close(Fl_Button*, void*) {
+  project_window->hide();
+}
+
+Fl_Input *header_file_input=(Fl_Input *)0;
+
+Fl_Input *code_file_input=(Fl_Input *)0;
+
+Fl_Light_Button *include_H_from_C_button=(Fl_Light_Button *)0;
+
+Fl_Choice *i18n_type_chooser=(Fl_Choice *)0;
+
+Fl_Menu_Item menu_i18n_type_chooser[] = {
+ {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 11, 0},
+ {"GNU gettext", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 11, 0},
+ {"POSIX catgets", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 11, 0},
+ {0,0,0,0,0,0,0,0,0}
+};
+
+Fl_Input *i18n_include_input=(Fl_Input *)0;
+
+Fl_Input *i18n_file_input=(Fl_Input *)0;
+
+Fl_Input *i18n_set_input=(Fl_Input *)0;
+
+Fl_Input *i18n_function_input=(Fl_Input *)0;
+
+Fl_Double_Window* make_project_window() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = project_window = new Fl_Double_Window(345, 185, "Project Settings");
+    w = o;
+    { Fl_Button* o = new Fl_Button(293, 156, 42, 20, "Close");
+      o->tooltip("Close this dialog.");
+      o->labelsize(11);
+      o->callback((Fl_Callback*)cb_Close);
+    }
+    { Fl_Tabs* o = new Fl_Tabs(10, 10, 325, 138);
+      o->selection_color((Fl_Color)4);
+      o->labelsize(11);
+      { Fl_Group* o = new Fl_Group(10, 30, 325, 116, "Output");
+        o->labelsize(11);
+        { Fl_Box* o = new Fl_Box(20, 40, 304, 15, "Use \"name.ext\" to set name or just \".ext\" to set extension.");
+          o->labelsize(11);
+          o->align(132|FL_ALIGN_INSIDE);
+        }
+        { Fl_Input* o = header_file_input = new Fl_Input(96, 60, 228, 20, "Header File:");
+          o->tooltip("The name of the generated header file.");
+          o->box(FL_THIN_DOWN_BOX);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)header_input_cb, (void*)(1));
+          o->when(FL_WHEN_CHANGED);
+        }
+        { Fl_Input* o = code_file_input = new Fl_Input(97, 85, 227, 20, "Code File:");
+          o->tooltip("The name of the generated code file.");
+          o->box(FL_THIN_DOWN_BOX);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)code_input_cb, (void*)(1));
+          o->when(FL_WHEN_CHANGED);
+        }
+        { Fl_Light_Button* o = include_H_from_C_button = new Fl_Light_Button(166, 110, 158, 20, "Include Header from Code");
+          o->tooltip("Include the header file from the code file.");
+          o->value(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)include_H_from_C_button_cb);
+        }
+        o->end();
+      }
+      { Fl_Group* o = new Fl_Group(10, 30, 325, 116, "Internationalization");
+        o->labelsize(11);
+        o->hide();
+        { Fl_Choice* o = i18n_type_chooser = new Fl_Choice(80, 42, 100, 20, "Use:");
+          o->tooltip("Type of internationalization to use.");
+          o->box(FL_THIN_UP_BOX);
+          o->down_box(FL_BORDER_BOX);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textsize(11);
+          o->callback((Fl_Callback*)i18n_type_cb);
+          o->menu(menu_i18n_type_chooser);
+        }
+        { Fl_Input* o = i18n_include_input = new Fl_Input(80, 67, 245, 20, "#include:");
+          o->tooltip("The include file for internationalization.");
+          o->box(FL_THIN_DOWN_BOX);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)i18n_text_cb);
+        }
+        { Fl_Input* o = i18n_file_input = new Fl_Input(80, 92, 245, 20, "File:");
+          o->tooltip("The name of the message catalog.");
+          o->box(FL_THIN_DOWN_BOX);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)i18n_text_cb);
+        }
+        { Fl_Input* o = i18n_set_input = new Fl_Input(80, 117, 245, 20, "Set:");
+          o->tooltip("The message set number.");
+          o->type(2);
+          o->box(FL_THIN_DOWN_BOX);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)i18n_text_cb);
+        }
+        { Fl_Input* o = i18n_function_input = new Fl_Input(80, 92, 245, 20, "Function:");
+          o->tooltip("The function to call to internationalize the labels and tooltips.");
+          o->box(FL_THIN_DOWN_BOX);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)i18n_text_cb);
+        }
+        o->end();
+      }
+      o->end();
+    }
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+Fl_Text_Buffer *shell_run_buffer;
+void scheme_cb(Fl_Choice *, void *);
+
+Fl_Double_Window *settings_window=(Fl_Double_Window *)0;
+
+Fl_Choice *scheme_choice=(Fl_Choice *)0;
+
+Fl_Menu_Item menu_scheme_choice[] = {
+ {"Default", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
+ {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
+ {"Plastic", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
+ {0,0,0,0,0,0,0,0,0}
+};
+
+Fl_Check_Button *tooltips_button=(Fl_Check_Button *)0;
+
+static void cb_tooltips_button(Fl_Check_Button*, void*) {
+  Fl_Tooltip::enable(tooltips_button->value());
+fluid_prefs.set("show_tooltips", tooltips_button->value());
+}
+
+Fl_Check_Button *completion_button=(Fl_Check_Button *)0;
+
+static void cb_completion_button(Fl_Check_Button*, void*) {
+  fluid_prefs.set("show_completion_dialogs", completion_button->value());
+}
+
+Fl_Check_Button *openlast_button=(Fl_Check_Button *)0;
+
+static void cb_openlast_button(Fl_Check_Button*, void*) {
+  fluid_prefs.set("open_previous_file", openlast_button->value());
+}
+
+Fl_Check_Button *prevpos_button=(Fl_Check_Button *)0;
+
+static void cb_prevpos_button(Fl_Check_Button*, void*) {
+  fluid_prefs.set("prev_window_pos", prevpos_button->value());
+}
+
+static void cb_Close1(Fl_Button*, void*) {
+  settings_window->hide();
+}
+
+Fl_Spinner *recent_spinner=(Fl_Spinner *)0;
+
+static void cb_recent_spinner(Fl_Spinner*, void*) {
+  fluid_prefs.set("recent_files", recent_spinner->value());
+load_history();
+}
+
+Fl_Double_Window* make_settings_window() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = settings_window = new Fl_Double_Window(340, 225, "GUI Settings");
+    w = o;
+    { Fl_Choice* o = scheme_choice = new Fl_Choice(116, 10, 115, 25, "Scheme:");
+      o->down_box(FL_BORDER_BOX);
+      o->labelfont(1);
+      o->callback((Fl_Callback*)scheme_cb);
+      o->menu(menu_scheme_choice);
+      int s;
+      fluid_prefs.get("scheme", s, 0);
+      scheme_choice->value(s);
+      scheme_cb(0, 0);
+    }
+    { Fl_Group* o = new Fl_Group(116, 45, 215, 100, "Options:\n\n\n\n\n");
+      o->labelfont(1);
+      o->align(FL_ALIGN_LEFT);
+      { Fl_Check_Button* o = tooltips_button = new Fl_Check_Button(116, 45, 113, 25, "Show Tooltips");
+        o->down_box(FL_DOWN_BOX);
+        o->callback((Fl_Callback*)cb_tooltips_button);
+        int b;
+        fluid_prefs.get("show_tooltips", b, 1);
+        tooltips_button->value(b);
+        Fl_Tooltip::enable(b);
+      }
+      { Fl_Check_Button* o = completion_button = new Fl_Check_Button(116, 70, 186, 25, "Show Completion Dialogs");
+        o->down_box(FL_DOWN_BOX);
+        o->callback((Fl_Callback*)cb_completion_button);
+        int b;
+        fluid_prefs.get("show_completion_dialogs", b, 1);
+        completion_button->value(b);
+      }
+      { Fl_Check_Button* o = openlast_button = new Fl_Check_Button(116, 95, 215, 25, "Open Previous File on Startup");
+        o->down_box(FL_DOWN_BOX);
+        o->callback((Fl_Callback*)cb_openlast_button);
+        int b;
+        fluid_prefs.get("open_previous_file", b, 0);
+        openlast_button->value(b);
+      }
+      { Fl_Check_Button* o = prevpos_button = new Fl_Check_Button(116, 120, 210, 25, "Remember Window Positions");
+        o->down_box(FL_DOWN_BOX);
+        o->callback((Fl_Callback*)cb_prevpos_button);
+        int b;
+        fluid_prefs.get("prev_window_pos", b, 1);
+        prevpos_button->value(b);
+      }
+      o->end();
+    }
+    { Fl_Button* o = new Fl_Button(266, 190, 64, 25, "Close");
+      o->tooltip("Close this dialog.");
+      o->callback((Fl_Callback*)cb_Close1);
+    }
+    { Fl_Spinner* o = recent_spinner = new Fl_Spinner(116, 155, 40, 25, "# Recent Files:");
+      o->labelfont(1);
+      o->callback((Fl_Callback*)cb_recent_spinner);
+      o->when(FL_WHEN_CHANGED);
+      int c;
+      fluid_prefs.get("recent_files", c, 5);
+      recent_spinner->maximum(10);
+      recent_spinner->value(c);
+    }
+    o->set_non_modal();
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *shell_window=(Fl_Double_Window *)0;
+
+Fl_Input *shell_command_input=(Fl_Input *)0;
+
+static void cb_shell_command_input(Fl_Input*, void*) {
+  fluid_prefs.set("shell_command", shell_command_input->value());
+}
+
+Fl_Check_Button *shell_writecode_button=(Fl_Check_Button *)0;
+
+static void cb_shell_writecode_button(Fl_Check_Button*, void*) {
+  fluid_prefs.set("shell_writecode", shell_writecode_button->value());
+}
+
+Fl_Check_Button *shell_writemsgs_button=(Fl_Check_Button *)0;
+
+static void cb_shell_writemsgs_button(Fl_Check_Button*, void*) {
+  fluid_prefs.set("shell_writemsgs", shell_writemsgs_button->value());
+}
+
+Fl_Check_Button *shell_savefl_button=(Fl_Check_Button *)0;
+
+static void cb_shell_savefl_button(Fl_Check_Button*, void*) {
+  fluid_prefs.set("shell_savefl", shell_savefl_button->value());
+}
+
+static void cb_Cancel(Fl_Button*, void*) {
+  shell_window->hide();
+}
+
+Fl_Double_Window *shell_run_window=(Fl_Double_Window *)0;
+
+Fl_Text_Display *shell_run_display=(Fl_Text_Display *)0;
+
+Fl_Return_Button *shell_run_button=(Fl_Return_Button *)0;
+
+static void cb_shell_run_button(Fl_Return_Button*, void*) {
+  shell_run_window->hide();
+}
+
+Fl_Double_Window* make_shell_window() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = shell_window = new Fl_Double_Window(365, 125, "Shell Command");
+    w = o;
+    { Fl_Input* o = shell_command_input = new Fl_Input(10, 27, 347, 25, "Command:");
+      o->labelfont(1);
+      o->callback((Fl_Callback*)cb_shell_command_input);
+      o->align(FL_ALIGN_TOP_LEFT);
+      char buf[1024];
+      fluid_prefs.get("shell_command", buf, "", sizeof(buf));
+      shell_command_input->value(buf);
+    }
+    { Fl_Check_Button* o = shell_writecode_button = new Fl_Check_Button(128, 61, 93, 19, "Write Code");
+      o->down_box(FL_DOWN_BOX);
+      o->callback((Fl_Callback*)cb_shell_writecode_button);
+      int b;
+      fluid_prefs.get("shell_writecode", b, 1);
+      shell_writecode_button->value(b);
+    }
+    { Fl_Check_Button* o = shell_writemsgs_button = new Fl_Check_Button(231, 61, 126, 19, "Write Messages");
+      o->down_box(FL_DOWN_BOX);
+      o->callback((Fl_Callback*)cb_shell_writemsgs_button);
+      int b;
+      fluid_prefs.get("shell_writemsgs", b, 0);
+      shell_writemsgs_button->value(b);
+    }
+    { Fl_Check_Button* o = shell_savefl_button = new Fl_Check_Button(10, 62, 108, 19, "Save .FL File");
+      o->down_box(FL_DOWN_BOX);
+      o->callback((Fl_Callback*)cb_shell_savefl_button);
+      int b;
+      fluid_prefs.get("shell_savefl", b, 1);
+      shell_savefl_button->value(b);
+    }
+    { Fl_Return_Button* o = new Fl_Return_Button(132, 90, 143, 25, "Run Command");
+      o->callback((Fl_Callback*)do_shell_command);
+    }
+    { Fl_Button* o = new Fl_Button(285, 90, 72, 25, "Cancel");
+      o->callback((Fl_Callback*)cb_Cancel);
+    }
+    o->end();
+  }
+  { Fl_Double_Window* o = shell_run_window = new Fl_Double_Window(555, 430, "Shell Command Output");
+    w = o;
+    { Fl_Text_Display* o = shell_run_display = new Fl_Text_Display(10, 10, 535, 375);
+      o->box(FL_DOWN_BOX);
+      o->textfont(4);
+      Fl_Group::current()->resizable(o);
+      shell_run_buffer = new Fl_Text_Buffer();
+      shell_run_display->buffer(shell_run_buffer);
+    }
+    { Fl_Return_Button* o = shell_run_button = new Fl_Return_Button(468, 395, 77, 25, "Close");
+      o->callback((Fl_Callback*)cb_shell_run_button);
+    }
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *grid_window=(Fl_Double_Window *)0;
+
+Fl_Input *horizontal_input=(Fl_Input *)0;
+
+Fl_Input *vertical_input=(Fl_Input *)0;
+
+Fl_Input *snap_input=(Fl_Input *)0;
+
+Fl_Check_Button *guides_toggle=(Fl_Check_Button *)0;
+
+static void cb_Close2(Fl_Button*, void*) {
+  grid_window->hide();
+}
+
+Fl_Round_Button *def_widget_size[6]={(Fl_Round_Button *)0};
+
+Fl_Double_Window* make_layout_window() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = grid_window = new Fl_Double_Window(285, 245, "Layout Settings");
+    w = o;
+    { Fl_Input* o = horizontal_input = new Fl_Input(106, 10, 50, 25, "x");
+      o->tooltip("Horizontal grid spacing.");
+      o->type(2);
+      o->box(FL_THIN_DOWN_BOX);
+      o->callback((Fl_Callback*)grid_cb, (void*)(1));
+      o->align(FL_ALIGN_RIGHT);
+      o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);
+    }
+    { Fl_Input* o = vertical_input = new Fl_Input(166, 10, 50, 25, "pixels");
+      o->tooltip("Vertical grid spacing.");
+      o->type(2);
+      o->box(FL_THIN_DOWN_BOX);
+      o->callback((Fl_Callback*)grid_cb, (void*)(2));
+      o->align(FL_ALIGN_RIGHT);
+      o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);
+    }
+    { Fl_Input* o = snap_input = new Fl_Input(106, 45, 50, 25, "pixel snap");
+      o->tooltip("Snap to grid within this many pixels.");
+      o->type(2);
+      o->box(FL_THIN_DOWN_BOX);
+      o->callback((Fl_Callback*)grid_cb, (void*)(3));
+      o->align(FL_ALIGN_RIGHT);
+      o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);
+    }
+    { Fl_Check_Button* o = guides_toggle = new Fl_Check_Button(106, 80, 110, 25, "Show Guides");
+      o->tooltip("Show distance and alignment guides in overlay");
+      o->down_box(FL_DOWN_BOX);
+      o->callback((Fl_Callback*)guides_cb, (void*)(4));
+    }
+    { Fl_Button* o = new Fl_Button(215, 210, 60, 25, "Close");
+      o->tooltip("Close this dialog.");
+      o->callback((Fl_Callback*)cb_Close2);
+    }
+    { Fl_Box* o = new Fl_Box(26, 10, 70, 25, "Grid:");
+      o->labelfont(1);
+      o->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE);
+    }
+    { Fl_Box* o = new Fl_Box(-1, 115, 97, 25, "Widget Size:");
+      o->labelfont(1);
+      o->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE);
+    }
+    { Fl_Group* o = new Fl_Group(105, 115, 170, 75);
+      { Fl_Round_Button* o = def_widget_size[0] = new Fl_Round_Button(105, 115, 70, 25);
+        o->type(102);
+        o->down_box(FL_ROUND_DOWN_BOX);
+        o->callback((Fl_Callback*)default_widget_size_cb, (void*)(8));
+      }
+      { Fl_Box* o = new Fl_Box(120, 115, 50, 25, "tiny");
+        o->labelsize(8);
+        o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+      }
+      { Fl_Round_Button* o = def_widget_size[1] = new Fl_Round_Button(180, 115, 70, 25);
+        o->type(102);
+        o->down_box(FL_ROUND_DOWN_BOX);
+        o->callback((Fl_Callback*)default_widget_size_cb, (void*)(11));
+      }
+      { Fl_Box* o = new Fl_Box(195, 115, 50, 25, "small");
+        o->labelsize(11);
+        o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+      }
+      { Fl_Round_Button* o = def_widget_size[2] = new Fl_Round_Button(105, 140, 70, 25);
+        o->type(102);
+        o->down_box(FL_ROUND_DOWN_BOX);
+        o->callback((Fl_Callback*)default_widget_size_cb, (void*)(14));
+      }
+      { Fl_Box* o = new Fl_Box(120, 140, 50, 25, "normal");
+        o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+      }
+      { Fl_Round_Button* o = def_widget_size[3] = new Fl_Round_Button(180, 140, 90, 25);
+        o->type(102);
+        o->down_box(FL_ROUND_DOWN_BOX);
+        o->callback((Fl_Callback*)default_widget_size_cb, (void*)(18));
+      }
+      { Fl_Box* o = new Fl_Box(195, 140, 68, 25, "medium");
+        o->labelsize(18);
+        o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+      }
+      { Fl_Round_Button* o = def_widget_size[4] = new Fl_Round_Button(105, 165, 75, 25);
+        o->type(102);
+        o->down_box(FL_ROUND_DOWN_BOX);
+        o->callback((Fl_Callback*)default_widget_size_cb, (void*)(24));
+      }
+      { Fl_Box* o = new Fl_Box(120, 165, 64, 25, "large");
+        o->labelsize(24);
+        o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+      }
+      { Fl_Round_Button* o = def_widget_size[5] = new Fl_Round_Button(180, 165, 95, 25);
+        o->type(102);
+        o->down_box(FL_ROUND_DOWN_BOX);
+        o->callback((Fl_Callback*)default_widget_size_cb, (void*)(32));
+      }
+      { Fl_Box* o = new Fl_Box(195, 165, 76, 25, "huge");
+        o->labelsize(32);
+        o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+      }
+      o->end();
+    }
+    o->set_non_modal();
+    o->end();
+  }
+  return w;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/alignment_panel.fl b/Utilities/FLTK/fluid/alignment_panel.fl
new file mode 100644
index 0000000000000000000000000000000000000000..34cfefa95072cb00a31dbbdc218a3b710ab45241
--- /dev/null
+++ b/Utilities/FLTK/fluid/alignment_panel.fl
@@ -0,0 +1,411 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {.h} 
+code_name {.cxx}
+comment {//
+// "$Id: alignment_panel.fl 4632 2005-11-03 22:16:52Z mike $"
+//
+// Setting and shell dialogs for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {in_source in_header
+} 
+
+decl {\#include <FL/Fl_Text_Buffer.H>} {public
+} 
+
+decl {\#include <FL/Fl_Text_Display.H>} {public
+} 
+
+decl {extern void load_history();} {public
+} 
+
+Function {make_project_window()} {open
+} {
+  Fl_Window project_window {
+    label {Project Settings}
+    xywh {312 395 345 185} type Double
+    code0 {\#include <FL/Fl_Preferences.H>}
+    code1 {\#include <FL/Fl_Tooltip.H>} modal visible
+  } {
+    Fl_Button {} {
+      label Close
+      callback {project_window->hide();}
+      tooltip {Close this dialog.} xywh {293 156 42 20} labelsize 11
+    }
+    Fl_Tabs {} {open
+      xywh {10 10 325 138} selection_color 4 labelsize 11
+    } {
+      Fl_Group {} {
+        label Output open
+        xywh {10 30 325 116} labelsize 11
+      } {
+        Fl_Box {} {
+          label {Use "name.ext" to set name or just ".ext" to set extension.}
+          xywh {20 40 304 15} labelsize 11 align 148
+        }
+        Fl_Input header_file_input {
+          label {Header File:}
+          user_data 1 user_data_type {void*}
+          callback header_input_cb
+          tooltip {The name of the generated header file.} xywh {96 60 228 20} box THIN_DOWN_BOX labelfont 1 labelsize 11 when 1 textfont 4 textsize 11
+        }
+        Fl_Input code_file_input {
+          label {Code File:}
+          user_data 1 user_data_type {void*}
+          callback code_input_cb
+          tooltip {The name of the generated code file.} xywh {97 85 227 20} box THIN_DOWN_BOX labelfont 1 labelsize 11 when 1 textfont 4 textsize 11
+        }
+        Fl_Light_Button include_H_from_C_button {
+          label {Include Header from Code}
+          callback include_H_from_C_button_cb
+          tooltip {Include the header file from the code file.} xywh {166 110 158 20} value 1 labelsize 11
+        }
+      }
+      Fl_Group {} {
+        label Internationalization open
+        xywh {10 30 325 116} labelsize 11 hide
+      } {
+        Fl_Choice i18n_type_chooser {
+          label {Use:}
+          callback i18n_type_cb open
+          tooltip {Type of internationalization to use.} xywh {80 42 100 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 textsize 11
+        } {
+          MenuItem {} {
+            label None
+            xywh {0 0 100 20} labelsize 11
+          }
+          MenuItem {} {
+            label {GNU gettext}
+            xywh {0 0 100 20} labelsize 11
+          }
+          MenuItem {} {
+            label {POSIX catgets}
+            xywh {0 0 100 20} labelsize 11
+          }
+        }
+        Fl_Input i18n_include_input {
+          label {\#include:}
+          callback i18n_text_cb
+          tooltip {The include file for internationalization.} xywh {80 67 245 20} box THIN_DOWN_BOX labelfont 1 labelsize 11 textfont 4 textsize 11
+        }
+        Fl_Input i18n_file_input {
+          label {File:}
+          callback i18n_text_cb
+          tooltip {The name of the message catalog.} xywh {80 92 245 20} box THIN_DOWN_BOX labelfont 1 labelsize 11 textfont 4 textsize 11
+        }
+        Fl_Input i18n_set_input {
+          label {Set:}
+          callback i18n_text_cb
+          tooltip {The message set number.} xywh {80 117 245 20} type Int box THIN_DOWN_BOX labelfont 1 labelsize 11 textfont 4 textsize 11
+        }
+        Fl_Input i18n_function_input {
+          label {Function:}
+          callback i18n_text_cb
+          tooltip {The function to call to internationalize the labels and tooltips.} xywh {80 92 245 20} box THIN_DOWN_BOX labelfont 1 labelsize 11 textfont 4 textsize 11
+        }
+      }
+    }
+  }
+} 
+
+decl {extern void i18n_cb(Fl_Choice *,void *);} {public
+} 
+
+decl {extern Fl_Preferences fluid_prefs;} {public
+} 
+
+decl {Fl_Text_Buffer *shell_run_buffer;} {public
+} 
+
+decl {void scheme_cb(Fl_Choice *, void *);} {public
+} 
+
+Function {make_settings_window()} {open
+} {
+  Fl_Window settings_window {
+    label {GUI Settings}
+    xywh {326 145 340 225} type Double non_modal visible
+  } {
+    Fl_Choice scheme_choice {
+      label {Scheme:}
+      callback scheme_cb
+      xywh {116 10 115 25} down_box BORDER_BOX labelfont 1
+      code0 {int s;}
+      code1 {fluid_prefs.get("scheme", s, 0);}
+      code2 {scheme_choice->value(s);}
+      code3 {scheme_cb(0, 0);}
+    } {
+      MenuItem {} {
+        label Default
+        xywh {0 0 35 25}
+      }
+      MenuItem {} {
+        label None
+        xywh {0 0 35 25}
+      }
+      MenuItem {} {
+        label Plastic
+        xywh {0 0 35 25}
+      }
+    }
+    Fl_Group {} {
+      label {Options:
+
+
+
+
+} open
+      xywh {116 45 215 100} labelfont 1 align 4
+    } {
+      Fl_Check_Button tooltips_button {
+        label {Show Tooltips}
+        callback {Fl_Tooltip::enable(tooltips_button->value());
+fluid_prefs.set("show_tooltips", tooltips_button->value());}
+        xywh {116 45 113 25} down_box DOWN_BOX
+        code0 {int b;}
+        code1 {fluid_prefs.get("show_tooltips", b, 1);}
+        code2 {tooltips_button->value(b);}
+        code3 {Fl_Tooltip::enable(b);}
+      }
+      Fl_Check_Button completion_button {
+        label {Show Completion Dialogs}
+        callback {fluid_prefs.set("show_completion_dialogs", completion_button->value());}
+        xywh {116 70 186 25} down_box DOWN_BOX
+        code0 {int b;}
+        code1 {fluid_prefs.get("show_completion_dialogs", b, 1);}
+        code2 {completion_button->value(b);}
+      }
+      Fl_Check_Button openlast_button {
+        label {Open Previous File on Startup}
+        callback {fluid_prefs.set("open_previous_file", openlast_button->value());}
+        xywh {116 95 215 25} down_box DOWN_BOX
+        code0 {int b;}
+        code1 {fluid_prefs.get("open_previous_file", b, 0);}
+        code2 {openlast_button->value(b);}
+      }
+      Fl_Check_Button prevpos_button {
+        label {Remember Window Positions}
+        callback {fluid_prefs.set("prev_window_pos", prevpos_button->value());}
+        xywh {116 120 210 25} down_box DOWN_BOX
+        code0 {int b;}
+        code1 {fluid_prefs.get("prev_window_pos", b, 1);}
+        code2 {prevpos_button->value(b);}
+      }
+    }
+    Fl_Button {} {
+      label Close
+      callback {settings_window->hide();}
+      tooltip {Close this dialog.} xywh {266 190 64 25}
+    }
+    Fl_Spinner recent_spinner {
+      label {\# Recent Files:}
+      callback {fluid_prefs.set("recent_files", recent_spinner->value());
+load_history();}
+      xywh {116 155 40 25} labelfont 1 when 1
+      code0 {int c;}
+      code1 {fluid_prefs.get("recent_files", c, 5);}
+      code2 {recent_spinner->maximum(10);}
+      code3 {recent_spinner->value(c);}
+    }
+  }
+} 
+
+Function {make_shell_window()} {open
+} {
+  Fl_Window shell_window {
+    label {Shell Command}
+    xywh {682 167 365 125} type Double visible
+  } {
+    Fl_Input shell_command_input {
+      label {Command:}
+      callback {fluid_prefs.set("shell_command", shell_command_input->value());}
+      xywh {10 27 347 25} labelfont 1 align 5
+      code0 {char buf[1024];}
+      code1 {fluid_prefs.get("shell_command", buf, "", sizeof(buf));}
+      code2 {shell_command_input->value(buf);}
+    }
+    Fl_Check_Button shell_writecode_button {
+      label {Write Code}
+      callback {fluid_prefs.set("shell_writecode", shell_writecode_button->value());}
+      xywh {128 61 93 19} down_box DOWN_BOX
+      code0 {int b;}
+      code1 {fluid_prefs.get("shell_writecode", b, 1);}
+      code2 {shell_writecode_button->value(b);}
+    }
+    Fl_Check_Button shell_writemsgs_button {
+      label {Write Messages}
+      callback {fluid_prefs.set("shell_writemsgs", shell_writemsgs_button->value());}
+      xywh {231 61 126 19} down_box DOWN_BOX
+      code0 {int b;}
+      code1 {fluid_prefs.get("shell_writemsgs", b, 0);}
+      code2 {shell_writemsgs_button->value(b);}
+    }
+    Fl_Check_Button shell_savefl_button {
+      label {Save .FL File}
+      callback {fluid_prefs.set("shell_savefl", shell_savefl_button->value());}
+      xywh {10 62 108 19} down_box DOWN_BOX
+      code0 {int b;}
+      code1 {fluid_prefs.get("shell_savefl", b, 1);}
+      code2 {shell_savefl_button->value(b);}
+    }
+    Fl_Return_Button {} {
+      label {Run Command}
+      callback do_shell_command
+      xywh {132 90 143 25}
+    }
+    Fl_Button {} {
+      label Cancel
+      callback {shell_window->hide();}
+      xywh {285 90 72 25}
+    }
+  }
+  Fl_Window shell_run_window {
+    label {Shell Command Output}
+    xywh {592 332 555 430} type Double hide resizable
+  } {
+    Fl_Text_Display shell_run_display {
+      xywh {10 10 535 375} box DOWN_BOX textfont 4 resizable
+      code0 {shell_run_buffer = new Fl_Text_Buffer();}
+      code1 {shell_run_display->buffer(shell_run_buffer);}
+    }
+    Fl_Return_Button shell_run_button {
+      label Close
+      callback {shell_run_window->hide();}
+      xywh {468 395 77 25}
+    }
+  }
+} 
+
+Function {make_layout_window()} {open
+} {
+  Fl_Window grid_window {
+    label {Layout Settings} selected
+    xywh {676 337 285 245} type Double non_modal visible
+  } {
+    Fl_Input horizontal_input {
+      label x
+      user_data 1 user_data_type long
+      callback grid_cb
+      tooltip {Horizontal grid spacing.} xywh {106 10 50 25} type Int box THIN_DOWN_BOX align 8
+      code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);}
+    }
+    Fl_Input vertical_input {
+      label pixels
+      user_data 2 user_data_type long
+      callback grid_cb
+      tooltip {Vertical grid spacing.} xywh {166 10 50 25} type Int box THIN_DOWN_BOX align 8
+      code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);}
+    }
+    Fl_Input snap_input {
+      label {pixel snap}
+      user_data 3 user_data_type long
+      callback grid_cb
+      tooltip {Snap to grid within this many pixels.} xywh {106 45 50 25} type Int box THIN_DOWN_BOX align 8
+      code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);}
+    }
+    Fl_Check_Button guides_toggle {
+      label {Show Guides}
+      user_data 4 user_data_type long
+      callback guides_cb
+      tooltip {Show distance and alignment guides in overlay} xywh {106 80 110 25} down_box DOWN_BOX
+    }
+    Fl_Button {} {
+      label Close
+      callback {grid_window->hide();}
+      tooltip {Close this dialog.} xywh {215 210 60 25}
+    }
+    Fl_Box {} {
+      label {Grid:}
+      xywh {26 10 70 25} labelfont 1 align 24
+    }
+    Fl_Box {} {
+      label {Widget Size:}
+      xywh {-1 115 97 25} labelfont 1 align 24
+    }
+    Fl_Group {} {open
+      xywh {105 115 170 75}
+    } {
+      Fl_Round_Button {def_widget_size[0]} {
+        user_data 8 user_data_type long
+        callback default_widget_size_cb
+        xywh {105 115 70 25} type Radio down_box ROUND_DOWN_BOX
+      }
+      Fl_Box {} {
+        label tiny
+        xywh {120 115 50 25} labelsize 8 align 20
+      }
+      Fl_Round_Button {def_widget_size[1]} {
+        user_data 11 user_data_type long
+        callback default_widget_size_cb
+        xywh {180 115 70 25} type Radio down_box ROUND_DOWN_BOX
+      }
+      Fl_Box {} {
+        label small
+        xywh {195 115 50 25} labelsize 11 align 20
+      }
+      Fl_Round_Button {def_widget_size[2]} {
+        user_data 14 user_data_type long
+        callback default_widget_size_cb
+        xywh {105 140 70 25} type Radio down_box ROUND_DOWN_BOX
+      }
+      Fl_Box {} {
+        label normal
+        xywh {120 140 50 25} align 20
+      }
+      Fl_Round_Button {def_widget_size[3]} {
+        user_data 18 user_data_type long
+        callback default_widget_size_cb
+        xywh {180 140 90 25} type Radio down_box ROUND_DOWN_BOX
+      }
+      Fl_Box {} {
+        label medium
+        xywh {195 140 68 25} labelsize 18 align 20
+      }
+      Fl_Round_Button {def_widget_size[4]} {
+        user_data 24 user_data_type long
+        callback default_widget_size_cb
+        xywh {105 165 75 25} type Radio down_box ROUND_DOWN_BOX
+      }
+      Fl_Box {} {
+        label large
+        xywh {120 165 64 25} labelsize 24 align 20
+      }
+      Fl_Round_Button {def_widget_size[5]} {
+        user_data 32 user_data_type long
+        callback default_widget_size_cb
+        xywh {180 165 95 25} type Radio down_box ROUND_DOWN_BOX
+      }
+      Fl_Box {} {
+        label huge
+        xywh {195 165 76 25} labelsize 32 align 20
+      }
+    }
+  }
+} 
+
+comment {
+//
+// End of "$Id: alignment_panel.fl 4632 2005-11-03 22:16:52Z mike $".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/fluid/alignment_panel.h b/Utilities/FLTK/fluid/alignment_panel.h
new file mode 100644
index 0000000000000000000000000000000000000000..a02bd462c33e502a9a8cb06586d652290c62580b
--- /dev/null
+++ b/Utilities/FLTK/fluid/alignment_panel.h
@@ -0,0 +1,105 @@
+//
+// "$Id$"
+//
+// Setting and shell dialogs for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef alignment_panel_h
+#define alignment_panel_h
+#include <FL/Fl.H>
+#include <FL/Fl_Text_Buffer.H>
+#include <FL/Fl_Text_Display.H>
+extern void load_history();
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Preferences.H>
+#include <FL/Fl_Tooltip.H>
+extern Fl_Double_Window *project_window;
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input.H>
+extern void header_input_cb(Fl_Input*, void*);
+extern Fl_Input *header_file_input;
+extern void code_input_cb(Fl_Input*, void*);
+extern Fl_Input *code_file_input;
+#include <FL/Fl_Light_Button.H>
+extern void include_H_from_C_button_cb(Fl_Light_Button*, void*);
+extern Fl_Light_Button *include_H_from_C_button;
+#include <FL/Fl_Choice.H>
+extern void i18n_type_cb(Fl_Choice*, void*);
+extern Fl_Choice *i18n_type_chooser;
+extern void i18n_text_cb(Fl_Input*, void*);
+extern Fl_Input *i18n_include_input;
+extern Fl_Input *i18n_file_input;
+extern Fl_Input *i18n_set_input;
+extern Fl_Input *i18n_function_input;
+Fl_Double_Window* make_project_window();
+extern Fl_Menu_Item menu_i18n_type_chooser[];
+extern void i18n_cb(Fl_Choice *,void *);
+extern Fl_Preferences fluid_prefs;
+extern Fl_Text_Buffer *shell_run_buffer;
+extern void scheme_cb(Fl_Choice *, void *);
+extern Fl_Double_Window *settings_window;
+extern void scheme_cb(Fl_Choice*, void*);
+extern Fl_Choice *scheme_choice;
+#include <FL/Fl_Check_Button.H>
+extern Fl_Check_Button *tooltips_button;
+extern Fl_Check_Button *completion_button;
+extern Fl_Check_Button *openlast_button;
+extern Fl_Check_Button *prevpos_button;
+#include <FL/Fl_Spinner.H>
+extern Fl_Spinner *recent_spinner;
+Fl_Double_Window* make_settings_window();
+extern Fl_Menu_Item menu_scheme_choice[];
+extern Fl_Double_Window *shell_window;
+extern Fl_Input *shell_command_input;
+extern Fl_Check_Button *shell_writecode_button;
+extern Fl_Check_Button *shell_writemsgs_button;
+extern Fl_Check_Button *shell_savefl_button;
+#include <FL/Fl_Return_Button.H>
+extern void do_shell_command(Fl_Return_Button*, void*);
+extern Fl_Double_Window *shell_run_window;
+#include <FL/Fl_Text_Display.H>
+extern Fl_Text_Display *shell_run_display;
+extern Fl_Return_Button *shell_run_button;
+Fl_Double_Window* make_shell_window();
+extern Fl_Double_Window *grid_window;
+extern void grid_cb(Fl_Input*, long);
+extern Fl_Input *horizontal_input;
+extern Fl_Input *vertical_input;
+extern Fl_Input *snap_input;
+extern void guides_cb(Fl_Check_Button*, long);
+extern Fl_Check_Button *guides_toggle;
+#include <FL/Fl_Round_Button.H>
+extern void default_widget_size_cb(Fl_Round_Button*, long);
+extern Fl_Round_Button *def_widget_size[6];
+Fl_Double_Window* make_layout_window();
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/code.cxx b/Utilities/FLTK/fluid/code.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..25f68fc45393eed6bde98abdc23985545d864f7a
--- /dev/null
+++ b/Utilities/FLTK/fluid/code.cxx
@@ -0,0 +1,578 @@
+//
+// "$Id$"
+//
+// Code output routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "../src/flstring.h"
+#include <stdarg.h>
+
+#include <FL/Fl.H>
+#include "Fl_Type.h"
+#include "alignment_panel.h"
+
+static FILE *code_file;
+static FILE *header_file;
+
+extern char i18n_program[];
+extern int i18n_type;
+extern const char* i18n_include;
+extern const char* i18n_function;
+extern const char* i18n_file;
+extern const char* i18n_set;
+
+// return true if c can be in a C identifier.  I needed this so
+// it is not messed up by locale settings:
+int is_id(char c) {
+  return c>='a' && c<='z' || c>='A' && c<='Z' || c>='0' && c<='9' || c=='_';
+}
+
+////////////////////////////////////////////////////////////////
+// Generate unique but human-readable identifiers:
+
+struct id {
+  char* text;
+  void* object;
+  id *left, *right;
+  id (const char* t, void* o) : text(strdup(t)), object(o) {left = right = 0;}
+  ~id();
+};
+
+id::~id() {
+  delete left;
+  free((void *)text);
+  delete right;
+}
+
+static id* id_root;
+
+const char* unique_id(void* o, const char* type, const char* name, const char* label) {
+  char buffer[128];
+  char* q = buffer;
+  while (*type) *q++ = *type++;
+  *q++ = '_';
+  const char* n = name;
+  if (!n || !*n) n = label;
+  if (n && *n) {
+    while (*n && !is_id(*n)) n++;
+    while (is_id(*n)) *q++ = *n++;
+  }
+  *q = 0;
+  // okay, search the tree and see if the name was already used:
+  id** p = &id_root;
+  int which = 0;
+  while (*p) {
+    int i = strcmp(buffer, (*p)->text);
+    if (!i) {
+      if ((*p)->object == o) return (*p)->text;
+      // already used, we need to pick a new name:
+      sprintf(q,"%x",++which);
+      p = &id_root;
+      continue;
+    }
+    else if (i < 0) p = &((*p)->left);
+    else p  = &((*p)->right);
+  }
+  *p = new id(buffer, o);
+  return (*p)->text;
+}
+
+////////////////////////////////////////////////////////////////
+// return current indentation:
+
+static const char* spaces = "                ";
+int indentation;
+const char* indent() {
+  int i = indentation; if (i>16) i = 16;
+  return spaces+16-i;
+}
+
+////////////////////////////////////////////////////////////////
+// declarations/include files:
+// Each string generated by write_declare is written only once to
+// the header file.  This is done by keeping a binary tree of all
+// the calls so far and not printing it if it is in the tree.
+
+struct included {
+  char *text;
+  included *left, *right;
+  included(const char *t) {
+    text = strdup(t);
+    left = right = 0;
+  }
+  ~included();
+};
+
+included::~included() {
+  delete left;
+  free((void *)text);
+  delete right;
+}
+static included *included_root;
+
+int write_declare(const char *format, ...) {
+  va_list args;
+  char buf[1024];
+  va_start(args, format);
+  vsnprintf(buf, sizeof(buf), format, args);
+  va_end(args);
+  included **p = &included_root;
+  while (*p) {
+    int i = strcmp(buf,(*p)->text);
+    if (!i) return 0;
+    else if (i < 0) p = &((*p)->left);
+    else p  = &((*p)->right);
+  }
+  fprintf(header_file,"%s\n",buf);
+  *p = new included(buf);
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+// silly thing to prevent declaring unused variables:
+// When this symbol is on, all attempts to write code don't write
+// anything, but set a variable if it looks like the varaible "o" is used:
+int varused_test;
+int varused;
+
+// write an array of C characters (adds a null):
+void write_cstring(const char *w, int length) {
+  if (varused_test) return;
+  const char *e = w+length;
+  int linelength = 1;
+  putc('\"', code_file);
+  for (; w < e;) {
+    int c = *w++;
+    switch (c) {
+    case '\b': c = 'b'; goto QUOTED;
+    case '\t': c = 't'; goto QUOTED;
+    case '\n': c = 'n'; goto QUOTED;
+    case '\f': c = 'f'; goto QUOTED;
+    case '\r': c = 'r'; goto QUOTED;
+    case '\"':
+    case '\'':
+    case '\\':
+    QUOTED:
+      if (linelength >= 77) {fputs("\\\n",code_file); linelength = 0;}
+      putc('\\', code_file);
+      putc(c, code_file);
+      linelength += 2;
+      break;
+    case '?': // prevent trigraphs by writing ?? as ?\?
+      if (*(w-2) == '?') goto QUOTED;
+      // else fall through:
+    default:
+      if (c >= ' ' && c < 127) {
+	// a legal ASCII character
+	if (linelength >= 78) {fputs("\\\n",code_file); linelength = 0;}
+	putc(c, code_file);
+	linelength++;
+	break;
+      }
+      // otherwise we must print it as an octal constant:
+      c &= 255;
+      if (c < 8) {
+	if (linelength >= 76) {fputs("\\\n",code_file); linelength = 0;}
+	fprintf(code_file, "\\%o",c);
+	linelength += 2;
+      } else if (c < 64) {
+	if (linelength >= 75) {fputs("\\\n",code_file); linelength = 0;}
+	fprintf(code_file, "\\%o",c);
+	linelength += 3;
+      } else {
+	if (linelength >= 74) {fputs("\\\n",code_file); linelength = 0;}
+	fprintf(code_file, "\\%o",c);
+	linelength += 4;
+      }
+      // We must not put more numbers after it, because some C compilers
+      // consume them as part of the quoted sequence.  Use string constant
+      // pasting to avoid this:
+      c = *w;
+      if (w < e && (c>='0'&&c<='9' || c>='a'&&c<='f' || c>='A'&&c<='F')) {
+	putc('\"', code_file); linelength++;
+	if (linelength >= 79) {fputs("\n",code_file); linelength = 0;}
+	putc('\"', code_file); linelength++;
+      }
+      break;
+    }
+  }
+  putc('\"', code_file);
+}
+
+// write a C string, quoting characters if necessary:
+void write_cstring(const char *w) {write_cstring(w,strlen(w));}
+
+// write an array of C binary data (does not add a null):
+void write_cdata(const char *s, int length) {
+  if (varused_test) return;
+  const unsigned char *w = (const unsigned char *)s;
+  const unsigned char *e = w+length;
+  int linelength = 1;
+  putc('{', code_file);
+  for (; w < e;) {
+    unsigned char c = *w++;
+    if (c>99) linelength += 4;
+    else if (c>9) linelength += 3;
+    else linelength += 2;
+    if (linelength >= 77) {fputs("\n",code_file); linelength = 0;}
+    fprintf(code_file, "%d", c);
+    if (w<e) putc(',', code_file);
+  }
+  putc('}', code_file);
+}
+
+void write_c(const char* format,...) {
+  if (varused_test) {varused = 1; return;}
+  va_list args;
+  va_start(args, format);
+  vfprintf(code_file, format, args);
+  va_end(args);
+}
+
+void write_h(const char* format,...) {
+  if (varused_test) return;
+  va_list args;
+  va_start(args, format);
+  vfprintf(header_file, format, args);
+  va_end(args);
+}
+
+#include <FL/filename.H>
+int write_number;
+int write_sourceview;
+
+// recursively dump code, putting children between the two parts
+// of the parent code:
+static Fl_Type* write_code(Fl_Type* p) {
+  if (write_sourceview) {
+    p->code_line = (int)ftell(code_file);
+    if (p->header_line_end==-1)
+      p->header_line = (int)ftell(header_file);
+  }
+  // write all code that come before the children code
+  // (but don't write the last comment until the very end)
+  if (!(p==Fl_Type::last && p->is_comment()))
+    p->write_code1();
+  // recursively write the code of all children
+  Fl_Type* q;
+  if (p->is_widget() && p->is_class()) {
+    // Handle widget classes specially
+    for (q = p->next; q && q->level > p->level;) {
+      if (strcmp(q->type_name(), "Function")) q = write_code(q);
+      else {
+        int level = q->level;
+	do {
+	  q = q->next;
+	} while (q && q->level > level);
+      }
+    }
+
+    // write all code that come after the children 
+    p->write_code2();
+
+    for (q = p->next; q && q->level > p->level;) {
+      if (!strcmp(q->type_name(), "Function")) q = write_code(q);
+      else {
+        int level = q->level;
+	do {
+	  q = q->next;
+	} while (q && q->level > level);
+      }
+    }
+
+    write_h("};\n");
+  } else {
+    for (q = p->next; q && q->level > p->level;) q = write_code(q);
+    // write all code that come after the children 
+    p->write_code2();
+  }
+  if (write_sourceview) {
+    p->code_line_end = (int)ftell(code_file);
+    if (p->header_line_end==-1)
+      p->header_line_end = (int)ftell(header_file);
+  }
+  return q;
+}
+
+extern const char* header_file_name;
+
+int write_code(const char *s, const char *t) {
+  const char *filemode = "w";
+  if (write_sourceview) 
+    filemode = "wb";
+  write_number++;
+  delete id_root; id_root = 0;
+  indentation = 0;
+  if (!s) code_file = stdout;
+  else {
+    FILE *f = fopen(s, filemode);
+    if (!f) return 0;
+    code_file = f;
+  }
+  if (!t) header_file = stdout;
+  else {
+    FILE *f = fopen(t, filemode);
+    if (!f) {fclose(code_file); return 0;}
+    header_file = f;
+  }
+  // if the first entry in the Type tree is a comment, then it is probably 
+  // a copyright notice. We print that before anything else in the file!
+  Fl_Type* first_type = Fl_Type::first;
+  if (first_type && first_type->is_comment()) {
+    if (write_sourceview) {
+      first_type->code_line = (int)ftell(code_file);
+      first_type->header_line = (int)ftell(header_file);
+    }
+    // it is ok to write non-recusive code here, because comments have no children or code2 blocks
+    first_type->write_code1();
+    if (write_sourceview) {
+      first_type->code_line_end = (int)ftell(code_file);
+      first_type->header_line_end = (int)ftell(header_file);
+    }
+    first_type = first_type->next;
+  }
+
+  const char *hdr = "\
+// generated by Fast Light User Interface Designer (fluid) version %.4f\n\n";
+  fprintf(header_file, hdr, FL_VERSION);
+  fprintf(code_file, hdr, FL_VERSION);
+
+  {char define_name[102];
+  const char* a = fl_filename_name(t);
+  char* b = define_name;
+  if (!isalpha(*a)) {*b++ = '_';}
+  while (*a) {*b++ = isalnum(*a) ? *a : '_'; a++;}
+  *b = 0;
+  fprintf(header_file, "#ifndef %s\n", define_name);
+  fprintf(header_file, "#define %s\n", define_name);
+  }  
+
+  write_declare("#include <FL/Fl.H>");
+  if (i18n_type && i18n_include[0]) {
+    if (i18n_include[0] != '<' &&
+        i18n_include[0] != '\"')
+      write_c("#include \"%s\"\n", i18n_include);
+    else
+      write_c("#include %s\n", i18n_include);
+    if (i18n_type == 2) {
+      if (i18n_file[0]) write_c("extern nl_catd %s;\n", i18n_file);
+      else {
+        write_c("// Initialize I18N stuff now for menus...\n");
+        write_c("#include <locale.h>\n");
+	write_c("static char *_locale = setlocale(LC_MESSAGES, \"\");\n");
+        write_c("static nl_catd _catalog = catopen(\"%s\", 0);\n",
+                   i18n_program);
+      }
+    }
+  }
+  if (t && include_H_from_C) {
+    if (*header_file_name == '.' && strchr(header_file_name, '/') == NULL) {
+      write_c("#include \"%s\"\n", fl_filename_name(t));
+    } else {
+      write_c("#include \"%s\"\n", t);
+    }
+  }
+  for (Fl_Type* p = first_type; p;) {
+    // write all static data for this & all children first
+    if (write_sourceview) p->header_line = (int)ftell(header_file);
+    p->write_static();
+    if (write_sourceview) {
+      p->header_line_end = (int)ftell(header_file);
+      if (p->header_line==p->header_line_end) p->header_line_end = -1;
+    }
+    for (Fl_Type* q = p->next; q && q->level > p->level; q = q->next) {
+      if (write_sourceview) q->header_line = (int)ftell(header_file);
+      q->write_static();
+      if (write_sourceview) {
+        q->header_line_end = (int)ftell(header_file);
+        if (q->header_line==q->header_line_end) q->header_line_end = -1;
+      }
+    }
+    // then write the nested code:
+    p = write_code(p);
+  }
+
+  delete included_root; included_root = 0;
+
+  if (!s) return 1;
+
+  fprintf(header_file, "#endif\n");
+
+  Fl_Type* last_type = Fl_Type::last;
+  if (last_type && last_type->is_comment()) {
+    if (write_sourceview) {
+      last_type->code_line = (int)ftell(code_file);
+      last_type->header_line = (int)ftell(header_file);
+    }
+    last_type->write_code1();
+    if (write_sourceview) {
+      last_type->code_line_end = (int)ftell(code_file);
+      last_type->header_line_end = (int)ftell(header_file);
+    }
+  }
+
+  int x = fclose(code_file);
+  code_file = 0;
+  int y = fclose(header_file);
+  header_file = 0;
+  return x >= 0 && y >= 0;
+}
+
+int write_strings(const char *sfile) {
+  FILE *fp = fopen(sfile, "w");
+  Fl_Type *p;
+  Fl_Widget_Type *w;
+  int i;
+
+  if (!fp) return 1;
+
+  switch (i18n_type) {
+  case 0 : /* None, just put static text out */
+      fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
+	      FL_VERSION);
+      for (p = Fl_Type::first; p; p = p->next) {
+        if (p->is_widget()) {
+	  w = (Fl_Widget_Type *)p;
+
+	  if (w->label()) {
+	    for (const char *s = w->label(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            putc('\n', fp);
+	  }
+
+	  if (w->tooltip()) {
+	    for (const char *s = w->tooltip(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            putc('\n', fp);
+	  }
+	}
+      }
+      break;
+  case 1 : /* GNU gettext, put a .po file out */
+      fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
+	      FL_VERSION);
+      for (p = Fl_Type::first; p; p = p->next) {
+        if (p->is_widget()) {
+	  w = (Fl_Widget_Type *)p;
+
+	  if (w->label()) {
+	    const char *s;
+
+	    fputs("msgid \"", fp);
+	    for (s = w->label(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            fputs("\"\n", fp);
+
+	    fputs("msgstr \"", fp);
+	    for (s = w->label(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            fputs("\"\n", fp);
+	  }
+
+	  if (w->tooltip()) {
+	    const char *s;
+
+	    fputs("msgid \"", fp);
+	    for (s = w->tooltip(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            fputs("\"\n", fp);
+
+	    fputs("msgstr \"", fp);
+	    for (s = w->tooltip(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            fputs("\"\n", fp);
+	  }
+	}
+      }
+      break;
+  case 2 : /* POSIX catgets, put a .msg file out */
+      fprintf(fp, "$ generated by Fast Light User Interface Designer (fluid) version %.4f\n",
+	      FL_VERSION);
+      fprintf(fp, "$set %s\n", i18n_set);
+      fputs("$quote \"\n", fp);
+
+      for (i = 1, p = Fl_Type::first; p; p = p->next) {
+        if (p->is_widget()) {
+	  w = (Fl_Widget_Type *)p;
+
+	  if (w->label()) {
+	    fprintf(fp, "%d \"", i ++);
+	    for (const char *s = w->label(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            fputs("\"\n", fp);
+	  }
+
+	  if (w->tooltip()) {
+	    fprintf(fp, "%d \"", i ++);
+	    for (const char *s = w->tooltip(); *s; s ++)
+	      if (*s < 32 || *s > 126 || *s == '\"')
+		fprintf(fp, "\\%03o", *s);
+	      else
+		putc(*s, fp);
+            fputs("\"\n", fp);
+	  }
+	}
+      }
+      break;
+  }
+
+  return fclose(fp);
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Type::write_static() {}
+void Fl_Type::write_code1() {
+  write_h("// Header for %s\n", title());
+  write_c("// Code for %s\n", title());
+}
+void Fl_Type::write_code2() {}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/comments.h b/Utilities/FLTK/fluid/comments.h
new file mode 100644
index 0000000000000000000000000000000000000000..e55a0b71cf10156f3f09f2cbbf2f6eef26fa11ce
--- /dev/null
+++ b/Utilities/FLTK/fluid/comments.h
@@ -0,0 +1,82 @@
+
+static const char * const comment_text[] = {
+  // GNU Public License/GPL Header
+    "//\n"
+    "// NameOfProgram, ShortDescription\n"
+    "// Copyright (C) YYYY  NameOfAuthor\n"
+    "//\n"
+    "// This program is free software; you can redistribute it and/or\n"
+    "// modify it under the terms of the GNU General Public License\n"
+    "// as published by the Free Software Foundation; either version 2\n"
+    "// of the License, or (at your option) any later version.\n"
+    "//\n"
+    "// This program is distributed in the hope that it will be useful,\n"
+    "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "// GNU General Public License for more details.\n"
+    "//\n"
+    "// You should have received a copy of the GNU General Public License\n"
+    "// along with this program; if not, write to the Free Software\n"
+    "// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"
+    "//\n",
+  // GNU Public License/GPL Footer
+    "\n//\n"
+    "// NameOfProgram, ShortDescription\n"
+    "// Copyright (C) YYYY  NameOfAuthor\n"
+    "//",
+  // GNU Public License/LGPL Header
+    "//\n"
+    "// NameOfLibrary, ShortDescription\n"
+    "// Copyright (C) YYYY  NameOfAuthor\n"
+    "//\n"
+    "// This library is free software; you can redistribute it and/or\n"
+    "// modify it under the terms of the GNU Lesser General Public\n"
+    "// License as published by the Free Software Foundation; either\n"
+    "// version 2.1 of the License, or (at your option) any later version.\n"
+    "//\n"
+    "// This library is distributed in the hope that it will be useful,\n"
+    "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "// GNU Lesser General Public License for more details.\n"
+    "//\n"
+    "// You should have received a copy of the GNU Lesser General Public\n"
+    "// License along with this program; if not, write to the Free Software\n"
+    "// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"
+    "//\n",
+  // GNU Public License/LGPL Footer
+    "\n//\n"
+    "// NameOfLibrary, ShortDescription\n"
+    "// Copyright (C) YYYY  NameOfAuthor\n"
+    "//",
+  // FLTK/Header
+    "//\n"
+    "// \"$Id$\"\n"
+    "//\n"
+    "// ... for the Fast Light Tool Kit (FLTK).\n"
+    "//\n"
+    "// Copyright 1998-2005 by Bill Spitzak and others.\n"
+    "//\n"
+    "// This library is free software; you can redistribute it and/or\n"
+    "// modify it under the terms of the GNU Library General Public\n"
+    "// License as published by the Free Software Foundation; either\n"
+    "// version 2 of the License, or (at your option) any later version.\n"
+    "//\n"
+    "// This library is distributed in the hope that it will be useful,\n"
+    "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
+    "// Library General Public License for more details.\n"
+    "//\n"
+    "// You should have received a copy of the GNU Library General Public\n"
+    "// License along with this library; if not, write to the Free Software\n"
+    "// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307\n"
+    "// USA.\n"
+    "//\n"
+    "// Please report all bugs and problems on the following page:\n"
+    "//\n"
+    "//     http://www.fltk.org/str.php\n"
+    "//\n",
+  // FLTK/Footer
+    "\n//\n"
+    "// End of \"$Id$\".\n"
+    "//",
+};
diff --git a/Utilities/FLTK/fluid/factory.cxx b/Utilities/FLTK/fluid/factory.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7eaf5dc87a0eff499a316a36922806fcfd67daf8
--- /dev/null
+++ b/Utilities/FLTK/fluid/factory.cxx
@@ -0,0 +1,1202 @@
+//
+// "$Id$"
+//
+// Widget factory code for the Fast Light Tool Kit (FLTK).
+//
+// Type classes for most of the fltk widgets.  Most of the work
+// is done by code in Fl_Widget_Type.C.  Also a factory instance
+// of each of these type classes.
+//
+// This file also contains the "new" menu, which has a pointer
+// to a factory instance for every class (both the ones defined
+// here and ones in other files)
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Pixmap.H>
+#include <stdio.h>
+#include "../src/flstring.h"
+#include "undo.h"
+
+#include "Fl_Widget_Type.h"
+
+extern Fl_Pixmap *pixmap[];
+
+#if !HAVE_STRCASECMP
+//
+// 'strcasecmp()' - Do a case-insensitive compare...
+//
+
+static int
+strcasecmp(const char *s, const char *t) {
+  while (*s != '\0' && *t != '\0') {
+    if (tolower(*s) < tolower(*t))
+      return (-1);
+    else if (tolower(*s) > tolower(*t))
+      return (1);
+
+    s ++;
+    t ++;
+  }
+
+  if (*s == '\0' && *t == '\0')
+    return (0);
+  else if (*s != '\0')
+    return (1);
+  else
+    return (-1);
+}
+#endif // !HAVE_STRCASECMP
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Box.H>
+class Fl_Box_Type : public Fl_Widget_Type {
+public:
+  virtual const char *type_name() {return "Fl_Box";}
+  Fl_Widget *widget(int x,int y,int w, int h) {
+    return new Fl_Box(x,y,w,h,"label");}
+  Fl_Widget_Type *_make() {return new Fl_Box_Type();}
+  int pixmapID() { return 5; }
+};
+static Fl_Box_Type Fl_Box_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Button.H>
+static Fl_Menu_Item buttontype_menu[] = {
+  {"Normal",0,0,(void*)0},
+  {"Toggle",0,0,(void*)FL_TOGGLE_BUTTON},
+  {"Radio",0,0,(void*)FL_RADIO_BUTTON},
+  {0}};
+class Fl_Button_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return buttontype_menu;}
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Widget_Type::ideal_size(w, h);
+    w += 2 * (o->labelsize() - 4);
+    h = (h / 5) * 5;
+  }
+  virtual const char *type_name() {return "Fl_Button";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Button(x,y,w,h,"button");}
+  Fl_Widget_Type *_make() {return new Fl_Button_Type();}
+  int is_button() const {return 1;}
+  int pixmapID() { return 2; }
+};
+static Fl_Button_Type Fl_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Return_Button.H>
+class Fl_Return_Button_Type : public Fl_Button_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Button_Type::ideal_size(w, h);
+    int W = o->h();
+    if (o->w()/3 < W) W = o->w()/3;
+    w += W + 8 - o->labelsize();
+  }
+  virtual const char *type_name() {return "Fl_Return_Button";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Return_Button(x,y,w,h,"button");}
+  Fl_Widget_Type *_make() {return new Fl_Return_Button_Type();}
+  int pixmapID() { return 23; }
+};
+static Fl_Return_Button_Type Fl_Return_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Repeat_Button.H>
+class Fl_Repeat_Button_Type : public Fl_Widget_Type {
+public:
+  virtual const char *type_name() {return "Fl_Repeat_Button";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Repeat_Button(x,y,w,h,"button");}
+  Fl_Widget_Type *_make() {return new Fl_Repeat_Button_Type();}
+  int pixmapID() { return 25; }
+};
+static Fl_Repeat_Button_Type Fl_Repeat_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Light_Button.H>
+class Fl_Light_Button_Type : public Fl_Button_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Button_Type::ideal_size(w, h);
+    w += 4;
+  }
+  virtual const char *type_name() {return "Fl_Light_Button";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Light_Button(x,y,w,h,"button");}
+  Fl_Widget_Type *_make() {return new Fl_Light_Button_Type();}
+  int pixmapID() { return 24; }
+};
+static Fl_Light_Button_Type Fl_Light_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Check_Button.H>
+class Fl_Check_Button_Type : public Fl_Button_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Button_Type::ideal_size(w, h);
+    w += 4;
+  }
+  virtual const char *type_name() {return "Fl_Check_Button";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Check_Button(x,y,w,h,"button");}
+  Fl_Widget_Type *_make() {return new Fl_Check_Button_Type();}
+  int pixmapID() { return 3; }
+};
+static Fl_Check_Button_Type Fl_Check_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Round_Button.H>
+class Fl_Round_Button_Type : public Fl_Button_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Button_Type::ideal_size(w, h);
+    w += 4;
+  }
+  virtual const char *type_name() {return "Fl_Round_Button";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Round_Button(x,y,w,h,"button");}
+  Fl_Widget_Type *_make() {return new Fl_Round_Button_Type();}
+  int pixmapID() { return 4; }
+};
+static Fl_Round_Button_Type Fl_Round_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+extern int compile_only;
+
+#include <FL/Fl_Browser.H>
+#include <FL/Fl_Check_Browser.H>
+#include <FL/Fl_File_Browser.H>
+
+static Fl_Menu_Item browser_type_menu[] = {
+  {"No Select",0,0,(void*)FL_NORMAL_BROWSER},
+  {"Select",0,0,(void*)FL_SELECT_BROWSER},
+  {"Hold",0,0,(void*)FL_HOLD_BROWSER},
+  {"Multi",0,0,(void*)FL_MULTI_BROWSER},
+  {0}};
+class Fl_Browser_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return browser_type_menu;}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Browser *myo = (Fl_Browser *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h -= Fl::box_dh(o->box());
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    h = ((h + fl_height() - 1) / fl_height()) * fl_height() +
+        Fl::box_dh(o->box());
+    if (h < 30) h = 30;
+    if (w < 50) w = 50;
+  }
+  virtual const char *type_name() {return "Fl_Browser";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Browser* b = new Fl_Browser(x,y,w,h);
+    // Fl_Browser::add calls fl_height(), which requires the X display open.
+    // Avoid this when compiling so it works w/o a display:
+    if (!compile_only) {
+      char buffer[20];
+      for (int i = 1; i <= 20; i++) {
+	sprintf(buffer,"Browser Line %d",i);
+	b->add(buffer);
+      }
+    }
+    return b;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Browser_Type();}
+  int pixmapID() { return 31; }
+};
+static Fl_Browser_Type Fl_Browser_type;
+
+int Fl_Browser_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Browser *myo = (Fl_Browser*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+class Fl_Check_Browser_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return browser_type_menu;}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Check_Browser *myo = (Fl_Check_Browser *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h -= Fl::box_dh(o->box());
+    w -= Fl::box_dw(o->box()) - fl_height();
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    h = ((h + fl_height() - 1) / fl_height()) * fl_height() +
+        Fl::box_dh(o->box());
+    if (h < 30) h = 30;
+    if (w < 50) w = 50;
+  }
+  virtual const char *type_name() {return "Fl_Check_Browser";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Check_Browser* b = new Fl_Check_Browser(x,y,w,h);
+    // Fl_Check_Browser::add calls fl_height(), which requires the X display open.
+    // Avoid this when compiling so it works w/o a display:
+    if (!compile_only) {
+      char buffer[20];
+      for (int i = 1; i <= 20; i++) {
+	sprintf(buffer,"Browser Line %d",i);
+	b->add(buffer);
+      }
+    }
+    return b;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Check_Browser_Type();}
+  int pixmapID() { return 32; }
+};
+static Fl_Check_Browser_Type Fl_Check_Browser_type;
+
+int Fl_Check_Browser_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Check_Browser *myo = (Fl_Check_Browser*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+class Fl_File_Browser_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return browser_type_menu;}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_File_Browser *myo = (Fl_File_Browser *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h -= Fl::box_dh(o->box());
+    w -= Fl::box_dw(o->box()) + fl_height();
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    h = ((h + fl_height() - 1) / fl_height()) * fl_height() +
+        Fl::box_dh(o->box());
+    if (h < 30) h = 30;
+    if (w < 50) w = 50;
+  }
+  virtual const char *type_name() {return "Fl_File_Browser";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_File_Browser* b = new Fl_File_Browser(x,y,w,h);
+    // Fl_File_Browser::add calls fl_height(), which requires the X display open.
+    // Avoid this when compiling so it works w/o a display:
+    if (!compile_only) {
+      b->load(".");
+    }
+    return b;
+  }
+  Fl_Widget_Type *_make() {return new Fl_File_Browser_Type();}
+  int pixmapID() { return 33; }
+};
+static Fl_File_Browser_Type Fl_File_Browser_type;
+
+int Fl_File_Browser_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_File_Browser *myo = (Fl_File_Browser*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Counter.H>
+static Fl_Menu_Item counter_type_menu[] = {
+  {"Normal",0,0,(void*)FL_NORMAL_COUNTER},
+  {"Simple",0,0,(void*)FL_SIMPLE_COUNTER},
+  {0}};
+class Fl_Counter_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return counter_type_menu;}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+  int is_valuator() const {return 1;}
+  int pixmapID() { return 41; }
+public:
+  virtual const char *type_name() {return "Fl_Counter";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Counter(x,y,w,h,"counter:");}
+  Fl_Widget_Type *_make() {return new Fl_Counter_Type();}
+};
+static Fl_Counter_Type Fl_Counter_type;
+
+int Fl_Counter_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Counter *myo = (Fl_Counter*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Spinner.H>
+class Fl_Spinner_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return 0;}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+  int pixmapID() { return 47; }
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Spinner *myo = (Fl_Spinner *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h = fl_height() + myo->textsize() - 6;
+    if (h < 15) h = 15;
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box()) + h / 2;
+    if (w < 40) w = 40	;
+  }
+  virtual const char *type_name() {return "Fl_Spinner";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Spinner(x,y,w,h,"spinner:");}
+  Fl_Widget_Type *_make() {return new Fl_Spinner_Type();}
+};
+static Fl_Spinner_Type Fl_Spinner_type;
+
+int Fl_Spinner_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Spinner *myo = (Fl_Spinner*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = (Fl_Font)myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Input.H>
+static Fl_Menu_Item input_type_menu[] = {
+  {"Normal",0,0,(void*)FL_NORMAL_INPUT},
+  {"Multiline",0,0,(void*)FL_MULTILINE_INPUT},
+  {"Secret",0,0,(void*)FL_SECRET_INPUT},
+  {"Int",0,0,(void*)FL_INT_INPUT},
+  {"Float",0,0,(void*)FL_FLOAT_INPUT},
+  {0}};
+class Fl_Input_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return input_type_menu;}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Input *myo = (Fl_Input *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h = fl_height() + myo->textsize() - 6;
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    if (h < 15) h = 15;
+    if (w < 15) w = 15;
+  }
+  virtual const char *type_name() {return "Fl_Input";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Input *myo = new Fl_Input(x,y,w,h,"input:");
+    myo->value("Text Input");
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Input_Type();}
+  int pixmapID() { return 14; }
+  virtual void copy_properties() {
+    Fl_Widget_Type::copy_properties();
+    Fl_Input_ *d = (Fl_Input_*)live_widget, *s = (Fl_Input_*)o;
+    d->textfont(s->textfont());
+    d->textsize(s->textsize());
+    d->textcolor(s->textcolor());
+  }
+};
+static Fl_Input_Type Fl_Input_type;
+
+int Fl_Input_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Input_ *myo = (Fl_Input_*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_File_Input.H>
+class Fl_File_Input_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return 0;}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_File_Input *myo = (Fl_File_Input *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h = fl_height() + myo->textsize() + 4;
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    if (h < 20) h = 20;
+    if (w < 50) w = 50;
+  }
+  virtual const char *type_name() {return "Fl_File_Input";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_File_Input *myo = new Fl_File_Input(x,y,w,h,"file:");
+    myo->value("/now/is/the/time/for/a/filename.ext");
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_File_Input_Type();}
+  int pixmapID() { return 30; }
+};
+static Fl_File_Input_Type Fl_File_Input_type;
+
+int Fl_File_Input_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_File_Input *myo = (Fl_File_Input*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Text_Display.H>
+class Fl_Text_Display_Type : public Fl_Widget_Type {
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Text_Display *myo = (Fl_Text_Display *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h -= Fl::box_dh(o->box());
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    h = ((h + fl_height() - 1) / fl_height()) * fl_height() +
+        Fl::box_dh(o->box());
+    if (h < 30) h = 30;
+    if (w < 50) w = 50;
+  }
+  virtual const char *type_name() {return "Fl_Text_Display";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Text_Display *myo = new Fl_Text_Display(x,y,w,h);
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Text_Display_Type();}
+  int pixmapID() { return 28; }
+};
+static Fl_Text_Display_Type Fl_Text_Display_type;
+
+int Fl_Text_Display_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Text_Display *myo = (Fl_Text_Display*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Text_Editor.H>
+class Fl_Text_Editor_Type : public Fl_Widget_Type {
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Text_Editor *myo = (Fl_Text_Editor *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h -= Fl::box_dh(o->box());
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    h = ((h + fl_height() - 1) / fl_height()) * fl_height() +
+        Fl::box_dh(o->box());
+    if (h < 30) h = 30;
+    if (w < 50) w = 50;
+  }
+  virtual const char *type_name() {return "Fl_Text_Editor";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Text_Editor *myo = new Fl_Text_Editor(x,y,w,h);
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Text_Editor_Type();}
+  int pixmapID() { return 29; }
+};
+static Fl_Text_Editor_Type Fl_Text_Editor_type;
+
+int Fl_Text_Editor_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Text_Editor *myo = (Fl_Text_Editor*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Clock.H>
+class Fl_Clock_Type : public Fl_Widget_Type {
+public:
+  virtual const char *type_name() {return "Fl_Clock";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Clock(x,y,w,h);}
+  Fl_Widget_Type *_make() {return new Fl_Clock_Type();}
+  int pixmapID() { return 34; }
+};
+static Fl_Clock_Type Fl_Clock_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Help_View.H>
+class Fl_Help_View_Type : public Fl_Widget_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Help_View *myo = (Fl_Help_View *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h -= Fl::box_dh(o->box());
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    h = ((h + fl_height() - 1) / fl_height()) * fl_height() +
+        Fl::box_dh(o->box());
+    if (h < 30) h = 30;
+    if (w < 50) w = 50;
+  }
+  virtual const char *type_name() {return "Fl_Help_View";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Help_View *myo = new Fl_Help_View(x,y,w,h);
+    myo->value("<HTML><BODY><H1>Fl_Help_View Widget</H1>"
+               "<P>This is a Fl_Help_View widget.</P></BODY></HTML>");
+    return myo;}
+  Fl_Widget_Type *_make() {return new Fl_Help_View_Type();}
+  int pixmapID() { return 35; }
+};
+static Fl_Help_View_Type Fl_Help_View_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Progress.H>
+class Fl_Progress_Type : public Fl_Widget_Type {
+public:
+  virtual const char *type_name() {return "Fl_Progress";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Progress *myo = new Fl_Progress(x,y,w,h,"label");
+    myo->value(50);
+    return myo;}
+  Fl_Widget_Type *_make() {return new Fl_Progress_Type();}
+  int pixmapID() { return 36; }
+};
+static Fl_Progress_Type Fl_Progress_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Adjuster.H>
+class Fl_Adjuster_Type : public Fl_Widget_Type {
+  int is_valuator() const {return 1;}
+public:
+  virtual const char *type_name() {return "Fl_Adjuster";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Adjuster(x,y,w,h);}
+  Fl_Widget_Type *_make() {return new Fl_Adjuster_Type();}
+  int pixmapID() { return 40; }
+};
+static Fl_Adjuster_Type Fl_Adjuster_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Dial.H>
+static Fl_Menu_Item dial_type_menu[] = {
+  {"Dot",0,0,(void*)0},
+  {"Line",0,0,(void*)FL_LINE_DIAL},
+  {"Fill",0,0,(void*)FL_FILL_DIAL},
+  {0}};
+class Fl_Dial_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return dial_type_menu;}
+  int is_valuator() const {return 1;}
+public:
+  virtual const char *type_name() {return "Fl_Dial";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Dial(x,y,w,h);}
+  Fl_Widget_Type *_make() {return new Fl_Dial_Type();}
+  int pixmapID() { return 42; }
+};
+static Fl_Dial_Type Fl_Dial_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Roller.H>
+static Fl_Menu_Item roller_type_menu[] = {
+  {"Vertical",0,0,(void*)0},
+  {"Horizontal",0,0,(void*)FL_HORIZONTAL},
+  {0}};
+class Fl_Roller_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return roller_type_menu;}
+  int is_valuator() const {return 1;}
+public:
+  virtual const char *type_name() {return "Fl_Roller";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Roller(x,y,w,h);}
+  Fl_Widget_Type *_make() {return new Fl_Roller_Type();}
+  int pixmapID() { return 43; }
+};
+static Fl_Roller_Type Fl_Roller_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Scrollbar.H>
+static Fl_Menu_Item slider_type_menu[] = {
+  {"Vertical",0,0,(void*)FL_VERT_SLIDER},
+  {"Horizontal",0,0,(void*)FL_HOR_SLIDER},
+  {"Vert Fill",0,0,(void*)FL_VERT_FILL_SLIDER},
+  {"Horz Fill",0,0,(void*)FL_HOR_FILL_SLIDER},
+  {"Vert Knob",0,0,(void*)FL_VERT_NICE_SLIDER},
+  {"Horz Knob",0,0,(void*)FL_HOR_NICE_SLIDER},
+  {0}};
+class Fl_Slider_Type : public Fl_Widget_Type {
+  Fl_Menu_Item *subtypes() {return slider_type_menu;}
+  int is_valuator() const {return 2;}
+public:
+  virtual const char *type_name() {return "Fl_Slider";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Slider(x,y,w,h,"slider:");}
+  Fl_Widget_Type *_make() {return new Fl_Slider_Type();}
+  int pixmapID() { return 37; }
+};
+static Fl_Slider_Type Fl_Slider_type;
+
+static Fl_Menu_Item scrollbar_type_menu[] = {
+  {"Vertical",0,0,(void*)FL_VERT_SLIDER},
+  {"Horizontal",0,0,(void*)FL_HOR_SLIDER},
+  {0}};
+class Fl_Scrollbar_Type : public Fl_Slider_Type {
+  Fl_Menu_Item *subtypes() {return scrollbar_type_menu;}
+public:
+  virtual const char *type_name() {return "Fl_Scrollbar";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Scrollbar(x,y,w,h);}
+  Fl_Widget_Type *_make() {return new Fl_Scrollbar_Type();}
+  int pixmapID() { return 38; }
+};
+static Fl_Scrollbar_Type Fl_Scrollbar_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Output.H>
+static Fl_Menu_Item output_type_menu[] = {
+  {"Normal",0,0,(void*)FL_NORMAL_OUTPUT},
+  {"Multiline",0,0,(void*)FL_MULTILINE_OUTPUT},
+  {0}};
+class Fl_Output_Type : public Fl_Input_Type {
+  Fl_Menu_Item *subtypes() {return output_type_menu;}
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Output *myo = (Fl_Output *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h = fl_height() + myo->textsize() - 6;
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    if (h < 15) h = 15;
+    if (w < 15) w = 15;
+  }
+  virtual const char *type_name() {return "Fl_Output";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Output *myo = new Fl_Output(x,y,w,h,"output:");
+    myo->value("Text Output");
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Output_Type();}
+  int pixmapID() { return 27; }
+};
+static Fl_Output_Type Fl_Output_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Value_Input.H>
+class Fl_Value_Input_Type : public Fl_Widget_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Value_Input *myo = (Fl_Value_Input *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h = fl_height() + myo->textsize() - 6;
+    w -= Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    if (h < 15) h = 15;
+    if (w < 15) w = 15;
+  }
+  virtual const char *type_name() {return "Fl_Value_Input";}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+  int is_valuator() const {return 1;}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Value_Input *myo = new Fl_Value_Input(x,y,w,h,"value:");
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Value_Input_Type();}
+  int pixmapID() { return 44; }
+};
+static Fl_Value_Input_Type Fl_Value_Input_type;
+
+int Fl_Value_Input_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Value_Input *myo = (Fl_Value_Input*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Value_Output.H>
+class Fl_Value_Output_Type : public Fl_Widget_Type {
+public:
+  virtual void ideal_size(int &w, int &h) {
+    Fl_Value_Output *myo = (Fl_Value_Output *)o;
+    fl_font(myo->textfont(), myo->textsize());
+    h = fl_height() + myo->textsize() - 6;
+    w = o->w() - Fl::box_dw(o->box());
+    int ww = (int)fl_width('m');
+    w = ((w + ww - 1) / ww) * ww + Fl::box_dw(o->box());
+    if (h < 15) h = 15;
+    if (w < 15) w = 15;
+  }
+  virtual const char *type_name() {return "Fl_Value_Output";}
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+  int is_valuator() const {return 1;}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    Fl_Value_Output *myo = new Fl_Value_Output(x,y,w,h,"value:");
+    return myo;
+  }
+  Fl_Widget_Type *_make() {return new Fl_Value_Output_Type();}
+  int pixmapID() { return 45; }
+};
+static Fl_Value_Output_Type Fl_Value_Output_type;
+
+int Fl_Value_Output_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Value_Output *myo = (Fl_Value_Output*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Value_Slider.H>
+class Fl_Value_Slider_Type : public Fl_Slider_Type {
+  int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c);
+public:
+  virtual const char *type_name() {return "Fl_Value_Slider";}
+  Fl_Widget *widget(int x,int y,int w,int h) {
+    return new Fl_Value_Slider(x,y,w,h,"slider:");}
+  Fl_Widget_Type *_make() {return new Fl_Value_Slider_Type();}
+  int pixmapID() { return 39; }
+};
+static Fl_Value_Slider_Type Fl_Value_Slider_type;
+
+int Fl_Value_Slider_Type::textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+  Fl_Value_Slider *myo = (Fl_Value_Slider*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+  switch (w) {
+    case 4:
+    case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+    case 1: myo->textfont(f); break;
+    case 2: myo->textsize(s); break;
+    case 3: myo->textcolor(c); break;
+  }
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+extern class Fl_Function_Type Fl_Function_type;
+extern class Fl_Code_Type Fl_Code_type;
+extern class Fl_CodeBlock_Type Fl_CodeBlock_type;
+extern class Fl_Decl_Type Fl_Decl_type;
+extern class Fl_DeclBlock_Type Fl_DeclBlock_type;
+extern class Fl_Comment_Type Fl_Comment_type;
+extern class Fl_Class_Type Fl_Class_type;
+extern class Fl_Window_Type Fl_Window_type;
+extern class Fl_Widget_Class_Type Fl_Widget_Class_type;
+extern class Fl_Group_Type Fl_Group_type;
+extern class Fl_Pack_Type Fl_Pack_type;
+extern class Fl_Tabs_Type Fl_Tabs_type;
+extern class Fl_Scroll_Type Fl_Scroll_type;
+extern class Fl_Tile_Type Fl_Tile_type;
+extern class Fl_Input_Choice_Type Fl_Input_Choice_type;
+extern class Fl_Choice_Type Fl_Choice_type;
+extern class Fl_Menu_Bar_Type Fl_Menu_Bar_type;
+extern class Fl_Menu_Button_Type Fl_Menu_Button_type;
+extern class Fl_Menu_Item_Type Fl_Menu_Item_type;
+extern class Fl_Submenu_Type Fl_Submenu_type;
+extern class Fl_Wizard_Type Fl_Wizard_type;
+
+extern void select(Fl_Type *,int);
+extern void select_only(Fl_Type *);
+
+#include <FL/Fl_Window.H>
+
+static void cb(Fl_Widget *, void *v) {
+  undo_checkpoint();
+  undo_suspend();
+  Fl_Type *t = ((Fl_Type*)v)->make();
+  if (t) {
+    if (t->is_widget() && !t->is_window()) {
+      Fl_Widget_Type *wt = (Fl_Widget_Type *)t;
+
+      // Set font sizes...
+      wt->o->labelsize(Fl_Widget_Type::default_size);
+
+      Fl_Font f;
+      int s = Fl_Widget_Type::default_size;
+      Fl_Color c;
+
+      wt->textstuff(2, f, s, c);
+
+      // Resize and/or reposition new widget...
+      int w = 0, h = 0;
+      wt->ideal_size(w, h);
+
+      if (!strcmp(wt->type_name(), "Fl_Menu_Bar")) {
+        // Move and resize the menubar across the top of the window...
+        wt->o->resize(0, 0, w, h);
+      } else {
+        // Just resize to the ideal size...
+        wt->o->size(w, h);
+      }
+    }
+    select_only(t);
+    set_modflag(1);
+    t->open();
+  } else {
+    undo_current --;
+    undo_last --;
+  }
+  undo_resume();
+}
+
+Fl_Menu_Item New_Menu[] = {
+{"Code",0,0,0,FL_SUBMENU},
+  {"Function/Method",0,cb,(void*)&Fl_Function_type},
+  {"Code",0,cb,(void*)&Fl_Code_type},
+  {"Code Block",0,cb,(void*)&Fl_CodeBlock_type},
+  {"Declaration",0,cb,(void*)&Fl_Decl_type},
+  {"Declaration Block",0,cb,(void*)&Fl_DeclBlock_type},
+  {"Class",0,cb,(void*)&Fl_Class_type},
+  {"Widget Class",0,cb,(void*)&Fl_Widget_Class_type},
+  {"Comment",0,cb,(void*)&Fl_Comment_type},
+{0},
+{"Group",0,0,0,FL_SUBMENU},
+  {0,0,cb,(void*)&Fl_Window_type},
+  {0,0,cb,(void*)&Fl_Group_type},
+  {0,0,cb,(void*)&Fl_Pack_type},
+  {0,0,cb,(void*)&Fl_Tabs_type},
+  {0,0,cb,(void*)&Fl_Scroll_type},
+  {0,0,cb,(void*)&Fl_Tile_type},
+  {0,0,cb,(void*)&Fl_Wizard_type},
+{0},
+{"Buttons",0,0,0,FL_SUBMENU},
+  {0,0,cb,(void*)&Fl_Button_type},
+  {0,0,cb,(void*)&Fl_Return_Button_type},
+  {0,0,cb,(void*)&Fl_Light_Button_type},
+  {0,0,cb,(void*)&Fl_Check_Button_type},
+  {0,0,cb,(void*)&Fl_Repeat_Button_type},
+  {0,0,cb,(void*)&Fl_Round_Button_type},
+{0},
+{"Valuators",0,0,0,FL_SUBMENU},
+  {0,0,cb,(void*)&Fl_Slider_type},
+  {0,0,cb,(void*)&Fl_Scrollbar_type},
+  {0,0,cb,(void*)&Fl_Value_Slider_type},
+  {0,0,cb,(void*)&Fl_Adjuster_type},
+  {0,0,cb,(void*)&Fl_Counter_type},
+  {0,0,cb,(void*)&Fl_Spinner_type},
+  {0,0,cb,(void*)&Fl_Dial_type},
+  {0,0,cb,(void*)&Fl_Roller_type},
+  {0,0,cb,(void*)&Fl_Value_Input_type},
+  {0,0,cb,(void*)&Fl_Value_Output_type},
+{0},
+{"Text",0,0,0,FL_SUBMENU},
+  {0,0,cb,(void*)&Fl_File_Input_type},
+  {0,0,cb,(void*)&Fl_Input_type},
+  {0,0,cb,(void*)&Fl_Output_type},
+  {0,0,cb,(void*)&Fl_Text_Display_type},
+  {0,0,cb,(void*)&Fl_Text_Editor_type},
+{0},
+{"Menus",0,0,0,FL_SUBMENU},
+  {0,0,cb,(void*)&Fl_Menu_Bar_type},
+  {0,0,cb,(void*)&Fl_Menu_Button_type},
+  {0,0,cb,(void*)&Fl_Choice_type},
+  {0,0,cb,(void*)&Fl_Input_Choice_type},
+  {0,0,cb, (void*)&Fl_Submenu_type},
+  {0,0,cb, (void*)&Fl_Menu_Item_type},
+{0},
+{"Browsers",0,0,0,FL_SUBMENU},
+  {0,0,cb,(void*)&Fl_Browser_type},
+  {0,0,cb,(void*)&Fl_Check_Browser_type},
+  {0,0,cb,(void*)&Fl_File_Browser_type},
+{0},
+{"Other",0,0,0,FL_SUBMENU},
+  {0,0,cb,(void*)&Fl_Box_type},
+  {0,0,cb,(void*)&Fl_Clock_type},
+  {0,0,cb,(void*)&Fl_Help_View_type},
+  {0,0,cb,(void*)&Fl_Progress_type},
+{0},
+{0}};
+
+#include <FL/Fl_Multi_Label.H>
+
+// modify a menuitem to display an icon in front of the label
+static void make_iconlabel( Fl_Menu_Item *mi, Fl_Image *ic, const char *txt )
+{
+  if (ic) {
+    char *t1 = new char[strlen(txt)+6];
+    strcpy( t1, " " );
+    strcat(t1, txt);
+    strcat(t1, "...");
+    mi->image( ic );
+    Fl_Multi_Label *ml = new Fl_Multi_Label;
+    ml->labela = (char*)ic;
+    ml->labelb = t1;
+    ml->typea = _FL_IMAGE_LABEL;
+    ml->typeb = FL_NORMAL_LABEL;
+    ml->label( mi );
+  }
+  else if (txt!=mi->text)
+    mi->label(txt);
+}
+
+void fill_in_New_Menu() {
+  for (unsigned i = 0; i < sizeof(New_Menu)/sizeof(*New_Menu); i++) {
+    Fl_Menu_Item *m = New_Menu+i;
+    if (m->user_data()) {
+      Fl_Type *t = (Fl_Type*)m->user_data();
+      if (m->text) {
+	make_iconlabel( m, pixmap[t->pixmapID()], m->label() );
+      }
+      else {
+	const char *n = t->type_name();
+	if (!strncmp(n,"Fl_",3)) n += 3;
+	make_iconlabel( m, pixmap[t->pixmapID()], n );
+      }
+    }
+  }
+}
+
+// use keyword to pick the type, this is used to parse files:
+int reading_file;
+Fl_Type *Fl_Type_make(const char *tn) {
+  reading_file = 1; // makes labels be null
+  Fl_Type *r = 0;
+  for (unsigned i = 0; i < sizeof(New_Menu)/sizeof(*New_Menu); i++) {
+    Fl_Menu_Item *m = New_Menu+i;
+    if (!m->user_data()) continue;
+    Fl_Type *t = (Fl_Type*)(m->user_data());
+    if (!strcasecmp(tn,t->type_name())) {r = t->make(); break;}
+  }
+  reading_file = 0;
+  return r;
+}
+
+////////////////////////////////////////////////////////////////
+
+// Since I have included all the .H files, do this table here:
+// This table is only used to read fdesign files:
+
+struct symbol {const char *name; int value;};
+
+static symbol table[] = {
+  {"BLACK",	FL_BLACK},
+  {"RED",	FL_RED},
+  {"GREEN",	FL_GREEN},
+  {"YELLOW",	FL_YELLOW},
+  {"BLUE",	FL_BLUE},
+  {"MAGENTA",	FL_MAGENTA},
+  {"CYAN",	FL_CYAN},
+  {"WHITE",	FL_WHITE},
+
+  {"LCOL",		 FL_BLACK},
+  {"COL1",		 FL_GRAY},
+  {"MCOL",		 FL_LIGHT1},
+  {"LEFT_BCOL",		 FL_LIGHT3},
+  {"TOP_BCOL",		 FL_LIGHT2},
+  {"BOTTOM_BCOL",	 FL_DARK2},
+  {"RIGHT_BCOL",		 FL_DARK3},
+  {"INACTIVE",		 FL_INACTIVE_COLOR},
+  {"INACTIVE_COL",	 FL_INACTIVE_COLOR},
+  {"FREE_COL1",		 FL_FREE_COLOR},
+  {"FREE_COL2",		 FL_FREE_COLOR+1},
+  {"FREE_COL3",		 FL_FREE_COLOR+2},
+  {"FREE_COL4",		 FL_FREE_COLOR+3},
+  {"FREE_COL5",		 FL_FREE_COLOR+4},
+  {"FREE_COL6",		 FL_FREE_COLOR+5},
+  {"FREE_COL7",		 FL_FREE_COLOR+6},
+  {"FREE_COL8",		 FL_FREE_COLOR+7},
+  {"FREE_COL9",		 FL_FREE_COLOR+8},
+  {"FREE_COL10",		 FL_FREE_COLOR+9},
+  {"FREE_COL11",		 FL_FREE_COLOR+10},
+  {"FREE_COL12",		 FL_FREE_COLOR+11},
+  {"FREE_COL13",		 FL_FREE_COLOR+12},
+  {"FREE_COL14",		 FL_FREE_COLOR+13},
+  {"FREE_COL15",		 FL_FREE_COLOR+14},
+  {"FREE_COL16",		 FL_FREE_COLOR+15},
+  {"TOMATO",		 131},
+  {"INDIANRED",		 164},
+  {"SLATEBLUE",		 195},
+  {"DARKGOLD",		 84},
+  {"PALEGREEN",		 157},
+  {"ORCHID",		 203},
+  {"DARKCYAN",		 189},
+  {"DARKTOMATO",		 113},
+  {"WHEAT",		 174},
+  {"ALIGN_CENTER",	FL_ALIGN_CENTER},
+  {"ALIGN_TOP",		FL_ALIGN_TOP},
+  {"ALIGN_BOTTOM",	FL_ALIGN_BOTTOM},
+  {"ALIGN_LEFT",	FL_ALIGN_LEFT},
+  {"ALIGN_RIGHT",	FL_ALIGN_RIGHT},
+  {"ALIGN_INSIDE",	FL_ALIGN_INSIDE},
+  {"ALIGN_TOP_LEFT",	 FL_ALIGN_TOP | FL_ALIGN_LEFT},
+  {"ALIGN_TOP_RIGHT",	 FL_ALIGN_TOP | FL_ALIGN_RIGHT},
+  {"ALIGN_BOTTOM_LEFT",	 FL_ALIGN_BOTTOM | FL_ALIGN_LEFT},
+  {"ALIGN_BOTTOM_RIGHT", FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT},
+  {"ALIGN_CENTER|FL_ALIGN_INSIDE",	FL_ALIGN_CENTER|FL_ALIGN_INSIDE},
+  {"ALIGN_TOP|FL_ALIGN_INSIDE",		FL_ALIGN_TOP|FL_ALIGN_INSIDE},
+  {"ALIGN_BOTTOM|FL_ALIGN_INSIDE",	FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE},
+  {"ALIGN_LEFT|FL_ALIGN_INSIDE",	FL_ALIGN_LEFT|FL_ALIGN_INSIDE},
+  {"ALIGN_RIGHT|FL_ALIGN_INSIDE",	FL_ALIGN_RIGHT|FL_ALIGN_INSIDE},
+  {"ALIGN_INSIDE|FL_ALIGN_INSIDE",	FL_ALIGN_INSIDE|FL_ALIGN_INSIDE},
+  {"ALIGN_TOP_LEFT|FL_ALIGN_INSIDE",	FL_ALIGN_TOP|FL_ALIGN_LEFT|FL_ALIGN_INSIDE},
+  {"ALIGN_TOP_RIGHT|FL_ALIGN_INSIDE",	FL_ALIGN_TOP|FL_ALIGN_RIGHT|FL_ALIGN_INSIDE},
+  {"ALIGN_BOTTOM_LEFT|FL_ALIGN_INSIDE",	FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_INSIDE},
+  {"ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE",FL_ALIGN_BOTTOM|FL_ALIGN_RIGHT|FL_ALIGN_INSIDE},
+
+  {"ALIGN_LEFT_TOP",	 FL_ALIGN_TOP | FL_ALIGN_LEFT},
+  {"ALIGN_RIGHT_TOP",	 FL_ALIGN_TOP | FL_ALIGN_RIGHT},
+  {"ALIGN_LEFT_BOTTOM",	 FL_ALIGN_BOTTOM | FL_ALIGN_LEFT},
+  {"ALIGN_RIGHT_BOTTOM", FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT},
+  {"INVALID_STYLE",	 255},
+  {"NORMAL_STYLE",	 FL_HELVETICA},
+  {"BOLD_STYLE",		 FL_HELVETICA|FL_BOLD},
+  {"ITALIC_STYLE",	 FL_HELVETICA|FL_ITALIC},
+  {"BOLDITALIC_STYLE",	 FL_HELVETICA|FL_BOLD|FL_ITALIC},
+  {"FIXED_STYLE",	 FL_COURIER},
+  {"FIXEDBOLD_STYLE",	 FL_COURIER|FL_BOLD},
+  {"FIXEDITALIC_STYLE",	 FL_COURIER|FL_ITALIC},
+  {"FIXEDBOLDITALIC_STYLE",  FL_COURIER|FL_BOLD|FL_ITALIC},
+  {"TIMES_STYLE",	 FL_TIMES},
+  {"TIMESBOLD_STYLE",	 FL_TIMES|FL_BOLD},
+  {"TIMESITALIC_STYLE",	 FL_TIMES|FL_ITALIC},
+  {"TIMESBOLDITALIC_STYLE",  FL_TIMES|FL_BOLD|FL_ITALIC},
+  {"SHADOW_STYLE",	(_FL_SHADOW_LABEL<<8)},
+  {"ENGRAVED_STYLE",	(_FL_ENGRAVED_LABEL<<8)},
+  {"EMBOSSED_STYLE",	(_FL_EMBOSSED_LABEL<<0)},
+  {"TINY_SIZE",		 8},
+  {"SMALL_SIZE",		 11},
+  {"NORMAL_SIZE",	 FL_NORMAL_SIZE},
+  {"MEDIUM_SIZE",	 18},
+  {"LARGE_SIZE",		 24},
+  {"HUGE_SIZE",		 32},
+  {"DEFAULT_SIZE",	 FL_NORMAL_SIZE},
+  {"TINY_FONT",		 8},
+  {"SMALL_FONT",		 11},
+  {"NORMAL_FONT",	 FL_NORMAL_SIZE},
+  {"MEDIUM_FONT",	 18},
+  {"LARGE_FONT",		 24},
+  {"HUGE_FONT",		 32},
+  {"NORMAL_FONT1",	 11},
+  {"NORMAL_FONT2",	 FL_NORMAL_SIZE},
+  {"DEFAULT_FONT",	 11},
+  {"RETURN_END_CHANGED",  0},
+  {"RETURN_CHANGED",	 1},
+  {"RETURN_END",		 2},
+  {"RETURN_ALWAYS",	 3},
+  {"PUSH_BUTTON",	FL_TOGGLE_BUTTON},
+  {"RADIO_BUTTON",	FL_RADIO_BUTTON},
+  {"HIDDEN_BUTTON",	FL_HIDDEN_BUTTON},
+  {"SELECT_BROWSER",	FL_SELECT_BROWSER},
+  {"HOLD_BROWSER",	FL_HOLD_BROWSER},
+  {"MULTI_BROWSER",	FL_MULTI_BROWSER},
+  {"SIMPLE_COUNTER",	FL_SIMPLE_COUNTER},
+  {"LINE_DIAL",		FL_LINE_DIAL},
+  {"FILL_DIAL",		FL_FILL_DIAL},
+  {"VERT_SLIDER",	FL_VERT_SLIDER},
+  {"HOR_SLIDER",	FL_HOR_SLIDER},
+  {"VERT_FILL_SLIDER",	FL_VERT_FILL_SLIDER},
+  {"HOR_FILL_SLIDER",	FL_HOR_FILL_SLIDER},
+  {"VERT_NICE_SLIDER",	FL_VERT_NICE_SLIDER},
+  {"HOR_NICE_SLIDER",	FL_HOR_NICE_SLIDER},
+};
+
+#include <stdlib.h>
+
+int lookup_symbol(const char *name, int &v, int numberok) {
+  if (name[0]=='F' && name[1]=='L' && name[2]=='_') name += 3;
+  for (int i=0; i < int(sizeof(table)/sizeof(*table)); i++)
+    if (!strcasecmp(name,table[i].name)) {v = table[i].value; return 1;}
+  if (numberok && ((v = atoi(name)) || !strcmp(name,"0"))) return 1;
+  return 0;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/file.cxx b/Utilities/FLTK/fluid/file.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fe41fc4b3117dc0edc4cfa37df0f3183449fabd1
--- /dev/null
+++ b/Utilities/FLTK/fluid/file.cxx
@@ -0,0 +1,643 @@
+//
+// "$Id$"
+//
+// Fluid file routines for the Fast Light Tool Kit (FLTK).
+//
+// You may find the basic read_* and write_* routines to
+// be useful for other programs.  I have used them many times.
+// They are somewhat similar to tcl, using matching { and }
+// to quote strings.
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "../src/flstring.h"
+#include <stdarg.h>
+#include "alignment_panel.h"
+
+////////////////////////////////////////////////////////////////
+// BASIC FILE WRITING:
+
+static FILE *fout;
+
+int open_write(const char *s) {
+  if (!s) {fout = stdout; return 1;}
+  FILE *f = fopen(s,"w");
+  if (!f) return 0;
+  fout = f;
+  return 1;
+}
+
+int close_write() {
+  if (fout != stdout) {
+    int x = fclose(fout);
+    fout = stdout;
+    return x >= 0;
+  }
+  return 1;
+}
+
+static int needspace;
+int is_id(char); // in code.C
+
+// write a string, quoting characters if necessary:
+void write_word(const char *w) {
+  if (needspace) putc(' ', fout);
+  needspace = 1;
+  if (!w || !*w) {fprintf(fout,"{}"); return;}
+  const char *p;
+  // see if it is a single word:
+  for (p = w; is_id(*p); p++) ;
+  if (!*p) {fprintf(fout,"%s",w); return;}
+  // see if there are matching braces:
+  int n = 0;
+  for (p = w; *p; p++) {
+    if (*p == '{') n++;
+    else if (*p == '}') {n--; if (n<0) break;}
+  }
+  int mismatched = (n != 0);
+  // write out brace-quoted string:
+  putc('{', fout);
+  for (; *w; w++) {
+    switch (*w) {
+    case '{':
+    case '}':
+      if (!mismatched) break;
+    case '\\':
+    case '#':
+      putc('\\',fout);
+      break;
+    }
+    putc(*w,fout);
+  }
+  putc('}', fout);
+}
+
+// write an arbitrary formatted word, or a comment, etc:
+void write_string(const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  if (needspace) fputc(' ',fout);
+  vfprintf(fout, format, args);
+  va_end(args);
+  needspace = !isspace(format[strlen(format)-1]);
+}
+
+// start a new line and indent it for a given nesting level:
+void write_indent(int n) {
+  fputc('\n',fout);
+  while (n--) {fputc(' ',fout); fputc(' ',fout);}
+  needspace = 0;
+}
+
+// write a '{' at the given indenting level:
+void write_open(int) {
+  if (needspace) fputc(' ',fout);
+  fputc('{',fout);
+  needspace = 0;
+}
+
+// write a '}' at the given indenting level:
+void write_close(int n) {
+  if (needspace) write_indent(n);
+  fputc('}',fout);
+  needspace = 1;
+}
+
+////////////////////////////////////////////////////////////////
+// BASIC FILE READING:
+
+static FILE *fin;
+static int lineno;
+static const char *fname;
+
+int open_read(const char *s) {
+  lineno = 1;
+  if (!s) {fin = stdin; fname = "stdin"; return 1;}
+  FILE *f = fopen(s,"r");
+  if (!f) return 0;
+  fin = f;
+  fname = s;
+  return 1;
+}
+
+int close_read() {
+  if (fin != stdin) {
+    int x = fclose(fin);
+    fin = 0;
+    return x >= 0;
+  }
+  return 1;
+}
+
+#include <FL/fl_message.H>
+
+void read_error(const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  if (!fin) {
+    char buffer[1024];
+    vsnprintf(buffer, sizeof(buffer), format, args);
+    fl_message(buffer);
+  } else {
+    fprintf(stderr, "%s:%d: ", fname, lineno);
+    vfprintf(stderr, format, args);
+    fprintf(stderr, "\n");
+  }
+  va_end(args);
+}
+
+static int hexdigit(int x) {
+  if (isdigit(x)) return x-'0';
+  if (isupper(x)) return x-'A'+10;
+  if (islower(x)) return x-'a'+10;
+  return 20;
+}
+
+
+static int read_quoted() {	// read whatever character is after a \ .
+  int c,d,x;
+  switch(c = fgetc(fin)) {
+  case '\n': lineno++; return -1;
+  case 'a' : return('\a');
+  case 'b' : return('\b');
+  case 'f' : return('\f');
+  case 'n' : return('\n');
+  case 'r' : return('\r');
+  case 't' : return('\t');
+  case 'v' : return('\v');
+  case 'x' :	/* read hex */
+    for (c=x=0; x<3; x++) {
+      int ch = fgetc(fin);
+      d = hexdigit(ch);
+      if (d > 15) {ungetc(ch,fin); break;}
+      c = (c<<4)+d;
+    }
+    break;
+  default:		/* read octal */
+    if (c<'0' || c>'7') break;
+    c -= '0';
+    for (x=0; x<2; x++) {
+      int ch = fgetc(fin);
+      d = hexdigit(ch);
+      if (d>7) {ungetc(ch,fin); break;}
+      c = (c<<3)+d;
+    }
+    break;
+  }
+  return(c);
+}
+
+// return a word read from the file, or NULL at the EOF:
+// This will skip all comments (# to end of line), and evaluate
+// all \xxx sequences and use \ at the end of line to remove the newline.
+// A word is any one of:
+//	a continuous string of non-space chars except { and } and #
+//	everything between matching {...} (unless wantbrace != 0)
+//	the characters '{' and '}'
+
+static char *buffer;
+static int buflen;
+static void expand_buffer(int length) {
+  if (length >= buflen) {
+    if (!buflen) {
+      buflen = length+1;
+      buffer = (char*)malloc(buflen);
+    } else {
+      buflen = 2*buflen;
+      if (length >= buflen) buflen = length+1;
+      buffer = (char *)realloc((void *)buffer,buflen);
+    }
+  }
+}
+
+const char *read_word(int wantbrace) {
+  int x;
+
+  // skip all the whitespace before it:
+  for (;;) {
+    x = getc(fin);
+    if (x < 0) {	// eof
+      return 0;
+    } else if (x == '#') {	// comment
+      do x = getc(fin); while (x >= 0 && x != '\n');
+      lineno++;
+      continue;
+    } else if (x == '\n') {
+      lineno++;
+    } else if (!isspace(x)) {
+      break;
+    }
+  }
+
+  expand_buffer(100);
+
+  if (x == '{' && !wantbrace) {
+
+    // read in whatever is between braces
+    int length = 0;
+    int nesting = 0;
+    for (;;) {
+      x = getc(fin);
+      if (x<0) {read_error("Missing '}'"); break;}
+      else if (x == '#') { // embedded comment
+	do x = getc(fin); while (x >= 0 && x != '\n');
+	lineno++;
+	continue;
+      } else if (x == '\n') lineno++;
+      else if (x == '\\') {x = read_quoted(); if (x<0) continue;}
+      else if (x == '{') nesting++;
+      else if (x == '}') {if (!nesting--) break;}
+      buffer[length++] = x;
+      expand_buffer(length);
+    }
+    buffer[length] = 0;
+    return buffer;
+
+  } else if (x == '{' || x == '}') {
+    // all the punctuation is a word:
+    buffer[0] = x;
+    buffer[1] = 0;
+    return buffer;
+
+  } else {
+
+    // read in an unquoted word:
+    int length = 0;
+    for (;;) {
+      if (x == '\\') {x = read_quoted(); if (x<0) continue;}
+      else if (x<0 || isspace(x) || x=='{' || x=='}' || x=='#') break;
+      buffer[length++] = x;
+      expand_buffer(length);
+      x = getc(fin);
+    }
+    ungetc(x, fin);
+    buffer[length] = 0;
+    return buffer;
+
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl.H>
+#include "Fl_Widget_Type.h"
+
+// global int variables:
+extern int i18n_type;
+extern const char* i18n_include;
+extern const char* i18n_function;
+extern const char* i18n_file;
+extern const char* i18n_set;
+
+
+extern int header_file_set;
+extern int code_file_set;
+extern const char* header_file_name;
+extern const char* code_file_name;
+
+int write_file(const char *filename, int selected_only) {
+  if (!open_write(filename)) return 0;
+  write_string("# data file for the Fltk User Interface Designer (fluid)\n"
+	       "version %.4f",FL_VERSION);
+  if(!include_H_from_C)
+    write_string("\ndo_not_include_H_from_C");
+  if (i18n_type) {
+    write_string("\ni18n_type %d", i18n_type);
+    write_string("\ni18n_include %s", i18n_include);
+    switch (i18n_type) {
+    case 1 : /* GNU gettext */
+	write_string("\ni18n_function %s", i18n_function);
+        break;
+    case 2 : /* POSIX catgets */
+        if (i18n_file[0]) write_string("\ni18n_file %s", i18n_file);
+	write_string("\ni18n_set %s", i18n_set);
+        break;
+    }
+  }
+  if (!selected_only) {
+    write_string("\nheader_name"); write_word(header_file_name);
+    write_string("\ncode_name"); write_word(code_file_name);
+  }
+  for (Fl_Type *p = Fl_Type::first; p;) {
+    if (!selected_only || p->selected) {
+      p->write();
+      write_string("\n");
+      int q = p->level;
+      for (p = p->next; p && p->level > q; p = p->next);
+    } else {
+      p = p->next;
+    }
+  }
+  return close_write();
+}
+
+////////////////////////////////////////////////////////////////
+// read all the objects out of the input file:
+
+void read_fdesign();
+
+double read_version;
+
+extern Fl_Type *Fl_Type_make(const char *tn);
+
+static void read_children(Fl_Type *p, int paste) {
+  Fl_Type::current = p;
+  for (;;) {
+    const char *c = read_word();
+  REUSE_C:
+    if (!c) {
+      if (p && !paste) read_error("Missing '}'");
+      break;
+    }
+
+    if (!strcmp(c,"}")) {
+      if (!p) read_error("Unexpected '}'");
+      break;
+    }
+
+    // this is the first word in a .fd file:
+    if (!strcmp(c,"Magic:")) {
+      read_fdesign();
+      return;
+    }
+
+    if (!strcmp(c,"version")) {
+      c = read_word();
+      read_version = strtod(c,0);
+      if (read_version<=0 || read_version>FL_VERSION)
+	read_error("unknown version '%s'",c);
+      continue;
+    }
+
+    // back compatability with Vincent Penne's original class code:
+    if (!p && !strcmp(c,"define_in_struct")) {
+      Fl_Type *t = Fl_Type_make("class");
+      t->name(read_word());
+      Fl_Type::current = p = t;
+      paste = 1; // stops "missing }" error
+      continue;
+    }
+
+    if (!strcmp(c,"do_not_include_H_from_C")) {
+      include_H_from_C=0;
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"i18n_type")) {
+      i18n_type = atoi(read_word());
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"i18n_function")) {
+      i18n_function = strdup(read_word());
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"i18n_file")) {
+      i18n_file = strdup(read_word());
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"i18n_set")) {
+      i18n_set = strdup(read_word());
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"i18n_include")) {
+      i18n_include = strdup(read_word());
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"i18n_type"))
+    {
+      i18n_type = atoi(read_word());
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"i18n_type"))
+    {
+      i18n_type = atoi(read_word());
+      goto CONTINUE;
+    }
+    if (!strcmp(c,"header_name")) {
+      if (!header_file_set) header_file_name = strdup(read_word());
+      else read_word();
+      goto CONTINUE;
+    }
+
+    if (!strcmp(c,"code_name")) {
+      if (!code_file_set) code_file_name = strdup(read_word());
+      else read_word();
+      goto CONTINUE;
+    }
+
+    if (!strcmp(c, "snap") || !strcmp(c, "gridx") || !strcmp(c, "gridy")) {
+      // grid settings are now global
+      read_word();
+      goto CONTINUE;
+    }
+
+    {Fl_Type *t = Fl_Type_make(c);
+    if (!t) {
+      read_error("Unknown word \"%s\"", c);
+      continue;
+    }
+    t->name(read_word());
+
+    c = read_word(1);
+    if (strcmp(c,"{") && t->is_class()) {   // <prefix> <name>
+      ((Fl_Class_Type*)t)->prefix(t->name());
+      t->name(c);
+      c = read_word(1);
+    }
+
+    if (strcmp(c,"{")) {
+      read_error("Missing property list for %s\n",t->title());
+      goto REUSE_C;
+    }
+
+    t->open_ = 0;
+    for (;;) {
+      const char *cc = read_word();
+      if (!cc || !strcmp(cc,"}")) break;
+      t->read_property(cc);
+    }
+
+    if (!t->is_parent()) continue;
+    c = read_word(1);
+    if (strcmp(c,"{")) {
+      read_error("Missing child list for %s\n",t->title());
+      goto REUSE_C;
+    }
+    read_children(t, 0);}
+    Fl_Type::current = p;
+  CONTINUE:;
+  }
+}
+
+extern void deselect();
+
+int read_file(const char *filename, int merge) {
+  Fl_Type *o;
+  read_version = 0.0;
+  if (!open_read(filename)) return 0;
+  if (merge) deselect(); else    delete_all();
+  read_children(Fl_Type::current, merge);
+  Fl_Type::current = 0;
+  // Force menu items to be rebuilt...
+  for (o = Fl_Type::first; o; o = o->next)
+    if (o->is_menu_button()) o->add_child(0,0);
+  for (o = Fl_Type::first; o; o = o->next)
+    if (o->selected) {Fl_Type::current = o; break;}
+  return close_read();
+}
+
+////////////////////////////////////////////////////////////////
+// Read Forms and XForms fdesign files:
+
+int read_fdesign_line(const char*& name, const char*& value) {
+
+  int length = 0;
+  int x;
+  // find a colon:
+  for (;;) {
+    x = getc(fin);
+    if (x < 0) return 0;
+    if (x == '\n') {length = 0; continue;} // no colon this line...
+    if (!isspace(x)) {
+      buffer[length++] = x;
+      expand_buffer(length);
+    }
+    if (x == ':') break;
+  }
+  int valueoffset = length;
+  buffer[length-1] = 0;
+
+  // skip to start of value:
+  for (;;) {
+    x = getc(fin);
+    if (x < 0 || x == '\n' || !isspace(x)) break;
+  }
+
+  // read the value:
+  for (;;) {
+    if (x == '\\') {x = read_quoted(); if (x<0) continue;}
+    else if (x == '\n') break;
+    buffer[length++] = x;
+    expand_buffer(length);
+    x = getc(fin);
+  }
+  buffer[length] = 0;
+  name = buffer;
+  value = buffer+valueoffset;
+  return 1;
+}
+
+int fdesign_flip;
+int fdesign_magic;
+#include <FL/Fl_Group.H>
+
+static const char *class_matcher[] = {
+"FL_CHECKBUTTON", "Fl_Check_Button",
+"FL_ROUNDBUTTON", "Fl_Round_Button",
+"FL_ROUND3DBUTTON", "Fl_Round_Button",
+"FL_LIGHTBUTTON", "Fl_Light_Button",
+"FL_FRAME", "Fl_Box",
+"FL_LABELFRAME", "Fl_Box",
+"FL_TEXT", "Fl_Box",
+"FL_VALSLIDER", "Fl_Value_Slider",
+"FL_MENU", "Fl_Menu_Button",
+"3", "FL_BITMAP",
+"1", "FL_BOX",
+"71","FL_BROWSER",
+"11","FL_BUTTON",
+"4", "FL_CHART",
+"42","FL_CHOICE",
+"61","FL_CLOCK",
+"25","FL_COUNTER",
+"22","FL_DIAL",
+"101","FL_FREE",
+"31","FL_INPUT",
+"12","Fl_Light_Button",
+"41","FL_MENU",
+"23","FL_POSITIONER",
+"13","Fl_Round_Button",
+"21","FL_SLIDER",
+"2", "FL_BOX", // was FL_TEXT
+"62","FL_TIMER",
+"24","Fl_Value_Slider",
+0};
+
+void read_fdesign() {
+  fdesign_magic = atoi(read_word());
+  fdesign_flip = (fdesign_magic < 13000);
+  Fl_Widget_Type *window = 0;
+  Fl_Widget_Type *group = 0;
+  Fl_Widget_Type *widget = 0;
+  if (!Fl_Type::current) {
+    Fl_Type *t = Fl_Type_make("Function");
+    t->name("create_the_forms()");
+    Fl_Type::current = t;
+  }
+  for (;;) {
+    const char *name;
+    const char *value;
+    if (!read_fdesign_line(name, value)) break;
+
+    if (!strcmp(name,"Name")) {
+
+      window = (Fl_Widget_Type*)Fl_Type_make("Fl_Window");
+      window->name(value);
+      window->label(value);
+      Fl_Type::current = widget = window;
+
+    } else if (!strcmp(name,"class")) {
+
+      if (!strcmp(value,"FL_BEGIN_GROUP")) {
+	group = widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Group");
+	Fl_Type::current = group;
+      } else if (!strcmp(value,"FL_END_GROUP")) {
+	if (group) {
+	  Fl_Group* g = (Fl_Group*)(group->o);
+	  g->begin();
+	  g->forms_end();
+	  Fl_Group::current(0);
+	}
+	group = widget = 0;
+	Fl_Type::current = window;
+      } else {
+	for (int i = 0; class_matcher[i]; i += 2)
+	  if (!strcmp(value,class_matcher[i])) {
+	    value = class_matcher[i+1]; break;}
+	widget = (Fl_Widget_Type*)Fl_Type_make(value);
+	if (!widget) {
+	  printf("class %s not found, using Fl_Button\n", value);
+	  widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Button");
+	}
+      }
+
+    } else if (widget) {
+      if (!widget->read_fdesign(name, value))
+	printf("Ignoring \"%s: %s\"\n", name, value);
+    }
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/fluid.app/Contents/Info.plist b/Utilities/FLTK/fluid/fluid.app/Contents/Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..73bbfd65741ce4bc4b5bb85b73b1209f60cac992
--- /dev/null
+++ b/Utilities/FLTK/fluid/fluid.app/Contents/Info.plist
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plist version="0.9">
+    <dict>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+
+	<key>CFBundleExecutable</key>
+	<string>fluid</string>
+
+	<key>CFBundleIdentifier</key>
+	<string>org.fltk.fluid</string>
+
+	<key>CFBundleVersion</key>
+	<string>1.1.7</string>
+
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright 1998-2006 by Bill Spitzak and others</string>
+
+	<key>CFAppleHelpAnchor</key>
+	<string>help</string>
+
+	<key>CFBundleName</key>
+	<string>FLUID</string>
+
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+
+	<key>CFBundleSignature</key>
+	<string>FLID</string>
+
+	<key>CFBundleIconFile</key>
+	<string>fluid.icns</string>
+
+	<key>CFBundleShortVersionString</key>
+	<string>1.1.7</string>
+
+	<key>CFBundleGetInfoString</key>
+	<string>1.1.7, Copyright 1998-2006 by Bill Spitzak and others</string>
+
+	<key>CFBundleDocumentTypes</key>
+	<array>
+            <dict>
+        	<key>CFBundleTypeExtensions</key>
+        	<array>
+                    <string>fl</string>
+        	</array>
+
+        	<key>CFBundleTypeIconFile</key>
+        	<string>fluid.icns</string>
+
+        	<key>CFBundleTypeName</key>
+        	<string>FLUID Designer File</string>
+
+        	<key>CFBundleTypeOSTypes</key>
+        	<array>
+                    <string>Flid</string>
+        	</array>
+
+        	<key>CFBundleTypeRole</key>
+        	<string>Editor</string>
+            </dict>
+	</array>
+
+    </dict>
+</plist>
diff --git a/Utilities/FLTK/fluid/fluid.app/Contents/PkgInfo b/Utilities/FLTK/fluid/fluid.app/Contents/PkgInfo
new file mode 100644
index 0000000000000000000000000000000000000000..c5f93635ddf84a9eca07713f11fd76d6955c656f
--- /dev/null
+++ b/Utilities/FLTK/fluid/fluid.app/Contents/PkgInfo
@@ -0,0 +1 @@
+FLIDFlid
diff --git a/Utilities/FLTK/fluid/fluid.app/Contents/Resources/fluid.icns b/Utilities/FLTK/fluid/fluid.app/Contents/Resources/fluid.icns
new file mode 100644
index 0000000000000000000000000000000000000000..0fda05512058483e39f5ef110b8b3bdd5398247a
Binary files /dev/null and b/Utilities/FLTK/fluid/fluid.app/Contents/Resources/fluid.icns differ
diff --git a/Utilities/FLTK/fluid/fluid.cxx b/Utilities/FLTK/fluid/fluid.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..49e287f5a2c0f6f7b2527892cecadf0d69fc126e
--- /dev/null
+++ b/Utilities/FLTK/fluid/fluid.cxx
@@ -0,0 +1,2240 @@
+//
+// "$Id$"
+//
+// FLUID main entry for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_File_Icon.H>
+#include <FL/Fl_Help_Dialog.H>
+#include <FL/Fl_Hold_Browser.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_ask.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_File_Chooser.H>
+#include <FL/fl_message.H>
+#include <FL/filename.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <time.h> // time(), localtime(), etc.
+
+#include "../src/flstring.h"
+#include "alignment_panel.h"
+#include "function_panel.h"
+#include "template_panel.h"
+#if !defined(WIN32) || defined(__CYGWIN__)
+#  include "print_panel.cxx"
+#endif // !WIN32 || __CYGWIN__
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  include <direct.h>
+#  include <windows.h>
+#  include <io.h>
+#  include <commdlg.h>
+#  include <FL/x.H>
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define access _access
+#  define chdir _chdir
+#  define getcwd _getcwd
+#else
+#  include <unistd.h>
+#endif
+#ifdef __EMX__
+#  include <X11/Xlibint.h>
+#endif
+
+#include "about_panel.h"
+#include "undo.h"
+
+#include "Fl_Type.h"
+
+extern "C"
+{
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+#  include <zlib.h>
+#  ifdef HAVE_PNG_H
+#    include <png.h>
+#  else
+#    include <libpng/png.h>
+#  endif // HAVE_PNG_H
+#endif // HAVE_LIBPNG && HAVE_LIBZ
+}
+
+static Fl_Help_Dialog *help_dialog = 0;
+
+Fl_Preferences	fluid_prefs(Fl_Preferences::USER, "fltk.org", "fluid");
+int gridx = 5;
+int gridy = 5;
+int snap = 1;
+int show_guides = 1;
+
+// File history info...
+char	absolute_history[10][1024];
+char	relative_history[10][1024];
+
+void	load_history();
+void	update_history(const char *);
+
+// Shell command support...
+void	show_shell_window();
+
+////////////////////////////////////////////////////////////////
+
+static const char *filename;
+void set_filename(const char *c);
+void set_modflag(int mf);
+int modflag;
+
+static char* pwd;
+static char in_source_dir;
+void goto_source_dir() {
+  if (in_source_dir) return;
+  if (!filename || !*filename) return;
+  const char *p = fl_filename_name(filename);
+  if (p <= filename) return; // it is in the current directory
+  char buffer[1024];
+  strlcpy(buffer, filename, sizeof(buffer));
+  int n = p-filename; if (n>1) n--; buffer[n] = 0;
+  if (!pwd) {
+    pwd = getcwd(0,1024);
+    if (!pwd) {fprintf(stderr,"getwd : %s\n",strerror(errno)); return;}
+  }
+  if (chdir(buffer)<0) {fprintf(stderr, "Can't chdir to %s : %s\n",
+				buffer, strerror(errno)); return;}
+  in_source_dir = 1;
+}
+
+void leave_source_dir() {
+  if (!in_source_dir) return;
+  if (chdir(pwd)<0) {fprintf(stderr, "Can't chdir to %s : %s\n",
+			     pwd, strerror(errno));}
+  in_source_dir = 0;
+}
+  
+char position_window(Fl_Window *w, const char *prefsName, int Visible, int X, int Y, int W=0, int H=0 ) {
+  Fl_Preferences pos(fluid_prefs, prefsName);
+  if (prevpos_button->value()) {
+    pos.get("x", X, X);
+    pos.get("y", Y, Y);
+    if ( W!=0 ) {
+      pos.get("w", W, W);
+      pos.get("h", H, H);
+      w->resize( X, Y, W, H );
+    }
+    else
+      w->position( X, Y );
+  }
+  pos.get("visible", Visible, Visible);
+  return Visible;
+}
+
+void save_position(Fl_Window *w, const char *prefsName) {
+  Fl_Preferences pos(fluid_prefs, prefsName);
+  pos.set("x", w->x());
+  pos.set("y", w->y());
+  pos.set("w", w->w());
+  pos.set("h", w->h());
+  pos.set("visible", (int)(w->shown() && w->visible()));
+}
+
+Fl_Window *main_window;
+Fl_Menu_Bar *main_menubar;
+
+static char* cutfname(int which = 0) {
+  static char name[2][1024];
+  static char beenhere = 0;
+
+  if (!beenhere) {
+    beenhere = 1;
+    fluid_prefs.getUserdataPath(name[0], sizeof(name[0]));
+    strlcat(name[0], "cut_buffer", sizeof(name[0]));
+    fluid_prefs.getUserdataPath(name[1], sizeof(name[1]));
+    strlcat(name[1], "dup_buffer", sizeof(name[1]));
+  }
+
+  return name[which];
+}
+
+void save_cb(Fl_Widget *, void *v) {
+  const char *c = filename;
+  if (v || !c || !*c) {
+    fl_file_chooser_ok_label("Save");
+    c=fl_file_chooser("Save To:", "FLUID Files (*.f[ld])", c);
+    fl_file_chooser_ok_label(NULL);
+    if (!c) return;
+
+    if (!access(c, 0)) {
+      const char *basename;
+      if ((basename = strrchr(c, '/')) != NULL)
+        basename ++;
+#if defined(WIN32) || defined(__EMX__)
+      if ((basename = strrchr(c, '\\')) != NULL)
+        basename ++;
+#endif // WIN32 || __EMX__
+      else
+        basename = c;
+
+      if (fl_choice("The file \"%s\" already exists.\n"
+                    "Do you want to replace it?", "Cancel",
+		    "Replace", NULL, basename) == 0) return;
+    }
+
+    if (v != (void *)2) set_filename(c);
+  }
+  if (!write_file(c)) {
+    fl_alert("Error writing %s: %s", c, strerror(errno));
+    return;
+  }
+
+  if (v != (void *)2) {
+    set_modflag(0);
+    undo_save = undo_current;
+  }
+}
+
+void save_template_cb(Fl_Widget *, void *) {
+  // Setup the template panel...
+  if (!template_panel) make_template_panel();
+
+  template_clear();
+  template_browser->add("New Template");
+  template_load();
+
+  template_name->show();
+  template_name->value("");
+
+  template_instance->hide();
+
+  template_delete->show();
+  template_delete->deactivate();
+
+  template_submit->label("Save");
+  template_submit->deactivate();
+
+  template_panel->label("Save Template");
+
+  // Show the panel and wait for the user to do something...
+  template_panel->show();
+  while (template_panel->shown()) Fl::wait();
+
+  // Get the template name, return if it is empty...
+  const char *c = template_name->value();
+  if (!c || !*c) return;
+
+  // Convert template name to filename_with_underscores
+  char safename[1024], *safeptr;
+  strlcpy(safename, c, sizeof(safename));
+  for (safeptr = safename; *safeptr; safeptr ++) {
+    if (isspace(*safeptr)) *safeptr = '_';
+  }
+
+  // Find the templates directory...
+  char filename[1024];
+  fluid_prefs.getUserdataPath(filename, sizeof(filename));
+
+  strlcat(filename, "templates", sizeof(filename));
+#if defined(WIN32) && !defined(__CYGWIN__)
+  if (access(filename, 0)) mkdir(filename);
+#else
+  if (access(filename, 0)) mkdir(filename, 0777);
+#endif // WIN32 && !__CYGWIN__
+
+  strlcat(filename, "/", sizeof(filename));
+  strlcat(filename, safename, sizeof(filename));
+
+  char *ext = filename + strlen(filename);
+  if (ext >= (filename + sizeof(filename) - 5)) {
+    fl_alert("The template name \"%s\" is too long!", c);
+    return;
+  }
+
+  // Save the .fl file...
+  strcpy(ext, ".fl");
+
+  if (!access(filename, 0)) {
+    if (fl_choice("The template \"%s\" already exists.\n"
+                  "Do you want to replace it?", "Cancel",
+		  "Replace", NULL, c) == 0) return;
+  }
+
+  if (!write_file(filename)) {
+    fl_alert("Error writing %s: %s", filename, strerror(errno));
+    return;
+  }
+
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+  // Get the screenshot, if any...
+  Fl_Type *t;
+
+  for (t = Fl_Type::first; t; t = t->next) {
+    // Find the first window...
+    if (t->is_window()) break;
+  }
+
+  if (!t) return;
+
+  // Grab a screenshot...
+  Fl_Window_Type *wt = (Fl_Window_Type *)t;
+  uchar *pixels;
+  int w, h;
+
+  if ((pixels = wt->read_image(w, h)) == NULL) return;
+
+  // Save to a PNG file...
+  strcpy(ext, ".png");
+
+  FILE *fp;
+
+  if ((fp = fopen(filename, "wb")) == NULL) {
+    delete[] pixels;
+    fl_alert("Error writing %s: %s", filename, strerror(errno));
+    return;
+  }
+
+  png_structp pptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+  png_infop iptr = png_create_info_struct(pptr);
+  png_bytep ptr = (png_bytep)pixels;
+
+  png_init_io(pptr, fp);
+  png_set_IHDR(pptr, iptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
+               PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+  png_set_sRGB(pptr, iptr, PNG_sRGB_INTENT_PERCEPTUAL);
+
+  png_write_info(pptr, iptr);
+
+  for (int i = h; i > 0; i --, ptr += w * 3) {
+    png_write_row(pptr, ptr);
+  }
+
+  png_write_end(pptr, iptr);
+  png_destroy_write_struct(&pptr, &iptr);
+
+  fclose(fp);
+
+#  if 0 // The original PPM output code...
+  strcpy(ext, ".ppm");
+  fp = fopen(filename, "wb");
+  fprintf(fp, "P6\n%d %d 255\n", w, h);
+  fwrite(pixels, w * h, 3, fp);
+  fclose(fp);
+#  endif // 0
+
+  delete[] pixels;
+#endif // HAVE_LIBPNG && HAVE_LIBZ
+}
+
+void revert_cb(Fl_Widget *,void *) {
+  if (modflag) {
+    if (!fl_choice("This user interface has been changed. Really revert?",
+                   "Cancel", "Revert", NULL)) return;
+  }
+  undo_suspend();
+  if (!read_file(filename, 0)) {
+    undo_resume();
+    fl_message("Can't read %s: %s", filename, strerror(errno));
+    return;
+  }
+  undo_resume();
+  set_modflag(0);
+  undo_clear();
+}
+
+void exit_cb(Fl_Widget *,void *) {
+  if (modflag)
+    switch (fl_choice("Do you want to save changes to this user\n"
+                      "interface before exiting?", "Cancel",
+                      "Save", "Don't Save"))
+    {
+      case 0 : /* Cancel */
+          return;
+      case 1 : /* Save */
+          save_cb(NULL, NULL);
+	  if (modflag) return;	// Didn't save!
+    }
+
+  save_position(main_window,"main_window_pos");
+
+  if (widgetbin_panel) {
+    save_position(widgetbin_panel,"widgetbin_pos");
+    delete widgetbin_panel;
+  }
+  if (sourceview_panel) {
+    Fl_Preferences svp(fluid_prefs, "sourceview");
+    svp.set("autorefresh", sv_autorefresh->value());
+    svp.set("autoposition", sv_autoposition->value());
+    svp.set("tab", sv_tab->find(sv_tab->value()));
+    save_position(sourceview_panel,"sourceview_pos");
+    delete sourceview_panel;
+  }
+  if (about_panel)
+    delete about_panel;
+  if (help_dialog)
+    delete help_dialog;
+
+  undo_clear();
+
+  exit(0);
+}
+
+#ifdef __APPLE__
+#  include <FL/x.H>
+
+void
+apple_open_cb(const char *c) {
+  if (modflag) {
+    switch (fl_choice("Do you want to save changes to this user\n"
+                      "interface before opening another one?", "Don't Save",
+                      "Save", "Cancel"))
+    {
+      case 0 : /* Cancel */
+          return;
+      case 1 : /* Save */
+          save_cb(NULL, NULL);
+	  if (modflag) return;	// Didn't save!
+    }
+  }
+  const char *oldfilename;
+  oldfilename = filename;
+  filename    = NULL;
+  set_filename(c);
+  undo_suspend();
+  if (!read_file(c, 0)) {
+    undo_resume();
+    fl_message("Can't read %s: %s", c, strerror(errno));
+    free((void *)filename);
+    filename = oldfilename;
+    if (main_window) main_window->label(filename);
+    return;
+  }
+
+  // Loaded a file; free the old filename...
+  set_modflag(0);
+  undo_resume();
+  undo_clear();
+  if (oldfilename) free((void *)oldfilename);
+}
+#endif // __APPLE__
+
+void open_cb(Fl_Widget *, void *v) {
+  if (!v && modflag) {
+    switch (fl_choice("Do you want to save changes to this user\n"
+                      "interface before opening another one?", "Cancel",
+                      "Save", "Don't Save"))
+    {
+      case 0 : /* Cancel */
+          return;
+      case 1 : /* Save */
+          save_cb(NULL, NULL);
+	  if (modflag) return;	// Didn't save!
+    }
+  }
+  const char *c;
+  const char *oldfilename;
+  fl_file_chooser_ok_label("Open");
+  c = fl_file_chooser("Open:", "FLUID Files (*.f[ld])", filename);
+  fl_file_chooser_ok_label(NULL);
+  if (!c) return;
+  oldfilename = filename;
+  filename    = NULL;
+  set_filename(c);
+  if (v != 0) undo_checkpoint();
+  undo_suspend();
+  if (!read_file(c, v!=0)) {
+    undo_resume();
+    fl_message("Can't read %s: %s", c, strerror(errno));
+    free((void *)filename);
+    filename = oldfilename;
+    if (main_window) set_modflag(modflag);
+    return;
+  }
+  undo_resume();
+  if (v) {
+    // Inserting a file; restore the original filename...
+    free((void *)filename);
+    filename = oldfilename;
+    set_modflag(1);
+  } else {
+    // Loaded a file; free the old filename...
+    set_modflag(0);
+    undo_clear();
+    if (oldfilename) free((void *)oldfilename);
+  }
+}
+
+void open_history_cb(Fl_Widget *, void *v) {
+  if (modflag) {
+    switch (fl_choice("Do you want to save changes to this user\n"
+                      "interface before opening another one?", "Cancel",
+                      "Save", "Don't Save"))
+    {
+      case 0 : /* Cancel */
+          return;
+      case 1 : /* Save */
+          save_cb(NULL, NULL);
+	  if (modflag) return;	// Didn't save!
+    }
+  }
+  const char *oldfilename = filename;
+  filename = NULL;
+  set_filename((char *)v);
+  undo_suspend();
+  if (!read_file(filename, 0)) {
+    undo_resume();
+    undo_clear();
+    fl_message("Can't read %s: %s", filename, strerror(errno));
+    free((void *)filename);
+    filename = oldfilename;
+    if (main_window) main_window->label(filename);
+    return;
+  }
+  set_modflag(0);
+  undo_resume();
+  undo_clear();
+  if (oldfilename) free((void *)oldfilename);
+}
+
+void new_cb(Fl_Widget *, void *v) {
+  // Check if the current file has been modified...
+  if (!v && modflag) {
+    // Yes, ask the user what to do...
+    switch (fl_choice("Do you want to save changes to this user\n"
+                      "interface before creating a new one?", "Cancel",
+                      "Save", "Don't Save"))
+    {
+      case 0 : /* Cancel */
+          return;
+      case 1 : /* Save */
+          save_cb(NULL, NULL);
+	  if (modflag) return;	// Didn't save!
+    }
+  }
+
+  // Setup the template panel...
+  if (!template_panel) make_template_panel();
+
+  template_clear();
+  template_browser->add("Blank");
+  template_load();
+
+  template_name->hide();
+  template_name->value("");
+
+  template_instance->show();
+  template_instance->deactivate();
+  template_instance->value("");
+
+  template_delete->hide();
+
+  template_submit->label("New");
+  template_submit->deactivate();
+
+  template_panel->label("New");
+
+  // Show the panel and wait for the user to do something...
+  template_panel->show();
+  while (template_panel->shown()) Fl::wait();
+
+  // See if the user chose anything...
+  int item = template_browser->value();
+  if (item < 1) return;
+
+  // Clear the current data...
+  delete_all();
+  set_filename(NULL);
+
+  // Load the template, if any...
+  const char *tname = (const char *)template_browser->data(item);
+
+  if (tname) {
+    // Grab the instance name...
+    const char *iname = template_instance->value();
+
+    if (iname && *iname) {
+      // Copy the template to a temp file, then read it in...
+      char line[1024], *ptr, *next;
+      FILE *infile, *outfile;
+
+      if ((infile = fopen(tname, "r")) == NULL) {
+	fl_alert("Error reading template file \"%s\":\n%s", tname,
+        	 strerror(errno));
+	set_modflag(0);
+	undo_clear();
+	return;
+      }
+
+      if ((outfile = fopen(cutfname(1), "w")) == NULL) {
+	fl_alert("Error writing buffer file \"%s\":\n%s", cutfname(1),
+        	 strerror(errno));
+	fclose(infile);
+	set_modflag(0);
+	undo_clear();
+	return;
+      }
+
+      while (fgets(line, sizeof(line), infile)) {
+	// Replace @INSTANCE@ with the instance name...
+	for (ptr = line; (next = strstr(ptr, "@INSTANCE@")) != NULL; ptr = next + 10) {
+	  fwrite(ptr, next - ptr, 1, outfile);
+	  fputs(iname, outfile);
+	}
+
+	fputs(ptr, outfile);
+      }
+
+      fclose(infile);
+      fclose(outfile);
+
+      undo_suspend();
+      read_file(cutfname(1), 0);
+      unlink(cutfname(1));
+      undo_resume();
+    } else {
+      // No instance name, so read the template without replacements...
+      undo_suspend();
+      read_file(tname, 0);
+      undo_resume();
+    }
+  }
+
+  set_modflag(0);
+  undo_clear();
+}
+
+int compile_only = 0;
+int compile_strings = 0;
+int header_file_set = 0;
+int code_file_set = 0;
+const char* header_file_name = ".h";
+const char* code_file_name = ".cxx";
+int i18n_type = 0;
+const char* i18n_include = "";
+const char* i18n_function = "";
+const char* i18n_file = "";
+const char* i18n_set = "";
+char i18n_program[1024] = "";
+
+void write_cb(Fl_Widget *, void *) {
+  if (!filename) {
+    save_cb(0,0);
+    if (!filename) return;
+  }
+  char cname[1024];
+  char hname[1024];
+  strlcpy(i18n_program, fl_filename_name(filename), sizeof(i18n_program));
+  fl_filename_setext(i18n_program, sizeof(i18n_program), "");
+  if (*code_file_name == '.' && strchr(code_file_name, '/') == NULL) {
+    strlcpy(cname, fl_filename_name(filename), sizeof(cname));
+    fl_filename_setext(cname, sizeof(cname), code_file_name);
+  } else {
+    strlcpy(cname, code_file_name, sizeof(hname));
+  }
+  if (*header_file_name == '.' && strchr(header_file_name, '/') == NULL) {
+    strlcpy(hname, fl_filename_name(filename), sizeof(hname));
+    fl_filename_setext(hname, sizeof(hname), header_file_name);
+  } else {
+    strlcpy(hname, header_file_name, sizeof(hname));
+  }
+  if (!compile_only) goto_source_dir();
+  int x = write_code(cname,hname);
+  if (!compile_only) leave_source_dir();
+  strlcat(cname, " and ", sizeof(cname));
+  strlcat(cname, hname, sizeof(cname));
+  if (compile_only) {
+    if (!x) {fprintf(stderr,"%s : %s\n",cname,strerror(errno)); exit(1);}
+  } else {
+    if (!x) {
+      fl_message("Can't write %s: %s", cname, strerror(errno));
+    } else if (completion_button->value()) {
+      fl_message("Wrote %s", cname);
+    }
+  }
+}
+
+void write_strings_cb(Fl_Widget *, void *) {
+  static const char *exts[] = { ".txt", ".po", ".msg" };
+  if (!filename) {
+    save_cb(0,0);
+    if (!filename) return;
+  }
+  char sname[1024];
+  strlcpy(sname, fl_filename_name(filename), sizeof(sname));
+  fl_filename_setext(sname, sizeof(sname), exts[i18n_type]);
+  if (!compile_only) goto_source_dir();
+  int x = write_strings(sname);
+  if (!compile_only) leave_source_dir();
+  if (compile_only) {
+    if (x) {fprintf(stderr,"%s : %s\n",sname,strerror(errno)); exit(1);}
+  } else {
+    if (x) {
+      fl_message("Can't write %s: %s", sname, strerror(errno));
+    } else if (completion_button->value()) {
+      fl_message("Wrote %s", sname);
+    }
+  }
+}
+
+void openwidget_cb(Fl_Widget *, void *) {
+  if (!Fl_Type::current) {
+    fl_message("Please select a widget");
+    return;
+  }
+  Fl_Type::current->open();
+}
+
+void toggle_overlays(Fl_Widget *,void *);
+
+void select_all_cb(Fl_Widget *,void *);
+void select_none_cb(Fl_Widget *,void *);
+
+void group_cb(Fl_Widget *, void *);
+
+void ungroup_cb(Fl_Widget *, void *);
+
+extern int pasteoffset;
+static int ipasteoffset;
+
+void copy_cb(Fl_Widget*, void*) {
+  if (!Fl_Type::current) {
+    fl_beep();
+    return;
+  }
+  ipasteoffset = 10;
+  if (!write_file(cutfname(),1)) {
+    fl_message("Can't write %s: %s", cutfname(), strerror(errno));
+    return;
+  }
+}
+
+extern void select_only(Fl_Type *);
+void cut_cb(Fl_Widget *, void *) {
+  if (!Fl_Type::current) {
+    fl_beep();
+    return;
+  }
+  if (!write_file(cutfname(),1)) {
+    fl_message("Can't write %s: %s", cutfname(), strerror(errno));
+    return;
+  }
+  undo_checkpoint();
+  set_modflag(1);
+  ipasteoffset = 0;
+  Fl_Type *p = Fl_Type::current->parent;
+  while (p && p->selected) p = p->parent;
+  delete_all(1);
+  if (p) select_only(p);
+}
+
+void delete_cb(Fl_Widget *, void *) {
+  if (!Fl_Type::current) {
+    fl_beep();
+    return;
+  }
+  undo_checkpoint();
+  set_modflag(1);
+  ipasteoffset = 0;
+  Fl_Type *p = Fl_Type::current->parent;
+  while (p && p->selected) p = p->parent;
+  delete_all(1);
+  if (p) select_only(p);
+}
+
+extern int force_parent;
+
+void paste_cb(Fl_Widget*, void*) {
+  //if (ipasteoffset) force_parent = 1;
+  pasteoffset = ipasteoffset;
+  if (gridx>1) pasteoffset = ((pasteoffset-1)/gridx+1)*gridx;
+  if (gridy>1) pasteoffset = ((pasteoffset-1)/gridy+1)*gridy;
+  undo_checkpoint();
+  undo_suspend();
+  if (!read_file(cutfname(), 1)) {
+    fl_message("Can't read %s: %s", cutfname(), strerror(errno));
+  }
+  undo_resume();
+  pasteoffset = 0;
+  ipasteoffset += 10;
+  force_parent = 0;
+}
+
+// Duplicate the selected widgets...
+void duplicate_cb(Fl_Widget*, void*) {
+  if (!Fl_Type::current) {
+    fl_beep();
+    return;
+  }
+
+  if (!write_file(cutfname(1),1)) {
+    fl_message("Can't write %s: %s", cutfname(1), strerror(errno));
+    return;
+  }
+
+  pasteoffset  = 0;
+  force_parent = 1;
+
+  undo_checkpoint();
+  undo_suspend();
+  if (!read_file(cutfname(1), 1)) {
+    fl_message("Can't read %s: %s", cutfname(1), strerror(errno));
+  }
+  unlink(cutfname(1));
+  undo_resume();
+
+  force_parent = 0;
+}
+
+void earlier_cb(Fl_Widget*,void*);
+
+void later_cb(Fl_Widget*,void*);
+
+Fl_Type *sort(Fl_Type *parent);
+
+static void sort_cb(Fl_Widget *,void *) {
+  sort((Fl_Type*)0);
+}
+
+void show_project_cb(Fl_Widget *, void *);
+void show_grid_cb(Fl_Widget *, void *);
+void show_settings_cb(Fl_Widget *, void *);
+
+void align_widget_cb(Fl_Widget *, long);
+void widget_size_cb(Fl_Widget *, long);
+
+void about_cb(Fl_Widget *, void *) {
+  if (!about_panel) make_about_panel();
+  about_panel->show();
+}
+
+void show_help(const char *name) {
+  const char	*docdir;
+  char		helpname[1024];
+  
+  if (!help_dialog) help_dialog = new Fl_Help_Dialog();
+
+  if ((docdir = getenv("FLTK_DOCDIR")) == NULL) {
+#ifdef __EMX__
+    // Doesn't make sense to have a hardcoded fallback
+    static char fltk_docdir[1024];
+
+    strlcpy(fltk_docdir, __XOS2RedirRoot("/XFree86/lib/X11/fltk/doc"),
+            sizeof(fltk_docdir));
+
+    docdir = fltk_docdir;
+#else
+    docdir = FLTK_DOCDIR;
+#endif // __EMX__
+  }
+  snprintf(helpname, sizeof(helpname), "%s/%s", docdir, name);  
+
+  help_dialog->load(helpname);
+  help_dialog->show();
+}
+
+void help_cb(Fl_Widget *, void *) {
+  show_help("fluid.html");
+}
+
+void manual_cb(Fl_Widget *, void *) {
+  show_help("index.html");
+}
+
+
+////////////////////////////////////////////////////////////////
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+// Draw a shaded box...
+static void win_box(int x, int y, int w, int h) {
+  fl_color(0xc0, 0xc0, 0xc0);
+  fl_rectf(x, y, w, h);
+  fl_color(0, 0, 0);
+  fl_rect(x, y, w, h);
+  fl_color(0xf0, 0xf0, 0xf0);
+  fl_rectf(x + 1, y + 1, 4, h - 2);
+  fl_rectf(x + 1, y + 1, w - 2, 4);
+  fl_color(0x90, 0x90, 0x90);
+  fl_rectf(x + w - 5, y + 1, 4, h - 2);
+  fl_rectf(x + 1, y + h - 5, w - 2, 4);
+}
+
+// Load and show the print dialog...
+void print_menu_cb(Fl_Widget *, void *) {
+  PRINTDLG	dialog;			// Print dialog
+  DOCINFO	docinfo;		// Document info
+  int		first, last;		// First and last page
+  int		page;			// Current page
+  int		winpage;		// Current window page
+  int		num_pages;		// Number of pages
+  Fl_Type	*t;			// Current widget
+  int		num_windows;		// Number of windows
+  Fl_Window_Type *windows[1000];	// Windows to print
+
+
+  // Show print dialog...
+  for (t = Fl_Type::first, num_pages = 0; t; t = t->next) {
+    if (t->is_window()) num_pages ++;
+  }
+
+  memset(&dialog, 0, sizeof(dialog));
+  dialog.lStructSize = sizeof(dialog);
+  dialog.hwndOwner   = fl_xid(main_window);
+  dialog.Flags       = PD_ALLPAGES |
+                       PD_RETURNDC;
+  dialog.nFromPage   = 1;
+  dialog.nToPage     = num_pages;
+  dialog.nMinPage    = 1;
+  dialog.nMaxPage    = num_pages;
+  dialog.nCopies     = 1;
+
+  if (!PrintDlg(&dialog)) return;
+
+  // Get the base filename...
+  const char *basename = strrchr(filename, '/');
+  if (basename) basename ++;
+  else basename = filename;
+
+  // Do the print job...
+  memset(&docinfo, 0, sizeof(docinfo));
+  docinfo.cbSize      = sizeof(docinfo);
+  docinfo.lpszDocName = basename;
+
+  StartDoc(dialog.hDC, &docinfo);
+
+  // Figure out how many pages we'll have to print...
+  if (dialog.Flags & PD_PAGENUMS) {
+    // Get from and to page numbers...
+    first = dialog.nFromPage;
+    last  = dialog.nToPage;
+
+    if (first > last) {
+      // Swap first/last page
+      page  = first;
+      first = last;
+      last  = page;
+    }
+  } else {
+    // Print everything...
+    first = 1;
+    last  = dialog.nMaxPage;
+  }
+
+  for (t = Fl_Type::first, num_windows = 0, winpage = 0; t; t = t->next) {
+    if (t->is_window()) {
+      winpage ++;
+      windows[num_windows] = (Fl_Window_Type *)t;
+      num_windows ++;
+#if 0
+      if (dialog.Flags & PD_ALLPAGES) num_windows ++;
+      else if ((dialog.Flags & PD_PAGENUMS) && winpage >= first &&
+               winpage <= last) num_windows ++;
+      else if ((dialog.Flags & PD_SELECTION) && t->selected) num_windows ++;
+#endif // 0
+    }
+  }
+
+  num_pages = num_windows;
+
+  // Figure out the page size and margins...
+  int	width, length;			// Size of page
+  int   xdpi, ydpi;			// Output resolution
+  char	buffer[1024];
+
+  width  = GetDeviceCaps(dialog.hDC, HORZRES);
+  length = GetDeviceCaps(dialog.hDC, VERTRES);
+  xdpi   = GetDeviceCaps(dialog.hDC, LOGPIXELSX);
+  ydpi   = GetDeviceCaps(dialog.hDC, LOGPIXELSY);
+
+//  fl_message("width=%d, length=%d, xdpi=%d, ydpi=%d, num_windows=%d\n",
+//             width, length, xdpi, ydpi, num_windows);
+
+  HDC	save_dc = fl_gc;
+  HWND	save_win = fl_window;
+  int	fontsize = 14 * ydpi / 72;
+
+  fl_gc = dialog.hDC;
+  fl_window = (HWND)dialog.hDC;
+  fl_push_no_clip();
+
+  // Get the time and date...
+  time_t curtime = time(NULL);
+  struct tm *curdate = localtime(&curtime);
+  char date[1024];
+
+  strftime(date, sizeof(date), "%c", curdate);
+    
+  // Print each of the windows...
+  for (winpage = 0; winpage < num_windows; winpage ++) {
+    // Draw header...
+    StartPage(dialog.hDC);
+
+    fl_font(FL_HELVETICA_BOLD, fontsize);
+    fl_color(0, 0, 0);
+
+    fl_draw(basename, 0, fontsize);
+
+    fl_draw(date, (width - (int)fl_width(date)) / 2, fontsize);
+
+    sprintf(buffer, "%d/%d", winpage + 1, num_windows);
+    fl_draw(buffer, width - (int)fl_width(buffer), fontsize);
+
+    // Get window image...
+    uchar	*pixels;		// Window image data
+    int		w, h;			// Window image dimensions
+    int		ww, hh;			// Scaled size
+    int		ulx, uly;		// Upper-lefthand corner
+    Fl_Window	*win;			// Window widget
+    BITMAPINFO	info;			// Bitmap information
+
+    win    = (Fl_Window *)(windows[winpage]->o);
+    pixels = windows[winpage]->read_image(w, h);
+
+    // Figure out the window size, first at 100 PPI and then scaled
+    // down if that is too big...
+    ww = w * xdpi / 100;
+    hh = h * ydpi / 100;
+
+    if (ww > width) {
+      ww = width;
+      hh = h * ww * ydpi / xdpi / w;
+    }
+
+    if (hh > (length - ydpi / 2)) {
+      hh = length - ydpi / 2;
+      ww = w * hh / h;
+    }
+
+    // Position the window in the center...
+    ulx = (width - ww) / 2;
+    uly = (length - hh) / 2;
+
+//    fl_message("winpage=%d, ulx=%d, uly=%d, ww=%d, hh=%d",
+//               winpage, ulx, uly, ww, hh);
+
+    // Draw a simulated window border...
+    int xborder = 4 * ww / w;
+    int yborder = 4 * hh / h;
+
+    win_box(ulx - xborder, uly - 5 * yborder,
+            ww + 2 * xborder, hh + 6 * yborder);
+
+    fl_color(0, 0, 255);
+    fl_rectf(ulx, uly - 4 * yborder, ww, 4 * yborder);
+
+    fl_font(FL_HELVETICA_BOLD, 2 * yborder);
+    fl_color(255, 255, 255);
+    fl_draw(win->label() ? win->label() : "Window",
+            ulx + xborder, uly - 3 * yborder);
+
+    int x = ulx + ww - 4 * xborder;
+
+    win_box(x, uly - 4 * yborder, 4 * xborder, 4 * yborder);
+    fl_color(0, 0, 0);
+    fl_line(x + xborder, uly - yborder,
+            x + 3 * xborder, uly - 3 * yborder);
+    fl_line(x + xborder, uly - 3 * yborder,
+            x + 3 * xborder, uly - yborder);
+    x -= 4 * xborder;
+
+    if (win->resizable()) {
+      win_box(x, uly - 4 * yborder, 4 * xborder, 4 * yborder);
+      fl_color(0, 0, 0);
+      fl_rect(x + xborder, uly - 3 * yborder, 2 * xborder, 2 * yborder);
+      x -= 4 * xborder;
+    }
+
+    if (!win->modal()) {
+      win_box(x, uly - 4 * yborder, 4 * xborder, 4 * yborder);
+      fl_color(0, 0, 0);
+      fl_line(x + xborder, uly - yborder, x + 3 * xborder, uly - yborder);
+      x -= 4 * xborder;
+    }
+
+    // Color image...
+    memset(&info, 0, sizeof(info));
+    info.bmiHeader.biSize        = sizeof(info);
+    info.bmiHeader.biWidth       = w;
+    info.bmiHeader.biHeight      = 1;
+    info.bmiHeader.biPlanes      = 1;
+    info.bmiHeader.biBitCount    = 24;
+    info.bmiHeader.biCompression = BI_RGB;
+
+    for (int y = 0; y < h; y ++) {
+      StretchDIBits(dialog.hDC, ulx, uly + y * hh / h, ww, (hh + h - 1) / h, 0, 0, w, 1,
+                    pixels + y * w * 3, &info, DIB_RGB_COLORS, SRCCOPY);
+    }
+
+    delete[] pixels;
+
+    // Show the page...
+    EndPage(dialog.hDC);
+  }
+
+  // Finish up...
+  EndDoc(dialog.hDC);
+
+  fl_gc = save_dc;
+  fl_window = save_win;
+  fl_pop_clip();
+
+  // Free the print DC and return...
+  DeleteDC(dialog.hDC);
+}
+#else
+// Load and show the print dialog...
+void print_menu_cb(Fl_Widget *, void *) {
+  if (!print_panel) make_print_panel();
+
+  print_load();
+
+  print_selection->deactivate();
+
+  for (Fl_Type *t = Fl_Type::first; t; t = t->next) {
+    if (t->selected && t->is_window()) {
+      print_selection->activate();
+      break;
+    }
+  }
+
+  print_all->setonly();
+  print_all->do_callback();
+
+  print_panel->show();
+}
+
+// Quote a string for PostScript printing
+static const char *ps_string(const char *s) {
+  char *bufptr;
+  static char buffer[2048];
+
+
+  if (!s) {
+    buffer[0] = '\0';
+  } else {
+    for (bufptr = buffer; bufptr < (buffer + sizeof(buffer) - 3) && *s;) {
+      if (*s == '(' || *s == ')' || *s == '\\') *bufptr++ = '\\';
+      *bufptr++ = *s++;
+    }
+
+    *bufptr = '\0';
+  }
+
+  return (buffer);
+}
+
+// Actually print...
+void print_cb(Fl_Return_Button *, void *) {
+  FILE		*outfile;		// Output file or pipe to print command
+  char		command[1024];		// Print command
+  int		copies;			// Collated copies
+  int		first, last;		// First and last page
+  int		page;			// Current page
+  int		winpage;		// Current window page
+  int		num_pages;		// Number of pages
+  Fl_Type	*t;			// Current widget
+  int		num_windows;		// Number of windows
+  Fl_Window_Type *windows[1000];	// Windows to print
+
+  // Show progress, deactivate controls...
+  print_panel_controls->deactivate();
+  print_progress->show();
+
+  // Figure out how many pages we'll have to print...
+  if (print_collate_button->value()) copies = (int)print_copies->value();
+  else copies = 1;
+
+  if (print_pages->value()) {
+    // Get from and to page numbers...
+    if ((first = atoi(print_from->value())) < 1) first = 1;
+    if ((last = atoi(print_to->value())) < 1) last = 1000;
+
+    if (first > last) {
+      // Swap first/last page
+      page  = first;
+      first = last;
+      last  = page;
+    }
+  } else {
+    // Print everything...
+    first = 1;
+    last  = 1000;
+  }
+
+  for (t = Fl_Type::first, num_windows = 0, winpage = 0; t; t = t->next) {
+    if (t->is_window()) {
+      winpage ++;
+      windows[num_windows] = (Fl_Window_Type *)t;
+
+      if (print_all->value()) num_windows ++;
+      else if (print_pages->value() && winpage >= first &&
+               winpage <= last) num_windows ++;
+      else if (print_selection->value() && t->selected) num_windows ++;
+    }
+  }
+
+  num_pages = num_windows * copies;
+
+  print_progress->minimum(0);
+  print_progress->maximum(num_pages);
+  print_progress->value(0);
+  Fl::check();
+
+  // Get the base filename...
+  const char *basename = strrchr(filename, '/');
+  if (basename) basename ++;
+  else basename = filename;
+
+  // Open the print stream...
+  if (print_choice->value()) {
+    // Pipe the output into the lp command...
+    const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data();
+
+    snprintf(command, sizeof(command), "lp -s -d %s -n %.0f -t '%s' -o media=%s",
+             printer, print_collate_button->value() ? 1.0 : print_copies->value(),
+	     basename, print_page_size->text(print_page_size->value()));
+    outfile = popen(command, "w");
+  } else {
+    // Print to file...
+    fl_file_chooser_ok_label("Print");
+    const char *outname = fl_file_chooser("Print To", "PostScript (*.ps)", NULL, 1);
+    fl_file_chooser_ok_label(NULL);
+
+    if (outname && !access(outname, 0)) {
+      if (fl_choice("The file \"%s\" already exists.\n"
+                    "Do you want to replace it?", "Cancel",
+		    "Replace", NULL, outname) == 0) outname = NULL;
+    }
+
+    if (outname) outfile = fopen(outname, "w");
+    else outfile = NULL;
+  }
+
+  if (outfile) {
+    // Figure out the page size and margins...
+    int	width, length;			// Size of page
+    int	left, bottom,			// Bottom lefthand corner
+	right, top;			// Top righthand corner
+
+    if (print_page_size->value()) {
+      // A4
+      width  = 595;
+      length = 842;
+    } else {
+      // Letter
+      width  = 612;
+      length = 792;
+    }
+
+    int output_mode;
+    for (output_mode = 0; output_mode < 4; output_mode ++) {
+      if (print_output_mode[output_mode]->value()) break;
+    }
+
+    if (output_mode & 1) {
+      // Landscape
+      left   = 36;
+      bottom = 18;
+      right  = length - 36;
+      top    = width - 18;
+    } else {
+      // Portrait
+      left   = 18;
+      bottom = 36;
+      right  = width - 18;
+      top    = length - 36;
+    }
+
+    // Get the time and date...
+    time_t curtime = time(NULL);
+    struct tm *curdate = localtime(&curtime);
+    char date[1024];
+
+    strftime(date, sizeof(date), "%c", curdate);
+    
+    // Write the prolog...
+    fprintf(outfile,
+            "%%!PS-Adobe-3.0\n"
+	    "%%%%BoundingBox: 18 36 %d %d\n"
+	    "%%%%Pages: %d\n"
+	    "%%%%LanguageLevel: 1\n"
+	    "%%%%DocumentData: Clean7Bit\n"
+	    "%%%%DocumentNeededResources: font Helvetica-Bold\n"
+	    "%%%%Creator: FLUID %.4f\n"
+	    "%%%%CreationDate: %s\n"
+	    "%%%%Title: (%s)\n"
+	    "%%%%EndComments\n"
+	    "%%%%BeginProlog\n"
+	    "%%languagelevel 1 eq {\n"
+	    "  /rectfill {\n"
+	    "    newpath 4 2 roll moveto dup 0 exch rlineto exch 0 rlineto\n"
+	    "    neg 0 exch rlineto closepath fill\n"
+	    "  } bind def\n"
+	    "  /rectstroke {\n"
+	    "    newpath 4 2 roll moveto dup 0 exch rlineto exch 0 rlineto\n"
+	    "    neg 0 exch rlineto closepath stroke\n"
+	    "  } bind def\n"
+	    "%%} if\n"
+	    "%%%%EndProlog\n"
+	    "%%%%BeginSetup\n"
+	    "%%%%BeginFeature: *PageSize %s\n"
+	    "languagelevel 1 ne {\n"
+	    "  <</PageSize[%d %d]/ImagingBBox null>>setpagedevice\n"
+	    "} {\n"
+	    "  %s\n"
+	    "} ifelse\n"
+	    "%%%%EndFeature\n"
+	    "%%%%EndSetup\n",
+	    width - 18, length - 36,
+	    num_pages,
+	    FL_VERSION,
+	    date,
+	    basename,
+	    print_page_size->text(print_page_size->value()),
+	    width, length,
+	    print_page_size->value() ? "a4tray" : "lettertray");
+
+    // Print each of the windows...
+    char	progress[255];		// Progress text
+    int		copy;			// Current copy
+
+    for (copy = 0, page = 0; copy < copies; copy ++) {
+      for (winpage = 0; winpage < num_pages; winpage ++) {
+        // Start next page...
+        page ++;
+	sprintf(progress, "Printing page %d/%d...", page, num_pages);
+	print_progress->value(page);
+	print_progress->label(progress);
+	Fl::check();
+
+        // Add common page stuff...
+	fprintf(outfile,
+	        "%%%%Page: %d %d\n"
+		"gsave\n",
+		page, page);
+
+        if (output_mode & 1) {
+	  // Landscape...
+	  fprintf(outfile, "%d 0 translate 90 rotate\n", width);
+	}
+
+        // Draw header...
+	fprintf(outfile,
+		"0 setgray\n"
+		"/Helvetica-Bold findfont 14 scalefont setfont\n"
+		"%d %d moveto (%s) show\n"
+		"%.1f %d moveto (%s) dup stringwidth pop -0.5 mul 0 rmoveto show\n"
+		"%d %d moveto (%d/%d) dup stringwidth pop neg 0 rmoveto show\n",
+	        left, top - 15, ps_string(basename),
+		0.5 * (left + right), top - 15, date,
+		right, top - 15, winpage + 1, num_windows);
+
+        // Get window image...
+	uchar	*pixels;		// Window image data
+        int	w, h;			// Window image dimensions
+	float	ww, hh;			// Scaled size
+	float	border;			// Width of 1 pixel
+        float	llx, lly,		// Lower-lefthand corner
+		urx, ury;		// Upper-righthand corner
+	Fl_Window *win;			// Window widget
+
+        win    = (Fl_Window *)(windows[winpage]->o);
+	pixels = windows[winpage]->read_image(w, h);
+
+        // Figure out the window size, first at 100 PPI and then scaled
+	// down if that is too big...
+        ww = w * 72.0 / 100.0;
+	hh = h * 72.0 / 100.0;
+
+        if (ww > (right - left)) {
+	  ww = right - left;
+	  hh = h * ww / w;
+	}
+
+        if (hh > (top - bottom - 36)) {
+	  hh = top - bottom;
+	  ww = w * hh / h;
+	}
+
+        border = ww / w;
+
+	// Position the window in the center...
+	llx = 0.5 * (right - left - ww);
+	lly = 0.5 * (top - bottom - hh);
+	urx = 0.5 * (right - left + ww);
+	ury = 0.5 * (top - bottom + hh);
+
+        // Draw a simulated window border...
+        fprintf(outfile,
+	        "0.75 setgray\n"			// Gray background
+	        "newpath %.2f %.2f %.2f 180 90 arcn\n"	// Top left 
+		"%.2f %.2f %.2f 90 0 arcn\n"		// Top right
+		"%.2f %.2f %.2f 0 -90 arcn\n"		// Bottom right
+		"%.2f %.2f %.2f -90 -180 arcn\n"	// Bottom left
+		"closepath gsave fill grestore\n"	// Fill
+		"0 setlinewidth 0 setgray stroke\n",	// Outline
+		llx, ury + 12 * border, 4 * border,
+		urx, ury + 12 * border, 4 * border,
+		urx, lly, 4 * border,
+		llx, lly, 4 * border);
+
+        // Title bar...
+	if (output_mode & 2) {
+	  fputs("0.25 setgray\n", outfile);
+	} else {
+	  fputs("0.1 0.2 0.6 setrgbcolor\n", outfile);
+	}
+
+        fprintf(outfile, "%.2f %.2f %.2f %.2f rectfill\n",
+	        llx + 12 * border, ury,
+		ww - (24 + 16 * (!win->modal() || win->resizable()) +
+		      16 * (!win->modal() && win->resizable())) * border,
+		16 * border);
+
+        if (win->resizable()) {
+	  fprintf(outfile,
+		  "%.2f %.2f %.2f -90 -180 arcn\n"	// Bottom left
+	          "0 %.2f rlineto %.2f 0 rlineto 0 -%.2f rlineto closepath fill\n"
+		  "%.2f %.2f %.2f 0 -90 arcn\n"	// Bottom right
+	          "-%.2f 0 rlineto 0 %.2f rlineto %.2f 0 rlineto closepath fill\n",
+		  llx, lly, 4 * border,
+		  12 * border, 16 * border, 16 * border,
+		  urx, lly, 4 * border,
+		  12 * border, 16 * border, 16 * border);
+	}
+
+        // Inside outline and button shading...
+        fprintf(outfile,
+	        "%.2f setlinewidth 0.5 setgray\n"
+		"%.2f %.2f %.2f %.2f rectstroke\n"
+		"%.2f %.2f moveto 0 %.2f rlineto\n"
+		"%.2f %.2f moveto 0 %.2f rlineto\n",
+		border,
+		llx - 0.5 * border, lly - 0.5 * border, ww + border, hh + border,
+		llx + 12 * border, ury, 16 * border,
+		urx - 12 * border, ury, 16 * border);
+
+        if (!win->modal() || win->resizable()) {
+	  fprintf(outfile, "%.2f %.2f moveto 0 %.2f rlineto\n",
+	          urx - 28 * border, ury, 16 * border);
+	}
+
+        if (!win->modal() && win->resizable()) {
+	  fprintf(outfile, "%.2f %.2f moveto 0 %.2f rlineto\n",
+	          urx - 44 * border, ury, 16 * border);
+	}
+
+        fprintf(outfile, "%.2f %.2f moveto %.2f 0 rlineto stroke\n",
+		llx - 3.5 * border, ury + 0.5 * border, ww + 7 * border);
+
+        // Button icons...
+        fprintf(outfile,
+	        "%.2f setlinewidth 0 setgray\n"
+		"%.2f %.2f moveto %.2f -%.2f rlineto %.2f %.2f rlineto\n"
+		"%.2f %.2f moveto -%.2f -%.2f rlineto 0 %.2f rmoveto %.2f -%.2f rlineto\n",
+		2 * border,
+		llx, ury + 10 * border, 4 * border, 4 * border, 4 * border, 4 * border,
+		urx, ury + 12 * border, 8 * border, 8 * border, 8 * border, 8 * border, 8 * border);
+
+        float x = urx - 16 * border;
+
+        if (win->resizable()) {
+	  // Maximize button
+	  fprintf(outfile,
+	          "%.2f %.2f moveto -%.2f 0 rlineto 0 -%.2f rlineto "
+		  "%.2f 0 rlineto 0 %.2f rlineto\n",
+		  x, ury + 12 * border, 8 * border, 8 * border,
+		  8 * border, 8 * border);
+
+          x -= 16 * border;
+        }
+
+        if (!win->modal()) {
+	  // Minimize button
+	  fprintf(outfile,
+	          "%.2f %.2f moveto -%.2f 0 rlineto\n",
+		  x, ury + 4 * border, 8 * border);
+        }
+
+        fputs("stroke\n", outfile);
+
+        if (win->label()) {
+	  // Add window title...
+	  fprintf(outfile,
+		  "1 setgray\n"
+		  "/Helvetica-Bold findfont %.2f scalefont setfont\n"
+		  "(%s) %.2f %.2f moveto show\n",
+		  12 * border,
+		  ps_string(win->label()), llx + 16 * border, ury + 4 * border);
+	}
+
+        fprintf(outfile,
+	        "gsave\n"
+		"%.2f %.2f translate %.2f %.2f scale\n",
+		llx, ury - border, border, border);
+
+        if (output_mode & 2) {
+	  // Grayscale image...
+	  fprintf(outfile,
+	          "/imgdata %d string def\n"
+		  "%d %d 8[1 0 0 -1 0 1] "
+		  "{currentfile imgdata readhexstring pop} image\n",
+		  w,
+		  w, h);
+
+          uchar *ptr = pixels;
+	  int i, count = w * h;
+
+          for (i = 0; i < count; i ++, ptr += 3) {
+	    fprintf(outfile, "%02X",
+	            (31 * ptr[0] + 61 * ptr[1] + 8 * ptr[2]) / 100);
+	    if (!(i % 40)) putc('\n', outfile);
+	  }
+	} else {
+	  // Color image...
+	  fprintf(outfile,
+	          "/imgdata %d string def\n"
+		  "%d %d 8[1 0 0 -1 0 1] "
+		  "{currentfile imgdata readhexstring pop} false 3 colorimage\n",
+		  w * 3,
+		  w, h);
+
+          uchar *ptr = pixels;
+	  int i, count = w * h;
+
+          for (i = 0; i < count; i ++, ptr += 3) {
+	    fprintf(outfile, "%02X%02X%02X", ptr[0], ptr[1], ptr[2]);
+	    if (!(i % 13)) putc('\n', outfile);
+	  }
+	}
+
+        fputs("\ngrestore\n", outfile);
+
+        delete[] pixels;
+
+        // Show the page...
+	fputs("grestore showpage\n", outfile);
+      }
+    }
+
+    // Finish up...
+    fputs("%%EOF\n", outfile);
+
+    if (print_choice->value()) pclose(outfile);
+    else fclose(outfile);
+  } else {
+    // Unable to print...
+    fl_alert("Error printing: %s", strerror(errno));
+  }
+
+  // Hide progress, activate controls, hide print panel...
+  print_panel_controls->activate();
+  print_progress->hide();
+  print_panel->hide();
+}
+#endif // WIN32 && !__CYGWIN__
+
+////////////////////////////////////////////////////////////////
+
+extern Fl_Menu_Item New_Menu[];
+
+void toggle_widgetbin_cb(Fl_Widget *, void *);
+void toggle_sourceview_cb(Fl_Double_Window *, void *);
+
+Fl_Menu_Item Main_Menu[] = {
+{"&File",0,0,0,FL_SUBMENU},
+  {"&New...", FL_CTRL+'n', new_cb, 0},
+  {"&Open...", FL_CTRL+'o', open_cb, 0},
+  {"&Insert...", FL_CTRL+'i', open_cb, (void*)1, FL_MENU_DIVIDER},
+#define SAVE_ITEM 4
+  {"&Save", FL_CTRL+'s', save_cb, 0},
+  {"Save &As...", FL_CTRL+FL_SHIFT+'s', save_cb, (void*)1},
+  {"Sa&ve A Copy...", 0, save_cb, (void*)2},
+  {"Save &Template...", 0, save_template_cb},
+  {"&Revert...", 0, revert_cb, 0, FL_MENU_DIVIDER},
+  {"&Print...", FL_CTRL+'p', print_menu_cb},
+  {"Write &Code...", FL_CTRL+FL_SHIFT+'c', write_cb, 0},
+  {"&Write Strings...", FL_CTRL+FL_SHIFT+'w', write_strings_cb, 0, FL_MENU_DIVIDER},
+#define HISTORY_ITEM 12
+  {relative_history[0], FL_CTRL+'0', open_history_cb, absolute_history[0]},
+  {relative_history[1], FL_CTRL+'1', open_history_cb, absolute_history[1]},
+  {relative_history[2], FL_CTRL+'2', open_history_cb, absolute_history[2]},
+  {relative_history[3], FL_CTRL+'3', open_history_cb, absolute_history[3]},
+  {relative_history[4], FL_CTRL+'4', open_history_cb, absolute_history[4]},
+  {relative_history[5], FL_CTRL+'5', open_history_cb, absolute_history[5]},
+  {relative_history[6], FL_CTRL+'6', open_history_cb, absolute_history[6]},
+  {relative_history[7], FL_CTRL+'7', open_history_cb, absolute_history[7]},
+  {relative_history[8], FL_CTRL+'8', open_history_cb, absolute_history[8]},
+  {relative_history[9], FL_CTRL+'9', open_history_cb, absolute_history[9], FL_MENU_DIVIDER},
+  {"&Quit", FL_CTRL+'q', exit_cb},
+  {0},
+{"&Edit",0,0,0,FL_SUBMENU},
+  {"&Undo", FL_CTRL+'z', undo_cb},
+  {"&Redo", FL_CTRL+FL_SHIFT+'z', redo_cb, 0, FL_MENU_DIVIDER},
+  {"C&ut", FL_CTRL+'x', cut_cb},
+  {"&Copy", FL_CTRL+'c', copy_cb},
+  {"&Paste", FL_CTRL+'v', paste_cb},
+  {"Dup&licate", FL_CTRL+'u', duplicate_cb},
+  {"&Delete", FL_Delete, delete_cb, 0, FL_MENU_DIVIDER},
+  {"Select &All", FL_CTRL+'a', select_all_cb},
+  {"Select &None", FL_CTRL+FL_SHIFT+'a', select_none_cb, 0, FL_MENU_DIVIDER},
+  {"Pr&operties...", FL_F+1, openwidget_cb},
+  {"&Sort",0,sort_cb},
+  {"&Earlier", FL_F+2, earlier_cb},
+  {"&Later", FL_F+3, later_cb},
+  {"&Group", FL_F+7, group_cb},
+  {"Ung&roup", FL_F+8, ungroup_cb,0, FL_MENU_DIVIDER},
+  {"Hide O&verlays",FL_CTRL+FL_SHIFT+'o',toggle_overlays},
+#define WIDGETBIN_ITEM 41
+  {"Show Widget &Bin...",FL_ALT+'b',toggle_widgetbin_cb},
+#define SOURCEVIEW_ITEM 42
+  {"Show Source Code...",FL_ALT+FL_SHIFT+'s', (Fl_Callback*)toggle_sourceview_cb, 0, FL_MENU_DIVIDER},
+  {"Pro&ject Settings...",FL_ALT+'p',show_project_cb},
+  {"GU&I Settings...",FL_ALT+FL_SHIFT+'p',show_settings_cb},
+  {0},
+{"&New", 0, 0, (void *)New_Menu, FL_SUBMENU_POINTER},
+{"&Layout",0,0,0,FL_SUBMENU},
+  {"&Align",0,0,0,FL_SUBMENU},
+    {"&Left",0,(Fl_Callback *)align_widget_cb,(void*)10},
+    {"&Center",0,(Fl_Callback *)align_widget_cb,(void*)11},
+    {"&Right",0,(Fl_Callback *)align_widget_cb,(void*)12},
+    {"&Top",0,(Fl_Callback *)align_widget_cb,(void*)13},
+    {"&Middle",0,(Fl_Callback *)align_widget_cb,(void*)14},
+    {"&Bottom",0,(Fl_Callback *)align_widget_cb,(void*)15},
+    {0},
+  {"&Space Evenly",0,0,0,FL_SUBMENU},
+    {"&Across",0,(Fl_Callback *)align_widget_cb,(void*)20},
+    {"&Down",0,(Fl_Callback *)align_widget_cb,(void*)21},
+    {0},
+  {"&Make Same Size",0,0,0,FL_SUBMENU},
+    {"&Width",0,(Fl_Callback *)align_widget_cb,(void*)30},
+    {"&Height",0,(Fl_Callback *)align_widget_cb,(void*)31},
+    {"&Both",0,(Fl_Callback *)align_widget_cb,(void*)32},
+    {0},
+  {"&Center In Group",0,0,0,FL_SUBMENU},
+    {"&Horizontal",0,(Fl_Callback *)align_widget_cb,(void*)40},
+    {"&Vertical",0,(Fl_Callback *)align_widget_cb,(void*)41},
+    {0},
+  {"Set &Widget Size",0,0,0,FL_SUBMENU|FL_MENU_DIVIDER},
+    {"&Tiny",FL_ALT+'1',(Fl_Callback *)widget_size_cb,(void*)8,0,FL_NORMAL_LABEL,FL_HELVETICA,8},
+    {"&Small",FL_ALT+'2',(Fl_Callback *)widget_size_cb,(void*)11,0,FL_NORMAL_LABEL,FL_HELVETICA,11},
+    {"&Normal",FL_ALT+'3',(Fl_Callback *)widget_size_cb,(void*)14,0,FL_NORMAL_LABEL,FL_HELVETICA,14},
+    {"&Medium",FL_ALT+'4',(Fl_Callback *)widget_size_cb,(void*)18,0,FL_NORMAL_LABEL,FL_HELVETICA,18},
+    {"&Large",FL_ALT+'5',(Fl_Callback *)widget_size_cb,(void*)24,0,FL_NORMAL_LABEL,FL_HELVETICA,24},
+    {"&Huge",FL_ALT+'6',(Fl_Callback *)widget_size_cb,(void*)32,0,FL_NORMAL_LABEL,FL_HELVETICA,32},
+    {0},
+  {"&Grid and Size Settings...",FL_CTRL+'g',show_grid_cb},
+  {0},
+{"&Shell",0,0,0,FL_SUBMENU},
+  {"Execute &Command...",FL_ALT+'x',(Fl_Callback *)show_shell_window},
+  {"Execute &Again...",FL_ALT+'g',(Fl_Callback *)do_shell_command},
+  {0},
+{"&Help",0,0,0,FL_SUBMENU},
+  {"&About FLUID...",0,about_cb},
+  {"&On FLUID...",0,help_cb},
+  {"&Manual...",0,manual_cb},
+  {0},
+{0}};
+
+#define BROWSERWIDTH 300
+#define BROWSERHEIGHT 500
+#define WINWIDTH 300
+#define MENUHEIGHT 25
+#define WINHEIGHT (BROWSERHEIGHT+MENUHEIGHT)
+
+extern void fill_in_New_Menu();
+
+void scheme_cb(Fl_Choice *, void *) {
+  if (compile_only)
+    return;
+
+  switch (scheme_choice->value()) {
+    case 0 : // Default
+      Fl::scheme(NULL);
+      break;
+    case 1 : // None
+      Fl::scheme("none");
+      break;
+    case 2 : // Plastic
+      Fl::scheme("plastic");
+      break;
+  }
+
+  fluid_prefs.set("scheme", scheme_choice->value());
+}
+
+void toggle_widgetbin_cb(Fl_Widget *, void *) {
+  if (!widgetbin_panel) {
+    make_widgetbin();
+    widgetbin_panel->callback(toggle_widgetbin_cb);
+    if (!position_window(widgetbin_panel,"widgetbin_pos", 1, 320, 30)) return;
+  }
+
+  if (widgetbin_panel->visible()) {
+    widgetbin_panel->hide();
+    Main_Menu[WIDGETBIN_ITEM].label("Show Widget &Bin...");
+  } else {
+    widgetbin_panel->show();
+    Main_Menu[WIDGETBIN_ITEM].label("Hide Widget &Bin");
+  }
+}
+
+
+void toggle_sourceview_cb(Fl_Double_Window *, void *) {
+  if (!sourceview_panel) {
+    make_sourceview();
+    sourceview_panel->callback((Fl_Callback*)toggle_sourceview_cb);
+    Fl_Preferences svp(fluid_prefs, "sourceview");
+    int autorefresh;
+    svp.get("autorefresh", autorefresh, 1);
+    sv_autorefresh->value(autorefresh);
+    int autoposition;
+    svp.get("autoposition", autoposition, 1);
+    sv_autoposition->value(autoposition);
+    int tab;
+    svp.get("tab", tab, 0);
+    if (tab>=0 && tab<sv_tab->children()) sv_tab->value(sv_tab->child(tab));
+    if (!position_window(sourceview_panel,"sourceview_pos", 0, 320, 120, 550, 500)) return;
+  }
+
+  if (sourceview_panel->visible()) {
+    sourceview_panel->hide();
+    Main_Menu[SOURCEVIEW_ITEM].label("Show Source Code...");
+  } else {
+    sourceview_panel->show();
+    Main_Menu[SOURCEVIEW_ITEM].label("Hide Source Code...");
+    update_sourceview_cb(0,0);
+  }
+}
+
+void toggle_sourceview_b_cb(Fl_Button*, void *) {
+  toggle_sourceview_cb(0,0);
+}
+
+void make_main_window() {
+  fluid_prefs.get("snap", snap, 1);
+  fluid_prefs.get("gridx", gridx, 5);
+  fluid_prefs.get("gridy", gridy, 5);
+  fluid_prefs.get("show_guides", show_guides, 0);
+  fluid_prefs.get("widget_size", Fl_Widget_Type::default_size, 14);
+
+  load_history();
+
+  make_layout_window();
+  make_settings_window();
+  make_shell_window();
+
+  if (!main_window) {
+    Fl_Widget *o;
+    main_window = new Fl_Double_Window(WINWIDTH,WINHEIGHT,"fluid");
+    main_window->box(FL_NO_BOX);
+    o = make_widget_browser(0,MENUHEIGHT,BROWSERWIDTH,BROWSERHEIGHT);
+    o->box(FL_FLAT_BOX);
+    o->tooltip("Double-click to view or change an item.");
+    main_window->resizable(o);
+    main_menubar = new Fl_Menu_Bar(0,0,BROWSERWIDTH,MENUHEIGHT);
+    main_menubar->menu(Main_Menu);
+    main_menubar->global();
+    fill_in_New_Menu();
+    main_window->end();
+  }
+}
+
+// Load file history from preferences...
+void load_history() {
+  int	i;		// Looping var
+  int	max_files;
+
+
+  fluid_prefs.get("recent_files", max_files, 5);
+  if (max_files > 10) max_files = 10;
+
+  for (i = 0; i < max_files; i ++) {
+    fluid_prefs.get( Fl_Preferences::Name("file%d", i), absolute_history[i], "", sizeof(absolute_history[i]));
+    if (absolute_history[i][0]) {
+      // Make a relative version of the filename for the menu...
+      fl_filename_relative(relative_history[i], sizeof(relative_history[i]),
+                           absolute_history[i]);
+
+      if (i == 9) Main_Menu[i + HISTORY_ITEM].flags = FL_MENU_DIVIDER;
+      else Main_Menu[i + HISTORY_ITEM].flags = 0;
+    } else break;
+  }
+
+  for (; i < 10; i ++) {
+    if (i) Main_Menu[i + HISTORY_ITEM - 1].flags |= FL_MENU_DIVIDER;
+    Main_Menu[i + HISTORY_ITEM].hide();
+  }
+}
+
+// Update file history from preferences...
+void update_history(const char *flname) {
+  int	i;		// Looping var
+  char	absolute[1024];
+  int	max_files;
+
+
+  fluid_prefs.get("recent_files", max_files, 5);
+  if (max_files > 10) max_files = 10;
+
+  fl_filename_absolute(absolute, sizeof(absolute), flname);
+
+  for (i = 0; i < max_files; i ++)
+#if defined(WIN32) || defined(__APPLE__)
+    if (!strcasecmp(absolute, absolute_history[i])) break;
+#else
+    if (!strcmp(absolute, absolute_history[i])) break;
+#endif // WIN32 || __APPLE__
+
+  if (i == 0) return;
+
+  if (i >= max_files) i = max_files - 1;
+
+  // Move the other flnames down in the list...
+  memmove(absolute_history + 1, absolute_history,
+          i * sizeof(absolute_history[0]));
+  memmove(relative_history + 1, relative_history,
+          i * sizeof(relative_history[0]));
+
+  // Put the new file at the top...
+  strlcpy(absolute_history[0], absolute, sizeof(absolute_history[0]));
+
+  fl_filename_relative(relative_history[0], sizeof(relative_history[0]),
+                       absolute_history[0]);
+
+  // Update the menu items as needed...
+  for (i = 0; i < max_files; i ++) {
+    fluid_prefs.set( Fl_Preferences::Name("file%d", i), absolute_history[i]);
+    if (absolute_history[i][0]) {
+      if (i == 9) Main_Menu[i + HISTORY_ITEM].flags = FL_MENU_DIVIDER;
+      else Main_Menu[i + HISTORY_ITEM].flags = 0;
+    } else break;
+  }
+
+  for (; i < 10; i ++) {
+    fluid_prefs.set( Fl_Preferences::Name("file%d", i), "");
+    if (i) Main_Menu[i + HISTORY_ITEM - 1].flags |= FL_MENU_DIVIDER;
+    Main_Menu[i + HISTORY_ITEM].hide();
+  }
+}
+
+// Shell command support...
+#if (!defined(WIN32) || defined(__CYGWIN__)) && !defined(__MWERKS__)
+// Support the full piped shell command...
+static FILE *shell_pipe = 0;
+
+void
+shell_pipe_cb(int, void*) {
+  char	line[1024];		// Line from command output...
+
+  if (fgets(line, sizeof(line), shell_pipe) != NULL) {
+    // Add the line to the output list...
+    shell_run_buffer->append(line);
+  } else {
+    // End of file; tell the parent...
+    Fl::remove_fd(fileno(shell_pipe));
+
+    pclose(shell_pipe);
+    shell_pipe = NULL;
+    shell_run_buffer->append("... END SHELL COMMAND ...\n");
+  }
+
+  shell_run_display->scroll(shell_run_display->count_lines(0,
+                            shell_run_buffer->length(), 1), 0);
+}
+
+void
+do_shell_command(Fl_Return_Button*, void*) {
+  const char	*command;	// Command to run
+
+
+  shell_window->hide();
+
+  if (shell_pipe) {
+    fl_alert("Previous shell command still running!");
+    return;
+  }
+
+  if ((command = shell_command_input->value()) == NULL || !*command) {
+    fl_alert("No shell command entered!");
+    return;
+  }
+
+  if (shell_savefl_button->value()) {
+    save_cb(0, 0);
+  }
+
+  if (shell_writecode_button->value()) {
+    compile_only = 1;
+    write_cb(0, 0);
+    compile_only = 0;
+  }
+
+  if (shell_writemsgs_button->value()) {
+    compile_only = 1;
+    write_strings_cb(0, 0);
+    compile_only = 0;
+  }
+
+  // Show the output window and clear things...
+  shell_run_buffer->text("");
+  shell_run_buffer->append(command);
+  shell_run_buffer->append("\n");
+  shell_run_window->label("Shell Command Running...");
+
+  if ((shell_pipe = popen((char *)command, "r")) == NULL) {
+    fl_alert("Unable to run shell command: %s", strerror(errno));
+    return;
+  }
+
+  shell_run_button->deactivate();
+  shell_run_window->hotspot(shell_run_display);
+  shell_run_window->show();
+
+  Fl::add_fd(fileno(shell_pipe), shell_pipe_cb);
+
+  while (shell_pipe) Fl::wait();
+
+  shell_run_button->activate();
+  shell_run_window->label("Shell Command Complete");
+  fl_beep();
+
+  while (shell_run_window->shown()) Fl::wait();
+}
+#else
+// Just do basic shell command stuff, no status window...
+void
+do_shell_command(Fl_Return_Button*, void*) {
+  const char	*command;	// Command to run
+  int		status;		// Status from command...
+
+
+  shell_window->hide();
+
+  if ((command = shell_command_input->value()) == NULL || !*command) {
+    fl_alert("No shell command entered!");
+    return;
+  }
+
+  if (shell_savefl_button->value()) {
+    save_cb(0, 0);
+  }
+
+  if (shell_writecode_button->value()) {
+    compile_only = 1;
+    write_cb(0, 0);
+    compile_only = 0;
+  }
+
+  if (shell_writemsgs_button->value()) {
+    compile_only = 1;
+    write_strings_cb(0, 0);
+    compile_only = 0;
+  }
+
+  if ((status = system(command)) != 0) {
+    fl_alert("Shell command returned status %d!", status);
+  } else if (completion_button->value()) {
+    fl_message("Shell command completed successfully!");
+  }
+}
+#endif // (!WIN32 || __CYGWIN__) && !__MWERKS__
+
+
+void
+show_shell_window() {
+  shell_window->hotspot(shell_command_input);
+  shell_window->show();
+}
+
+void set_filename(const char *c) {
+  if (filename) free((void *)filename);
+  filename = c ? strdup(c) : NULL;
+
+  if (filename) update_history(filename);
+
+  set_modflag(modflag);
+}
+
+//
+// The Source View system offers an immediate preview of the code 
+// files that will be generated by FLUID. It also marks the code
+// generated for the last selected item in the header and the source
+// file.
+//
+// Can we patent this?  ;-)  - Matt, mm@matthiasm.com
+//
+
+//
+// Update the header and source code highlighting depending on the
+// currently selected object
+//
+void update_sourceview_position()
+{
+  if (!sourceview_panel || !sourceview_panel->visible()) 
+    return;
+  if (sv_autoposition->value()==0) 
+    return;
+  if (sourceview_panel && sourceview_panel->visible() && Fl_Type::current) {
+    int pos0, pos1;
+    if (sv_source->visible_r()) {
+      pos0 = Fl_Type::current->code_line;
+      pos1 = Fl_Type::current->code_line_end;
+      if (pos0>=0) {
+        if (pos1<pos0)
+          pos1 = pos0;
+        sv_source->buffer()->highlight(pos0, pos1);
+        int line = sv_source->buffer()->count_lines(0, pos0);
+        sv_source->scroll(line, 0);
+      }
+    }
+    if (sv_header->visible_r()) {
+      pos0 = Fl_Type::current->header_line;
+      pos1 = Fl_Type::current->header_line_end;
+      if (pos0>=0) {
+        if (pos1<pos0)
+          pos1 = pos0;
+        sv_header->buffer()->highlight(pos0, pos1);
+        int line = sv_header->buffer()->count_lines(0, pos0);
+        sv_header->scroll(line, 0);
+      }
+    }
+  }
+}
+
+void update_sourceview_position_cb(Fl_Tabs*, void*) 
+{
+  update_sourceview_position();
+}
+
+static char *sv_source_filename = 0;
+static char *sv_header_filename = 0;
+
+//
+// Generate a header and source file in a temporary directory and
+// load those into the Code Viewer widgets.
+//
+void update_sourceview_cb(Fl_Button*, void*) 
+{
+  if (!sourceview_panel || !sourceview_panel->visible()) 
+    return;
+  // generate space for the source and header file filenames
+  if (!sv_source_filename) {
+    sv_source_filename = (char*)malloc(FL_PATH_MAX);
+    fluid_prefs.getUserdataPath(sv_source_filename, FL_PATH_MAX);
+    strlcat(sv_source_filename, "source_view_tmp.cxx", FL_PATH_MAX);
+  }
+  if (!sv_header_filename) {
+    sv_header_filename = (char*)malloc(FL_PATH_MAX);
+    fluid_prefs.getUserdataPath(sv_header_filename, FL_PATH_MAX);
+    strlcat(sv_header_filename, "source_view_tmp.h", FL_PATH_MAX);
+  }
+
+  strlcpy(i18n_program, fl_filename_name(sv_source_filename), sizeof(i18n_program));
+  fl_filename_setext(i18n_program, sizeof(i18n_program), "");
+  const char *code_file_name_bak = code_file_name;
+  code_file_name = sv_source_filename;
+  const char *header_file_name_bak = header_file_name;
+  header_file_name = sv_header_filename;
+
+  // generate the code and load the files
+  write_sourceview = 1;
+  // generate files
+  if (write_code(sv_source_filename, sv_header_filename)) 
+  {
+    // load file into source editor
+    int pos = sv_source->top_line();
+    sv_source->buffer()->loadfile(sv_source_filename);
+    sv_source->scroll(pos, 0);
+    // load file into header editor
+    pos = sv_header->top_line();
+    sv_header->buffer()->loadfile(sv_header_filename);
+    sv_header->scroll(pos, 0);
+    // update the source code highlighting
+    update_sourceview_position();
+  }
+  write_sourceview = 0;
+
+  code_file_name = code_file_name_bak;
+  header_file_name = header_file_name_bak;
+}
+
+void update_sourceview_timer(void*) 
+{
+  update_sourceview_cb(0,0);
+}
+
+// Set the "modified" flag and update the title of the main window...
+void set_modflag(int mf) {
+  const char	*basename;
+  static char	title[1024];
+
+  modflag = mf;
+
+  if (main_window) {
+    if (!filename) basename = "Untitled.fl";
+    else if ((basename = strrchr(filename, '/')) != NULL) basename ++;
+#if defined(WIN32) || defined(__EMX__) 
+    else if ((basename = strrchr(filename, '\\')) != NULL) basename ++;
+#endif // WIN32 || __EMX__
+    else basename = filename;
+
+    if (modflag) {
+      snprintf(title, sizeof(title), "%s (modified)", basename);
+      main_window->label(title);
+    } else main_window->label(basename);
+  }
+  // if the UI was modified in any way, update the Source View panel
+  if (sourceview_panel && sourceview_panel->visible() && sv_autorefresh->value())
+  {
+    // we will only update ealiest 0.5 seconds after the last change, and only
+    // if no other change was made, so dragging a widget will not generate any
+    // CPU load
+    Fl::remove_timeout(update_sourceview_timer, 0);
+    Fl::add_timeout(0.5, update_sourceview_timer, 0);
+  }
+
+  // Enable/disable the Save menu item...
+  if (modflag) Main_Menu[SAVE_ITEM].activate();
+  else Main_Menu[SAVE_ITEM].deactivate();
+}
+
+////////////////////////////////////////////////////////////////
+
+static int arg(int argc, char** argv, int& i) {
+  if (argv[i][1] == 'c' && !argv[i][2]) {compile_only = 1; i++; return 1;}
+  if (argv[i][1] == 'c' && argv[i][2] == 's' && !argv[i][3]) {compile_only = 1; compile_strings = 1; i++; return 1;}
+  if (argv[i][1] == 'o' && !argv[i][2] && i+1 < argc) {
+    code_file_name = argv[i+1];
+    code_file_set  = 1;
+    i += 2;
+    return 2;
+  }
+  if (argv[i][1] == 'h' && !argv[i][2]) {
+    header_file_name = argv[i+1];
+    header_file_set  = 1;
+    i += 2;
+    return 2;
+  }
+  return 0;
+}
+
+#if ! (defined(WIN32) && !defined (__CYGWIN__))
+
+int quit_flag = 0;
+#include <signal.h>
+#ifdef _sigargs
+#define SIGARG _sigargs
+#else
+#ifdef __sigargs
+#define SIGARG __sigargs
+#else
+#define SIGARG int // you may need to fix this for older systems
+#endif
+#endif
+
+extern "C" {
+static void sigint(SIGARG) {
+  signal(SIGINT,sigint);
+  quit_flag = 1;
+}
+}
+#endif
+
+int main(int argc,char **argv) {
+  int i = 1;
+  if (!Fl::args(argc,argv,i,arg) || i < argc-1) {
+    fprintf(stderr,"usage: %s <switches> name.fl\n"
+" -c : write .cxx and .h and exit\n"
+" -cs : write .cxx and .h and strings and exit\n"
+" -o <name> : .cxx output filename, or extension if <name> starts with '.'\n"
+" -h <name> : .h output filename, or extension if <name> starts with '.'\n"
+"%s\n", argv[0], Fl::help);
+    return 1;
+  }
+  const char *c = argv[i];
+
+  fl_register_images();
+
+  make_main_window();
+
+#ifdef __APPLE__
+  fl_open_callback(apple_open_cb);
+#endif // __APPLE__
+
+  if (c) set_filename(c);
+  if (!compile_only) {
+    Fl::visual((Fl_Mode)(FL_DOUBLE|FL_INDEX));
+    Fl_File_Icon::load_system_icons();
+    main_window->callback(exit_cb);
+    position_window(main_window,"main_window_pos", 1, 10, 30, WINWIDTH, WINHEIGHT );
+    main_window->show(argc,argv);
+    toggle_widgetbin_cb(0,0);
+    toggle_sourceview_cb(0,0);
+    if (!c && openlast_button->value() && absolute_history[0][0]) {
+      // Open previous file when no file specified...
+      open_history_cb(0, absolute_history[0]);
+    }
+  }
+  undo_suspend();
+  if (c && !read_file(c,0)) {
+    if (compile_only) {
+      fprintf(stderr,"%s : %s\n", c, strerror(errno));
+      exit(1);
+    }
+    fl_message("Can't read %s: %s", c, strerror(errno));
+  }
+  undo_resume();
+  if (compile_only) {
+    if (compile_strings) write_strings_cb(0,0);
+    write_cb(0,0);
+    exit(0);
+  }
+  set_modflag(0);
+  undo_clear();
+#ifndef WIN32
+  signal(SIGINT,sigint);
+#endif
+
+  grid_cb(horizontal_input, 0); // Makes sure that windows get snap params...
+
+#ifdef WIN32
+  Fl::run();
+#else
+  while (!quit_flag) Fl::wait();
+
+  if (quit_flag) exit_cb(0,0);
+#endif // WIN32
+
+  undo_clear();
+
+  return (0);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/fluid.desktop b/Utilities/FLTK/fluid/fluid.desktop
new file mode 100644
index 0000000000000000000000000000000000000000..61a531db6f2749e7a510a50de24712d54d4977b3
--- /dev/null
+++ b/Utilities/FLTK/fluid/fluid.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Name=FLUID
+Comment=FLTK GUI Designer
+TryExec=fluid
+Exec=fluid %F
+Icon=fluid
+Terminal=false
+Type=Application
+MimeType=application/x-fluid
+Encoding=UTF-8
+Categories=Development
diff --git a/Utilities/FLTK/fluid/function_panel.cxx b/Utilities/FLTK/fluid/function_panel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..43c6ccf8803e3baad3c36433be9ccc236111063a
--- /dev/null
+++ b/Utilities/FLTK/fluid/function_panel.cxx
@@ -0,0 +1,933 @@
+//
+// "$Id$"
+//
+// Code dialogs for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "function_panel.h"
+#include <FL/Fl_Pixmap.H>
+#include "Fl_Type.h"
+#include "undo.h"
+extern class Fl_Pixmap *pixmap[];
+extern class Fl_Type *Fl_Type_make(const char*);
+extern void select_only(Fl_Type*);
+
+Fl_Double_Window *function_panel=(Fl_Double_Window *)0;
+
+Fl_Light_Button *f_public_button=(Fl_Light_Button *)0;
+
+Fl_Light_Button *f_c_button=(Fl_Light_Button *)0;
+
+Fl_Input *f_name_input=(Fl_Input *)0;
+
+Fl_Input *f_return_type_input=(Fl_Input *)0;
+
+Fl_Return_Button *f_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *f_panel_cancel=(Fl_Button *)0;
+
+Fl_Double_Window* make_function_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = function_panel = new Fl_Double_Window(290, 150, "Function/Method Properties");
+    w = o;
+    { Fl_Group* o = new Fl_Group(10, 10, 270, 20);
+      { Fl_Light_Button* o = f_public_button = new Fl_Light_Button(10, 10, 60, 20, "public");
+        o->tooltip("Make the function or method publicly accessible.");
+        o->labelsize(11);
+        o->when(FL_WHEN_NEVER);
+      }
+      { Fl_Light_Button* o = f_c_button = new Fl_Light_Button(80, 10, 80, 20, "C declaration");
+        o->tooltip("Declare with a C interface instead of C++.");
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(170, 10, 110, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    { Fl_Input* o = f_name_input = new Fl_Input(10, 50, 270, 20, "Name(args): (blank for main())");
+      o->tooltip("The name of the function or method.");
+      o->labelfont(1);
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Input* o = f_return_type_input = new Fl_Input(10, 90, 270, 20, "Return Type: (blank to return outermost widget)");
+      o->tooltip("The return type of the function or method.");
+      o->labelfont(1);
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+    }
+    { Fl_Group* o = new Fl_Group(10, 120, 270, 20);
+      { Fl_Return_Button* o = f_panel_ok = new Fl_Return_Button(170, 120, 50, 20, "OK");
+        o->tooltip("Apply the changes.");
+        o->labelsize(11);
+        w->hotspot(o);
+      }
+      { Fl_Button* o = f_panel_cancel = new Fl_Button(230, 120, 50, 20, "Cancel");
+        o->tooltip("Cancel the changes.");
+        o->shortcut(0xff1b);
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(10, 120, 150, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(o->w(), o->h(), Fl::w(), o->h());
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *code_panel=(Fl_Double_Window *)0;
+
+CodeEditor *code_input=(CodeEditor *)0;
+
+Fl_Return_Button *code_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *code_panel_cancel=(Fl_Button *)0;
+
+Fl_Double_Window* make_code_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = code_panel = new Fl_Double_Window(540, 180, "Code Properties");
+    w = o;
+    o->labelsize(11);
+    { CodeEditor* o = code_input = new CodeEditor(10, 10, 520, 130);
+      o->box(FL_DOWN_BOX);
+      o->color(FL_BACKGROUND2_COLOR);
+      o->selection_color(FL_SELECTION_COLOR);
+      o->labeltype(FL_NORMAL_LABEL);
+      o->labelfont(0);
+      o->labelsize(11);
+      o->labelcolor(FL_FOREGROUND_COLOR);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP);
+      o->when(FL_WHEN_RELEASE);
+      Fl_Group::current()->resizable(o);
+      o->when(FL_WHEN_ENTER_KEY_CHANGED|FL_WHEN_RELEASE);
+    }
+    { Fl_Group* o = new Fl_Group(10, 150, 520, 20);
+      o->labelsize(11);
+      { Fl_Return_Button* o = code_panel_ok = new Fl_Return_Button(400, 150, 60, 20, "OK");
+        o->labelsize(11);
+        w->hotspot(o);
+      }
+      { Fl_Button* o = code_panel_cancel = new Fl_Button(470, 150, 60, 20, "Cancel");
+        o->shortcut(0xff1b);
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(10, 150, 380, 20);
+        o->labelsize(11);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(200, 150);
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *codeblock_panel=(Fl_Double_Window *)0;
+
+Fl_Input *code_before_input=(Fl_Input *)0;
+
+Fl_Input *code_after_input=(Fl_Input *)0;
+
+Fl_Return_Button *codeblock_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *codeblock_panel_cancel=(Fl_Button *)0;
+
+Fl_Double_Window* make_codeblock_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = codeblock_panel = new Fl_Double_Window(300, 115, "Code Block Properties");
+    w = o;
+    o->labelsize(11);
+    { Fl_Input* o = code_before_input = new Fl_Input(10, 15, 280, 20, "Conditional code block");
+      o->tooltip("#ifdef or similar conditional code block.");
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+    }
+    { Fl_Input* o = code_after_input = new Fl_Input(10, 55, 280, 20, "\"{...child code...}\" is inserted here");
+      o->tooltip("#endif or similar conditional code block.");
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Group* o = new Fl_Group(10, 85, 280, 20);
+      { Fl_Return_Button* o = codeblock_panel_ok = new Fl_Return_Button(160, 85, 60, 20, "OK");
+        o->labelsize(11);
+        w->hotspot(o);
+      }
+      { Fl_Button* o = codeblock_panel_cancel = new Fl_Button(230, 85, 60, 20, "Cancel");
+        o->shortcut(0xff1b);
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(10, 85, 140, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(o->w(), o->h(), Fl::w(), o->h());
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *declblock_panel=(Fl_Double_Window *)0;
+
+Fl_Input *decl_before_input=(Fl_Input *)0;
+
+Fl_Input *decl_after_input=(Fl_Input *)0;
+
+Fl_Return_Button *declblock_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *declblock_panel_cancel=(Fl_Button *)0;
+
+Fl_Light_Button *declblock_public_button=(Fl_Light_Button *)0;
+
+Fl_Double_Window* make_declblock_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = declblock_panel = new Fl_Double_Window(300, 135, "Declaration Block Properties");
+    w = o;
+    o->labelsize(11);
+    { Fl_Input* o = decl_before_input = new Fl_Input(10, 40, 280, 20);
+      o->tooltip("#ifdef or similar conditional declaration block.");
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Input* o = decl_after_input = new Fl_Input(10, 75, 280, 20, "\"\\n...child code...\\n\" is inserted here");
+      o->tooltip("#endif or similar declaration code block.");
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+    }
+    { Fl_Group* o = new Fl_Group(10, 105, 280, 20);
+      { Fl_Return_Button* o = declblock_panel_ok = new Fl_Return_Button(160, 105, 60, 20, "OK");
+        o->labelsize(11);
+        w->hotspot(o);
+      }
+      { Fl_Button* o = declblock_panel_cancel = new Fl_Button(230, 105, 60, 20, "Cancel");
+        o->shortcut(0xff1b);
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(10, 105, 140, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(10, 10, 280, 20);
+      { Fl_Light_Button* o = declblock_public_button = new Fl_Light_Button(10, 10, 60, 20, "public");
+        o->tooltip("Make the declaration publicly accessible.");
+        o->labelsize(11);
+        o->when(FL_WHEN_NEVER);
+      }
+      { Fl_Box* o = new Fl_Box(80, 10, 210, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(o->w(), o->h(), Fl::w(), o->h());
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *decl_panel=(Fl_Double_Window *)0;
+
+Fl_Light_Button *decl_public_button=(Fl_Light_Button *)0;
+
+Fl_Input *decl_input=(Fl_Input *)0;
+
+Fl_Return_Button *decl_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *decl_panel_cancel=(Fl_Button *)0;
+
+Fl_Double_Window* make_decl_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = decl_panel = new Fl_Double_Window(290, 150, "Declaration Properties");
+    w = o;
+    { Fl_Group* o = new Fl_Group(10, 10, 270, 20);
+      { Fl_Light_Button* o = decl_public_button = new Fl_Light_Button(10, 10, 60, 20, "public");
+        o->tooltip("Make the declaration publicly accessible.");
+        o->labelsize(11);
+        o->when(FL_WHEN_NEVER);
+      }
+      { Fl_Box* o = new Fl_Box(80, 10, 200, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    { Fl_Input* o = decl_input = new Fl_Input(10, 40, 270, 20, "Can be any declaration, like \"int x;\", an external symbol like \"extern int\
+ foo();\", a #directive like \"#include <foo.h>\", a comment like \"//foo\" or\
+ \"/*foo*/\", or typedef like \"typedef char byte;\" or \"using std::list;\".");
+      o->tooltip("Declaration text.");
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(134);
+      o->when(FL_WHEN_NEVER);
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Group* o = new Fl_Group(10, 120, 270, 20);
+      { Fl_Return_Button* o = decl_panel_ok = new Fl_Return_Button(150, 120, 60, 20, "OK");
+        o->labelsize(11);
+        w->hotspot(o);
+      }
+      { Fl_Button* o = decl_panel_cancel = new Fl_Button(220, 120, 60, 20, "Cancel");
+        o->shortcut(0xff1b);
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(10, 120, 130, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(o->w(), o->h(), Fl::w(), o->h());
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *class_panel=(Fl_Double_Window *)0;
+
+Fl_Light_Button *c_public_button=(Fl_Light_Button *)0;
+
+Fl_Input *c_name_input=(Fl_Input *)0;
+
+Fl_Input *c_subclass_input=(Fl_Input *)0;
+
+Fl_Return_Button *c_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *c_panel_cancel=(Fl_Button *)0;
+
+Fl_Double_Window* make_class_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = class_panel = new Fl_Double_Window(300, 140, "Class Properties");
+    w = o;
+    o->labelsize(11);
+    { Fl_Group* o = new Fl_Group(10, 10, 280, 20);
+      { Fl_Light_Button* o = c_public_button = new Fl_Light_Button(10, 10, 60, 20, "public");
+        o->tooltip("Make the class publicly accessible.");
+        o->labelsize(11);
+        o->when(FL_WHEN_NEVER);
+      }
+      { Fl_Box* o = new Fl_Box(80, 10, 210, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    { Fl_Input* o = c_name_input = new Fl_Input(10, 45, 280, 20, "Name:");
+      o->tooltip("Name of class.");
+      o->labelfont(1);
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Input* o = c_subclass_input = new Fl_Input(10, 80, 280, 20, "Subclass of (text between : and {)");
+      o->tooltip("Name of subclass.");
+      o->labelfont(1);
+      o->labelsize(11);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(FL_WHEN_NEVER);
+    }
+    { Fl_Group* o = new Fl_Group(10, 110, 280, 20);
+      { Fl_Return_Button* o = c_panel_ok = new Fl_Return_Button(160, 110, 60, 20, "OK");
+        o->labelsize(11);
+        w->hotspot(o);
+      }
+      { Fl_Button* o = c_panel_cancel = new Fl_Button(230, 110, 60, 20, "Cancel");
+        o->shortcut(0xff1b);
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(10, 110, 140, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(o->w(), o->h(), Fl::w(), o->h());
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *comment_panel=(Fl_Double_Window *)0;
+
+CodeEditor *comment_input=(CodeEditor *)0;
+
+Fl_Return_Button *comment_panel_ok=(Fl_Return_Button *)0;
+
+Fl_Button *comment_panel_cancel=(Fl_Button *)0;
+
+Fl_Light_Button *comment_in_source=(Fl_Light_Button *)0;
+
+Fl_Light_Button *comment_in_header=(Fl_Light_Button *)0;
+
+Fl_Menu_Button *comment_predefined=(Fl_Menu_Button *)0;
+
+Fl_Button *comment_load=(Fl_Button *)0;
+
+Fl_Double_Window* make_comment_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = comment_panel = new Fl_Double_Window(550, 280, "Comment Properties");
+    w = o;
+    o->labelsize(11);
+    { CodeEditor* o = comment_input = new CodeEditor(110, 10, 430, 230);
+      o->box(FL_DOWN_BOX);
+      o->color(FL_BACKGROUND2_COLOR);
+      o->selection_color(FL_SELECTION_COLOR);
+      o->labeltype(FL_NORMAL_LABEL);
+      o->labelfont(0);
+      o->labelsize(11);
+      o->labelcolor(FL_FOREGROUND_COLOR);
+      o->textfont(4);
+      o->textsize(11);
+      o->align(FL_ALIGN_TOP);
+      o->when(FL_WHEN_RELEASE);
+      Fl_Group::current()->resizable(o);
+      o->when(FL_WHEN_ENTER_KEY_CHANGED|FL_WHEN_RELEASE);
+    }
+    { Fl_Group* o = new Fl_Group(110, 250, 430, 20);
+      o->labelsize(11);
+      { Fl_Return_Button* o = comment_panel_ok = new Fl_Return_Button(370, 250, 80, 20, "OK");
+        o->labelsize(11);
+        w->hotspot(o);
+      }
+      { Fl_Button* o = comment_panel_cancel = new Fl_Button(460, 250, 80, 20, "Cancel");
+        o->shortcut(0xff1b);
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(110, 250, 250, 20);
+        o->labelsize(11);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(10, 10, 90, 243);
+      o->labelsize(11);
+      { Fl_Light_Button* o = comment_in_source = new Fl_Light_Button(10, 10, 90, 20, "In Source");
+        o->tooltip("Put the comment into the source (.cxx) file.");
+        o->labelsize(11);
+        o->when(FL_WHEN_NEVER);
+      }
+      { Fl_Light_Button* o = comment_in_header = new Fl_Light_Button(10, 40, 90, 20, "In Header");
+        o->tooltip("Put the comment into the header (.h) file.");
+        o->labelsize(11);
+        o->when(FL_WHEN_NEVER);
+      }
+      { Fl_Menu_Button* o = comment_predefined = new Fl_Menu_Button(10, 70, 90, 20, "Predefined");
+        o->labelsize(11);
+        o->textsize(11);
+      }
+      { Fl_Button* o = comment_load = new Fl_Button(10, 100, 90, 20, "Import...");
+        o->labelsize(11);
+      }
+      { Fl_Box* o = new Fl_Box(10, 132, 90, 121);
+        o->labelsize(11);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(320, 180);
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+
+void type_make_cb(Fl_Widget*w,void*d) {
+  undo_checkpoint();
+  Fl_Type *t = Fl_Type_make((char*)d);
+  if (t) {
+    select_only(t);
+    set_modflag(1);
+    t->open();
+  } else {
+    undo_current --;
+    undo_last --;
+  }
+}
+
+Fl_Window *widgetbin_panel=(Fl_Window *)0;
+
+Fl_Window* make_widgetbin() {
+  Fl_Window* w;
+  { Fl_Window* o = widgetbin_panel = new Fl_Window(520, 85, "Widget Bin");
+    w = o;
+    { Fl_Group* o = new Fl_Group(3, 3, 79, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(5, 5, 25, 25);
+        o->tooltip("Function");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Function"));
+        o->image(pixmap[7]);
+      }
+      { Fl_Button* o = new Fl_Button(30, 5, 25, 25);
+        o->tooltip("Class");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Class"));
+        o->image(pixmap[12]);
+      }
+      { Fl_Button* o = new Fl_Button(55, 5, 25, 25);
+        o->tooltip("Comment");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("comment"));
+        o->image(pixmap[46]);
+      }
+      { Fl_Button* o = new Fl_Button(5, 30, 25, 25);
+        o->tooltip("Code");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Code"));
+        o->image(pixmap[8]);
+      }
+      { Fl_Button* o = new Fl_Button(30, 30, 25, 25);
+        o->tooltip("Code Block");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("CodeBlock"));
+        o->image(pixmap[9]);
+      }
+      { Fl_Button* o = new Fl_Button(55, 30, 25, 25);
+        o->tooltip("Widget Class");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("widget_class"));
+        o->image(pixmap[48]);
+      }
+      { Fl_Button* o = new Fl_Button(5, 55, 25, 25);
+        o->tooltip("Declaration");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("decl"));
+        o->image(pixmap[10]);
+      }
+      { Fl_Button* o = new Fl_Button(30, 55, 25, 25);
+        o->tooltip("Declaration Block");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("declblock"));
+        o->image(pixmap[11]);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(83, 3, 79, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(85, 5, 25, 25);
+        o->tooltip("Window");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Window"));
+        o->image(pixmap[1]);
+      }
+      { Fl_Button* o = new Fl_Button(110, 5, 25, 25);
+        o->tooltip("Group");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Group"));
+        o->image(pixmap[6]);
+      }
+      { Fl_Button* o = new Fl_Button(135, 5, 25, 25);
+        o->tooltip("Pack");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Pack"));
+        o->image(pixmap[22]);
+      }
+      { Fl_Button* o = new Fl_Button(85, 30, 25, 25);
+        o->tooltip("Tabs");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Tabs"));
+        o->image(pixmap[13]);
+      }
+      { Fl_Button* o = new Fl_Button(110, 30, 25, 25);
+        o->tooltip("Scroll");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Scroll"));
+        o->image(pixmap[19]);
+      }
+      { Fl_Button* o = new Fl_Button(85, 55, 25, 25);
+        o->tooltip("Tile");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Tile"));
+        o->image(pixmap[20]);
+      }
+      { Fl_Button* o = new Fl_Button(110, 55, 25, 25);
+        o->tooltip("Wizard");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Wizard"));
+        o->image(pixmap[21]);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(163, 3, 54, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(165, 5, 25, 25);
+        o->tooltip("Button");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Button"));
+        o->image(pixmap[2]);
+      }
+      { Fl_Button* o = new Fl_Button(190, 5, 25, 25);
+        o->tooltip("Return Button");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Return_Button"));
+        o->image(pixmap[23]);
+      }
+      { Fl_Button* o = new Fl_Button(165, 30, 25, 25);
+        o->tooltip("Light Button");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Light_Button"));
+        o->image(pixmap[24]);
+      }
+      { Fl_Button* o = new Fl_Button(190, 30, 25, 25);
+        o->tooltip("Repeat Button");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Repeat_Button"));
+        o->image(pixmap[25]);
+      }
+      { Fl_Button* o = new Fl_Button(165, 55, 25, 25);
+        o->tooltip("Check Button");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Check_Button"));
+        o->image(pixmap[3]);
+      }
+      { Fl_Button* o = new Fl_Button(190, 55, 25, 25);
+        o->tooltip("Round Button");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Round_Button"));
+        o->image(pixmap[4]);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(218, 3, 104, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(220, 5, 25, 25);
+        o->tooltip("Slider");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Slider"));
+        o->image(pixmap[37]);
+      }
+      { Fl_Button* o = new Fl_Button(245, 5, 25, 25);
+        o->tooltip("Scroll Bar");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Scrollbar"));
+        o->image(pixmap[38]);
+      }
+      { Fl_Button* o = new Fl_Button(270, 5, 25, 25);
+        o->tooltip("Value Slider");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Value_Slider"));
+        o->image(pixmap[39]);
+      }
+      { Fl_Button* o = new Fl_Button(295, 5, 25, 25);
+        o->tooltip("Value Output");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Value_Output"));
+        o->image(pixmap[45]);
+      }
+      { Fl_Button* o = new Fl_Button(220, 30, 25, 25);
+        o->tooltip("Adjuster");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Adjuster"));
+        o->image(pixmap[40]);
+      }
+      { Fl_Button* o = new Fl_Button(245, 30, 25, 25);
+        o->tooltip("Counter");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Counter"));
+        o->image(pixmap[41]);
+      }
+      { Fl_Button* o = new Fl_Button(270, 30, 25, 25);
+        o->tooltip("Dial");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Dial"));
+        o->image(pixmap[42]);
+      }
+      { Fl_Button* o = new Fl_Button(220, 55, 25, 25);
+        o->tooltip("Roller");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Roller"));
+        o->image(pixmap[43]);
+      }
+      { Fl_Button* o = new Fl_Button(245, 55, 25, 25);
+        o->tooltip("Spinner");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Spinner"));
+        o->image(pixmap[47]);
+      }
+      { Fl_Button* o = new Fl_Button(270, 55, 25, 25);
+        o->tooltip("Value Input");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Value_Input"));
+        o->image(pixmap[44]);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(323, 3, 54, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(325, 5, 25, 25);
+        o->tooltip("Input");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Input"));
+        o->image(pixmap[14]);
+      }
+      { Fl_Button* o = new Fl_Button(350, 5, 25, 25);
+        o->tooltip("Output");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Output"));
+        o->image(pixmap[27]);
+      }
+      { Fl_Button* o = new Fl_Button(325, 30, 25, 25);
+        o->tooltip("Text Edit");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Text_Editor"));
+        o->image(pixmap[29]);
+      }
+      { Fl_Button* o = new Fl_Button(350, 30, 25, 25);
+        o->tooltip("Text Display");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Text_Display"));
+        o->image(pixmap[28]);
+      }
+      { Fl_Button* o = new Fl_Button(325, 55, 25, 25);
+        o->tooltip("File Input");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_File_Input"));
+        o->image(pixmap[30]);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(378, 3, 54, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(380, 5, 25, 25);
+        o->tooltip("Menu Bar");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Menu_Bar"));
+        o->image(pixmap[17]);
+      }
+      { Fl_Button* o = new Fl_Button(405, 5, 25, 25);
+        o->tooltip("Input Choice");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Input_Choice"));
+        o->image(pixmap[15]);
+      }
+      { Fl_Button* o = new Fl_Button(380, 30, 25, 25);
+        o->tooltip("Menu Button");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Menu_Button"));
+        o->image(pixmap[26]);
+      }
+      { Fl_Button* o = new Fl_Button(405, 30, 25, 25);
+        o->tooltip("Menu Item");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("menuitem"));
+        o->image(pixmap[16]);
+      }
+      { Fl_Button* o = new Fl_Button(380, 55, 25, 25);
+        o->tooltip("Choice");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Choice"));
+        o->image(pixmap[15]);
+      }
+      { Fl_Button* o = new Fl_Button(405, 55, 25, 25);
+        o->tooltip("Sub Menu");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("submenu"));
+        o->image(pixmap[18]);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(433, 3, 29, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(435, 5, 25, 25);
+        o->tooltip("Browser");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Browser"));
+        o->image(pixmap[31]);
+      }
+      { Fl_Button* o = new Fl_Button(435, 30, 25, 25);
+        o->tooltip("Check Browser");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Check_Browser"));
+        o->image(pixmap[32]);
+      }
+      { Fl_Button* o = new Fl_Button(435, 55, 25, 25);
+        o->tooltip("File Browser");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_File_Browser"));
+        o->image(pixmap[33]);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(463, 3, 54, 79);
+      o->box(FL_THIN_DOWN_BOX);
+      { Fl_Button* o = new Fl_Button(465, 5, 25, 25);
+        o->tooltip("Box");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Box"));
+        o->image(pixmap[5]);
+      }
+      { Fl_Button* o = new Fl_Button(490, 5, 25, 25);
+        o->tooltip("Clock");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Clock"));
+        o->image(pixmap[34]);
+      }
+      { Fl_Button* o = new Fl_Button(465, 30, 25, 25);
+        o->tooltip("Help Browser");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Help_View"));
+        o->image(pixmap[35]);
+      }
+      { Fl_Button* o = new Fl_Button(465, 55, 25, 25);
+        o->tooltip("Progress");
+        o->box(FL_THIN_UP_BOX);
+        o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Progress"));
+        o->image(pixmap[36]);
+      }
+      o->end();
+    }
+    o->set_non_modal();
+    o->end();
+  }
+  return w;
+}
+
+Fl_Double_Window *sourceview_panel=(Fl_Double_Window *)0;
+
+Fl_Tabs *sv_tab=(Fl_Tabs *)0;
+
+CodeEditor *sv_source=(CodeEditor *)0;
+
+CodeEditor *sv_header=(CodeEditor *)0;
+
+Fl_Light_Button *sv_autorefresh=(Fl_Light_Button *)0;
+
+Fl_Light_Button *sv_autoposition=(Fl_Light_Button *)0;
+
+Fl_Double_Window* make_sourceview() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = sourceview_panel = new Fl_Double_Window(520, 490, "Code View");
+    w = o;
+    o->callback((Fl_Callback*)toggle_sourceview_cb);
+    { Fl_Tabs* o = sv_tab = new Fl_Tabs(10, 10, 500, 440);
+      o->selection_color((Fl_Color)4);
+      o->labelcolor(FL_BACKGROUND2_COLOR);
+      o->callback((Fl_Callback*)update_sourceview_position_cb);
+      { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Source");
+        o->labelsize(13);
+        o->hide();
+        { CodeEditor* o = sv_source = new CodeEditor(20, 50, 480, 390);
+          o->box(FL_DOWN_FRAME);
+          o->color(FL_BACKGROUND2_COLOR);
+          o->selection_color(FL_SELECTION_COLOR);
+          o->labeltype(FL_NORMAL_LABEL);
+          o->labelfont(0);
+          o->labelsize(14);
+          o->labelcolor(FL_FOREGROUND_COLOR);
+          o->textfont(4);
+          o->textsize(11);
+          o->align(FL_ALIGN_TOP);
+          o->when(FL_WHEN_RELEASE);
+          Fl_Group::current()->resizable(o);
+        }
+        o->end();
+        Fl_Group::current()->resizable(o);
+      }
+      { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Header");
+        o->labelsize(13);
+        { CodeEditor* o = sv_header = new CodeEditor(20, 50, 480, 390);
+          o->box(FL_DOWN_FRAME);
+          o->color(FL_BACKGROUND2_COLOR);
+          o->selection_color(FL_SELECTION_COLOR);
+          o->labeltype(FL_NORMAL_LABEL);
+          o->labelfont(0);
+          o->labelsize(14);
+          o->labelcolor(FL_FOREGROUND_COLOR);
+          o->textfont(4);
+          o->textsize(11);
+          o->align(FL_ALIGN_TOP);
+          o->when(FL_WHEN_RELEASE);
+          Fl_Group::current()->resizable(o);
+        }
+        o->end();
+      }
+      o->end();
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Group* o = new Fl_Group(10, 460, 500, 20);
+      { Fl_Button* o = new Fl_Button(10, 460, 61, 20, "Refresh");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)update_sourceview_cb);
+      }
+      { Fl_Light_Button* o = sv_autorefresh = new Fl_Light_Button(76, 460, 91, 20, "Auto-Refresh");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)update_sourceview_cb);
+      }
+      { Fl_Light_Button* o = sv_autoposition = new Fl_Light_Button(172, 460, 89, 20, "Auto-Position");
+        o->labelsize(11);
+      }
+      { Fl_Button* o = new Fl_Button(460, 460, 50, 20, "Close");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)toggle_sourceview_b_cb);
+      }
+      { Fl_Box* o = new Fl_Box(265, 460, 190, 20);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(384, 120);
+    o->end();
+  }
+  return w;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/function_panel.fl b/Utilities/FLTK/fluid/function_panel.fl
new file mode 100644
index 0000000000000000000000000000000000000000..05528ce52aded0907517442570a45f0bcd63eca9
--- /dev/null
+++ b/Utilities/FLTK/fluid/function_panel.fl
@@ -0,0 +1,752 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {.h} 
+code_name {.cxx}
+comment {//
+// "$Id: function_panel.fl 4638 2005-11-04 15:16:24Z matt $"
+//
+// Code dialogs for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {in_source in_header
+} 
+
+decl {\#include <FL/Fl_Pixmap.H>} {} 
+
+decl {\#include "Fl_Type.h"} {} 
+
+decl {\#include "undo.h"} {} 
+
+decl {extern class Fl_Pixmap *pixmap[];} {} 
+
+decl {extern class Fl_Type *Fl_Type_make(const char*);} {} 
+
+decl {extern void select_only(Fl_Type*);} {} 
+
+Function {make_function_panel()} {open
+} {
+  Fl_Window function_panel {
+    label {Function/Method Properties}
+    xywh {419 200 290 150} type Double hide resizable
+    code0 {o->size_range(o->w(), o->h(), Fl::w(), o->h());} modal
+  } {
+    Fl_Group {} {open
+      xywh {10 10 270 20}
+    } {
+      Fl_Light_Button f_public_button {
+        label public
+        tooltip {Make the function or method publicly accessible.} xywh {10 10 60 20} labelsize 11 when 0
+      }
+      Fl_Light_Button f_c_button {
+        label {C declaration}
+        tooltip {Declare with a C interface instead of C++.} xywh {80 10 80 20} labelsize 11
+      }
+      Fl_Box {} {
+        xywh {170 10 110 20} resizable
+      }
+    }
+    Fl_Input f_name_input {
+      label {Name(args): (blank for main())}
+      tooltip {The name of the function or method.} xywh {10 50 270 20} labelfont 1 labelsize 11 align 5 when 0 textfont 4 textsize 11 resizable
+    }
+    Fl_Input f_return_type_input {
+      label {Return Type: (blank to return outermost widget)}
+      tooltip {The return type of the function or method.} xywh {10 90 270 20} labelfont 1 labelsize 11 align 5 when 0 textfont 4 textsize 11
+    }
+    Fl_Group {} {open
+      xywh {10 120 270 20}
+    } {
+      Fl_Return_Button f_panel_ok {
+        label OK
+        tooltip {Apply the changes.} xywh {170 120 50 20} labelsize 11 hotspot
+      }
+      Fl_Button f_panel_cancel {
+        label Cancel
+        tooltip {Cancel the changes.} xywh {230 120 50 20} shortcut 0xff1b labelsize 11
+      }
+      Fl_Box {} {
+        xywh {10 120 150 20} resizable
+      }
+    }
+  }
+} 
+
+Function {make_code_panel()} {open
+} {
+  Fl_Window code_panel {
+    label {Code Properties}
+    xywh {353 262 540 180} type Double labelsize 11 hide resizable
+    code0 {o->size_range(200, 150);} modal
+  } {
+    Fl_Text_Editor code_input {
+      xywh {10 10 520 130} box DOWN_BOX labelsize 11 textfont 4 textsize 11 resizable
+      code0 {o->when(FL_WHEN_ENTER_KEY_CHANGED|FL_WHEN_RELEASE);}
+      code1 {\#include "CodeEditor.h"}
+      class CodeEditor
+    }
+    Fl_Group {} {open
+      xywh {10 150 520 20} labelsize 11
+    } {
+      Fl_Return_Button code_panel_ok {
+        label OK
+        xywh {400 150 60 20} labelsize 11 hotspot
+      }
+      Fl_Button code_panel_cancel {
+        label Cancel
+        xywh {470 150 60 20} shortcut 0xff1b labelsize 11
+      }
+      Fl_Box {} {
+        xywh {10 150 380 20} labelsize 11 resizable
+      }
+    }
+  }
+} 
+
+Function {make_codeblock_panel()} {open
+} {
+  Fl_Window codeblock_panel {
+    label {Code Block Properties}
+    xywh {468 221 300 115} type Double labelsize 11 hide resizable
+    code0 {o->size_range(o->w(), o->h(), Fl::w(), o->h());} modal
+  } {
+    Fl_Input code_before_input {
+      label {Conditional code block}
+      tooltip {\#ifdef or similar conditional code block.} xywh {10 15 280 20} labelsize 11 align 5 when 0 textfont 4 textsize 11
+    }
+    Fl_Input code_after_input {
+      label {"{...child code...}" is inserted here}
+      tooltip {\#endif or similar conditional code block.} xywh {10 55 280 20} labelsize 11 align 5 when 0 textfont 4 textsize 11 resizable
+    }
+    Fl_Group {} {open
+      xywh {10 85 280 20}
+    } {
+      Fl_Return_Button codeblock_panel_ok {
+        label OK
+        xywh {160 85 60 20} labelsize 11 hotspot
+      }
+      Fl_Button codeblock_panel_cancel {
+        label Cancel
+        xywh {230 85 60 20} shortcut 0xff1b labelsize 11
+      }
+      Fl_Box {} {
+        xywh {10 85 140 20} resizable
+      }
+    }
+  }
+} 
+
+Function {make_declblock_panel()} {open
+} {
+  Fl_Window declblock_panel {
+    label {Declaration Block Properties}
+    xywh {428 215 300 135} type Double labelsize 11 hide resizable
+    code0 {o->size_range(o->w(), o->h(), Fl::w(), o->h());} modal
+  } {
+    Fl_Input decl_before_input {
+      tooltip {\#ifdef or similar conditional declaration block.} xywh {10 40 280 20} labelsize 11 align 5 when 0 textfont 4 textsize 11 resizable
+    }
+    Fl_Input decl_after_input {
+      label {"\\n...child code...\\n" is inserted here}
+      tooltip {\#endif or similar declaration code block.} xywh {10 75 280 20} labelsize 11 align 5 when 0 textfont 4 textsize 11
+    }
+    Fl_Group {} {open
+      xywh {10 105 280 20}
+    } {
+      Fl_Return_Button declblock_panel_ok {
+        label OK
+        xywh {160 105 60 20} labelsize 11 hotspot
+      }
+      Fl_Button declblock_panel_cancel {
+        label Cancel
+        xywh {230 105 60 20} shortcut 0xff1b labelsize 11
+      }
+      Fl_Box {} {
+        xywh {10 105 140 20} resizable
+      }
+    }
+    Fl_Group {} {open
+      xywh {10 10 280 20}
+    } {
+      Fl_Light_Button declblock_public_button {
+        label public
+        tooltip {Make the declaration publicly accessible.} xywh {10 10 60 20} labelsize 11 when 0
+      }
+      Fl_Box {} {
+        xywh {80 10 210 20} resizable
+      }
+    }
+  }
+} 
+
+Function {make_decl_panel()} {open
+} {
+  Fl_Window decl_panel {
+    label {Declaration Properties}
+    xywh {412 206 290 150} type Double hide resizable
+    code0 {o->size_range(o->w(), o->h(), Fl::w(), o->h());}
+  } {
+    Fl_Group {} {open
+      xywh {10 10 270 20}
+    } {
+      Fl_Light_Button decl_public_button {
+        label public
+        tooltip {Make the declaration publicly accessible.} xywh {10 10 60 20} labelsize 11 when 0
+      }
+      Fl_Box {} {
+        xywh {80 10 200 20} resizable
+      }
+    }
+    Fl_Input decl_input {
+      label {Can be any declaration, like "int x;", an external symbol like "extern int foo();", a \#directive like "\#include <foo.h>", a comment like "//foo" or "/*foo*/", or typedef like "typedef char byte;" or "using std::list;".}
+      tooltip {Declaration text.} xywh {10 40 270 20} labelsize 11 align 134 when 0 textfont 4 textsize 11 resizable
+    }
+    Fl_Group {} {open
+      xywh {10 120 270 20}
+    } {
+      Fl_Return_Button decl_panel_ok {
+        label OK
+        xywh {150 120 60 20} labelsize 11 hotspot
+      }
+      Fl_Button decl_panel_cancel {
+        label Cancel
+        xywh {220 120 60 20} shortcut 0xff1b labelsize 11
+      }
+      Fl_Box {} {
+        xywh {10 120 130 20} resizable
+      }
+    }
+  }
+} 
+
+Function {make_class_panel()} {open
+} {
+  Fl_Window class_panel {
+    label {Class Properties}
+    xywh {449 218 300 140} type Double labelsize 11 hide resizable
+    code0 {o->size_range(o->w(), o->h(), Fl::w(), o->h());} modal
+  } {
+    Fl_Group {} {open
+      xywh {10 10 280 20}
+    } {
+      Fl_Light_Button c_public_button {
+        label public
+        tooltip {Make the class publicly accessible.} xywh {10 10 60 20} labelsize 11 when 0
+      }
+      Fl_Box {} {
+        xywh {80 10 210 20} resizable
+      }
+    }
+    Fl_Input c_name_input {
+      label {Name:}
+      tooltip {Name of class.} xywh {10 45 280 20} labelfont 1 labelsize 11 align 5 when 0 textfont 4 textsize 11 resizable
+    }
+    Fl_Input c_subclass_input {
+      label {Subclass of (text between : and \{)}
+      tooltip {Name of subclass.} xywh {10 80 280 20} labelfont 1 labelsize 11 align 5 when 0 textfont 4 textsize 11
+    }
+    Fl_Group {} {open
+      xywh {10 110 280 20}
+    } {
+      Fl_Return_Button c_panel_ok {
+        label OK
+        xywh {160 110 60 20} labelsize 11 hotspot
+      }
+      Fl_Button c_panel_cancel {
+        label Cancel
+        xywh {230 110 60 20} shortcut 0xff1b labelsize 11
+      }
+      Fl_Box {} {
+        xywh {10 110 140 20} resizable
+      }
+    }
+  }
+} 
+
+Function {make_comment_panel()} {open
+} {
+  Fl_Window comment_panel {
+    label {Comment Properties}
+    xywh {422 190 550 280} type Double labelsize 11 hide resizable
+    code0 {o->size_range(320, 180);} modal
+  } {
+    Fl_Text_Editor comment_input {
+      xywh {110 10 430 230} box DOWN_BOX labelsize 11 textfont 4 textsize 11 resizable
+      code0 {o->when(FL_WHEN_ENTER_KEY_CHANGED|FL_WHEN_RELEASE);}
+      class CodeEditor
+    }
+    Fl_Group {} {open
+      xywh {110 250 430 20} labelsize 11
+    } {
+      Fl_Return_Button comment_panel_ok {
+        label OK
+        xywh {370 250 80 20} labelsize 11 hotspot
+      }
+      Fl_Button comment_panel_cancel {
+        label Cancel
+        xywh {460 250 80 20} shortcut 0xff1b labelsize 11
+      }
+      Fl_Box {} {
+        xywh {110 250 250 20} labelsize 11 resizable
+      }
+    }
+    Fl_Group {} {open
+      xywh {10 10 90 243} labelsize 11
+    } {
+      Fl_Light_Button comment_in_source {
+        label {In Source}
+        tooltip {Put the comment into the source (.cxx) file.} xywh {10 10 90 20} labelsize 11 when 0
+      }
+      Fl_Light_Button comment_in_header {
+        label {In Header}
+        tooltip {Put the comment into the header (.h) file.} xywh {10 40 90 20} labelsize 11 when 0
+      }
+      Fl_Menu_Button comment_predefined {
+        label Predefined open
+        xywh {10 70 90 20} labelsize 11 textsize 11
+      } {}
+      Fl_Button comment_load {
+        label {Import...}
+        xywh {10 100 90 20} labelsize 11
+      }
+      Fl_Box {} {
+        xywh {10 132 90 121} labelsize 11 resizable
+      }
+    }
+  }
+} 
+
+Function {type_make_cb(Fl_Widget*w,void*d)} {open return_type void
+} {
+  code {undo_checkpoint();
+  Fl_Type *t = Fl_Type_make((char*)d);
+  if (t) {
+    select_only(t);
+    set_modflag(1);
+    t->open();
+  } else {
+    undo_current --;
+    undo_last --;
+  }} {}
+} 
+
+Function {make_widgetbin()} {open
+} {
+  Fl_Window widgetbin_panel {
+    label {Widget Bin}
+    xywh {413 185 520 85} type Single non_modal visible
+  } {
+    Fl_Group {} {
+      xywh {3 3 79 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Function"}
+        callback type_make_cb
+        tooltip Function xywh {5 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[7]);}
+      }
+      Fl_Button {} {
+        user_data {"Class"}
+        callback type_make_cb
+        tooltip Class xywh {30 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[12]);}
+      }
+      Fl_Button {} {
+        user_data {"comment"}
+        callback type_make_cb
+        tooltip Comment xywh {55 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[46]);}
+      }
+      Fl_Button {} {
+        user_data {"Code"}
+        callback type_make_cb
+        tooltip Code xywh {5 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[8]);}
+      }
+      Fl_Button {} {
+        user_data {"CodeBlock"}
+        callback type_make_cb
+        tooltip {Code Block} xywh {30 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[9]);}
+      }
+      Fl_Button {} {
+        user_data {"widget_class"}
+        callback type_make_cb
+        tooltip {Widget Class} xywh {55 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[48]);}
+      }
+      Fl_Button {} {
+        user_data {"decl"}
+        callback type_make_cb
+        tooltip Declaration xywh {5 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[10]);}
+      }
+      Fl_Button {} {
+        user_data {"declblock"}
+        callback type_make_cb selected
+        tooltip {Declaration Block} xywh {30 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[11]);}
+      }
+    }
+    Fl_Group {} {
+      xywh {83 3 79 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Fl_Window"}
+        callback type_make_cb
+        tooltip Window xywh {85 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[1]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Group"}
+        callback type_make_cb
+        tooltip Group xywh {110 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[6]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Pack"}
+        callback type_make_cb
+        tooltip Pack xywh {135 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[22]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Tabs"}
+        callback type_make_cb
+        tooltip Tabs xywh {85 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[13]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Scroll"}
+        callback type_make_cb
+        tooltip Scroll xywh {110 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[19]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Tile"}
+        callback type_make_cb
+        tooltip Tile xywh {85 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[20]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Wizard"}
+        callback type_make_cb
+        tooltip Wizard xywh {110 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[21]);}
+      }
+    }
+    Fl_Group {} {
+      xywh {163 3 54 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Fl_Button"}
+        callback type_make_cb
+        tooltip Button xywh {165 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[2]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Return_Button"}
+        callback type_make_cb
+        tooltip {Return Button} xywh {190 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[23]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Light_Button"}
+        callback type_make_cb
+        tooltip {Light Button} xywh {165 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[24]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Repeat_Button"}
+        callback type_make_cb
+        tooltip {Repeat Button} xywh {190 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[25]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Check_Button"}
+        callback type_make_cb
+        tooltip {Check Button} xywh {165 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[3]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Round_Button"}
+        callback type_make_cb
+        tooltip {Round Button} xywh {190 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[4]);}
+      }
+    }
+    Fl_Group {} {
+      xywh {218 3 104 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Fl_Slider"}
+        callback type_make_cb
+        tooltip Slider xywh {220 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[37]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Scrollbar"}
+        callback type_make_cb
+        tooltip {Scroll Bar} xywh {245 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[38]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Value_Slider"}
+        callback type_make_cb
+        tooltip {Value Slider} xywh {270 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[39]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Value_Output"}
+        callback type_make_cb
+        tooltip {Value Output} xywh {295 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[45]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Adjuster"}
+        callback type_make_cb
+        tooltip Adjuster xywh {220 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[40]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Counter"}
+        callback type_make_cb
+        tooltip Counter xywh {245 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[41]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Dial"}
+        callback type_make_cb
+        tooltip Dial xywh {270 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[42]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Roller"}
+        callback type_make_cb
+        tooltip Roller xywh {220 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[43]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Spinner"}
+        callback type_make_cb
+        tooltip Spinner xywh {245 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[47]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Value_Input"}
+        callback type_make_cb
+        tooltip {Value Input} xywh {270 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[44]);}
+      }
+    }
+    Fl_Group {} {
+      xywh {323 3 54 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Fl_Input"}
+        callback type_make_cb
+        tooltip Input xywh {325 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[14]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Output"}
+        callback type_make_cb
+        tooltip Output xywh {350 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[27]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Text_Editor"}
+        callback type_make_cb
+        tooltip {Text Edit} xywh {325 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[29]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Text_Display"}
+        callback type_make_cb
+        tooltip {Text Display} xywh {350 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[28]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_File_Input"}
+        callback type_make_cb
+        tooltip {File Input} xywh {325 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[30]);}
+      }
+    }
+    Fl_Group {} {
+      xywh {378 3 54 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Fl_Menu_Bar"}
+        callback type_make_cb
+        tooltip {Menu Bar} xywh {380 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[17]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Input_Choice"}
+        callback type_make_cb
+        tooltip {Input Choice} xywh {405 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[15]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Menu_Button"}
+        callback type_make_cb
+        tooltip {Menu Button} xywh {380 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[26]);}
+      }
+      Fl_Button {} {
+        user_data {"menuitem"}
+        callback type_make_cb
+        tooltip {Menu Item} xywh {405 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[16]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Choice"}
+        callback type_make_cb
+        tooltip Choice xywh {380 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[15]);}
+      }
+      Fl_Button {} {
+        user_data {"submenu"}
+        callback type_make_cb
+        tooltip {Sub Menu} xywh {405 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[18]);}
+      }
+    }
+    Fl_Group {} {
+      xywh {433 3 29 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Fl_Browser"}
+        callback type_make_cb
+        tooltip Browser xywh {435 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[31]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Check_Browser"}
+        callback type_make_cb
+        tooltip {Check Browser} xywh {435 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[32]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_File_Browser"}
+        callback type_make_cb
+        tooltip {File Browser} xywh {435 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[33]);}
+      }
+    }
+    Fl_Group {} {
+      xywh {463 3 54 79} box THIN_DOWN_BOX
+    } {
+      Fl_Button {} {
+        user_data {"Fl_Box"}
+        callback type_make_cb
+        tooltip Box xywh {465 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[5]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Clock"}
+        callback type_make_cb
+        tooltip Clock xywh {490 5 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[34]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Help_View"}
+        callback type_make_cb
+        tooltip {Help Browser} xywh {465 30 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[35]);}
+      }
+      Fl_Button {} {
+        user_data {"Fl_Progress"}
+        callback type_make_cb
+        tooltip Progress xywh {465 55 25 25} box THIN_UP_BOX
+        code0 {o->image(pixmap[36]);}
+      }
+    }
+  }
+} 
+
+Function {make_sourceview()} {open
+} {
+  Fl_Window sourceview_panel {
+    label {Code View}
+    callback toggle_sourceview_cb
+    xywh {533 374 520 490} type Double resizable size_range {384 120 0 0} visible
+  } {
+    Fl_Tabs sv_tab {
+      callback update_sourceview_position_cb
+      xywh {10 10 500 440} selection_color 4 labelcolor 7 resizable
+    } {
+      Fl_Group {} {
+        label Source open
+        xywh {10 35 500 415} labelsize 13 hide resizable
+      } {
+        Fl_Text_Editor sv_source {
+          xywh {20 50 480 390} textfont 4 textsize 11 resizable
+          code0 {\#include "CodeEditor.h"}
+          class CodeEditor
+        }
+      }
+      Fl_Group {} {
+        label Header open
+        xywh {10 35 500 415} labelsize 13
+      } {
+        Fl_Text_Editor sv_header {
+          xywh {20 50 480 390} textfont 4 textsize 11 resizable
+          code0 {\#include "CodeEditor.h"}
+          class CodeEditor
+        }
+      }
+    }
+    Fl_Group {} {
+      xywh {10 460 500 20}
+    } {
+      Fl_Button {} {
+        label Refresh
+        callback update_sourceview_cb
+        xywh {10 460 61 20} labelsize 11
+      }
+      Fl_Light_Button sv_autorefresh {
+        label {Auto-Refresh}
+        xywh {76 460 91 20} labelsize 11
+        code0 {o->callback((Fl_Callback*)update_sourceview_cb);}
+      }
+      Fl_Light_Button sv_autoposition {
+        label {Auto-Position}
+        xywh {172 460 89 20} labelsize 11
+      }
+      Fl_Button {} {
+        label Close
+        callback toggle_sourceview_b_cb
+        xywh {460 460 50 20} labelsize 11
+      }
+      Fl_Box {} {
+        xywh {265 460 190 20} resizable
+      }
+    }
+  }
+} 
+
+comment {
+//
+// End of "$Id: function_panel.fl 4638 2005-11-04 15:16:24Z matt $".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/fluid/function_panel.h b/Utilities/FLTK/fluid/function_panel.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd8c5254c7c82986acebcbb6ced05e43e611f79c
--- /dev/null
+++ b/Utilities/FLTK/fluid/function_panel.h
@@ -0,0 +1,111 @@
+//
+// "$Id$"
+//
+// Code dialogs for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef function_panel_h
+#define function_panel_h
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+extern Fl_Double_Window *function_panel;
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Light_Button.H>
+extern Fl_Light_Button *f_public_button;
+extern Fl_Light_Button *f_c_button;
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input.H>
+extern Fl_Input *f_name_input;
+extern Fl_Input *f_return_type_input;
+#include <FL/Fl_Return_Button.H>
+extern Fl_Return_Button *f_panel_ok;
+#include <FL/Fl_Button.H>
+extern Fl_Button *f_panel_cancel;
+Fl_Double_Window* make_function_panel();
+extern Fl_Double_Window *code_panel;
+#include "CodeEditor.h"
+extern CodeEditor *code_input;
+extern Fl_Return_Button *code_panel_ok;
+extern Fl_Button *code_panel_cancel;
+Fl_Double_Window* make_code_panel();
+extern Fl_Double_Window *codeblock_panel;
+extern Fl_Input *code_before_input;
+extern Fl_Input *code_after_input;
+extern Fl_Return_Button *codeblock_panel_ok;
+extern Fl_Button *codeblock_panel_cancel;
+Fl_Double_Window* make_codeblock_panel();
+extern Fl_Double_Window *declblock_panel;
+extern Fl_Input *decl_before_input;
+extern Fl_Input *decl_after_input;
+extern Fl_Return_Button *declblock_panel_ok;
+extern Fl_Button *declblock_panel_cancel;
+extern Fl_Light_Button *declblock_public_button;
+Fl_Double_Window* make_declblock_panel();
+extern Fl_Double_Window *decl_panel;
+extern Fl_Light_Button *decl_public_button;
+extern Fl_Input *decl_input;
+extern Fl_Return_Button *decl_panel_ok;
+extern Fl_Button *decl_panel_cancel;
+Fl_Double_Window* make_decl_panel();
+extern Fl_Double_Window *class_panel;
+extern Fl_Light_Button *c_public_button;
+extern Fl_Input *c_name_input;
+extern Fl_Input *c_subclass_input;
+extern Fl_Return_Button *c_panel_ok;
+extern Fl_Button *c_panel_cancel;
+Fl_Double_Window* make_class_panel();
+extern Fl_Double_Window *comment_panel;
+extern CodeEditor *comment_input;
+extern Fl_Return_Button *comment_panel_ok;
+extern Fl_Button *comment_panel_cancel;
+extern Fl_Light_Button *comment_in_source;
+extern Fl_Light_Button *comment_in_header;
+#include <FL/Fl_Menu_Button.H>
+extern Fl_Menu_Button *comment_predefined;
+extern Fl_Button *comment_load;
+Fl_Double_Window* make_comment_panel();
+void type_make_cb(Fl_Widget*w,void*d);
+#include <FL/Fl_Window.H>
+extern Fl_Window *widgetbin_panel;
+extern void type_make_cb(Fl_Button*, void*);
+Fl_Window* make_widgetbin();
+extern void toggle_sourceview_cb(Fl_Double_Window*, void*);
+extern Fl_Double_Window *sourceview_panel;
+#include <FL/Fl_Tabs.H>
+extern void update_sourceview_position_cb(Fl_Tabs*, void*);
+extern Fl_Tabs *sv_tab;
+extern CodeEditor *sv_source;
+extern CodeEditor *sv_header;
+extern void update_sourceview_cb(Fl_Button*, void*);
+extern Fl_Light_Button *sv_autorefresh;
+extern Fl_Light_Button *sv_autoposition;
+extern void toggle_sourceview_b_cb(Fl_Button*, void*);
+Fl_Double_Window* make_sourceview();
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/icons/fluid-128.png b/Utilities/FLTK/fluid/icons/fluid-128.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf9cf406e17201dbf7ea5edef85fb910e248f539
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-128.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-16.png b/Utilities/FLTK/fluid/icons/fluid-16.png
new file mode 100644
index 0000000000000000000000000000000000000000..5a50222d456bcd18c59f444cea7ee4bbd8d990ba
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-16.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-16i.png b/Utilities/FLTK/fluid/icons/fluid-16i.png
new file mode 100644
index 0000000000000000000000000000000000000000..10e0dfa30699558bad8657df8ac109699da3a5e1
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-16i.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-256.png b/Utilities/FLTK/fluid/icons/fluid-256.png
new file mode 100644
index 0000000000000000000000000000000000000000..33681a74e3b5466a0ea75f7db75f30ba6eed2c59
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-256.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-32.png b/Utilities/FLTK/fluid/icons/fluid-32.png
new file mode 100644
index 0000000000000000000000000000000000000000..38efb2ea25054186cac20a089f7daac63feb7cac
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-32.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-32.xpm b/Utilities/FLTK/fluid/icons/fluid-32.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..4b9ba19a9f816879099e4c576e0be1e996d67412
--- /dev/null
+++ b/Utilities/FLTK/fluid/icons/fluid-32.xpm
@@ -0,0 +1,67 @@
+/* XPM */
+static char * fluid_32_xpm[] = {
+"32 32 32 1",
+" 	c None",
+".	c #000200",
+"+	c #01162D",
+"@	c #01356A",
+"#	c #2F312E",
+"$	c #035FB1",
+"%	c #0061C0",
+"&	c #0071E1",
+"*	c #007FFF",
+"=	c #247ABD",
+"-	c #626E6F",
+";	c #777976",
+">	c #2A90E9",
+",	c #3291D2",
+"'	c #2690FC",
+")	c #449EAD",
+"!	c #5A9D87",
+"~	c #70AD78",
+"{	c #7EA3C4",
+"]	c #87B556",
+"^	c #6EB8FF",
+"/	c #A8ABA9",
+"(	c #A2C443",
+"_	c #8BC3F9",
+":	c #BED831",
+"<	c #CDDF1B",
+"[	c #CACDCB",
+"}	c #ACD7FF",
+"|	c #ECF408",
+"1	c #E5E7E4",
+"2	c #DDEDFD",
+"3	c #FCFFFC",
+"                                ",
+"             .......            ",
+"            .-//[//.            ",
+"            ./^^333.            ",
+"            .{''231.            ",
+"            .[^^331.            ",
+"            .[33331.            ",
+"            .[33331.            ",
+"            .[33^'_.            ",
+"            .[33^',.            ",
+"            .[332}2.            ",
+"            .133331.            ",
+"            .133331.            ",
+"           .-333333;.           ",
+"          .#1332_333#.          ",
+"          .[333''^333.          ",
+"         ./3333>'}333/.         ",
+"        .-333333232_}3;.        ",
+"       .#132}23333_'>33#.       ",
+"       .[33^'^33332>^331.       ",
+"      .$'''*'*''''''''''$.      ",
+"     .@*')>{******,***>)&@.     ",
+"    .+&':~(:&*****:)**)|&*+.    ",
+"    .%*!:&~(&,'>'*>**,~(**&.    ",
+"   .$*':]>:!!|&|=~<&]~<!&**$.   ",
+"  .@***:-'|%~()<&]])<%|=****@.  ",
+" .+***'|%):=(!(]>:!(]!:%*****+. ",
+" .&***):&!:=<]((&|!~:]<=*****&. ",
+".$&**)~!**&**&&&*&&*&*&*******$.",
+".%***]~%*****************'****%.",
+".@%%%%%%%%%%%%%%%%%%%%%$%%%$%%@.",
+" .............................. "};
diff --git a/Utilities/FLTK/fluid/icons/fluid-32i.png b/Utilities/FLTK/fluid/icons/fluid-32i.png
new file mode 100644
index 0000000000000000000000000000000000000000..d7581d8c82a9b6a6ba6b6e110481f3f6d0af6eb7
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-32i.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-48.png b/Utilities/FLTK/fluid/icons/fluid-48.png
new file mode 100644
index 0000000000000000000000000000000000000000..0aab52c6369adfd41c2e93e07deb2c68d7cca80c
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-48.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-64.png b/Utilities/FLTK/fluid/icons/fluid-64.png
new file mode 100644
index 0000000000000000000000000000000000000000..9157ccaa9f2741b7ce4b98cd5559392e0c23c71f
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid-64.png differ
diff --git a/Utilities/FLTK/fluid/icons/fluid-96.xpm b/Utilities/FLTK/fluid/icons/fluid-96.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..5c018aa12aaa61dfc65a15aee5d1d35a52713dc3
--- /dev/null
+++ b/Utilities/FLTK/fluid/icons/fluid-96.xpm
@@ -0,0 +1,131 @@
+/* XPM */
+static char * fluid_96_xpm[] = {
+"96 96 32 1",
+" 	c None",
+".	c #000100",
+"+	c #031F3F",
+"@	c #00366C",
+"#	c #2E302D",
+"$	c #0058AC",
+"%	c #0060BF",
+"&	c #4E504D",
+"*	c #14659F",
+"=	c #006DDC",
+"-	c #2C7087",
+";	c #0080FF",
+">	c #407B74",
+",	c #0F85F9",
+"'	c #268CCD",
+")	c #7C7E7B",
+"!	c #2D92EC",
+"~	c #4498A9",
+"{	c #2F94FE",
+"]	c #5BA18C",
+"^	c #6BA674",
+"/	c #7DAD62",
+"(	c #93BD53",
+"_	c #A4A6A2",
+":	c #6CB6FF",
+"<	c #ABCC3F",
+"[	c #C4DA2A",
+"}	c #CACCC9",
+"|	c #DCE913",
+"1	c #BBDEFF",
+"2	c #FDFE00",
+"3	c #FDFFFC",
+"                                                                                                ",
+"                                                                                                ",
+"                                                                                                ",
+"                                           ...........                                          ",
+"                                     ......................                                     ",
+"                                    ........................                                    ",
+"                                    ........#&#&#&#&##......                                    ",
+"                                    ....)__}33333333333}_...                                    ",
+"                                    ...&33333333333333333...                                    ",
+"                                    ...#33311133333333333...                                    ",
+"                                    ...&33!,{,;:333333333...                                    ",
+"                                    ...&3:,{{{{,13333333}...                                    ",
+"                                    ...&3!{{!{{,13333333}...                                    ",
+"                                    ...&3:!{{!{;13333333}...                                    ",
+"                                    ...&3{{{{{{;133333333...                                    ",
+"                                    ...&31,{{{;,33333333}...                                    ",
+"                                    ...&331{{{:133333333}...                                    ",
+"                                    ...&3333333333333333_...                                    ",
+"                                    ...&3333333333333333}...                                    ",
+"                                    ...&3333333333333333_...                                    ",
+"                                    ...&3333333333333333}...                                    ",
+"                                    ...&3333333333333333_...                                    ",
+"                                    ...&3333333333333333}...                                    ",
+"                                    ...&3333333333333333_...                                    ",
+"                                    ...&3333333331!,,;:3}...                                    ",
+"                                    ...&333333333{{{{{;:_...                                    ",
+"                                    ...&333333331,{!{!{{}...                                    ",
+"                                    ...&333333331{{{{{{,_...                                    ",
+"                                    ...)333333331{{!{{{{_...                                    ",
+"                                    ...)333333333{{{!{;:_...                                    ",
+"                                    ...)3333333331{;;;:3_...                                    ",
+"                                    ...)3333333333331333_...                                    ",
+"                                    ...)3333333333333333_...                                    ",
+"                                    ...)3333333333333333_...                                    ",
+"                                    ..._3333333333333333_...                                    ",
+"                                    ..._3333333333333333_...                                    ",
+"                                    ..._3333333333333333_...                                    ",
+"                                    ..._3333333333333333}....                                   ",
+"                                   ...._33333333333333333#...                                   ",
+"                                  ....&333333333333333333_....                                  ",
+"                                 ....&33333333333333333333)....                                 ",
+"                                 ....333333333333333333333}&....                                ",
+"                                ...._33333333333333333333333....                                ",
+"                               ....&333333333331:11333333333_....                               ",
+"                              ....#33333333333:,,,;:333333333&....                              ",
+"                              ....}3333333333:,!{{{;1333333333&....                             ",
+"                             ....}33333333333{{{!{{,!3333333333....                             ",
+"                            ....)333333333333{{{{!{{{3333333333_....                            ",
+"                           ....#3333333333333!{{{{{,:33333333333&....                           ",
+"                           ...._33333333333331{{!{,;1333333333333#....                          ",
+"                          ...._333333333333333:;,;,13333333333333_....                          ",
+"                         ...._333333333333333333113333333333333333_....                         ",
+"                        ....&33333333333333333333333333331::1333333&....                        ",
+"                        ...._333333333333333333333333333{,{{;{133333#...                        ",
+"                       ...._3333333333333333333333333331,{!{{,:33333}....                       ",
+"                      ....&3333333333133333333333333333:{{{{{{:333333)....                      ",
+"                      ...#333333331{,,;:333333333333333:{!{!{{:3333333&....                     ",
+"                     ....}33333333,{{{{;:333333333333331,{!{{;:33333333#...                     ",
+"                    ...._333333331,!{!{{,333333333333333{,{{;{1333333333....                    ",
+"                   ....&3333333331{{{{{{{3333333333333333::::33333333333)....                   ",
+"                  ....+!:::::::::{{{{!{{;::::::::::::::::::::::::::!:::::+....                  ",
+"                  ...+=;;;;;;;;;;;;{{{{;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;=....                  ",
+"                 ....%;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%....                 ",
+"                ....@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;$....                ",
+"                ...+%;;;;;;!!!;;;;;,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!=;;;+....               ",
+"               ....%;;;;;!([<|^~]^([%;;;;;;;;;;;;;;;;;,(<'=;;;;;;;!^/<[|'=;;=+...               ",
+"              ....$;;;;;'|2>]22<|22[%=;;;;;;;;;;;;;;;;^22[%=;;;;;;!][22|%=;;;$....              ",
+"             ....@;;;;;;[2[%^2|*[22(%=;;;;;;;;;;;;;;;,/22|$=;;;;;;;;<22<%=;;;;$....             ",
+"            ....+=;;;;;~22^$%]~$|22>%=;;;;;;;;;;;;;;;;'||^%=;;;;;;;,[22^$=;;;;;+....            ",
+"            ....%;;;;;,[22-%==='22|*==;;;;;;;;;;;;;;;;;;=%=;;;;;;;;'22|*%=;;;;;=+...            ",
+"           ....$;;;;;;!22|$%;,;^22<$=;;;;;;;;;;;;;;;;;;===;;;;;;;;;^22|$==;;;;;;%....           ",
+"          ....@;;;;;'](22[^]=;;<22^$==!~]/~=;!]]~;;;;{'~]==;;;;~<<]<22($=;;;;;;;;@....          ",
+"         ....@;;;;;;]<|22|[<%;!|22-%'[2222*=;/22(%;~|222(=;;;!<2|^[222>$=;;;;;;;;;+....         ",
+"         ....=;;;;;;;,[22>$===~22|$==,[22[%=;[22]%=,!|22]%=;![2|*%]22|*==;;;;;;;;;%+...         ",
+"        ....@;;;;;;;;!|22*$=;;/22($=;,[22/$='222*%=;!|22-%;;<22>%=]22[$%;;;;;;;;;;;=....        ",
+"       ....@;;;;;;;;;~22[*==;;[22>%=;'22|-%,^22[$=;,~22[$%;]22<$%=(22/$=;;;;;;;;;;;;@....       ",
+"      ....+;;;;;;;;;;^22<$=;;!222*$=;]22[$==[22/$=;;(22/$=![22]$=;|22-%=;;;;;;;;;;;;;+...       ",
+"      ....;;;;;;;;;;;<22^%=;;]22[$=;;(22/$=~222-%=;;[22>%=]22|$%;~22|$==;;;;;;;;;;;;;;....      ",
+"     ....%;;;;;;;;;;;|22-%=;;(22/$=;{|22-%=<22|$%;;'22|*%;<22<$==(22<$=;=;;;;;;;;;;;;;$....     ",
+"    ....+;;;;;;;;;;;!222$==;,|22>%=;~22|$=]|22($=;;]22[$%,|22^%=!|22^$=;;;;;;;;;;;;;;;;@....    ",
+"   ....+=;;;;;;;;;;;~22[$%;;'22|*-/;]22($*[<22^$^=;(22/$(-222>$=(222->~;;;;;;;;;;;;;;;;=+....   ",
+"   ...+;;;;;;;;;;;;;(22/$=;;]22|*<'=(22/*[~[22>(]=;|22>//=|22/$^(|2|-[%=;;;;;;;;;;;;;;;;=....   ",
+"  ....$;;;;;;;;;;;;;<22>%=;;]222|>==(222|^=|22|<%=;|222<%=(222|<-222|-==;;;;;;;;;;;;;;;;;$....  ",
+" ....@;;;;;;;;;;;;;!|2|$=;;;'[2[>%=;'|2[]%=/2|/$==;^2|(*%=!(2|($%<2[-%=;;;;;;;;;;;;;;;;;;;@.... ",
+"....@;;;;;;;;;;;;;;'22($%;;;;=%%==;;;=%%%==;=%%==;;;=%===;;==%%====%%=,;;;;;;;;;;;;;;;;;;;;+... ",
+"...+=;;;;;;;;;;!'=,]22-%=;;;;;;==;=;;;===;=;;===;;;;;===;;;;=;=,;;,=;=;;;;;;;;;;;;;;;;;;;;;=....",
+"...+;;;;;;;;;;;[2^=<2<$==;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+...",
+"...+;;;;;;;;;;;22('2|*%=;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+...",
+"...+;;;;;;;;;;;^|<[[-%=;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+...",
+"...+;;;;;;;;;;;;*~*%===;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@...",
+"...+;;;;;;;;;;;;;====;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+...",
+"....$=;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;=$....",
+" .....++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++..... ",
+" .............................................................................................  ",
+"  ............................................................................................  ",
+"     ......................................................................................     "};
diff --git a/Utilities/FLTK/fluid/icons/fluid.ico b/Utilities/FLTK/fluid/icons/fluid.ico
new file mode 100644
index 0000000000000000000000000000000000000000..aee6b18e16144ef80b099cd14d374b10252f56eb
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid.ico differ
diff --git a/Utilities/FLTK/fluid/icons/fluid.xcf.gz b/Utilities/FLTK/fluid/icons/fluid.xcf.gz
new file mode 100644
index 0000000000000000000000000000000000000000..13a7c93006f806461dd5f056695230ed2e5ebb63
Binary files /dev/null and b/Utilities/FLTK/fluid/icons/fluid.xcf.gz differ
diff --git a/Utilities/FLTK/fluid/makedepend b/Utilities/FLTK/fluid/makedepend
new file mode 100644
index 0000000000000000000000000000000000000000..86b86c162bfb5befd59f3b1abfc9d98ba0907a82
--- /dev/null
+++ b/Utilities/FLTK/fluid/makedepend
@@ -0,0 +1,327 @@
+# DO NOT DELETE
+
+CodeEditor.o: CodeEditor.h ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+CodeEditor.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Editor.H
+CodeEditor.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H ../FL/Fl_Group.H
+CodeEditor.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+CodeEditor.o: ../FL/Fl_Valuator.H ../FL/Fl_Text_Buffer.H
+Fl_Function_Type.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Function_Type.o: ../FL/Fl_Preferences.H ../FL/Fl_File_Chooser.H
+Fl_Function_Type.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+Fl_Function_Type.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Group.H
+Fl_Function_Type.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_.H ../FL/Fl_Menu_Item.H
+Fl_Function_Type.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H
+Fl_Function_Type.o: ../FL/Fl_Tile.H ../FL/Fl_File_Browser.H
+Fl_Function_Type.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H
+Fl_Function_Type.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+Fl_Function_Type.o: ../FL/Fl_Valuator.H ../FL/Fl_File_Icon.H ../FL/Fl.H
+Fl_Function_Type.o: ../FL/filename.H ../FL/Fl_Box.H ../FL/Fl_Check_Button.H
+Fl_Function_Type.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
+Fl_Function_Type.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+Fl_Function_Type.o: ../FL/Fl_Return_Button.H ../FL/fl_ask.H Fl_Type.h
+Fl_Function_Type.o: ../FL/Fl_Widget.H ../FL/Fl_Menu.H Fluid_Image.h
+Fl_Function_Type.o: ../FL/Fl_Shared_Image.H ../FL/fl_draw.H ../FL/Fl_Tabs.H
+Fl_Function_Type.o: ../FL/Fl_Pack.H ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H
+Fl_Function_Type.o: ../FL/Fl_Input_Choice.H ../FL/Fl_Window.H
+Fl_Function_Type.o: ../FL/Fl_Menu_Bar.H ../FL/fl_show_input.H ../FL/fl_ask.H
+Fl_Function_Type.o: ../src/flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Function_Type.o: function_panel.h ../FL/Fl_Light_Button.H CodeEditor.h
+Fl_Function_Type.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Editor.H
+Fl_Function_Type.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H
+Fl_Function_Type.o: ../FL/Fl_Text_Buffer.H comments.h
+Fl_Group_Type.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Group_Type.o: ../FL/Fl_Group.H ../FL/fl_message.H ../FL/fl_ask.H
+Fl_Group_Type.o: Fl_Widget_Type.h Fl_Type.h ../FL/Fl_Widget.H ../FL/Fl_Menu.H
+Fl_Group_Type.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H
+Fl_Group_Type.o: Fluid_Image.h ../FL/Fl_Shared_Image.H ../FL/fl_draw.H
+Fl_Group_Type.o: ../FL/Fl_Tabs.H ../FL/Fl_Group.H ../FL/Fl_Pack.H
+Fl_Group_Type.o: ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H ../FL/Fl_Menu_Button.H
+Fl_Group_Type.o: ../FL/Fl_Menu_.H ../FL/Fl_Choice.H ../FL/Fl_Input_Choice.H
+Fl_Group_Type.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Window.H
+Fl_Group_Type.o: ../FL/Fl_Menu_Bar.H ../src/flstring.h ../FL/Fl_Export.H
+Fl_Group_Type.o: ../config.h ../FL/Fl_Scroll.H ../FL/Fl_Scrollbar.H
+Fl_Group_Type.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Menu_Type.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Menu_Type.o: Fl_Widget_Type.h Fl_Type.h ../FL/Fl_Widget.H ../FL/Fl_Menu.H
+Fl_Menu_Type.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H
+Fl_Menu_Type.o: Fluid_Image.h ../FL/Fl_Shared_Image.H ../FL/fl_draw.H
+Fl_Menu_Type.o: ../FL/Fl_Tabs.H ../FL/Fl_Group.H ../FL/Fl_Pack.H
+Fl_Menu_Type.o: ../FL/Fl_Group.H ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H
+Fl_Menu_Type.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H ../FL/Fl_Choice.H
+Fl_Menu_Type.o: ../FL/Fl_Input_Choice.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+Fl_Menu_Type.o: ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H alignment_panel.h
+Fl_Menu_Type.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Display.H
+Fl_Menu_Type.o: ../FL/fl_draw.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+Fl_Menu_Type.o: ../FL/Fl_Valuator.H ../FL/Fl_Text_Buffer.H
+Fl_Menu_Type.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+Fl_Menu_Type.o: ../FL/Fl_Preferences.H ../FL/Fl_Tooltip.H ../FL/Fl_Button.H
+Fl_Menu_Type.o: ../FL/Fl_Box.H ../FL/Fl_Light_Button.H
+Fl_Menu_Type.o: ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H
+Fl_Menu_Type.o: ../FL/Fl_Button.H ../FL/Fl_Spinner.H ../FL/Fl_Repeat_Button.H
+Fl_Menu_Type.o: ../FL/Fl.H ../FL/Fl_Return_Button.H ../FL/Fl_Round_Button.H
+Fl_Menu_Type.o: ../FL/fl_message.H ../FL/fl_ask.H ../src/flstring.h
+Fl_Menu_Type.o: ../FL/Fl_Export.H ../config.h ../FL/Fl_Output.H
+Fl_Menu_Type.o: ../FL/Fl_Input.H Shortcut_Button.h
+Fl_Type.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Type.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Type.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Type.o: ../FL/fl_draw.H ../src/flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Type.o: Fl_Type.h ../FL/Fl_Widget.H ../FL/Fl_Menu.H ../FL/Fl_Menu_Item.H
+Fl_Type.o: ../FL/Fl_Image.H Fluid_Image.h ../FL/Fl_Shared_Image.H
+Fl_Type.o: ../FL/Fl_Tabs.H ../FL/Fl_Pack.H ../FL/Fl_Group.H ../FL/Fl_Wizard.H
+Fl_Type.o: ../FL/Fl_Menu_.H ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H
+Fl_Type.o: ../FL/Fl_Choice.H ../FL/Fl_Input_Choice.H ../FL/Fl_Input.H
+Fl_Type.o: ../FL/Fl_Input_.H ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H undo.h
+Fl_Type.o: ../FL/Fl_Pixmap.H pixmaps/lock.xpm pixmaps/flWindow.xpm
+Fl_Type.o: pixmaps/flButton.xpm pixmaps/flCheckButton.xpm
+Fl_Type.o: pixmaps/flRoundButton.xpm pixmaps/flBox.xpm pixmaps/flGroup.xpm
+Fl_Type.o: pixmaps/flFunction.xpm pixmaps/flCode.xpm pixmaps/flCodeBlock.xpm
+Fl_Type.o: pixmaps/flComment.xpm pixmaps/flDeclaration.xpm
+Fl_Type.o: pixmaps/flDeclarationBlock.xpm pixmaps/flClass.xpm
+Fl_Type.o: pixmaps/flTabs.xpm pixmaps/flInput.xpm pixmaps/flChoice.xpm
+Fl_Type.o: pixmaps/flMenuitem.xpm pixmaps/flMenubar.xpm pixmaps/flSubmenu.xpm
+Fl_Type.o: pixmaps/flScroll.xpm pixmaps/flTile.xpm pixmaps/flWizard.xpm
+Fl_Type.o: pixmaps/flPack.xpm pixmaps/flReturnButton.xpm
+Fl_Type.o: pixmaps/flLightButton.xpm pixmaps/flRepeatButton.xpm
+Fl_Type.o: pixmaps/flMenuButton.xpm pixmaps/flOutput.xpm
+Fl_Type.o: pixmaps/flTextDisplay.xpm pixmaps/flTextEdit.xpm
+Fl_Type.o: pixmaps/flFileInput.xpm pixmaps/flBrowser.xpm
+Fl_Type.o: pixmaps/flCheckBrowser.xpm pixmaps/flFileBrowser.xpm
+Fl_Type.o: pixmaps/flClock.xpm pixmaps/flHelp.xpm pixmaps/flProgress.xpm
+Fl_Type.o: pixmaps/flSlider.xpm pixmaps/flScrollBar.xpm
+Fl_Type.o: pixmaps/flValueSlider.xpm pixmaps/flAdjuster.xpm
+Fl_Type.o: pixmaps/flCounter.xpm pixmaps/flDial.xpm pixmaps/flRoller.xpm
+Fl_Type.o: pixmaps/flValueInput.xpm pixmaps/flValueOutput.xpm
+Fl_Type.o: pixmaps/flSpinner.xpm pixmaps/flWidgetClass.xpm
+Fl_Widget_Type.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Widget_Type.o: ../FL/Fl_Group.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+Fl_Widget_Type.o: Fl_Widget_Type.h Fl_Type.h ../FL/Fl_Widget.H
+Fl_Widget_Type.o: ../FL/Fl_Menu.H ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H
+Fl_Widget_Type.o: ../FL/Fl_Image.H Fluid_Image.h ../FL/Fl_Shared_Image.H
+Fl_Widget_Type.o: ../FL/fl_draw.H ../FL/Fl_Tabs.H ../FL/Fl_Group.H
+Fl_Widget_Type.o: ../FL/Fl_Pack.H ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H
+Fl_Widget_Type.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H ../FL/Fl_Choice.H
+Fl_Widget_Type.o: ../FL/Fl_Input_Choice.H ../FL/Fl_Window.H
+Fl_Widget_Type.o: ../FL/Fl_Menu_Bar.H alignment_panel.h
+Fl_Widget_Type.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Display.H
+Fl_Widget_Type.o: ../FL/fl_draw.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+Fl_Widget_Type.o: ../FL/Fl_Valuator.H ../FL/Fl_Text_Buffer.H
+Fl_Widget_Type.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+Fl_Widget_Type.o: ../FL/Fl_Preferences.H ../FL/Fl_Tooltip.H ../FL/Fl_Button.H
+Fl_Widget_Type.o: ../FL/Fl_Box.H ../FL/Fl_Light_Button.H
+Fl_Widget_Type.o: ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H
+Fl_Widget_Type.o: ../FL/Fl_Button.H ../FL/Fl_Spinner.H
+Fl_Widget_Type.o: ../FL/Fl_Repeat_Button.H ../FL/Fl.H
+Fl_Widget_Type.o: ../FL/Fl_Return_Button.H ../FL/Fl_Round_Button.H
+Fl_Widget_Type.o: ../FL/fl_message.H ../FL/fl_ask.H ../FL/Fl_Slider.H
+Fl_Widget_Type.o: ../src/flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Widget_Type.o: widget_panel.h ../FL/Fl_Value_Input.H ../FL/Fl_Input.H
+Fl_Widget_Type.o: Shortcut_Button.h CodeEditor.h ../FL/Fl_Text_Editor.H
+Fl_Widget_Type.o: ../FL/Fl_Text_Display.H ../FL/fl_show_colormap.H
+Fl_Window_Type.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fl_Window_Type.o: ../FL/Fl_Overlay_Window.H ../FL/Fl_Double_Window.H
+Fl_Window_Type.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Window_Type.o: ../FL/fl_message.H ../FL/fl_ask.H ../FL/fl_draw.H ../FL/x.H
+Fl_Window_Type.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
+Fl_Window_Type.o: ../FL/Fl_Round_Button.H ../FL/Fl_Light_Button.H
+Fl_Window_Type.o: ../FL/Fl_Button.H Fl_Widget_Type.h Fl_Type.h
+Fl_Window_Type.o: ../FL/Fl_Widget.H ../FL/Fl_Menu.H ../FL/Fl_Menu_Item.H
+Fl_Window_Type.o: Fluid_Image.h ../FL/Fl_Shared_Image.H ../FL/Fl_Tabs.H
+Fl_Window_Type.o: ../FL/Fl_Pack.H ../FL/Fl_Group.H ../FL/Fl_Wizard.H
+Fl_Window_Type.o: ../FL/Fl_Menu_.H ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H
+Fl_Window_Type.o: ../FL/Fl_Choice.H ../FL/Fl_Input_Choice.H ../FL/Fl_Input.H
+Fl_Window_Type.o: ../FL/Fl_Input_.H ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H
+Fl_Window_Type.o: undo.h alignment_panel.h ../FL/Fl_Text_Buffer.H
+Fl_Window_Type.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H
+Fl_Window_Type.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Window_Type.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Double_Window.H
+Fl_Window_Type.o: ../FL/Fl_Preferences.H ../FL/Fl_Tooltip.H ../FL/Fl_Button.H
+Fl_Window_Type.o: ../FL/Fl_Box.H ../FL/Fl_Light_Button.H
+Fl_Window_Type.o: ../FL/Fl_Check_Button.H ../FL/Fl_Spinner.H
+Fl_Window_Type.o: ../FL/Fl_Repeat_Button.H ../FL/Fl.H
+Fl_Window_Type.o: ../FL/Fl_Return_Button.H widget_panel.h
+Fl_Window_Type.o: ../FL/Fl_Value_Input.H ../FL/Fl_Input.H Shortcut_Button.h
+Fl_Window_Type.o: CodeEditor.h ../FL/Fl_Text_Editor.H ../FL/Fl_Text_Display.H
+Fl_Window_Type.o: ../src/flstring.h ../FL/Fl_Export.H ../config.h
+Fluid_Image.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+Fluid_Image.o: ../FL/Fl_Widget.H Fl_Type.h ../FL/Fl_Menu.H
+Fluid_Image.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H
+Fluid_Image.o: Fluid_Image.h ../FL/Fl_Shared_Image.H ../FL/fl_draw.H
+Fluid_Image.o: ../FL/Fl_Tabs.H ../FL/Fl_Group.H ../FL/Fl_Pack.H
+Fluid_Image.o: ../FL/Fl_Group.H ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H
+Fluid_Image.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H ../FL/Fl_Choice.H
+Fluid_Image.o: ../FL/Fl_Input_Choice.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+Fluid_Image.o: ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H ../src/flstring.h
+Fluid_Image.o: ../FL/Fl_Export.H ../config.h ../FL/filename.H
+Fluid_Image.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H
+Fluid_Image.o: ../FL/Fl_Window.H ../FL/Fl_Button.H ../FL/Fl_Preferences.H
+Fluid_Image.o: ../FL/Fl_Tile.H ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H
+Fluid_Image.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+Fluid_Image.o: ../FL/Fl_Valuator.H ../FL/Fl_File_Icon.H ../FL/Fl.H
+Fluid_Image.o: ../FL/filename.H ../FL/Fl_Box.H ../FL/Fl_Check_Button.H
+Fluid_Image.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
+Fluid_Image.o: ../FL/Fl_File_Input.H ../FL/Fl_Return_Button.H ../FL/fl_ask.H
+about_panel.o: about_panel.h ../FL/Fl.H ../FL/Enumerations.H
+about_panel.o: ../FL/Fl_Export.H ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+about_panel.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Box.H
+about_panel.o: ../FL/Fl_Button.H ../FL/Fl_Return_Button.H ../FL/Fl_Button.H
+about_panel.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H
+align_widget.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+align_widget.o: ../FL/Fl_Window.H Fl_Widget_Type.h Fl_Type.h
+align_widget.o: ../FL/Fl_Widget.H ../FL/Fl_Menu.H ../FL/Fl_Menu_Item.H
+align_widget.o: ../FL/Fl_Widget.H ../FL/Fl_Image.H Fluid_Image.h
+align_widget.o: ../FL/Fl_Shared_Image.H ../FL/fl_draw.H ../FL/Fl_Tabs.H
+align_widget.o: ../FL/Fl_Group.H ../FL/Fl_Pack.H ../FL/Fl_Group.H
+align_widget.o: ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H ../FL/Fl_Menu_Button.H
+align_widget.o: ../FL/Fl_Menu_.H ../FL/Fl_Choice.H ../FL/Fl_Input_Choice.H
+align_widget.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Menu_Bar.H undo.h
+alignment_panel.o: alignment_panel.h ../FL/Fl.H ../FL/Enumerations.H
+alignment_panel.o: ../FL/Fl_Export.H ../FL/Fl_Text_Buffer.H
+alignment_panel.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H ../FL/Fl_Group.H
+alignment_panel.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+alignment_panel.o: ../FL/Fl_Valuator.H ../FL/Fl_Text_Buffer.H
+alignment_panel.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+alignment_panel.o: ../FL/Fl_Preferences.H ../FL/Fl_Tooltip.H
+alignment_panel.o: ../FL/Fl_Widget.H ../FL/Fl_Button.H ../FL/Fl_Tabs.H
+alignment_panel.o: ../FL/Fl_Group.H ../FL/Fl_Box.H ../FL/Fl_Input.H
+alignment_panel.o: ../FL/Fl_Input_.H ../FL/Fl_Light_Button.H
+alignment_panel.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_.H ../FL/Fl_Menu_Item.H
+alignment_panel.o: ../FL/Fl_Image.H ../FL/Fl_Check_Button.H
+alignment_panel.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
+alignment_panel.o: ../FL/Fl_Spinner.H ../FL/Fl_Repeat_Button.H ../FL/Fl.H
+alignment_panel.o: ../FL/Fl_Return_Button.H ../FL/Fl_Round_Button.H
+code.o: ../src/flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H
+code.o: ../FL/Enumerations.H ../FL/Fl_Export.H Fl_Type.h ../FL/Fl_Widget.H
+code.o: ../FL/Fl_Menu.H ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H
+code.o: ../FL/Fl_Image.H Fluid_Image.h ../FL/Fl_Shared_Image.H
+code.o: ../FL/fl_draw.H ../FL/Fl_Tabs.H ../FL/Fl_Group.H ../FL/Fl_Pack.H
+code.o: ../FL/Fl_Group.H ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H
+code.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H ../FL/Fl_Choice.H
+code.o: ../FL/Fl_Input_Choice.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+code.o: ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H alignment_panel.h
+code.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Display.H ../FL/fl_draw.H
+code.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+code.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+code.o: ../FL/Fl_Preferences.H ../FL/Fl_Tooltip.H ../FL/Fl_Button.H
+code.o: ../FL/Fl_Box.H ../FL/Fl_Light_Button.H ../FL/Fl_Check_Button.H
+code.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H ../FL/Fl_Spinner.H
+code.o: ../FL/Fl_Repeat_Button.H ../FL/Fl.H ../FL/Fl_Return_Button.H
+code.o: ../FL/Fl_Round_Button.H ../FL/filename.H
+factory.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/Fl_Group.H
+factory.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H
+factory.o: ../FL/Fl_Pixmap.H ../src/flstring.h ../FL/Fl_Export.H ../config.h
+factory.o: undo.h Fl_Widget_Type.h Fl_Type.h ../FL/Fl_Widget.H
+factory.o: ../FL/Fl_Menu.H ../FL/Fl_Menu_Item.H Fluid_Image.h
+factory.o: ../FL/Fl_Shared_Image.H ../FL/fl_draw.H ../FL/Fl_Tabs.H
+factory.o: ../FL/Fl_Group.H ../FL/Fl_Pack.H ../FL/Fl_Wizard.H
+factory.o: ../FL/Fl_Menu_.H ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H
+factory.o: ../FL/Fl_Choice.H ../FL/Fl_Input_Choice.H ../FL/Fl_Input.H
+factory.o: ../FL/Fl_Input_.H ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H
+factory.o: ../FL/Fl_Box.H ../FL/Fl_Button.H ../FL/Fl_Return_Button.H
+factory.o: ../FL/Fl_Button.H ../FL/Fl_Repeat_Button.H ../FL/Fl.H
+factory.o: ../FL/Fl_Light_Button.H ../FL/Fl_Check_Button.H
+factory.o: ../FL/Fl_Light_Button.H ../FL/Fl_Round_Button.H ../FL/Fl_Browser.H
+factory.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+factory.o: ../FL/Fl_Valuator.H ../FL/Fl_Check_Browser.H
+factory.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H ../FL/Fl_File_Icon.H
+factory.o: ../FL/filename.H ../FL/Fl_Counter.H ../FL/Fl_Spinner.H
+factory.o: ../FL/Fl_File_Input.H ../FL/Fl_Text_Display.H ../FL/fl_draw.H
+factory.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Editor.H
+factory.o: ../FL/Fl_Text_Display.H ../FL/Fl_Clock.H ../FL/Fl_Help_View.H
+factory.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Progress.H ../FL/Fl_Adjuster.H
+factory.o: ../FL/Fl_Dial.H ../FL/Fl_Roller.H ../FL/Fl_Scrollbar.H
+factory.o: ../FL/Fl_Output.H ../FL/Fl_Input.H ../FL/Fl_Value_Input.H
+factory.o: ../FL/Fl_Value_Output.H ../FL/Fl_Value_Slider.H
+factory.o: ../FL/Fl_Multi_Label.H
+file.o: ../src/flstring.h ../FL/Fl_Export.H ../config.h alignment_panel.h
+file.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+file.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Display.H ../FL/fl_draw.H
+file.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H
+file.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Text_Buffer.H
+file.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H ../FL/Fl_Preferences.H
+file.o: ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H ../FL/Fl_Button.H
+file.o: ../FL/Fl_Tabs.H ../FL/Fl_Group.H ../FL/Fl_Box.H ../FL/Fl_Input.H
+file.o: ../FL/Fl_Input_.H ../FL/Fl_Light_Button.H ../FL/Fl_Choice.H
+file.o: ../FL/Fl_Menu_.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
+file.o: ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
+file.o: ../FL/Fl_Spinner.H ../FL/Fl_Repeat_Button.H ../FL/Fl.H
+file.o: ../FL/Fl_Return_Button.H ../FL/Fl_Round_Button.H ../FL/fl_message.H
+file.o: ../FL/fl_ask.H Fl_Widget_Type.h Fl_Type.h ../FL/Fl_Menu.H
+file.o: Fluid_Image.h ../FL/Fl_Shared_Image.H ../FL/fl_draw.H ../FL/Fl_Pack.H
+file.o: ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H ../FL/Fl_Menu_Button.H
+file.o: ../FL/Fl_Input_Choice.H ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H
+fluid.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H
+fluid.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fluid.o: ../FL/Fl_Widget.H ../FL/Fl_Box.H ../FL/Fl_Button.H
+fluid.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/Fl_Help_Dialog.H
+fluid.o: ../FL/Fl_Help_View.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+fluid.o: ../FL/Fl_Valuator.H ../FL/fl_draw.H ../FL/Fl_Shared_Image.H
+fluid.o: ../FL/Fl_Group.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+fluid.o: ../FL/Fl_Hold_Browser.H ../FL/Fl_Browser.H ../FL/Fl_Browser_.H
+fluid.o: ../FL/Fl_Menu_Bar.H ../FL/Fl_Menu_.H ../FL/Fl_Menu_Item.H
+fluid.o: ../FL/Fl_Image.H ../FL/fl_ask.H ../FL/fl_draw.H
+fluid.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H
+fluid.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_File_Browser.H
+fluid.o: ../FL/Fl_File_Icon.H ../FL/filename.H ../FL/Fl_Check_Button.H
+fluid.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H ../FL/Fl_File_Input.H
+fluid.o: ../FL/Fl_Return_Button.H ../FL/fl_message.H ../FL/fl_ask.H
+fluid.o: ../FL/filename.H ../src/flstring.h ../FL/Fl_Export.H ../config.h
+fluid.o: alignment_panel.h ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Display.H
+fluid.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H
+fluid.o: ../FL/Fl_Tabs.H ../FL/Fl_Light_Button.H ../FL/Fl_Spinner.H
+fluid.o: ../FL/Fl_Repeat_Button.H ../FL/Fl_Round_Button.H function_panel.h
+fluid.o: CodeEditor.h ../FL/Fl_Text_Editor.H ../FL/Fl_Text_Display.H
+fluid.o: ../FL/Fl_Window.H template_panel.h ../FL/Fl_Browser.H
+fluid.o: print_panel.cxx print_panel.h ../FL/Fl_Progress.H ../FL/Fl_Pixmap.H
+fluid.o: about_panel.h undo.h Fl_Type.h ../FL/Fl_Menu.H Fluid_Image.h
+fluid.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Pack.H ../FL/Fl_Wizard.H
+fluid.o: ../FL/Fl_Menu_.H ../FL/Fl_Input_Choice.H
+function_panel.o: function_panel.h ../FL/Fl.H ../FL/Enumerations.H
+function_panel.o: ../FL/Fl_Export.H ../FL/Fl_Double_Window.H
+function_panel.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+function_panel.o: ../FL/Fl_Group.H ../FL/Fl_Light_Button.H ../FL/Fl_Box.H
+function_panel.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H
+function_panel.o: ../FL/Fl_Button.H ../FL/Fl_Button.H CodeEditor.h
+function_panel.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Editor.H
+function_panel.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H
+function_panel.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+function_panel.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Menu_Button.H
+function_panel.o: ../FL/Fl_Menu_.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
+function_panel.o: ../FL/Fl_Window.H ../FL/Fl_Tabs.H ../FL/Fl_Pixmap.H
+function_panel.o: Fl_Type.h ../FL/Fl_Widget.H ../FL/Fl_Menu.H Fluid_Image.h
+function_panel.o: ../FL/Fl_Shared_Image.H ../FL/fl_draw.H ../FL/Fl_Pack.H
+function_panel.o: ../FL/Fl_Wizard.H ../FL/Fl_Menu_.H ../FL/Fl_Choice.H
+function_panel.o: ../FL/Fl_Input_Choice.H ../FL/Fl_Menu_Bar.H undo.h
+template_panel.o: template_panel.h ../FL/Fl.H ../FL/Enumerations.H
+template_panel.o: ../FL/Fl_Export.H ../FL/Fl_Double_Window.H
+template_panel.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+template_panel.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
+template_panel.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Box.H
+template_panel.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Group.H
+template_panel.o: ../FL/Fl_Button.H ../FL/Fl_Return_Button.H
+template_panel.o: ../FL/Fl_Button.H ../src/flstring.h ../FL/Fl_Export.H
+template_panel.o: ../config.h ../FL/filename.H ../FL/fl_ask.H
+template_panel.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Image.H
+template_panel.o: ../FL/Fl_Preferences.H
+undo.o: ../FL/Fl.H ../FL/Enumerations.H ../FL/Fl_Export.H Fl_Type.h
+undo.o: ../FL/Fl_Widget.H ../FL/Fl_Menu.H ../FL/Fl_Menu_Item.H
+undo.o: ../FL/Fl_Widget.H ../FL/Fl_Image.H Fluid_Image.h
+undo.o: ../FL/Fl_Shared_Image.H ../FL/fl_draw.H ../FL/Fl_Tabs.H
+undo.o: ../FL/Fl_Group.H ../FL/Fl_Pack.H ../FL/Fl_Group.H ../FL/Fl_Wizard.H
+undo.o: ../FL/Fl_Menu_.H ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H
+undo.o: ../FL/Fl_Choice.H ../FL/Fl_Input_Choice.H ../FL/Fl_Input.H
+undo.o: ../FL/Fl_Input_.H ../FL/Fl_Window.H ../FL/Fl_Menu_Bar.H undo.h
+undo.o: ../FL/Fl_Preferences.H ../src/flstring.h ../FL/Fl_Export.H
+undo.o: ../config.h
+widget_panel.o: widget_panel.h ../FL/Fl.H ../FL/Enumerations.H
+widget_panel.o: ../FL/Fl_Export.H ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+widget_panel.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Tabs.H
+widget_panel.o: ../FL/Fl_Group.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+widget_panel.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_.H ../FL/Fl_Menu_Item.H
+widget_panel.o: ../FL/Fl_Image.H ../FL/Fl_Button.H ../FL/Fl_Box.H
+widget_panel.o: ../FL/Fl_Value_Input.H ../FL/Fl_Valuator.H ../FL/Fl_Input.H
+widget_panel.o: ../FL/Fl_Light_Button.H Shortcut_Button.h CodeEditor.h
+widget_panel.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Editor.H
+widget_panel.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H ../FL/Fl_Scrollbar.H
+widget_panel.o: ../FL/Fl_Slider.H ../FL/Fl_Text_Buffer.H
+widget_panel.o: ../FL/Fl_Return_Button.H ../FL/Fl_Button.H
diff --git a/Utilities/FLTK/fluid/makefile.wat b/Utilities/FLTK/fluid/makefile.wat
new file mode 100644
index 0000000000000000000000000000000000000000..8a1a5d9fc97330a9ebc9a0472a9ab5e8e5d2cede
--- /dev/null
+++ b/Utilities/FLTK/fluid/makefile.wat
@@ -0,0 +1,76 @@
+#
+# "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $"
+#
+# FLUID makefile for the Fast Light Tool Kit (FLTK).
+#
+# Copyright 1998-2004 by Bill Spitzak and others.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+OBJECTS = &
+    Fl_Function_Type.obj &
+    Fl_Menu_Type.obj &
+    Fl_Group_Type.obj &
+    Fl_Widget_Type.obj &
+    Fl_Type.obj &
+    Fl_Window_Type.obj &
+    Fluid_Image.obj &
+    code.obj &
+    factory.obj &
+    file.obj &
+    align_widget.obj &
+    about_panel.obj &
+    widget_panel.obj &
+    alignment_panel.obj &
+    function_panel.obj
+
+#   fluid.obj should not be in the list, because the watcom.mif file
+#   assumes an object file with the same name as the target executable
+
+################################################################
+
+!include ../watcom.mif
+
+all:  $(ODIR)/fluid$(EXEEXT)
+
+$(ODIR)\fluid$(EXEEXT): $(OBJECTS) $(LIBS)
+
+#
+# Clean all directories
+#
+clean : .SYMBOLIC
+    @echo Cleaning up.
+CLEANEXTS = exe map sym obj lk1
+    @for %a in ($(CLEANEXTS)) do -rm -f $(ODIR)\*.%a
+    -rm -f *.err
+
+#
+# Note: The rebuild target can only be used if you have the original .fl
+#       files.  This is normally only used by the FLTK maintainers...
+#
+
+rebuild:
+    ./fluid -c about_panel.fl
+    ./fluid -c alignment_panel.fl
+    ./fluid -c function_panel.fl
+    ./fluid -c widget_panel.fl
+
+#
+# End of "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $".
+#
diff --git a/Utilities/FLTK/fluid/pixmaps/.cvsignore b/Utilities/FLTK/fluid/pixmaps/.cvsignore
new file mode 100644
index 0000000000000000000000000000000000000000..3df5b205563156d7f1b575ced97f57572ddb42ef
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/.cvsignore
@@ -0,0 +1 @@
+*.bck
diff --git a/Utilities/FLTK/fluid/pixmaps/flAdjuster.xpm b/Utilities/FLTK/fluid/pixmaps/flAdjuster.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..12ae646b476a89bd8d0bb15e66d8f772117d5759
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flAdjuster.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flAdjuster_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #e0e0e0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"fffffffffffffffc",
+"fdddafdddafdddac",
+"fdddafdddafdddac",
+"fdddafdddafdddac",
+"fdddafdddafdddac",
+"fdddafdddafdddac",
+"fdddafdddafdddac",
+"aaaaaaaaaaaaaaac",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flBox.xpm b/Utilities/FLTK/fluid/pixmaps/flBox.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..881170c09dbb1642d133120cfd4796d8cdd86b2b
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flBox.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flBox_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #c0c0c0",
+"e c #909090",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dddddddddddddddc",
+"deeeeeeeeeeeeedc",
+"deeeeeeeeeeeeedc",
+"deeeeeeeeeeeeedc",
+"deeeeeeeeeeeeedc",
+"deeeeeeeeeeeeedc",
+"deeeeeeeeeeeeedc",
+"deeeeeeeeeeeeedc",
+"deeeeeeeeeeeeedc",
+"dddddddddddddddc",
+"dddddddddddddddc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flBrowser.xpm b/Utilities/FLTK/fluid/pixmaps/flBrowser.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..50b1d0a42cf6c8b3eb643353bfa659e74613c3e4
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flBrowser.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flBrowser_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #808080",
+"c c none",
+"d c #c0c0c0",
+"e c #ffffff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfeeeeeeeeebbfdc",
+"dfeeeeeeeeebdfdc",
+"dfeeeeeeeeebdfdc",
+"dfeeeeeeeeebffdc",
+"dfeeeeeeeeebdfdc",
+"dfeeeeeeeeebdfdc",
+"dfeeeeeeeeebdfdc",
+"dfeeeeeeeeebdfdc",
+"dfbbbbbbbbbbbfdc",
+"dfbdddfddddbdfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flButton.xpm b/Utilities/FLTK/fluid/pixmaps/flButton.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..509293e6d66b29ac00eea556b44c2f8ae8ed2dff
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flButton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flButton_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #a0a0a0",
+"e c #8080ff",
+"f c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffac",
+"fdddddddddddddac",
+"fdddddddddddddac",
+"fdddddddddddddac",
+"fdddddddddddddac",
+"fdddddddddddddac",
+"fdddddddddddddac",
+"aaaaaaaaaaaaaaac",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flCheckBrowser.xpm b/Utilities/FLTK/fluid/pixmaps/flCheckBrowser.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..77ffc56b491e5d8b8728cfcf4d9d0804455f3f73
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flCheckBrowser.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flCheckBrowser_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #808080",
+"c c none",
+"d c #c0c0c0",
+"e c #ffffff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfeeeeeeeeebbfdc",
+"dfefffeeeeebdfdc",
+"dfefefeeeeebdfdc",
+"dfefffeeeeebffdc",
+"dfeeeeeeeeebdfdc",
+"dfefffeeeeebdfdc",
+"dfefefeeeeebdfdc",
+"dfefffeeeeebdfdc",
+"dfbbbbbbbbbbbfdc",
+"dfbdddfddddbdfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flCheckButton.xpm b/Utilities/FLTK/fluid/pixmaps/flCheckButton.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..24f51cb39249f8c69bc87127ef0248d6dba62d25
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flCheckButton.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char *flCheckButton_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 7 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #ffffff",
+"e c #8080ff",
+"f c #d0d0d0",
+"' c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccaaaaaaaaaaccc",
+"cccaddddddddfccc",
+"cccadddddd''fccc",
+"cccaddddd''dfccc",
+"cccaddddd''dfccc",
+"ccca''dd''ddfccc",
+"cccad''''dddfccc",
+"cccadd''ddddfccc",
+"cccaddddddddfccc",
+"cccaaaaaaaaaaccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flChoice.xpm b/Utilities/FLTK/fluid/pixmaps/flChoice.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..85f54963cb0b64ef36b03637393a9a12e1f9518a
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flChoice.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flChoice_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+". c #000000",
+"c c none",
+"d c #b0b0b0",
+"e c #ffffff",
+"f c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"feeeeeafddddddda",
+"feeeeeafddddddda",
+"feeeeeaf.......a",
+"feeeeeafd.....da",
+"feeeeeafdd...dda",
+"feeeeeafddd.ddda",
+"feeeeeafddddddda",
+"feeeeeafddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flClass.xpm b/Utilities/FLTK/fluid/pixmaps/flClass.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..cd551bc72e019c6cb70de9f1f4eb558690dba042
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flClass.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *flClass_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 4 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0e0c0",
+"c c #000000",
+/* pixels */
+"................",
+"................",
+"...aaaaaaaaaaaaa",
+"..abbbbbbbbbbbc.",
+".abbbbbbbbbbbc..",
+".abbbbbbbbbbbc..",
+"abbbbbbbbbbbc...",
+"abbbbbbbbbbbc...",
+"abbbbbbbbbbbc...",
+"abbbbbbbbbbbc...",
+".abbbbbbbbbbbc..",
+".abbbbbbbbbbbc..",
+"..cbbbbbbbbbbbc.",
+"...ccccccccccccc",
+"................",
+"................",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flClock.xpm b/Utilities/FLTK/fluid/pixmaps/flClock.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..f69f0bf79ff4521bb4d6574ccde3a4f25f55c197
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flClock.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *flClock_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 5 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0c0c0",
+"c c #000000",
+"' c #202080",
+/* pixels */
+"................",
+"................",
+"....aaaaaaa.....",
+"..aabbbbbbbcc...",
+".abbbbbbbbb'bc..",
+".abb'bbbbb'bbc..",
+"abbbb'bbb'bbbbc.",
+"abbbbb'b'bbbbbc.",
+"abbbbbb'bbbbbbc.",
+"abbbbbbbbbbbbbc.",
+"abbbbbbbbbbbbbc.",
+".abbbbbbbbbbbc..",
+".abbbbbbbbbbbc..",
+"..ccbbbbbbbcc...",
+"....ccccccc.....",
+"................",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flCode.xpm b/Utilities/FLTK/fluid/pixmaps/flCode.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..7a10b26167522a1f00e9a0febfce828823223d85
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flCode.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *flCode_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 4 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0e0c0",
+"c c #000000",
+/* pixels */
+"................",
+"................",
+"aaaaaaaaaaaaaaaa",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"accccccccccccccc",
+"................",
+"................",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flCodeBlock.xpm b/Utilities/FLTK/fluid/pixmaps/flCodeBlock.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..dd18f425a22267d24a5f7bc12a4d8ff2e4494a9e
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flCodeBlock.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *flCodeBlock_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 4 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0e0c0",
+"c c #000000",
+/* pixels */
+".......aa.......",
+"......abbc......",
+".....abbbbc.....",
+"....abbbbbbc....",
+"...abbbbbbbbc...",
+"..abbbbbbbbbbc..",
+".abbbbbbbbbbbbc.",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+".abbbbbbbbbbbbc.",
+"..abbbbbbbbbbc..",
+"...abbbbbbbbc...",
+"....abbbbbbc....",
+".....abbbbc.....",
+"......abbc......",
+".......ac.......",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flComment.xpm b/Utilities/FLTK/fluid/pixmaps/flComment.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..191b139104b330f741aa869ca3c241637fc8cf65
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flComment.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *flComment_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 4 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0e0c0",
+"c c #000000",
+/* pixels */
+"................",
+"................",
+".aaaaaaaaaaaaaa.",
+".abbbbbbbbbbbbc.",
+".abbbbbccbbccbc.",
+".abbbbccbbccbbc.",
+".abbbbccbbccbbc.",
+".abbbccbbccbbbc.",
+".abbbccbbccbbbc.",
+".abbccbbccbbbbc.",
+".abbccbbccbbbbc.",
+".abccbbccbbbbbc.",
+".abbbbbbbbbbbbc.",
+".accccccccccccc.",
+"................",
+"................",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flCounter.xpm b/Utilities/FLTK/fluid/pixmaps/flCounter.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..995b7efb10e4f28e5e82c602aacd86b0ddf1623a
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flCounter.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flCounter_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"' c #000000",
+"c c none",
+"d c #c0c0c0",
+"e c #ffffff",
+"f c #e0e0e0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"fffffffffffffffc",
+"fdddaeeeeefdddac",
+"fd'daee'eefd'dac",
+"f''dae''eefd''ac",
+"f''daee'eefd''ac",
+"fd'dae'''efd'dac",
+"fdddaeeeeefdddac",
+"aaaaaaaaaaaaaaac",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flDeclaration.xpm b/Utilities/FLTK/fluid/pixmaps/flDeclaration.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..dd6a4de473bef05e8b1bb25d5c9dc5c273b405a6
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flDeclaration.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *flDeclaration_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 4 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0e0c0",
+"c c #000000",
+/* pixels */
+"................",
+"................",
+"...aaaaaaaaaaaaa",
+"...abbbbbbbbbbbc",
+"...abbbbbbbbbbbc",
+"..abbbbbbbbbbbc.",
+"..abbbbbbbbbbbc.",
+"..abbbbbbbbbbbc.",
+".abbbbbbbbbbbc..",
+".abbbbbbbbbbbc..",
+".abbbbbbbbbbbc..",
+"abbbbbbbbbbbc...",
+"abbbbbbbbbbbc...",
+"acccccccccccc...",
+"................",
+"................",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flDeclarationBlock.xpm b/Utilities/FLTK/fluid/pixmaps/flDeclarationBlock.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..ec4df041b723848211295eabc4a008b7bb86d012
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flDeclarationBlock.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *flDeclarationBlock_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 4 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0e0c0",
+"c c #000000",
+/* pixels */
+".......aa.......",
+"......abbc......",
+".....abbbbc.....",
+"....abbbbbbc....",
+"...abbbbbbbbc...",
+"..abbbcbbcbbbc..",
+".abbbccccccbbbc.",
+"abbbbbcbbcbbbbbc",
+"abbbbbcbbcbbbbbc",
+".abbbccccccbbbc.",
+"..abbbcbbcbbbc..",
+"...abbbbbbbbc...",
+"....abbbbbbc....",
+".....abbbbc.....",
+"......abbc......",
+".......ac.......",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flDial.xpm b/Utilities/FLTK/fluid/pixmaps/flDial.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..29376ac42ec804d8fb718b3bc0e18ae3b9fd0201
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flDial.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *flDial_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 5 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0c0c0",
+"c c #000000",
+"' c #202080",
+/* pixels */
+"................",
+"................",
+"....aaaaaaa.....",
+"..aabbbbbbbcc...",
+".abbbbbbbbbbbc..",
+".ab''bbbbbbbbc..",
+"ab'bb'bbbbbbbbc.",
+"ab'bb'bbbbbbbbc.",
+"abb''bbbbbbbbbc.",
+"abbbbbbbbbbbbbc.",
+"abbbbbbbbbbbbbc.",
+".abbbbbbbbbbbc..",
+".abbbbbbbbbbbc..",
+"..ccbbbbbbbcc...",
+"....ccccccc.....",
+"................",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flFileBrowser.xpm b/Utilities/FLTK/fluid/pixmaps/flFileBrowser.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..98b02e9dd50fd46105dcf5e6a261ddcee7516923
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flFileBrowser.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flFileBrowser_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #ffff00",
+"b c #808080",
+"c c none",
+"d c #c0c0c0",
+"e c #ffffff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfeeeeeeeeebbfdc",
+"dfeefffeeeebdfdc",
+"dfefaaafffebdfdc",
+"dfefaaaaafebffdc",
+"dfefaaaaafebdfdc",
+"dfefaaaaafebdfdc",
+"dfefffffffebdfdc",
+"dfeeeeeeeeebdfdc",
+"dfbbbbbbbbbbbfdc",
+"dfbdddfddddbdfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flFileInput.xpm b/Utilities/FLTK/fluid/pixmaps/flFileInput.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..014c2248eb1256041eed8fff4bb48b9776f5fd92
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flFileInput.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flFileInput_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #000000",
+"c c none",
+"d c #ffffff",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"faaaaaaaafaaaaaa",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdd...dd..ddddda",
+"fd.ddd.d..ddddda",
+"fd.ddd.d..ddddda",
+"fd.....d..ddddda",
+"fd.ddd.d..ddddda",
+"fd.ddd.d..ddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flFunction.xpm b/Utilities/FLTK/fluid/pixmaps/flFunction.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..54f6cef9a4f6eef98704b5d9de8638fe832cbd48
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flFunction.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char *flFunction_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 4 1",
+/* colors */
+". c none",
+"a c #000000",
+"b c #c0e0c0",
+"c c #000000",
+/* pixels */
+"................",
+"................",
+"....aaaaaaaa....",
+"..aabbbbbbbbcc..",
+".abbbbbbbbbbbbc.",
+".abbbbbbbbbbbbc.",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+"abbbbbbbbbbbbbbc",
+".abbbbbbbbbbbbc.",
+".abbbbbbbbbbbbc.",
+"..ccbbbbbbbbcc..",
+"....cccccccc....",
+"................",
+"................",
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flGroup.xpm b/Utilities/FLTK/fluid/pixmaps/flGroup.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..daa21cfccf9274ac945d77958b5aa2bb6ca9ba97
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flGroup.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flGroup_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flHelp.xpm b/Utilities/FLTK/fluid/pixmaps/flHelp.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..6a9c0a0fa7140f732c67dc67fb3d35ba606912bc
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flHelp.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flHelp_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #808080",
+"c c none",
+"d c #c0c0c0",
+"e c #ffffff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfeeeeeeeeebbfdc",
+"dfeeeffeeeebdfdc",
+"dfeeffeeeeebdfdc",
+"dfeffeeeeeebffdc",
+"dfeeffeeeeebdfdc",
+"dfeeeffeeeebdfdc",
+"dfeeeeeeeeebdfdc",
+"dfeeeeeeeeebdfdc",
+"dfbbbbbbbbbbbfdc",
+"dfbdddfddddbdfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flInput.xpm b/Utilities/FLTK/fluid/pixmaps/flInput.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f04c830d7a471231748ec38c0bf0e8d4d5763
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flInput.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flInput_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #000000",
+"c c none",
+"d c #ffffff",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdd...dd..ddddda",
+"fd.ddd.d..ddddda",
+"fd.ddd.d..ddddda",
+"fd.....d..ddddda",
+"fd.ddd.d..ddddda",
+"fd.ddd.d..ddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flLightButton.xpm b/Utilities/FLTK/fluid/pixmaps/flLightButton.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..bd14fc7a013603f674a02839b3f4048cc26e1ff9
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flLightButton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flLightButton_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #ffff00",
+"c c none",
+"d c #a0a0a0",
+"e c #8080ff",
+"f c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffac",
+"fdddddddddddddac",
+"fdaaaaddddddddac",
+"fdabbfddddddddac",
+"fdabbfddddddddac",
+"fdafffddddddddac",
+"fdddddddddddddac",
+"aaaaaaaaaaaaaaac",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flMenuButton.xpm b/Utilities/FLTK/fluid/pixmaps/flMenuButton.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..1cf862490d6998b3b63245b420e84222b8b650f3
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flMenuButton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flMenuButton_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+". c #000000",
+"c c none",
+"d c #b0b0b0",
+"e c #ffffff",
+"f c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fddddddd.......a",
+"fdddddddd.ddd.da",
+"fddddddddd.d.dda",
+"fdddddddddd.ddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flMenubar.xpm b/Utilities/FLTK/fluid/pixmaps/flMenubar.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..d72436df520354fbcebd3d852014741f2bdaa286
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flMenubar.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flMenubar_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+". c #2020cf",
+"c c none",
+"d c #b0b0b0",
+"e c #ffffff",
+"f c #e0e0e0",
+/* pixels */
+"cccccccccccccccc",
+"ffffffffffffffff",
+"dddddddddddddddd",
+"dddddddddddddddd",
+"dddddddddddddddd",
+"dddffffffffffffd",
+"aaafddddddddddaa",
+"cccfddddddddddac",
+"cccfddddddddddac",
+"cccfddddddddddac",
+"cccfddddddddddac",
+"cccfddddddddddac",
+"cccfddddddddddac",
+"cccfddddddddddac",
+"cccfaaaaaaaaaaac",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flMenuitem.xpm b/Utilities/FLTK/fluid/pixmaps/flMenuitem.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..73228fc04b8bedd90fb7ca00d0c9690d02f1d654
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flMenuitem.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flMenuitem_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+". c #000000",
+"c c none",
+"d c #b0b0b0",
+"e c #d0d0d0",
+"f c #c0c0c0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccffffccccccccc",
+"c.fffffffccccf.c",
+"c.ffffffffffff.c",
+"c.eeeeeeeeeeee.c",
+"c.ee.ee.eeeeee.c",
+"c.e.e.e.eee..e.c",
+"c.e...e..e.eee.c",
+"c.e.e.e..e.eee.c",
+"c.e.e.e..ee..e.c",
+"c.eeeeeeeeeeee.c",
+"c.ffffffffffff.c",
+"c.fccccfffffff.c",
+"cccccccccffffccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flOutput.xpm b/Utilities/FLTK/fluid/pixmaps/flOutput.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..0588f7a2270cdb47cac7450ffc1dfe916a02f756
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flOutput.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flOutput_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #000000",
+"c c none",
+"d c #d0d0d0",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdd...ddddddddda",
+"fd.ddd.dddddddda",
+"fd.ddd.dddddddda",
+"fd.....dddddddda",
+"fd.ddd.dddddddda",
+"fd.ddd.dddddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flPack.xpm b/Utilities/FLTK/fluid/pixmaps/flPack.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..8161c98f747f76491caffcf45ff388cf4d30d366
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flPack.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flPack_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #f0f0f0",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfddfddfddfddfdc",
+"dfddfddfddfddfdc",
+"dfddfddfddfddfdc",
+"dfddfddfddfddfdc",
+"dfddfddfddfddfdc",
+"dfddfddfddfddfdc",
+"dfddfddfddfddfdc",
+"dfddfddfddfddfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flProgress.xpm b/Utilities/FLTK/fluid/pixmaps/flProgress.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..02890f26079fd0f11e89bf61685c17ba1c1688a3
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flProgress.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flProgress_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #f0f000",
+"c c none",
+"d c #ffffff",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"f.........ddddda",
+"f.........ddddda",
+"f.........ddddda",
+"f.........ddddda",
+"f.........ddddda",
+"f.........ddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flRepeatButton.xpm b/Utilities/FLTK/fluid/pixmaps/flRepeatButton.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..1ee05f398b926f0c743824ad8397ac7c6e73da79
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flRepeatButton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flRepeatButton_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"' c #000000",
+"c c none",
+"d c #a0a0a0",
+"e c #8080ff",
+"f c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffac",
+"fdddddddddddddac",
+"fdddddddddddddac",
+"fdddddddddddddac",
+"fdddd''d''d''dac",
+"fdddd''d''d''dac",
+"fdddddddddddddac",
+"aaaaaaaaaaaaaaac",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flReturnButton.xpm b/Utilities/FLTK/fluid/pixmaps/flReturnButton.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..d875e01a0f7cba08e0c5fd2470056b7d65f47e09
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flReturnButton.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flReturnButton_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"' c #000000",
+"c c none",
+"d c #a0a0a0",
+"e c #8080ff",
+"f c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffac",
+"fdddddddddddddac",
+"fddddddd'dd''dac",
+"fdddddd''dd''dac",
+"fddddd'''''''dac",
+"fdddddd''dddddac",
+"fddddddd'dddddac",
+"aaaaaaaaaaaaaaac",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flRoller.xpm b/Utilities/FLTK/fluid/pixmaps/flRoller.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..1000bb5bd02c9ebdb721d02c9b199bd923e3298a
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flRoller.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flRoller_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #e0e0e0",
+"' c #000000",
+"c c none",
+"d c #c0c0c0",
+"e c #ffffff",
+"f c #606060",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"aaaaaaaaaaaaaaac",
+"a'f'ee'ddd'dd'f'",
+"a'f'ee'ddd'dd'f'",
+"a'f'ee'ddd'dd'f'",
+"a'f'ee'ddd'dd'f'",
+"a'f'ee'ddd'dd'f'",
+"a'f'ee'ddd'dd'f'",
+"''''''''''''''''",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flRoundButton.xpm b/Utilities/FLTK/fluid/pixmaps/flRoundButton.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..c9658e6067af111d7ee5158f5bc32d280fa45978
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flRoundButton.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char *flRoundButton_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 7 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+". c none",
+"d c #ffffff",
+"e c #8080ff",
+"f c #d0d0d0",
+"# c #000000",
+/* pixels */
+"................",
+"................",
+"......aaa.......",
+"....aadddaa.....",
+"...adddddddf....",
+"...add###ddf....",
+"..add#####ddf...",
+"..add#####ddf...",
+"..add#####ddf...",
+"...add###ddf....",
+"...adddddddf....",
+"....ffdddff.....",
+"......fff.......",
+"................",
+"................",
+"................"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flScroll.xpm b/Utilities/FLTK/fluid/pixmaps/flScroll.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..9dcdd2411d2f316fedab560a10146b9b25fd3c16
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flScroll.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flScroll_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #f0f0f0",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfddddddddbbbfdc",
+"dfddddddddbddfdc",
+"dfddddddddbddfdc",
+"dfddddddddbfffdc",
+"dfddddddddbddfdc",
+"dfbbbbbbbbbbbfdc",
+"dfbdddfdddbddfdc",
+"dfbdddfdddbddfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flScrollBar.xpm b/Utilities/FLTK/fluid/pixmaps/flScrollBar.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..c18a08ca154a3b2530e7f52f765f2fe078a5d10f
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flScrollBar.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flScrollBar_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #e0e0e0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"aaaaaaaaaaaaaaaa",
+"adddfffffddddddf",
+"ad'dfdddadddd'df",
+"a''dfdddadddd''f",
+"a''dfdddadddd''f",
+"ad'dfdddadddd'df",
+"adddfaaaaddddddf",
+"afffffffffffffff",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flSlider.xpm b/Utilities/FLTK/fluid/pixmaps/flSlider.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..524268de5e76c0910828e264c65a085894ccc5d3
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flSlider.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flSlider_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #e0e0e0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"aaaaaaaaaaaaaaaa",
+"afffffdddddddddf",
+"afdddadddddddddf",
+"afdddadddddddddf",
+"afdddadddddddddf",
+"afdddadddddddddf",
+"afaaaadddddddddf",
+"afffffffffffffff",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flSpinner.xpm b/Utilities/FLTK/fluid/pixmaps/flSpinner.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..840d87b89e1023d2c1005d710f9c911ec4057ae9
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flSpinner.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char *flSpinner_xpm[]={
+"16 16 6 1",
+". c None",
+"c c #000000",
+"d c #606060",
+"b c #c0c0c0",
+"# c #e0e0e0",
+"a c #ffffff",
+"................",
+"................",
+"................",
+"................",
+"###############.",
+"#aaaaaaaaa#bcbd.",
+"#aaaaaacaa#cccd.",
+"#aaaaaccaaddddd.",
+"#aaaaaacaa####d.",
+"#aaaaaccca#cccd.",
+"#aaaaaaaaa#bcbd.",
+"ddddddddddddddd.",
+"................",
+"................",
+"................",
+"................"};
diff --git a/Utilities/FLTK/fluid/pixmaps/flSubmenu.xpm b/Utilities/FLTK/fluid/pixmaps/flSubmenu.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..18439f8b285fa3d14f82c520f8fcd381d09d598b
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flSubmenu.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flSubmenu_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+". c #000000",
+"c c none",
+"d c #b0b0b0",
+"e c #d0d0d0",
+"f c #c0c0c0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccffffccccccccc",
+"c.fffffffccccf.c",
+"c.ffffffffffff.c",
+"c.eeeeeeeeeeee.c",
+"c.ee.eeeee.eee.c",
+"c.e.e.eeee..ee.c",
+"c.e...eeee...e.c",
+"c.e.e.eeee..ee.c",
+"c.e.e.eeee.eee.c",
+"c.eeeeeeeee.....",
+"c.fffffffff.ffff",
+"c.fccccffff.ffff",
+"cccccccccff.ffff",
+"ccccccccccc.ffff"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flTabs.xpm b/Utilities/FLTK/fluid/pixmaps/flTabs.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..8aec7937b9f600d94cd0f7e94f883bb025812b0e
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flTabs.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flTabs_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #a0a0a0",
+"b c #2020ff",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"dddddddddddddddc",
+"ddffffdffffddddc",
+"dfddddfaaaafdddc",
+"dfddddfaaaafdddc",
+"dfddddffffffffdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flTextDisplay.xpm b/Utilities/FLTK/fluid/pixmaps/flTextDisplay.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..990c4a0a087882920225d447835f2fd2c7b26d17
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flTextDisplay.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flTextDisplay_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #000000",
+"c c none",
+"d c #d0d0d0",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdd...ddddddddda",
+"fd.ddd.dddddddda",
+"fd.ddd.dddddddda",
+"fd.....dddddddda",
+"fd.ddd.dddddddda",
+"fd.ddd.dddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flTextEdit.xpm b/Utilities/FLTK/fluid/pixmaps/flTextEdit.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..8a892d897a03ee993bdca9f1beb03091400f48ea
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flTextEdit.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flTextEdit_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #000000",
+"c c none",
+"d c #ffffff",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdd...dd..ddddda",
+"fd.ddd.d..ddddda",
+"fd.ddd.d..ddddda",
+"fd.....d..ddddda",
+"fd.ddd.d..ddddda",
+"fd.ddd.d..ddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flTile.xpm b/Utilities/FLTK/fluid/pixmaps/flTile.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..c64f78fefbdb5dd04fa7399bdc1bc853a99bb3db
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flTile.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flTile_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #f0f0f0",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"dddddddddddddddd",
+"dfffffffffffffbd",
+"dfdddddbfdddddbd",
+"dfdddddbfdddddbd",
+"dfdddddbfdddddbdc",
+"dfbbbbbbfbbbbbbd",
+"dfffffffffffffbd",
+"dfdddddbfdddddbd",
+"dfdddddbfdddddbd",
+"dfdddddbfdddddbd",
+"dfbbbbbbfbbbbbbd",
+"dddddddddddddddd",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flValueInput.xpm b/Utilities/FLTK/fluid/pixmaps/flValueInput.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..dc56bd86586a71608d30e5add2530c42bde288fa
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flValueInput.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flValueInput_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #000000",
+"c c none",
+"d c #ffffff",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdd...dd..ddddda",
+"fd.dd..d..ddddda",
+"fd.d.d.d..ddddda",
+"fd..dd.d..ddddda",
+"fd.ddd.d..ddddda",
+"fdd...dd..ddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flValueOutput.xpm b/Utilities/FLTK/fluid/pixmaps/flValueOutput.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..c6d1de1606aadcd9abe092c6e7c1e704f7f15641
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flValueOutput.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flValueOutput_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"f c #606060",
+". c #000000",
+"c c none",
+"d c #d0d0d0",
+"e c #8080ff",
+"a c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"fdddddddddddddda",
+"fdd...ddddddddda",
+"fd.dd..dddddddda",
+"fd.d.d.dddddddda",
+"fd..dd.dddddddda",
+"fd.ddd.dddddddda",
+"fdd...ddddddddda",
+"fdddddddddddddda",
+"aaaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flValueSlider.xpm b/Utilities/FLTK/fluid/pixmaps/flValueSlider.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..819a4f5e43d97c5f23c4abd340503acf220c4298
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flValueSlider.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flValueSlider_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #c0c0c0",
+"' c #000000",
+"f c #e0e0e0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"aaaaaaaaaaaaaaaa",
+"adddddfffffddddf",
+"add'ddfdddaddddf",
+"ad''ddfdddaddddf",
+"add'ddfdddaddddf",
+"ad'''dfdddaddddf",
+"adddddfaaaaddddf",
+"afffffffffffffff",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flWidgetClass.xpm b/Utilities/FLTK/fluid/pixmaps/flWidgetClass.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..79c3377687625209b8e9148e7da291825c1d6f0d
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flWidgetClass.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static const char *flWidgetClass_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 8 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #a0a0a0",
+"e c #8080ff",
+"f c #d0d0d0",
+"g c #c0e0c0",
+"h c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"feebbbbbbbeebeea",
+"feebbbbbbbeebeea",
+"fdddhhhhhhhhhhda",
+"fddhgggggggghdda",
+"fdhgggggggghddda",
+"fdhgggggggghddda",
+"fdhgggggggghddda",
+"fdhgggggggghddda",
+"fddhgggggggghdda",
+"fdddhhhhhhhhhhda",
+"faaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flWindow.xpm b/Utilities/FLTK/fluid/pixmaps/flWindow.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..9581a26463f11d07ea3a4577e2db5b6ffd40c1df
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flWindow.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flWindow_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #2020ff",
+"c c none",
+"d c #a0a0a0",
+"e c #8080ff",
+"f c #d0d0d0",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"ffffffffffffffff",
+"feebbbbbbbeebeea",
+"feebbbbbbbeebeea",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"fdddddddddddddda",
+"faaaaaaaaaaaaaaa",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/flWizard.xpm b/Utilities/FLTK/fluid/pixmaps/flWizard.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..2347b93407ac399b96d5604de087b14fa19c7549
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/flWizard.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *flWizard_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"a c #606060",
+"b c #f0f0f0",
+"c c none",
+"d c #c0c0c0",
+"e c #8080ff",
+"f c #000000",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"dddddddddddddddc",
+"dfffffffffffffdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfdddddddddddfdc",
+"dfbbbbbbbbbbbfdc",
+"dfbddddfbdbddfdc",
+"dfbddddfbdbddfdc",
+"dfffffffffffffdc",
+"dddddddddddddddc",
+"cccccccccccccccc",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/lock.xpm b/Utilities/FLTK/fluid/pixmaps/lock.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..3ce4b4c108e037944278c867878b6f3dc5f7456e
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/lock.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *lock_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"` c #000000",
+"a c #c08080",
+"b c #FFc0c0",
+"c c none",
+"d c #FFc0c0",
+"e c #804040",
+/* pixels */
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccccccccc",
+"cccccccccc```ccc",
+"ccccccccc`daa`cc",
+"cccccccc`da`bd`c",
+"cccccccc`a`c`d`c",
+"ccccccc`````````",
+"ccccccc`dddaaae`",
+"ccccccc`daa`aae`",
+"ccccccc`da`eaae`",
+"ccccccc`da`daee`",
+"ccccccc`````````",
+"cccccccccccccccc"
+};
diff --git a/Utilities/FLTK/fluid/pixmaps/print_color.xpm b/Utilities/FLTK/fluid/pixmaps/print_color.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..149d67b2978a494a5685fca4effa69d5614056ff
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/print_color.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * print_color_xpm[] = {
+"24 24 17 1",
+" 	c None",
+".	c #FFFF00",
+"+	c #C8FF00",
+"@	c #00FF00",
+"#	c #FFC800",
+"$	c #FF0000",
+"%	c #00FFFF",
+"&	c #000000",
+"*	c #FF00FF",
+"=	c #00FFC8",
+"-	c #FF00C8",
+";	c #00C800",
+">	c #C80000",
+",	c #0000C8",
+"'	c #0000FF",
+")	c #00C8FF",
+"!	c #C800FF",
+"         ......         ",
+"       ..........       ",
+"      ............      ",
+"     ..............     ",
+"     ..............     ",
+"    ................    ",
+"    ................    ",
+"    ................    ",
+"    +@@@@@@+#$$$$$$#    ",
+"   %@@@@@@@&&$$$$$$$*   ",
+"  %%@@@@@@&&&&$$$$$$**  ",
+" %%%=@@@@&&&&&&$$$$-*** ",
+" %%%%@@@;&&&&&&>$$$**** ",
+"%%%%%%@@&&&&&&&&$$******",
+"%%%%%%%@&&&&&&&&$*******",
+"%%%%%%%%,&&&&&&,********",
+"%%%%%%%%''''''''********",
+"%%%%%%%%''''''''********",
+"%%%%%%%%''''''''********",
+" %%%%%%%)''''''!******* ",
+" %%%%%%%%''''''******** ",
+"  %%%%%%%%''''********  ",
+"   %%%%%%%%''********   ",
+"     %%%%%%  ******     "};
diff --git a/Utilities/FLTK/fluid/pixmaps/print_gray.xpm b/Utilities/FLTK/fluid/pixmaps/print_gray.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..4d5057bebfa281bde9671517e53780dc748c7bfc
--- /dev/null
+++ b/Utilities/FLTK/fluid/pixmaps/print_gray.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * print_gray_xpm[] = {
+"24 24 17 1",
+" 	c None",
+".	c #E3E3E3",
+"+	c #D2D2D2",
+"@	c #969696",
+"#	c #C2C2C2",
+"$	c #4C4C4C",
+"%	c #B2B2B2",
+"&	c #000000",
+"*	c #696969",
+"=	c #ACACAC",
+"-	c #626262",
+";	c #767676",
+">	c #3C3C3C",
+",	c #161616",
+"'	c #1C1C1C",
+")	c #929292",
+"!	c #585858",
+"         ......         ",
+"       ..........       ",
+"      ............      ",
+"     ..............     ",
+"     ..............     ",
+"    ................    ",
+"    ................    ",
+"    ................    ",
+"    +@@@@@@+#$$$$$$#    ",
+"   %@@@@@@@&&$$$$$$$*   ",
+"  %%@@@@@@&&&&$$$$$$**  ",
+" %%%=@@@@&&&&&&$$$$-*** ",
+" %%%%@@@;&&&&&&>$$$**** ",
+"%%%%%%@@&&&&&&&&$$******",
+"%%%%%%%@&&&&&&&&$*******",
+"%%%%%%%%,&&&&&&,********",
+"%%%%%%%%''''''''********",
+"%%%%%%%%''''''''********",
+"%%%%%%%%''''''''********",
+" %%%%%%%)''''''!******* ",
+" %%%%%%%%''''''******** ",
+"  %%%%%%%%''''********  ",
+"   %%%%%%%%''********   ",
+"     %%%%%%  ******     "};
diff --git a/Utilities/FLTK/fluid/print_panel.cxx b/Utilities/FLTK/fluid/print_panel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..881bb014724961438c5e33f9c678e6f6725602a9
--- /dev/null
+++ b/Utilities/FLTK/fluid/print_panel.cxx
@@ -0,0 +1,591 @@
+//
+// "$Id$"
+//
+// FLUID print panel for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "print_panel.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "../src/flstring.h"
+#include <FL/Fl_Preferences.H>
+extern Fl_Preferences fluid_prefs;
+
+Fl_Double_Window *print_panel=(Fl_Double_Window *)0;
+
+Fl_Group *print_panel_controls=(Fl_Group *)0;
+
+Fl_Choice *print_choice=(Fl_Choice *)0;
+
+static void cb_print_choice(Fl_Choice*, void*) {
+  print_update_status();
+}
+
+Fl_Button *print_properties=(Fl_Button *)0;
+
+static void cb_print_properties(Fl_Button*, void*) {
+  print_properties_panel->show();
+}
+
+Fl_Box *print_status=(Fl_Box *)0;
+
+Fl_Round_Button *print_all=(Fl_Round_Button *)0;
+
+static void cb_print_all(Fl_Round_Button*, void*) {
+  print_from->deactivate();
+print_to->deactivate();
+}
+
+Fl_Round_Button *print_pages=(Fl_Round_Button *)0;
+
+static void cb_print_pages(Fl_Round_Button*, void*) {
+  print_from->activate();
+print_to->activate();
+}
+
+Fl_Round_Button *print_selection=(Fl_Round_Button *)0;
+
+static void cb_print_selection(Fl_Round_Button*, void*) {
+  print_from->deactivate();
+print_to->deactivate();
+}
+
+Fl_Input *print_from=(Fl_Input *)0;
+
+Fl_Input *print_to=(Fl_Input *)0;
+
+Fl_Spinner *print_copies=(Fl_Spinner *)0;
+
+static void cb_print_copies(Fl_Spinner*, void*) {
+  if (print_copies->value() == 1) {
+  print_collate_button->deactivate();
+  print_collate_group[0]->deactivate();
+  print_collate_group[1]->deactivate();
+} else {
+  print_collate_button->activate();
+  print_collate_group[0]->activate();
+  print_collate_group[1]->activate();
+};
+}
+
+Fl_Check_Button *print_collate_button=(Fl_Check_Button *)0;
+
+static void cb_print_collate_button(Fl_Check_Button*, void*) {
+  int i = print_collate_button->value() != 0;
+print_collate_group[i]->show();
+print_collate_group[1 - i]->hide();
+}
+
+Fl_Group *print_collate_group[2]={(Fl_Group *)0};
+
+static void cb_Cancel(Fl_Button*, void*) {
+  print_panel->hide();
+}
+
+Fl_Progress *print_progress=(Fl_Progress *)0;
+
+Fl_Double_Window *print_properties_panel=(Fl_Double_Window *)0;
+
+static void cb_print_properties_panel(Fl_Double_Window*, void*) {
+  print_properties_panel->hide();
+print_update_status();
+}
+
+Fl_Choice *print_page_size=(Fl_Choice *)0;
+
+Fl_Menu_Item menu_print_page_size[] = {
+ {"Letter", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
+ {"A4", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
+ {0,0,0,0,0,0,0,0,0}
+};
+
+#include <FL/Fl_Pixmap.H>
+static const char *idata_print_color[] = {
+"24 24 17 1",
+" \tc None",
+".\tc #FFFF00",
+"+\tc #C8FF00",
+"@\tc #00FF00",
+"#\tc #FFC800",
+"$\tc #FF0000",
+"%\tc #00FFFF",
+"&\tc #000000",
+"*\tc #FF00FF",
+"=\tc #00FFC8",
+"-\tc #FF00C8",
+";\tc #00C800",
+">\tc #C80000",
+",\tc #0000C8",
+"\'\tc #0000FF",
+")\tc #00C8FF",
+"!\tc #C800FF",
+"         ......         ",
+"       ..........       ",
+"      ............      ",
+"     ..............     ",
+"     ..............     ",
+"    ................    ",
+"    ................    ",
+"    ................    ",
+"    +@@@@@@+#$$$$$$#    ",
+"   %@@@@@@@&&$$$$$$$*   ",
+"  %%@@@@@@&&&&$$$$$$**  ",
+" %%%=@@@@&&&&&&$$$$-*** ",
+" %%%%@@@;&&&&&&>$$$**** ",
+"%%%%%%@@&&&&&&&&$$******",
+"%%%%%%%@&&&&&&&&$*******",
+"%%%%%%%%,&&&&&&,********",
+"%%%%%%%%\'\'\'\'\'\'\'\'********",
+"%%%%%%%%\'\'\'\'\'\'\'\'********",
+"%%%%%%%%\'\'\'\'\'\'\'\'********",
+" %%%%%%%)\'\'\'\'\'\'!******* ",
+" %%%%%%%%\'\'\'\'\'\'******** ",
+"  %%%%%%%%\'\'\'\'********  ",
+"   %%%%%%%%\'\'********   ",
+"     %%%%%%  ******     "
+};
+static Fl_Pixmap image_print_color(idata_print_color);
+
+static const char *idata_print_gray[] = {
+"24 24 17 1",
+" \tc None",
+".\tc #E3E3E3",
+"+\tc #D2D2D2",
+"@\tc #969696",
+"#\tc #C2C2C2",
+"$\tc #4C4C4C",
+"%\tc #B2B2B2",
+"&\tc #000000",
+"*\tc #696969",
+"=\tc #ACACAC",
+"-\tc #626262",
+";\tc #767676",
+">\tc #3C3C3C",
+",\tc #161616",
+"\'\tc #1C1C1C",
+")\tc #929292",
+"!\tc #585858",
+"         ......         ",
+"       ..........       ",
+"      ............      ",
+"     ..............     ",
+"     ..............     ",
+"    ................    ",
+"    ................    ",
+"    ................    ",
+"    +@@@@@@+#$$$$$$#    ",
+"   %@@@@@@@&&$$$$$$$*   ",
+"  %%@@@@@@&&&&$$$$$$**  ",
+" %%%=@@@@&&&&&&$$$$-*** ",
+" %%%%@@@;&&&&&&>$$$**** ",
+"%%%%%%@@&&&&&&&&$$******",
+"%%%%%%%@&&&&&&&&$*******",
+"%%%%%%%%,&&&&&&,********",
+"%%%%%%%%\'\'\'\'\'\'\'\'********",
+"%%%%%%%%\'\'\'\'\'\'\'\'********",
+"%%%%%%%%\'\'\'\'\'\'\'\'********",
+" %%%%%%%)\'\'\'\'\'\'!******* ",
+" %%%%%%%%\'\'\'\'\'\'******** ",
+"  %%%%%%%%\'\'\'\'********  ",
+"   %%%%%%%%\'\'********   ",
+"     %%%%%%  ******     "
+};
+static Fl_Pixmap image_print_gray(idata_print_gray);
+
+Fl_Button *print_output_mode[4]={(Fl_Button *)0};
+
+static void cb_Save(Fl_Return_Button*, void*) {
+  print_properties_panel->hide();
+
+char name[1024];
+int val;
+const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data();
+
+snprintf(name, sizeof(name), "%s/page_size", printer);
+fluid_prefs.set(name, print_page_size->value());
+
+snprintf(name, sizeof(name), "%s/output_mode", printer);
+for (val = 0; val < 4; val ++) {
+  if (print_output_mode[val]->value()) break;
+}
+fluid_prefs.set(name, val);
+}
+
+static void cb_Cancel1(Fl_Button*, void*) {
+  print_properties_panel->hide();
+print_update_status();
+}
+
+static void cb_Use(Fl_Button*, void*) {
+  print_properties_panel->hide();
+}
+
+Fl_Double_Window* make_print_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = print_panel = new Fl_Double_Window(465, 235, "Print");
+    w = o;
+    { Fl_Group* o = print_panel_controls = new Fl_Group(10, 10, 447, 216);
+      { Fl_Choice* o = print_choice = new Fl_Choice(113, 10, 181, 25, "Printer:");
+        o->down_box(FL_BORDER_BOX);
+        o->labelfont(1);
+        o->callback((Fl_Callback*)cb_print_choice);
+        o->when(FL_WHEN_CHANGED);
+      }
+      { Fl_Button* o = print_properties = new Fl_Button(294, 10, 105, 25, "Properties...");
+        o->callback((Fl_Callback*)cb_print_properties);
+      }
+      { Fl_Box* o = print_status = new Fl_Box(111, 41, 288, 17, "printer/job status");
+        o->align(68|FL_ALIGN_INSIDE);
+      }
+      { Fl_Group* o = new Fl_Group(10, 86, 227, 105, "Print Range");
+        o->box(FL_THIN_DOWN_BOX);
+        o->labelfont(1);
+        o->align(FL_ALIGN_TOP_LEFT);
+        { Fl_Round_Button* o = print_all = new Fl_Round_Button(20, 96, 38, 25, "All");
+          o->type(102);
+          o->down_box(FL_ROUND_DOWN_BOX);
+          o->value(1);
+          o->callback((Fl_Callback*)cb_print_all);
+        }
+        { Fl_Round_Button* o = print_pages = new Fl_Round_Button(20, 126, 64, 25, "Pages");
+          o->type(102);
+          o->down_box(FL_ROUND_DOWN_BOX);
+          o->callback((Fl_Callback*)cb_print_pages);
+        }
+        { Fl_Round_Button* o = print_selection = new Fl_Round_Button(20, 156, 82, 25, "Selection");
+          o->type(102);
+          o->down_box(FL_ROUND_DOWN_BOX);
+          o->callback((Fl_Callback*)cb_print_selection);
+        }
+        { Fl_Input* o = print_from = new Fl_Input(136, 126, 28, 25, "From:");
+          o->type(2);
+          o->textfont(4);
+          o->deactivate();
+        }
+        { Fl_Input* o = print_to = new Fl_Input(199, 126, 28, 25, "To:");
+          o->type(2);
+          o->textfont(4);
+          o->deactivate();
+        }
+        o->end();
+      }
+      { Fl_Group* o = new Fl_Group(247, 86, 210, 105, "Copies");
+        o->box(FL_THIN_DOWN_BOX);
+        o->labelfont(1);
+        o->align(FL_ALIGN_TOP_LEFT);
+        { Fl_Spinner* o = print_copies = new Fl_Spinner(321, 96, 45, 25, "# Copies:");
+          o->callback((Fl_Callback*)cb_print_copies);
+          o->when(FL_WHEN_CHANGED);
+        }
+        { Fl_Check_Button* o = print_collate_button = new Fl_Check_Button(376, 96, 64, 25, "Collate");
+          o->down_box(FL_DOWN_BOX);
+          o->callback((Fl_Callback*)cb_print_collate_button);
+          o->when(FL_WHEN_CHANGED);
+          o->deactivate();
+        }
+        { Fl_Group* o = print_collate_group[0] = new Fl_Group(257, 131, 191, 50);
+          o->deactivate();
+          { Fl_Box* o = new Fl_Box(287, 141, 30, 40, "1");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(272, 136, 30, 40, "1");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(257, 131, 30, 40, "1");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(352, 141, 30, 40, "2");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(337, 136, 30, 40, "2");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(322, 131, 30, 40, "2");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(417, 141, 30, 40, "3");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(402, 136, 30, 40, "3");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          { Fl_Box* o = new Fl_Box(387, 131, 30, 40, "3");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+            o->deactivate();
+          }
+          o->end();
+        }
+        { Fl_Group* o = print_collate_group[1] = new Fl_Group(257, 131, 191, 50);
+          o->hide();
+          o->deactivate();
+          { Fl_Box* o = new Fl_Box(287, 141, 30, 40, "3");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(272, 136, 30, 40, "2");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(257, 131, 30, 40, "1");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(352, 141, 30, 40, "3");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(337, 136, 30, 40, "2");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(322, 131, 30, 40, "1");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(417, 141, 30, 40, "3");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(402, 136, 30, 40, "2");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          { Fl_Box* o = new Fl_Box(387, 131, 30, 40, "1");
+            o->box(FL_BORDER_BOX);
+            o->color(FL_BACKGROUND2_COLOR);
+            o->labelsize(11);
+            o->align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE);
+          }
+          o->end();
+        }
+        o->end();
+      }
+      { Fl_Return_Button* o = new Fl_Return_Button(309, 201, 70, 25, "Print");
+        o->callback((Fl_Callback*)print_cb);
+      }
+      { Fl_Button* o = new Fl_Button(389, 201, 68, 25, "Cancel");
+        o->callback((Fl_Callback*)cb_Cancel);
+      }
+      o->end();
+    }
+    { Fl_Progress* o = print_progress = new Fl_Progress(10, 203, 289, 21);
+      o->selection_color((Fl_Color)4);
+      o->hide();
+    }
+    o->set_modal();
+    o->end();
+  }
+  { Fl_Double_Window* o = print_properties_panel = new Fl_Double_Window(290, 130, "Printer Properties");
+    w = o;
+    o->callback((Fl_Callback*)cb_print_properties_panel);
+    { Fl_Choice* o = print_page_size = new Fl_Choice(110, 10, 80, 25, "Page Size:");
+      o->down_box(FL_BORDER_BOX);
+      o->labelfont(1);
+      o->menu(menu_print_page_size);
+    }
+    { Fl_Group* o = new Fl_Group(110, 45, 170, 40, "Output Mode:");
+      o->labelfont(1);
+      o->align(FL_ALIGN_LEFT);
+      { Fl_Button* o = print_output_mode[0] = new Fl_Button(110, 45, 30, 40);
+        o->type(102);
+        o->box(FL_BORDER_BOX);
+        o->down_box(FL_BORDER_BOX);
+        o->value(1);
+        o->color(FL_BACKGROUND2_COLOR);
+        o->selection_color(FL_FOREGROUND_COLOR);
+        o->image(image_print_color);
+      }
+      { Fl_Button* o = print_output_mode[1] = new Fl_Button(150, 50, 40, 30);
+        o->type(102);
+        o->box(FL_BORDER_BOX);
+        o->down_box(FL_BORDER_BOX);
+        o->color(FL_BACKGROUND2_COLOR);
+        o->selection_color(FL_FOREGROUND_COLOR);
+        o->image(image_print_color);
+      }
+      { Fl_Button* o = print_output_mode[2] = new Fl_Button(200, 45, 30, 40);
+        o->type(102);
+        o->box(FL_BORDER_BOX);
+        o->down_box(FL_BORDER_BOX);
+        o->color(FL_BACKGROUND2_COLOR);
+        o->selection_color(FL_FOREGROUND_COLOR);
+        o->image(image_print_gray);
+      }
+      { Fl_Button* o = print_output_mode[3] = new Fl_Button(240, 50, 40, 30);
+        o->type(102);
+        o->box(FL_BORDER_BOX);
+        o->down_box(FL_BORDER_BOX);
+        o->color(FL_BACKGROUND2_COLOR);
+        o->selection_color(FL_FOREGROUND_COLOR);
+        o->image(image_print_gray);
+      }
+      o->end();
+    }
+    { Fl_Return_Button* o = new Fl_Return_Button(123, 95, 79, 25, "Save");
+      o->callback((Fl_Callback*)cb_Save);
+    }
+    { Fl_Button* o = new Fl_Button(212, 95, 68, 25, "Cancel");
+      o->callback((Fl_Callback*)cb_Cancel1);
+    }
+    { Fl_Button* o = new Fl_Button(60, 95, 53, 25, "Use");
+      o->callback((Fl_Callback*)cb_Use);
+    }
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+void print_cb(Fl_Return_Button *, void *);
+
+void print_load() {
+  FILE *lpstat;
+char line[1024], name[1024], *nptr, qname[2048], *qptr, defname[1024];
+int i;
+
+if (print_choice->size() > 1) {
+  for (i = 1; print_choice->text(i); i ++) {
+    free(print_choice->menu()[i].user_data());
+  }
+}
+
+print_choice->clear();
+print_choice->add("Print To File", 0, 0, 0, FL_MENU_DIVIDER);
+print_choice->value(0);
+
+defname[0] = '\0';
+
+if ((lpstat = popen("lpstat -p -d", "r")) != NULL) {
+  while (fgets(line, sizeof(line), lpstat)) {
+    if (!strncmp(line, "printer ", 8) &&
+        sscanf(line + 8, "%s", name) == 1) {
+      for (nptr = name, qptr = qname; *nptr; *qptr++ = *nptr++) {
+        if (*nptr == '/') *qptr++ = '\\';
+      }
+      *qptr = '\0';
+
+      print_choice->add(qname, 0, 0, (void *)strdup(name), 0);
+    } else if (!strncmp(line, "system default destination: ", 28)) {
+      if (sscanf(line + 28, "%s", defname) != 1) defname[0] = '\0';
+    }
+  }
+  pclose(lpstat);
+}
+
+if (defname[0]) {
+  for (i = 1; print_choice->text(i); i ++) {
+    if (!strcmp((char *)print_choice->menu()[i].user_data(), defname)) {
+      print_choice->value(i);
+      break;
+    }
+  }
+} else if (print_choice->size() > 2) print_choice->value(1);
+
+
+print_update_status();
+}
+
+void print_update_status() {
+  FILE *lpstat;
+char command[1024];
+static char status[1024];
+const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data();
+
+if (print_choice->value()) {
+  snprintf(command, sizeof(command), "lpstat -p '%s'", printer);
+  if ((lpstat = popen(command, "r")) != NULL) {
+    fgets(status, sizeof(status), lpstat);
+    pclose(lpstat);
+  } else strcpy(status, "printer status unavailable");
+} else status[0] = '\0';
+
+print_status->label(status);
+
+char name[1024];
+int val;
+
+snprintf(name, sizeof(name), "%s/page_size", printer);
+fluid_prefs.get(name, val, 0);
+print_page_size->value(val);
+
+snprintf(name, sizeof(name), "%s/output_mode", printer);
+fluid_prefs.get(name, val, 0);
+print_output_mode[val]->setonly();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/print_panel.fl b/Utilities/FLTK/fluid/print_panel.fl
new file mode 100644
index 0000000000000000000000000000000000000000..723dbe841e1c89ecab6ae12c2c50233915586b42
--- /dev/null
+++ b/Utilities/FLTK/fluid/print_panel.fl
@@ -0,0 +1,370 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {.h} 
+code_name {.cxx}
+comment {//
+// "$Id$"
+//
+// FLUID print panel for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {in_source in_header
+} 
+
+decl {\#include <stdio.h>} {} 
+
+decl {\#include <stdlib.h>} {} 
+
+decl {\#include "../src/flstring.h"} {} 
+
+decl {\#include <FL/Fl_Preferences.H>} {} 
+
+decl {extern Fl_Preferences fluid_prefs;} {} 
+
+Function {make_print_panel()} {open
+} {
+  Fl_Window print_panel {
+    label Print open
+    xywh {342 21 465 235} type Double modal visible
+  } {
+    Fl_Group print_panel_controls {open
+      xywh {10 10 447 216}
+    } {
+      Fl_Choice print_choice {
+        label {Printer:}
+        callback {print_update_status();} open
+        xywh {113 10 181 25} down_box BORDER_BOX labelfont 1 when 1
+      } {}
+      Fl_Button print_properties {
+        label {Properties...}
+        callback {print_properties_panel->show();}
+        xywh {294 10 105 25}
+      }
+      Fl_Box print_status {
+        label {printer/job status}
+        xywh {111 41 288 17} align 84
+      }
+      Fl_Group {} {
+        label {Print Range} open
+        xywh {10 86 227 105} box THIN_DOWN_BOX labelfont 1 align 5
+      } {
+        Fl_Round_Button print_all {
+          label All
+          callback {print_from->deactivate();
+print_to->deactivate();}
+          xywh {20 96 38 25} type Radio down_box ROUND_DOWN_BOX value 1
+        }
+        Fl_Round_Button print_pages {
+          label Pages
+          callback {print_from->activate();
+print_to->activate();}
+          xywh {20 126 64 25} type Radio down_box ROUND_DOWN_BOX
+        }
+        Fl_Round_Button print_selection {
+          label Selection
+          callback {print_from->deactivate();
+print_to->deactivate();}
+          xywh {20 156 82 25} type Radio down_box ROUND_DOWN_BOX
+        }
+        Fl_Input print_from {
+          label {From:}
+          xywh {136 126 28 25} type Int textfont 4 deactivate
+        }
+        Fl_Input print_to {
+          label {To:}
+          xywh {199 126 28 25} type Int textfont 4 deactivate
+        }
+      }
+      Fl_Group {} {
+        label Copies open
+        xywh {247 86 210 105} box THIN_DOWN_BOX labelfont 1 align 5
+      } {
+        Fl_Spinner print_copies {
+          label {\# Copies:}
+          callback {if (print_copies->value() == 1) {
+  print_collate_button->deactivate();
+  print_collate_group[0]->deactivate();
+  print_collate_group[1]->deactivate();
+} else {
+  print_collate_button->activate();
+  print_collate_group[0]->activate();
+  print_collate_group[1]->activate();
+}} selected
+          xywh {321 96 45 25} when 1
+        }
+        Fl_Check_Button print_collate_button {
+          label Collate
+          callback {int i = print_collate_button->value() != 0;
+print_collate_group[i]->show();
+print_collate_group[1 - i]->hide();}
+          xywh {376 96 64 25} down_box DOWN_BOX when 1 deactivate
+        }
+        Fl_Group {print_collate_group[0]} {
+          xywh {257 131 191 50} deactivate
+        } {
+          Fl_Box {} {
+            label 1
+            xywh {287 141 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 1
+            xywh {272 136 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 1
+            xywh {257 131 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 2
+            xywh {352 141 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 2
+            xywh {337 136 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 2
+            xywh {322 131 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 3
+            xywh {417 141 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 3
+            xywh {402 136 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+          Fl_Box {} {
+            label 3
+            xywh {387 131 30 40} box BORDER_BOX color 7 labelsize 11 align 26 deactivate
+          }
+        }
+        Fl_Group {print_collate_group[1]} {
+          xywh {257 131 191 50} hide deactivate
+        } {
+          Fl_Box {} {
+            label 3
+            xywh {287 141 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 2
+            xywh {272 136 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 1
+            xywh {257 131 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 3
+            xywh {352 141 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 2
+            xywh {337 136 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 1
+            xywh {322 131 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 3
+            xywh {417 141 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 2
+            xywh {402 136 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+          Fl_Box {} {
+            label 1
+            xywh {387 131 30 40} box BORDER_BOX color 7 labelsize 11 align 26
+          }
+        }
+      }
+      Fl_Return_Button {} {
+        label Print
+        callback print_cb
+        xywh {309 201 70 25}
+      }
+      Fl_Button {} {
+        label Cancel
+        callback {print_panel->hide();}
+        xywh {389 201 68 25}
+      }
+    }
+    Fl_Progress print_progress {
+      xywh {10 203 289 21} selection_color 4 hide
+    }
+  }
+  Fl_Window print_properties_panel {
+    label {Printer Properties}
+    callback {print_properties_panel->hide();
+print_update_status();} open
+    xywh {340 213 290 130} type Double modal visible
+  } {
+    Fl_Choice print_page_size {
+      label {Page Size:}
+      xywh {110 10 80 25} down_box BORDER_BOX labelfont 1
+    } {
+      MenuItem {} {
+        label Letter
+        xywh {0 0 35 25}
+      }
+      MenuItem {} {
+        label A4
+        xywh {0 0 35 25}
+      }
+    }
+    Fl_Group {} {
+      label {Output Mode:} open
+      xywh {110 45 170 40} labelfont 1 align 4
+    } {
+      Fl_Button {print_output_mode[0]} {
+        image {pixmaps/print_color.xpm} xywh {110 45 30 40} type Radio box BORDER_BOX down_box BORDER_BOX value 1 color 7 selection_color 0
+      }
+      Fl_Button {print_output_mode[1]} {
+        image {pixmaps/print_color.xpm} xywh {150 50 40 30} type Radio box BORDER_BOX down_box BORDER_BOX color 7 selection_color 0
+      }
+      Fl_Button {print_output_mode[2]} {
+        image {pixmaps/print_gray.xpm} xywh {200 45 30 40} type Radio box BORDER_BOX down_box BORDER_BOX color 7 selection_color 0
+      }
+      Fl_Button {print_output_mode[3]} {
+        image {pixmaps/print_gray.xpm} xywh {240 50 40 30} type Radio box BORDER_BOX down_box BORDER_BOX color 7 selection_color 0
+      }
+    }
+    Fl_Return_Button {} {
+      label Save
+      callback {print_properties_panel->hide();
+
+char name[1024];
+int val;
+const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data();
+
+snprintf(name, sizeof(name), "%s/page_size", printer);
+fluid_prefs.set(name, print_page_size->value());
+
+snprintf(name, sizeof(name), "%s/output_mode", printer);
+for (val = 0; val < 4; val ++) {
+  if (print_output_mode[val]->value()) break;
+}
+fluid_prefs.set(name, val);}
+      xywh {123 95 79 25}
+    }
+    Fl_Button {} {
+      label Cancel
+      callback {print_properties_panel->hide();
+print_update_status();}
+      xywh {212 95 68 25}
+    }
+    Fl_Button {} {
+      label Use
+      callback {print_properties_panel->hide();}
+      xywh {60 95 53 25}
+    }
+  }
+} 
+
+decl {void print_cb(Fl_Return_Button *, void *);} {public
+} 
+
+Function {print_load()} {open return_type void
+} {
+  code {FILE *lpstat;
+char line[1024], name[1024], *nptr, qname[2048], *qptr, defname[1024];
+int i;
+
+if (print_choice->size() > 1) {
+  for (i = 1; print_choice->text(i); i ++) {
+    free(print_choice->menu()[i].user_data());
+  }
+}
+
+print_choice->clear();
+print_choice->add("Print To File", 0, 0, 0, FL_MENU_DIVIDER);
+print_choice->value(0);
+
+defname[0] = '\\0';
+
+if ((lpstat = popen("lpstat -p -d", "r")) != NULL) {
+  while (fgets(line, sizeof(line), lpstat)) {
+    if (!strncmp(line, "printer ", 8) &&
+        sscanf(line + 8, "%s", name) == 1) {
+      for (nptr = name, qptr = qname; *nptr; *qptr++ = *nptr++) {
+        if (*nptr == '/') *qptr++ = '\\\\';
+      }
+      *qptr = '\\0';
+
+      print_choice->add(qname, 0, 0, (void *)strdup(name), 0);
+    } else if (!strncmp(line, "system default destination: ", 28)) {
+      if (sscanf(line + 28, "%s", defname) != 1) defname[0] = '\\0';
+    }
+  }
+  pclose(lpstat);
+}
+
+if (defname[0]) {
+  for (i = 1; print_choice->text(i); i ++) {
+    if (!strcmp((char *)print_choice->menu()[i].user_data(), defname)) {
+      print_choice->value(i);
+      break;
+    }
+  }
+} else if (print_choice->size() > 2) print_choice->value(1);
+
+
+print_update_status();} {}
+} 
+
+Function {print_update_status()} {open return_type void
+} {
+  code {FILE *lpstat;
+char command[1024];
+static char status[1024];
+const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data();
+
+if (print_choice->value()) {
+  snprintf(command, sizeof(command), "lpstat -p '%s'", printer);
+  if ((lpstat = popen(command, "r")) != NULL) {
+    fgets(status, sizeof(status), lpstat);
+    pclose(lpstat);
+  } else strcpy(status, "printer status unavailable");
+} else status[0] = '\\0';
+
+print_status->label(status);
+
+char name[1024];
+int val;
+
+snprintf(name, sizeof(name), "%s/page_size", printer);
+fluid_prefs.get(name, val, 0);
+print_page_size->value(val);
+
+snprintf(name, sizeof(name), "%s/output_mode", printer);
+fluid_prefs.get(name, val, 0);
+print_output_mode[val]->setonly();} {}
+} 
+
+comment {
+//
+// End of "$Id$".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/fluid/print_panel.h b/Utilities/FLTK/fluid/print_panel.h
new file mode 100644
index 0000000000000000000000000000000000000000..123936f527d5077021b0b231ebc5a3a41d759517
--- /dev/null
+++ b/Utilities/FLTK/fluid/print_panel.h
@@ -0,0 +1,71 @@
+//
+// "$Id$"
+//
+// FLUID print panel for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef print_panel_h
+#define print_panel_h
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+extern Fl_Double_Window *print_panel;
+#include <FL/Fl_Group.H>
+extern Fl_Group *print_panel_controls;
+#include <FL/Fl_Choice.H>
+extern Fl_Choice *print_choice;
+#include <FL/Fl_Button.H>
+extern Fl_Button *print_properties;
+#include <FL/Fl_Box.H>
+extern Fl_Box *print_status;
+#include <FL/Fl_Round_Button.H>
+extern Fl_Round_Button *print_all;
+extern Fl_Round_Button *print_pages;
+extern Fl_Round_Button *print_selection;
+#include <FL/Fl_Input.H>
+extern Fl_Input *print_from;
+extern Fl_Input *print_to;
+#include <FL/Fl_Spinner.H>
+extern Fl_Spinner *print_copies;
+#include <FL/Fl_Check_Button.H>
+extern Fl_Check_Button *print_collate_button;
+extern Fl_Group *print_collate_group[2];
+#include <FL/Fl_Return_Button.H>
+extern void print_cb(Fl_Return_Button*, void*);
+#include <FL/Fl_Progress.H>
+extern Fl_Progress *print_progress;
+extern Fl_Double_Window *print_properties_panel;
+extern Fl_Choice *print_page_size;
+extern Fl_Button *print_output_mode[4];
+Fl_Double_Window* make_print_panel();
+extern Fl_Menu_Item menu_print_page_size[];
+extern void print_cb(Fl_Return_Button *, void *);
+void print_load();
+void print_update_status();
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/template_panel.cxx b/Utilities/FLTK/fluid/template_panel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..01b1a35dd7c4614714f3c59609be854482f91a4c
--- /dev/null
+++ b/Utilities/FLTK/fluid/template_panel.cxx
@@ -0,0 +1,260 @@
+//
+// "$Id$"
+//
+// FLUID template support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "template_panel.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "../src/flstring.h"
+#include <errno.h>
+#include <FL/filename.H>
+#include <FL/fl_ask.H>
+#include <FL/Fl_Shared_Image.H>
+#include <FL/Fl_Preferences.H>
+#if defined(WIN32) && !defined(__CYGWIN__)
+#include <io.h>
+#else
+#include <unistd.h>
+#endif // WIN32 && !__CYGWIN__
+extern Fl_Preferences fluid_prefs;
+
+Fl_Double_Window *template_panel=(Fl_Double_Window *)0;
+
+static void cb_template_panel(Fl_Double_Window*, void*) {
+  Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+
+template_browser->deselect();
+template_name->value("");
+template_instance->value("");
+template_panel->hide();
+}
+
+Fl_Browser *template_browser=(Fl_Browser *)0;
+
+static void cb_template_browser(Fl_Browser*, void*) {
+  if (Fl::event_clicks()) {
+  template_panel->hide();
+  return;
+}
+Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+template_preview->redraw();
+
+int item = template_browser->value();
+
+if (item <= 1) template_instance->deactivate();
+else template_instance->activate();
+
+if (item < 1) {
+  template_submit->deactivate();
+  template_delete->deactivate();
+  return;
+}
+
+template_submit->activate();
+
+const char *flfile = (const char *)template_browser->data(item);
+if (!flfile) {
+  template_delete->deactivate();
+  return;
+}
+
+template_name->value(template_browser->text(item));
+
+template_delete->activate();
+
+char pngfile[1024], *ext;
+
+strlcpy(pngfile, flfile, sizeof(pngfile));
+if ((ext = strrchr(pngfile, '.')) == NULL) return;
+strcpy(ext, ".png");
+
+img = Fl_Shared_Image::get(pngfile);
+
+if (img) {
+  template_preview->image(img);
+  template_preview->redraw();
+};
+}
+
+Fl_Box *template_preview=(Fl_Box *)0;
+
+Fl_Input *template_name=(Fl_Input *)0;
+
+static void cb_template_name(Fl_Input*, void*) {
+  if (strlen(template_name->value())) {
+  template_submit->activate();
+  if (Fl::event_key() == FL_Enter) template_panel->hide();
+} else template_submit->deactivate();
+}
+
+Fl_Input *template_instance=(Fl_Input *)0;
+
+Fl_Button *template_delete=(Fl_Button *)0;
+
+static void cb_Cancel(Fl_Button*, void*) {
+  Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+
+template_browser->deselect();
+template_name->value("");
+template_instance->value("");
+template_panel->hide();
+}
+
+Fl_Return_Button *template_submit=(Fl_Return_Button *)0;
+
+static void cb_template_submit(Fl_Return_Button*, void*) {
+  Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+
+template_panel->hide();
+}
+
+Fl_Double_Window* make_template_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = template_panel = new Fl_Double_Window(460, 355, "New/Save Template");
+    w = o;
+    o->callback((Fl_Callback*)cb_template_panel);
+    { Fl_Browser* o = template_browser = new Fl_Browser(10, 28, 180, 250, "Available Templates:");
+      o->type(2);
+      o->labelfont(1);
+      o->callback((Fl_Callback*)cb_template_browser);
+      o->align(FL_ALIGN_TOP_LEFT);
+      o->when(3);
+    }
+    { Fl_Box* o = template_preview = new Fl_Box(200, 28, 250, 250);
+      o->box(FL_THIN_DOWN_BOX);
+      o->align(69|FL_ALIGN_INSIDE);
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Input* o = template_name = new Fl_Input(124, 288, 326, 25, "Template Name:");
+      o->labelfont(1);
+      o->textfont(4);
+      o->callback((Fl_Callback*)cb_template_name);
+      o->when(3);
+    }
+    { Fl_Input* o = template_instance = new Fl_Input(124, 288, 326, 25, "Instance Name:");
+      o->labelfont(1);
+      o->textfont(4);
+      o->hide();
+    }
+    { Fl_Group* o = new Fl_Group(10, 323, 440, 25);
+      { Fl_Button* o = template_delete = new Fl_Button(10, 323, 133, 25, "Delete Template");
+        o->callback((Fl_Callback*)template_delete_cb);
+      }
+      { Fl_Box* o = new Fl_Box(153, 323, 126, 25);
+        Fl_Group::current()->resizable(o);
+      }
+      { Fl_Button* o = new Fl_Button(289, 323, 72, 25, "Cancel");
+        o->callback((Fl_Callback*)cb_Cancel);
+      }
+      { Fl_Return_Button* o = template_submit = new Fl_Return_Button(371, 323, 79, 25, "Save");
+        o->callback((Fl_Callback*)cb_template_submit);
+      }
+      o->end();
+    }
+    o->set_modal();
+    o->end();
+  }
+  return w;
+}
+
+void template_clear() {
+  int i;
+void *filename;
+
+for (i = 1; i <= template_browser->size(); i ++) {
+  if ((filename = template_browser->data(i)) != NULL) free(filename);
+}
+
+template_browser->deselect();
+template_browser->clear();
+}
+
+void template_delete_cb(Fl_Button *, void *) {
+  int item = template_browser->value();
+if (item < 1) return;
+
+const char *name = template_browser->text(item);
+const char *flfile = (const char *)template_browser->data(item);
+if (!flfile) return;
+
+if (!fl_choice("Are you sure you want to delete the template \"%s\"?",
+               "Cancel", "Delete", 0, name)) return;
+
+if (unlink(flfile)) {
+  fl_alert("Unable to delete template \"%s\":\n%s", name, strerror(errno));
+  return;
+}
+
+template_browser->remove(item);
+template_browser->do_callback();
+}
+
+void template_load() {
+  int i;
+char name[1024], filename[1024], path[1024], *ptr;
+struct dirent **files;
+int num_files;
+
+fluid_prefs.getUserdataPath(path, sizeof(path));
+strlcat(path, "templates", sizeof(path));
+
+num_files = fl_filename_list(path, &files);
+
+for (i = 0; i < num_files; i ++) {
+  if (fl_filename_match(files[i]->d_name, "*.fl")) {
+    // Format the name as the filename with "_" replaced with " "
+    // and without the trailing ".fl"...
+    strlcpy(name, files[i]->d_name, sizeof(name));
+    *strstr(name, ".fl") = '\0';
+
+    for (ptr = name; *ptr; ptr ++) {
+      if (*ptr == '_') *ptr = ' ';
+    }
+
+    // Add the template to the browser...
+    snprintf(filename, sizeof(filename), "%s/%s", path, files[i]->d_name);
+    template_browser->add(name, strdup(filename));
+  }
+
+  free(files[i]);
+}
+
+if (num_files > 0) free(files);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/template_panel.fl b/Utilities/FLTK/fluid/template_panel.fl
new file mode 100644
index 0000000000000000000000000000000000000000..8192ead4478e47baa16684717229278a18f91892
--- /dev/null
+++ b/Utilities/FLTK/fluid/template_panel.fl
@@ -0,0 +1,244 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {.h} 
+code_name {.cxx}
+comment {//
+// "$Id$"
+//
+// FLUID template support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {in_source in_header
+} 
+
+decl {\#include <stdio.h>} {} 
+
+decl {\#include <stdlib.h>} {} 
+
+decl {\#include "../src/flstring.h"} {} 
+
+decl {\#include <errno.h>} {} 
+
+decl {\#include <FL/filename.H>} {} 
+
+decl {\#include <FL/fl_ask.H>} {} 
+
+decl {\#include <FL/Fl_Shared_Image.H>} {} 
+
+decl {\#include <FL/Fl_Preferences.H>} {} 
+
+declblock {\#if defined(WIN32) && !defined(__CYGWIN__)} {selected after {\#endif // WIN32 && !__CYGWIN__}
+} {
+  decl {\#include <io.h>} {}
+  decl {\#else} {}
+  decl {\#include <unistd.h>} {}
+} 
+
+decl {extern Fl_Preferences fluid_prefs;} {} 
+
+Function {make_template_panel()} {open
+} {
+  Fl_Window template_panel {
+    label {New/Save Template}
+    callback {Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+
+template_browser->deselect();
+template_name->value("");
+template_instance->value("");
+template_panel->hide();} open
+    xywh {340 237 460 355} type Double resizable modal visible
+  } {
+    Fl_Browser template_browser {
+      label {Available Templates:}
+      callback {if (Fl::event_clicks()) {
+  template_panel->hide();
+  return;
+}
+Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+template_preview->redraw();
+
+int item = template_browser->value();
+
+if (item <= 1) template_instance->deactivate();
+else template_instance->activate();
+
+if (item < 1) {
+  template_submit->deactivate();
+  template_delete->deactivate();
+  return;
+}
+
+template_submit->activate();
+
+const char *flfile = (const char *)template_browser->data(item);
+if (!flfile) {
+  template_delete->deactivate();
+  return;
+}
+
+template_name->value(template_browser->text(item));
+
+template_delete->activate();
+
+char pngfile[1024], *ext;
+
+strlcpy(pngfile, flfile, sizeof(pngfile));
+if ((ext = strrchr(pngfile, '.')) == NULL) return;
+strcpy(ext, ".png");
+
+img = Fl_Shared_Image::get(pngfile);
+
+if (img) {
+  template_preview->image(img);
+  template_preview->redraw();
+}}
+      xywh {10 28 180 250} type Hold labelfont 1 align 5 when 3
+    }
+    Fl_Box template_preview {
+      xywh {200 28 250 250} box THIN_DOWN_BOX align 85 resizable
+    }
+    Fl_Input template_name {
+      label {Template Name:}
+      callback {if (strlen(template_name->value())) {
+  template_submit->activate();
+  if (Fl::event_key() == FL_Enter) template_panel->hide();
+} else template_submit->deactivate();}
+      xywh {124 288 326 25} labelfont 1 when 3 textfont 4
+    }
+    Fl_Input template_instance {
+      label {Instance Name:}
+      xywh {124 288 326 25} labelfont 1 textfont 4 hide
+    }
+    Fl_Group {} {
+      xywh {10 323 440 25}
+    } {
+      Fl_Button template_delete {
+        label {Delete Template}
+        callback template_delete_cb
+        xywh {10 323 133 25}
+      }
+      Fl_Box {} {
+        xywh {153 323 126 25} resizable
+      }
+      Fl_Button {} {
+        label Cancel
+        callback {Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+
+template_browser->deselect();
+template_name->value("");
+template_instance->value("");
+template_panel->hide();}
+        xywh {289 323 72 25}
+      }
+      Fl_Return_Button template_submit {
+        label Save
+        callback {Fl_Shared_Image *img = (Fl_Shared_Image *)template_preview->image();
+if (img) img->release();
+template_preview->image(0);
+
+template_panel->hide();}
+        xywh {371 323 79 25}
+      }
+    }
+  }
+} 
+
+Function {template_clear()} {return_type void
+} {
+  code {int i;
+void *filename;
+
+for (i = 1; i <= template_browser->size(); i ++) {
+  if ((filename = template_browser->data(i)) != NULL) free(filename);
+}
+
+template_browser->deselect();
+template_browser->clear();} {}
+} 
+
+Function {template_delete_cb(Fl_Button *, void *)} {return_type void
+} {
+  code {int item = template_browser->value();
+if (item < 1) return;
+
+const char *name = template_browser->text(item);
+const char *flfile = (const char *)template_browser->data(item);
+if (!flfile) return;
+
+if (!fl_choice("Are you sure you want to delete the template \\"%s\\"?",
+               "Cancel", "Delete", 0, name)) return;
+
+if (unlink(flfile)) {
+  fl_alert("Unable to delete template \\"%s\\":\\n%s", name, strerror(errno));
+  return;
+}
+
+template_browser->remove(item);
+template_browser->do_callback();} {}
+} 
+
+Function {template_load()} {open return_type void
+} {
+  code {int i;
+char name[1024], filename[1024], path[1024], *ptr;
+struct dirent **files;
+int num_files;
+
+fluid_prefs.getUserdataPath(path, sizeof(path));
+strlcat(path, "templates", sizeof(path));
+
+num_files = fl_filename_list(path, &files);
+
+for (i = 0; i < num_files; i ++) {
+  if (fl_filename_match(files[i]->d_name, "*.fl")) {
+    // Format the name as the filename with "_" replaced with " "
+    // and without the trailing ".fl"...
+    strlcpy(name, files[i]->d_name, sizeof(name));
+    *strstr(name, ".fl") = '\\0';
+
+    for (ptr = name; *ptr; ptr ++) {
+      if (*ptr == '_') *ptr = ' ';
+    }
+
+    // Add the template to the browser...
+    snprintf(filename, sizeof(filename), "%s/%s", path, files[i]->d_name);
+    template_browser->add(name, strdup(filename));
+  }
+
+  free(files[i]);
+}
+
+if (num_files > 0) free(files);} {}
+} 
+
+comment {
+//
+// End of "$Id$".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/fluid/template_panel.h b/Utilities/FLTK/fluid/template_panel.h
new file mode 100644
index 0000000000000000000000000000000000000000..df5898a88f308a912d37e833fff7db2b32d3a5eb
--- /dev/null
+++ b/Utilities/FLTK/fluid/template_panel.h
@@ -0,0 +1,56 @@
+//
+// "$Id$"
+//
+// FLUID template support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef template_panel_h
+#define template_panel_h
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+extern Fl_Double_Window *template_panel;
+#include <FL/Fl_Browser.H>
+extern Fl_Browser *template_browser;
+#include <FL/Fl_Box.H>
+extern Fl_Box *template_preview;
+#include <FL/Fl_Input.H>
+extern Fl_Input *template_name;
+extern Fl_Input *template_instance;
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Button.H>
+extern void template_delete_cb(Fl_Button*, void*);
+extern Fl_Button *template_delete;
+#include <FL/Fl_Return_Button.H>
+extern Fl_Return_Button *template_submit;
+Fl_Double_Window* make_template_panel();
+void template_clear();
+void template_delete_cb(Fl_Button *, void *);
+void template_load();
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/undo.cxx b/Utilities/FLTK/fluid/undo.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e23b6ca16166e323b15ca3a8e436868f54f6ea6f
--- /dev/null
+++ b/Utilities/FLTK/fluid/undo.cxx
@@ -0,0 +1,189 @@
+//
+// "$Id$"
+//
+// FLUID undo support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include "Fl_Type.h"
+#include "undo.h"
+#include <FL/Fl_Preferences.H>
+#include "../src/flstring.h"
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  include <io.h>
+#  include <windows.h>
+#  define getpid (int)GetCurrentProcessId
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define unlink _unlink
+#else
+#  include <unistd.h>
+#endif // WIN32 && !__CYGWIN__
+
+
+extern Fl_Preferences	fluid_prefs;	// FLUID preferences
+extern Fl_Menu_Item	Main_Menu[];	// Main menu
+
+#define UNDO_ITEM	25		// Undo menu item index
+#define REDO_ITEM	26		// Redo menu item index
+
+
+//
+// This file implements an undo system using temporary files; ideally
+// we'd like to do this in memory, however the current data structures
+// and design aren't well-suited...  Instead, we save and restore
+// checkpoint files.
+//
+
+
+int undo_current = 0;			// Current undo level in buffer
+int undo_last = 0;			// Last undo level in buffer
+int undo_max = 0;			// Maximum undo level used
+int undo_save = -1;			// Last undo level that was saved
+static int undo_paused = 0;		// Undo checkpointing paused?
+
+
+// Return the undo filename
+static char *undo_filename(int level, char *buf, int bufsize) {
+  static char	undo_path[1024] = "";	// Undo path
+
+
+  if (!undo_path[0]) fluid_prefs.getUserdataPath(undo_path, sizeof(undo_path));
+
+  snprintf(buf, bufsize, "%sundo_%d_%d.fl", undo_path, getpid(), level);
+  return buf;
+}
+
+
+// Redo menu callback
+void redo_cb(Fl_Widget *, void *) {
+  char	filename[1024];			// Undo checkpoint file
+
+  if (undo_current >= undo_last) return;
+
+  undo_suspend();
+  if (!read_file(undo_filename(undo_current + 1, filename, sizeof(filename)), 0)) {
+    // Unable to read checkpoint file, don't redo...
+    undo_resume();
+    return;
+  }
+
+  undo_current ++;
+
+  // Update modified flag...
+  set_modflag(undo_current != undo_save);
+
+  // Update undo/redo menu items...
+  if (undo_current >= undo_last) Main_Menu[REDO_ITEM].deactivate();
+  Main_Menu[UNDO_ITEM].activate();
+}
+
+// Undo menu callback
+void undo_cb(Fl_Widget *, void *) {
+  char	filename[1024];			// Undo checkpoint file
+
+  if (undo_current <= 0) return;
+
+  if (undo_current == undo_last) {
+    write_file(undo_filename(undo_current, filename, sizeof(filename)));
+  }
+
+  undo_suspend();
+  if (!read_file(undo_filename(undo_current - 1, filename, sizeof(filename)), 0)) {
+    // Unable to read checkpoint file, don't undo...
+    undo_resume();
+    return;
+  }
+
+  undo_current --;
+
+  // Update modified flag...
+  set_modflag(undo_current != undo_save);
+
+  // Update undo/redo menu items...
+  if (undo_current <= 0) Main_Menu[UNDO_ITEM].deactivate();
+  Main_Menu[REDO_ITEM].activate();
+}
+
+// Save current file to undo buffer
+void undo_checkpoint() {
+  char	filename[1024];			// Undo checkpoint filename
+
+//  printf("undo_checkpoint(): undo_current=%d, undo_paused=%d, modflag=%d\n",
+//         undo_current, undo_paused, modflag);
+
+  // Don't checkpoint if undo_suspend() has been called...
+  if (undo_paused) return;
+
+  // Save the current UI to a checkpoint file...
+  if (!write_file(undo_filename(undo_current, filename, sizeof(filename)))) {
+    // Don't attempt to do undo stuff if we can't write a checkpoint file...
+    perror(filename);
+    return;
+  }
+
+  // Update the saved level...
+  if (modflag && undo_current <= undo_save) undo_save = -1;
+  else if (!modflag) undo_save = undo_current;
+
+  // Update the current undo level...
+  undo_current ++;
+  undo_last = undo_current;
+  if (undo_current > undo_max) undo_max = undo_current;
+
+  // Enable the Undo and disable the Redo menu items...
+  Main_Menu[UNDO_ITEM].activate();
+  Main_Menu[REDO_ITEM].deactivate();
+}
+
+// Clear undo buffer
+void undo_clear() {
+  char	filename[1024];			// Undo checkpoint filename
+
+
+  // Remove old checkpoint files...
+  for (int i = 0; i <= undo_max; i ++) {
+    unlink(undo_filename(i, filename, sizeof(filename)));
+  }
+
+  // Reset current, last, and save indices...
+  undo_current = undo_last = undo_max = 0;
+  if (modflag) undo_save = -1;
+  else undo_save = 0;
+}
+
+// Resume undo checkpoints
+void undo_resume() {
+  undo_paused = 0;
+}
+
+// Suspend undo checkpoints
+void undo_suspend() {
+  undo_paused = 1;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/undo.h b/Utilities/FLTK/fluid/undo.h
new file mode 100644
index 0000000000000000000000000000000000000000..949f150e539cf7a3ada11452ba5517388272c858
--- /dev/null
+++ b/Utilities/FLTK/fluid/undo.h
@@ -0,0 +1,46 @@
+//
+// "$Id$"
+//
+// FLUID undo definitions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifndef undo_h
+#  define undo_h
+
+extern int undo_current;		// Current undo level in buffer
+extern int undo_last;			// Last undo level in buffer
+extern int undo_save;			// Last undo level that was saved
+
+void redo_cb(Fl_Widget *, void *);	// Redo menu callback
+void undo_cb(Fl_Widget *, void *);	// Undo menu callback
+void undo_checkpoint();			// Save current file to undo buffer
+void undo_clear();			// Clear undo buffer
+void undo_resume();			// Resume undo checkpoints
+void undo_suspend();			// Suspend undo checkpoints
+
+#endif // !undo_h
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/widget_panel.cxx b/Utilities/FLTK/fluid/widget_panel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1adf4c4367020f0b33ffe35b334fa1068ab683f5
--- /dev/null
+++ b/Utilities/FLTK/fluid/widget_panel.cxx
@@ -0,0 +1,764 @@
+//
+// "$Id$"
+//
+// Widget panel for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "widget_panel.h"
+
+static void cb_(Fl_Tabs* o, void* v) {
+  propagate_load((Fl_Group *)o,v);
+}
+
+Fl_Value_Input *widget_x_input=(Fl_Value_Input *)0;
+
+Fl_Value_Input *widget_y_input=(Fl_Value_Input *)0;
+
+Fl_Value_Input *widget_w_input=(Fl_Value_Input *)0;
+
+Fl_Value_Input *widget_h_input=(Fl_Value_Input *)0;
+
+Fl_Input *v_input[4]={(Fl_Input *)0};
+
+Fl_Button *wLiveMode=(Fl_Button *)0;
+
+Fl_Double_Window* make_widget_panel() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = new Fl_Double_Window(410, 355);
+    w = o;
+    o->labelsize(11);
+    w->hotspot(o);
+    { Fl_Tabs* o = new Fl_Tabs(5, 5, 400, 310);
+      o->selection_color((Fl_Color)4);
+      o->labelsize(11);
+      o->labelcolor(FL_BACKGROUND2_COLOR);
+      o->callback((Fl_Callback*)cb_);
+      o->when(FL_WHEN_NEVER);
+      { Fl_Group* o = new Fl_Group(5, 25, 400, 290, "GUI");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)propagate_load);
+        o->when(FL_WHEN_NEVER);
+        { Fl_Group* o = new Fl_Group(90, 35, 300, 20, "Label:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 35, 180, 20);
+            o->tooltip("The label text for the widget.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)label_cb);
+            o->when(FL_WHEN_CHANGED);
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Choice* o = new Fl_Choice(270, 35, 120, 20);
+            o->tooltip("The label style for the widget.");
+            o->box(FL_THIN_UP_BOX);
+            o->down_box(FL_BORDER_BOX);
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)labeltype_cb);
+            o->menu(labeltypemenu);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 60, 300, 20, "Image:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 60, 230, 20);
+            o->tooltip("The active image for the widget.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)image_cb);
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Button* o = new Fl_Button(320, 60, 70, 20, "Browse...");
+            o->tooltip("Click to choose the active image.");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)image_browse_cb);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 85, 300, 20, "Inactive:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 85, 230, 20);
+            o->tooltip("The inactive image for the widget.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)inactive_cb);
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Button* o = new Fl_Button(320, 85, 70, 20, "Browse...");
+            o->tooltip("Click to choose the inactive image.");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)inactive_browse_cb);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 110, 300, 20, "Alignment:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Button* o = new Fl_Button(90, 110, 45, 20, "Clip");
+            o->tooltip("Clip the label to the inside of the widget.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_CLIP));
+            o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
+          }
+          { Fl_Button* o = new Fl_Button(140, 110, 50, 20, "Wrap");
+            o->tooltip("Wrap the label text.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_WRAP));
+          }
+          { Fl_Button* o = new Fl_Button(195, 110, 65, 20, "Text/Image");
+            o->tooltip("Show the label text over the image.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_TEXT_OVER_IMAGE));
+          }
+          { Fl_Button* o = new Fl_Button(265, 110, 20, 20, "@-1<-");
+            o->tooltip("Left-align the label.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->labelcolor(FL_INACTIVE_COLOR);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_LEFT));
+          }
+          { Fl_Button* o = new Fl_Button(290, 110, 20, 20, "@-1->");
+            o->tooltip("Right-align the label.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->labelcolor(FL_INACTIVE_COLOR);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_RIGHT));
+          }
+          { Fl_Button* o = new Fl_Button(315, 110, 20, 20, "@-18");
+            o->tooltip("Top-align the label.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->labelcolor(FL_INACTIVE_COLOR);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_TOP));
+          }
+          { Fl_Button* o = new Fl_Button(340, 110, 20, 20, "@-12");
+            o->tooltip("Bottom-align the label.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->labelcolor(FL_INACTIVE_COLOR);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_BOTTOM));
+          }
+          { Fl_Button* o = new Fl_Button(365, 110, 20, 20, "@-3square");
+            o->tooltip("Show the label inside the widget.");
+            o->type(1);
+            o->selection_color(FL_INACTIVE_COLOR);
+            o->labelsize(11);
+            o->labelcolor(FL_INACTIVE_COLOR);
+            o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_INSIDE));
+          }
+          { Fl_Box* o = new Fl_Box(390, 110, 0, 20);
+            o->labelsize(11);
+            Fl_Group::current()->resizable(o);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 145, 300, 20, "Position:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Value_Input* o = widget_x_input = new Fl_Value_Input(90, 145, 55, 20, "X:");
+            o->tooltip("The X position of the widget.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)x_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = widget_y_input = new Fl_Value_Input(150, 145, 55, 20, "Y:");
+            o->tooltip("The Y position of the widget.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)y_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = widget_w_input = new Fl_Value_Input(210, 145, 55, 20, "Width:");
+            o->tooltip("The width of the widget.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)w_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = widget_h_input = new Fl_Value_Input(270, 145, 55, 20, "Height:");
+            o->tooltip("The height of the widget.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)h_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(330, 145, 55, 20, "Relative");
+            o->tooltip("If set, widgets inside a widget class of type Fl_Group are repositioned relat\
+ive to the origin at construction time");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)wc_relative_cb);
+          }
+          { Fl_Box* o = new Fl_Box(389, 145, 1, 20);
+            Fl_Group::current()->resizable(o);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 180, 300, 20, "Values:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Value_Input* o = new Fl_Value_Input(90, 180, 55, 20, "Size:");
+            o->tooltip("The size of the slider.");
+            o->labelsize(11);
+            o->step(0.010101);
+            o->textsize(11);
+            o->callback((Fl_Callback*)slider_size_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(150, 180, 55, 20, "Minimum:");
+            o->tooltip("The minimum value of the widget.");
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)min_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(210, 180, 55, 20, "Maximum:");
+            o->tooltip("The maximum value of the widget.");
+            o->labelsize(11);
+            o->value(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)max_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(270, 180, 55, 20, "Step:");
+            o->tooltip("The resolution of the widget value.");
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)step_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(330, 180, 55, 20, "Value:");
+            o->tooltip("The current widget value.");
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)value_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Box* o = new Fl_Box(390, 180, 0, 20);
+            Fl_Group::current()->resizable(o);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 180, 300, 20, "Size Range:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          o->hide();
+          { Fl_Value_Input* o = new Fl_Value_Input(90, 180, 55, 20, "Minimum Size:");
+            o->tooltip("The size of the slider.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)min_w_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(150, 180, 55, 20);
+            o->tooltip("The minimum value of the widget.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)min_h_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Button* o = new Fl_Button(210, 180, 25, 20, "set");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)set_min_size_cb);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(240, 180, 55, 20, "Maximum Size:");
+            o->tooltip("The maximum value of the widget.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)max_w_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(300, 180, 55, 20);
+            o->tooltip("The resolution of the widget value.");
+            o->labelsize(11);
+            o->maximum(2048);
+            o->step(1);
+            o->textsize(11);
+            o->callback((Fl_Callback*)max_h_cb);
+            o->align(FL_ALIGN_TOP_LEFT);
+          }
+          { Fl_Button* o = new Fl_Button(360, 180, 25, 20, "set");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)set_max_size_cb);
+          }
+          { Fl_Box* o = new Fl_Box(390, 180, 0, 20);
+            Fl_Group::current()->resizable(o);
+          }
+          o->end();
+        }
+        { Shortcut_Button* o = new Shortcut_Button(90, 205, 300, 20, "Shortcut:");
+          o->tooltip("The shortcut key for the widget.");
+          o->box(FL_DOWN_BOX);
+          o->color(FL_BACKGROUND2_COLOR);
+          o->selection_color(FL_BACKGROUND2_COLOR);
+          o->labeltype(FL_NORMAL_LABEL);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->labelcolor(FL_FOREGROUND_COLOR);
+          o->callback((Fl_Callback*)shortcut_in_cb);
+          o->align(FL_ALIGN_LEFT);
+          o->when(FL_WHEN_RELEASE);
+        }
+        { Fl_Group* o = new Fl_Group(90, 230, 300, 20, "X Class:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 230, 95, 20, ":");
+            o->tooltip("The X resource class.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)xclass_cb);
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(190, 230, 60, 20, "Border");
+            o->tooltip("Add a border around the window.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)border_cb);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(255, 230, 55, 20, "Modal");
+            o->tooltip("Make the window modal.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)modal_cb);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(315, 230, 75, 20, "Nonmodal");
+            o->tooltip("Make the window non-modal.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)non_modal_cb);
+            o->align(132|FL_ALIGN_INSIDE);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 255, 305, 20, "Attributes:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Light_Button* o = new Fl_Light_Button(90, 255, 60, 20, "Visible");
+            o->tooltip("Show the widget.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)visible_cb);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(155, 255, 60, 20, "Active");
+            o->tooltip("Activate the widget.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)active_cb);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(220, 255, 75, 20, "Resizable");
+            o->tooltip("Make the widget resizable.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)resizable_cb);
+            o->when(FL_WHEN_CHANGED);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(300, 255, 70, 20, "Hotspot");
+            o->tooltip("Center the window under this widget.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)hotspot_cb);
+            o->when(FL_WHEN_CHANGED);
+          }
+          { Fl_Box* o = new Fl_Box(390, 255, 0, 20);
+            o->labelsize(11);
+            Fl_Group::current()->resizable(o);
+          }
+          o->end();
+        }
+        { Fl_Input* o = new Fl_Input(90, 280, 300, 20, "Tooltip:");
+          o->tooltip("The tooltip text for the widget.");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textsize(11);
+          o->callback((Fl_Callback*)tooltip_cb);
+        }
+        { Fl_Box* o = new Fl_Box(90, 300, 300, 5);
+          o->labelsize(11);
+          Fl_Group::current()->resizable(o);
+        }
+        o->end();
+        Fl_Group::current()->resizable(o);
+      }
+      { Fl_Group* o = new Fl_Group(5, 25, 400, 290, "Style");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)propagate_load);
+        o->when(FL_WHEN_NEVER);
+        o->hide();
+        { Fl_Group* o = new Fl_Group(90, 35, 300, 20, "Label Font:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Choice* o = new Fl_Choice(90, 35, 160, 20);
+            o->tooltip("The style of the label text.");
+            o->box(FL_THIN_UP_BOX);
+            o->down_box(FL_BORDER_BOX);
+            o->labelfont(1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)labelfont_cb);
+            Fl_Group::current()->resizable(o);
+            o->menu(fontmenu);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(250, 35, 50, 20);
+            o->tooltip("The size of the label text.");
+            o->labelsize(11);
+            o->maximum(100);
+            o->step(1);
+            o->value(14);
+            o->textsize(11);
+            o->callback((Fl_Callback*)labelsize_cb);
+          }
+          { Fl_Button* o = new Fl_Button(300, 35, 90, 20, "Label Color");
+            o->tooltip("The color of the label text.");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)labelcolor_cb);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 60, 300, 20, "Box:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Choice* o = new Fl_Choice(90, 60, 210, 20);
+            o->tooltip("The \"up\" box of the widget.");
+            o->box(FL_THIN_UP_BOX);
+            o->down_box(FL_BORDER_BOX);
+            o->labelfont(1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)box_cb);
+            Fl_Group::current()->resizable(o);
+            o->menu(boxmenu);
+          }
+          { Fl_Button* o = new Fl_Button(300, 60, 90, 20, "Color");
+            o->tooltip("The background color of the widget.");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)color_cb);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 85, 300, 20, "Down Box:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Choice* o = new Fl_Choice(90, 85, 210, 20);
+            o->tooltip("The \"down\" box of the widget.");
+            o->box(FL_THIN_UP_BOX);
+            o->down_box(FL_BORDER_BOX);
+            o->labelfont(1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)down_box_cb);
+            Fl_Group::current()->resizable(o);
+            o->menu(boxmenu);
+          }
+          { Fl_Button* o = new Fl_Button(300, 85, 90, 20, "Select Color");
+            o->tooltip("The selection color of the widget.");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)color2_cb);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 110, 300, 20, "Text Font:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Choice* o = new Fl_Choice(90, 110, 160, 20);
+            o->tooltip("The value text style.");
+            o->box(FL_DOWN_BOX);
+            o->down_box(FL_BORDER_BOX);
+            o->labelfont(1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)textfont_cb);
+            Fl_Group::current()->resizable(o);
+            o->menu(fontmenu);
+          }
+          { Fl_Value_Input* o = new Fl_Value_Input(250, 110, 50, 20);
+            o->tooltip("The value text size.");
+            o->labelsize(11);
+            o->maximum(100);
+            o->step(1);
+            o->value(14);
+            o->textsize(11);
+            o->callback((Fl_Callback*)textsize_cb);
+          }
+          { Fl_Button* o = new Fl_Button(300, 110, 90, 20, "Text Color");
+            o->tooltip("The value text color.");
+            o->labelsize(11);
+            o->callback((Fl_Callback*)textcolor_cb);
+          }
+          o->end();
+        }
+        { Fl_Box* o = new Fl_Box(90, 135, 300, 40);
+          o->labelsize(11);
+          Fl_Group::current()->resizable(o);
+        }
+        o->end();
+      }
+      { Fl_Group* o = new Fl_Group(5, 25, 400, 290, "C++");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)propagate_load);
+        o->when(FL_WHEN_NEVER);
+        o->hide();
+        { Fl_Group* o = new Fl_Group(90, 35, 300, 20, "Class:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 35, 160, 20);
+            o->tooltip("The widget subclass.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textfont(4);
+            o->textsize(11);
+            o->callback((Fl_Callback*)subclass_cb, (void*)(4));
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Choice* o = new Fl_Choice(250, 35, 140, 20);
+            o->tooltip("The widget subtype.");
+            o->box(FL_THIN_UP_BOX);
+            o->down_box(FL_BORDER_BOX);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)subtype_cb);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 60, 300, 20, "Name:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 60, 240, 20);
+            o->tooltip("The name of the widget.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textsize(11);
+            o->callback((Fl_Callback*)name_cb);
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(330, 60, 60, 20, "public");
+            o->tooltip("Make the widget publicly accessible.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)name_public_cb);
+            o->when(FL_WHEN_CHANGED);
+          }
+          o->end();
+        }
+        { Fl_Input* o = v_input[0] = new Fl_Input(90, 85, 300, 20, "Extra Code:");
+          o->tooltip("Extra initialization code for the widget.");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)v_input_cb, (void*)(0));
+        }
+        { Fl_Input* o = v_input[1] = new Fl_Input(90, 105, 300, 20);
+          o->tooltip("Extra initialization code for the widget.");
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)v_input_cb, (void*)(1));
+        }
+        { Fl_Input* o = v_input[2] = new Fl_Input(90, 125, 300, 20);
+          o->tooltip("Extra initialization code for the widget.");
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)v_input_cb, (void*)(2));
+        }
+        { Fl_Input* o = v_input[3] = new Fl_Input(90, 145, 300, 20);
+          o->tooltip("Extra initialization code for the widget.");
+          o->labelsize(11);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)v_input_cb, (void*)(3));
+        }
+        { CodeEditor* o = new CodeEditor(90, 170, 300, 90, "Callback:");
+          o->tooltip("The callback function or code for the widget. Use the variable name \'o\' to \
+access the Widget pointer and \'v\' to access the user value.");
+          o->box(FL_DOWN_BOX);
+          o->color(FL_BACKGROUND2_COLOR);
+          o->selection_color(FL_SELECTION_COLOR);
+          o->labeltype(FL_NORMAL_LABEL);
+          o->labelfont(1);
+          o->labelsize(11);
+          o->labelcolor(FL_FOREGROUND_COLOR);
+          o->textfont(4);
+          o->textsize(11);
+          o->callback((Fl_Callback*)callback_cb);
+          o->align(FL_ALIGN_LEFT);
+          o->when(FL_WHEN_RELEASE);
+          Fl_Group::current()->resizable(o);
+        }
+        { Fl_Group* o = new Fl_Group(90, 265, 300, 20, "User Data:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 265, 140, 20);
+            o->tooltip("The user data to pass into the callback code.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textfont(4);
+            o->textsize(11);
+            o->callback((Fl_Callback*)user_data_cb);
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Choice* o = new Fl_Choice(285, 265, 105, 20, "When:");
+            o->tooltip("When to call the callback function.");
+            o->box(FL_THIN_UP_BOX);
+            o->down_box(FL_BORDER_BOX);
+            o->labelfont(1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)when_cb);
+            o->when(FL_WHEN_CHANGED);
+            o->menu(whenmenu);
+          }
+          o->end();
+        }
+        { Fl_Group* o = new Fl_Group(90, 290, 300, 20, "Type:");
+          o->labelfont(1);
+          o->labelsize(11);
+          o->callback((Fl_Callback*)propagate_load);
+          o->align(FL_ALIGN_LEFT);
+          { Fl_Input* o = new Fl_Input(90, 290, 140, 20);
+            o->tooltip("The type of the user data.");
+            o->labelfont(1);
+            o->labelsize(11);
+            o->textfont(4);
+            o->textsize(11);
+            o->callback((Fl_Callback*)user_data_type_cb);
+            Fl_Group::current()->resizable(o);
+          }
+          { Fl_Light_Button* o = new Fl_Light_Button(285, 290, 105, 20, "No Change");
+            o->tooltip("Call the callback even if the value has not changed.");
+            o->selection_color((Fl_Color)1);
+            o->labelsize(11);
+            o->callback((Fl_Callback*)when_button_cb);
+          }
+          o->end();
+        }
+        o->end();
+      }
+      o->end();
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Group* o = new Fl_Group(8, 321, 391, 24);
+      o->labelsize(11);
+      { Fl_Box* o = new Fl_Box(8, 325, 20, 20);
+        o->labelsize(11);
+        Fl_Group::current()->resizable(o);
+      }
+      { Fl_Button* o = new Fl_Button(231, 325, 99, 20, "Hide &Overlays");
+        o->tooltip("Hide the widget overlay box.");
+        o->labelsize(11);
+        o->labelcolor((Fl_Color)1);
+        o->callback((Fl_Callback*)overlay_cb);
+      }
+      { Fl_Button* o = new Fl_Button(80, 325, 80, 20, "Revert");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)revert_cb);
+        o->hide();
+      }
+      { Fl_Return_Button* o = new Fl_Return_Button(335, 325, 64, 20, "Close");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)ok_cb);
+      }
+      { Fl_Button* o = new Fl_Button(329, 325, 70, 20, "Cancel");
+        o->labelsize(11);
+        o->callback((Fl_Callback*)cancel_cb);
+        o->hide();
+      }
+      { Fl_Button* o = wLiveMode = new Fl_Button(142, 325, 84, 20, "Live &Mode");
+        o->tooltip("Create a live duplicate of the selected widgets to test resizing and menu beh\
+avior.");
+        o->type(1);
+        o->labelsize(11);
+        o->callback((Fl_Callback*)live_mode_cb);
+      }
+      o->end();
+    }
+    o->size_range(o->w(), o->h());
+    o->end();
+  }
+  return w;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/widget_panel.fl b/Utilities/FLTK/fluid/widget_panel.fl
new file mode 100644
index 0000000000000000000000000000000000000000..df6da0281e55bbc02df6d541870336f1cf7f8271
--- /dev/null
+++ b/Utilities/FLTK/fluid/widget_panel.fl
@@ -0,0 +1,549 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {.h} 
+code_name {.cxx}
+comment {//
+// "$Id: widget_panel.fl 4625 2005-11-02 13:55:13Z matt $"
+//
+// Widget panel for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {in_source in_header
+} 
+
+Function {make_widget_panel()} {open
+} {
+  Fl_Window {} {open
+    xywh {353 184 410 355} type Double labelsize 11 resizable hotspot
+    code0 {o->size_range(o->w(), o->h());} visible
+  } {
+    Fl_Tabs {} {
+      callback {propagate_load((Fl_Group *)o,v);} open
+      xywh {5 5 400 310} selection_color 4 labelsize 11 labelcolor 7 when 0 resizable
+    } {
+      Fl_Group {} {
+        label GUI
+        callback propagate_load
+        xywh {5 25 400 290} labelsize 11 when 0 resizable
+      } {
+        Fl_Group {} {
+          label {Label:}
+          callback propagate_load
+          xywh {90 35 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            callback label_cb
+            tooltip {The label text for the widget.} xywh {90 35 180 20} labelfont 1 labelsize 11 when 1 textsize 11 resizable
+          }
+          Fl_Choice {} {
+            callback labeltype_cb open
+            tooltip {The label style for the widget.} xywh {270 35 120 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 textsize 11
+            code0 {extern Fl_Menu_Item labeltypemenu[];}
+            code1 {o->menu(labeltypemenu);}
+          } {}
+        }
+        Fl_Group {} {
+          label {Image:}
+          callback propagate_load
+          xywh {90 60 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            callback image_cb
+            tooltip {The active image for the widget.} xywh {90 60 230 20} labelfont 1 labelsize 11 textsize 11 resizable
+          }
+          Fl_Button {} {
+            label {Browse...}
+            callback image_browse_cb
+            tooltip {Click to choose the active image.} xywh {320 60 70 20} labelsize 11
+          }
+        }
+        Fl_Group {} {
+          label {Inactive:}
+          callback propagate_load
+          xywh {90 85 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            callback inactive_cb
+            tooltip {The inactive image for the widget.} xywh {90 85 230 20} labelfont 1 labelsize 11 textsize 11 resizable
+          }
+          Fl_Button {} {
+            label {Browse...}
+            callback inactive_browse_cb
+            tooltip {Click to choose the inactive image.} xywh {320 85 70 20} labelsize 11
+          }
+        }
+        Fl_Group {} {
+          label {Alignment:}
+          callback propagate_load
+          xywh {90 110 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Button {} {
+            label Clip
+            user_data FL_ALIGN_CLIP
+            callback align_cb
+            tooltip {Clip the label to the inside of the widget.} xywh {90 110 45 20} type Toggle selection_color 8 labelsize 11 align 16
+          }
+          Fl_Button {} {
+            label Wrap
+            user_data FL_ALIGN_WRAP
+            callback align_cb selected
+            tooltip {Wrap the label text.} xywh {140 110 50 20} type Toggle selection_color 8 labelsize 11
+          }
+          Fl_Button {} {
+            label {Text/Image}
+            user_data FL_ALIGN_TEXT_OVER_IMAGE
+            callback align_cb
+            tooltip {Show the label text over the image.} xywh {195 110 65 20} type Toggle selection_color 8 labelsize 11
+          }
+          Fl_Button {} {
+            label {@-1<-}
+            user_data FL_ALIGN_LEFT
+            callback align_cb
+            tooltip {Left-align the label.} xywh {265 110 20 20} type Toggle selection_color 8 labelsize 11 labelcolor 8
+          }
+          Fl_Button {} {
+            label {@-1->}
+            user_data FL_ALIGN_RIGHT
+            callback align_cb
+            tooltip {Right-align the label.} xywh {290 110 20 20} type Toggle selection_color 8 labelsize 11 labelcolor 8
+          }
+          Fl_Button {} {
+            label {@-18}
+            user_data FL_ALIGN_TOP
+            callback align_cb
+            tooltip {Top-align the label.} xywh {315 110 20 20} type Toggle selection_color 8 labelsize 11 labelcolor 8
+          }
+          Fl_Button {} {
+            label {@-12}
+            user_data FL_ALIGN_BOTTOM
+            callback align_cb
+            tooltip {Bottom-align the label.} xywh {340 110 20 20} type Toggle selection_color 8 labelsize 11 labelcolor 8
+          }
+          Fl_Button {} {
+            label {@-3square}
+            user_data FL_ALIGN_INSIDE
+            callback align_cb
+            tooltip {Show the label inside the widget.} xywh {365 110 20 20} type Toggle selection_color 8 labelsize 11 labelcolor 8
+          }
+          Fl_Box {} {
+            xywh {390 110 0 20} labelsize 11 resizable
+          }
+        }
+        Fl_Group {} {
+          label {Position:}
+          callback propagate_load open
+          xywh {90 145 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Value_Input widget_x_input {
+            label {X:}
+            callback x_cb
+            tooltip {The X position of the widget.} xywh {90 145 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Value_Input widget_y_input {
+            label {Y:}
+            callback y_cb
+            tooltip {The Y position of the widget.} xywh {150 145 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Value_Input widget_w_input {
+            label {Width:}
+            callback w_cb
+            tooltip {The width of the widget.} xywh {210 145 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Value_Input widget_h_input {
+            label {Height:}
+            callback h_cb
+            tooltip {The height of the widget.} xywh {270 145 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Light_Button {} {
+            label Relative
+            callback wc_relative_cb
+            tooltip {If set, widgets inside a widget class of type Fl_Group are repositioned relative to the origin at construction time} xywh {330 145 55 20} labelsize 11
+          }
+          Fl_Box {} {
+            xywh {389 145 1 20} resizable
+          }
+        }
+        Fl_Group {} {
+          label {Values:}
+          callback propagate_load
+          xywh {90 180 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Value_Input {} {
+            label {Size:}
+            callback slider_size_cb
+            tooltip {The size of the slider.} xywh {90 180 55 20} labelsize 11 align 5 step 0.010101 textsize 11
+          }
+          Fl_Value_Input {} {
+            label {Minimum:}
+            callback min_cb
+            tooltip {The minimum value of the widget.} xywh {150 180 55 20} labelsize 11 align 5 textsize 11
+          }
+          Fl_Value_Input {} {
+            label {Maximum:}
+            callback max_cb
+            tooltip {The maximum value of the widget.} xywh {210 180 55 20} labelsize 11 align 5 value 1 textsize 11
+          }
+          Fl_Value_Input {} {
+            label {Step:}
+            callback step_cb
+            tooltip {The resolution of the widget value.} xywh {270 180 55 20} labelsize 11 align 5 textsize 11
+          }
+          Fl_Value_Input {} {
+            label {Value:}
+            callback value_cb
+            tooltip {The current widget value.} xywh {330 180 55 20} labelsize 11 align 5 textsize 11
+          }
+          Fl_Box {} {
+            xywh {390 180 0 20} resizable
+          }
+        }
+        Fl_Group {} {
+          label {Size Range:}
+          callback propagate_load
+          xywh {90 180 300 20} labelfont 1 labelsize 11 align 4 hide
+        } {
+          Fl_Value_Input {} {
+            label {Minimum Size:}
+            callback min_w_cb
+            tooltip {The size of the slider.} xywh {90 180 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Value_Input {} {
+            callback min_h_cb
+            tooltip {The minimum value of the widget.} xywh {150 180 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Button {} {
+            label set
+            callback set_min_size_cb
+            xywh {210 180 25 20} labelsize 11
+          }
+          Fl_Value_Input {} {
+            label {Maximum Size:}
+            callback max_w_cb
+            tooltip {The maximum value of the widget.} xywh {240 180 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Value_Input {} {
+            callback max_h_cb
+            tooltip {The resolution of the widget value.} xywh {300 180 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+          }
+          Fl_Button {} {
+            label set
+            callback set_max_size_cb
+            xywh {360 180 25 20} labelsize 11
+          }
+          Fl_Box {} {
+            xywh {390 180 0 20} resizable
+          }
+        }
+        Fl_Button {} {
+          label {Shortcut:}
+          callback shortcut_in_cb
+          tooltip {The shortcut key for the widget.} xywh {90 205 300 20} box DOWN_BOX color 7 selection_color 7 labelfont 1 labelsize 11 align 4
+          code0 {\#include "Shortcut_Button.h"}
+          class Shortcut_Button
+        }
+        Fl_Group {} {
+          label {X Class:}
+          callback propagate_load
+          xywh {90 230 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            label {:}
+            callback xclass_cb
+            tooltip {The X resource class.} xywh {90 230 95 20} labelfont 1 labelsize 11 textsize 11 resizable
+          }
+          Fl_Light_Button {} {
+            label Border
+            callback border_cb
+            tooltip {Add a border around the window.} xywh {190 230 60 20} selection_color 1 labelsize 11
+          }
+          Fl_Light_Button {} {
+            label Modal
+            callback modal_cb
+            tooltip {Make the window modal.} xywh {255 230 55 20} selection_color 1 labelsize 11
+          }
+          Fl_Light_Button {} {
+            label Nonmodal
+            callback non_modal_cb
+            tooltip {Make the window non-modal.} xywh {315 230 75 20} selection_color 1 labelsize 11 align 148
+          }
+        }
+        Fl_Group {} {
+          label {Attributes:}
+          callback propagate_load
+          xywh {90 255 305 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Light_Button {} {
+            label Visible
+            callback visible_cb
+            tooltip {Show the widget.} xywh {90 255 60 20} selection_color 1 labelsize 11
+          }
+          Fl_Light_Button {} {
+            label Active
+            callback active_cb
+            tooltip {Activate the widget.} xywh {155 255 60 20} selection_color 1 labelsize 11
+          }
+          Fl_Light_Button {} {
+            label Resizable
+            callback resizable_cb
+            tooltip {Make the widget resizable.} xywh {220 255 75 20} selection_color 1 labelsize 11 when 1
+          }
+          Fl_Light_Button {} {
+            label Hotspot
+            callback hotspot_cb
+            tooltip {Center the window under this widget.} xywh {300 255 70 20} selection_color 1 labelsize 11 when 1
+          }
+          Fl_Box {} {
+            xywh {390 255 0 20} labelsize 11 resizable
+          }
+        }
+        Fl_Input {} {
+          label {Tooltip:}
+          callback tooltip_cb
+          tooltip {The tooltip text for the widget.} xywh {90 280 300 20} labelfont 1 labelsize 11 textsize 11
+        }
+        Fl_Box {} {
+          xywh {90 300 300 5} labelsize 11 resizable
+        }
+      }
+      Fl_Group {} {
+        label Style
+        callback propagate_load
+        xywh {5 25 400 290} labelsize 11 when 0 hide
+      } {
+        Fl_Group {} {
+          label {Label Font:}
+          callback propagate_load open
+          xywh {90 35 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Choice {} {
+            callback labelfont_cb open
+            tooltip {The style of the label text.} xywh {90 35 160 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 resizable
+            code0 {extern Fl_Menu_Item fontmenu[];}
+            code1 {o->menu(fontmenu);}
+          } {}
+          Fl_Value_Input {} {
+            callback labelsize_cb
+            tooltip {The size of the label text.} xywh {250 35 50 20} labelsize 11 maximum 100 step 1 value 14 textsize 11
+          }
+          Fl_Button {} {
+            label {Label Color}
+            callback labelcolor_cb
+            tooltip {The color of the label text.} xywh {300 35 90 20} labelsize 11
+          }
+        }
+        Fl_Group {} {
+          label {Box:}
+          callback propagate_load open
+          xywh {90 60 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Choice {} {
+            callback box_cb open
+            tooltip {The "up" box of the widget.} xywh {90 60 210 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 resizable
+            code0 {extern Fl_Menu_Item boxmenu[];}
+            code1 {o->menu(boxmenu);}
+          } {}
+          Fl_Button {} {
+            label Color
+            callback color_cb
+            tooltip {The background color of the widget.} xywh {300 60 90 20} labelsize 11
+          }
+        }
+        Fl_Group {} {
+          label {Down Box:}
+          callback propagate_load open
+          xywh {90 85 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Choice {} {
+            callback down_box_cb open
+            tooltip {The "down" box of the widget.} xywh {90 85 210 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 resizable
+            code0 {extern Fl_Menu_Item boxmenu[];}
+            code1 {o->menu(boxmenu);}
+          } {}
+          Fl_Button {} {
+            label {Select Color}
+            callback color2_cb
+            tooltip {The selection color of the widget.} xywh {300 85 90 20} labelsize 11
+          }
+        }
+        Fl_Group {} {
+          label {Text Font:}
+          callback propagate_load open
+          xywh {90 110 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Choice {} {
+            callback textfont_cb open
+            tooltip {The value text style.} xywh {90 110 160 20} box DOWN_BOX down_box BORDER_BOX labelfont 1 labelsize 11 resizable
+            code0 {extern Fl_Menu_Item fontmenu[];}
+            code1 {o->menu(fontmenu);}
+          } {}
+          Fl_Value_Input {} {
+            callback textsize_cb
+            tooltip {The value text size.} xywh {250 110 50 20} labelsize 11 maximum 100 step 1 value 14 textsize 11
+          }
+          Fl_Button {} {
+            label {Text Color}
+            callback textcolor_cb
+            tooltip {The value text color.} xywh {300 110 90 20} labelsize 11
+          }
+        }
+        Fl_Box {} {
+          xywh {90 135 300 40} labelsize 11 resizable
+        }
+      }
+      Fl_Group {} {
+        label {C++}
+        callback propagate_load
+        xywh {5 25 400 290} labelsize 11 when 0 hide
+      } {
+        Fl_Group {} {
+          label {Class:}
+          callback propagate_load
+          xywh {90 35 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            user_data 4
+            callback subclass_cb
+            tooltip {The widget subclass.} xywh {90 35 160 20} labelfont 1 labelsize 11 textfont 4 textsize 11 resizable
+          }
+          Fl_Choice {} {
+            callback subtype_cb open
+            tooltip {The widget subtype.} xywh {250 35 140 20} box THIN_UP_BOX down_box BORDER_BOX labelsize 11
+          } {}
+        }
+        Fl_Group {} {
+          label {Name:}
+          callback propagate_load
+          xywh {90 60 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            callback name_cb
+            tooltip {The name of the widget.} xywh {90 60 240 20} labelfont 1 labelsize 11 textsize 11 resizable
+          }
+          Fl_Light_Button {} {
+            label public
+            callback name_public_cb
+            tooltip {Make the widget publicly accessible.} xywh {330 60 60 20} selection_color 1 labelsize 11 when 1
+          }
+        }
+        Fl_Input {v_input[0]} {
+          label {Extra Code:}
+          user_data 0
+          callback v_input_cb
+          tooltip {Extra initialization code for the widget.} xywh {90 85 300 20} labelfont 1 labelsize 11 textfont 4 textsize 11
+        }
+        Fl_Input {v_input[1]} {
+          user_data 1
+          callback v_input_cb
+          tooltip {Extra initialization code for the widget.} xywh {90 105 300 20} labelsize 11 textfont 4 textsize 11
+        }
+        Fl_Input {v_input[2]} {
+          user_data 2
+          callback v_input_cb
+          tooltip {Extra initialization code for the widget.} xywh {90 125 300 20} labelsize 11 textfont 4 textsize 11
+        }
+        Fl_Input {v_input[3]} {
+          user_data 3
+          callback v_input_cb
+          tooltip {Extra initialization code for the widget.} xywh {90 145 300 20} labelsize 11 textfont 4 textsize 11
+        }
+        Fl_Text_Editor {} {
+          label {Callback:}
+          callback callback_cb
+          tooltip {The callback function or code for the widget. Use the variable name 'o' to access the Widget pointer and 'v' to access the user value.} xywh {90 170 300 90} box DOWN_BOX labelfont 1 labelsize 11 align 4 textfont 4 textsize 11 resizable
+          code0 {\#include "CodeEditor.h"}
+          class CodeEditor
+        }
+        Fl_Group {} {
+          label {User Data:}
+          callback propagate_load
+          xywh {90 265 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            callback user_data_cb
+            tooltip {The user data to pass into the callback code.} xywh {90 265 140 20} labelfont 1 labelsize 11 textfont 4 textsize 11 resizable
+          }
+          Fl_Choice {} {
+            label {When:}
+            callback when_cb open
+            tooltip {When to call the callback function.} xywh {285 265 105 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 when 1
+            code0 {extern Fl_Menu_Item whenmenu[];}
+            code1 {o->menu(whenmenu);}
+          } {}
+        }
+        Fl_Group {} {
+          label {Type:}
+          callback propagate_load
+          xywh {90 290 300 20} labelfont 1 labelsize 11 align 4
+        } {
+          Fl_Input {} {
+            callback user_data_type_cb
+            tooltip {The type of the user data.} xywh {90 290 140 20} labelfont 1 labelsize 11 textfont 4 textsize 11 resizable
+          }
+          Fl_Light_Button {} {
+            label {No Change}
+            callback when_button_cb
+            tooltip {Call the callback even if the value has not changed.} xywh {285 290 105 20} selection_color 1 labelsize 11
+          }
+        }
+      }
+    }
+    Fl_Group {} {
+      xywh {8 321 391 24} labelsize 11
+    } {
+      Fl_Box {} {
+        xywh {8 325 20 20} labelsize 11 resizable
+      }
+      Fl_Button {} {
+        label {Hide &Overlays}
+        callback overlay_cb
+        tooltip {Hide the widget overlay box.} xywh {231 325 99 20} labelsize 11 labelcolor 1
+      }
+      Fl_Button {} {
+        label Revert
+        callback revert_cb
+        xywh {80 325 80 20} labelsize 11 hide
+      }
+      Fl_Return_Button {} {
+        label Close
+        callback ok_cb
+        xywh {335 325 64 20} labelsize 11
+      }
+      Fl_Button {} {
+        label Cancel
+        callback cancel_cb
+        xywh {329 325 70 20} labelsize 11 hide
+      }
+      Fl_Button wLiveMode {
+        label {Live &Mode}
+        callback live_mode_cb
+        tooltip {Create a live duplicate of the selected widgets to test resizing and menu behavior.} xywh {142 325 84 20} type Toggle labelsize 11
+      }
+    }
+  }
+} 
+
+comment {
+//
+// End of "$Id: widget_panel.fl 4625 2005-11-02 13:55:13Z matt $".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/fluid/widget_panel.h b/Utilities/FLTK/fluid/widget_panel.h
new file mode 100644
index 0000000000000000000000000000000000000000..bdb7468c23fc364bef7550e272b1f38036a2977a
--- /dev/null
+++ b/Utilities/FLTK/fluid/widget_panel.h
@@ -0,0 +1,119 @@
+//
+// "$Id$"
+//
+// Widget panel for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#ifndef widget_panel_h
+#define widget_panel_h
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Group.H>
+extern void propagate_load(Fl_Group*, void*);
+#include <FL/Fl_Input.H>
+extern void label_cb(Fl_Input*, void*);
+#include <FL/Fl_Choice.H>
+extern Fl_Menu_Item labeltypemenu[];
+extern void labeltype_cb(Fl_Choice*, void*);
+extern void image_cb(Fl_Input*, void*);
+#include <FL/Fl_Button.H>
+extern void image_browse_cb(Fl_Button*, void*);
+extern void inactive_cb(Fl_Input*, void*);
+extern void inactive_browse_cb(Fl_Button*, void*);
+extern void align_cb(Fl_Button*, void*);
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Value_Input.H>
+extern void x_cb(Fl_Value_Input*, void*);
+extern Fl_Value_Input *widget_x_input;
+extern void y_cb(Fl_Value_Input*, void*);
+extern Fl_Value_Input *widget_y_input;
+extern void w_cb(Fl_Value_Input*, void*);
+extern Fl_Value_Input *widget_w_input;
+extern void h_cb(Fl_Value_Input*, void*);
+extern Fl_Value_Input *widget_h_input;
+#include <FL/Fl_Light_Button.H>
+extern void wc_relative_cb(Fl_Light_Button*, void*);
+extern void slider_size_cb(Fl_Value_Input*, void*);
+extern void min_cb(Fl_Value_Input*, void*);
+extern void max_cb(Fl_Value_Input*, void*);
+extern void step_cb(Fl_Value_Input*, void*);
+extern void value_cb(Fl_Value_Input*, void*);
+extern void min_w_cb(Fl_Value_Input*, void*);
+extern void min_h_cb(Fl_Value_Input*, void*);
+extern void set_min_size_cb(Fl_Button*, void*);
+extern void max_w_cb(Fl_Value_Input*, void*);
+extern void max_h_cb(Fl_Value_Input*, void*);
+extern void set_max_size_cb(Fl_Button*, void*);
+#include "Shortcut_Button.h"
+extern void shortcut_in_cb(Shortcut_Button*, void*);
+extern void xclass_cb(Fl_Input*, void*);
+extern void border_cb(Fl_Light_Button*, void*);
+extern void modal_cb(Fl_Light_Button*, void*);
+extern void non_modal_cb(Fl_Light_Button*, void*);
+extern void visible_cb(Fl_Light_Button*, void*);
+extern void active_cb(Fl_Light_Button*, void*);
+extern void resizable_cb(Fl_Light_Button*, void*);
+extern void hotspot_cb(Fl_Light_Button*, void*);
+extern void tooltip_cb(Fl_Input*, void*);
+extern Fl_Menu_Item fontmenu[];
+extern void labelfont_cb(Fl_Choice*, void*);
+extern void labelsize_cb(Fl_Value_Input*, void*);
+extern void labelcolor_cb(Fl_Button*, void*);
+extern Fl_Menu_Item boxmenu[];
+extern void box_cb(Fl_Choice*, void*);
+extern void color_cb(Fl_Button*, void*);
+extern void down_box_cb(Fl_Choice*, void*);
+extern void color2_cb(Fl_Button*, void*);
+extern void textfont_cb(Fl_Choice*, void*);
+extern void textsize_cb(Fl_Value_Input*, void*);
+extern void textcolor_cb(Fl_Button*, void*);
+extern void subclass_cb(Fl_Input*, void*);
+extern void subtype_cb(Fl_Choice*, void*);
+extern void name_cb(Fl_Input*, void*);
+extern void name_public_cb(Fl_Light_Button*, void*);
+extern void v_input_cb(Fl_Input*, void*);
+extern Fl_Input *v_input[4];
+#include "CodeEditor.h"
+extern void callback_cb(CodeEditor*, void*);
+extern void user_data_cb(Fl_Input*, void*);
+extern Fl_Menu_Item whenmenu[];
+extern void when_cb(Fl_Choice*, void*);
+extern void user_data_type_cb(Fl_Input*, void*);
+extern void when_button_cb(Fl_Light_Button*, void*);
+extern void overlay_cb(Fl_Button*, void*);
+extern void revert_cb(Fl_Button*, void*);
+#include <FL/Fl_Return_Button.H>
+extern void ok_cb(Fl_Return_Button*, void*);
+extern void cancel_cb(Fl_Button*, void*);
+extern void live_mode_cb(Fl_Button*, void*);
+extern Fl_Button *wLiveMode;
+Fl_Double_Window* make_widget_panel();
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/fluid/x-fluid.desktop b/Utilities/FLTK/fluid/x-fluid.desktop
new file mode 100644
index 0000000000000000000000000000000000000000..994e6443cbe02f1b92f6e7975cfc00caa3797825
--- /dev/null
+++ b/Utilities/FLTK/fluid/x-fluid.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Type=MimeType
+MimeType=application/x-fluid
+Icon=fluid.png
+Patterns=*.fl
+Name=FLUID
+Comment=FLUID GUI Design
+Encoding=UTF-8
diff --git a/Utilities/FLTK/forms.h b/Utilities/FLTK/forms.h
new file mode 100644
index 0000000000000000000000000000000000000000..967b24b67cc6cfbd10e28c97259a9923b7a632ac
--- /dev/null
+++ b/Utilities/FLTK/forms.h
@@ -0,0 +1,3 @@
+// this file allows some forms programs to be compiled with no change.
+// put it in your include path.
+#include <FL/forms.H>
diff --git a/Utilities/FLTK/jpeg/CMakeLists.txt b/Utilities/FLTK/jpeg/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..eb05c48a3d96605e05be1655ce5fffdaa0795c5d
--- /dev/null
+++ b/Utilities/FLTK/jpeg/CMakeLists.txt
@@ -0,0 +1,36 @@
+PROJECT(FLTKJPEG)
+
+INCLUDE_REGULAR_EXPRESSION("^(jchuff|jconfig|jdct|jdhuff|jerror|jinclude|jmemsys|jmorecfg|jpegint|jpeglib|jversion|jpeg).*$")
+
+INCLUDE_DIRECTORIES(${FLTKJPEG_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${FLTKJPEG_BINARY_DIR})
+
+# memmgr back ends: compile only one of these into a working library
+# (For now, let's use the mode that requires the image fit into memory.
+# This is the recommended mode for Win32 anyway.)
+SET(systemdependent_SRCS jmemnobs.c)
+
+# library object files common to compression and decompression
+SET(common_SRCS
+jcomapi.c jutils.c jerror.c jmemmgr.c
+)
+
+# compression library object files
+SET(compression_SRCS
+jcapimin.c jcapistd.c jctrans.c jcparam.c jdatadst.c jcinit.c
+jcmaster.c jcmarker.c jcmainct.c jcprepct.c jccoefct.c jccolor.c
+jcsample.c jchuff.c jcphuff.c jcdctmgr.c jfdctfst.c jfdctflt.c
+jfdctint.c
+)
+
+# decompression library object files
+SET(decompression_SRCS
+jdapimin.c jdapistd.c jdtrans.c jdatasrc.c jdmaster.c
+jdinput.c jdmarker.c jdhuff.c jdphuff.c jdmainct.c jdcoefct.c
+jdpostct.c jddctmgr.c jidctfst.c jidctflt.c jidctint.c jidctred.c
+jdsample.c jdcolor.c jquant1.c jquant2.c jdmerge.c
+)
+
+ADD_LIBRARY(fltk_jpeg ${systemdependent_SRCS} ${common_SRCS} ${compression_SRCS} ${decompression_SRCS})
+INSTALL_TARGETS(/lib fltk_jpeg)
+
diff --git a/Utilities/FLTK/jpeg/Makefile b/Utilities/FLTK/jpeg/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..715d9cd3c183622eff4dafdc1b00fc3f8b56e96f
--- /dev/null
+++ b/Utilities/FLTK/jpeg/Makefile
@@ -0,0 +1,116 @@
+#
+# "$Id: Makefile 4058 2005-02-28 00:11:07Z mike $"
+#
+# JPEG library makefile for the Fast Light Toolkit (FLTK).
+#
+# Copyright 1997-2005 by Easy Software Products.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+include ../makeinclude
+
+
+#
+# Object files...
+#
+
+OBJS	=	jmemnobs.o \
+		jcapimin.o jcapistd.o jccoefct.o jccolor.o jcdctmgr.o \
+		jchuff.o jcinit.o jcmainct.o jcmarker.o jcmaster.o jcomapi.o \
+		jcparam.o jcphuff.o jcprepct.o jcsample.o jctrans.o \
+		jdapimin.o jdapistd.o jdatadst.o jdatasrc.o jdcoefct.o \
+		jdcolor.o jddctmgr.o jdhuff.o jdinput.o jdmainct.o jdmarker.o \
+		jdmaster.o jdmerge.o jdphuff.o jdpostct.o jdsample.o \
+		jdtrans.o jerror.o jfdctflt.o jfdctfst.o jfdctint.o \
+		jidctflt.o jidctfst.o jidctint.o jidctred.o jquant1.o \
+		jquant2.o jutils.o jmemmgr.o
+
+LIBJPEG	=	../lib/libfltk_jpeg$(LIBEXT)
+
+
+#
+# Make all targets...
+#
+
+all:	$(LIBJPEG)
+
+
+#
+# Clean all targets and object files...
+#
+
+clean:
+	$(RM) $(OBJS)
+	$(RM) $(LIBJPEG)
+
+
+#
+# Install everything...
+#
+
+install:
+	echo "Installing libfltk_jpeg$(LIBEXT) in $(libdir)..."
+	-$(MKDIR) $(libdir)
+	$(RM) $(libdir)/libfltk_jpeg$(LIBEXT)
+	$(CP) $(LIBJPEG) $(libdir)
+	$(RANLIB) $(libdir)/libfltk_jpeg$(LIBEXT)
+	echo "Installing jpeg headers in $(includedir)/FL/images..."
+	-$(MKDIR) $(includedir)/FL/images
+	$(CP) jconfig.h jerror.h jmorecfg.h jpeglib.h $(includedir)/FL/images
+
+
+#
+# Uninstall everything...
+#
+
+uninstall:
+	echo "Uninstalling libfltk_jpeg$(LIBEXT) in $(libdir)..."
+	$(RM) $(libdir)/libfltk_jpeg$(LIBEXT)
+	echo "Uninstalling jpeg headers in $(includedir)/FL/images..."
+	$(RM) $(includedir)/FL/images/jconfig.h
+	$(RM) $(includedir)/FL/images/jerror.h
+	$(RM) $(includedir)/FL/images/jmorecfg.h
+	$(RM) $(includedir)/FL/images/jpeglib.h
+
+
+#
+# libfltk_jpeg.a
+#
+
+$(LIBJPEG):	$(OBJS)
+	echo Archiving $@...
+	$(RM) $@
+	$(LIBCOMMAND) $@ $(OBJS)
+	$(RANLIB) $@
+
+
+#
+# Make dependencies...
+#
+
+depend:	$(OBJS:.o=.c)
+	makedepend -Y -I.. -f makedepend $(OBJS:.o=.c)
+
+include makedepend
+
+$(OBJS):	../makeinclude
+
+#
+# End of "$Id: Makefile 4058 2005-02-28 00:11:07Z mike $".
+#
diff --git a/Utilities/FLTK/jpeg/README b/Utilities/FLTK/jpeg/README
new file mode 100644
index 0000000000000000000000000000000000000000..86cc20669d6123ee2999fd0c8f6c21641825fda6
--- /dev/null
+++ b/Utilities/FLTK/jpeg/README
@@ -0,0 +1,385 @@
+The Independent JPEG Group's JPEG software
+==========================================
+
+README for release 6b of 27-Mar-1998
+====================================
+
+This distribution contains the sixth public release of the Independent JPEG
+Group's free JPEG software.  You are welcome to redistribute this software and
+to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
+
+Serious users of this software (particularly those incorporating it into
+larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
+our electronic mailing list.  Mailing list members are notified of updates
+and have a chance to participate in technical discussions, etc.
+
+This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
+Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
+Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
+Group.
+
+IJG is not affiliated with the official ISO JPEG standards committee.
+
+
+DOCUMENTATION ROADMAP
+=====================
+
+This file contains the following sections:
+
+OVERVIEW            General description of JPEG and the IJG software.
+LEGAL ISSUES        Copyright, lack of warranty, terms of distribution.
+REFERENCES          Where to learn more about JPEG.
+ARCHIVE LOCATIONS   Where to find newer versions of this software.
+RELATED SOFTWARE    Other stuff you should get.
+FILE FORMAT WARS    Software *not* to get.
+TO DO               Plans for future IJG releases.
+
+Other documentation files in the distribution are:
+
+User documentation:
+  install.doc       How to configure and install the IJG software.
+  usage.doc         Usage instructions for cjpeg, djpeg, jpegtran,
+                    rdjpgcom, and wrjpgcom.
+  *.1               Unix-style man pages for programs (same info as usage.doc).
+  wizard.doc        Advanced usage instructions for JPEG wizards only.
+  change.log        Version-to-version change highlights.
+Programmer and internal documentation:
+  libjpeg.doc       How to use the JPEG library in your own programs.
+  example.c         Sample code for calling the JPEG library.
+  structure.doc     Overview of the JPEG library's internal structure.
+  filelist.doc      Road map of IJG files.
+  coderules.doc     Coding style rules --- please read if you contribute code.
+
+Please read at least the files install.doc and usage.doc.  Useful information
+can also be found in the JPEG FAQ (Frequently Asked Questions) article.  See
+ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
+
+If you want to understand how the JPEG code works, we suggest reading one or
+more of the REFERENCES, then looking at the documentation files (in roughly
+the order listed) before diving into the code.
+
+
+OVERVIEW
+========
+
+This package contains C software to implement JPEG image compression and
+decompression.  JPEG (pronounced "jay-peg") is a standardized compression
+method for full-color and gray-scale images.  JPEG is intended for compressing
+"real-world" scenes; line drawings, cartoons and other non-realistic images
+are not its strong suit.  JPEG is lossy, meaning that the output image is not
+exactly identical to the input image.  Hence you must not use JPEG if you
+have to have identical output bits.  However, on typical photographic images,
+very good compression levels can be obtained with no visible change, and
+remarkably high compression levels are possible if you can tolerate a
+low-quality image.  For more details, see the references, or just experiment
+with various compression settings.
+
+This software implements JPEG baseline, extended-sequential, and progressive
+compression processes.  Provision is made for supporting all variants of these
+processes, although some uncommon parameter settings aren't implemented yet.
+For legal reasons, we are not distributing code for the arithmetic-coding
+variants of JPEG; see LEGAL ISSUES.  We have made no provision for supporting
+the hierarchical or lossless processes defined in the standard.
+
+We provide a set of library routines for reading and writing JPEG image files,
+plus two sample applications "cjpeg" and "djpeg", which use the library to
+perform conversion between JPEG and some other popular image file formats.
+The library is intended to be reused in other applications.
+
+In order to support file conversion and viewing software, we have included
+considerable functionality beyond the bare JPEG coding/decoding capability;
+for example, the color quantization modules are not strictly part of JPEG
+decoding, but they are essential for output to colormapped file formats or
+colormapped displays.  These extra functions can be compiled out of the
+library if not required for a particular application.  We have also included
+"jpegtran", a utility for lossless transcoding between different JPEG
+processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
+inserting and extracting textual comments in JFIF files.
+
+The emphasis in designing this software has been on achieving portability and
+flexibility, while also making it fast enough to be useful.  In particular,
+the software is not intended to be read as a tutorial on JPEG.  (See the
+REFERENCES section for introductory material.)  Rather, it is intended to
+be reliable, portable, industrial-strength code.  We do not claim to have
+achieved that goal in every aspect of the software, but we strive for it.
+
+We welcome the use of this software as a component of commercial products.
+No royalty is required, but we do ask for an acknowledgement in product
+documentation, as described under LEGAL ISSUES.
+
+
+LEGAL ISSUES
+============
+
+In plain English:
+
+1. We don't promise that this software works.  (But if you find any bugs,
+   please let us know!)
+2. You can use this software for whatever you want.  You don't have to pay us.
+3. You may not pretend that you wrote this software.  If you use it in a
+   program, you must acknowledge somewhere in your documentation that
+   you've used the IJG code.
+
+In legalese:
+
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose.  This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library.  If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it.  This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it.  (See the file
+ansi2knr.c for full details.)  However, since ansi2knr.c is not needed as part
+of any program generated from the IJG code, this does not limit you more than
+the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltconfig, ltmain.sh).  Another support script, install-sh, is copyright
+by M.I.T. but is also freely distributable.
+
+It appears that the arithmetic coding option of the JPEG spec is covered by
+patents owned by IBM, AT&T, and Mitsubishi.  Hence arithmetic coding cannot
+legally be used without obtaining one or more licenses.  For this reason,
+support for arithmetic coding has been removed from the free JPEG software.
+(Since arithmetic coding provides only a marginal gain over the unpatented
+Huffman mode, it is unlikely that very many implementations will support it.)
+So far as we are aware, there are no patent restrictions on the remaining
+code.
+
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs".  This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
+
+We are required to state that
+    "The Graphics Interchange Format(c) is the Copyright property of
+    CompuServe Incorporated.  GIF(sm) is a Service Mark property of
+    CompuServe Incorporated."
+
+
+REFERENCES
+==========
+
+We highly recommend reading one or more of these references before trying to
+understand the innards of the JPEG software.
+
+The best short technical introduction to the JPEG compression algorithm is
+	Wallace, Gregory K.  "The JPEG Still Picture Compression Standard",
+	Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
+(Adjacent articles in that issue discuss MPEG motion picture compression,
+applications of JPEG, and related topics.)  If you don't have the CACM issue
+handy, a PostScript file containing a revised version of Wallace's article is
+available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz.  The file (actually
+a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
+omits the sample images that appeared in CACM, but it includes corrections
+and some added material.  Note: the Wallace article is copyright ACM and IEEE,
+and it may not be used for commercial purposes.
+
+A somewhat less technical, more leisurely introduction to JPEG can be found in
+"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
+M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1.  This book provides
+good explanations and example C code for a multitude of compression methods
+including JPEG.  It is an excellent source if you are comfortable reading C
+code but don't know much about data compression in general.  The book's JPEG
+sample code is far from industrial-strength, but when you are ready to look
+at a full implementation, you've got one here...
+
+The best full description of JPEG is the textbook "JPEG Still Image Data
+Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
+by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.  Price US$59.95, 638 pp.
+The book includes the complete text of the ISO JPEG standards (DIS 10918-1
+and draft DIS 10918-2).  This is by far the most complete exposition of JPEG
+in existence, and we highly recommend it.
+
+The JPEG standard itself is not available electronically; you must order a
+paper copy through ISO or ITU.  (Unless you feel a need to own a certified
+official copy, we recommend buying the Pennebaker and Mitchell book instead;
+it's much cheaper and includes a great deal of useful explanatory material.)
+In the USA, copies of the standard may be ordered from ANSI Sales at (212)
+642-4900, or from Global Engineering Documents at (800) 854-7179.  (ANSI
+doesn't take credit card orders, but Global does.)  It's not cheap: as of
+1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
+shipping/handling.  The standard is divided into two parts, Part 1 being the
+actual specification, while Part 2 covers compliance testing methods.  Part 1
+is titled "Digital Compression and Coding of Continuous-tone Still Images,
+Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
+10918-1, ITU-T T.81.  Part 2 is titled "Digital Compression and Coding of
+Continuous-tone Still Images, Part 2: Compliance testing" and has document
+numbers ISO/IEC IS 10918-2, ITU-T T.83.
+
+Some extensions to the original JPEG standard are defined in JPEG Part 3,
+a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84.  IJG
+currently does not support any Part 3 extensions.
+
+The JPEG standard does not specify all details of an interchangeable file
+format.  For the omitted details we follow the "JFIF" conventions, revision
+1.02.  A copy of the JFIF spec is available from:
+	Literature Department
+	C-Cube Microsystems, Inc.
+	1778 McCarthy Blvd.
+	Milpitas, CA 95035
+	phone (408) 944-6300,  fax (408) 944-6314
+A PostScript version of this document is available by FTP at
+ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz.  There is also a plain text
+version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
+the figures.
+
+The TIFF 6.0 file format specification can be obtained by FTP from
+ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz.  The JPEG incorporation scheme
+found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
+IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
+Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
+(Compression tag 7).  Copies of this Note can be obtained from ftp.sgi.com or
+from ftp://ftp.uu.net/graphics/jpeg/.  It is expected that the next revision
+of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
+Although IJG's own code does not support TIFF/JPEG, the free libtiff library
+uses our library to implement TIFF/JPEG per the Note.  libtiff is available
+from ftp://ftp.sgi.com/graphics/tiff/.
+
+
+ARCHIVE LOCATIONS
+=================
+
+The "official" archive site for this software is ftp.uu.net (Internet
+address 192.48.96.9).  The most recent released version can always be found
+there in directory graphics/jpeg.  This particular version will be archived
+as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz.  If you don't have
+direct Internet access, UUNET's archives are also available via UUCP; contact
+help@uunet.uu.net for information on retrieving files that way.
+
+Numerous Internet sites maintain copies of the UUNET files.  However, only
+ftp.uu.net is guaranteed to have the latest official version.
+
+You can also obtain this software in DOS-compatible "zip" archive format from
+the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
+on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
+"JPEG Tools".  Again, these versions may sometimes lag behind the ftp.uu.net
+release.
+
+The JPEG FAQ (Frequently Asked Questions) article is a useful source of
+general information about JPEG.  It is updated constantly and therefore is
+not included in this distribution.  The FAQ is posted every two weeks to
+Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
+It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
+and other news.answers archive sites, including the official news.answers
+archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
+If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
+with body
+	send usenet/news.answers/jpeg-faq/part1
+	send usenet/news.answers/jpeg-faq/part2
+
+
+RELATED SOFTWARE
+================
+
+Numerous viewing and image manipulation programs now support JPEG.  (Quite a
+few of them use this library to do so.)  The JPEG FAQ described above lists
+some of the more popular free and shareware viewers, and tells where to
+obtain them on Internet.
+
+If you are on a Unix machine, we highly recommend Jef Poskanzer's free
+PBMPLUS software, which provides many useful operations on PPM-format image
+files.  In particular, it can convert PPM images to and from a wide range of
+other formats, thus making cjpeg/djpeg considerably more useful.  The latest
+version is distributed by the NetPBM group, and is available from numerous
+sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
+Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
+you are likely to have difficulty making it work on any non-Unix machine.
+
+A different free JPEG implementation, written by the PVRG group at Stanford,
+is available from ftp://havefun.stanford.edu/pub/jpeg/.  This program
+is designed for research and experimentation rather than production use;
+it is slower, harder to use, and less portable than the IJG code, but it
+is easier to read and modify.  Also, the PVRG code supports lossless JPEG,
+which we do not.  (On the other hand, it doesn't do progressive JPEG.)
+
+
+FILE FORMAT WARS
+================
+
+Some JPEG programs produce files that are not compatible with our library.
+The root of the problem is that the ISO JPEG committee failed to specify a
+concrete file format.  Some vendors "filled in the blanks" on their own,
+creating proprietary formats that no one else could read.  (For example, none
+of the early commercial JPEG implementations for the Macintosh were able to
+exchange compressed files.)
+
+The file format we have adopted is called JFIF (see REFERENCES).  This format
+has been agreed to by a number of major commercial JPEG vendors, and it has
+become the de facto standard.  JFIF is a minimal or "low end" representation.
+We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
+Technical Note #2) for "high end" applications that need to record a lot of
+additional data about an image.  TIFF/JPEG is fairly new and not yet widely
+supported, unfortunately.
+
+The upcoming JPEG Part 3 standard defines a file format called SPIFF.
+SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
+be able to read the most common variant of SPIFF.  SPIFF has some technical
+advantages over JFIF, but its major claim to fame is simply that it is an
+official standard rather than an informal one.  At this point it is unclear
+whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
+standard.  IJG intends to support SPIFF once the standard is frozen, but we
+have not decided whether it should become our default output format or not.
+(In any case, our decoder will remain capable of reading JFIF indefinitely.)
+
+Various proprietary file formats incorporating JPEG compression also exist.
+We have little or no sympathy for the existence of these formats.  Indeed,
+one of the original reasons for developing this free software was to help
+force convergence on common, open format standards for JPEG files.  Don't
+use a proprietary file format!
+
+
+TO DO
+=====
+
+The major thrust for v7 will probably be improvement of visual quality.
+The current method for scaling the quantization tables is known not to be
+very good at low Q values.  We also intend to investigate block boundary
+smoothing, "poor man's variable quantization", and other means of improving
+quality-vs-file-size performance without sacrificing compatibility.
+
+In future versions, we are considering supporting some of the upcoming JPEG
+Part 3 extensions --- principally, variable quantization and the SPIFF file
+format.
+
+As always, speeding things up is of great interest.
+
+Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
diff --git a/Utilities/FLTK/jpeg/coderules.doc b/Utilities/FLTK/jpeg/coderules.doc
new file mode 100644
index 0000000000000000000000000000000000000000..0ab5d9bd302ea3dc548c18fa69f2505fc142896b
--- /dev/null
+++ b/Utilities/FLTK/jpeg/coderules.doc
@@ -0,0 +1,118 @@
+IJG JPEG LIBRARY:  CODING RULES
+
+Copyright (C) 1991-1996, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+Since numerous people will be contributing code and bug fixes, it's important
+to establish a common coding style.  The goal of using similar coding styles
+is much more important than the details of just what that style is.
+
+In general we follow the recommendations of "Recommended C Style and Coding
+Standards" revision 6.1 (Cannon et al. as modified by Spencer, Keppel and
+Brader).  This document is available in the IJG FTP archive (see
+jpeg/doc/cstyle.ms.tbl.Z, or cstyle.txt.Z for those without nroff/tbl).
+
+Block comments should be laid out thusly:
+
+/*
+ *  Block comments in this style.
+ */
+
+We indent statements in K&R style, e.g.,
+	if (test) {
+	  then-part;
+	} else {
+	  else-part;
+	}
+with two spaces per indentation level.  (This indentation convention is
+handled automatically by GNU Emacs and many other text editors.)
+
+Multi-word names should be written in lower case with underscores, e.g.,
+multi_word_name (not multiWordName).  Preprocessor symbols and enum constants
+are similar but upper case (MULTI_WORD_NAME).  Names should be unique within
+the first fifteen characters.  (On some older systems, global names must be
+unique within six characters.  We accommodate this without cluttering the
+source code by using macros to substitute shorter names.)
+
+We use function prototypes everywhere; we rely on automatic source code
+transformation to feed prototype-less C compilers.  Transformation is done
+by the simple and portable tool 'ansi2knr.c' (courtesy of Ghostscript).
+ansi2knr is not very bright, so it imposes a format requirement on function
+declarations: the function name MUST BEGIN IN COLUMN 1.  Thus all functions
+should be written in the following style:
+
+LOCAL(int *)
+function_name (int a, char *b)
+{
+    code...
+}
+
+Note that each function definition must begin with GLOBAL(type), LOCAL(type),
+or METHODDEF(type).  These macros expand to "static type" or just "type" as
+appropriate.  They provide a readable indication of the routine's usage and
+can readily be changed for special needs.  (For instance, special linkage
+keywords can be inserted for use in Windows DLLs.)
+
+ansi2knr does not transform method declarations (function pointers in
+structs).  We handle these with a macro JMETHOD, defined as
+	#ifdef HAVE_PROTOTYPES
+	#define JMETHOD(type,methodname,arglist)  type (*methodname) arglist
+	#else
+	#define JMETHOD(type,methodname,arglist)  type (*methodname) ()
+	#endif
+which is used like this:
+	struct function_pointers {
+	  JMETHOD(void, init_entropy_encoder, (int somearg, jparms *jp));
+	  JMETHOD(void, term_entropy_encoder, (void));
+	};
+Note the set of parentheses surrounding the parameter list.
+
+A similar solution is used for forward and external function declarations
+(see the EXTERN and JPP macros).
+
+If the code is to work on non-ANSI compilers, we cannot rely on a prototype
+declaration to coerce actual parameters into the right types.  Therefore, use
+explicit casts on actual parameters whenever the actual parameter type is not
+identical to the formal parameter.  Beware of implicit conversions to "int".
+
+It seems there are some non-ANSI compilers in which the sizeof() operator
+is defined to return int, yet size_t is defined as long.  Needless to say,
+this is brain-damaged.  Always use the SIZEOF() macro in place of sizeof(),
+so that the result is guaranteed to be of type size_t.
+
+
+The JPEG library is intended to be used within larger programs.  Furthermore,
+we want it to be reentrant so that it can be used by applications that process
+multiple images concurrently.  The following rules support these requirements:
+
+1. Avoid direct use of file I/O, "malloc", error report printouts, etc;
+pass these through the common routines provided.
+
+2. Minimize global namespace pollution.  Functions should be declared static
+wherever possible.  (Note that our method-based calling conventions help this
+a lot: in many modules only the initialization function will ever need to be
+called directly, so only that function need be externally visible.)  All
+global function names should begin with "jpeg_", and should have an
+abbreviated name (unique in the first six characters) substituted by macro
+when NEED_SHORT_EXTERNAL_NAMES is set.
+
+3. Don't use global variables; anything that must be used in another module
+should be in the common data structures.
+
+4. Don't use static variables except for read-only constant tables.  Variables
+that should be private to a module can be placed into private structures (see
+the system architecture document, structure.doc).
+
+5. Source file names should begin with "j" for files that are part of the
+library proper; source files that are not part of the library, such as cjpeg.c
+and djpeg.c, do not begin with "j".  Keep source file names to eight
+characters (plus ".c" or ".h", etc) to make life easy for MS-DOSers.  Keep
+compression and decompression code in separate source files --- some
+applications may want only one half of the library.
+
+Note: these rules (particularly #4) are not followed religiously in the
+modules that are used in cjpeg/djpeg but are not part of the JPEG library
+proper.  Those modules are not really intended to be used in other
+applications.
diff --git a/Utilities/FLTK/jpeg/filelist.doc b/Utilities/FLTK/jpeg/filelist.doc
new file mode 100644
index 0000000000000000000000000000000000000000..e14982ca55b97cb2885e7cc42574042fd2b20ef3
--- /dev/null
+++ b/Utilities/FLTK/jpeg/filelist.doc
@@ -0,0 +1,210 @@
+IJG JPEG LIBRARY:  FILE LIST
+
+Copyright (C) 1994-1998, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+Here is a road map to the files in the IJG JPEG distribution.  The
+distribution includes the JPEG library proper, plus two application
+programs ("cjpeg" and "djpeg") which use the library to convert JPEG
+files to and from some other popular image formats.  A third application
+"jpegtran" uses the library to do lossless conversion between different
+variants of JPEG.  There are also two stand-alone applications,
+"rdjpgcom" and "wrjpgcom".
+
+
+THE JPEG LIBRARY
+================
+
+Include files:
+
+jpeglib.h	JPEG library's exported data and function declarations.
+jconfig.h	Configuration declarations.  Note: this file is not present
+		in the distribution; it is generated during installation.
+jmorecfg.h	Additional configuration declarations; need not be changed
+		for a standard installation.
+jerror.h	Declares JPEG library's error and trace message codes.
+jinclude.h	Central include file used by all IJG .c files to reference
+		system include files.
+jpegint.h	JPEG library's internal data structures.
+jchuff.h	Private declarations for Huffman encoder modules.
+jdhuff.h	Private declarations for Huffman decoder modules.
+jdct.h		Private declarations for forward & reverse DCT subsystems.
+jmemsys.h	Private declarations for memory management subsystem.
+jversion.h	Version information.
+
+Applications using the library should include jpeglib.h (which in turn
+includes jconfig.h and jmorecfg.h).  Optionally, jerror.h may be included
+if the application needs to reference individual JPEG error codes.  The
+other include files are intended for internal use and would not normally
+be included by an application program.  (cjpeg/djpeg/etc do use jinclude.h,
+since its function is to improve portability of the whole IJG distribution.
+Most other applications will directly include the system include files they
+want, and hence won't need jinclude.h.)
+
+
+C source code files:
+
+These files contain most of the functions intended to be called directly by
+an application program:
+
+jcapimin.c	Application program interface: core routines for compression.
+jcapistd.c	Application program interface: standard compression.
+jdapimin.c	Application program interface: core routines for decompression.
+jdapistd.c	Application program interface: standard decompression.
+jcomapi.c	Application program interface routines common to compression
+		and decompression.
+jcparam.c	Compression parameter setting helper routines.
+jctrans.c	API and library routines for transcoding compression.
+jdtrans.c	API and library routines for transcoding decompression.
+
+Compression side of the library:
+
+jcinit.c	Initialization: determines which other modules to use.
+jcmaster.c	Master control: setup and inter-pass sequencing logic.
+jcmainct.c	Main buffer controller (preprocessor => JPEG compressor).
+jcprepct.c	Preprocessor buffer controller.
+jccoefct.c	Buffer controller for DCT coefficient buffer.
+jccolor.c	Color space conversion.
+jcsample.c	Downsampling.
+jcdctmgr.c	DCT manager (DCT implementation selection & control).
+jfdctint.c	Forward DCT using slow-but-accurate integer method.
+jfdctfst.c	Forward DCT using faster, less accurate integer method.
+jfdctflt.c	Forward DCT using floating-point arithmetic.
+jchuff.c	Huffman entropy coding for sequential JPEG.
+jcphuff.c	Huffman entropy coding for progressive JPEG.
+jcmarker.c	JPEG marker writing.
+jdatadst.c	Data destination manager for stdio output.
+
+Decompression side of the library:
+
+jdmaster.c	Master control: determines which other modules to use.
+jdinput.c	Input controller: controls input processing modules.
+jdmainct.c	Main buffer controller (JPEG decompressor => postprocessor).
+jdcoefct.c	Buffer controller for DCT coefficient buffer.
+jdpostct.c	Postprocessor buffer controller.
+jdmarker.c	JPEG marker reading.
+jdhuff.c	Huffman entropy decoding for sequential JPEG.
+jdphuff.c	Huffman entropy decoding for progressive JPEG.
+jddctmgr.c	IDCT manager (IDCT implementation selection & control).
+jidctint.c	Inverse DCT using slow-but-accurate integer method.
+jidctfst.c	Inverse DCT using faster, less accurate integer method.
+jidctflt.c	Inverse DCT using floating-point arithmetic.
+jidctred.c	Inverse DCTs with reduced-size outputs.
+jdsample.c	Upsampling.
+jdcolor.c	Color space conversion.
+jdmerge.c	Merged upsampling/color conversion (faster, lower quality).
+jquant1.c	One-pass color quantization using a fixed-spacing colormap.
+jquant2.c	Two-pass color quantization using a custom-generated colormap.
+		Also handles one-pass quantization to an externally given map.
+jdatasrc.c	Data source manager for stdio input.
+
+Support files for both compression and decompression:
+
+jerror.c	Standard error handling routines (application replaceable).
+jmemmgr.c	System-independent (more or less) memory management code.
+jutils.c	Miscellaneous utility routines.
+
+jmemmgr.c relies on a system-dependent memory management module.  The IJG
+distribution includes the following implementations of the system-dependent
+module:
+
+jmemnobs.c	"No backing store": assumes adequate virtual memory exists.
+jmemansi.c	Makes temporary files with ANSI-standard routine tmpfile().
+jmemname.c	Makes temporary files with program-generated file names.
+jmemdos.c	Custom implementation for MS-DOS (16-bit environment only):
+		can use extended and expanded memory as well as temp files.
+jmemmac.c	Custom implementation for Apple Macintosh.
+
+Exactly one of the system-dependent modules should be configured into an
+installed JPEG library (see install.doc for hints about which one to use).
+On unusual systems you may find it worthwhile to make a special
+system-dependent memory manager.
+
+
+Non-C source code files:
+
+jmemdosa.asm	80x86 assembly code support for jmemdos.c; used only in
+		MS-DOS-specific configurations of the JPEG library.
+
+
+CJPEG/DJPEG/JPEGTRAN
+====================
+
+Include files:
+
+cdjpeg.h	Declarations shared by cjpeg/djpeg/jpegtran modules.
+cderror.h	Additional error and trace message codes for cjpeg et al.
+transupp.h	Declarations for jpegtran support routines in transupp.c.
+
+C source code files:
+
+cjpeg.c		Main program for cjpeg.
+djpeg.c		Main program for djpeg.
+jpegtran.c	Main program for jpegtran.
+cdjpeg.c	Utility routines used by all three programs.
+rdcolmap.c	Code to read a colormap file for djpeg's "-map" switch.
+rdswitch.c	Code to process some of cjpeg's more complex switches.
+		Also used by jpegtran.
+transupp.c	Support code for jpegtran: lossless image manipulations.
+
+Image file reader modules for cjpeg:
+
+rdbmp.c		BMP file input.
+rdgif.c		GIF file input (now just a stub).
+rdppm.c		PPM/PGM file input.
+rdrle.c		Utah RLE file input.
+rdtarga.c	Targa file input.
+
+Image file writer modules for djpeg:
+
+wrbmp.c		BMP file output.
+wrgif.c		GIF file output (a mere shadow of its former self).
+wrppm.c		PPM/PGM file output.
+wrrle.c		Utah RLE file output.
+wrtarga.c	Targa file output.
+
+
+RDJPGCOM/WRJPGCOM
+=================
+
+C source code files:
+
+rdjpgcom.c	Stand-alone rdjpgcom application.
+wrjpgcom.c	Stand-alone wrjpgcom application.
+
+These programs do not depend on the IJG library.  They do use
+jconfig.h and jinclude.h, only to improve portability.
+
+
+ADDITIONAL FILES
+================
+
+Documentation (see README for a guide to the documentation files):
+
+README		Master documentation file.
+*.doc		Other documentation files.
+*.1		Documentation in Unix man page format.
+change.log	Version-to-version change highlights.
+example.c	Sample code for calling JPEG library.
+
+Configuration/installation files and programs (see install.doc for more info):
+
+configure	Unix shell script to perform automatic configuration.
+ltconfig	Support scripts for configure (from GNU libtool).
+ltmain.sh
+config.guess
+config.sub
+install-sh	Install shell script for those Unix systems lacking one.
+ckconfig.c	Program to generate jconfig.h on non-Unix systems.
+jconfig.doc	Template for making jconfig.h by hand.
+makefile.*	Sample makefiles for particular systems.
+jconfig.*	Sample jconfig.h for particular systems.
+ansi2knr.c	De-ANSIfier for pre-ANSI C compilers (courtesy of
+		L. Peter Deutsch and Aladdin Enterprises).
+
+Test files (see install.doc for test procedure):
+
+test*.*		Source and comparison files for confidence test.
+		These are binary image files, NOT text files.
diff --git a/Utilities/FLTK/jpeg/jcapimin.c b/Utilities/FLTK/jpeg/jcapimin.c
new file mode 100644
index 0000000000000000000000000000000000000000..54fb8c58c5656947c285fc8d98d5c23815aec1eb
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcapimin.c
@@ -0,0 +1,280 @@
+/*
+ * jcapimin.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the compression half
+ * of the JPEG library.  These are the "minimum" API routines that may be
+ * needed in either the normal full-compression case or the transcoding-only
+ * case.
+ *
+ * Most of the routines intended to be called directly by an application
+ * are in this file or in jcapistd.c.  But also see jcparam.c for
+ * parameter-setup helper routines, jcomapi.c for routines shared by
+ * compression and decompression, and jctrans.c for the transcoding case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Initialization of a JPEG compression object.
+ * The error manager must already be set up (in case memory manager fails).
+ */
+
+GLOBAL(void)
+jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
+{
+  int i;
+
+  /* Guard against version mismatches between library and caller. */
+  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
+  if (version != JPEG_LIB_VERSION)
+    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
+  if (structsize != SIZEOF(struct jpeg_compress_struct))
+    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
+	     (int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
+
+  /* For debugging purposes, we zero the whole master structure.
+   * But the application has already set the err pointer, and may have set
+   * client_data, so we have to save and restore those fields.
+   * Note: if application hasn't set client_data, tools like Purify may
+   * complain here.
+   */
+  {
+    struct jpeg_error_mgr * err = cinfo->err;
+    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
+    MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
+    cinfo->err = err;
+    cinfo->client_data = client_data;
+  }
+  cinfo->is_decompressor = FALSE;
+
+  /* Initialize a memory manager instance for this object */
+  jinit_memory_mgr((j_common_ptr) cinfo);
+
+  /* Zero out pointers to permanent structures. */
+  cinfo->progress = NULL;
+  cinfo->dest = NULL;
+
+  cinfo->comp_info = NULL;
+
+  for (i = 0; i < NUM_QUANT_TBLS; i++)
+    cinfo->quant_tbl_ptrs[i] = NULL;
+
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    cinfo->dc_huff_tbl_ptrs[i] = NULL;
+    cinfo->ac_huff_tbl_ptrs[i] = NULL;
+  }
+
+  cinfo->script_space = NULL;
+
+  cinfo->input_gamma = 1.0;	/* in case application forgets */
+
+  /* OK, I'm ready */
+  cinfo->global_state = CSTATE_START;
+}
+
+
+/*
+ * Destruction of a JPEG compression object
+ */
+
+GLOBAL(void)
+jpeg_destroy_compress (j_compress_ptr cinfo)
+{
+  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Abort processing of a JPEG compression operation,
+ * but don't destroy the object itself.
+ */
+
+GLOBAL(void)
+jpeg_abort_compress (j_compress_ptr cinfo)
+{
+  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Forcibly suppress or un-suppress all quantization and Huffman tables.
+ * Marks all currently defined tables as already written (if suppress)
+ * or not written (if !suppress).  This will control whether they get emitted
+ * by a subsequent jpeg_start_compress call.
+ *
+ * This routine is exported for use by applications that want to produce
+ * abbreviated JPEG datastreams.  It logically belongs in jcparam.c, but
+ * since it is called by jpeg_start_compress, we put it here --- otherwise
+ * jcparam.o would be linked whether the application used it or not.
+ */
+
+GLOBAL(void)
+jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
+{
+  int i;
+  JQUANT_TBL * qtbl;
+  JHUFF_TBL * htbl;
+
+  for (i = 0; i < NUM_QUANT_TBLS; i++) {
+    if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
+      qtbl->sent_table = suppress;
+  }
+
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
+      htbl->sent_table = suppress;
+    if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
+      htbl->sent_table = suppress;
+  }
+}
+
+
+/*
+ * Finish JPEG compression.
+ *
+ * If a multipass operating mode was selected, this may do a great deal of
+ * work including most of the actual output.
+ */
+
+GLOBAL(void)
+jpeg_finish_compress (j_compress_ptr cinfo)
+{
+  JDIMENSION iMCU_row;
+
+  if (cinfo->global_state == CSTATE_SCANNING ||
+      cinfo->global_state == CSTATE_RAW_OK) {
+    /* Terminate first pass */
+    if (cinfo->next_scanline < cinfo->image_height)
+      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
+    (*cinfo->master->finish_pass) (cinfo);
+  } else if (cinfo->global_state != CSTATE_WRCOEFS)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  /* Perform any remaining passes */
+  while (! cinfo->master->is_last_pass) {
+    (*cinfo->master->prepare_for_pass) (cinfo);
+    for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
+      if (cinfo->progress != NULL) {
+	cinfo->progress->pass_counter = (long) iMCU_row;
+	cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
+	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+      }
+      /* We bypass the main controller and invoke coef controller directly;
+       * all work is being done from the coefficient buffer.
+       */
+      if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
+	ERREXIT(cinfo, JERR_CANT_SUSPEND);
+    }
+    (*cinfo->master->finish_pass) (cinfo);
+  }
+  /* Write EOI, do final cleanup */
+  (*cinfo->marker->write_file_trailer) (cinfo);
+  (*cinfo->dest->term_destination) (cinfo);
+  /* We can use jpeg_abort to release memory and reset global_state */
+  jpeg_abort((j_common_ptr) cinfo);
+}
+
+
+/*
+ * Write a special marker.
+ * This is only recommended for writing COM or APPn markers.
+ * Must be called after jpeg_start_compress() and before
+ * first call to jpeg_write_scanlines() or jpeg_write_raw_data().
+ */
+
+GLOBAL(void)
+jpeg_write_marker (j_compress_ptr cinfo, int marker,
+		   const JOCTET *dataptr, unsigned int datalen)
+{
+  JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
+
+  if (cinfo->next_scanline != 0 ||
+      (cinfo->global_state != CSTATE_SCANNING &&
+       cinfo->global_state != CSTATE_RAW_OK &&
+       cinfo->global_state != CSTATE_WRCOEFS))
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+  write_marker_byte = cinfo->marker->write_marker_byte;	/* copy for speed */
+  while (datalen--) {
+    (*write_marker_byte) (cinfo, *dataptr);
+    dataptr++;
+  }
+}
+
+/* Same, but piecemeal. */
+
+GLOBAL(void)
+jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+{
+  if (cinfo->next_scanline != 0 ||
+      (cinfo->global_state != CSTATE_SCANNING &&
+       cinfo->global_state != CSTATE_RAW_OK &&
+       cinfo->global_state != CSTATE_WRCOEFS))
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+}
+
+GLOBAL(void)
+jpeg_write_m_byte (j_compress_ptr cinfo, int val)
+{
+  (*cinfo->marker->write_marker_byte) (cinfo, val);
+}
+
+
+/*
+ * Alternate compression function: just write an abbreviated table file.
+ * Before calling this, all parameters and a data destination must be set up.
+ *
+ * To produce a pair of files containing abbreviated tables and abbreviated
+ * image data, one would proceed as follows:
+ *
+ *		initialize JPEG object
+ *		set JPEG parameters
+ *		set destination to table file
+ *		jpeg_write_tables(cinfo);
+ *		set destination to image file
+ *		jpeg_start_compress(cinfo, FALSE);
+ *		write data...
+ *		jpeg_finish_compress(cinfo);
+ *
+ * jpeg_write_tables has the side effect of marking all tables written
+ * (same as jpeg_suppress_tables(..., TRUE)).  Thus a subsequent start_compress
+ * will not re-emit the tables unless it is passed write_all_tables=TRUE.
+ */
+
+GLOBAL(void)
+jpeg_write_tables (j_compress_ptr cinfo)
+{
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  /* (Re)initialize error mgr and destination modules */
+  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+  (*cinfo->dest->init_destination) (cinfo);
+  /* Initialize the marker writer ... bit of a crock to do it here. */
+  jinit_marker_writer(cinfo);
+  /* Write them tables! */
+  (*cinfo->marker->write_tables_only) (cinfo);
+  /* And clean up. */
+  (*cinfo->dest->term_destination) (cinfo);
+  /*
+   * In library releases up through v6a, we called jpeg_abort() here to free
+   * any working memory allocated by the destination manager and marker
+   * writer.  Some applications had a problem with that: they allocated space
+   * of their own from the library memory manager, and didn't want it to go
+   * away during write_tables.  So now we do nothing.  This will cause a
+   * memory leak if an app calls write_tables repeatedly without doing a full
+   * compression cycle or otherwise resetting the JPEG object.  However, that
+   * seems less bad than unexpectedly freeing memory in the normal case.
+   * An app that prefers the old behavior can call jpeg_abort for itself after
+   * each call to jpeg_write_tables().
+   */
+}
diff --git a/Utilities/FLTK/jpeg/jcapistd.c b/Utilities/FLTK/jpeg/jcapistd.c
new file mode 100644
index 0000000000000000000000000000000000000000..c0320b1b190f5b3b14e9f903bcd0a5cba8c84ef2
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcapistd.c
@@ -0,0 +1,161 @@
+/*
+ * jcapistd.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the compression half
+ * of the JPEG library.  These are the "standard" API routines that are
+ * used in the normal full-compression case.  They are not used by a
+ * transcoding-only application.  Note that if an application links in
+ * jpeg_start_compress, it will end up linking in the entire compressor.
+ * We thus must separate this file from jcapimin.c to avoid linking the
+ * whole compression library into a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Compression initialization.
+ * Before calling this, all parameters and a data destination must be set up.
+ *
+ * We require a write_all_tables parameter as a failsafe check when writing
+ * multiple datastreams from the same compression object.  Since prior runs
+ * will have left all the tables marked sent_table=TRUE, a subsequent run
+ * would emit an abbreviated stream (no tables) by default.  This may be what
+ * is wanted, but for safety's sake it should not be the default behavior:
+ * programmers should have to make a deliberate choice to emit abbreviated
+ * images.  Therefore the documentation and examples should encourage people
+ * to pass write_all_tables=TRUE; then it will take active thought to do the
+ * wrong thing.
+ */
+
+GLOBAL(void)
+jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
+{
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  if (write_all_tables)
+    jpeg_suppress_tables(cinfo, FALSE);	/* mark all tables to be written */
+
+  /* (Re)initialize error mgr and destination modules */
+  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+  (*cinfo->dest->init_destination) (cinfo);
+  /* Perform master selection of active modules */
+  jinit_compress_master(cinfo);
+  /* Set up for the first pass */
+  (*cinfo->master->prepare_for_pass) (cinfo);
+  /* Ready for application to drive first pass through jpeg_write_scanlines
+   * or jpeg_write_raw_data.
+   */
+  cinfo->next_scanline = 0;
+  cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
+}
+
+
+/*
+ * Write some scanlines of data to the JPEG compressor.
+ *
+ * The return value will be the number of lines actually written.
+ * This should be less than the supplied num_lines only in case that
+ * the data destination module has requested suspension of the compressor,
+ * or if more than image_height scanlines are passed in.
+ *
+ * Note: we warn about excess calls to jpeg_write_scanlines() since
+ * this likely signals an application programmer error.  However,
+ * excess scanlines passed in the last valid call are *silently* ignored,
+ * so that the application need not adjust num_lines for end-of-image
+ * when using a multiple-scanline buffer.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
+		      JDIMENSION num_lines)
+{
+  JDIMENSION row_ctr, rows_left;
+
+  if (cinfo->global_state != CSTATE_SCANNING)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  if (cinfo->next_scanline >= cinfo->image_height)
+    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+
+  /* Call progress monitor hook if present */
+  if (cinfo->progress != NULL) {
+    cinfo->progress->pass_counter = (long) cinfo->next_scanline;
+    cinfo->progress->pass_limit = (long) cinfo->image_height;
+    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+  }
+
+  /* Give master control module another chance if this is first call to
+   * jpeg_write_scanlines.  This lets output of the frame/scan headers be
+   * delayed so that application can write COM, etc, markers between
+   * jpeg_start_compress and jpeg_write_scanlines.
+   */
+  if (cinfo->master->call_pass_startup)
+    (*cinfo->master->pass_startup) (cinfo);
+
+  /* Ignore any extra scanlines at bottom of image. */
+  rows_left = cinfo->image_height - cinfo->next_scanline;
+  if (num_lines > rows_left)
+    num_lines = rows_left;
+
+  row_ctr = 0;
+  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
+  cinfo->next_scanline += row_ctr;
+  return row_ctr;
+}
+
+
+/*
+ * Alternate entry point to write raw data.
+ * Processes exactly one iMCU row per call, unless suspended.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
+		     JDIMENSION num_lines)
+{
+  JDIMENSION lines_per_iMCU_row;
+
+  if (cinfo->global_state != CSTATE_RAW_OK)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  if (cinfo->next_scanline >= cinfo->image_height) {
+    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+    return 0;
+  }
+
+  /* Call progress monitor hook if present */
+  if (cinfo->progress != NULL) {
+    cinfo->progress->pass_counter = (long) cinfo->next_scanline;
+    cinfo->progress->pass_limit = (long) cinfo->image_height;
+    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+  }
+
+  /* Give master control module another chance if this is first call to
+   * jpeg_write_raw_data.  This lets output of the frame/scan headers be
+   * delayed so that application can write COM, etc, markers between
+   * jpeg_start_compress and jpeg_write_raw_data.
+   */
+  if (cinfo->master->call_pass_startup)
+    (*cinfo->master->pass_startup) (cinfo);
+
+  /* Verify that at least one iMCU row has been passed. */
+  lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
+  if (num_lines < lines_per_iMCU_row)
+    ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+  /* Directly compress the row. */
+  if (! (*cinfo->coef->compress_data) (cinfo, data)) {
+    /* If compressor did not consume the whole row, suspend processing. */
+    return 0;
+  }
+
+  /* OK, we processed one iMCU row. */
+  cinfo->next_scanline += lines_per_iMCU_row;
+  return lines_per_iMCU_row;
+}
diff --git a/Utilities/FLTK/jpeg/jccoefct.c b/Utilities/FLTK/jpeg/jccoefct.c
new file mode 100644
index 0000000000000000000000000000000000000000..1963ddb61b15689e36e3f1774007d3583b787a26
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jccoefct.c
@@ -0,0 +1,449 @@
+/*
+ * jccoefct.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the coefficient buffer controller for compression.
+ * This controller is the top level of the JPEG compressor proper.
+ * The coefficient buffer lies between forward-DCT and entropy encoding steps.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* We use a full-image coefficient buffer when doing Huffman optimization,
+ * and also for writing multiple-scan JPEG files.  In all cases, the DCT
+ * step is run during the first pass, and subsequent passes need only read
+ * the buffered coefficients.
+ */
+#ifdef ENTROPY_OPT_SUPPORTED
+#define FULL_COEF_BUFFER_SUPPORTED
+#else
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+#define FULL_COEF_BUFFER_SUPPORTED
+#endif
+#endif
+
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_c_coef_controller pub; /* public fields */
+
+  JDIMENSION iMCU_row_num;	/* iMCU row # within image */
+  JDIMENSION mcu_ctr;		/* counts MCUs processed in current row */
+  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
+  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
+
+  /* For single-pass compression, it's sufficient to buffer just one MCU
+   * (although this may prove a bit slow in practice).  We allocate a
+   * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
+   * MCU constructed and sent.  (On 80x86, the workspace is FAR even though
+   * it's not really very big; this is to keep the module interfaces unchanged
+   * when a large coefficient buffer is necessary.)
+   * In multi-pass modes, this array points to the current MCU's blocks
+   * within the virtual arrays.
+   */
+  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
+
+  /* In multi-pass modes, we need a virtual block array for each component. */
+  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+
+/* Forward declarations */
+METHODDEF(boolean) compress_data
+    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+METHODDEF(boolean) compress_first_pass
+    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+METHODDEF(boolean) compress_output
+    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+#endif
+
+
+LOCAL(void)
+start_iMCU_row (j_compress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row */
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  /* In an interleaved scan, an MCU row is the same as an iMCU row.
+   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+   * But at the bottom of the image, process only what's left.
+   */
+  if (cinfo->comps_in_scan > 1) {
+    coef->MCU_rows_per_iMCU_row = 1;
+  } else {
+    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+    else
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+  }
+
+  coef->mcu_ctr = 0;
+  coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  coef->iMCU_row_num = 0;
+  start_iMCU_row(cinfo);
+
+  switch (pass_mode) {
+  case JBUF_PASS_THRU:
+    if (coef->whole_image[0] != NULL)
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    coef->pub.compress_data = compress_data;
+    break;
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+  case JBUF_SAVE_AND_PASS:
+    if (coef->whole_image[0] == NULL)
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    coef->pub.compress_data = compress_first_pass;
+    break;
+  case JBUF_CRANK_DEST:
+    if (coef->whole_image[0] == NULL)
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    coef->pub.compress_data = compress_output;
+    break;
+#endif
+  default:
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    break;
+  }
+}
+
+
+/*
+ * Process some data in the single-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the image.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf contains a plane for each component in image,
+ * which we index according to the component's SOF position.
+ */
+
+METHODDEF(boolean)
+compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION MCU_col_num;	/* index of current MCU within row */
+  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+  int blkn, bi, ci, yindex, yoffset, blockcnt;
+  JDIMENSION ypos, xpos;
+  jpeg_component_info *compptr;
+
+  /* Loop to write as much as one whole iMCU row */
+  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+       yoffset++) {
+    for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
+	 MCU_col_num++) {
+      /* Determine where data comes from in input_buf and do the DCT thing.
+       * Each call on forward_DCT processes a horizontal row of DCT blocks
+       * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
+       * sequentially.  Dummy blocks at the right or bottom edge are filled in
+       * specially.  The data in them does not matter for image reconstruction,
+       * so we fill them with values that will encode to the smallest amount of
+       * data, viz: all zeroes in the AC entries, DC entries equal to previous
+       * block's DC value.  (Thanks to Thomas Kinsman for this idea.)
+       */
+      blkn = 0;
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+	compptr = cinfo->cur_comp_info[ci];
+	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+						: compptr->last_col_width;
+	xpos = MCU_col_num * compptr->MCU_sample_width;
+	ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
+	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+	  if (coef->iMCU_row_num < last_iMCU_row ||
+	      yoffset+yindex < compptr->last_row_height) {
+	    (*cinfo->fdct->forward_DCT) (cinfo, compptr,
+					 input_buf[compptr->component_index],
+					 coef->MCU_buffer[blkn],
+					 ypos, xpos, (JDIMENSION) blockcnt);
+	    if (blockcnt < compptr->MCU_width) {
+	      /* Create some dummy blocks at the right edge of the image. */
+	      jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
+			(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
+	      for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
+		coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
+	      }
+	    }
+	  } else {
+	    /* Create a row of dummy blocks at the bottom of the image. */
+	    jzero_far((void FAR *) coef->MCU_buffer[blkn],
+		      compptr->MCU_width * SIZEOF(JBLOCK));
+	    for (bi = 0; bi < compptr->MCU_width; bi++) {
+	      coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
+	    }
+	  }
+	  blkn += compptr->MCU_width;
+	  ypos += DCTSIZE;
+	}
+      }
+      /* Try to write the MCU.  In event of a suspension failure, we will
+       * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
+       */
+      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
+	/* Suspension forced; update state counters and exit */
+	coef->MCU_vert_offset = yoffset;
+	coef->mcu_ctr = MCU_col_num;
+	return FALSE;
+      }
+    }
+    /* Completed an MCU row, but perhaps not an iMCU row */
+    coef->mcu_ctr = 0;
+  }
+  /* Completed the iMCU row, advance counters for next one */
+  coef->iMCU_row_num++;
+  start_iMCU_row(cinfo);
+  return TRUE;
+}
+
+
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+
+/*
+ * Process some data in the first pass of a multi-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the image.
+ * This amount of data is read from the source buffer, DCT'd and quantized,
+ * and saved into the virtual arrays.  We also generate suitable dummy blocks
+ * as needed at the right and lower edges.  (The dummy blocks are constructed
+ * in the virtual arrays, which have been padded appropriately.)  This makes
+ * it possible for subsequent passes not to worry about real vs. dummy blocks.
+ *
+ * We must also emit the data to the entropy encoder.  This is conveniently
+ * done by calling compress_output() after we've loaded the current strip
+ * of the virtual arrays.
+ *
+ * NB: input_buf contains a plane for each component in image.  All
+ * components are DCT'd and loaded into the virtual arrays in this pass.
+ * However, it may be that only a subset of the components are emitted to
+ * the entropy encoder during this first pass; be careful about looking
+ * at the scan-dependent variables (MCU dimensions, etc).
+ */
+
+METHODDEF(boolean)
+compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+  JDIMENSION blocks_across, MCUs_across, MCUindex;
+  int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
+  JCOEF lastDC;
+  jpeg_component_info *compptr;
+  JBLOCKARRAY buffer;
+  JBLOCKROW thisblockrow, lastblockrow;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Align the virtual buffer for this component. */
+    buffer = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr) cinfo, coef->whole_image[ci],
+       coef->iMCU_row_num * compptr->v_samp_factor,
+       (JDIMENSION) compptr->v_samp_factor, TRUE);
+    /* Count non-dummy DCT block rows in this iMCU row. */
+    if (coef->iMCU_row_num < last_iMCU_row)
+      block_rows = compptr->v_samp_factor;
+    else {
+      /* NB: can't use last_row_height here, since may not be set! */
+      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+      if (block_rows == 0) block_rows = compptr->v_samp_factor;
+    }
+    blocks_across = compptr->width_in_blocks;
+    h_samp_factor = compptr->h_samp_factor;
+    /* Count number of dummy blocks to be added at the right margin. */
+    ndummy = (int) (blocks_across % h_samp_factor);
+    if (ndummy > 0)
+      ndummy = h_samp_factor - ndummy;
+    /* Perform DCT for all non-dummy blocks in this iMCU row.  Each call
+     * on forward_DCT processes a complete horizontal row of DCT blocks.
+     */
+    for (block_row = 0; block_row < block_rows; block_row++) {
+      thisblockrow = buffer[block_row];
+      (*cinfo->fdct->forward_DCT) (cinfo, compptr,
+				   input_buf[ci], thisblockrow,
+				   (JDIMENSION) (block_row * DCTSIZE),
+				   (JDIMENSION) 0, blocks_across);
+      if (ndummy > 0) {
+	/* Create dummy blocks at the right edge of the image. */
+	thisblockrow += blocks_across; /* => first dummy block */
+	jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
+	lastDC = thisblockrow[-1][0];
+	for (bi = 0; bi < ndummy; bi++) {
+	  thisblockrow[bi][0] = lastDC;
+	}
+      }
+    }
+    /* If at end of image, create dummy block rows as needed.
+     * The tricky part here is that within each MCU, we want the DC values
+     * of the dummy blocks to match the last real block's DC value.
+     * This squeezes a few more bytes out of the resulting file...
+     */
+    if (coef->iMCU_row_num == last_iMCU_row) {
+      blocks_across += ndummy;	/* include lower right corner */
+      MCUs_across = blocks_across / h_samp_factor;
+      for (block_row = block_rows; block_row < compptr->v_samp_factor;
+	   block_row++) {
+	thisblockrow = buffer[block_row];
+	lastblockrow = buffer[block_row-1];
+	jzero_far((void FAR *) thisblockrow,
+		  (size_t) (blocks_across * SIZEOF(JBLOCK)));
+	for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
+	  lastDC = lastblockrow[h_samp_factor-1][0];
+	  for (bi = 0; bi < h_samp_factor; bi++) {
+	    thisblockrow[bi][0] = lastDC;
+	  }
+	  thisblockrow += h_samp_factor; /* advance to next MCU in row */
+	  lastblockrow += h_samp_factor;
+	}
+      }
+    }
+  }
+  /* NB: compress_output will increment iMCU_row_num if successful.
+   * A suspension return will result in redoing all the work above next time.
+   */
+
+  /* Emit data to the entropy encoder, sharing code with subsequent passes */
+  return compress_output(cinfo, input_buf);
+}
+
+
+/*
+ * Process some data in subsequent passes of a multi-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the scan.
+ * The data is obtained from the virtual arrays and fed to the entropy coder.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf is ignored; it is likely to be a NULL pointer.
+ */
+
+METHODDEF(boolean)
+compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION MCU_col_num;	/* index of current MCU within row */
+  int blkn, ci, xindex, yindex, yoffset;
+  JDIMENSION start_col;
+  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+  JBLOCKROW buffer_ptr;
+  jpeg_component_info *compptr;
+
+  /* Align the virtual buffers for the components used in this scan.
+   * NB: during first pass, this is safe only because the buffers will
+   * already be aligned properly, so jmemmgr.c won't need to do any I/O.
+   */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    buffer[ci] = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+       coef->iMCU_row_num * compptr->v_samp_factor,
+       (JDIMENSION) compptr->v_samp_factor, FALSE);
+  }
+
+  /* Loop to process one whole iMCU row */
+  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+       yoffset++) {
+    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
+	 MCU_col_num++) {
+      /* Construct list of pointers to DCT blocks belonging to this MCU */
+      blkn = 0;			/* index of current DCT block within MCU */
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+	compptr = cinfo->cur_comp_info[ci];
+	start_col = MCU_col_num * compptr->MCU_width;
+	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
+	    coef->MCU_buffer[blkn++] = buffer_ptr++;
+	  }
+	}
+      }
+      /* Try to write the MCU. */
+      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
+	/* Suspension forced; update state counters and exit */
+	coef->MCU_vert_offset = yoffset;
+	coef->mcu_ctr = MCU_col_num;
+	return FALSE;
+      }
+    }
+    /* Completed an MCU row, but perhaps not an iMCU row */
+    coef->mcu_ctr = 0;
+  }
+  /* Completed the iMCU row, advance counters for next one */
+  coef->iMCU_row_num++;
+  start_iMCU_row(cinfo);
+  return TRUE;
+}
+
+#endif /* FULL_COEF_BUFFER_SUPPORTED */
+
+
+/*
+ * Initialize coefficient buffer controller.
+ */
+
+GLOBAL(void)
+jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+  my_coef_ptr coef;
+
+  coef = (my_coef_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_coef_controller));
+  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+  coef->pub.start_pass = start_pass_coef;
+
+  /* Create the coefficient buffer. */
+  if (need_full_buffer) {
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+    /* Allocate a full-image virtual array for each component, */
+    /* padded to a multiple of samp_factor DCT blocks in each direction. */
+    int ci;
+    jpeg_component_info *compptr;
+
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+				(long) compptr->h_samp_factor),
+	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+				(long) compptr->v_samp_factor),
+	 (JDIMENSION) compptr->v_samp_factor);
+    }
+#else
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+  } else {
+    /* We only need a single-MCU buffer. */
+    JBLOCKROW buffer;
+    int i;
+
+    buffer = (JBLOCKROW)
+      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+    for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
+      coef->MCU_buffer[i] = buffer + i;
+    }
+    coef->whole_image[0] = NULL; /* flag for no virtual arrays */
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jccolor.c b/Utilities/FLTK/jpeg/jccolor.c
new file mode 100644
index 0000000000000000000000000000000000000000..0a8a4b5d13c303c4d14cd5b4333adcbb3cfcc4a2
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jccolor.c
@@ -0,0 +1,459 @@
+/*
+ * jccolor.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains input colorspace conversion routines.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private subobject */
+
+typedef struct {
+  struct jpeg_color_converter pub; /* public fields */
+
+  /* Private state for RGB->YCC conversion */
+  INT32 * rgb_ycc_tab;		/* => table for RGB to YCbCr conversion */
+} my_color_converter;
+
+typedef my_color_converter * my_cconvert_ptr;
+
+
+/**************** RGB -> YCbCr conversion: most common case **************/
+
+/*
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *	Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
+ *	Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + CENTERJSAMPLE
+ *	Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + CENTERJSAMPLE
+ * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
+ * rather than CENTERJSAMPLE, for Cb and Cr.  This gave equal positive and
+ * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
+ * were not represented exactly.  Now we sacrifice exact representation of
+ * maximum red and maximum blue in order to get exact grayscales.
+ *
+ * To avoid floating-point arithmetic, we represent the fractional constants
+ * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
+ * the products by 2^16, with appropriate rounding, to get the correct answer.
+ *
+ * For even more speed, we avoid doing any multiplications in the inner loop
+ * by precalculating the constants times R,G,B for all possible values.
+ * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
+ * for 12-bit samples it is still acceptable.  It's not very reasonable for
+ * 16-bit samples, but if you want lossless storage you shouldn't be changing
+ * colorspace anyway.
+ * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
+ * in the tables to save adding them separately in the inner loop.
+ */
+
+#define SCALEBITS	16	/* speediest right-shift on some machines */
+#define CBCR_OFFSET	((INT32) CENTERJSAMPLE << SCALEBITS)
+#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
+#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+/* We allocate one big table and divide it up into eight parts, instead of
+ * doing eight alloc_small requests.  This lets us use a single table base
+ * address, which can be held in a register in the inner loops on many
+ * machines (more than can hold all eight addresses, anyway).
+ */
+
+#define R_Y_OFF		0			/* offset to R => Y section */
+#define G_Y_OFF		(1*(MAXJSAMPLE+1))	/* offset to G => Y section */
+#define B_Y_OFF		(2*(MAXJSAMPLE+1))	/* etc. */
+#define R_CB_OFF	(3*(MAXJSAMPLE+1))
+#define G_CB_OFF	(4*(MAXJSAMPLE+1))
+#define B_CB_OFF	(5*(MAXJSAMPLE+1))
+#define R_CR_OFF	B_CB_OFF		/* B=>Cb, R=>Cr are the same */
+#define G_CR_OFF	(6*(MAXJSAMPLE+1))
+#define B_CR_OFF	(7*(MAXJSAMPLE+1))
+#define TABLE_SIZE	(8*(MAXJSAMPLE+1))
+
+
+/*
+ * Initialize for RGB->YCC colorspace conversion.
+ */
+
+METHODDEF(void)
+rgb_ycc_start (j_compress_ptr cinfo)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  INT32 * rgb_ycc_tab;
+  INT32 i;
+
+  /* Allocate and fill in the conversion tables. */
+  cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(TABLE_SIZE * SIZEOF(INT32)));
+
+  for (i = 0; i <= MAXJSAMPLE; i++) {
+    rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
+    rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
+    rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i     + ONE_HALF;
+    rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
+    rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
+    /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
+     * This ensures that the maximum output will round to MAXJSAMPLE
+     * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
+     */
+    rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
+/*  B=>Cb and R=>Cr tables are the same
+    rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
+*/
+    rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
+    rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
+  }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ *
+ * Note that we change from the application's interleaved-pixel format
+ * to our internal noninterleaved, one-plane-per-component format.
+ * The input buffer is therefore three times as wide as the output buffer.
+ *
+ * A starting row offset is provided only for the output buffer.  The caller
+ * can easily adjust the passed input_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+METHODDEF(void)
+rgb_ycc_convert (j_compress_ptr cinfo,
+		 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+		 JDIMENSION output_row, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int r, g, b;
+  register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register JSAMPROW inptr;
+  register JSAMPROW outptr0, outptr1, outptr2;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->image_width;
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr0 = output_buf[0][output_row];
+    outptr1 = output_buf[1][output_row];
+    outptr2 = output_buf[2][output_row];
+    output_row++;
+    for (col = 0; col < num_cols; col++) {
+      r = GETJSAMPLE(inptr[RGB_RED]);
+      g = GETJSAMPLE(inptr[RGB_GREEN]);
+      b = GETJSAMPLE(inptr[RGB_BLUE]);
+      inptr += RGB_PIXELSIZE;
+      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+       * must be too; we do not need an explicit range-limiting operation.
+       * Hence the value being shifted is never negative, and we don't
+       * need the general RIGHT_SHIFT macro.
+       */
+      /* Y */
+      outptr0[col] = (JSAMPLE)
+		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+		 >> SCALEBITS);
+      /* Cb */
+      outptr1[col] = (JSAMPLE)
+		((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
+		 >> SCALEBITS);
+      /* Cr */
+      outptr2[col] = (JSAMPLE)
+		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
+		 >> SCALEBITS);
+    }
+  }
+}
+
+
+/**************** Cases other than RGB -> YCbCr **************/
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles RGB->grayscale conversion, which is the same
+ * as the RGB->Y portion of RGB->YCbCr.
+ * We assume rgb_ycc_start has been called (we only use the Y tables).
+ */
+
+METHODDEF(void)
+rgb_gray_convert (j_compress_ptr cinfo,
+		  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+		  JDIMENSION output_row, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int r, g, b;
+  register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register JSAMPROW inptr;
+  register JSAMPROW outptr;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->image_width;
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr = output_buf[0][output_row];
+    output_row++;
+    for (col = 0; col < num_cols; col++) {
+      r = GETJSAMPLE(inptr[RGB_RED]);
+      g = GETJSAMPLE(inptr[RGB_GREEN]);
+      b = GETJSAMPLE(inptr[RGB_BLUE]);
+      inptr += RGB_PIXELSIZE;
+      /* Y */
+      outptr[col] = (JSAMPLE)
+		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+		 >> SCALEBITS);
+    }
+  }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles Adobe-style CMYK->YCCK conversion,
+ * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
+ * conversion as above, while passing K (black) unchanged.
+ * We assume rgb_ycc_start has been called.
+ */
+
+METHODDEF(void)
+cmyk_ycck_convert (j_compress_ptr cinfo,
+		   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+		   JDIMENSION output_row, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int r, g, b;
+  register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register JSAMPROW inptr;
+  register JSAMPROW outptr0, outptr1, outptr2, outptr3;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->image_width;
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr0 = output_buf[0][output_row];
+    outptr1 = output_buf[1][output_row];
+    outptr2 = output_buf[2][output_row];
+    outptr3 = output_buf[3][output_row];
+    output_row++;
+    for (col = 0; col < num_cols; col++) {
+      r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
+      g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
+      b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
+      /* K passes through as-is */
+      outptr3[col] = inptr[3];	/* don't need GETJSAMPLE here */
+      inptr += 4;
+      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+       * must be too; we do not need an explicit range-limiting operation.
+       * Hence the value being shifted is never negative, and we don't
+       * need the general RIGHT_SHIFT macro.
+       */
+      /* Y */
+      outptr0[col] = (JSAMPLE)
+		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+		 >> SCALEBITS);
+      /* Cb */
+      outptr1[col] = (JSAMPLE)
+		((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
+		 >> SCALEBITS);
+      /* Cr */
+      outptr2[col] = (JSAMPLE)
+		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
+		 >> SCALEBITS);
+    }
+  }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles grayscale output with no conversion.
+ * The source can be either plain grayscale or YCbCr (since Y == gray).
+ */
+
+METHODDEF(void)
+grayscale_convert (j_compress_ptr cinfo,
+		   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+		   JDIMENSION output_row, int num_rows)
+{
+  register JSAMPROW inptr;
+  register JSAMPROW outptr;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->image_width;
+  int instride = cinfo->input_components;
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr = output_buf[0][output_row];
+    output_row++;
+    for (col = 0; col < num_cols; col++) {
+      outptr[col] = inptr[0];	/* don't need GETJSAMPLE() here */
+      inptr += instride;
+    }
+  }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles multi-component colorspaces without conversion.
+ * We assume input_components == num_components.
+ */
+
+METHODDEF(void)
+null_convert (j_compress_ptr cinfo,
+	      JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+	      JDIMENSION output_row, int num_rows)
+{
+  register JSAMPROW inptr;
+  register JSAMPROW outptr;
+  register JDIMENSION col;
+  register int ci;
+  int nc = cinfo->num_components;
+  JDIMENSION num_cols = cinfo->image_width;
+
+  while (--num_rows >= 0) {
+    /* It seems fastest to make a separate pass for each component. */
+    for (ci = 0; ci < nc; ci++) {
+      inptr = *input_buf;
+      outptr = output_buf[ci][output_row];
+      for (col = 0; col < num_cols; col++) {
+	outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
+	inptr += nc;
+      }
+    }
+    input_buf++;
+    output_row++;
+  }
+}
+
+
+/*
+ * Empty method for start_pass.
+ */
+
+METHODDEF(void)
+null_method (j_compress_ptr cinfo)
+{
+  /* no work needed */
+}
+
+
+/*
+ * Module initialization routine for input colorspace conversion.
+ */
+
+GLOBAL(void)
+jinit_color_converter (j_compress_ptr cinfo)
+{
+  my_cconvert_ptr cconvert;
+
+  cconvert = (my_cconvert_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_color_converter));
+  cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
+  /* set start_pass to null method until we find out differently */
+  cconvert->pub.start_pass = null_method;
+
+  /* Make sure input_components agrees with in_color_space */
+  switch (cinfo->in_color_space) {
+  case JCS_GRAYSCALE:
+    if (cinfo->input_components != 1)
+      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+    break;
+
+  case JCS_RGB:
+#if RGB_PIXELSIZE != 3
+    if (cinfo->input_components != RGB_PIXELSIZE)
+      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+    break;
+#endif /* else share code with YCbCr */
+
+  case JCS_YCbCr:
+    if (cinfo->input_components != 3)
+      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+    break;
+
+  case JCS_CMYK:
+  case JCS_YCCK:
+    if (cinfo->input_components != 4)
+      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+    break;
+
+  default:			/* JCS_UNKNOWN can be anything */
+    if (cinfo->input_components < 1)
+      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+    break;
+  }
+
+  /* Check num_components, set conversion method based on requested space */
+  switch (cinfo->jpeg_color_space) {
+  case JCS_GRAYSCALE:
+    if (cinfo->num_components != 1)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    if (cinfo->in_color_space == JCS_GRAYSCALE)
+      cconvert->pub.color_convert = grayscale_convert;
+    else if (cinfo->in_color_space == JCS_RGB) {
+      cconvert->pub.start_pass = rgb_ycc_start;
+      cconvert->pub.color_convert = rgb_gray_convert;
+    } else if (cinfo->in_color_space == JCS_YCbCr)
+      cconvert->pub.color_convert = grayscale_convert;
+    else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  case JCS_RGB:
+    if (cinfo->num_components != 3)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
+      cconvert->pub.color_convert = null_convert;
+    else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  case JCS_YCbCr:
+    if (cinfo->num_components != 3)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    if (cinfo->in_color_space == JCS_RGB) {
+      cconvert->pub.start_pass = rgb_ycc_start;
+      cconvert->pub.color_convert = rgb_ycc_convert;
+    } else if (cinfo->in_color_space == JCS_YCbCr)
+      cconvert->pub.color_convert = null_convert;
+    else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  case JCS_CMYK:
+    if (cinfo->num_components != 4)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    if (cinfo->in_color_space == JCS_CMYK)
+      cconvert->pub.color_convert = null_convert;
+    else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  case JCS_YCCK:
+    if (cinfo->num_components != 4)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    if (cinfo->in_color_space == JCS_CMYK) {
+      cconvert->pub.start_pass = rgb_ycc_start;
+      cconvert->pub.color_convert = cmyk_ycck_convert;
+    } else if (cinfo->in_color_space == JCS_YCCK)
+      cconvert->pub.color_convert = null_convert;
+    else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  default:			/* allow null conversion of JCS_UNKNOWN */
+    if (cinfo->jpeg_color_space != cinfo->in_color_space ||
+	cinfo->num_components != cinfo->input_components)
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    cconvert->pub.color_convert = null_convert;
+    break;
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jcdctmgr.c b/Utilities/FLTK/jpeg/jcdctmgr.c
new file mode 100644
index 0000000000000000000000000000000000000000..61fa79b9e68bcc3e3bfe84b9a50af55a9598214b
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcdctmgr.c
@@ -0,0 +1,387 @@
+/*
+ * jcdctmgr.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the forward-DCT management logic.
+ * This code selects a particular DCT implementation to be used,
+ * and it performs related housekeeping chores including coefficient
+ * quantization.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+
+/* Private subobject for this module */
+
+typedef struct {
+  struct jpeg_forward_dct pub;	/* public fields */
+
+  /* Pointer to the DCT routine actually in use */
+  forward_DCT_method_ptr do_dct;
+
+  /* The actual post-DCT divisors --- not identical to the quant table
+   * entries, because of scaling (especially for an unnormalized DCT).
+   * Each table is given in normal array order.
+   */
+  DCTELEM * divisors[NUM_QUANT_TBLS];
+
+#ifdef DCT_FLOAT_SUPPORTED
+  /* Same as above for the floating-point case. */
+  float_DCT_method_ptr do_float_dct;
+  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
+#endif
+} my_fdct_controller;
+
+typedef my_fdct_controller * my_fdct_ptr;
+
+
+/*
+ * Initialize for a processing pass.
+ * Verify that all referenced Q-tables are present, and set up
+ * the divisor table for each one.
+ * In the current implementation, DCT of all components is done during
+ * the first pass, even if only some components will be output in the
+ * first scan.  Hence all components should be examined here.
+ */
+
+METHODDEF(void)
+start_pass_fdctmgr (j_compress_ptr cinfo)
+{
+  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+  int ci, qtblno, i;
+  jpeg_component_info *compptr;
+  JQUANT_TBL * qtbl;
+  DCTELEM * dtbl;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    qtblno = compptr->quant_tbl_no;
+    /* Make sure specified quantization table is present */
+    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
+	cinfo->quant_tbl_ptrs[qtblno] == NULL)
+      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
+    qtbl = cinfo->quant_tbl_ptrs[qtblno];
+    /* Compute divisors for this quant table */
+    /* We may do this more than once for same table, but it's not a big deal */
+    switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+    case JDCT_ISLOW:
+      /* For LL&M IDCT method, divisors are equal to raw quantization
+       * coefficients multiplied by 8 (to counteract scaling).
+       */
+      if (fdct->divisors[qtblno] == NULL) {
+	fdct->divisors[qtblno] = (DCTELEM *)
+	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				      DCTSIZE2 * SIZEOF(DCTELEM));
+      }
+      dtbl = fdct->divisors[qtblno];
+      for (i = 0; i < DCTSIZE2; i++) {
+	dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
+      }
+      break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+    case JDCT_IFAST:
+      {
+	/* For AA&N IDCT method, divisors are equal to quantization
+	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
+	 *   scalefactor[0] = 1
+	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
+	 * We apply a further scale factor of 8.
+	 */
+#define CONST_BITS 14
+	static const INT16 aanscales[DCTSIZE2] = {
+	  /* precomputed values scaled up by 14 bits */
+	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
+	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
+	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
+	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
+	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
+	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
+	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
+	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
+	};
+	SHIFT_TEMPS
+
+	if (fdct->divisors[qtblno] == NULL) {
+	  fdct->divisors[qtblno] = (DCTELEM *)
+	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+					DCTSIZE2 * SIZEOF(DCTELEM));
+	}
+	dtbl = fdct->divisors[qtblno];
+	for (i = 0; i < DCTSIZE2; i++) {
+	  dtbl[i] = (DCTELEM)
+	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
+				  (INT32) aanscales[i]),
+		    CONST_BITS-3);
+	}
+      }
+      break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+    case JDCT_FLOAT:
+      {
+	/* For float AA&N IDCT method, divisors are equal to quantization
+	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
+	 *   scalefactor[0] = 1
+	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
+	 * We apply a further scale factor of 8.
+	 * What's actually stored is 1/divisor so that the inner loop can
+	 * use a multiplication rather than a division.
+	 */
+	FAST_FLOAT * fdtbl;
+	int row, col;
+	static const double aanscalefactor[DCTSIZE] = {
+	  1.0, 1.387039845, 1.306562965, 1.175875602,
+	  1.0, 0.785694958, 0.541196100, 0.275899379
+	};
+
+	if (fdct->float_divisors[qtblno] == NULL) {
+	  fdct->float_divisors[qtblno] = (FAST_FLOAT *)
+	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+					DCTSIZE2 * SIZEOF(FAST_FLOAT));
+	}
+	fdtbl = fdct->float_divisors[qtblno];
+	i = 0;
+	for (row = 0; row < DCTSIZE; row++) {
+	  for (col = 0; col < DCTSIZE; col++) {
+	    fdtbl[i] = (FAST_FLOAT)
+	      (1.0 / (((double) qtbl->quantval[i] *
+		       aanscalefactor[row] * aanscalefactor[col] * 8.0)));
+	    i++;
+	  }
+	}
+      }
+      break;
+#endif
+    default:
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+      break;
+    }
+  }
+}
+
+
+/*
+ * Perform forward DCT on one or more blocks of a component.
+ *
+ * The input samples are taken from the sample_data[] array starting at
+ * position start_row/start_col, and moving to the right for any additional
+ * blocks. The quantized coefficients are returned in coef_blocks[].
+ */
+
+METHODDEF(void)
+forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
+	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+	     JDIMENSION start_row, JDIMENSION start_col,
+	     JDIMENSION num_blocks)
+/* This version is used for integer DCT implementations. */
+{
+  /* This routine is heavily used, so it's worth coding it tightly. */
+  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+  forward_DCT_method_ptr do_dct = fdct->do_dct;
+  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
+  DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
+  JDIMENSION bi;
+
+  sample_data += start_row;	/* fold in the vertical offset once */
+
+  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
+    /* Load data into workspace, applying unsigned->signed conversion */
+    { register DCTELEM *workspaceptr;
+      register JSAMPROW elemptr;
+      register int elemr;
+
+      workspaceptr = workspace;
+      for (elemr = 0; elemr < DCTSIZE; elemr++) {
+	elemptr = sample_data[elemr] + start_col;
+#if DCTSIZE == 8		/* unroll the inner loop */
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+#else
+	{ register int elemc;
+	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
+	    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+	  }
+	}
+#endif
+      }
+    }
+
+    /* Perform the DCT */
+    (*do_dct) (workspace);
+
+    /* Quantize/descale the coefficients, and store into coef_blocks[] */
+    { register DCTELEM temp, qval;
+      register int i;
+      register JCOEFPTR output_ptr = coef_blocks[bi];
+
+      for (i = 0; i < DCTSIZE2; i++) {
+	qval = divisors[i];
+	temp = workspace[i];
+	/* Divide the coefficient value by qval, ensuring proper rounding.
+	 * Since C does not specify the direction of rounding for negative
+	 * quotients, we have to force the dividend positive for portability.
+	 *
+	 * In most files, at least half of the output values will be zero
+	 * (at default quantization settings, more like three-quarters...)
+	 * so we should ensure that this case is fast.  On many machines,
+	 * a comparison is enough cheaper than a divide to make a special test
+	 * a win.  Since both inputs will be nonnegative, we need only test
+	 * for a < b to discover whether a/b is 0.
+	 * If your machine's division is fast enough, define FAST_DIVIDE.
+	 */
+#ifdef FAST_DIVIDE
+#define DIVIDE_BY(a,b)	a /= b
+#else
+#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
+#endif
+	if (temp < 0) {
+	  temp = -temp;
+	  temp += qval>>1;	/* for rounding */
+	  DIVIDE_BY(temp, qval);
+	  temp = -temp;
+	} else {
+	  temp += qval>>1;	/* for rounding */
+	  DIVIDE_BY(temp, qval);
+	}
+	output_ptr[i] = (JCOEF) temp;
+      }
+    }
+  }
+}
+
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+METHODDEF(void)
+forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
+		   JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+		   JDIMENSION start_row, JDIMENSION start_col,
+		   JDIMENSION num_blocks)
+/* This version is used for floating-point DCT implementations. */
+{
+  /* This routine is heavily used, so it's worth coding it tightly. */
+  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+  float_DCT_method_ptr do_dct = fdct->do_float_dct;
+  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
+  FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
+  JDIMENSION bi;
+
+  sample_data += start_row;	/* fold in the vertical offset once */
+
+  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
+    /* Load data into workspace, applying unsigned->signed conversion */
+    { register FAST_FLOAT *workspaceptr;
+      register JSAMPROW elemptr;
+      register int elemr;
+
+      workspaceptr = workspace;
+      for (elemr = 0; elemr < DCTSIZE; elemr++) {
+	elemptr = sample_data[elemr] + start_col;
+#if DCTSIZE == 8		/* unroll the inner loop */
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+#else
+	{ register int elemc;
+	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
+	    *workspaceptr++ = (FAST_FLOAT)
+	      (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+	  }
+	}
+#endif
+      }
+    }
+
+    /* Perform the DCT */
+    (*do_dct) (workspace);
+
+    /* Quantize/descale the coefficients, and store into coef_blocks[] */
+    { register FAST_FLOAT temp;
+      register int i;
+      register JCOEFPTR output_ptr = coef_blocks[bi];
+
+      for (i = 0; i < DCTSIZE2; i++) {
+	/* Apply the quantization and scaling factor */
+	temp = workspace[i] * divisors[i];
+	/* Round to nearest integer.
+	 * Since C does not specify the direction of rounding for negative
+	 * quotients, we have to force the dividend positive for portability.
+	 * The maximum coefficient size is +-16K (for 12-bit data), so this
+	 * code should work for either 16-bit or 32-bit ints.
+	 */
+	output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
+      }
+    }
+  }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
+
+
+/*
+ * Initialize FDCT manager.
+ */
+
+GLOBAL(void)
+jinit_forward_dct (j_compress_ptr cinfo)
+{
+  my_fdct_ptr fdct;
+  int i;
+
+  fdct = (my_fdct_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_fdct_controller));
+  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
+  fdct->pub.start_pass = start_pass_fdctmgr;
+
+  switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+  case JDCT_ISLOW:
+    fdct->pub.forward_DCT = forward_DCT;
+    fdct->do_dct = jpeg_fdct_islow;
+    break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+  case JDCT_IFAST:
+    fdct->pub.forward_DCT = forward_DCT;
+    fdct->do_dct = jpeg_fdct_ifast;
+    break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+  case JDCT_FLOAT:
+    fdct->pub.forward_DCT = forward_DCT_float;
+    fdct->do_float_dct = jpeg_fdct_float;
+    break;
+#endif
+  default:
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+    break;
+  }
+
+  /* Mark divisor tables unallocated */
+  for (i = 0; i < NUM_QUANT_TBLS; i++) {
+    fdct->divisors[i] = NULL;
+#ifdef DCT_FLOAT_SUPPORTED
+    fdct->float_divisors[i] = NULL;
+#endif
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jchuff.c b/Utilities/FLTK/jpeg/jchuff.c
new file mode 100644
index 0000000000000000000000000000000000000000..f235250548671f2d52cabd12ce366a07db4cbf34
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jchuff.c
@@ -0,0 +1,909 @@
+/*
+ * jchuff.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy encoding routines.
+ *
+ * Much of the complexity here has to do with supporting output suspension.
+ * If the data destination module demands suspension, we want to be able to
+ * back up to the start of the current MCU.  To do this, we copy state
+ * variables into local working storage, and update them back to the
+ * permanent JPEG objects only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jchuff.h"		/* Declarations shared with jcphuff.c */
+
+
+/* Expanded entropy encoder object for Huffman encoding.
+ *
+ * The savable_state subrecord contains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+  INT32 put_buffer;		/* current bit-accumulation buffer */
+  int put_bits;			/* # of bits now in it */
+  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment.  You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src)  ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src)  \
+	((dest).put_buffer = (src).put_buffer, \
+	 (dest).put_bits = (src).put_bits, \
+	 (dest).last_dc_val[0] = (src).last_dc_val[0], \
+	 (dest).last_dc_val[1] = (src).last_dc_val[1], \
+	 (dest).last_dc_val[2] = (src).last_dc_val[2], \
+	 (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+  struct jpeg_entropy_encoder pub; /* public fields */
+
+  savable_state saved;		/* Bit buffer & DC state at start of MCU */
+
+  /* These fields are NOT loaded into local working state. */
+  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
+  int next_restart_num;		/* next restart number to write (0-7) */
+
+  /* Pointers to derived tables (these workspaces have image lifespan) */
+  c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
+  c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+
+#ifdef ENTROPY_OPT_SUPPORTED	/* Statistics tables for optimization */
+  long * dc_count_ptrs[NUM_HUFF_TBLS];
+  long * ac_count_ptrs[NUM_HUFF_TBLS];
+#endif
+} huff_entropy_encoder;
+
+typedef huff_entropy_encoder * huff_entropy_ptr;
+
+/* Working state while writing an MCU.
+ * This struct contains all the fields that are needed by subroutines.
+ */
+
+typedef struct {
+  JOCTET * next_output_byte;	/* => next byte to write in buffer */
+  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */
+  savable_state cur;		/* Current bit buffer & DC state */
+  j_compress_ptr cinfo;		/* dump_buffer needs access to this */
+} working_state;
+
+
+/* Forward declarations */
+METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo,
+					JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
+#ifdef ENTROPY_OPT_SUPPORTED
+METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo,
+					  JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
+#endif
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ * If gather_statistics is TRUE, we do not output anything during the scan,
+ * just count the Huffman symbols used and generate Huffman code tables.
+ */
+
+METHODDEF(void)
+start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  int ci, dctbl, actbl;
+  jpeg_component_info * compptr;
+
+  if (gather_statistics) {
+#ifdef ENTROPY_OPT_SUPPORTED
+    entropy->pub.encode_mcu = encode_mcu_gather;
+    entropy->pub.finish_pass = finish_pass_gather;
+#else
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+  } else {
+    entropy->pub.encode_mcu = encode_mcu_huff;
+    entropy->pub.finish_pass = finish_pass_huff;
+  }
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    dctbl = compptr->dc_tbl_no;
+    actbl = compptr->ac_tbl_no;
+    if (gather_statistics) {
+#ifdef ENTROPY_OPT_SUPPORTED
+      /* Check for invalid table indexes */
+      /* (make_c_derived_tbl does this in the other path) */
+      if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
+	ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
+      if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
+	ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
+      /* Allocate and zero the statistics tables */
+      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
+      if (entropy->dc_count_ptrs[dctbl] == NULL)
+	entropy->dc_count_ptrs[dctbl] = (long *)
+	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				      257 * SIZEOF(long));
+      MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long));
+      if (entropy->ac_count_ptrs[actbl] == NULL)
+	entropy->ac_count_ptrs[actbl] = (long *)
+	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				      257 * SIZEOF(long));
+      MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long));
+#endif
+    } else {
+      /* Compute derived values for Huffman tables */
+      /* We may do this more than once for a table, but it's not expensive */
+      jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
+			      & entropy->dc_derived_tbls[dctbl]);
+      jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
+			      & entropy->ac_derived_tbls[actbl]);
+    }
+    /* Initialize DC predictions to 0 */
+    entropy->saved.last_dc_val[ci] = 0;
+  }
+
+  /* Initialize bit buffer to empty */
+  entropy->saved.put_buffer = 0;
+  entropy->saved.put_bits = 0;
+
+  /* Initialize restart stuff */
+  entropy->restarts_to_go = cinfo->restart_interval;
+  entropy->next_restart_num = 0;
+}
+
+
+/*
+ * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
+ * Note this is also used by jcphuff.c.
+ */
+
+GLOBAL(void)
+jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
+			 c_derived_tbl ** pdtbl)
+{
+  JHUFF_TBL *htbl;
+  c_derived_tbl *dtbl;
+  int p, i, l, lastp, si, maxsymbol;
+  char huffsize[257];
+  unsigned int huffcode[257];
+  unsigned int code;
+
+  /* Note that huffsize[] and huffcode[] are filled in code-length order,
+   * paralleling the order of the symbols themselves in htbl->huffval[].
+   */
+
+  /* Find the input Huffman table */
+  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+  htbl =
+    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+  if (htbl == NULL)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
+  /* Allocate a workspace if we haven't already done so. */
+  if (*pdtbl == NULL)
+    *pdtbl = (c_derived_tbl *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(c_derived_tbl));
+  dtbl = *pdtbl;
+  
+  /* Figure C.1: make table of Huffman code length for each symbol */
+
+  p = 0;
+  for (l = 1; l <= 16; l++) {
+    i = (int) htbl->bits[l];
+    if (i < 0 || p + i > 256)	/* protect against table overrun */
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    while (i--)
+      huffsize[p++] = (char) l;
+  }
+  huffsize[p] = 0;
+  lastp = p;
+  
+  /* Figure C.2: generate the codes themselves */
+  /* We also validate that the counts represent a legal Huffman code tree. */
+
+  code = 0;
+  si = huffsize[0];
+  p = 0;
+  while (huffsize[p]) {
+    while (((int) huffsize[p]) == si) {
+      huffcode[p++] = code;
+      code++;
+    }
+    /* code is now 1 more than the last code used for codelength si; but
+     * it must still fit in si bits, since no code is allowed to be all ones.
+     */
+    if (((INT32) code) >= (((INT32) 1) << si))
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    code <<= 1;
+    si++;
+  }
+  
+  /* Figure C.3: generate encoding tables */
+  /* These are code and size indexed by symbol value */
+
+  /* Set all codeless symbols to have code length 0;
+   * this lets us detect duplicate VAL entries here, and later
+   * allows emit_bits to detect any attempt to emit such symbols.
+   */
+  MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
+
+  /* This is also a convenient place to check for out-of-range
+   * and duplicated VAL entries.  We allow 0..255 for AC symbols
+   * but only 0..15 for DC.  (We could constrain them further
+   * based on data depth and mode, but this seems enough.)
+   */
+  maxsymbol = isDC ? 15 : 255;
+
+  for (p = 0; p < lastp; p++) {
+    i = htbl->huffval[p];
+    if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    dtbl->ehufco[i] = huffcode[p];
+    dtbl->ehufsi[i] = huffsize[p];
+  }
+}
+
+
+/* Outputting bytes to the file */
+
+/* Emit a byte, taking 'action' if must suspend. */
+#define emit_byte(state,val,action)  \
+	{ *(state)->next_output_byte++ = (JOCTET) (val);  \
+	  if (--(state)->free_in_buffer == 0)  \
+	    if (! dump_buffer(state))  \
+	      { action; } }
+
+
+LOCAL(boolean)
+dump_buffer (working_state * state)
+/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
+{
+  struct jpeg_destination_mgr * dest = state->cinfo->dest;
+
+  if (! (*dest->empty_output_buffer) (state->cinfo))
+    return FALSE;
+  /* After a successful buffer dump, must reset buffer pointers */
+  state->next_output_byte = dest->next_output_byte;
+  state->free_in_buffer = dest->free_in_buffer;
+  return TRUE;
+}
+
+
+/* Outputting bits to the file */
+
+/* Only the right 24 bits of put_buffer are used; the valid bits are
+ * left-justified in this part.  At most 16 bits can be passed to emit_bits
+ * in one call, and we never retain more than 7 bits in put_buffer
+ * between calls, so 24 bits are sufficient.
+ */
+
+INLINE
+LOCAL(boolean)
+emit_bits (working_state * state, unsigned int code, int size)
+/* Emit some bits; return TRUE if successful, FALSE if must suspend */
+{
+  /* This routine is heavily used, so it's worth coding tightly. */
+  register INT32 put_buffer = (INT32) code;
+  register int put_bits = state->cur.put_bits;
+
+  /* if size is 0, caller used an invalid Huffman table entry */
+  if (size == 0)
+    ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
+
+  put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
+  
+  put_bits += size;		/* new number of bits in buffer */
+  
+  put_buffer <<= 24 - put_bits; /* align incoming bits */
+
+  put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
+  
+  while (put_bits >= 8) {
+    int c = (int) ((put_buffer >> 16) & 0xFF);
+    
+    emit_byte(state, c, return FALSE);
+    if (c == 0xFF) {		/* need to stuff a zero byte? */
+      emit_byte(state, 0, return FALSE);
+    }
+    put_buffer <<= 8;
+    put_bits -= 8;
+  }
+
+  state->cur.put_buffer = put_buffer; /* update state variables */
+  state->cur.put_bits = put_bits;
+
+  return TRUE;
+}
+
+
+LOCAL(boolean)
+flush_bits (working_state * state)
+{
+  if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
+    return FALSE;
+  state->cur.put_buffer = 0;	/* and reset bit-buffer to empty */
+  state->cur.put_bits = 0;
+  return TRUE;
+}
+
+
+/* Encode a single block's worth of coefficients */
+
+LOCAL(boolean)
+encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
+		  c_derived_tbl *dctbl, c_derived_tbl *actbl)
+{
+  register int temp, temp2;
+  register int nbits;
+  register int k, r, i;
+  
+  /* Encode the DC coefficient difference per section F.1.2.1 */
+  
+  temp = temp2 = block[0] - last_dc_val;
+
+  if (temp < 0) {
+    temp = -temp;		/* temp is abs value of input */
+    /* For a negative input, want temp2 = bitwise complement of abs(input) */
+    /* This code assumes we are on a two's complement machine */
+    temp2--;
+  }
+  
+  /* Find the number of bits needed for the magnitude of the coefficient */
+  nbits = 0;
+  while (temp) {
+    nbits++;
+    temp >>= 1;
+  }
+  /* Check for out-of-range coefficient values.
+   * Since we're encoding a difference, the range limit is twice as much.
+   */
+  if (nbits > MAX_COEF_BITS+1)
+    ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
+  
+  /* Emit the Huffman-coded symbol for the number of bits */
+  if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
+    return FALSE;
+
+  /* Emit that number of bits of the value, if positive, */
+  /* or the complement of its magnitude, if negative. */
+  if (nbits)			/* emit_bits rejects calls with size 0 */
+    if (! emit_bits(state, (unsigned int) temp2, nbits))
+      return FALSE;
+
+  /* Encode the AC coefficients per section F.1.2.2 */
+  
+  r = 0;			/* r = run length of zeros */
+  
+  for (k = 1; k < DCTSIZE2; k++) {
+    if ((temp = block[jpeg_natural_order[k]]) == 0) {
+      r++;
+    } else {
+      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+      while (r > 15) {
+	if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
+	  return FALSE;
+	r -= 16;
+      }
+
+      temp2 = temp;
+      if (temp < 0) {
+	temp = -temp;		/* temp is abs value of input */
+	/* This code assumes we are on a two's complement machine */
+	temp2--;
+      }
+      
+      /* Find the number of bits needed for the magnitude of the coefficient */
+      nbits = 1;		/* there must be at least one 1 bit */
+      while ((temp >>= 1))
+	nbits++;
+      /* Check for out-of-range coefficient values */
+      if (nbits > MAX_COEF_BITS)
+	ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
+      
+      /* Emit Huffman symbol for run length / number of bits */
+      i = (r << 4) + nbits;
+      if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
+	return FALSE;
+
+      /* Emit that number of bits of the value, if positive, */
+      /* or the complement of its magnitude, if negative. */
+      if (! emit_bits(state, (unsigned int) temp2, nbits))
+	return FALSE;
+      
+      r = 0;
+    }
+  }
+
+  /* If the last coef(s) were zero, emit an end-of-block code */
+  if (r > 0)
+    if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
+      return FALSE;
+
+  return TRUE;
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL(boolean)
+emit_restart (working_state * state, int restart_num)
+{
+  int ci;
+
+  if (! flush_bits(state))
+    return FALSE;
+
+  emit_byte(state, 0xFF, return FALSE);
+  emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
+
+  /* Re-initialize DC predictions to 0 */
+  for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
+    state->cur.last_dc_val[ci] = 0;
+
+  /* The restart counter is not updated until we successfully write the MCU. */
+
+  return TRUE;
+}
+
+
+/*
+ * Encode and output one MCU's worth of Huffman-compressed coefficients.
+ */
+
+METHODDEF(boolean)
+encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  working_state state;
+  int blkn, ci;
+  jpeg_component_info * compptr;
+
+  /* Load up working state */
+  state.next_output_byte = cinfo->dest->next_output_byte;
+  state.free_in_buffer = cinfo->dest->free_in_buffer;
+  ASSIGN_STATE(state.cur, entropy->saved);
+  state.cinfo = cinfo;
+
+  /* Emit restart marker if needed */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0)
+      if (! emit_restart(&state, entropy->next_restart_num))
+	return FALSE;
+  }
+
+  /* Encode the MCU data blocks */
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+    if (! encode_one_block(&state,
+			   MCU_data[blkn][0], state.cur.last_dc_val[ci],
+			   entropy->dc_derived_tbls[compptr->dc_tbl_no],
+			   entropy->ac_derived_tbls[compptr->ac_tbl_no]))
+      return FALSE;
+    /* Update last_dc_val */
+    state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
+  }
+
+  /* Completed MCU, so update state */
+  cinfo->dest->next_output_byte = state.next_output_byte;
+  cinfo->dest->free_in_buffer = state.free_in_buffer;
+  ASSIGN_STATE(entropy->saved, state.cur);
+
+  /* Update restart-interval state too */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0) {
+      entropy->restarts_to_go = cinfo->restart_interval;
+      entropy->next_restart_num++;
+      entropy->next_restart_num &= 7;
+    }
+    entropy->restarts_to_go--;
+  }
+
+  return TRUE;
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+finish_pass_huff (j_compress_ptr cinfo)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  working_state state;
+
+  /* Load up working state ... flush_bits needs it */
+  state.next_output_byte = cinfo->dest->next_output_byte;
+  state.free_in_buffer = cinfo->dest->free_in_buffer;
+  ASSIGN_STATE(state.cur, entropy->saved);
+  state.cinfo = cinfo;
+
+  /* Flush out the last data */
+  if (! flush_bits(&state))
+    ERREXIT(cinfo, JERR_CANT_SUSPEND);
+
+  /* Update state */
+  cinfo->dest->next_output_byte = state.next_output_byte;
+  cinfo->dest->free_in_buffer = state.free_in_buffer;
+  ASSIGN_STATE(entropy->saved, state.cur);
+}
+
+
+/*
+ * Huffman coding optimization.
+ *
+ * We first scan the supplied data and count the number of uses of each symbol
+ * that is to be Huffman-coded. (This process MUST agree with the code above.)
+ * Then we build a Huffman coding tree for the observed counts.
+ * Symbols which are not needed at all for the particular image are not
+ * assigned any code, which saves space in the DHT marker as well as in
+ * the compressed data.
+ */
+
+#ifdef ENTROPY_OPT_SUPPORTED
+
+
+/* Process a single block's worth of coefficients */
+
+LOCAL(void)
+htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
+		 long dc_counts[], long ac_counts[])
+{
+  register int temp;
+  register int nbits;
+  register int k, r;
+  
+  /* Encode the DC coefficient difference per section F.1.2.1 */
+  
+  temp = block[0] - last_dc_val;
+  if (temp < 0)
+    temp = -temp;
+  
+  /* Find the number of bits needed for the magnitude of the coefficient */
+  nbits = 0;
+  while (temp) {
+    nbits++;
+    temp >>= 1;
+  }
+  /* Check for out-of-range coefficient values.
+   * Since we're encoding a difference, the range limit is twice as much.
+   */
+  if (nbits > MAX_COEF_BITS+1)
+    ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+  /* Count the Huffman symbol for the number of bits */
+  dc_counts[nbits]++;
+  
+  /* Encode the AC coefficients per section F.1.2.2 */
+  
+  r = 0;			/* r = run length of zeros */
+  
+  for (k = 1; k < DCTSIZE2; k++) {
+    if ((temp = block[jpeg_natural_order[k]]) == 0) {
+      r++;
+    } else {
+      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+      while (r > 15) {
+	ac_counts[0xF0]++;
+	r -= 16;
+      }
+      
+      /* Find the number of bits needed for the magnitude of the coefficient */
+      if (temp < 0)
+	temp = -temp;
+      
+      /* Find the number of bits needed for the magnitude of the coefficient */
+      nbits = 1;		/* there must be at least one 1 bit */
+      while ((temp >>= 1))
+	nbits++;
+      /* Check for out-of-range coefficient values */
+      if (nbits > MAX_COEF_BITS)
+	ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+      
+      /* Count Huffman symbol for run length / number of bits */
+      ac_counts[(r << 4) + nbits]++;
+      
+      r = 0;
+    }
+  }
+
+  /* If the last coef(s) were zero, emit an end-of-block code */
+  if (r > 0)
+    ac_counts[0]++;
+}
+
+
+/*
+ * Trial-encode one MCU's worth of Huffman-compressed coefficients.
+ * No data is actually output, so no suspension return is possible.
+ */
+
+METHODDEF(boolean)
+encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  int blkn, ci;
+  jpeg_component_info * compptr;
+
+  /* Take care of restart intervals if needed */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0) {
+      /* Re-initialize DC predictions to 0 */
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+	entropy->saved.last_dc_val[ci] = 0;
+      /* Update restart state */
+      entropy->restarts_to_go = cinfo->restart_interval;
+    }
+    entropy->restarts_to_go--;
+  }
+
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+    htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
+		    entropy->dc_count_ptrs[compptr->dc_tbl_no],
+		    entropy->ac_count_ptrs[compptr->ac_tbl_no]);
+    entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
+  }
+
+  return TRUE;
+}
+
+
+/*
+ * Generate the best Huffman code table for the given counts, fill htbl.
+ * Note this is also used by jcphuff.c.
+ *
+ * The JPEG standard requires that no symbol be assigned a codeword of all
+ * one bits (so that padding bits added at the end of a compressed segment
+ * can't look like a valid code).  Because of the canonical ordering of
+ * codewords, this just means that there must be an unused slot in the
+ * longest codeword length category.  Section K.2 of the JPEG spec suggests
+ * reserving such a slot by pretending that symbol 256 is a valid symbol
+ * with count 1.  In theory that's not optimal; giving it count zero but
+ * including it in the symbol set anyway should give a better Huffman code.
+ * But the theoretically better code actually seems to come out worse in
+ * practice, because it produces more all-ones bytes (which incur stuffed
+ * zero bytes in the final file).  In any case the difference is tiny.
+ *
+ * The JPEG standard requires Huffman codes to be no more than 16 bits long.
+ * If some symbols have a very small but nonzero probability, the Huffman tree
+ * must be adjusted to meet the code length restriction.  We currently use
+ * the adjustment method suggested in JPEG section K.2.  This method is *not*
+ * optimal; it may not choose the best possible limited-length code.  But
+ * typically only very-low-frequency symbols will be given less-than-optimal
+ * lengths, so the code is almost optimal.  Experimental comparisons against
+ * an optimal limited-length-code algorithm indicate that the difference is
+ * microscopic --- usually less than a hundredth of a percent of total size.
+ * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
+ */
+
+GLOBAL(void)
+jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
+{
+#define MAX_CLEN 32		/* assumed maximum initial code length */
+  UINT8 bits[MAX_CLEN+1];	/* bits[k] = # of symbols with code length k */
+  int codesize[257];		/* codesize[k] = code length of symbol k */
+  int others[257];		/* next symbol in current branch of tree */
+  int c1, c2;
+  int p, i, j;
+  long v;
+
+  /* This algorithm is explained in section K.2 of the JPEG standard */
+
+  MEMZERO(bits, SIZEOF(bits));
+  MEMZERO(codesize, SIZEOF(codesize));
+  for (i = 0; i < 257; i++)
+    others[i] = -1;		/* init links to empty */
+  
+  freq[256] = 1;		/* make sure 256 has a nonzero count */
+  /* Including the pseudo-symbol 256 in the Huffman procedure guarantees
+   * that no real symbol is given code-value of all ones, because 256
+   * will be placed last in the largest codeword category.
+   */
+
+  /* Huffman's basic algorithm to assign optimal code lengths to symbols */
+
+  for (;;) {
+    /* Find the smallest nonzero frequency, set c1 = its symbol */
+    /* In case of ties, take the larger symbol number */
+    c1 = -1;
+    v = 1000000000L;
+    for (i = 0; i <= 256; i++) {
+      if (freq[i] && freq[i] <= v) {
+	v = freq[i];
+	c1 = i;
+      }
+    }
+
+    /* Find the next smallest nonzero frequency, set c2 = its symbol */
+    /* In case of ties, take the larger symbol number */
+    c2 = -1;
+    v = 1000000000L;
+    for (i = 0; i <= 256; i++) {
+      if (freq[i] && freq[i] <= v && i != c1) {
+	v = freq[i];
+	c2 = i;
+      }
+    }
+
+    /* Done if we've merged everything into one frequency */
+    if (c2 < 0)
+      break;
+    
+    /* Else merge the two counts/trees */
+    freq[c1] += freq[c2];
+    freq[c2] = 0;
+
+    /* Increment the codesize of everything in c1's tree branch */
+    codesize[c1]++;
+    while (others[c1] >= 0) {
+      c1 = others[c1];
+      codesize[c1]++;
+    }
+    
+    others[c1] = c2;		/* chain c2 onto c1's tree branch */
+    
+    /* Increment the codesize of everything in c2's tree branch */
+    codesize[c2]++;
+    while (others[c2] >= 0) {
+      c2 = others[c2];
+      codesize[c2]++;
+    }
+  }
+
+  /* Now count the number of symbols of each code length */
+  for (i = 0; i <= 256; i++) {
+    if (codesize[i]) {
+      /* The JPEG standard seems to think that this can't happen, */
+      /* but I'm paranoid... */
+      if (codesize[i] > MAX_CLEN)
+	ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
+
+      bits[codesize[i]]++;
+    }
+  }
+
+  /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
+   * Huffman procedure assigned any such lengths, we must adjust the coding.
+   * Here is what the JPEG spec says about how this next bit works:
+   * Since symbols are paired for the longest Huffman code, the symbols are
+   * removed from this length category two at a time.  The prefix for the pair
+   * (which is one bit shorter) is allocated to one of the pair; then,
+   * skipping the BITS entry for that prefix length, a code word from the next
+   * shortest nonzero BITS entry is converted into a prefix for two code words
+   * one bit longer.
+   */
+  
+  for (i = MAX_CLEN; i > 16; i--) {
+    while (bits[i] > 0) {
+      j = i - 2;		/* find length of new prefix to be used */
+      while (bits[j] == 0)
+	j--;
+      
+      bits[i] -= 2;		/* remove two symbols */
+      bits[i-1]++;		/* one goes in this length */
+      bits[j+1] += 2;		/* two new symbols in this length */
+      bits[j]--;		/* symbol of this length is now a prefix */
+    }
+  }
+
+  /* Remove the count for the pseudo-symbol 256 from the largest codelength */
+  while (bits[i] == 0)		/* find largest codelength still in use */
+    i--;
+  bits[i]--;
+  
+  /* Return final symbol counts (only for lengths 0..16) */
+  MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
+  
+  /* Return a list of the symbols sorted by code length */
+  /* It's not real clear to me why we don't need to consider the codelength
+   * changes made above, but the JPEG spec seems to think this works.
+   */
+  p = 0;
+  for (i = 1; i <= MAX_CLEN; i++) {
+    for (j = 0; j <= 255; j++) {
+      if (codesize[j] == i) {
+	htbl->huffval[p] = (UINT8) j;
+	p++;
+      }
+    }
+  }
+
+  /* Set sent_table FALSE so updated table will be written to JPEG file. */
+  htbl->sent_table = FALSE;
+}
+
+
+/*
+ * Finish up a statistics-gathering pass and create the new Huffman tables.
+ */
+
+METHODDEF(void)
+finish_pass_gather (j_compress_ptr cinfo)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  int ci, dctbl, actbl;
+  jpeg_component_info * compptr;
+  JHUFF_TBL **htblptr;
+  boolean did_dc[NUM_HUFF_TBLS];
+  boolean did_ac[NUM_HUFF_TBLS];
+
+  /* It's important not to apply jpeg_gen_optimal_table more than once
+   * per table, because it clobbers the input frequency counts!
+   */
+  MEMZERO(did_dc, SIZEOF(did_dc));
+  MEMZERO(did_ac, SIZEOF(did_ac));
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    dctbl = compptr->dc_tbl_no;
+    actbl = compptr->ac_tbl_no;
+    if (! did_dc[dctbl]) {
+      htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl];
+      if (*htblptr == NULL)
+	*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]);
+      did_dc[dctbl] = TRUE;
+    }
+    if (! did_ac[actbl]) {
+      htblptr = & cinfo->ac_huff_tbl_ptrs[actbl];
+      if (*htblptr == NULL)
+	*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]);
+      did_ac[actbl] = TRUE;
+    }
+  }
+}
+
+
+#endif /* ENTROPY_OPT_SUPPORTED */
+
+
+/*
+ * Module initialization routine for Huffman entropy encoding.
+ */
+
+GLOBAL(void)
+jinit_huff_encoder (j_compress_ptr cinfo)
+{
+  huff_entropy_ptr entropy;
+  int i;
+
+  entropy = (huff_entropy_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(huff_entropy_encoder));
+  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+  entropy->pub.start_pass = start_pass_huff;
+
+  /* Mark tables unallocated */
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
+#ifdef ENTROPY_OPT_SUPPORTED
+    entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
+#endif
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jchuff.h b/Utilities/FLTK/jpeg/jchuff.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9599fc1e6f9613ca5b7ce02a3b734f0c89cba51
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jchuff.h
@@ -0,0 +1,47 @@
+/*
+ * jchuff.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains declarations for Huffman entropy encoding routines
+ * that are shared between the sequential encoder (jchuff.c) and the
+ * progressive encoder (jcphuff.c).  No other modules need to see these.
+ */
+
+/* The legal range of a DCT coefficient is
+ *  -1024 .. +1023  for 8-bit data;
+ * -16384 .. +16383 for 12-bit data.
+ * Hence the magnitude should always fit in 10 or 14 bits respectively.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MAX_COEF_BITS 10
+#else
+#define MAX_COEF_BITS 14
+#endif
+
+/* Derived data constructed for each Huffman table */
+
+typedef struct {
+  unsigned int ehufco[256];	/* code for each symbol */
+  char ehufsi[256];		/* length of code for each symbol */
+  /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
+} c_derived_tbl;
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_make_c_derived_tbl	jMkCDerived
+#define jpeg_gen_optimal_table	jGenOptTbl
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+/* Expand a Huffman table definition into the derived format */
+EXTERN(void) jpeg_make_c_derived_tbl
+	JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
+	     c_derived_tbl ** pdtbl));
+
+/* Generate an optimal table definition given the specified counts */
+EXTERN(void) jpeg_gen_optimal_table
+	JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
diff --git a/Utilities/FLTK/jpeg/jcinit.c b/Utilities/FLTK/jpeg/jcinit.c
new file mode 100644
index 0000000000000000000000000000000000000000..5efffe33166bc0d6ac7ea8c691a00be5b9ff0de8
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcinit.c
@@ -0,0 +1,72 @@
+/*
+ * jcinit.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains initialization logic for the JPEG compressor.
+ * This routine is in charge of selecting the modules to be executed and
+ * making an initialization call to each one.
+ *
+ * Logically, this code belongs in jcmaster.c.  It's split out because
+ * linking this routine implies linking the entire compression library.
+ * For a transcoding-only application, we want to be able to use jcmaster.c
+ * without linking in the whole library.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Master selection of compression modules.
+ * This is done once at the start of processing an image.  We determine
+ * which modules will be used and give them appropriate initialization calls.
+ */
+
+GLOBAL(void)
+jinit_compress_master (j_compress_ptr cinfo)
+{
+  /* Initialize master control (includes parameter checking/processing) */
+  jinit_c_master_control(cinfo, FALSE /* full compression */);
+
+  /* Preprocessing */
+  if (! cinfo->raw_data_in) {
+    jinit_color_converter(cinfo);
+    jinit_downsampler(cinfo);
+    jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
+  }
+  /* Forward DCT */
+  jinit_forward_dct(cinfo);
+  /* Entropy encoding: either Huffman or arithmetic coding. */
+  if (cinfo->arith_code) {
+    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+  } else {
+    if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+      jinit_phuff_encoder(cinfo);
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    } else
+      jinit_huff_encoder(cinfo);
+  }
+
+  /* Need a full-image coefficient buffer in any multi-pass mode. */
+  jinit_c_coef_controller(cinfo,
+		(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
+  jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
+
+  jinit_marker_writer(cinfo);
+
+  /* We can now tell the memory manager to allocate virtual arrays. */
+  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+  /* Write the datastream header (SOI) immediately.
+   * Frame and scan headers are postponed till later.
+   * This lets application insert special markers after the SOI.
+   */
+  (*cinfo->marker->write_file_header) (cinfo);
+}
diff --git a/Utilities/FLTK/jpeg/jcmainct.c b/Utilities/FLTK/jpeg/jcmainct.c
new file mode 100644
index 0000000000000000000000000000000000000000..a0d82683f4584c2d5e3aaec3fb26058077c7313a
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcmainct.c
@@ -0,0 +1,293 @@
+/*
+ * jcmainct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the main buffer controller for compression.
+ * The main buffer lies between the pre-processor and the JPEG
+ * compressor proper; it holds downsampled data in the JPEG colorspace.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Note: currently, there is no operating mode in which a full-image buffer
+ * is needed at this step.  If there were, that mode could not be used with
+ * "raw data" input, since this module is bypassed in that case.  However,
+ * we've left the code here for possible use in special applications.
+ */
+#undef FULL_MAIN_BUFFER_SUPPORTED
+
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_c_main_controller pub; /* public fields */
+
+  JDIMENSION cur_iMCU_row;	/* number of current iMCU row */
+  JDIMENSION rowgroup_ctr;	/* counts row groups received in iMCU row */
+  boolean suspended;		/* remember if we suspended output */
+  J_BUF_MODE pass_mode;		/* current operating mode */
+
+  /* If using just a strip buffer, this points to the entire set of buffers
+   * (we allocate one for each component).  In the full-image case, this
+   * points to the currently accessible strips of the virtual arrays.
+   */
+  JSAMPARRAY buffer[MAX_COMPONENTS];
+
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+  /* If using full-image storage, this array holds pointers to virtual-array
+   * control blocks for each component.  Unused if not full-image storage.
+   */
+  jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
+#endif
+} my_main_controller;
+
+typedef my_main_controller * my_main_ptr;
+
+
+/* Forward declarations */
+METHODDEF(void) process_data_simple_main
+	JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
+	     JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+METHODDEF(void) process_data_buffer_main
+	JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
+	     JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
+#endif
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+
+  /* Do nothing in raw-data mode. */
+  if (cinfo->raw_data_in)
+    return;
+
+  jmain->cur_iMCU_row = 0;	/* initialize counters */
+  jmain->rowgroup_ctr = 0;
+  jmain->suspended = FALSE;
+  jmain->pass_mode = pass_mode;	/* save mode for use by process_data */
+
+  switch (pass_mode) {
+  case JBUF_PASS_THRU:
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+    if (jmain->whole_image[0] != NULL)
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+    jmain->pub.process_data = process_data_simple_main;
+    break;
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+  case JBUF_SAVE_SOURCE:
+  case JBUF_CRANK_DEST:
+  case JBUF_SAVE_AND_PASS:
+    if (jmain->whole_image[0] == NULL)
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    jmain->pub.process_data = process_data_buffer_main;
+    break;
+#endif
+  default:
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    break;
+  }
+}
+
+
+/*
+ * Process some data.
+ * This routine handles the simple pass-through mode,
+ * where we have only a strip buffer.
+ */
+
+METHODDEF(void)
+process_data_simple_main (j_compress_ptr cinfo,
+			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+			  JDIMENSION in_rows_avail)
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+
+  while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) {
+    /* Read input data if we haven't filled the main buffer yet */
+    if (jmain->rowgroup_ctr < DCTSIZE)
+      (*cinfo->prep->pre_process_data) (cinfo,
+					input_buf, in_row_ctr, in_rows_avail,
+					jmain->buffer, &jmain->rowgroup_ctr,
+					(JDIMENSION) DCTSIZE);
+
+    /* If we don't have a full iMCU row buffered, return to application for
+     * more data.  Note that preprocessor will always pad to fill the iMCU row
+     * at the bottom of the image.
+     */
+    if (jmain->rowgroup_ctr != DCTSIZE)
+      return;
+
+    /* Send the completed row to the compressor */
+    if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) {
+      /* If compressor did not consume the whole row, then we must need to
+       * suspend processing and return to the application.  In this situation
+       * we pretend we didn't yet consume the last input row; otherwise, if
+       * it happened to be the last row of the image, the application would
+       * think we were done.
+       */
+      if (! jmain->suspended) {
+	(*in_row_ctr)--;
+	jmain->suspended = TRUE;
+      }
+      return;
+    }
+    /* We did finish the row.  Undo our little suspension hack if a previous
+     * call suspended; then mark the main buffer empty.
+     */
+    if (jmain->suspended) {
+      (*in_row_ctr)++;
+      jmain->suspended = FALSE;
+    }
+    jmain->rowgroup_ctr = 0;
+    jmain->cur_iMCU_row++;
+  }
+}
+
+
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+
+/*
+ * Process some data.
+ * This routine handles all of the modes that use a full-size buffer.
+ */
+
+METHODDEF(void)
+process_data_buffer_main (j_compress_ptr cinfo,
+			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+			  JDIMENSION in_rows_avail)
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+  int ci;
+  jpeg_component_info *compptr;
+  boolean writing = (jmain->pass_mode != JBUF_CRANK_DEST);
+
+  while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) {
+    /* Realign the virtual buffers if at the start of an iMCU row. */
+    if (jmain->rowgroup_ctr == 0) {
+      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	   ci++, compptr++) {
+	jmain->buffer[ci] = (*cinfo->mem->access_virt_sarray)
+	  ((j_common_ptr) cinfo, jmain->whole_image[ci],
+	   jmain->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
+	   (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
+      }
+      /* In a read pass, pretend we just read some source data. */
+      if (! writing) {
+	*in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
+	jmain->rowgroup_ctr = DCTSIZE;
+      }
+    }
+
+    /* If a write pass, read input data until the current iMCU row is full. */
+    /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
+    if (writing) {
+      (*cinfo->prep->pre_process_data) (cinfo,
+					input_buf, in_row_ctr, in_rows_avail,
+					jmain->buffer, &jmain->rowgroup_ctr,
+					(JDIMENSION) DCTSIZE);
+      /* Return to application if we need more data to fill the iMCU row. */
+      if (jmain->rowgroup_ctr < DCTSIZE)
+	return;
+    }
+
+    /* Emit data, unless this is a sink-only pass. */
+    if (jmain->pass_mode != JBUF_SAVE_SOURCE) {
+      if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) {
+	/* If compressor did not consume the whole row, then we must need to
+	 * suspend processing and return to the application.  In this situation
+	 * we pretend we didn't yet consume the last input row; otherwise, if
+	 * it happened to be the last row of the image, the application would
+	 * think we were done.
+	 */
+	if (! jmain->suspended) {
+	  (*in_row_ctr)--;
+	  jmain->suspended = TRUE;
+	}
+	return;
+      }
+      /* We did finish the row.  Undo our little suspension hack if a previous
+       * call suspended; then mark the main buffer empty.
+       */
+      if (jmain->suspended) {
+	(*in_row_ctr)++;
+	jmain->suspended = FALSE;
+      }
+    }
+
+    /* If get here, we are done with this iMCU row.  Mark buffer empty. */
+    jmain->rowgroup_ctr = 0;
+    jmain->cur_iMCU_row++;
+  }
+}
+
+#endif /* FULL_MAIN_BUFFER_SUPPORTED */
+
+
+/*
+ * Initialize main buffer controller.
+ */
+
+GLOBAL(void)
+jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+  my_main_ptr jmain;
+  int ci;
+  jpeg_component_info *compptr;
+
+  jmain = (my_main_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_main_controller));
+  cinfo->main = (struct jpeg_c_main_controller *) jmain;
+  jmain->pub.start_pass = start_pass_main;
+
+  /* We don't need to create a buffer in raw-data mode. */
+  if (cinfo->raw_data_in)
+    return;
+
+  /* Create the buffer.  It holds downsampled data, so each component
+   * may be of a different size.
+   */
+  if (need_full_buffer) {
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+    /* Allocate a full-image virtual array for each component */
+    /* Note we pad the bottom to a multiple of the iMCU height */
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      jmain->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+	 compptr->width_in_blocks * DCTSIZE,
+	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+				(long) compptr->v_samp_factor) * DCTSIZE,
+	 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
+    }
+#else
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+  } else {
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+    jmain->whole_image[0] = NULL; /* flag for no virtual arrays */
+#endif
+    /* Allocate a strip buffer for each component */
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      jmain->buffer[ci] = (*cinfo->mem->alloc_sarray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE,
+	 compptr->width_in_blocks * DCTSIZE,
+	 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
+    }
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jcmarker.c b/Utilities/FLTK/jpeg/jcmarker.c
new file mode 100644
index 0000000000000000000000000000000000000000..3d1e6c6d524850e0d401fcec9f590d5648d13ee7
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcmarker.c
@@ -0,0 +1,664 @@
+/*
+ * jcmarker.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to write JPEG datastream markers.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+typedef enum {			/* JPEG marker codes */
+  M_SOF0  = 0xc0,
+  M_SOF1  = 0xc1,
+  M_SOF2  = 0xc2,
+  M_SOF3  = 0xc3,
+  
+  M_SOF5  = 0xc5,
+  M_SOF6  = 0xc6,
+  M_SOF7  = 0xc7,
+  
+  M_JPG   = 0xc8,
+  M_SOF9  = 0xc9,
+  M_SOF10 = 0xca,
+  M_SOF11 = 0xcb,
+  
+  M_SOF13 = 0xcd,
+  M_SOF14 = 0xce,
+  M_SOF15 = 0xcf,
+  
+  M_DHT   = 0xc4,
+  
+  M_DAC   = 0xcc,
+  
+  M_RST0  = 0xd0,
+  M_RST1  = 0xd1,
+  M_RST2  = 0xd2,
+  M_RST3  = 0xd3,
+  M_RST4  = 0xd4,
+  M_RST5  = 0xd5,
+  M_RST6  = 0xd6,
+  M_RST7  = 0xd7,
+  
+  M_SOI   = 0xd8,
+  M_EOI   = 0xd9,
+  M_SOS   = 0xda,
+  M_DQT   = 0xdb,
+  M_DNL   = 0xdc,
+  M_DRI   = 0xdd,
+  M_DHP   = 0xde,
+  M_EXP   = 0xdf,
+  
+  M_APP0  = 0xe0,
+  M_APP1  = 0xe1,
+  M_APP2  = 0xe2,
+  M_APP3  = 0xe3,
+  M_APP4  = 0xe4,
+  M_APP5  = 0xe5,
+  M_APP6  = 0xe6,
+  M_APP7  = 0xe7,
+  M_APP8  = 0xe8,
+  M_APP9  = 0xe9,
+  M_APP10 = 0xea,
+  M_APP11 = 0xeb,
+  M_APP12 = 0xec,
+  M_APP13 = 0xed,
+  M_APP14 = 0xee,
+  M_APP15 = 0xef,
+  
+  M_JPG0  = 0xf0,
+  M_JPG13 = 0xfd,
+  M_COM   = 0xfe,
+  
+  M_TEM   = 0x01,
+  
+  M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+/* Private state */
+
+typedef struct {
+  struct jpeg_marker_writer pub; /* public fields */
+
+  unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
+} my_marker_writer;
+
+typedef my_marker_writer * my_marker_ptr;
+
+
+/*
+ * Basic output routines.
+ *
+ * Note that we do not support suspension while writing a marker.
+ * Therefore, an application using suspension must ensure that there is
+ * enough buffer space for the initial markers (typ. 600-700 bytes) before
+ * calling jpeg_start_compress, and enough space to write the trailing EOI
+ * (a few bytes) before calling jpeg_finish_compress.  Multipass compression
+ * modes are not supported at all with suspension, so those two are the only
+ * points where markers will be written.
+ */
+
+LOCAL(void)
+emit_byte (j_compress_ptr cinfo, int val)
+/* Emit a byte */
+{
+  struct jpeg_destination_mgr * dest = cinfo->dest;
+
+  *(dest->next_output_byte)++ = (JOCTET) val;
+  if (--dest->free_in_buffer == 0) {
+    if (! (*dest->empty_output_buffer) (cinfo))
+      ERREXIT(cinfo, JERR_CANT_SUSPEND);
+  }
+}
+
+
+LOCAL(void)
+emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
+/* Emit a marker code */
+{
+  emit_byte(cinfo, 0xFF);
+  emit_byte(cinfo, (int) mark);
+}
+
+
+LOCAL(void)
+emit_2bytes (j_compress_ptr cinfo, int value)
+/* Emit a 2-byte integer; these are always MSB first in JPEG files */
+{
+  emit_byte(cinfo, (value >> 8) & 0xFF);
+  emit_byte(cinfo, value & 0xFF);
+}
+
+
+/*
+ * Routines to write specific marker types.
+ */
+
+LOCAL(int)
+emit_dqt (j_compress_ptr cinfo, int index)
+/* Emit a DQT marker */
+/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
+{
+  JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
+  int prec;
+  int i;
+
+  if (qtbl == NULL)
+    ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
+
+  prec = 0;
+  for (i = 0; i < DCTSIZE2; i++) {
+    if (qtbl->quantval[i] > 255)
+      prec = 1;
+  }
+
+  if (! qtbl->sent_table) {
+    emit_marker(cinfo, M_DQT);
+
+    emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
+
+    emit_byte(cinfo, index + (prec<<4));
+
+    for (i = 0; i < DCTSIZE2; i++) {
+      /* The table entries must be emitted in zigzag order. */
+      unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
+      if (prec)
+	emit_byte(cinfo, (int) (qval >> 8));
+      emit_byte(cinfo, (int) (qval & 0xFF));
+    }
+
+    qtbl->sent_table = TRUE;
+  }
+
+  return prec;
+}
+
+
+LOCAL(void)
+emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
+/* Emit a DHT marker */
+{
+  JHUFF_TBL * htbl;
+  int length, i;
+  
+  if (is_ac) {
+    htbl = cinfo->ac_huff_tbl_ptrs[index];
+    index += 0x10;		/* output index has AC bit set */
+  } else {
+    htbl = cinfo->dc_huff_tbl_ptrs[index];
+  }
+
+  if (htbl == NULL)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
+  
+  if (! htbl->sent_table) {
+    emit_marker(cinfo, M_DHT);
+    
+    length = 0;
+    for (i = 1; i <= 16; i++)
+      length += htbl->bits[i];
+    
+    emit_2bytes(cinfo, length + 2 + 1 + 16);
+    emit_byte(cinfo, index);
+    
+    for (i = 1; i <= 16; i++)
+      emit_byte(cinfo, htbl->bits[i]);
+    
+    for (i = 0; i < length; i++)
+      emit_byte(cinfo, htbl->huffval[i]);
+    
+    htbl->sent_table = TRUE;
+  }
+}
+
+
+LOCAL(void)
+emit_dac (j_compress_ptr cinfo)
+/* Emit a DAC marker */
+/* Since the useful info is so small, we want to emit all the tables in */
+/* one DAC marker.  Therefore this routine does its own scan of the table. */
+{
+#ifdef C_ARITH_CODING_SUPPORTED
+  char dc_in_use[NUM_ARITH_TBLS];
+  char ac_in_use[NUM_ARITH_TBLS];
+  int length, i;
+  jpeg_component_info *compptr;
+  
+  for (i = 0; i < NUM_ARITH_TBLS; i++)
+    dc_in_use[i] = ac_in_use[i] = 0;
+  
+  for (i = 0; i < cinfo->comps_in_scan; i++) {
+    compptr = cinfo->cur_comp_info[i];
+    dc_in_use[compptr->dc_tbl_no] = 1;
+    ac_in_use[compptr->ac_tbl_no] = 1;
+  }
+  
+  length = 0;
+  for (i = 0; i < NUM_ARITH_TBLS; i++)
+    length += dc_in_use[i] + ac_in_use[i];
+  
+  emit_marker(cinfo, M_DAC);
+  
+  emit_2bytes(cinfo, length*2 + 2);
+  
+  for (i = 0; i < NUM_ARITH_TBLS; i++) {
+    if (dc_in_use[i]) {
+      emit_byte(cinfo, i);
+      emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
+    }
+    if (ac_in_use[i]) {
+      emit_byte(cinfo, i + 0x10);
+      emit_byte(cinfo, cinfo->arith_ac_K[i]);
+    }
+  }
+#endif /* C_ARITH_CODING_SUPPORTED */
+}
+
+
+LOCAL(void)
+emit_dri (j_compress_ptr cinfo)
+/* Emit a DRI marker */
+{
+  emit_marker(cinfo, M_DRI);
+  
+  emit_2bytes(cinfo, 4);	/* fixed length */
+
+  emit_2bytes(cinfo, (int) cinfo->restart_interval);
+}
+
+
+LOCAL(void)
+emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
+/* Emit a SOF marker */
+{
+  int ci;
+  jpeg_component_info *compptr;
+  
+  emit_marker(cinfo, code);
+  
+  emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
+
+  /* Make sure image isn't bigger than SOF field can handle */
+  if ((long) cinfo->image_height > 65535L ||
+      (long) cinfo->image_width > 65535L)
+    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
+
+  emit_byte(cinfo, cinfo->data_precision);
+  emit_2bytes(cinfo, (int) cinfo->image_height);
+  emit_2bytes(cinfo, (int) cinfo->image_width);
+
+  emit_byte(cinfo, cinfo->num_components);
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    emit_byte(cinfo, compptr->component_id);
+    emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
+    emit_byte(cinfo, compptr->quant_tbl_no);
+  }
+}
+
+
+LOCAL(void)
+emit_sos (j_compress_ptr cinfo)
+/* Emit a SOS marker */
+{
+  int i, td, ta;
+  jpeg_component_info *compptr;
+  
+  emit_marker(cinfo, M_SOS);
+  
+  emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
+  
+  emit_byte(cinfo, cinfo->comps_in_scan);
+  
+  for (i = 0; i < cinfo->comps_in_scan; i++) {
+    compptr = cinfo->cur_comp_info[i];
+    emit_byte(cinfo, compptr->component_id);
+    td = compptr->dc_tbl_no;
+    ta = compptr->ac_tbl_no;
+    if (cinfo->progressive_mode) {
+      /* Progressive mode: only DC or only AC tables are used in one scan;
+       * furthermore, Huffman coding of DC refinement uses no table at all.
+       * We emit 0 for unused field(s); this is recommended by the P&M text
+       * but does not seem to be specified in the standard.
+       */
+      if (cinfo->Ss == 0) {
+	ta = 0;			/* DC scan */
+	if (cinfo->Ah != 0 && !cinfo->arith_code)
+	  td = 0;		/* no DC table either */
+      } else {
+	td = 0;			/* AC scan */
+      }
+    }
+    emit_byte(cinfo, (td << 4) + ta);
+  }
+
+  emit_byte(cinfo, cinfo->Ss);
+  emit_byte(cinfo, cinfo->Se);
+  emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
+}
+
+
+LOCAL(void)
+emit_jfif_app0 (j_compress_ptr cinfo)
+/* Emit a JFIF-compliant APP0 marker */
+{
+  /*
+   * Length of APP0 block	(2 bytes)
+   * Block ID			(4 bytes - ASCII "JFIF")
+   * Zero byte			(1 byte to terminate the ID string)
+   * Version Major, Minor	(2 bytes - major first)
+   * Units			(1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
+   * Xdpu			(2 bytes - dots per unit horizontal)
+   * Ydpu			(2 bytes - dots per unit vertical)
+   * Thumbnail X size		(1 byte)
+   * Thumbnail Y size		(1 byte)
+   */
+  
+  emit_marker(cinfo, M_APP0);
+  
+  emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
+
+  emit_byte(cinfo, 0x4A);	/* Identifier: ASCII "JFIF" */
+  emit_byte(cinfo, 0x46);
+  emit_byte(cinfo, 0x49);
+  emit_byte(cinfo, 0x46);
+  emit_byte(cinfo, 0);
+  emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
+  emit_byte(cinfo, cinfo->JFIF_minor_version);
+  emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
+  emit_2bytes(cinfo, (int) cinfo->X_density);
+  emit_2bytes(cinfo, (int) cinfo->Y_density);
+  emit_byte(cinfo, 0);		/* No thumbnail image */
+  emit_byte(cinfo, 0);
+}
+
+
+LOCAL(void)
+emit_adobe_app14 (j_compress_ptr cinfo)
+/* Emit an Adobe APP14 marker */
+{
+  /*
+   * Length of APP14 block	(2 bytes)
+   * Block ID			(5 bytes - ASCII "Adobe")
+   * Version Number		(2 bytes - currently 100)
+   * Flags0			(2 bytes - currently 0)
+   * Flags1			(2 bytes - currently 0)
+   * Color transform		(1 byte)
+   *
+   * Although Adobe TN 5116 mentions Version = 101, all the Adobe files
+   * now in circulation seem to use Version = 100, so that's what we write.
+   *
+   * We write the color transform byte as 1 if the JPEG color space is
+   * YCbCr, 2 if it's YCCK, 0 otherwise.  Adobe's definition has to do with
+   * whether the encoder performed a transformation, which is pretty useless.
+   */
+  
+  emit_marker(cinfo, M_APP14);
+  
+  emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */
+
+  emit_byte(cinfo, 0x41);	/* Identifier: ASCII "Adobe" */
+  emit_byte(cinfo, 0x64);
+  emit_byte(cinfo, 0x6F);
+  emit_byte(cinfo, 0x62);
+  emit_byte(cinfo, 0x65);
+  emit_2bytes(cinfo, 100);	/* Version */
+  emit_2bytes(cinfo, 0);	/* Flags0 */
+  emit_2bytes(cinfo, 0);	/* Flags1 */
+  switch (cinfo->jpeg_color_space) {
+  case JCS_YCbCr:
+    emit_byte(cinfo, 1);	/* Color transform = 1 */
+    break;
+  case JCS_YCCK:
+    emit_byte(cinfo, 2);	/* Color transform = 2 */
+    break;
+  default:
+    emit_byte(cinfo, 0);	/* Color transform = 0 */
+    break;
+  }
+}
+
+
+/*
+ * These routines allow writing an arbitrary marker with parameters.
+ * The only intended use is to emit COM or APPn markers after calling
+ * write_file_header and before calling write_frame_header.
+ * Other uses are not guaranteed to produce desirable results.
+ * Counting the parameter bytes properly is the caller's responsibility.
+ */
+
+METHODDEF(void)
+write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+/* Emit an arbitrary marker header */
+{
+  if (datalen > (unsigned int) 65533)		/* safety check */
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  emit_marker(cinfo, (JPEG_MARKER) marker);
+
+  emit_2bytes(cinfo, (int) (datalen + 2));	/* total length */
+}
+
+METHODDEF(void)
+write_marker_byte (j_compress_ptr cinfo, int val)
+/* Emit one byte of marker parameters following write_marker_header */
+{
+  emit_byte(cinfo, val);
+}
+
+
+/*
+ * Write datastream header.
+ * This consists of an SOI and optional APPn markers.
+ * We recommend use of the JFIF marker, but not the Adobe marker,
+ * when using YCbCr or grayscale data.  The JFIF marker should NOT
+ * be used for any other JPEG colorspace.  The Adobe marker is helpful
+ * to distinguish RGB, CMYK, and YCCK colorspaces.
+ * Note that an application can write additional header markers after
+ * jpeg_start_compress returns.
+ */
+
+METHODDEF(void)
+write_file_header (j_compress_ptr cinfo)
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+  emit_marker(cinfo, M_SOI);	/* first the SOI */
+
+  /* SOI is defined to reset restart interval to 0 */
+  marker->last_restart_interval = 0;
+
+  if (cinfo->write_JFIF_header)	/* next an optional JFIF APP0 */
+    emit_jfif_app0(cinfo);
+  if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
+    emit_adobe_app14(cinfo);
+}
+
+
+/*
+ * Write frame header.
+ * This consists of DQT and SOFn markers.
+ * Note that we do not emit the SOF until we have emitted the DQT(s).
+ * This avoids compatibility problems with incorrect implementations that
+ * try to error-check the quant table numbers as soon as they see the SOF.
+ */
+
+METHODDEF(void)
+write_frame_header (j_compress_ptr cinfo)
+{
+  int ci, prec;
+  boolean is_baseline;
+  jpeg_component_info *compptr;
+  
+  /* Emit DQT for each quantization table.
+   * Note that emit_dqt() suppresses any duplicate tables.
+   */
+  prec = 0;
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    prec += emit_dqt(cinfo, compptr->quant_tbl_no);
+  }
+  /* now prec is nonzero iff there are any 16-bit quant tables. */
+
+  /* Check for a non-baseline specification.
+   * Note we assume that Huffman table numbers won't be changed later.
+   */
+  if (cinfo->arith_code || cinfo->progressive_mode ||
+      cinfo->data_precision != 8) {
+    is_baseline = FALSE;
+  } else {
+    is_baseline = TRUE;
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
+	is_baseline = FALSE;
+    }
+    if (prec && is_baseline) {
+      is_baseline = FALSE;
+      /* If it's baseline except for quantizer size, warn the user */
+      TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
+    }
+  }
+
+  /* Emit the proper SOF marker */
+  if (cinfo->arith_code) {
+    emit_sof(cinfo, M_SOF9);	/* SOF code for arithmetic coding */
+  } else {
+    if (cinfo->progressive_mode)
+      emit_sof(cinfo, M_SOF2);	/* SOF code for progressive Huffman */
+    else if (is_baseline)
+      emit_sof(cinfo, M_SOF0);	/* SOF code for baseline implementation */
+    else
+      emit_sof(cinfo, M_SOF1);	/* SOF code for non-baseline Huffman file */
+  }
+}
+
+
+/*
+ * Write scan header.
+ * This consists of DHT or DAC markers, optional DRI, and SOS.
+ * Compressed data will be written following the SOS.
+ */
+
+METHODDEF(void)
+write_scan_header (j_compress_ptr cinfo)
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+  int i;
+  jpeg_component_info *compptr;
+
+  if (cinfo->arith_code) {
+    /* Emit arith conditioning info.  We may have some duplication
+     * if the file has multiple scans, but it's so small it's hardly
+     * worth worrying about.
+     */
+    emit_dac(cinfo);
+  } else {
+    /* Emit Huffman tables.
+     * Note that emit_dht() suppresses any duplicate tables.
+     */
+    for (i = 0; i < cinfo->comps_in_scan; i++) {
+      compptr = cinfo->cur_comp_info[i];
+      if (cinfo->progressive_mode) {
+	/* Progressive mode: only DC or only AC tables are used in one scan */
+	if (cinfo->Ss == 0) {
+	  if (cinfo->Ah == 0)	/* DC needs no table for refinement scan */
+	    emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
+	} else {
+	  emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
+	}
+      } else {
+	/* Sequential mode: need both DC and AC tables */
+	emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
+	emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
+      }
+    }
+  }
+
+  /* Emit DRI if required --- note that DRI value could change for each scan.
+   * We avoid wasting space with unnecessary DRIs, however.
+   */
+  if (cinfo->restart_interval != marker->last_restart_interval) {
+    emit_dri(cinfo);
+    marker->last_restart_interval = cinfo->restart_interval;
+  }
+
+  emit_sos(cinfo);
+}
+
+
+/*
+ * Write datastream trailer.
+ */
+
+METHODDEF(void)
+write_file_trailer (j_compress_ptr cinfo)
+{
+  emit_marker(cinfo, M_EOI);
+}
+
+
+/*
+ * Write an abbreviated table-specification datastream.
+ * This consists of SOI, DQT and DHT tables, and EOI.
+ * Any table that is defined and not marked sent_table = TRUE will be
+ * emitted.  Note that all tables will be marked sent_table = TRUE at exit.
+ */
+
+METHODDEF(void)
+write_tables_only (j_compress_ptr cinfo)
+{
+  int i;
+
+  emit_marker(cinfo, M_SOI);
+
+  for (i = 0; i < NUM_QUANT_TBLS; i++) {
+    if (cinfo->quant_tbl_ptrs[i] != NULL)
+      (void) emit_dqt(cinfo, i);
+  }
+
+  if (! cinfo->arith_code) {
+    for (i = 0; i < NUM_HUFF_TBLS; i++) {
+      if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
+	emit_dht(cinfo, i, FALSE);
+      if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
+	emit_dht(cinfo, i, TRUE);
+    }
+  }
+
+  emit_marker(cinfo, M_EOI);
+}
+
+
+/*
+ * Initialize the marker writer module.
+ */
+
+GLOBAL(void)
+jinit_marker_writer (j_compress_ptr cinfo)
+{
+  my_marker_ptr marker;
+
+  /* Create the subobject */
+  marker = (my_marker_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_marker_writer));
+  cinfo->marker = (struct jpeg_marker_writer *) marker;
+  /* Initialize method pointers */
+  marker->pub.write_file_header = write_file_header;
+  marker->pub.write_frame_header = write_frame_header;
+  marker->pub.write_scan_header = write_scan_header;
+  marker->pub.write_file_trailer = write_file_trailer;
+  marker->pub.write_tables_only = write_tables_only;
+  marker->pub.write_marker_header = write_marker_header;
+  marker->pub.write_marker_byte = write_marker_byte;
+  /* Initialize private state */
+  marker->last_restart_interval = 0;
+}
diff --git a/Utilities/FLTK/jpeg/jcmaster.c b/Utilities/FLTK/jpeg/jcmaster.c
new file mode 100644
index 0000000000000000000000000000000000000000..aab4020b8796ab29492aa1780898f3ccacc45413
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcmaster.c
@@ -0,0 +1,590 @@
+/*
+ * jcmaster.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains master control logic for the JPEG compressor.
+ * These routines are concerned with parameter validation, initial setup,
+ * and inter-pass control (determining the number of passes and the work 
+ * to be done in each pass).
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private state */
+
+typedef enum {
+	main_pass,		/* input data, also do first output step */
+	huff_opt_pass,		/* Huffman code optimization pass */
+	output_pass		/* data output pass */
+} c_pass_type;
+
+typedef struct {
+  struct jpeg_comp_master pub;	/* public fields */
+
+  c_pass_type pass_type;	/* the type of the current pass */
+
+  int pass_number;		/* # of passes completed */
+  int total_passes;		/* total # of passes needed */
+
+  int scan_number;		/* current index in scan_info[] */
+} my_comp_master;
+
+typedef my_comp_master * my_master_ptr;
+
+
+/*
+ * Support routines that do various essential calculations.
+ */
+
+LOCAL(void)
+initial_setup (j_compress_ptr cinfo)
+/* Do computations that are needed before master selection phase */
+{
+  int ci;
+  jpeg_component_info *compptr;
+  long samplesperrow;
+  JDIMENSION jd_samplesperrow;
+
+  /* Sanity check on image dimensions */
+  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
+      || cinfo->num_components <= 0 || cinfo->input_components <= 0)
+    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
+  /* Make sure image isn't bigger than I can handle */
+  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
+      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
+    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
+
+  /* Width of an input scanline must be representable as JDIMENSION. */
+  samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
+  jd_samplesperrow = (JDIMENSION) samplesperrow;
+  if ((long) jd_samplesperrow != samplesperrow)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+
+  /* For now, precision must match compiled-in value... */
+  if (cinfo->data_precision != BITS_IN_JSAMPLE)
+    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
+  /* Check that number of components won't exceed internal array sizes */
+  if (cinfo->num_components > MAX_COMPONENTS)
+    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+	     MAX_COMPONENTS);
+
+  /* Compute maximum sampling factors; check factor validity */
+  cinfo->max_h_samp_factor = 1;
+  cinfo->max_v_samp_factor = 1;
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+	compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+      ERREXIT(cinfo, JERR_BAD_SAMPLING);
+    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+				   compptr->h_samp_factor);
+    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+				   compptr->v_samp_factor);
+  }
+
+  /* Compute dimensions of components */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Fill in the correct component_index value; don't rely on application */
+    compptr->component_index = ci;
+    /* For compression, we never do DCT scaling. */
+    compptr->DCT_scaled_size = DCTSIZE;
+    /* Size in DCT blocks */
+    compptr->width_in_blocks = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
+    compptr->height_in_blocks = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
+    /* Size in samples */
+    compptr->downsampled_width = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+		    (long) cinfo->max_h_samp_factor);
+    compptr->downsampled_height = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+		    (long) cinfo->max_v_samp_factor);
+    /* Mark component needed (this flag isn't actually used for compression) */
+    compptr->component_needed = TRUE;
+  }
+
+  /* Compute number of fully interleaved MCU rows (number of times that
+   * main controller will call coefficient controller).
+   */
+  cinfo->total_iMCU_rows = (JDIMENSION)
+    jdiv_round_up((long) cinfo->image_height,
+		  (long) (cinfo->max_v_samp_factor*DCTSIZE));
+}
+
+
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+
+LOCAL(void)
+validate_script (j_compress_ptr cinfo)
+/* Verify that the scan script in cinfo->scan_info[] is valid; also
+ * determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
+ */
+{
+  const jpeg_scan_info * scanptr;
+  int scanno, ncomps, ci, coefi, thisi;
+  int Ss, Se, Ah, Al;
+  boolean component_sent[MAX_COMPONENTS];
+#ifdef C_PROGRESSIVE_SUPPORTED
+  int * last_bitpos_ptr;
+  int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
+  /* -1 until that coefficient has been seen; then last Al for it */
+#endif
+
+  if (cinfo->num_scans <= 0)
+    ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
+
+  /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
+   * for progressive JPEG, no scan can have this.
+   */
+  scanptr = cinfo->scan_info;
+  if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+    cinfo->progressive_mode = TRUE;
+    last_bitpos_ptr = & last_bitpos[0][0];
+    for (ci = 0; ci < cinfo->num_components; ci++) 
+      for (coefi = 0; coefi < DCTSIZE2; coefi++)
+	*last_bitpos_ptr++ = -1;
+#else
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+  } else {
+    cinfo->progressive_mode = FALSE;
+    for (ci = 0; ci < cinfo->num_components; ci++) 
+      component_sent[ci] = FALSE;
+  }
+
+  for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
+    /* Validate component indexes */
+    ncomps = scanptr->comps_in_scan;
+    if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
+      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
+    for (ci = 0; ci < ncomps; ci++) {
+      thisi = scanptr->component_index[ci];
+      if (thisi < 0 || thisi >= cinfo->num_components)
+	ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+      /* Components must appear in SOF order within each scan */
+      if (ci > 0 && thisi <= scanptr->component_index[ci-1])
+	ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+    }
+    /* Validate progression parameters */
+    Ss = scanptr->Ss;
+    Se = scanptr->Se;
+    Ah = scanptr->Ah;
+    Al = scanptr->Al;
+    if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+      /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
+       * seems wrong: the upper bound ought to depend on data precision.
+       * Perhaps they really meant 0..N+1 for N-bit precision.
+       * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
+       * out-of-range reconstructed DC values during the first DC scan,
+       * which might cause problems for some decoders.
+       */
+#if BITS_IN_JSAMPLE == 8
+#define MAX_AH_AL 10
+#else
+#define MAX_AH_AL 13
+#endif
+      if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
+	  Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
+	ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+      if (Ss == 0) {
+	if (Se != 0)		/* DC and AC together not OK */
+	  ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+      } else {
+	if (ncomps != 1)	/* AC scans must be for only one component */
+	  ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+      }
+      for (ci = 0; ci < ncomps; ci++) {
+	last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
+	if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
+	  ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+	for (coefi = Ss; coefi <= Se; coefi++) {
+	  if (last_bitpos_ptr[coefi] < 0) {
+	    /* first scan of this coefficient */
+	    if (Ah != 0)
+	      ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+	  } else {
+	    /* not first scan */
+	    if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
+	      ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+	  }
+	  last_bitpos_ptr[coefi] = Al;
+	}
+      }
+#endif
+    } else {
+      /* For sequential JPEG, all progression parameters must be these: */
+      if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
+	ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+      /* Make sure components are not sent twice */
+      for (ci = 0; ci < ncomps; ci++) {
+	thisi = scanptr->component_index[ci];
+	if (component_sent[thisi])
+	  ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+	component_sent[thisi] = TRUE;
+      }
+    }
+  }
+
+  /* Now verify that everything got sent. */
+  if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+    /* For progressive mode, we only check that at least some DC data
+     * got sent for each component; the spec does not require that all bits
+     * of all coefficients be transmitted.  Would it be wiser to enforce
+     * transmission of all coefficient bits??
+     */
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      if (last_bitpos[ci][0] < 0)
+	ERREXIT(cinfo, JERR_MISSING_DATA);
+    }
+#endif
+  } else {
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      if (! component_sent[ci])
+	ERREXIT(cinfo, JERR_MISSING_DATA);
+    }
+  }
+}
+
+#endif /* C_MULTISCAN_FILES_SUPPORTED */
+
+
+LOCAL(void)
+select_scan_parameters (j_compress_ptr cinfo)
+/* Set up the scan parameters for the current scan */
+{
+  int ci;
+
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+  if (cinfo->scan_info != NULL) {
+    /* Prepare for current scan --- the script is already validated */
+    my_master_ptr master = (my_master_ptr) cinfo->master;
+    const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
+
+    cinfo->comps_in_scan = scanptr->comps_in_scan;
+    for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
+      cinfo->cur_comp_info[ci] =
+	&cinfo->comp_info[scanptr->component_index[ci]];
+    }
+    cinfo->Ss = scanptr->Ss;
+    cinfo->Se = scanptr->Se;
+    cinfo->Ah = scanptr->Ah;
+    cinfo->Al = scanptr->Al;
+  }
+  else
+#endif
+  {
+    /* Prepare for single sequential-JPEG scan containing all components */
+    if (cinfo->num_components > MAX_COMPS_IN_SCAN)
+      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+	       MAX_COMPS_IN_SCAN);
+    cinfo->comps_in_scan = cinfo->num_components;
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
+    }
+    cinfo->Ss = 0;
+    cinfo->Se = DCTSIZE2-1;
+    cinfo->Ah = 0;
+    cinfo->Al = 0;
+  }
+}
+
+
+LOCAL(void)
+per_scan_setup (j_compress_ptr cinfo)
+/* Do computations that are needed before processing a JPEG scan */
+/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
+{
+  int ci, mcublks, tmp;
+  jpeg_component_info *compptr;
+  
+  if (cinfo->comps_in_scan == 1) {
+    
+    /* Noninterleaved (single-component) scan */
+    compptr = cinfo->cur_comp_info[0];
+    
+    /* Overall image size in MCUs */
+    cinfo->MCUs_per_row = compptr->width_in_blocks;
+    cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
+    
+    /* For noninterleaved scan, always one block per MCU */
+    compptr->MCU_width = 1;
+    compptr->MCU_height = 1;
+    compptr->MCU_blocks = 1;
+    compptr->MCU_sample_width = DCTSIZE;
+    compptr->last_col_width = 1;
+    /* For noninterleaved scans, it is convenient to define last_row_height
+     * as the number of block rows present in the last iMCU row.
+     */
+    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+    if (tmp == 0) tmp = compptr->v_samp_factor;
+    compptr->last_row_height = tmp;
+    
+    /* Prepare array describing MCU composition */
+    cinfo->blocks_in_MCU = 1;
+    cinfo->MCU_membership[0] = 0;
+    
+  } else {
+    
+    /* Interleaved (multi-component) scan */
+    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
+	       MAX_COMPS_IN_SCAN);
+    
+    /* Overall image size in MCUs */
+    cinfo->MCUs_per_row = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width,
+		    (long) (cinfo->max_h_samp_factor*DCTSIZE));
+    cinfo->MCU_rows_in_scan = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height,
+		    (long) (cinfo->max_v_samp_factor*DCTSIZE));
+    
+    cinfo->blocks_in_MCU = 0;
+    
+    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+      compptr = cinfo->cur_comp_info[ci];
+      /* Sampling factors give # of blocks of component in each MCU */
+      compptr->MCU_width = compptr->h_samp_factor;
+      compptr->MCU_height = compptr->v_samp_factor;
+      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+      compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
+      /* Figure number of non-dummy blocks in last MCU column & row */
+      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
+      if (tmp == 0) tmp = compptr->MCU_width;
+      compptr->last_col_width = tmp;
+      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
+      if (tmp == 0) tmp = compptr->MCU_height;
+      compptr->last_row_height = tmp;
+      /* Prepare array describing MCU composition */
+      mcublks = compptr->MCU_blocks;
+      if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
+	ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
+      while (mcublks-- > 0) {
+	cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+      }
+    }
+    
+  }
+
+  /* Convert restart specified in rows to actual MCU count. */
+  /* Note that count must fit in 16 bits, so we provide limiting. */
+  if (cinfo->restart_in_rows > 0) {
+    long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row;
+    cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L);
+  }
+}
+
+
+/*
+ * Per-pass setup.
+ * This is called at the beginning of each pass.  We determine which modules
+ * will be active during this pass and give them appropriate start_pass calls.
+ * We also set is_last_pass to indicate whether any more passes will be
+ * required.
+ */
+
+METHODDEF(void)
+prepare_for_pass (j_compress_ptr cinfo)
+{
+  my_master_ptr master = (my_master_ptr) cinfo->master;
+
+  switch (master->pass_type) {
+  case main_pass:
+    /* Initial pass: will collect input data, and do either Huffman
+     * optimization or data output for the first scan.
+     */
+    select_scan_parameters(cinfo);
+    per_scan_setup(cinfo);
+    if (! cinfo->raw_data_in) {
+      (*cinfo->cconvert->start_pass) (cinfo);
+      (*cinfo->downsample->start_pass) (cinfo);
+      (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
+    }
+    (*cinfo->fdct->start_pass) (cinfo);
+    (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
+    (*cinfo->coef->start_pass) (cinfo,
+				(master->total_passes > 1 ?
+				 JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
+    (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
+    if (cinfo->optimize_coding) {
+      /* No immediate data output; postpone writing frame/scan headers */
+      master->pub.call_pass_startup = FALSE;
+    } else {
+      /* Will write frame/scan headers at first jpeg_write_scanlines call */
+      master->pub.call_pass_startup = TRUE;
+    }
+    break;
+#ifdef ENTROPY_OPT_SUPPORTED
+  case huff_opt_pass:
+    /* Do Huffman optimization for a scan after the first one. */
+    select_scan_parameters(cinfo);
+    per_scan_setup(cinfo);
+    if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
+      (*cinfo->entropy->start_pass) (cinfo, TRUE);
+      (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
+      master->pub.call_pass_startup = FALSE;
+      break;
+    }
+    /* Special case: Huffman DC refinement scans need no Huffman table
+     * and therefore we can skip the optimization pass for them.
+     */
+    master->pass_type = output_pass;
+    master->pass_number++;
+    /*FALLTHROUGH*/
+#endif
+  case output_pass:
+    /* Do a data-output pass. */
+    /* We need not repeat per-scan setup if prior optimization pass did it. */
+    if (! cinfo->optimize_coding) {
+      select_scan_parameters(cinfo);
+      per_scan_setup(cinfo);
+    }
+    (*cinfo->entropy->start_pass) (cinfo, FALSE);
+    (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
+    /* We emit frame/scan headers now */
+    if (master->scan_number == 0)
+      (*cinfo->marker->write_frame_header) (cinfo);
+    (*cinfo->marker->write_scan_header) (cinfo);
+    master->pub.call_pass_startup = FALSE;
+    break;
+  default:
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+  }
+
+  master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
+
+  /* Set up progress monitor's pass info if present */
+  if (cinfo->progress != NULL) {
+    cinfo->progress->completed_passes = master->pass_number;
+    cinfo->progress->total_passes = master->total_passes;
+  }
+}
+
+
+/*
+ * Special start-of-pass hook.
+ * This is called by jpeg_write_scanlines if call_pass_startup is TRUE.
+ * In single-pass processing, we need this hook because we don't want to
+ * write frame/scan headers during jpeg_start_compress; we want to let the
+ * application write COM markers etc. between jpeg_start_compress and the
+ * jpeg_write_scanlines loop.
+ * In multi-pass processing, this routine is not used.
+ */
+
+METHODDEF(void)
+pass_startup (j_compress_ptr cinfo)
+{
+  cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
+
+  (*cinfo->marker->write_frame_header) (cinfo);
+  (*cinfo->marker->write_scan_header) (cinfo);
+}
+
+
+/*
+ * Finish up at end of pass.
+ */
+
+METHODDEF(void)
+finish_pass_master (j_compress_ptr cinfo)
+{
+  my_master_ptr master = (my_master_ptr) cinfo->master;
+
+  /* The entropy coder always needs an end-of-pass call,
+   * either to analyze statistics or to flush its output buffer.
+   */
+  (*cinfo->entropy->finish_pass) (cinfo);
+
+  /* Update state for next pass */
+  switch (master->pass_type) {
+  case main_pass:
+    /* next pass is either output of scan 0 (after optimization)
+     * or output of scan 1 (if no optimization).
+     */
+    master->pass_type = output_pass;
+    if (! cinfo->optimize_coding)
+      master->scan_number++;
+    break;
+  case huff_opt_pass:
+    /* next pass is always output of current scan */
+    master->pass_type = output_pass;
+    break;
+  case output_pass:
+    /* next pass is either optimization or output of next scan */
+    if (cinfo->optimize_coding)
+      master->pass_type = huff_opt_pass;
+    master->scan_number++;
+    break;
+  }
+
+  master->pass_number++;
+}
+
+
+/*
+ * Initialize master compression control.
+ */
+
+GLOBAL(void)
+jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
+{
+  my_master_ptr master;
+
+  master = (my_master_ptr)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(my_comp_master));
+  cinfo->master = (struct jpeg_comp_master *) master;
+  master->pub.prepare_for_pass = prepare_for_pass;
+  master->pub.pass_startup = pass_startup;
+  master->pub.finish_pass = finish_pass_master;
+  master->pub.is_last_pass = FALSE;
+
+  /* Validate parameters, determine derived values */
+  initial_setup(cinfo);
+
+  if (cinfo->scan_info != NULL) {
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+    validate_script(cinfo);
+#else
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+  } else {
+    cinfo->progressive_mode = FALSE;
+    cinfo->num_scans = 1;
+  }
+
+  if (cinfo->progressive_mode)	/*  TEMPORARY HACK ??? */
+    cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
+
+  /* Initialize my private state */
+  if (transcode_only) {
+    /* no main pass in transcoding */
+    if (cinfo->optimize_coding)
+      master->pass_type = huff_opt_pass;
+    else
+      master->pass_type = output_pass;
+  } else {
+    /* for normal compression, first pass is always this type: */
+    master->pass_type = main_pass;
+  }
+  master->scan_number = 0;
+  master->pass_number = 0;
+  if (cinfo->optimize_coding)
+    master->total_passes = cinfo->num_scans * 2;
+  else
+    master->total_passes = cinfo->num_scans;
+}
diff --git a/Utilities/FLTK/jpeg/jcomapi.c b/Utilities/FLTK/jpeg/jcomapi.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b1fa7568a67a7c25a599976ada93c53db665c57
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcomapi.c
@@ -0,0 +1,106 @@
+/*
+ * jcomapi.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface routines that are used for both
+ * compression and decompression.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Abort processing of a JPEG compression or decompression operation,
+ * but don't destroy the object itself.
+ *
+ * For this, we merely clean up all the nonpermanent memory pools.
+ * Note that temp files (virtual arrays) are not allowed to belong to
+ * the permanent pool, so we will be able to close all temp files here.
+ * Closing a data source or destination, if necessary, is the application's
+ * responsibility.
+ */
+
+GLOBAL(void)
+jpeg_abort (j_common_ptr cinfo)
+{
+  int pool;
+
+  /* Do nothing if called on a not-initialized or destroyed JPEG object. */
+  if (cinfo->mem == NULL)
+    return;
+
+  /* Releasing pools in reverse order might help avoid fragmentation
+   * with some (brain-damaged) malloc libraries.
+   */
+  for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
+    (*cinfo->mem->free_pool) (cinfo, pool);
+  }
+
+  /* Reset overall state for possible reuse of object */
+  if (cinfo->is_decompressor) {
+    cinfo->global_state = DSTATE_START;
+    /* Try to keep application from accessing now-deleted marker list.
+     * A bit kludgy to do it here, but this is the most central place.
+     */
+    ((j_decompress_ptr) cinfo)->marker_list = NULL;
+  } else {
+    cinfo->global_state = CSTATE_START;
+  }
+}
+
+
+/*
+ * Destruction of a JPEG object.
+ *
+ * Everything gets deallocated except the master jpeg_compress_struct itself
+ * and the error manager struct.  Both of these are supplied by the application
+ * and must be freed, if necessary, by the application.  (Often they are on
+ * the stack and so don't need to be freed anyway.)
+ * Closing a data source or destination, if necessary, is the application's
+ * responsibility.
+ */
+
+GLOBAL(void)
+jpeg_destroy (j_common_ptr cinfo)
+{
+  /* We need only tell the memory manager to release everything. */
+  /* NB: mem pointer is NULL if memory mgr failed to initialize. */
+  if (cinfo->mem != NULL)
+    (*cinfo->mem->self_destruct) (cinfo);
+  cinfo->mem = NULL;		/* be safe if jpeg_destroy is called twice */
+  cinfo->global_state = 0;	/* mark it destroyed */
+}
+
+
+/*
+ * Convenience routines for allocating quantization and Huffman tables.
+ * (Would jutils.c be a more reasonable place to put these?)
+ */
+
+GLOBAL(JQUANT_TBL *)
+jpeg_alloc_quant_table (j_common_ptr cinfo)
+{
+  JQUANT_TBL *tbl;
+
+  tbl = (JQUANT_TBL *)
+    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
+  tbl->sent_table = FALSE;	/* make sure this is false in any new table */
+  return tbl;
+}
+
+
+GLOBAL(JHUFF_TBL *)
+jpeg_alloc_huff_table (j_common_ptr cinfo)
+{
+  JHUFF_TBL *tbl;
+
+  tbl = (JHUFF_TBL *)
+    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
+  tbl->sent_table = FALSE;	/* make sure this is false in any new table */
+  return tbl;
+}
diff --git a/Utilities/FLTK/jpeg/jconfig.doc b/Utilities/FLTK/jpeg/jconfig.doc
new file mode 100644
index 0000000000000000000000000000000000000000..c18d1c064b77287209ab5d5d6b83e591b702df9f
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jconfig.doc
@@ -0,0 +1,155 @@
+/*
+ * jconfig.doc
+ *
+ * Copyright (C) 1991-1994, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file documents the configuration options that are required to
+ * customize the JPEG software for a particular system.
+ *
+ * The actual configuration options for a particular installation are stored
+ * in jconfig.h.  On many machines, jconfig.h can be generated automatically
+ * or copied from one of the "canned" jconfig files that we supply.  But if
+ * you need to generate a jconfig.h file by hand, this file tells you how.
+ *
+ * DO NOT EDIT THIS FILE --- IT WON'T ACCOMPLISH ANYTHING.
+ * EDIT A COPY NAMED JCONFIG.H.
+ */
+
+
+/*
+ * These symbols indicate the properties of your machine or compiler.
+ * #define the symbol if yes, #undef it if no.
+ */
+
+/* Does your compiler support function prototypes?
+ * (If not, you also need to use ansi2knr, see install.doc)
+ */
+#define HAVE_PROTOTYPES
+
+/* Does your compiler support the declaration "unsigned char" ?
+ * How about "unsigned short" ?
+ */
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+
+/* Define "void" as "char" if your compiler doesn't know about type void.
+ * NOTE: be sure to define void such that "void *" represents the most general
+ * pointer type, e.g., that returned by malloc().
+ */
+/* #define void char */
+
+/* Define "const" as empty if your compiler doesn't know the "const" keyword.
+ */
+/* #define const */
+
+/* Define this if an ordinary "char" type is unsigned.
+ * If you're not sure, leaving it undefined will work at some cost in speed.
+ * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal.
+ */
+#undef CHAR_IS_UNSIGNED
+
+/* Define this if your system has an ANSI-conforming <stddef.h> file.
+ */
+#define HAVE_STDDEF_H
+
+/* Define this if your system has an ANSI-conforming <stdlib.h> file.
+ */
+#define HAVE_STDLIB_H
+
+/* Define this if your system does not have an ANSI/SysV <string.h>,
+ * but does have a BSD-style <strings.h>.
+ */
+#undef NEED_BSD_STRINGS
+
+/* Define this if your system does not provide typedef size_t in any of the
+ * ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in
+ * <sys/types.h> instead.
+ */
+#undef NEED_SYS_TYPES_H
+
+/* For 80x86 machines, you need to define NEED_FAR_POINTERS,
+ * unless you are using a large-data memory model or 80386 flat-memory mode.
+ * On less brain-damaged CPUs this symbol must not be defined.
+ * (Defining this symbol causes large data structures to be referenced through
+ * "far" pointers and to be allocated with a special version of malloc.)
+ */
+#undef NEED_FAR_POINTERS
+
+/* Define this if your linker needs global names to be unique in less
+ * than the first 15 characters.
+ */
+#undef NEED_SHORT_EXTERNAL_NAMES
+
+/* Although a real ANSI C compiler can deal perfectly well with pointers to
+ * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
+ * and pseudo-ANSI compilers get confused.  To keep one of these bozos happy,
+ * define INCOMPLETE_TYPES_BROKEN.  This is not recommended unless you
+ * actually get "missing structure definition" warnings or errors while
+ * compiling the JPEG code.
+ */
+#undef INCOMPLETE_TYPES_BROKEN
+
+
+/*
+ * The following options affect code selection within the JPEG library,
+ * but they don't need to be visible to applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+
+/* Define this if your compiler implements ">>" on signed values as a logical
+ * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
+ * which is the normal and rational definition.
+ */
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+
+#endif /* JPEG_INTERNALS */
+
+
+/*
+ * The remaining options do not affect the JPEG library proper,
+ * but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c).
+ * Other applications can ignore these.
+ */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+/* These defines indicate which image (non-JPEG) file formats are allowed. */
+
+#define BMP_SUPPORTED		/* BMP image file format */
+#define GIF_SUPPORTED		/* GIF image file format */
+#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED		/* Utah RLE image file format */
+#define TARGA_SUPPORTED		/* Targa image file format */
+
+/* Define this if you want to name both input and output files on the command
+ * line, rather than using stdout and optionally stdin.  You MUST do this if
+ * your system can't cope with binary I/O to stdin/stdout.  See comments at
+ * head of cjpeg.c or djpeg.c.
+ */
+#undef TWO_FILE_COMMANDLINE
+
+/* Define this if your system needs explicit cleanup of temporary files.
+ * This is crucial under MS-DOS, where the temporary "files" may be areas
+ * of extended memory; on most other systems it's not as important.
+ */
+#undef NEED_SIGNAL_CATCHER
+
+/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
+ * This is necessary on systems that distinguish text files from binary files,
+ * and is harmless on most systems that don't.  If you have one of the rare
+ * systems that complains about the "b" spec, define this symbol.
+ */
+#undef DONT_USE_B_MODE
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg.
+ */
+#undef PROGRESS_REPORT
+
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/Utilities/FLTK/jpeg/jconfig.h b/Utilities/FLTK/jpeg/jconfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..a990022846a11fefb218e54706271e4ad77f5f71
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jconfig.h
@@ -0,0 +1,50 @@
+/* jconfig.cfg --- source file edited by configure script */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+#ifdef __CHAR_UNSIGNED__
+#  define CHAR_IS_UNSIGNED
+#endif /* __CHAR_UNSIGNED__ */
+/* Define this if you get warnings about undefined structures. */
+#undef INCOMPLETE_TYPES_BROKEN
+
+#if defined(WIN32) || defined(__EMX__)
+/* Define "boolean" as unsigned char, not int, per Windows custom */
+#  ifndef __RPCNDR_H__		/* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#  endif
+#  define HAVE_BOOLEAN		/* prevent jmorecfg.h from redefining it */
+#endif /* WIN32 || __EMX__ */
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+#undef INLINE
+/* These are for configuring the JPEG memory manager. */
+#undef DEFAULT_MAX_MEM
+#undef NO_MKTEMP
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED		/* BMP image file format */
+#define GIF_SUPPORTED		/* GIF image file format */
+#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED		/* Utah RLE image file format */
+#define TARGA_SUPPORTED		/* Targa image file format */
+
+#undef TWO_FILE_COMMANDLINE
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+
+#if defined(WIN32) || defined(__EMX__)
+#  define USE_SETMODE
+#endif /* WIN32 || __EMX__ */
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
+#undef PROGRESS_REPORT
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/Utilities/FLTK/jpeg/jcparam.c b/Utilities/FLTK/jpeg/jcparam.c
new file mode 100644
index 0000000000000000000000000000000000000000..6fc48f53653315537ffd098d83c25c0d3db502b5
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcparam.c
@@ -0,0 +1,610 @@
+/*
+ * jcparam.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains optional default-setting code for the JPEG compressor.
+ * Applications do not have to use this file, but those that don't use it
+ * must know a lot more about the innards of the JPEG code.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Quantization table setup routines
+ */
+
+GLOBAL(void)
+jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
+		      const unsigned int *basic_table,
+		      int scale_factor, boolean force_baseline)
+/* Define a quantization table equal to the basic_table times
+ * a scale factor (given as a percentage).
+ * If force_baseline is TRUE, the computed quantization table entries
+ * are limited to 1..255 for JPEG baseline compatibility.
+ */
+{
+  JQUANT_TBL ** qtblptr;
+  int i;
+  long temp;
+
+  /* Safety check to ensure start_compress not called yet. */
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
+    ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
+
+  qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
+
+  if (*qtblptr == NULL)
+    *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
+
+  for (i = 0; i < DCTSIZE2; i++) {
+    temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
+    /* limit the values to the valid range */
+    if (temp <= 0L) temp = 1L;
+    if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
+    if (force_baseline && temp > 255L)
+      temp = 255L;		/* limit to baseline range if requested */
+    (*qtblptr)->quantval[i] = (UINT16) temp;
+  }
+
+  /* Initialize sent_table FALSE so table will be written to JPEG file. */
+  (*qtblptr)->sent_table = FALSE;
+}
+
+
+GLOBAL(void)
+jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
+			 boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting, using default tables
+ * and a straight percentage-scaling quality scale.  In most cases it's better
+ * to use jpeg_set_quality (below); this entry point is provided for
+ * applications that insist on a linear percentage scaling.
+ */
+{
+  /* These are the sample quantization tables given in JPEG spec section K.1.
+   * The spec says that the values given produce "good" quality, and
+   * when divided by 2, "very good" quality.
+   */
+  static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
+    16,  11,  10,  16,  24,  40,  51,  61,
+    12,  12,  14,  19,  26,  58,  60,  55,
+    14,  13,  16,  24,  40,  57,  69,  56,
+    14,  17,  22,  29,  51,  87,  80,  62,
+    18,  22,  37,  56,  68, 109, 103,  77,
+    24,  35,  55,  64,  81, 104, 113,  92,
+    49,  64,  78,  87, 103, 121, 120, 101,
+    72,  92,  95,  98, 112, 100, 103,  99
+  };
+  static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
+    17,  18,  24,  47,  99,  99,  99,  99,
+    18,  21,  26,  66,  99,  99,  99,  99,
+    24,  26,  56,  99,  99,  99,  99,  99,
+    47,  66,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99
+  };
+
+  /* Set up two quantization tables using the specified scaling */
+  jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
+		       scale_factor, force_baseline);
+  jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
+		       scale_factor, force_baseline);
+}
+
+
+GLOBAL(int)
+jpeg_quality_scaling (int quality)
+/* Convert a user-specified quality rating to a percentage scaling factor
+ * for an underlying quantization table, using our recommended scaling curve.
+ * The input 'quality' factor should be 0 (terrible) to 100 (very good).
+ */
+{
+  /* Safety limit on quality factor.  Convert 0 to 1 to avoid zero divide. */
+  if (quality <= 0) quality = 1;
+  if (quality > 100) quality = 100;
+
+  /* The basic table is used as-is (scaling 100) for a quality of 50.
+   * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
+   * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
+   * to make all the table entries 1 (hence, minimum quantization loss).
+   * Qualities 1..50 are converted to scaling percentage 5000/Q.
+   */
+  if (quality < 50)
+    quality = 5000 / quality;
+  else
+    quality = 200 - quality*2;
+
+  return quality;
+}
+
+
+GLOBAL(void)
+jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting, using default tables.
+ * This is the standard quality-adjusting entry point for typical user
+ * interfaces; only those who want detailed control over quantization tables
+ * would use the preceding three routines directly.
+ */
+{
+  /* Convert user 0-100 rating to percentage scaling */
+  quality = jpeg_quality_scaling(quality);
+
+  /* Set up standard quality tables */
+  jpeg_set_linear_quality(cinfo, quality, force_baseline);
+}
+
+
+/*
+ * Huffman table setup routines
+ */
+
+LOCAL(void)
+add_huff_table (j_compress_ptr cinfo,
+		JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
+/* Define a Huffman table */
+{
+  int nsymbols, len;
+
+  if (*htblptr == NULL)
+    *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+
+  /* Copy the number-of-symbols-of-each-code-length counts */
+  MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
+
+  /* Validate the counts.  We do this here mainly so we can copy the right
+   * number of symbols from the val[] array, without risking marching off
+   * the end of memory.  jchuff.c will do a more thorough test later.
+   */
+  nsymbols = 0;
+  for (len = 1; len <= 16; len++)
+    nsymbols += bits[len];
+  if (nsymbols < 1 || nsymbols > 256)
+    ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+  MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
+
+  /* Initialize sent_table FALSE so table will be written to JPEG file. */
+  (*htblptr)->sent_table = FALSE;
+}
+
+
+LOCAL(void)
+std_huff_tables (j_compress_ptr cinfo)
+/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
+/* IMPORTANT: these are only valid for 8-bit data precision! */
+{
+  static const UINT8 bits_dc_luminance[17] =
+    { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+  static const UINT8 val_dc_luminance[] =
+    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+  
+  static const UINT8 bits_dc_chrominance[17] =
+    { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+  static const UINT8 val_dc_chrominance[] =
+    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+  
+  static const UINT8 bits_ac_luminance[17] =
+    { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
+  static const UINT8 val_ac_luminance[] =
+    { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+      0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+      0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+      0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+      0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+      0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+      0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+      0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+      0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+      0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+      0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+      0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+      0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+      0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+      0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+      0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+      0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+      0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+      0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+      0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+      0xf9, 0xfa };
+  
+  static const UINT8 bits_ac_chrominance[17] =
+    { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
+  static const UINT8 val_ac_chrominance[] =
+    { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+      0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+      0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+      0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+      0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+      0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+      0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+      0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+      0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+      0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+      0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+      0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+      0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+      0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+      0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+      0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+      0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+      0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+      0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+      0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+      0xf9, 0xfa };
+  
+  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
+		 bits_dc_luminance, val_dc_luminance);
+  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
+		 bits_ac_luminance, val_ac_luminance);
+  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
+		 bits_dc_chrominance, val_dc_chrominance);
+  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
+		 bits_ac_chrominance, val_ac_chrominance);
+}
+
+
+/*
+ * Default parameter setup for compression.
+ *
+ * Applications that don't choose to use this routine must do their
+ * own setup of all these parameters.  Alternately, you can call this
+ * to establish defaults and then alter parameters selectively.  This
+ * is the recommended approach since, if we add any new parameters,
+ * your code will still work (they'll be set to reasonable defaults).
+ */
+
+GLOBAL(void)
+jpeg_set_defaults (j_compress_ptr cinfo)
+{
+  int i;
+
+  /* Safety check to ensure start_compress not called yet. */
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  /* Allocate comp_info array large enough for maximum component count.
+   * Array is made permanent in case application wants to compress
+   * multiple images at same param settings.
+   */
+  if (cinfo->comp_info == NULL)
+    cinfo->comp_info = (jpeg_component_info *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				  MAX_COMPONENTS * SIZEOF(jpeg_component_info));
+
+  /* Initialize everything not dependent on the color space */
+
+  cinfo->data_precision = BITS_IN_JSAMPLE;
+  /* Set up two quantization tables using default quality of 75 */
+  jpeg_set_quality(cinfo, 75, TRUE);
+  /* Set up two Huffman tables */
+  std_huff_tables(cinfo);
+
+  /* Initialize default arithmetic coding conditioning */
+  for (i = 0; i < NUM_ARITH_TBLS; i++) {
+    cinfo->arith_dc_L[i] = 0;
+    cinfo->arith_dc_U[i] = 1;
+    cinfo->arith_ac_K[i] = 5;
+  }
+
+  /* Default is no multiple-scan output */
+  cinfo->scan_info = NULL;
+  cinfo->num_scans = 0;
+
+  /* Expect normal source image, not raw downsampled data */
+  cinfo->raw_data_in = FALSE;
+
+  /* Use Huffman coding, not arithmetic coding, by default */
+  cinfo->arith_code = FALSE;
+
+  /* By default, don't do extra passes to optimize entropy coding */
+  cinfo->optimize_coding = FALSE;
+  /* The standard Huffman tables are only valid for 8-bit data precision.
+   * If the precision is higher, force optimization on so that usable
+   * tables will be computed.  This test can be removed if default tables
+   * are supplied that are valid for the desired precision.
+   */
+  if (cinfo->data_precision > 8)
+    cinfo->optimize_coding = TRUE;
+
+  /* By default, use the simpler non-cosited sampling alignment */
+  cinfo->CCIR601_sampling = FALSE;
+
+  /* No input smoothing */
+  cinfo->smoothing_factor = 0;
+
+  /* DCT algorithm preference */
+  cinfo->dct_method = JDCT_DEFAULT;
+
+  /* No restart markers */
+  cinfo->restart_interval = 0;
+  cinfo->restart_in_rows = 0;
+
+  /* Fill in default JFIF marker parameters.  Note that whether the marker
+   * will actually be written is determined by jpeg_set_colorspace.
+   *
+   * By default, the library emits JFIF version code 1.01.
+   * An application that wants to emit JFIF 1.02 extension markers should set
+   * JFIF_minor_version to 2.  We could probably get away with just defaulting
+   * to 1.02, but there may still be some decoders in use that will complain
+   * about that; saying 1.01 should minimize compatibility problems.
+   */
+  cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
+  cinfo->JFIF_minor_version = 1;
+  cinfo->density_unit = 0;	/* Pixel size is unknown by default */
+  cinfo->X_density = 1;		/* Pixel aspect ratio is square by default */
+  cinfo->Y_density = 1;
+
+  /* Choose JPEG colorspace based on input space, set defaults accordingly */
+
+  jpeg_default_colorspace(cinfo);
+}
+
+
+/*
+ * Select an appropriate JPEG colorspace for in_color_space.
+ */
+
+GLOBAL(void)
+jpeg_default_colorspace (j_compress_ptr cinfo)
+{
+  switch (cinfo->in_color_space) {
+  case JCS_GRAYSCALE:
+    jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
+    break;
+  case JCS_RGB:
+    jpeg_set_colorspace(cinfo, JCS_YCbCr);
+    break;
+  case JCS_YCbCr:
+    jpeg_set_colorspace(cinfo, JCS_YCbCr);
+    break;
+  case JCS_CMYK:
+    jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
+    break;
+  case JCS_YCCK:
+    jpeg_set_colorspace(cinfo, JCS_YCCK);
+    break;
+  case JCS_UNKNOWN:
+    jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
+    break;
+  default:
+    ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+  }
+}
+
+
+/*
+ * Set the JPEG colorspace, and choose colorspace-dependent default values.
+ */
+
+GLOBAL(void)
+jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
+{
+  jpeg_component_info * compptr;
+  int ci;
+
+#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl)  \
+  (compptr = &cinfo->comp_info[index], \
+   compptr->component_id = (id), \
+   compptr->h_samp_factor = (hsamp), \
+   compptr->v_samp_factor = (vsamp), \
+   compptr->quant_tbl_no = (quant), \
+   compptr->dc_tbl_no = (dctbl), \
+   compptr->ac_tbl_no = (actbl) )
+
+  /* Safety check to ensure start_compress not called yet. */
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  /* For all colorspaces, we use Q and Huff tables 0 for luminance components,
+   * tables 1 for chrominance components.
+   */
+
+  cinfo->jpeg_color_space = colorspace;
+
+  cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */
+  cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */
+
+  switch (colorspace) {
+  case JCS_GRAYSCALE:
+    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+    cinfo->num_components = 1;
+    /* JFIF specifies component ID 1 */
+    SET_COMP(0, 1, 1,1, 0, 0,0);
+    break;
+  case JCS_RGB:
+    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
+    cinfo->num_components = 3;
+    SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
+    SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
+    SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
+    break;
+  case JCS_YCbCr:
+    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+    cinfo->num_components = 3;
+    /* JFIF specifies component IDs 1,2,3 */
+    /* We default to 2x2 subsamples of chrominance */
+    SET_COMP(0, 1, 2,2, 0, 0,0);
+    SET_COMP(1, 2, 1,1, 1, 1,1);
+    SET_COMP(2, 3, 1,1, 1, 1,1);
+    break;
+  case JCS_CMYK:
+    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
+    cinfo->num_components = 4;
+    SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0);
+    SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0);
+    SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0);
+    SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0);
+    break;
+  case JCS_YCCK:
+    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
+    cinfo->num_components = 4;
+    SET_COMP(0, 1, 2,2, 0, 0,0);
+    SET_COMP(1, 2, 1,1, 1, 1,1);
+    SET_COMP(2, 3, 1,1, 1, 1,1);
+    SET_COMP(3, 4, 2,2, 0, 0,0);
+    break;
+  case JCS_UNKNOWN:
+    cinfo->num_components = cinfo->input_components;
+    if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
+      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+	       MAX_COMPONENTS);
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      SET_COMP(ci, ci, 1,1, 0, 0,0);
+    }
+    break;
+  default:
+    ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+  }
+}
+
+
+#ifdef C_PROGRESSIVE_SUPPORTED
+
+LOCAL(jpeg_scan_info *)
+fill_a_scan (jpeg_scan_info * scanptr, int ci,
+	     int Ss, int Se, int Ah, int Al)
+/* Support routine: generate one scan for specified component */
+{
+  scanptr->comps_in_scan = 1;
+  scanptr->component_index[0] = ci;
+  scanptr->Ss = Ss;
+  scanptr->Se = Se;
+  scanptr->Ah = Ah;
+  scanptr->Al = Al;
+  scanptr++;
+  return scanptr;
+}
+
+LOCAL(jpeg_scan_info *)
+fill_scans (jpeg_scan_info * scanptr, int ncomps,
+	    int Ss, int Se, int Ah, int Al)
+/* Support routine: generate one scan for each component */
+{
+  int ci;
+
+  for (ci = 0; ci < ncomps; ci++) {
+    scanptr->comps_in_scan = 1;
+    scanptr->component_index[0] = ci;
+    scanptr->Ss = Ss;
+    scanptr->Se = Se;
+    scanptr->Ah = Ah;
+    scanptr->Al = Al;
+    scanptr++;
+  }
+  return scanptr;
+}
+
+LOCAL(jpeg_scan_info *)
+fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
+/* Support routine: generate interleaved DC scan if possible, else N scans */
+{
+  int ci;
+
+  if (ncomps <= MAX_COMPS_IN_SCAN) {
+    /* Single interleaved DC scan */
+    scanptr->comps_in_scan = ncomps;
+    for (ci = 0; ci < ncomps; ci++)
+      scanptr->component_index[ci] = ci;
+    scanptr->Ss = scanptr->Se = 0;
+    scanptr->Ah = Ah;
+    scanptr->Al = Al;
+    scanptr++;
+  } else {
+    /* Noninterleaved DC scan for each component */
+    scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al);
+  }
+  return scanptr;
+}
+
+
+/*
+ * Create a recommended progressive-JPEG script.
+ * cinfo->num_components and cinfo->jpeg_color_space must be correct.
+ */
+
+GLOBAL(void)
+jpeg_simple_progression (j_compress_ptr cinfo)
+{
+  int ncomps = cinfo->num_components;
+  int nscans;
+  jpeg_scan_info * scanptr;
+
+  /* Safety check to ensure start_compress not called yet. */
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  /* Figure space needed for script.  Calculation must match code below! */
+  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
+    /* Custom script for YCbCr color images. */
+    nscans = 10;
+  } else {
+    /* All-purpose script for other color spaces. */
+    if (ncomps > MAX_COMPS_IN_SCAN)
+      nscans = 6 * ncomps;	/* 2 DC + 4 AC scans per component */
+    else
+      nscans = 2 + 4 * ncomps;	/* 2 DC scans; 4 AC scans per component */
+  }
+
+  /* Allocate space for script.
+   * We need to put it in the permanent pool in case the application performs
+   * multiple compressions without changing the settings.  To avoid a memory
+   * leak if jpeg_simple_progression is called repeatedly for the same JPEG
+   * object, we try to re-use previously allocated space, and we allocate
+   * enough space to handle YCbCr even if initially asked for grayscale.
+   */
+  if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
+    cinfo->script_space_size = MAX(nscans, 10);
+    cinfo->script_space = (jpeg_scan_info *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+			cinfo->script_space_size * SIZEOF(jpeg_scan_info));
+  }
+  scanptr = cinfo->script_space;
+  cinfo->scan_info = scanptr;
+  cinfo->num_scans = nscans;
+
+  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
+    /* Custom script for YCbCr color images. */
+    /* Initial DC scan */
+    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
+    /* Initial AC scan: get some luma data out in a hurry */
+    scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
+    /* Chroma data is too small to be worth expending many scans on */
+    scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
+    scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
+    /* Complete spectral selection for luma AC */
+    scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
+    /* Refine next bit of luma AC */
+    scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
+    /* Finish DC successive approximation */
+    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
+    /* Finish AC successive approximation */
+    scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
+    scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
+    /* Luma bottom bit comes last since it's usually largest scan */
+    scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
+  } else {
+    /* All-purpose script for other color spaces. */
+    /* Successive approximation first pass */
+    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
+    scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
+    scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
+    /* Successive approximation second pass */
+    scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
+    /* Successive approximation final pass */
+    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
+    scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
+  }
+}
+
+#endif /* C_PROGRESSIVE_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jcphuff.c b/Utilities/FLTK/jpeg/jcphuff.c
new file mode 100644
index 0000000000000000000000000000000000000000..07f9178b01c885820889cf377c0e73d444f5dd1b
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcphuff.c
@@ -0,0 +1,833 @@
+/*
+ * jcphuff.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy encoding routines for progressive JPEG.
+ *
+ * We do not support output suspension in this module, since the library
+ * currently does not allow multiple-scan files to be written with output
+ * suspension.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jchuff.h"		/* Declarations shared with jchuff.c */
+
+#ifdef C_PROGRESSIVE_SUPPORTED
+
+/* Expanded entropy encoder object for progressive Huffman encoding. */
+
+typedef struct {
+  struct jpeg_entropy_encoder pub; /* public fields */
+
+  /* Mode flag: TRUE for optimization, FALSE for actual data output */
+  boolean gather_statistics;
+
+  /* Bit-level coding status.
+   * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
+   */
+  JOCTET * next_output_byte;	/* => next byte to write in buffer */
+  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */
+  INT32 put_buffer;		/* current bit-accumulation buffer */
+  int put_bits;			/* # of bits now in it */
+  j_compress_ptr cinfo;		/* link to cinfo (needed for dump_buffer) */
+
+  /* Coding status for DC components */
+  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+
+  /* Coding status for AC components */
+  int ac_tbl_no;		/* the table number of the single component */
+  unsigned int EOBRUN;		/* run length of EOBs */
+  unsigned int BE;		/* # of buffered correction bits before MCU */
+  char * bit_buffer;		/* buffer for correction bits (1 per char) */
+  /* packing correction bits tightly would save some space but cost time... */
+
+  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
+  int next_restart_num;		/* next restart number to write (0-7) */
+
+  /* Pointers to derived tables (these workspaces have image lifespan).
+   * Since any one scan codes only DC or only AC, we only need one set
+   * of tables, not one for DC and one for AC.
+   */
+  c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
+
+  /* Statistics tables for optimization; again, one set is enough */
+  long * count_ptrs[NUM_HUFF_TBLS];
+} phuff_entropy_encoder;
+
+typedef phuff_entropy_encoder * phuff_entropy_ptr;
+
+/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
+ * buffer can hold.  Larger sizes may slightly improve compression, but
+ * 1000 is already well into the realm of overkill.
+ * The minimum safe size is 64 bits.
+ */
+
+#define MAX_CORR_BITS  1000	/* Max # of correction bits I can buffer */
+
+/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
+ * We assume that int right shift is unsigned if INT32 right shift is,
+ * which should be safe.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define ISHIFT_TEMPS	int ishift_temp;
+#define IRIGHT_SHIFT(x,shft)  \
+	((ishift_temp = (x)) < 0 ? \
+	 (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
+	 (ishift_temp >> (shft)))
+#else
+#define ISHIFT_TEMPS
+#define IRIGHT_SHIFT(x,shft)	((x) >> (shft))
+#endif
+
+/* Forward declarations */
+METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
+					    JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
+					    JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
+					     JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
+					     JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
+METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
+
+
+/*
+ * Initialize for a Huffman-compressed scan using progressive JPEG.
+ */
+
+METHODDEF(void)
+start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
+{  
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  boolean is_DC_band;
+  int ci, tbl;
+  jpeg_component_info * compptr;
+
+  entropy->cinfo = cinfo;
+  entropy->gather_statistics = gather_statistics;
+
+  is_DC_band = (cinfo->Ss == 0);
+
+  /* We assume jcmaster.c already validated the scan parameters. */
+
+  /* Select execution routines */
+  if (cinfo->Ah == 0) {
+    if (is_DC_band)
+      entropy->pub.encode_mcu = encode_mcu_DC_first;
+    else
+      entropy->pub.encode_mcu = encode_mcu_AC_first;
+  } else {
+    if (is_DC_band)
+      entropy->pub.encode_mcu = encode_mcu_DC_refine;
+    else {
+      entropy->pub.encode_mcu = encode_mcu_AC_refine;
+      /* AC refinement needs a correction bit buffer */
+      if (entropy->bit_buffer == NULL)
+	entropy->bit_buffer = (char *)
+	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				      MAX_CORR_BITS * SIZEOF(char));
+    }
+  }
+  if (gather_statistics)
+    entropy->pub.finish_pass = finish_pass_gather_phuff;
+  else
+    entropy->pub.finish_pass = finish_pass_phuff;
+
+  /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
+   * for AC coefficients.
+   */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    /* Initialize DC predictions to 0 */
+    entropy->last_dc_val[ci] = 0;
+    /* Get table index */
+    if (is_DC_band) {
+      if (cinfo->Ah != 0)	/* DC refinement needs no table */
+	continue;
+      tbl = compptr->dc_tbl_no;
+    } else {
+      entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
+    }
+    if (gather_statistics) {
+      /* Check for invalid table index */
+      /* (make_c_derived_tbl does this in the other path) */
+      if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
+        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
+      /* Allocate and zero the statistics tables */
+      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
+      if (entropy->count_ptrs[tbl] == NULL)
+	entropy->count_ptrs[tbl] = (long *)
+	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				      257 * SIZEOF(long));
+      MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
+    } else {
+      /* Compute derived values for Huffman table */
+      /* We may do this more than once for a table, but it's not expensive */
+      jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
+			      & entropy->derived_tbls[tbl]);
+    }
+  }
+
+  /* Initialize AC stuff */
+  entropy->EOBRUN = 0;
+  entropy->BE = 0;
+
+  /* Initialize bit buffer to empty */
+  entropy->put_buffer = 0;
+  entropy->put_bits = 0;
+
+  /* Initialize restart stuff */
+  entropy->restarts_to_go = cinfo->restart_interval;
+  entropy->next_restart_num = 0;
+}
+
+
+/* Outputting bytes to the file.
+ * NB: these must be called only when actually outputting,
+ * that is, entropy->gather_statistics == FALSE.
+ */
+
+/* Emit a byte */
+#define emit_byte(entropy,val)  \
+	{ *(entropy)->next_output_byte++ = (JOCTET) (val);  \
+	  if (--(entropy)->free_in_buffer == 0)  \
+	    dump_buffer(entropy); }
+
+
+LOCAL(void)
+dump_buffer (phuff_entropy_ptr entropy)
+/* Empty the output buffer; we do not support suspension in this module. */
+{
+  struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
+
+  if (! (*dest->empty_output_buffer) (entropy->cinfo))
+    ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
+  /* After a successful buffer dump, must reset buffer pointers */
+  entropy->next_output_byte = dest->next_output_byte;
+  entropy->free_in_buffer = dest->free_in_buffer;
+}
+
+
+/* Outputting bits to the file */
+
+/* Only the right 24 bits of put_buffer are used; the valid bits are
+ * left-justified in this part.  At most 16 bits can be passed to emit_bits
+ * in one call, and we never retain more than 7 bits in put_buffer
+ * between calls, so 24 bits are sufficient.
+ */
+
+INLINE
+LOCAL(void)
+emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
+/* Emit some bits, unless we are in gather mode */
+{
+  /* This routine is heavily used, so it's worth coding tightly. */
+  register INT32 put_buffer = (INT32) code;
+  register int put_bits = entropy->put_bits;
+
+  /* if size is 0, caller used an invalid Huffman table entry */
+  if (size == 0)
+    ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
+
+  if (entropy->gather_statistics)
+    return;			/* do nothing if we're only getting stats */
+
+  put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
+  
+  put_bits += size;		/* new number of bits in buffer */
+  
+  put_buffer <<= 24 - put_bits; /* align incoming bits */
+
+  put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */
+
+  while (put_bits >= 8) {
+    int c = (int) ((put_buffer >> 16) & 0xFF);
+    
+    emit_byte(entropy, c);
+    if (c == 0xFF) {		/* need to stuff a zero byte? */
+      emit_byte(entropy, 0);
+    }
+    put_buffer <<= 8;
+    put_bits -= 8;
+  }
+
+  entropy->put_buffer = put_buffer; /* update variables */
+  entropy->put_bits = put_bits;
+}
+
+
+LOCAL(void)
+flush_bits (phuff_entropy_ptr entropy)
+{
+  emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
+  entropy->put_buffer = 0;     /* and reset bit-buffer to empty */
+  entropy->put_bits = 0;
+}
+
+
+/*
+ * Emit (or just count) a Huffman symbol.
+ */
+
+INLINE
+LOCAL(void)
+emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
+{
+  if (entropy->gather_statistics)
+    entropy->count_ptrs[tbl_no][symbol]++;
+  else {
+    c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
+    emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
+  }
+}
+
+
+/*
+ * Emit bits from a correction bit buffer.
+ */
+
+LOCAL(void)
+emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
+		    unsigned int nbits)
+{
+  if (entropy->gather_statistics)
+    return;			/* no real work */
+
+  while (nbits > 0) {
+    emit_bits(entropy, (unsigned int) (*bufstart), 1);
+    bufstart++;
+    nbits--;
+  }
+}
+
+
+/*
+ * Emit any pending EOBRUN symbol.
+ */
+
+LOCAL(void)
+emit_eobrun (phuff_entropy_ptr entropy)
+{
+  register int temp, nbits;
+
+  if (entropy->EOBRUN > 0) {	/* if there is any pending EOBRUN */
+    temp = entropy->EOBRUN;
+    nbits = 0;
+    while ((temp >>= 1))
+      nbits++;
+    /* safety check: shouldn't happen given limited correction-bit buffer */
+    if (nbits > 14)
+      ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
+
+    emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
+    if (nbits)
+      emit_bits(entropy, entropy->EOBRUN, nbits);
+
+    entropy->EOBRUN = 0;
+
+    /* Emit any buffered correction bits */
+    emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
+    entropy->BE = 0;
+  }
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL(void)
+emit_restart (phuff_entropy_ptr entropy, int restart_num)
+{
+  int ci;
+
+  emit_eobrun(entropy);
+
+  if (! entropy->gather_statistics) {
+    flush_bits(entropy);
+    emit_byte(entropy, 0xFF);
+    emit_byte(entropy, JPEG_RST0 + restart_num);
+  }
+
+  if (entropy->cinfo->Ss == 0) {
+    /* Re-initialize DC predictions to 0 */
+    for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
+      entropy->last_dc_val[ci] = 0;
+  } else {
+    /* Re-initialize all AC-related fields to 0 */
+    entropy->EOBRUN = 0;
+    entropy->BE = 0;
+  }
+}
+
+
+/*
+ * MCU encoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  register int temp, temp2;
+  register int nbits;
+  int blkn, ci;
+  int Al = cinfo->Al;
+  JBLOCKROW block;
+  jpeg_component_info * compptr;
+  ISHIFT_TEMPS
+
+  entropy->next_output_byte = cinfo->dest->next_output_byte;
+  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+  /* Emit restart marker if needed */
+  if (cinfo->restart_interval)
+    if (entropy->restarts_to_go == 0)
+      emit_restart(entropy, entropy->next_restart_num);
+
+  /* Encode the MCU data blocks */
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    block = MCU_data[blkn];
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+
+    /* Compute the DC value after the required point transform by Al.
+     * This is simply an arithmetic right shift.
+     */
+    temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
+
+    /* DC differences are figured on the point-transformed values. */
+    temp = temp2 - entropy->last_dc_val[ci];
+    entropy->last_dc_val[ci] = temp2;
+
+    /* Encode the DC coefficient difference per section G.1.2.1 */
+    temp2 = temp;
+    if (temp < 0) {
+      temp = -temp;		/* temp is abs value of input */
+      /* For a negative input, want temp2 = bitwise complement of abs(input) */
+      /* This code assumes we are on a two's complement machine */
+      temp2--;
+    }
+    
+    /* Find the number of bits needed for the magnitude of the coefficient */
+    nbits = 0;
+    while (temp) {
+      nbits++;
+      temp >>= 1;
+    }
+    /* Check for out-of-range coefficient values.
+     * Since we're encoding a difference, the range limit is twice as much.
+     */
+    if (nbits > MAX_COEF_BITS+1)
+      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+    
+    /* Count/emit the Huffman-coded symbol for the number of bits */
+    emit_symbol(entropy, compptr->dc_tbl_no, nbits);
+    
+    /* Emit that number of bits of the value, if positive, */
+    /* or the complement of its magnitude, if negative. */
+    if (nbits)			/* emit_bits rejects calls with size 0 */
+      emit_bits(entropy, (unsigned int) temp2, nbits);
+  }
+
+  cinfo->dest->next_output_byte = entropy->next_output_byte;
+  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+  /* Update restart-interval state too */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0) {
+      entropy->restarts_to_go = cinfo->restart_interval;
+      entropy->next_restart_num++;
+      entropy->next_restart_num &= 7;
+    }
+    entropy->restarts_to_go--;
+  }
+
+  return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  register int temp, temp2;
+  register int nbits;
+  register int r, k;
+  int Se = cinfo->Se;
+  int Al = cinfo->Al;
+  JBLOCKROW block;
+
+  entropy->next_output_byte = cinfo->dest->next_output_byte;
+  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+  /* Emit restart marker if needed */
+  if (cinfo->restart_interval)
+    if (entropy->restarts_to_go == 0)
+      emit_restart(entropy, entropy->next_restart_num);
+
+  /* Encode the MCU data block */
+  block = MCU_data[0];
+
+  /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
+  
+  r = 0;			/* r = run length of zeros */
+   
+  for (k = cinfo->Ss; k <= Se; k++) {
+    if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
+      r++;
+      continue;
+    }
+    /* We must apply the point transform by Al.  For AC coefficients this
+     * is an integer division with rounding towards 0.  To do this portably
+     * in C, we shift after obtaining the absolute value; so the code is
+     * interwoven with finding the abs value (temp) and output bits (temp2).
+     */
+    if (temp < 0) {
+      temp = -temp;		/* temp is abs value of input */
+      temp >>= Al;		/* apply the point transform */
+      /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
+      temp2 = ~temp;
+    } else {
+      temp >>= Al;		/* apply the point transform */
+      temp2 = temp;
+    }
+    /* Watch out for case that nonzero coef is zero after point transform */
+    if (temp == 0) {
+      r++;
+      continue;
+    }
+
+    /* Emit any pending EOBRUN */
+    if (entropy->EOBRUN > 0)
+      emit_eobrun(entropy);
+    /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+    while (r > 15) {
+      emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
+      r -= 16;
+    }
+
+    /* Find the number of bits needed for the magnitude of the coefficient */
+    nbits = 1;			/* there must be at least one 1 bit */
+    while ((temp >>= 1))
+      nbits++;
+    /* Check for out-of-range coefficient values */
+    if (nbits > MAX_COEF_BITS)
+      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+    /* Count/emit Huffman symbol for run length / number of bits */
+    emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
+
+    /* Emit that number of bits of the value, if positive, */
+    /* or the complement of its magnitude, if negative. */
+    emit_bits(entropy, (unsigned int) temp2, nbits);
+
+    r = 0;			/* reset zero run length */
+  }
+
+  if (r > 0) {			/* If there are trailing zeroes, */
+    entropy->EOBRUN++;		/* count an EOB */
+    if (entropy->EOBRUN == 0x7FFF)
+      emit_eobrun(entropy);	/* force it out to avoid overflow */
+  }
+
+  cinfo->dest->next_output_byte = entropy->next_output_byte;
+  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+  /* Update restart-interval state too */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0) {
+      entropy->restarts_to_go = cinfo->restart_interval;
+      entropy->next_restart_num++;
+      entropy->next_restart_num &= 7;
+    }
+    entropy->restarts_to_go--;
+  }
+
+  return TRUE;
+}
+
+
+/*
+ * MCU encoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component, although the spec
+ * is not very clear on the point.
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  register int temp;
+  int blkn;
+  int Al = cinfo->Al;
+  JBLOCKROW block;
+
+  entropy->next_output_byte = cinfo->dest->next_output_byte;
+  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+  /* Emit restart marker if needed */
+  if (cinfo->restart_interval)
+    if (entropy->restarts_to_go == 0)
+      emit_restart(entropy, entropy->next_restart_num);
+
+  /* Encode the MCU data blocks */
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    block = MCU_data[blkn];
+
+    /* We simply emit the Al'th bit of the DC coefficient value. */
+    temp = (*block)[0];
+    emit_bits(entropy, (unsigned int) (temp >> Al), 1);
+  }
+
+  cinfo->dest->next_output_byte = entropy->next_output_byte;
+  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+  /* Update restart-interval state too */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0) {
+      entropy->restarts_to_go = cinfo->restart_interval;
+      entropy->next_restart_num++;
+      entropy->next_restart_num &= 7;
+    }
+    entropy->restarts_to_go--;
+  }
+
+  return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  register int temp;
+  register int r, k;
+  int EOB;
+  char *BR_buffer;
+  unsigned int BR;
+  int Se = cinfo->Se;
+  int Al = cinfo->Al;
+  JBLOCKROW block;
+  int absvalues[DCTSIZE2];
+
+  entropy->next_output_byte = cinfo->dest->next_output_byte;
+  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+  /* Emit restart marker if needed */
+  if (cinfo->restart_interval)
+    if (entropy->restarts_to_go == 0)
+      emit_restart(entropy, entropy->next_restart_num);
+
+  /* Encode the MCU data block */
+  block = MCU_data[0];
+
+  /* It is convenient to make a pre-pass to determine the transformed
+   * coefficients' absolute values and the EOB position.
+   */
+  EOB = 0;
+  for (k = cinfo->Ss; k <= Se; k++) {
+    temp = (*block)[jpeg_natural_order[k]];
+    /* We must apply the point transform by Al.  For AC coefficients this
+     * is an integer division with rounding towards 0.  To do this portably
+     * in C, we shift after obtaining the absolute value.
+     */
+    if (temp < 0)
+      temp = -temp;		/* temp is abs value of input */
+    temp >>= Al;		/* apply the point transform */
+    absvalues[k] = temp;	/* save abs value for main pass */
+    if (temp == 1)
+      EOB = k;			/* EOB = index of last newly-nonzero coef */
+  }
+
+  /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
+  
+  r = 0;			/* r = run length of zeros */
+  BR = 0;			/* BR = count of buffered bits added now */
+  BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
+
+  for (k = cinfo->Ss; k <= Se; k++) {
+    if ((temp = absvalues[k]) == 0) {
+      r++;
+      continue;
+    }
+
+    /* Emit any required ZRLs, but not if they can be folded into EOB */
+    while (r > 15 && k <= EOB) {
+      /* emit any pending EOBRUN and the BE correction bits */
+      emit_eobrun(entropy);
+      /* Emit ZRL */
+      emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
+      r -= 16;
+      /* Emit buffered correction bits that must be associated with ZRL */
+      emit_buffered_bits(entropy, BR_buffer, BR);
+      BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
+      BR = 0;
+    }
+
+    /* If the coef was previously nonzero, it only needs a correction bit.
+     * NOTE: a straight translation of the spec's figure G.7 would suggest
+     * that we also need to test r > 15.  But if r > 15, we can only get here
+     * if k > EOB, which implies that this coefficient is not 1.
+     */
+    if (temp > 1) {
+      /* The correction bit is the next bit of the absolute value. */
+      BR_buffer[BR++] = (char) (temp & 1);
+      continue;
+    }
+
+    /* Emit any pending EOBRUN and the BE correction bits */
+    emit_eobrun(entropy);
+
+    /* Count/emit Huffman symbol for run length / number of bits */
+    emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
+
+    /* Emit output bit for newly-nonzero coef */
+    temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
+    emit_bits(entropy, (unsigned int) temp, 1);
+
+    /* Emit buffered correction bits that must be associated with this code */
+    emit_buffered_bits(entropy, BR_buffer, BR);
+    BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
+    BR = 0;
+    r = 0;			/* reset zero run length */
+  }
+
+  if (r > 0 || BR > 0) {	/* If there are trailing zeroes, */
+    entropy->EOBRUN++;		/* count an EOB */
+    entropy->BE += BR;		/* concat my correction bits to older ones */
+    /* We force out the EOB if we risk either:
+     * 1. overflow of the EOB counter;
+     * 2. overflow of the correction bit buffer during the next MCU.
+     */
+    if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
+      emit_eobrun(entropy);
+  }
+
+  cinfo->dest->next_output_byte = entropy->next_output_byte;
+  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+  /* Update restart-interval state too */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0) {
+      entropy->restarts_to_go = cinfo->restart_interval;
+      entropy->next_restart_num++;
+      entropy->next_restart_num &= 7;
+    }
+    entropy->restarts_to_go--;
+  }
+
+  return TRUE;
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed progressive scan.
+ */
+
+METHODDEF(void)
+finish_pass_phuff (j_compress_ptr cinfo)
+{   
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+
+  entropy->next_output_byte = cinfo->dest->next_output_byte;
+  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+  /* Flush out any buffered data */
+  emit_eobrun(entropy);
+  flush_bits(entropy);
+
+  cinfo->dest->next_output_byte = entropy->next_output_byte;
+  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+}
+
+
+/*
+ * Finish up a statistics-gathering pass and create the new Huffman tables.
+ */
+
+METHODDEF(void)
+finish_pass_gather_phuff (j_compress_ptr cinfo)
+{
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  boolean is_DC_band;
+  int ci, tbl;
+  jpeg_component_info * compptr;
+  JHUFF_TBL **htblptr;
+  boolean did[NUM_HUFF_TBLS];
+
+  /* Flush out buffered data (all we care about is counting the EOB symbol) */
+  emit_eobrun(entropy);
+
+  is_DC_band = (cinfo->Ss == 0);
+
+  /* It's important not to apply jpeg_gen_optimal_table more than once
+   * per table, because it clobbers the input frequency counts!
+   */
+  MEMZERO(did, SIZEOF(did));
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    if (is_DC_band) {
+      if (cinfo->Ah != 0)	/* DC refinement needs no table */
+	continue;
+      tbl = compptr->dc_tbl_no;
+    } else {
+      tbl = compptr->ac_tbl_no;
+    }
+    if (! did[tbl]) {
+      if (is_DC_band)
+        htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
+      else
+        htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
+      if (*htblptr == NULL)
+        *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
+      did[tbl] = TRUE;
+    }
+  }
+}
+
+
+/*
+ * Module initialization routine for progressive Huffman entropy encoding.
+ */
+
+GLOBAL(void)
+jinit_phuff_encoder (j_compress_ptr cinfo)
+{
+  phuff_entropy_ptr entropy;
+  int i;
+
+  entropy = (phuff_entropy_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(phuff_entropy_encoder));
+  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+  entropy->pub.start_pass = start_pass_phuff;
+
+  /* Mark tables unallocated */
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    entropy->derived_tbls[i] = NULL;
+    entropy->count_ptrs[i] = NULL;
+  }
+  entropy->bit_buffer = NULL;	/* needed only in AC refinement scan */
+}
+
+#endif /* C_PROGRESSIVE_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jcprepct.c b/Utilities/FLTK/jpeg/jcprepct.c
new file mode 100644
index 0000000000000000000000000000000000000000..fa93333db20f74cbcc3b660523b7dc26688d06ef
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcprepct.c
@@ -0,0 +1,354 @@
+/*
+ * jcprepct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the compression preprocessing controller.
+ * This controller manages the color conversion, downsampling,
+ * and edge expansion steps.
+ *
+ * Most of the complexity here is associated with buffering input rows
+ * as required by the downsampler.  See the comments at the head of
+ * jcsample.c for the downsampler's needs.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* At present, jcsample.c can request context rows only for smoothing.
+ * In the future, we might also need context rows for CCIR601 sampling
+ * or other more-complex downsampling procedures.  The code to support
+ * context rows should be compiled only if needed.
+ */
+#ifdef INPUT_SMOOTHING_SUPPORTED
+#define CONTEXT_ROWS_SUPPORTED
+#endif
+
+
+/*
+ * For the simple (no-context-row) case, we just need to buffer one
+ * row group's worth of pixels for the downsampling step.  At the bottom of
+ * the image, we pad to a full row group by replicating the last pixel row.
+ * The downsampler's last output row is then replicated if needed to pad
+ * out to a full iMCU row.
+ *
+ * When providing context rows, we must buffer three row groups' worth of
+ * pixels.  Three row groups are physically allocated, but the row pointer
+ * arrays are made five row groups high, with the extra pointers above and
+ * below "wrapping around" to point to the last and first real row groups.
+ * This allows the downsampler to access the proper context rows.
+ * At the top and bottom of the image, we create dummy context rows by
+ * copying the first or last real pixel row.  This copying could be avoided
+ * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
+ * trouble on the compression side.
+ */
+
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_c_prep_controller pub; /* public fields */
+
+  /* Downsampling input buffer.  This buffer holds color-converted data
+   * until we have enough to do a downsample step.
+   */
+  JSAMPARRAY color_buf[MAX_COMPONENTS];
+
+  JDIMENSION rows_to_go;	/* counts rows remaining in source image */
+  int next_buf_row;		/* index of next row to store in color_buf */
+
+#ifdef CONTEXT_ROWS_SUPPORTED	/* only needed for context case */
+  int this_row_group;		/* starting row index of group to process */
+  int next_buf_stop;		/* downsample when we reach this index */
+#endif
+} my_prep_controller;
+
+typedef my_prep_controller * my_prep_ptr;
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+
+  if (pass_mode != JBUF_PASS_THRU)
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+  /* Initialize total-height counter for detecting bottom of image */
+  prep->rows_to_go = cinfo->image_height;
+  /* Mark the conversion buffer empty */
+  prep->next_buf_row = 0;
+#ifdef CONTEXT_ROWS_SUPPORTED
+  /* Preset additional state variables for context mode.
+   * These aren't used in non-context mode, so we needn't test which mode.
+   */
+  prep->this_row_group = 0;
+  /* Set next_buf_stop to stop after two row groups have been read in. */
+  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
+#endif
+}
+
+
+/*
+ * Expand an image vertically from height input_rows to height output_rows,
+ * by duplicating the bottom row.
+ */
+
+LOCAL(void)
+expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
+		    int input_rows, int output_rows)
+{
+  register int row;
+
+  for (row = input_rows; row < output_rows; row++) {
+    jcopy_sample_rows(image_data, input_rows-1, image_data, row,
+		      1, num_cols);
+  }
+}
+
+
+/*
+ * Process some data in the simple no-context case.
+ *
+ * Preprocessor output data is counted in "row groups".  A row group
+ * is defined to be v_samp_factor sample rows of each component.
+ * Downsampling will produce this much data from each max_v_samp_factor
+ * input rows.
+ */
+
+METHODDEF(void)
+pre_process_data (j_compress_ptr cinfo,
+		  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+		  JDIMENSION in_rows_avail,
+		  JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
+		  JDIMENSION out_row_groups_avail)
+{
+  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+  int numrows, ci;
+  JDIMENSION inrows;
+  jpeg_component_info * compptr;
+
+  while (*in_row_ctr < in_rows_avail &&
+	 *out_row_group_ctr < out_row_groups_avail) {
+    /* Do color conversion to fill the conversion buffer. */
+    inrows = in_rows_avail - *in_row_ctr;
+    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
+    numrows = (int) MIN((JDIMENSION) numrows, inrows);
+    (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
+				       prep->color_buf,
+				       (JDIMENSION) prep->next_buf_row,
+				       numrows);
+    *in_row_ctr += numrows;
+    prep->next_buf_row += numrows;
+    prep->rows_to_go -= numrows;
+    /* If at bottom of image, pad to fill the conversion buffer. */
+    if (prep->rows_to_go == 0 &&
+	prep->next_buf_row < cinfo->max_v_samp_factor) {
+      for (ci = 0; ci < cinfo->num_components; ci++) {
+	expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
+			   prep->next_buf_row, cinfo->max_v_samp_factor);
+      }
+      prep->next_buf_row = cinfo->max_v_samp_factor;
+    }
+    /* If we've filled the conversion buffer, empty it. */
+    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
+      (*cinfo->downsample->downsample) (cinfo,
+					prep->color_buf, (JDIMENSION) 0,
+					output_buf, *out_row_group_ctr);
+      prep->next_buf_row = 0;
+      (*out_row_group_ctr)++;
+    }
+    /* If at bottom of image, pad the output to a full iMCU height.
+     * Note we assume the caller is providing a one-iMCU-height output buffer!
+     */
+    if (prep->rows_to_go == 0 &&
+	*out_row_group_ctr < out_row_groups_avail) {
+      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	   ci++, compptr++) {
+	expand_bottom_edge(output_buf[ci],
+			   compptr->width_in_blocks * DCTSIZE,
+			   (int) (*out_row_group_ctr * compptr->v_samp_factor),
+			   (int) (out_row_groups_avail * compptr->v_samp_factor));
+      }
+      *out_row_group_ctr = out_row_groups_avail;
+      break;			/* can exit outer loop without test */
+    }
+  }
+}
+
+
+#ifdef CONTEXT_ROWS_SUPPORTED
+
+/*
+ * Process some data in the context case.
+ */
+
+METHODDEF(void)
+pre_process_context (j_compress_ptr cinfo,
+		     JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+		     JDIMENSION in_rows_avail,
+		     JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
+		     JDIMENSION out_row_groups_avail)
+{
+  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+  int numrows, ci;
+  int buf_height = cinfo->max_v_samp_factor * 3;
+  JDIMENSION inrows;
+
+  while (*out_row_group_ctr < out_row_groups_avail) {
+    if (*in_row_ctr < in_rows_avail) {
+      /* Do color conversion to fill the conversion buffer. */
+      inrows = in_rows_avail - *in_row_ctr;
+      numrows = prep->next_buf_stop - prep->next_buf_row;
+      numrows = (int) MIN((JDIMENSION) numrows, inrows);
+      (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
+					 prep->color_buf,
+					 (JDIMENSION) prep->next_buf_row,
+					 numrows);
+      /* Pad at top of image, if first time through */
+      if (prep->rows_to_go == cinfo->image_height) {
+	for (ci = 0; ci < cinfo->num_components; ci++) {
+	  int row;
+	  for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
+	    jcopy_sample_rows(prep->color_buf[ci], 0,
+			      prep->color_buf[ci], -row,
+			      1, cinfo->image_width);
+	  }
+	}
+      }
+      *in_row_ctr += numrows;
+      prep->next_buf_row += numrows;
+      prep->rows_to_go -= numrows;
+    } else {
+      /* Return for more data, unless we are at the bottom of the image. */
+      if (prep->rows_to_go != 0)
+	break;
+      /* When at bottom of image, pad to fill the conversion buffer. */
+      if (prep->next_buf_row < prep->next_buf_stop) {
+	for (ci = 0; ci < cinfo->num_components; ci++) {
+	  expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
+			     prep->next_buf_row, prep->next_buf_stop);
+	}
+	prep->next_buf_row = prep->next_buf_stop;
+      }
+    }
+    /* If we've gotten enough data, downsample a row group. */
+    if (prep->next_buf_row == prep->next_buf_stop) {
+      (*cinfo->downsample->downsample) (cinfo,
+					prep->color_buf,
+					(JDIMENSION) prep->this_row_group,
+					output_buf, *out_row_group_ctr);
+      (*out_row_group_ctr)++;
+      /* Advance pointers with wraparound as necessary. */
+      prep->this_row_group += cinfo->max_v_samp_factor;
+      if (prep->this_row_group >= buf_height)
+	prep->this_row_group = 0;
+      if (prep->next_buf_row >= buf_height)
+	prep->next_buf_row = 0;
+      prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
+    }
+  }
+}
+
+
+/*
+ * Create the wrapped-around downsampling input buffer needed for context mode.
+ */
+
+LOCAL(void)
+create_context_buffer (j_compress_ptr cinfo)
+{
+  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+  int rgroup_height = cinfo->max_v_samp_factor;
+  int ci, i;
+  jpeg_component_info * compptr;
+  JSAMPARRAY true_buffer, fake_buffer;
+
+  /* Grab enough space for fake row pointers for all the components;
+   * we need five row groups' worth of pointers for each component.
+   */
+  fake_buffer = (JSAMPARRAY)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(cinfo->num_components * 5 * rgroup_height) *
+				SIZEOF(JSAMPROW));
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Allocate the actual buffer space (3 row groups) for this component.
+     * We make the buffer wide enough to allow the downsampler to edge-expand
+     * horizontally within the buffer, if it so chooses.
+     */
+    true_buffer = (*cinfo->mem->alloc_sarray)
+      ((j_common_ptr) cinfo, JPOOL_IMAGE,
+       (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
+		      cinfo->max_h_samp_factor) / compptr->h_samp_factor),
+       (JDIMENSION) (3 * rgroup_height));
+    /* Copy true buffer row pointers into the middle of the fake row array */
+    MEMCOPY(fake_buffer + rgroup_height, true_buffer,
+	    3 * rgroup_height * SIZEOF(JSAMPROW));
+    /* Fill in the above and below wraparound pointers */
+    for (i = 0; i < rgroup_height; i++) {
+      fake_buffer[i] = true_buffer[2 * rgroup_height + i];
+      fake_buffer[4 * rgroup_height + i] = true_buffer[i];
+    }
+    prep->color_buf[ci] = fake_buffer + rgroup_height;
+    fake_buffer += 5 * rgroup_height; /* point to space for next component */
+  }
+}
+
+#endif /* CONTEXT_ROWS_SUPPORTED */
+
+
+/*
+ * Initialize preprocessing controller.
+ */
+
+GLOBAL(void)
+jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+  my_prep_ptr prep;
+  int ci;
+  jpeg_component_info * compptr;
+
+  if (need_full_buffer)		/* safety check */
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+  prep = (my_prep_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_prep_controller));
+  cinfo->prep = (struct jpeg_c_prep_controller *) prep;
+  prep->pub.start_pass = start_pass_prep;
+
+  /* Allocate the color conversion buffer.
+   * We make the buffer wide enough to allow the downsampler to edge-expand
+   * horizontally within the buffer, if it so chooses.
+   */
+  if (cinfo->downsample->need_context_rows) {
+    /* Set up to provide context rows */
+#ifdef CONTEXT_ROWS_SUPPORTED
+    prep->pub.pre_process_data = pre_process_context;
+    create_context_buffer(cinfo);
+#else
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+  } else {
+    /* No context, just make it tall enough for one row group */
+    prep->pub.pre_process_data = pre_process_data;
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE,
+	 (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
+			cinfo->max_h_samp_factor) / compptr->h_samp_factor),
+	 (JDIMENSION) cinfo->max_v_samp_factor);
+    }
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jcsample.c b/Utilities/FLTK/jpeg/jcsample.c
new file mode 100644
index 0000000000000000000000000000000000000000..212ec8757c4ca865eba34a80530d42e8d371dec7
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jcsample.c
@@ -0,0 +1,519 @@
+/*
+ * jcsample.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains downsampling routines.
+ *
+ * Downsampling input data is counted in "row groups".  A row group
+ * is defined to be max_v_samp_factor pixel rows of each component,
+ * from which the downsampler produces v_samp_factor sample rows.
+ * A single row group is processed in each call to the downsampler module.
+ *
+ * The downsampler is responsible for edge-expansion of its output data
+ * to fill an integral number of DCT blocks horizontally.  The source buffer
+ * may be modified if it is helpful for this purpose (the source buffer is
+ * allocated wide enough to correspond to the desired output width).
+ * The caller (the prep controller) is responsible for vertical padding.
+ *
+ * The downsampler may request "context rows" by setting need_context_rows
+ * during startup.  In this case, the input arrays will contain at least
+ * one row group's worth of pixels above and below the passed-in data;
+ * the caller will create dummy rows at image top and bottom by replicating
+ * the first or last real pixel row.
+ *
+ * An excellent reference for image resampling is
+ *   Digital Image Warping, George Wolberg, 1990.
+ *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
+ *
+ * The downsampling algorithm used here is a simple average of the source
+ * pixels covered by the output pixel.  The hi-falutin sampling literature
+ * refers to this as a "box filter".  In general the characteristics of a box
+ * filter are not very good, but for the specific cases we normally use (1:1
+ * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not
+ * nearly so bad.  If you intend to use other sampling ratios, you'd be well
+ * advised to improve this code.
+ *
+ * A simple input-smoothing capability is provided.  This is mainly intended
+ * for cleaning up color-dithered GIF input files (if you find it inadequate,
+ * we suggest using an external filtering program such as pnmconvol).  When
+ * enabled, each input pixel P is replaced by a weighted sum of itself and its
+ * eight neighbors.  P's weight is 1-8*SF and each neighbor's weight is SF,
+ * where SF = (smoothing_factor / 1024).
+ * Currently, smoothing is only supported for 2h2v sampling factors.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Pointer to routine to downsample a single component */
+typedef JMETHOD(void, downsample1_ptr,
+		(j_compress_ptr cinfo, jpeg_component_info * compptr,
+		 JSAMPARRAY input_data, JSAMPARRAY output_data));
+
+/* Private subobject */
+
+typedef struct {
+  struct jpeg_downsampler pub;	/* public fields */
+
+  /* Downsampling method pointers, one per component */
+  downsample1_ptr methods[MAX_COMPONENTS];
+} my_downsampler;
+
+typedef my_downsampler * my_downsample_ptr;
+
+
+/*
+ * Initialize for a downsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_downsample (j_compress_ptr cinfo)
+{
+  /* no work for now */
+}
+
+
+/*
+ * Expand a component horizontally from width input_cols to width output_cols,
+ * by duplicating the rightmost samples.
+ */
+
+LOCAL(void)
+expand_right_edge (JSAMPARRAY image_data, int num_rows,
+		   JDIMENSION input_cols, JDIMENSION output_cols)
+{
+  register JSAMPROW ptr;
+  register JSAMPLE pixval;
+  register int count;
+  int row;
+  int numcols = (int) (output_cols - input_cols);
+
+  if (numcols > 0) {
+    for (row = 0; row < num_rows; row++) {
+      ptr = image_data[row] + input_cols;
+      pixval = ptr[-1];		/* don't need GETJSAMPLE() here */
+      for (count = numcols; count > 0; count--)
+	*ptr++ = pixval;
+    }
+  }
+}
+
+
+/*
+ * Do downsampling for a whole row group (all components).
+ *
+ * In this version we simply downsample each component independently.
+ */
+
+METHODDEF(void)
+sep_downsample (j_compress_ptr cinfo,
+		JSAMPIMAGE input_buf, JDIMENSION in_row_index,
+		JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
+{
+  my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
+  int ci;
+  jpeg_component_info * compptr;
+  JSAMPARRAY in_ptr, out_ptr;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    in_ptr = input_buf[ci] + in_row_index;
+    out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
+    (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
+  }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * One row group is processed per call.
+ * This version handles arbitrary integral sampling ratios, without smoothing.
+ * Note that this version is not actually used for customary sampling ratios.
+ */
+
+METHODDEF(void)
+int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+		JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
+  JDIMENSION outcol, outcol_h;	/* outcol_h == outcol*h_expand */
+  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+  JSAMPROW inptr, outptr;
+  INT32 outvalue;
+
+  h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
+  v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
+  numpix = h_expand * v_expand;
+  numpix2 = numpix/2;
+
+  /* Expand input data enough to let all the output samples be generated
+   * by the standard loop.  Special-casing padded output would be more
+   * efficient.
+   */
+  expand_right_edge(input_data, cinfo->max_v_samp_factor,
+		    cinfo->image_width, output_cols * h_expand);
+
+  inrow = 0;
+  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+    outptr = output_data[outrow];
+    for (outcol = 0, outcol_h = 0; outcol < output_cols;
+	 outcol++, outcol_h += h_expand) {
+      outvalue = 0;
+      for (v = 0; v < v_expand; v++) {
+	inptr = input_data[inrow+v] + outcol_h;
+	for (h = 0; h < h_expand; h++) {
+	  outvalue += (INT32) GETJSAMPLE(*inptr++);
+	}
+      }
+      *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
+    }
+    inrow += v_expand;
+  }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the special case of a full-size component,
+ * without smoothing.
+ */
+
+METHODDEF(void)
+fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+		     JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  /* Copy the data */
+  jcopy_sample_rows(input_data, 0, output_data, 0,
+		    cinfo->max_v_samp_factor, cinfo->image_width);
+  /* Edge-expand */
+  expand_right_edge(output_data, cinfo->max_v_samp_factor,
+		    cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the common case of 2:1 horizontal and 1:1 vertical,
+ * without smoothing.
+ *
+ * A note about the "bias" calculations: when rounding fractional values to
+ * integer, we do not want to always round 0.5 up to the next integer.
+ * If we did that, we'd introduce a noticeable bias towards larger values.
+ * Instead, this code is arranged so that 0.5 will be rounded up or down at
+ * alternate pixel locations (a simple ordered dither pattern).
+ */
+
+METHODDEF(void)
+h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+		 JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  int outrow;
+  JDIMENSION outcol;
+  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+  register JSAMPROW inptr, outptr;
+  register int bias;
+
+  /* Expand input data enough to let all the output samples be generated
+   * by the standard loop.  Special-casing padded output would be more
+   * efficient.
+   */
+  expand_right_edge(input_data, cinfo->max_v_samp_factor,
+		    cinfo->image_width, output_cols * 2);
+
+  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+    outptr = output_data[outrow];
+    inptr = input_data[outrow];
+    bias = 0;			/* bias = 0,1,0,1,... for successive samples */
+    for (outcol = 0; outcol < output_cols; outcol++) {
+      *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
+			      + bias) >> 1);
+      bias ^= 1;		/* 0=>1, 1=>0 */
+      inptr += 2;
+    }
+  }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
+ * without smoothing.
+ */
+
+METHODDEF(void)
+h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+		 JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  int inrow, outrow;
+  JDIMENSION outcol;
+  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+  register JSAMPROW inptr0, inptr1, outptr;
+  register int bias;
+
+  /* Expand input data enough to let all the output samples be generated
+   * by the standard loop.  Special-casing padded output would be more
+   * efficient.
+   */
+  expand_right_edge(input_data, cinfo->max_v_samp_factor,
+		    cinfo->image_width, output_cols * 2);
+
+  inrow = 0;
+  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+    outptr = output_data[outrow];
+    inptr0 = input_data[inrow];
+    inptr1 = input_data[inrow+1];
+    bias = 1;			/* bias = 1,2,1,2,... for successive samples */
+    for (outcol = 0; outcol < output_cols; outcol++) {
+      *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+			      GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])
+			      + bias) >> 2);
+      bias ^= 3;		/* 1=>2, 2=>1 */
+      inptr0 += 2; inptr1 += 2;
+    }
+    inrow += 2;
+  }
+}
+
+
+#ifdef INPUT_SMOOTHING_SUPPORTED
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
+ * with smoothing.  One row of context is required.
+ */
+
+METHODDEF(void)
+h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+			JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  int inrow, outrow;
+  JDIMENSION colctr;
+  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+  register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
+  INT32 membersum, neighsum, memberscale, neighscale;
+
+  /* Expand input data enough to let all the output samples be generated
+   * by the standard loop.  Special-casing padded output would be more
+   * efficient.
+   */
+  expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
+		    cinfo->image_width, output_cols * 2);
+
+  /* We don't bother to form the individual "smoothed" input pixel values;
+   * we can directly compute the output which is the average of the four
+   * smoothed values.  Each of the four member pixels contributes a fraction
+   * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
+   * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
+   * output.  The four corner-adjacent neighbor pixels contribute a fraction
+   * SF to just one smoothed pixel, or SF/4 to the final output; while the
+   * eight edge-adjacent neighbors contribute SF to each of two smoothed
+   * pixels, or SF/2 overall.  In order to use integer arithmetic, these
+   * factors are scaled by 2^16 = 65536.
+   * Also recall that SF = smoothing_factor / 1024.
+   */
+
+  memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
+  neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
+
+  inrow = 0;
+  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+    outptr = output_data[outrow];
+    inptr0 = input_data[inrow];
+    inptr1 = input_data[inrow+1];
+    above_ptr = input_data[inrow-1];
+    below_ptr = input_data[inrow+2];
+
+    /* Special case for first column: pretend column -1 is same as column 0 */
+    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+	       GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
+	       GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
+    neighsum += neighsum;
+    neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
+		GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
+    membersum = membersum * memberscale + neighsum * neighscale;
+    *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+    inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
+
+    for (colctr = output_cols - 2; colctr > 0; colctr--) {
+      /* sum of pixels directly mapped to this output element */
+      membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+		  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+      /* sum of edge-neighbor pixels */
+      neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+		 GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+		 GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
+		 GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
+      /* The edge-neighbors count twice as much as corner-neighbors */
+      neighsum += neighsum;
+      /* Add in the corner-neighbors */
+      neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
+		  GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
+      /* form final output scaled up by 2^16 */
+      membersum = membersum * memberscale + neighsum * neighscale;
+      /* round, descale and output it */
+      *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+      inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
+    }
+
+    /* Special case for last column */
+    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+	       GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
+	       GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
+    neighsum += neighsum;
+    neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
+		GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
+    membersum = membersum * memberscale + neighsum * neighscale;
+    *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
+
+    inrow += 2;
+  }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the special case of a full-size component,
+ * with smoothing.  One row of context is required.
+ */
+
+METHODDEF(void)
+fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
+			    JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  int outrow;
+  JDIMENSION colctr;
+  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+  register JSAMPROW inptr, above_ptr, below_ptr, outptr;
+  INT32 membersum, neighsum, memberscale, neighscale;
+  int colsum, lastcolsum, nextcolsum;
+
+  /* Expand input data enough to let all the output samples be generated
+   * by the standard loop.  Special-casing padded output would be more
+   * efficient.
+   */
+  expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
+		    cinfo->image_width, output_cols);
+
+  /* Each of the eight neighbor pixels contributes a fraction SF to the
+   * smoothed pixel, while the main pixel contributes (1-8*SF).  In order
+   * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
+   * Also recall that SF = smoothing_factor / 1024.
+   */
+
+  memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
+  neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
+
+  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+    outptr = output_data[outrow];
+    inptr = input_data[outrow];
+    above_ptr = input_data[outrow-1];
+    below_ptr = input_data[outrow+1];
+
+    /* Special case for first column */
+    colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
+	     GETJSAMPLE(*inptr);
+    membersum = GETJSAMPLE(*inptr++);
+    nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
+		 GETJSAMPLE(*inptr);
+    neighsum = colsum + (colsum - membersum) + nextcolsum;
+    membersum = membersum * memberscale + neighsum * neighscale;
+    *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+    lastcolsum = colsum; colsum = nextcolsum;
+
+    for (colctr = output_cols - 2; colctr > 0; colctr--) {
+      membersum = GETJSAMPLE(*inptr++);
+      above_ptr++; below_ptr++;
+      nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
+		   GETJSAMPLE(*inptr);
+      neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
+      membersum = membersum * memberscale + neighsum * neighscale;
+      *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+      lastcolsum = colsum; colsum = nextcolsum;
+    }
+
+    /* Special case for last column */
+    membersum = GETJSAMPLE(*inptr);
+    neighsum = lastcolsum + (colsum - membersum) + colsum;
+    membersum = membersum * memberscale + neighsum * neighscale;
+    *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
+
+  }
+}
+
+#endif /* INPUT_SMOOTHING_SUPPORTED */
+
+
+/*
+ * Module initialization routine for downsampling.
+ * Note that we must select a routine for each component.
+ */
+
+GLOBAL(void)
+jinit_downsampler (j_compress_ptr cinfo)
+{
+  my_downsample_ptr downsample;
+  int ci;
+  jpeg_component_info * compptr;
+  boolean smoothok = TRUE;
+
+  downsample = (my_downsample_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_downsampler));
+  cinfo->downsample = (struct jpeg_downsampler *) downsample;
+  downsample->pub.start_pass = start_pass_downsample;
+  downsample->pub.downsample = sep_downsample;
+  downsample->pub.need_context_rows = FALSE;
+
+  if (cinfo->CCIR601_sampling)
+    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
+
+  /* Verify we can handle the sampling factors, and set up method pointers */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
+	compptr->v_samp_factor == cinfo->max_v_samp_factor) {
+#ifdef INPUT_SMOOTHING_SUPPORTED
+      if (cinfo->smoothing_factor) {
+	downsample->methods[ci] = fullsize_smooth_downsample;
+	downsample->pub.need_context_rows = TRUE;
+      } else
+#endif
+	downsample->methods[ci] = fullsize_downsample;
+    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
+	       compptr->v_samp_factor == cinfo->max_v_samp_factor) {
+      smoothok = FALSE;
+      downsample->methods[ci] = h2v1_downsample;
+    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
+	       compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
+#ifdef INPUT_SMOOTHING_SUPPORTED
+      if (cinfo->smoothing_factor) {
+	downsample->methods[ci] = h2v2_smooth_downsample;
+	downsample->pub.need_context_rows = TRUE;
+      } else
+#endif
+	downsample->methods[ci] = h2v2_downsample;
+    } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
+	       (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
+      smoothok = FALSE;
+      downsample->methods[ci] = int_downsample;
+    } else
+      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
+  }
+
+#ifdef INPUT_SMOOTHING_SUPPORTED
+  if (cinfo->smoothing_factor && !smoothok)
+    TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
+#endif
+}
diff --git a/Utilities/FLTK/jpeg/jctrans.c b/Utilities/FLTK/jpeg/jctrans.c
new file mode 100644
index 0000000000000000000000000000000000000000..0e6d70769df543d84cd5a2bec154443648e5c61a
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jctrans.c
@@ -0,0 +1,388 @@
+/*
+ * jctrans.c
+ *
+ * Copyright (C) 1995-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains library routines for transcoding compression,
+ * that is, writing raw DCT coefficient arrays to an output JPEG file.
+ * The routines in jcapimin.c will also be needed by a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(void) transencode_master_selection
+	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+LOCAL(void) transencode_coef_controller
+	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+
+
+/*
+ * Compression initialization for writing raw-coefficient data.
+ * Before calling this, all parameters and a data destination must be set up.
+ * Call jpeg_finish_compress() to actually write the data.
+ *
+ * The number of passed virtual arrays must match cinfo->num_components.
+ * Note that the virtual arrays need not be filled or even realized at
+ * the time write_coefficients is called; indeed, if the virtual arrays
+ * were requested from this compression object's memory manager, they
+ * typically will be realized during this routine and filled afterwards.
+ */
+
+GLOBAL(void)
+jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
+{
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  /* Mark all tables to be written */
+  jpeg_suppress_tables(cinfo, FALSE);
+  /* (Re)initialize error mgr and destination modules */
+  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+  (*cinfo->dest->init_destination) (cinfo);
+  /* Perform master selection of active modules */
+  transencode_master_selection(cinfo, coef_arrays);
+  /* Wait for jpeg_finish_compress() call */
+  cinfo->next_scanline = 0;	/* so jpeg_write_marker works */
+  cinfo->global_state = CSTATE_WRCOEFS;
+}
+
+
+/*
+ * Initialize the compression object with default parameters,
+ * then copy from the source object all parameters needed for lossless
+ * transcoding.  Parameters that can be varied without loss (such as
+ * scan script and Huffman optimization) are left in their default states.
+ */
+
+GLOBAL(void)
+jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
+			       j_compress_ptr dstinfo)
+{
+  JQUANT_TBL ** qtblptr;
+  jpeg_component_info *incomp, *outcomp;
+  JQUANT_TBL *c_quant, *slot_quant;
+  int tblno, ci, coefi;
+
+  /* Safety check to ensure start_compress not called yet. */
+  if (dstinfo->global_state != CSTATE_START)
+    ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
+  /* Copy fundamental image dimensions */
+  dstinfo->image_width = srcinfo->image_width;
+  dstinfo->image_height = srcinfo->image_height;
+  dstinfo->input_components = srcinfo->num_components;
+  dstinfo->in_color_space = srcinfo->jpeg_color_space;
+  /* Initialize all parameters to default values */
+  jpeg_set_defaults(dstinfo);
+  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
+   * Fix it to get the right header markers for the image colorspace.
+   */
+  jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
+  dstinfo->data_precision = srcinfo->data_precision;
+  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
+  /* Copy the source's quantization tables. */
+  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
+    if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
+      qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
+      if (*qtblptr == NULL)
+	*qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
+      MEMCOPY((*qtblptr)->quantval,
+	      srcinfo->quant_tbl_ptrs[tblno]->quantval,
+	      SIZEOF((*qtblptr)->quantval));
+      (*qtblptr)->sent_table = FALSE;
+    }
+  }
+  /* Copy the source's per-component info.
+   * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
+   */
+  dstinfo->num_components = srcinfo->num_components;
+  if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
+    ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
+	     MAX_COMPONENTS);
+  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
+       ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
+    outcomp->component_id = incomp->component_id;
+    outcomp->h_samp_factor = incomp->h_samp_factor;
+    outcomp->v_samp_factor = incomp->v_samp_factor;
+    outcomp->quant_tbl_no = incomp->quant_tbl_no;
+    /* Make sure saved quantization table for component matches the qtable
+     * slot.  If not, the input file re-used this qtable slot.
+     * IJG encoder currently cannot duplicate this.
+     */
+    tblno = outcomp->quant_tbl_no;
+    if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
+	srcinfo->quant_tbl_ptrs[tblno] == NULL)
+      ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
+    slot_quant = srcinfo->quant_tbl_ptrs[tblno];
+    c_quant = incomp->quant_table;
+    if (c_quant != NULL) {
+      for (coefi = 0; coefi < DCTSIZE2; coefi++) {
+	if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
+	  ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
+      }
+    }
+    /* Note: we do not copy the source's Huffman table assignments;
+     * instead we rely on jpeg_set_colorspace to have made a suitable choice.
+     */
+  }
+  /* Also copy JFIF version and resolution information, if available.
+   * Strictly speaking this isn't "critical" info, but it's nearly
+   * always appropriate to copy it if available.  In particular,
+   * if the application chooses to copy JFIF 1.02 extension markers from
+   * the source file, we need to copy the version to make sure we don't
+   * emit a file that has 1.02 extensions but a claimed version of 1.01.
+   * We will *not*, however, copy version info from mislabeled "2.01" files.
+   */
+  if (srcinfo->saw_JFIF_marker) {
+    if (srcinfo->JFIF_major_version == 1) {
+      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
+      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
+    }
+    dstinfo->density_unit = srcinfo->density_unit;
+    dstinfo->X_density = srcinfo->X_density;
+    dstinfo->Y_density = srcinfo->Y_density;
+  }
+}
+
+
+/*
+ * Master selection of compression modules for transcoding.
+ * This substitutes for jcinit.c's initialization of the full compressor.
+ */
+
+LOCAL(void)
+transencode_master_selection (j_compress_ptr cinfo,
+			      jvirt_barray_ptr * coef_arrays)
+{
+  /* Although we don't actually use input_components for transcoding,
+   * jcmaster.c's initial_setup will complain if input_components is 0.
+   */
+  cinfo->input_components = 1;
+  /* Initialize master control (includes parameter checking/processing) */
+  jinit_c_master_control(cinfo, TRUE /* transcode only */);
+
+  /* Entropy encoding: either Huffman or arithmetic coding. */
+  if (cinfo->arith_code) {
+    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+  } else {
+    if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+      jinit_phuff_encoder(cinfo);
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    } else
+      jinit_huff_encoder(cinfo);
+  }
+
+  /* We need a special coefficient buffer controller. */
+  transencode_coef_controller(cinfo, coef_arrays);
+
+  jinit_marker_writer(cinfo);
+
+  /* We can now tell the memory manager to allocate virtual arrays. */
+  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+  /* Write the datastream header (SOI, JFIF) immediately.
+   * Frame and scan headers are postponed till later.
+   * This lets application insert special markers after the SOI.
+   */
+  (*cinfo->marker->write_file_header) (cinfo);
+}
+
+
+/*
+ * The rest of this file is a special implementation of the coefficient
+ * buffer controller.  This is similar to jccoefct.c, but it handles only
+ * output from presupplied virtual arrays.  Furthermore, we generate any
+ * dummy padding blocks on-the-fly rather than expecting them to be present
+ * in the arrays.
+ */
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_c_coef_controller pub; /* public fields */
+
+  JDIMENSION iMCU_row_num;	/* iMCU row # within image */
+  JDIMENSION mcu_ctr;		/* counts MCUs processed in current row */
+  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
+  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
+
+  /* Virtual block array for each component. */
+  jvirt_barray_ptr * whole_image;
+
+  /* Workspace for constructing dummy blocks at right/bottom edges. */
+  JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+
+LOCAL(void)
+start_iMCU_row (j_compress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row */
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  /* In an interleaved scan, an MCU row is the same as an iMCU row.
+   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+   * But at the bottom of the image, process only what's left.
+   */
+  if (cinfo->comps_in_scan > 1) {
+    coef->MCU_rows_per_iMCU_row = 1;
+  } else {
+    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+    else
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+  }
+
+  coef->mcu_ctr = 0;
+  coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  if (pass_mode != JBUF_CRANK_DEST)
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+  coef->iMCU_row_num = 0;
+  start_iMCU_row(cinfo);
+}
+
+
+/*
+ * Process some data.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the scan.
+ * The data is obtained from the virtual arrays and fed to the entropy coder.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf is ignored; it is likely to be a NULL pointer.
+ */
+
+METHODDEF(boolean)
+compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION MCU_col_num;	/* index of current MCU within row */
+  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+  int blkn, ci, xindex, yindex, yoffset, blockcnt;
+  JDIMENSION start_col;
+  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
+  JBLOCKROW buffer_ptr;
+  jpeg_component_info *compptr;
+
+  /* Align the virtual buffers for the components used in this scan. */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    buffer[ci] = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+       coef->iMCU_row_num * compptr->v_samp_factor,
+       (JDIMENSION) compptr->v_samp_factor, FALSE);
+  }
+
+  /* Loop to process one whole iMCU row */
+  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+       yoffset++) {
+    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
+	 MCU_col_num++) {
+      /* Construct list of pointers to DCT blocks belonging to this MCU */
+      blkn = 0;			/* index of current DCT block within MCU */
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+	compptr = cinfo->cur_comp_info[ci];
+	start_col = MCU_col_num * compptr->MCU_width;
+	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+						: compptr->last_col_width;
+	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+	  if (coef->iMCU_row_num < last_iMCU_row ||
+	      yindex+yoffset < compptr->last_row_height) {
+	    /* Fill in pointers to real blocks in this row */
+	    buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+	    for (xindex = 0; xindex < blockcnt; xindex++)
+	      MCU_buffer[blkn++] = buffer_ptr++;
+	  } else {
+	    /* At bottom of image, need a whole row of dummy blocks */
+	    xindex = 0;
+	  }
+	  /* Fill in any dummy blocks needed in this row.
+	   * Dummy blocks are filled in the same way as in jccoefct.c:
+	   * all zeroes in the AC entries, DC entries equal to previous
+	   * block's DC value.  The init routine has already zeroed the
+	   * AC entries, so we need only set the DC entries correctly.
+	   */
+	  for (; xindex < compptr->MCU_width; xindex++) {
+	    MCU_buffer[blkn] = coef->dummy_buffer[blkn];
+	    MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
+	    blkn++;
+	  }
+	}
+      }
+      /* Try to write the MCU. */
+      if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
+	/* Suspension forced; update state counters and exit */
+	coef->MCU_vert_offset = yoffset;
+	coef->mcu_ctr = MCU_col_num;
+	return FALSE;
+      }
+    }
+    /* Completed an MCU row, but perhaps not an iMCU row */
+    coef->mcu_ctr = 0;
+  }
+  /* Completed the iMCU row, advance counters for next one */
+  coef->iMCU_row_num++;
+  start_iMCU_row(cinfo);
+  return TRUE;
+}
+
+
+/*
+ * Initialize coefficient buffer controller.
+ *
+ * Each passed coefficient array must be the right size for that
+ * coefficient: width_in_blocks wide and height_in_blocks high,
+ * with unitheight at least v_samp_factor.
+ */
+
+LOCAL(void)
+transencode_coef_controller (j_compress_ptr cinfo,
+			     jvirt_barray_ptr * coef_arrays)
+{
+  my_coef_ptr coef;
+  JBLOCKROW buffer;
+  int i;
+
+  coef = (my_coef_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_coef_controller));
+  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+  coef->pub.start_pass = start_pass_coef;
+  coef->pub.compress_data = compress_output;
+
+  /* Save pointer to virtual arrays */
+  coef->whole_image = coef_arrays;
+
+  /* Allocate and pre-zero space for dummy DCT blocks. */
+  buffer = (JBLOCKROW)
+    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+  jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
+    coef->dummy_buffer[i] = buffer + i;
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jdapimin.c b/Utilities/FLTK/jpeg/jdapimin.c
new file mode 100644
index 0000000000000000000000000000000000000000..cadb59fce3aa1cc239e86c592774cc500e109613
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdapimin.c
@@ -0,0 +1,395 @@
+/*
+ * jdapimin.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the decompression half
+ * of the JPEG library.  These are the "minimum" API routines that may be
+ * needed in either the normal full-decompression case or the
+ * transcoding-only case.
+ *
+ * Most of the routines intended to be called directly by an application
+ * are in this file or in jdapistd.c.  But also see jcomapi.c for routines
+ * shared by compression and decompression, and jdtrans.c for the transcoding
+ * case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Initialization of a JPEG decompression object.
+ * The error manager must already be set up (in case memory manager fails).
+ */
+
+GLOBAL(void)
+jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
+{
+  int i;
+
+  /* Guard against version mismatches between library and caller. */
+  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
+  if (version != JPEG_LIB_VERSION)
+    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
+  if (structsize != SIZEOF(struct jpeg_decompress_struct))
+    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
+	     (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
+
+  /* For debugging purposes, we zero the whole master structure.
+   * But the application has already set the err pointer, and may have set
+   * client_data, so we have to save and restore those fields.
+   * Note: if application hasn't set client_data, tools like Purify may
+   * complain here.
+   */
+  {
+    struct jpeg_error_mgr * err = cinfo->err;
+    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
+    MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
+    cinfo->err = err;
+    cinfo->client_data = client_data;
+  }
+  cinfo->is_decompressor = TRUE;
+
+  /* Initialize a memory manager instance for this object */
+  jinit_memory_mgr((j_common_ptr) cinfo);
+
+  /* Zero out pointers to permanent structures. */
+  cinfo->progress = NULL;
+  cinfo->src = NULL;
+
+  for (i = 0; i < NUM_QUANT_TBLS; i++)
+    cinfo->quant_tbl_ptrs[i] = NULL;
+
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    cinfo->dc_huff_tbl_ptrs[i] = NULL;
+    cinfo->ac_huff_tbl_ptrs[i] = NULL;
+  }
+
+  /* Initialize marker processor so application can override methods
+   * for COM, APPn markers before calling jpeg_read_header.
+   */
+  cinfo->marker_list = NULL;
+  jinit_marker_reader(cinfo);
+
+  /* And initialize the overall input controller. */
+  jinit_input_controller(cinfo);
+
+  /* OK, I'm ready */
+  cinfo->global_state = DSTATE_START;
+}
+
+
+/*
+ * Destruction of a JPEG decompression object
+ */
+
+GLOBAL(void)
+jpeg_destroy_decompress (j_decompress_ptr cinfo)
+{
+  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Abort processing of a JPEG decompression operation,
+ * but don't destroy the object itself.
+ */
+
+GLOBAL(void)
+jpeg_abort_decompress (j_decompress_ptr cinfo)
+{
+  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Set default decompression parameters.
+ */
+
+LOCAL(void)
+default_decompress_parms (j_decompress_ptr cinfo)
+{
+  /* Guess the input colorspace, and set output colorspace accordingly. */
+  /* (Wish JPEG committee had provided a real way to specify this...) */
+  /* Note application may override our guesses. */
+  switch (cinfo->num_components) {
+  case 1:
+    cinfo->jpeg_color_space = JCS_GRAYSCALE;
+    cinfo->out_color_space = JCS_GRAYSCALE;
+    break;
+    
+  case 3:
+    if (cinfo->saw_JFIF_marker) {
+      cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
+    } else if (cinfo->saw_Adobe_marker) {
+      switch (cinfo->Adobe_transform) {
+      case 0:
+	cinfo->jpeg_color_space = JCS_RGB;
+	break;
+      case 1:
+	cinfo->jpeg_color_space = JCS_YCbCr;
+	break;
+      default:
+	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
+	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
+	break;
+      }
+    } else {
+      /* Saw no special markers, try to guess from the component IDs */
+      int cid0 = cinfo->comp_info[0].component_id;
+      int cid1 = cinfo->comp_info[1].component_id;
+      int cid2 = cinfo->comp_info[2].component_id;
+
+      if (cid0 == 1 && cid1 == 2 && cid2 == 3)
+	cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
+      else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
+	cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
+      else {
+	TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
+	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
+      }
+    }
+    /* Always guess RGB is proper output colorspace. */
+    cinfo->out_color_space = JCS_RGB;
+    break;
+    
+  case 4:
+    if (cinfo->saw_Adobe_marker) {
+      switch (cinfo->Adobe_transform) {
+      case 0:
+	cinfo->jpeg_color_space = JCS_CMYK;
+	break;
+      case 2:
+	cinfo->jpeg_color_space = JCS_YCCK;
+	break;
+      default:
+	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
+	cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
+	break;
+      }
+    } else {
+      /* No special markers, assume straight CMYK. */
+      cinfo->jpeg_color_space = JCS_CMYK;
+    }
+    cinfo->out_color_space = JCS_CMYK;
+    break;
+    
+  default:
+    cinfo->jpeg_color_space = JCS_UNKNOWN;
+    cinfo->out_color_space = JCS_UNKNOWN;
+    break;
+  }
+
+  /* Set defaults for other decompression parameters. */
+  cinfo->scale_num = 1;		/* 1:1 scaling */
+  cinfo->scale_denom = 1;
+  cinfo->output_gamma = 1.0;
+  cinfo->buffered_image = FALSE;
+  cinfo->raw_data_out = FALSE;
+  cinfo->dct_method = JDCT_DEFAULT;
+  cinfo->do_fancy_upsampling = TRUE;
+  cinfo->do_block_smoothing = TRUE;
+  cinfo->quantize_colors = FALSE;
+  /* We set these in case application only sets quantize_colors. */
+  cinfo->dither_mode = JDITHER_FS;
+#ifdef QUANT_2PASS_SUPPORTED
+  cinfo->two_pass_quantize = TRUE;
+#else
+  cinfo->two_pass_quantize = FALSE;
+#endif
+  cinfo->desired_number_of_colors = 256;
+  cinfo->colormap = NULL;
+  /* Initialize for no mode change in buffered-image mode. */
+  cinfo->enable_1pass_quant = FALSE;
+  cinfo->enable_external_quant = FALSE;
+  cinfo->enable_2pass_quant = FALSE;
+}
+
+
+/*
+ * Decompression startup: read start of JPEG datastream to see what's there.
+ * Need only initialize JPEG object and supply a data source before calling.
+ *
+ * This routine will read as far as the first SOS marker (ie, actual start of
+ * compressed data), and will save all tables and parameters in the JPEG
+ * object.  It will also initialize the decompression parameters to default
+ * values, and finally return JPEG_HEADER_OK.  On return, the application may
+ * adjust the decompression parameters and then call jpeg_start_decompress.
+ * (Or, if the application only wanted to determine the image parameters,
+ * the data need not be decompressed.  In that case, call jpeg_abort or
+ * jpeg_destroy to release any temporary space.)
+ * If an abbreviated (tables only) datastream is presented, the routine will
+ * return JPEG_HEADER_TABLES_ONLY upon reaching EOI.  The application may then
+ * re-use the JPEG object to read the abbreviated image datastream(s).
+ * It is unnecessary (but OK) to call jpeg_abort in this case.
+ * The JPEG_SUSPENDED return code only occurs if the data source module
+ * requests suspension of the decompressor.  In this case the application
+ * should load more source data and then re-call jpeg_read_header to resume
+ * processing.
+ * If a non-suspending data source is used and require_image is TRUE, then the
+ * return code need not be inspected since only JPEG_HEADER_OK is possible.
+ *
+ * This routine is now just a front end to jpeg_consume_input, with some
+ * extra error checking.
+ */
+
+GLOBAL(int)
+jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
+{
+  int retcode;
+
+  if (cinfo->global_state != DSTATE_START &&
+      cinfo->global_state != DSTATE_INHEADER)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  retcode = jpeg_consume_input(cinfo);
+
+  switch (retcode) {
+  case JPEG_REACHED_SOS:
+    retcode = JPEG_HEADER_OK;
+    break;
+  case JPEG_REACHED_EOI:
+    if (require_image)		/* Complain if application wanted an image */
+      ERREXIT(cinfo, JERR_NO_IMAGE);
+    /* Reset to start state; it would be safer to require the application to
+     * call jpeg_abort, but we can't change it now for compatibility reasons.
+     * A side effect is to free any temporary memory (there shouldn't be any).
+     */
+    jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
+    retcode = JPEG_HEADER_TABLES_ONLY;
+    break;
+  case JPEG_SUSPENDED:
+    /* no work */
+    break;
+  }
+
+  return retcode;
+}
+
+
+/*
+ * Consume data in advance of what the decompressor requires.
+ * This can be called at any time once the decompressor object has
+ * been created and a data source has been set up.
+ *
+ * This routine is essentially a state machine that handles a couple
+ * of critical state-transition actions, namely initial setup and
+ * transition from header scanning to ready-for-start_decompress.
+ * All the actual input is done via the input controller's consume_input
+ * method.
+ */
+
+GLOBAL(int)
+jpeg_consume_input (j_decompress_ptr cinfo)
+{
+  int retcode = JPEG_SUSPENDED;
+
+  /* NB: every possible DSTATE value should be listed in this switch */
+  switch (cinfo->global_state) {
+  case DSTATE_START:
+    /* Start-of-datastream actions: reset appropriate modules */
+    (*cinfo->inputctl->reset_input_controller) (cinfo);
+    /* Initialize application's data source module */
+    (*cinfo->src->init_source) (cinfo);
+    cinfo->global_state = DSTATE_INHEADER;
+    /*FALLTHROUGH*/
+  case DSTATE_INHEADER:
+    retcode = (*cinfo->inputctl->consume_input) (cinfo);
+    if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
+      /* Set up default parameters based on header data */
+      default_decompress_parms(cinfo);
+      /* Set global state: ready for start_decompress */
+      cinfo->global_state = DSTATE_READY;
+    }
+    break;
+  case DSTATE_READY:
+    /* Can't advance past first SOS until start_decompress is called */
+    retcode = JPEG_REACHED_SOS;
+    break;
+  case DSTATE_PRELOAD:
+  case DSTATE_PRESCAN:
+  case DSTATE_SCANNING:
+  case DSTATE_RAW_OK:
+  case DSTATE_BUFIMAGE:
+  case DSTATE_BUFPOST:
+  case DSTATE_STOPPING:
+    retcode = (*cinfo->inputctl->consume_input) (cinfo);
+    break;
+  default:
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  }
+  return retcode;
+}
+
+
+/*
+ * Have we finished reading the input file?
+ */
+
+GLOBAL(boolean)
+jpeg_input_complete (j_decompress_ptr cinfo)
+{
+  /* Check for valid jpeg object */
+  if (cinfo->global_state < DSTATE_START ||
+      cinfo->global_state > DSTATE_STOPPING)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  return cinfo->inputctl->eoi_reached;
+}
+
+
+/*
+ * Is there more than one scan?
+ */
+
+GLOBAL(boolean)
+jpeg_has_multiple_scans (j_decompress_ptr cinfo)
+{
+  /* Only valid after jpeg_read_header completes */
+  if (cinfo->global_state < DSTATE_READY ||
+      cinfo->global_state > DSTATE_STOPPING)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  return cinfo->inputctl->has_multiple_scans;
+}
+
+
+/*
+ * Finish JPEG decompression.
+ *
+ * This will normally just verify the file trailer and release temp storage.
+ *
+ * Returns FALSE if suspended.  The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_finish_decompress (j_decompress_ptr cinfo)
+{
+  if ((cinfo->global_state == DSTATE_SCANNING ||
+       cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
+    /* Terminate final pass of non-buffered mode */
+    if (cinfo->output_scanline < cinfo->output_height)
+      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
+    (*cinfo->master->finish_output_pass) (cinfo);
+    cinfo->global_state = DSTATE_STOPPING;
+  } else if (cinfo->global_state == DSTATE_BUFIMAGE) {
+    /* Finishing after a buffered-image operation */
+    cinfo->global_state = DSTATE_STOPPING;
+  } else if (cinfo->global_state != DSTATE_STOPPING) {
+    /* STOPPING = repeat call after a suspension, anything else is error */
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  }
+  /* Read until EOI */
+  while (! cinfo->inputctl->eoi_reached) {
+    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
+      return FALSE;		/* Suspend, come back later */
+  }
+  /* Do final cleanup */
+  (*cinfo->src->term_source) (cinfo);
+  /* We can use jpeg_abort to release memory and reset global_state */
+  jpeg_abort((j_common_ptr) cinfo);
+  return TRUE;
+}
diff --git a/Utilities/FLTK/jpeg/jdapistd.c b/Utilities/FLTK/jpeg/jdapistd.c
new file mode 100644
index 0000000000000000000000000000000000000000..c8e3fa0c35d2cc0f7b63de5c3d4ab6aa4c68c030
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdapistd.c
@@ -0,0 +1,275 @@
+/*
+ * jdapistd.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the decompression half
+ * of the JPEG library.  These are the "standard" API routines that are
+ * used in the normal full-decompression case.  They are not used by a
+ * transcoding-only application.  Note that if an application links in
+ * jpeg_start_decompress, it will end up linking in the entire decompressor.
+ * We thus must separate this file from jdapimin.c to avoid linking the
+ * whole decompression library into a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Decompression initialization.
+ * jpeg_read_header must be completed before calling this.
+ *
+ * If a multipass operating mode was selected, this will do all but the
+ * last pass, and thus may take a great deal of time.
+ *
+ * Returns FALSE if suspended.  The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_start_decompress (j_decompress_ptr cinfo)
+{
+  if (cinfo->global_state == DSTATE_READY) {
+    /* First call: initialize master control, select active modules */
+    jinit_master_decompress(cinfo);
+    if (cinfo->buffered_image) {
+      /* No more work here; expecting jpeg_start_output next */
+      cinfo->global_state = DSTATE_BUFIMAGE;
+      return TRUE;
+    }
+    cinfo->global_state = DSTATE_PRELOAD;
+  }
+  if (cinfo->global_state == DSTATE_PRELOAD) {
+    /* If file has multiple scans, absorb them all into the coef buffer */
+    if (cinfo->inputctl->has_multiple_scans) {
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+      for (;;) {
+	int retcode;
+	/* Call progress monitor hook if present */
+	if (cinfo->progress != NULL)
+	  (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+	/* Absorb some more input */
+	retcode = (*cinfo->inputctl->consume_input) (cinfo);
+	if (retcode == JPEG_SUSPENDED)
+	  return FALSE;
+	if (retcode == JPEG_REACHED_EOI)
+	  break;
+	/* Advance progress counter if appropriate */
+	if (cinfo->progress != NULL &&
+	    (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
+	  if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
+	    /* jdmaster underestimated number of scans; ratchet up one scan */
+	    cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+	  }
+	}
+      }
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+    }
+    cinfo->output_scan_number = cinfo->input_scan_number;
+  } else if (cinfo->global_state != DSTATE_PRESCAN)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  /* Perform any dummy output passes, and set up for the final pass */
+  return output_pass_setup(cinfo);
+}
+
+
+/*
+ * Set up for an output pass, and perform any dummy pass(es) needed.
+ * Common subroutine for jpeg_start_decompress and jpeg_start_output.
+ * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
+ * Exit: If done, returns TRUE and sets global_state for proper output mode.
+ *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
+ */
+
+LOCAL(boolean)
+output_pass_setup (j_decompress_ptr cinfo)
+{
+  if (cinfo->global_state != DSTATE_PRESCAN) {
+    /* First call: do pass setup */
+    (*cinfo->master->prepare_for_output_pass) (cinfo);
+    cinfo->output_scanline = 0;
+    cinfo->global_state = DSTATE_PRESCAN;
+  }
+  /* Loop over any required dummy passes */
+  while (cinfo->master->is_dummy_pass) {
+#ifdef QUANT_2PASS_SUPPORTED
+    /* Crank through the dummy pass */
+    while (cinfo->output_scanline < cinfo->output_height) {
+      JDIMENSION last_scanline;
+      /* Call progress monitor hook if present */
+      if (cinfo->progress != NULL) {
+	cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+	cinfo->progress->pass_limit = (long) cinfo->output_height;
+	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+      }
+      /* Process some data */
+      last_scanline = cinfo->output_scanline;
+      (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
+				    &cinfo->output_scanline, (JDIMENSION) 0);
+      if (cinfo->output_scanline == last_scanline)
+	return FALSE;		/* No progress made, must suspend */
+    }
+    /* Finish up dummy pass, and set up for another one */
+    (*cinfo->master->finish_output_pass) (cinfo);
+    (*cinfo->master->prepare_for_output_pass) (cinfo);
+    cinfo->output_scanline = 0;
+#else
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* QUANT_2PASS_SUPPORTED */
+  }
+  /* Ready for application to drive output pass through
+   * jpeg_read_scanlines or jpeg_read_raw_data.
+   */
+  cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
+  return TRUE;
+}
+
+
+/*
+ * Read some scanlines of data from the JPEG decompressor.
+ *
+ * The return value will be the number of lines actually read.
+ * This may be less than the number requested in several cases,
+ * including bottom of image, data source suspension, and operating
+ * modes that emit multiple scanlines at a time.
+ *
+ * Note: we warn about excess calls to jpeg_read_scanlines() since
+ * this likely signals an application programmer error.  However,
+ * an oversize buffer (max_lines > scanlines remaining) is not an error.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
+		     JDIMENSION max_lines)
+{
+  JDIMENSION row_ctr;
+
+  if (cinfo->global_state != DSTATE_SCANNING)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  if (cinfo->output_scanline >= cinfo->output_height) {
+    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+    return 0;
+  }
+
+  /* Call progress monitor hook if present */
+  if (cinfo->progress != NULL) {
+    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+    cinfo->progress->pass_limit = (long) cinfo->output_height;
+    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+  }
+
+  /* Process some data */
+  row_ctr = 0;
+  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
+  cinfo->output_scanline += row_ctr;
+  return row_ctr;
+}
+
+
+/*
+ * Alternate entry point to read raw data.
+ * Processes exactly one iMCU row per call, unless suspended.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
+		    JDIMENSION max_lines)
+{
+  JDIMENSION lines_per_iMCU_row;
+
+  if (cinfo->global_state != DSTATE_RAW_OK)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  if (cinfo->output_scanline >= cinfo->output_height) {
+    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+    return 0;
+  }
+
+  /* Call progress monitor hook if present */
+  if (cinfo->progress != NULL) {
+    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+    cinfo->progress->pass_limit = (long) cinfo->output_height;
+    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+  }
+
+  /* Verify that at least one iMCU row can be returned. */
+  lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
+  if (max_lines < lines_per_iMCU_row)
+    ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+  /* Decompress directly into user's buffer. */
+  if (! (*cinfo->coef->decompress_data) (cinfo, data))
+    return 0;			/* suspension forced, can do nothing more */
+
+  /* OK, we processed one iMCU row. */
+  cinfo->output_scanline += lines_per_iMCU_row;
+  return lines_per_iMCU_row;
+}
+
+
+/* Additional entry points for buffered-image mode. */
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Initialize for an output pass in buffered-image mode.
+ */
+
+GLOBAL(boolean)
+jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
+{
+  if (cinfo->global_state != DSTATE_BUFIMAGE &&
+      cinfo->global_state != DSTATE_PRESCAN)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  /* Limit scan number to valid range */
+  if (scan_number <= 0)
+    scan_number = 1;
+  if (cinfo->inputctl->eoi_reached &&
+      scan_number > cinfo->input_scan_number)
+    scan_number = cinfo->input_scan_number;
+  cinfo->output_scan_number = scan_number;
+  /* Perform any dummy output passes, and set up for the real pass */
+  return output_pass_setup(cinfo);
+}
+
+
+/*
+ * Finish up after an output pass in buffered-image mode.
+ *
+ * Returns FALSE if suspended.  The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_finish_output (j_decompress_ptr cinfo)
+{
+  if ((cinfo->global_state == DSTATE_SCANNING ||
+       cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
+    /* Terminate this pass. */
+    /* We do not require the whole pass to have been completed. */
+    (*cinfo->master->finish_output_pass) (cinfo);
+    cinfo->global_state = DSTATE_BUFPOST;
+  } else if (cinfo->global_state != DSTATE_BUFPOST) {
+    /* BUFPOST = repeat call after a suspension, anything else is error */
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  }
+  /* Read markers looking for SOS or EOI */
+  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
+	 ! cinfo->inputctl->eoi_reached) {
+    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
+      return FALSE;		/* Suspend, come back later */
+  }
+  cinfo->global_state = DSTATE_BUFIMAGE;
+  return TRUE;
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jdatadst.c b/Utilities/FLTK/jpeg/jdatadst.c
new file mode 100644
index 0000000000000000000000000000000000000000..a8f6fb0e025364eccfcb033dcf576560fc7c0fb3
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdatadst.c
@@ -0,0 +1,151 @@
+/*
+ * jdatadst.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains compression data destination routines for the case of
+ * emitting JPEG data to a file (or any stdio stream).  While these routines
+ * are sufficient for most applications, some will want to use a different
+ * destination manager.
+ * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
+ * JOCTETs into 8-bit-wide elements on external storage.  If char is wider
+ * than 8 bits on your machine, you may need to do some tweaking.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jerror.h"
+
+
+/* Expanded data destination object for stdio output */
+
+typedef struct {
+  struct jpeg_destination_mgr pub; /* public fields */
+
+  FILE * outfile;		/* target stream */
+  JOCTET * buffer;		/* start of buffer */
+} my_destination_mgr;
+
+typedef my_destination_mgr * my_dest_ptr;
+
+#define OUTPUT_BUF_SIZE  4096	/* choose an efficiently fwrite'able size */
+
+
+/*
+ * Initialize destination --- called by jpeg_start_compress
+ * before any data is actually written.
+ */
+
+METHODDEF(void)
+init_destination (j_compress_ptr cinfo)
+{
+  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+  /* Allocate the output buffer --- it will be released when done with image */
+  dest->buffer = (JOCTET *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
+
+  dest->pub.next_output_byte = dest->buffer;
+  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+}
+
+
+/*
+ * Empty the output buffer --- called whenever buffer fills up.
+ *
+ * In typical applications, this should write the entire output buffer
+ * (ignoring the current state of next_output_byte & free_in_buffer),
+ * reset the pointer & count to the start of the buffer, and return TRUE
+ * indicating that the buffer has been dumped.
+ *
+ * In applications that need to be able to suspend compression due to output
+ * overrun, a FALSE return indicates that the buffer cannot be emptied now.
+ * In this situation, the compressor will return to its caller (possibly with
+ * an indication that it has not accepted all the supplied scanlines).  The
+ * application should resume compression after it has made more room in the
+ * output buffer.  Note that there are substantial restrictions on the use of
+ * suspension --- see the documentation.
+ *
+ * When suspending, the compressor will back up to a convenient restart point
+ * (typically the start of the current MCU). next_output_byte & free_in_buffer
+ * indicate where the restart point will be if the current call returns FALSE.
+ * Data beyond this point will be regenerated after resumption, so do not
+ * write it out when emptying the buffer externally.
+ */
+
+METHODDEF(boolean)
+empty_output_buffer (j_compress_ptr cinfo)
+{
+  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+  if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) !=
+      (size_t) OUTPUT_BUF_SIZE)
+    ERREXIT(cinfo, JERR_FILE_WRITE);
+
+  dest->pub.next_output_byte = dest->buffer;
+  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+
+  return TRUE;
+}
+
+
+/*
+ * Terminate destination --- called by jpeg_finish_compress
+ * after all data has been written.  Usually needs to flush buffer.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+
+METHODDEF(void)
+term_destination (j_compress_ptr cinfo)
+{
+  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
+
+  /* Write any data remaining in the buffer */
+  if (datacount > 0) {
+    if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
+      ERREXIT(cinfo, JERR_FILE_WRITE);
+  }
+  fflush(dest->outfile);
+  /* Make sure we wrote the output file OK */
+  if (ferror(dest->outfile))
+    ERREXIT(cinfo, JERR_FILE_WRITE);
+}
+
+
+/*
+ * Prepare for output to a stdio stream.
+ * The caller must have already opened the stream, and is responsible
+ * for closing it after finishing compression.
+ */
+
+GLOBAL(void)
+jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
+{
+  my_dest_ptr dest;
+
+  /* The destination object is made permanent so that multiple JPEG images
+   * can be written to the same file without re-executing jpeg_stdio_dest.
+   * This makes it dangerous to use this manager and a different destination
+   * manager serially with the same JPEG object, because their private object
+   * sizes may be different.  Caveat programmer.
+   */
+  if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
+    cinfo->dest = (struct jpeg_destination_mgr *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				  SIZEOF(my_destination_mgr));
+  }
+
+  dest = (my_dest_ptr) cinfo->dest;
+  dest->pub.init_destination = init_destination;
+  dest->pub.empty_output_buffer = empty_output_buffer;
+  dest->pub.term_destination = term_destination;
+  dest->outfile = outfile;
+}
diff --git a/Utilities/FLTK/jpeg/jdatasrc.c b/Utilities/FLTK/jpeg/jdatasrc.c
new file mode 100644
index 0000000000000000000000000000000000000000..edc752bf5d8c233a6597ba6a46d48ec7e43c65c7
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdatasrc.c
@@ -0,0 +1,212 @@
+/*
+ * jdatasrc.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains decompression data source routines for the case of
+ * reading JPEG data from a file (or any stdio stream).  While these routines
+ * are sufficient for most applications, some will want to use a different
+ * source manager.
+ * IMPORTANT: we assume that fread() will correctly transcribe an array of
+ * JOCTETs from 8-bit-wide elements on external storage.  If char is wider
+ * than 8 bits on your machine, you may need to do some tweaking.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jerror.h"
+
+
+/* Expanded data source object for stdio input */
+
+typedef struct {
+  struct jpeg_source_mgr pub;	/* public fields */
+
+  FILE * infile;		/* source stream */
+  JOCTET * buffer;		/* start of buffer */
+  boolean start_of_file;	/* have we gotten any data yet? */
+} my_source_mgr;
+
+typedef my_source_mgr * my_src_ptr;
+
+#define INPUT_BUF_SIZE  4096	/* choose an efficiently fread'able size */
+
+
+/*
+ * Initialize source --- called by jpeg_read_header
+ * before any data is actually read.
+ */
+
+METHODDEF(void)
+init_source (j_decompress_ptr cinfo)
+{
+  my_src_ptr src = (my_src_ptr) cinfo->src;
+
+  /* We reset the empty-input-file flag for each image,
+   * but we don't clear the input buffer.
+   * This is correct behavior for reading a series of images from one source.
+   */
+  src->start_of_file = TRUE;
+}
+
+
+/*
+ * Fill the input buffer --- called whenever buffer is emptied.
+ *
+ * In typical applications, this should read fresh data into the buffer
+ * (ignoring the current state of next_input_byte & bytes_in_buffer),
+ * reset the pointer & count to the start of the buffer, and return TRUE
+ * indicating that the buffer has been reloaded.  It is not necessary to
+ * fill the buffer entirely, only to obtain at least one more byte.
+ *
+ * There is no such thing as an EOF return.  If the end of the file has been
+ * reached, the routine has a choice of ERREXIT() or inserting fake data into
+ * the buffer.  In most cases, generating a warning message and inserting a
+ * fake EOI marker is the best course of action --- this will allow the
+ * decompressor to output however much of the image is there.  However,
+ * the resulting error message is misleading if the real problem is an empty
+ * input file, so we handle that case specially.
+ *
+ * In applications that need to be able to suspend compression due to input
+ * not being available yet, a FALSE return indicates that no more data can be
+ * obtained right now, but more may be forthcoming later.  In this situation,
+ * the decompressor will return to its caller (with an indication of the
+ * number of scanlines it has read, if any).  The application should resume
+ * decompression after it has loaded more data into the input buffer.  Note
+ * that there are substantial restrictions on the use of suspension --- see
+ * the documentation.
+ *
+ * When suspending, the decompressor will back up to a convenient restart point
+ * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
+ * indicate where the restart point will be if the current call returns FALSE.
+ * Data beyond this point must be rescanned after resumption, so move it to
+ * the front of the buffer rather than discarding it.
+ */
+
+METHODDEF(boolean)
+fill_input_buffer (j_decompress_ptr cinfo)
+{
+  my_src_ptr src = (my_src_ptr) cinfo->src;
+  size_t nbytes;
+
+  nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
+
+  if (nbytes <= 0) {
+    if (src->start_of_file)	/* Treat empty input file as fatal error */
+      ERREXIT(cinfo, JERR_INPUT_EMPTY);
+    WARNMS(cinfo, JWRN_JPEG_EOF);
+    /* Insert a fake EOI marker */
+    src->buffer[0] = (JOCTET) 0xFF;
+    src->buffer[1] = (JOCTET) JPEG_EOI;
+    nbytes = 2;
+  }
+
+  src->pub.next_input_byte = src->buffer;
+  src->pub.bytes_in_buffer = nbytes;
+  src->start_of_file = FALSE;
+
+  return TRUE;
+}
+
+
+/*
+ * Skip data --- used to skip over a potentially large amount of
+ * uninteresting data (such as an APPn marker).
+ *
+ * Writers of suspendable-input applications must note that skip_input_data
+ * is not granted the right to give a suspension return.  If the skip extends
+ * beyond the data currently in the buffer, the buffer can be marked empty so
+ * that the next read will cause a fill_input_buffer call that can suspend.
+ * Arranging for additional bytes to be discarded before reloading the input
+ * buffer is the application writer's problem.
+ */
+
+METHODDEF(void)
+skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+  my_src_ptr src = (my_src_ptr) cinfo->src;
+
+  /* Just a dumb implementation for now.  Could use fseek() except
+   * it doesn't work on pipes.  Not clear that being smart is worth
+   * any trouble anyway --- large skips are infrequent.
+   */
+  if (num_bytes > 0) {
+    while (num_bytes > (long) src->pub.bytes_in_buffer) {
+      num_bytes -= (long) src->pub.bytes_in_buffer;
+      (void) fill_input_buffer(cinfo);
+      /* note we assume that fill_input_buffer will never return FALSE,
+       * so suspension need not be handled.
+       */
+    }
+    src->pub.next_input_byte += (size_t) num_bytes;
+    src->pub.bytes_in_buffer -= (size_t) num_bytes;
+  }
+}
+
+
+/*
+ * An additional method that can be provided by data source modules is the
+ * resync_to_restart method for error recovery in the presence of RST markers.
+ * For the moment, this source module just uses the default resync method
+ * provided by the JPEG library.  That method assumes that no backtracking
+ * is possible.
+ */
+
+
+/*
+ * Terminate source --- called by jpeg_finish_decompress
+ * after all data has been read.  Often a no-op.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+
+METHODDEF(void)
+term_source (j_decompress_ptr cinfo)
+{
+  /* no work necessary here */
+}
+
+
+/*
+ * Prepare for input from a stdio stream.
+ * The caller must have already opened the stream, and is responsible
+ * for closing it after finishing decompression.
+ */
+
+GLOBAL(void)
+jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
+{
+  my_src_ptr src;
+
+  /* The source object and input buffer are made permanent so that a series
+   * of JPEG images can be read from the same file by calling jpeg_stdio_src
+   * only before the first one.  (If we discarded the buffer at the end of
+   * one image, we'd likely lose the start of the next one.)
+   * This makes it unsafe to use this manager and a different source
+   * manager serially with the same JPEG object.  Caveat programmer.
+   */
+  if (cinfo->src == NULL) {	/* first time for this JPEG object? */
+    cinfo->src = (struct jpeg_source_mgr *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				  SIZEOF(my_source_mgr));
+    src = (my_src_ptr) cinfo->src;
+    src->buffer = (JOCTET *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				  INPUT_BUF_SIZE * SIZEOF(JOCTET));
+  }
+
+  src = (my_src_ptr) cinfo->src;
+  src->pub.init_source = init_source;
+  src->pub.fill_input_buffer = fill_input_buffer;
+  src->pub.skip_input_data = skip_input_data;
+  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+  src->pub.term_source = term_source;
+  src->infile = infile;
+  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+  src->pub.next_input_byte = NULL; /* until buffer loaded */
+}
diff --git a/Utilities/FLTK/jpeg/jdcoefct.c b/Utilities/FLTK/jpeg/jdcoefct.c
new file mode 100644
index 0000000000000000000000000000000000000000..4938d20fcb655632d640534ba19e73f0c8fdccbc
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdcoefct.c
@@ -0,0 +1,736 @@
+/*
+ * jdcoefct.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the coefficient buffer controller for decompression.
+ * This controller is the top level of the JPEG decompressor proper.
+ * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
+ *
+ * In buffered-image mode, this controller is the interface between
+ * input-oriented processing and output-oriented processing.
+ * Also, the input side (only) is used when reading a file for transcoding.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+/* Block smoothing is only applicable for progressive JPEG, so: */
+#ifndef D_PROGRESSIVE_SUPPORTED
+#undef BLOCK_SMOOTHING_SUPPORTED
+#endif
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_d_coef_controller pub; /* public fields */
+
+  /* These variables keep track of the current location of the input side. */
+  /* cinfo->input_iMCU_row is also used for this. */
+  JDIMENSION MCU_ctr;		/* counts MCUs processed in current row */
+  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
+  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
+
+  /* The output side's location is represented by cinfo->output_iMCU_row. */
+
+  /* In single-pass modes, it's sufficient to buffer just one MCU.
+   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
+   * and let the entropy decoder write into that workspace each time.
+   * (On 80x86, the workspace is FAR even though it's not really very big;
+   * this is to keep the module interfaces unchanged when a large coefficient
+   * buffer is necessary.)
+   * In multi-pass modes, this array points to the current MCU's blocks
+   * within the virtual arrays; it is used only by the input side.
+   */
+  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+  /* In multi-pass modes, we need a virtual block array for each component. */
+  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
+#endif
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  /* When doing block smoothing, we latch coefficient Al values here */
+  int * coef_bits_latch;
+#define SAVED_COEFS  6		/* we save coef_bits[0..5] */
+#endif
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+/* Forward declarations */
+METHODDEF(int) decompress_onepass
+	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+METHODDEF(int) decompress_data
+	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#endif
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
+METHODDEF(int) decompress_smooth_data
+	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#endif
+
+
+LOCAL(void)
+start_iMCU_row (j_decompress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row (input side) */
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  /* In an interleaved scan, an MCU row is the same as an iMCU row.
+   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+   * But at the bottom of the image, process only what's left.
+   */
+  if (cinfo->comps_in_scan > 1) {
+    coef->MCU_rows_per_iMCU_row = 1;
+  } else {
+    if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+    else
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+  }
+
+  coef->MCU_ctr = 0;
+  coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for an input processing pass.
+ */
+
+METHODDEF(void)
+start_input_pass (j_decompress_ptr cinfo)
+{
+  cinfo->input_iMCU_row = 0;
+  start_iMCU_row(cinfo);
+}
+
+
+/*
+ * Initialize for an output processing pass.
+ */
+
+METHODDEF(void)
+start_output_pass (j_decompress_ptr cinfo)
+{
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  /* If multipass, check to see whether to use block smoothing on this pass */
+  if (coef->pub.coef_arrays != NULL) {
+    if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
+      coef->pub.decompress_data = decompress_smooth_data;
+    else
+      coef->pub.decompress_data = decompress_data;
+  }
+#endif
+  cinfo->output_iMCU_row = 0;
+}
+
+
+/*
+ * Decompress and return some data in the single-pass case.
+ * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
+ * Input and output must run in lockstep since we have only a one-MCU buffer.
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ *
+ * NB: output_buf contains a plane for each component in image,
+ * which we index according to the component's SOF position.
+ */
+
+METHODDEF(int)
+decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION MCU_col_num;	/* index of current MCU within row */
+  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+  int blkn, ci, xindex, yindex, yoffset, useful_width;
+  JSAMPARRAY output_ptr;
+  JDIMENSION start_col, output_col;
+  jpeg_component_info *compptr;
+  inverse_DCT_method_ptr inverse_DCT;
+
+  /* Loop to process as much as one whole iMCU row */
+  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+       yoffset++) {
+    for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
+	 MCU_col_num++) {
+      /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
+      jzero_far((void FAR *) coef->MCU_buffer[0],
+		(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
+      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
+	/* Suspension forced; update state counters and exit */
+	coef->MCU_vert_offset = yoffset;
+	coef->MCU_ctr = MCU_col_num;
+	return JPEG_SUSPENDED;
+      }
+      /* Determine where data should go in output_buf and do the IDCT thing.
+       * We skip dummy blocks at the right and bottom edges (but blkn gets
+       * incremented past them!).  Note the inner loop relies on having
+       * allocated the MCU_buffer[] blocks sequentially.
+       */
+      blkn = 0;			/* index of current DCT block within MCU */
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+	compptr = cinfo->cur_comp_info[ci];
+	/* Don't bother to IDCT an uninteresting component. */
+	if (! compptr->component_needed) {
+	  blkn += compptr->MCU_blocks;
+	  continue;
+	}
+	inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
+	useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+						    : compptr->last_col_width;
+	output_ptr = output_buf[compptr->component_index] +
+	  yoffset * compptr->DCT_scaled_size;
+	start_col = MCU_col_num * compptr->MCU_sample_width;
+	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+	  if (cinfo->input_iMCU_row < last_iMCU_row ||
+	      yoffset+yindex < compptr->last_row_height) {
+	    output_col = start_col;
+	    for (xindex = 0; xindex < useful_width; xindex++) {
+	      (*inverse_DCT) (cinfo, compptr,
+			      (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
+			      output_ptr, output_col);
+	      output_col += compptr->DCT_scaled_size;
+	    }
+	  }
+	  blkn += compptr->MCU_width;
+	  output_ptr += compptr->DCT_scaled_size;
+	}
+      }
+    }
+    /* Completed an MCU row, but perhaps not an iMCU row */
+    coef->MCU_ctr = 0;
+  }
+  /* Completed the iMCU row, advance counters for next one */
+  cinfo->output_iMCU_row++;
+  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
+    start_iMCU_row(cinfo);
+    return JPEG_ROW_COMPLETED;
+  }
+  /* Completed the scan */
+  (*cinfo->inputctl->finish_input_pass) (cinfo);
+  return JPEG_SCAN_COMPLETED;
+}
+
+
+/*
+ * Dummy consume-input routine for single-pass operation.
+ */
+
+METHODDEF(int)
+dummy_consume_data (j_decompress_ptr cinfo)
+{
+  return JPEG_SUSPENDED;	/* Always indicate nothing was done */
+}
+
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Consume input data and store it in the full-image coefficient buffer.
+ * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
+ * ie, v_samp_factor block rows for each component in the scan.
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ */
+
+METHODDEF(int)
+consume_data (j_decompress_ptr cinfo)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION MCU_col_num;	/* index of current MCU within row */
+  int blkn, ci, xindex, yindex, yoffset;
+  JDIMENSION start_col;
+  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+  JBLOCKROW buffer_ptr;
+  jpeg_component_info *compptr;
+
+  /* Align the virtual buffers for the components used in this scan. */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    buffer[ci] = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+       cinfo->input_iMCU_row * compptr->v_samp_factor,
+       (JDIMENSION) compptr->v_samp_factor, TRUE);
+    /* Note: entropy decoder expects buffer to be zeroed,
+     * but this is handled automatically by the memory manager
+     * because we requested a pre-zeroed array.
+     */
+  }
+
+  /* Loop to process one whole iMCU row */
+  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+       yoffset++) {
+    for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
+	 MCU_col_num++) {
+      /* Construct list of pointers to DCT blocks belonging to this MCU */
+      blkn = 0;			/* index of current DCT block within MCU */
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+	compptr = cinfo->cur_comp_info[ci];
+	start_col = MCU_col_num * compptr->MCU_width;
+	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
+	    coef->MCU_buffer[blkn++] = buffer_ptr++;
+	  }
+	}
+      }
+      /* Try to fetch the MCU. */
+      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
+	/* Suspension forced; update state counters and exit */
+	coef->MCU_vert_offset = yoffset;
+	coef->MCU_ctr = MCU_col_num;
+	return JPEG_SUSPENDED;
+      }
+    }
+    /* Completed an MCU row, but perhaps not an iMCU row */
+    coef->MCU_ctr = 0;
+  }
+  /* Completed the iMCU row, advance counters for next one */
+  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
+    start_iMCU_row(cinfo);
+    return JPEG_ROW_COMPLETED;
+  }
+  /* Completed the scan */
+  (*cinfo->inputctl->finish_input_pass) (cinfo);
+  return JPEG_SCAN_COMPLETED;
+}
+
+
+/*
+ * Decompress and return some data in the multi-pass case.
+ * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ *
+ * NB: output_buf contains a plane for each component in image.
+ */
+
+METHODDEF(int)
+decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+  JDIMENSION block_num;
+  int ci, block_row, block_rows;
+  JBLOCKARRAY buffer;
+  JBLOCKROW buffer_ptr;
+  JSAMPARRAY output_ptr;
+  JDIMENSION output_col;
+  jpeg_component_info *compptr;
+  inverse_DCT_method_ptr inverse_DCT;
+
+  /* Force some input to be done if we are getting ahead of the input. */
+  while (cinfo->input_scan_number < cinfo->output_scan_number ||
+	 (cinfo->input_scan_number == cinfo->output_scan_number &&
+	  cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
+    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
+      return JPEG_SUSPENDED;
+  }
+
+  /* OK, output from the virtual arrays. */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Don't bother to IDCT an uninteresting component. */
+    if (! compptr->component_needed)
+      continue;
+    /* Align the virtual buffer for this component. */
+    buffer = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr) cinfo, coef->whole_image[ci],
+       cinfo->output_iMCU_row * compptr->v_samp_factor,
+       (JDIMENSION) compptr->v_samp_factor, FALSE);
+    /* Count non-dummy DCT block rows in this iMCU row. */
+    if (cinfo->output_iMCU_row < last_iMCU_row)
+      block_rows = compptr->v_samp_factor;
+    else {
+      /* NB: can't use last_row_height here; it is input-side-dependent! */
+      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+      if (block_rows == 0) block_rows = compptr->v_samp_factor;
+    }
+    inverse_DCT = cinfo->idct->inverse_DCT[ci];
+    output_ptr = output_buf[ci];
+    /* Loop over all DCT blocks to be processed. */
+    for (block_row = 0; block_row < block_rows; block_row++) {
+      buffer_ptr = buffer[block_row];
+      output_col = 0;
+      for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
+	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
+			output_ptr, output_col);
+	buffer_ptr++;
+	output_col += compptr->DCT_scaled_size;
+      }
+      output_ptr += compptr->DCT_scaled_size;
+    }
+  }
+
+  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
+    return JPEG_ROW_COMPLETED;
+  return JPEG_SCAN_COMPLETED;
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+
+/*
+ * This code applies interblock smoothing as described by section K.8
+ * of the JPEG standard: the first 5 AC coefficients are estimated from
+ * the DC values of a DCT block and its 8 neighboring blocks.
+ * We apply smoothing only for progressive JPEG decoding, and only if
+ * the coefficients it can estimate are not yet known to full precision.
+ */
+
+/* Natural-order array positions of the first 5 zigzag-order coefficients */
+#define Q01_POS  1
+#define Q10_POS  8
+#define Q20_POS  16
+#define Q11_POS  9
+#define Q02_POS  2
+
+/*
+ * Determine whether block smoothing is applicable and safe.
+ * We also latch the current states of the coef_bits[] entries for the
+ * AC coefficients; otherwise, if the input side of the decompressor
+ * advances into a new scan, we might think the coefficients are known
+ * more accurately than they really are.
+ */
+
+LOCAL(boolean)
+smoothing_ok (j_decompress_ptr cinfo)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  boolean smoothing_useful = FALSE;
+  int ci, coefi;
+  jpeg_component_info *compptr;
+  JQUANT_TBL * qtable;
+  int * coef_bits;
+  int * coef_bits_latch;
+
+  if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
+    return FALSE;
+
+  /* Allocate latch area if not already done */
+  if (coef->coef_bits_latch == NULL)
+    coef->coef_bits_latch = (int *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  cinfo->num_components *
+				  (SAVED_COEFS * SIZEOF(int)));
+  coef_bits_latch = coef->coef_bits_latch;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* All components' quantization values must already be latched. */
+    if ((qtable = compptr->quant_table) == NULL)
+      return FALSE;
+    /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
+    if (qtable->quantval[0] == 0 ||
+	qtable->quantval[Q01_POS] == 0 ||
+	qtable->quantval[Q10_POS] == 0 ||
+	qtable->quantval[Q20_POS] == 0 ||
+	qtable->quantval[Q11_POS] == 0 ||
+	qtable->quantval[Q02_POS] == 0)
+      return FALSE;
+    /* DC values must be at least partly known for all components. */
+    coef_bits = cinfo->coef_bits[ci];
+    if (coef_bits[0] < 0)
+      return FALSE;
+    /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
+    for (coefi = 1; coefi <= 5; coefi++) {
+      coef_bits_latch[coefi] = coef_bits[coefi];
+      if (coef_bits[coefi] != 0)
+	smoothing_useful = TRUE;
+    }
+    coef_bits_latch += SAVED_COEFS;
+  }
+
+  return smoothing_useful;
+}
+
+
+/*
+ * Variant of decompress_data for use when doing block smoothing.
+ */
+
+METHODDEF(int)
+decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+  JDIMENSION block_num, last_block_column;
+  int ci, block_row, block_rows, access_rows;
+  JBLOCKARRAY buffer;
+  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
+  JSAMPARRAY output_ptr;
+  JDIMENSION output_col;
+  jpeg_component_info *compptr;
+  inverse_DCT_method_ptr inverse_DCT;
+  boolean first_row, last_row;
+  JBLOCK workspace;
+  int *coef_bits;
+  JQUANT_TBL *quanttbl;
+  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
+  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
+  int Al, pred;
+
+  /* Force some input to be done if we are getting ahead of the input. */
+  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
+	 ! cinfo->inputctl->eoi_reached) {
+    if (cinfo->input_scan_number == cinfo->output_scan_number) {
+      /* If input is working on current scan, we ordinarily want it to
+       * have completed the current row.  But if input scan is DC,
+       * we want it to keep one row ahead so that next block row's DC
+       * values are up to date.
+       */
+      JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
+      if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
+	break;
+    }
+    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
+      return JPEG_SUSPENDED;
+  }
+
+  /* OK, output from the virtual arrays. */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Don't bother to IDCT an uninteresting component. */
+    if (! compptr->component_needed)
+      continue;
+    /* Count non-dummy DCT block rows in this iMCU row. */
+    if (cinfo->output_iMCU_row < last_iMCU_row) {
+      block_rows = compptr->v_samp_factor;
+      access_rows = block_rows * 2; /* this and next iMCU row */
+      last_row = FALSE;
+    } else {
+      /* NB: can't use last_row_height here; it is input-side-dependent! */
+      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+      if (block_rows == 0) block_rows = compptr->v_samp_factor;
+      access_rows = block_rows; /* this iMCU row only */
+      last_row = TRUE;
+    }
+    /* Align the virtual buffer for this component. */
+    if (cinfo->output_iMCU_row > 0) {
+      access_rows += compptr->v_samp_factor; /* prior iMCU row too */
+      buffer = (*cinfo->mem->access_virt_barray)
+	((j_common_ptr) cinfo, coef->whole_image[ci],
+	 (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
+	 (JDIMENSION) access_rows, FALSE);
+      buffer += compptr->v_samp_factor;	/* point to current iMCU row */
+      first_row = FALSE;
+    } else {
+      buffer = (*cinfo->mem->access_virt_barray)
+	((j_common_ptr) cinfo, coef->whole_image[ci],
+	 (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
+      first_row = TRUE;
+    }
+    /* Fetch component-dependent info */
+    coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
+    quanttbl = compptr->quant_table;
+    Q00 = quanttbl->quantval[0];
+    Q01 = quanttbl->quantval[Q01_POS];
+    Q10 = quanttbl->quantval[Q10_POS];
+    Q20 = quanttbl->quantval[Q20_POS];
+    Q11 = quanttbl->quantval[Q11_POS];
+    Q02 = quanttbl->quantval[Q02_POS];
+    inverse_DCT = cinfo->idct->inverse_DCT[ci];
+    output_ptr = output_buf[ci];
+    /* Loop over all DCT blocks to be processed. */
+    for (block_row = 0; block_row < block_rows; block_row++) {
+      buffer_ptr = buffer[block_row];
+      if (first_row && block_row == 0)
+	prev_block_row = buffer_ptr;
+      else
+	prev_block_row = buffer[block_row-1];
+      if (last_row && block_row == block_rows-1)
+	next_block_row = buffer_ptr;
+      else
+	next_block_row = buffer[block_row+1];
+      /* We fetch the surrounding DC values using a sliding-register approach.
+       * Initialize all nine here so as to do the right thing on narrow pics.
+       */
+      DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
+      DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
+      DC7 = DC8 = DC9 = (int) next_block_row[0][0];
+      output_col = 0;
+      last_block_column = compptr->width_in_blocks - 1;
+      for (block_num = 0; block_num <= last_block_column; block_num++) {
+	/* Fetch current DCT block into workspace so we can modify it. */
+	jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
+	/* Update DC values */
+	if (block_num < last_block_column) {
+	  DC3 = (int) prev_block_row[1][0];
+	  DC6 = (int) buffer_ptr[1][0];
+	  DC9 = (int) next_block_row[1][0];
+	}
+	/* Compute coefficient estimates per K.8.
+	 * An estimate is applied only if coefficient is still zero,
+	 * and is not known to be fully accurate.
+	 */
+	/* AC01 */
+	if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
+	  num = 36 * Q00 * (DC4 - DC6);
+	  if (num >= 0) {
+	    pred = (int) (((Q01<<7) + num) / (Q01<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	  } else {
+	    pred = (int) (((Q01<<7) - num) / (Q01<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	    pred = -pred;
+	  }
+	  workspace[1] = (JCOEF) pred;
+	}
+	/* AC10 */
+	if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
+	  num = 36 * Q00 * (DC2 - DC8);
+	  if (num >= 0) {
+	    pred = (int) (((Q10<<7) + num) / (Q10<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	  } else {
+	    pred = (int) (((Q10<<7) - num) / (Q10<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	    pred = -pred;
+	  }
+	  workspace[8] = (JCOEF) pred;
+	}
+	/* AC20 */
+	if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
+	  num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
+	  if (num >= 0) {
+	    pred = (int) (((Q20<<7) + num) / (Q20<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	  } else {
+	    pred = (int) (((Q20<<7) - num) / (Q20<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	    pred = -pred;
+	  }
+	  workspace[16] = (JCOEF) pred;
+	}
+	/* AC11 */
+	if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
+	  num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
+	  if (num >= 0) {
+	    pred = (int) (((Q11<<7) + num) / (Q11<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	  } else {
+	    pred = (int) (((Q11<<7) - num) / (Q11<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	    pred = -pred;
+	  }
+	  workspace[9] = (JCOEF) pred;
+	}
+	/* AC02 */
+	if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
+	  num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
+	  if (num >= 0) {
+	    pred = (int) (((Q02<<7) + num) / (Q02<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	  } else {
+	    pred = (int) (((Q02<<7) - num) / (Q02<<8));
+	    if (Al > 0 && pred >= (1<<Al))
+	      pred = (1<<Al)-1;
+	    pred = -pred;
+	  }
+	  workspace[2] = (JCOEF) pred;
+	}
+	/* OK, do the IDCT */
+	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
+			output_ptr, output_col);
+	/* Advance for next column */
+	DC1 = DC2; DC2 = DC3;
+	DC4 = DC5; DC5 = DC6;
+	DC7 = DC8; DC8 = DC9;
+	buffer_ptr++, prev_block_row++, next_block_row++;
+	output_col += compptr->DCT_scaled_size;
+      }
+      output_ptr += compptr->DCT_scaled_size;
+    }
+  }
+
+  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
+    return JPEG_ROW_COMPLETED;
+  return JPEG_SCAN_COMPLETED;
+}
+
+#endif /* BLOCK_SMOOTHING_SUPPORTED */
+
+
+/*
+ * Initialize coefficient buffer controller.
+ */
+
+GLOBAL(void)
+jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+  my_coef_ptr coef;
+
+  coef = (my_coef_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_coef_controller));
+  cinfo->coef = (struct jpeg_d_coef_controller *) coef;
+  coef->pub.start_input_pass = start_input_pass;
+  coef->pub.start_output_pass = start_output_pass;
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  coef->coef_bits_latch = NULL;
+#endif
+
+  /* Create the coefficient buffer. */
+  if (need_full_buffer) {
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+    /* Allocate a full-image virtual array for each component, */
+    /* padded to a multiple of samp_factor DCT blocks in each direction. */
+    /* Note we ask for a pre-zeroed array. */
+    int ci, access_rows;
+    jpeg_component_info *compptr;
+
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      access_rows = compptr->v_samp_factor;
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+      /* If block smoothing could be used, need a bigger window */
+      if (cinfo->progressive_mode)
+	access_rows *= 3;
+#endif
+      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
+	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+				(long) compptr->h_samp_factor),
+	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+				(long) compptr->v_samp_factor),
+	 (JDIMENSION) access_rows);
+    }
+    coef->pub.consume_data = consume_data;
+    coef->pub.decompress_data = decompress_data;
+    coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
+#else
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+  } else {
+    /* We only need a single-MCU buffer. */
+    JBLOCKROW buffer;
+    int i;
+
+    buffer = (JBLOCKROW)
+      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
+      coef->MCU_buffer[i] = buffer + i;
+    }
+    coef->pub.consume_data = dummy_consume_data;
+    coef->pub.decompress_data = decompress_onepass;
+    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jdcolor.c b/Utilities/FLTK/jpeg/jdcolor.c
new file mode 100644
index 0000000000000000000000000000000000000000..6c04dfe8aa1b36e4ab4c9909c77e9cd26b74e9d7
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdcolor.c
@@ -0,0 +1,396 @@
+/*
+ * jdcolor.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains output colorspace conversion routines.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private subobject */
+
+typedef struct {
+  struct jpeg_color_deconverter pub; /* public fields */
+
+  /* Private state for YCC->RGB conversion */
+  int * Cr_r_tab;		/* => table for Cr to R conversion */
+  int * Cb_b_tab;		/* => table for Cb to B conversion */
+  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
+  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
+} my_color_deconverter;
+
+typedef my_color_deconverter * my_cconvert_ptr;
+
+
+/**************** YCbCr -> RGB conversion: most common case **************/
+
+/*
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *	R = Y                + 1.40200 * Cr
+ *	G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *	B = Y + 1.77200 * Cb
+ * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
+ * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ *
+ * To avoid floating-point arithmetic, we represent the fractional constants
+ * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
+ * the products by 2^16, with appropriate rounding, to get the correct answer.
+ * Notice that Y, being an integral input, does not contribute any fraction
+ * so it need not participate in the rounding.
+ *
+ * For even more speed, we avoid doing any multiplications in the inner loop
+ * by precalculating the constants times Cb and Cr for all possible values.
+ * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
+ * for 12-bit samples it is still acceptable.  It's not very reasonable for
+ * 16-bit samples, but if you want lossless storage you shouldn't be changing
+ * colorspace anyway.
+ * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
+ * values for the G calculation are left scaled up, since we must add them
+ * together before rounding.
+ */
+
+#define SCALEBITS	16	/* speediest right-shift on some machines */
+#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
+#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+
+/*
+ * Initialize tables for YCC->RGB colorspace conversion.
+ */
+
+LOCAL(void)
+build_ycc_rgb_table (j_decompress_ptr cinfo)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  int i;
+  INT32 x;
+  SHIFT_TEMPS
+
+  cconvert->Cr_r_tab = (int *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(int));
+  cconvert->Cb_b_tab = (int *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(int));
+  cconvert->Cr_g_tab = (INT32 *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(INT32));
+  cconvert->Cb_g_tab = (INT32 *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(INT32));
+
+  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
+    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+    /* Cr=>R value is nearest int to 1.40200 * x */
+    cconvert->Cr_r_tab[i] = (int)
+		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
+    /* Cb=>B value is nearest int to 1.77200 * x */
+    cconvert->Cb_b_tab[i] = (int)
+		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
+    /* Cr=>G value is scaled-up -0.71414 * x */
+    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
+    /* Cb=>G value is scaled-up -0.34414 * x */
+    /* We also add in ONE_HALF so that need not do it in inner loop */
+    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+  }
+}
+
+
+/*
+ * Convert some rows of samples to the output colorspace.
+ *
+ * Note that we change from noninterleaved, one-plane-per-component format
+ * to interleaved-pixel format.  The output buffer is therefore three times
+ * as wide as the input buffer.
+ * A starting row offset is provided only for the input buffer.  The caller
+ * can easily adjust the passed output_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+METHODDEF(void)
+ycc_rgb_convert (j_decompress_ptr cinfo,
+		 JSAMPIMAGE input_buf, JDIMENSION input_row,
+		 JSAMPARRAY output_buf, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int y, cb, cr;
+  register JSAMPROW outptr;
+  register JSAMPROW inptr0, inptr1, inptr2;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+  /* copy these pointers into registers if possible */
+  register JSAMPLE * range_limit = cinfo->sample_range_limit;
+  register int * Crrtab = cconvert->Cr_r_tab;
+  register int * Cbbtab = cconvert->Cb_b_tab;
+  register INT32 * Crgtab = cconvert->Cr_g_tab;
+  register INT32 * Cbgtab = cconvert->Cb_g_tab;
+  SHIFT_TEMPS
+
+  while (--num_rows >= 0) {
+    inptr0 = input_buf[0][input_row];
+    inptr1 = input_buf[1][input_row];
+    inptr2 = input_buf[2][input_row];
+    input_row++;
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      y  = GETJSAMPLE(inptr0[col]);
+      cb = GETJSAMPLE(inptr1[col]);
+      cr = GETJSAMPLE(inptr2[col]);
+      /* Range-limiting is essential due to noise introduced by DCT losses. */
+      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
+      outptr[RGB_GREEN] = range_limit[y +
+			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
+						 SCALEBITS))];
+      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
+      outptr += RGB_PIXELSIZE;
+    }
+  }
+}
+
+
+/**************** Cases other than YCbCr -> RGB **************/
+
+
+/*
+ * Color conversion for no colorspace change: just copy the data,
+ * converting from separate-planes to interleaved representation.
+ */
+
+METHODDEF(void)
+null_convert (j_decompress_ptr cinfo,
+	      JSAMPIMAGE input_buf, JDIMENSION input_row,
+	      JSAMPARRAY output_buf, int num_rows)
+{
+  register JSAMPROW inptr, outptr;
+  register JDIMENSION count;
+  register int num_components = cinfo->num_components;
+  JDIMENSION num_cols = cinfo->output_width;
+  int ci;
+
+  while (--num_rows >= 0) {
+    for (ci = 0; ci < num_components; ci++) {
+      inptr = input_buf[ci][input_row];
+      outptr = output_buf[0] + ci;
+      for (count = num_cols; count > 0; count--) {
+	*outptr = *inptr++;	/* needn't bother with GETJSAMPLE() here */
+	outptr += num_components;
+      }
+    }
+    input_row++;
+    output_buf++;
+  }
+}
+
+
+/*
+ * Color conversion for grayscale: just copy the data.
+ * This also works for YCbCr -> grayscale conversion, in which
+ * we just copy the Y (luminance) component and ignore chrominance.
+ */
+
+METHODDEF(void)
+grayscale_convert (j_decompress_ptr cinfo,
+		   JSAMPIMAGE input_buf, JDIMENSION input_row,
+		   JSAMPARRAY output_buf, int num_rows)
+{
+  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
+		    num_rows, cinfo->output_width);
+}
+
+
+/*
+ * Convert grayscale to RGB: just duplicate the graylevel three times.
+ * This is provided to support applications that don't want to cope
+ * with grayscale as a separate case.
+ */
+
+METHODDEF(void)
+gray_rgb_convert (j_decompress_ptr cinfo,
+		  JSAMPIMAGE input_buf, JDIMENSION input_row,
+		  JSAMPARRAY output_buf, int num_rows)
+{
+  register JSAMPROW inptr, outptr;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+
+  while (--num_rows >= 0) {
+    inptr = input_buf[0][input_row++];
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      /* We can dispense with GETJSAMPLE() here */
+      outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
+      outptr += RGB_PIXELSIZE;
+    }
+  }
+}
+
+
+/*
+ * Adobe-style YCCK->CMYK conversion.
+ * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
+ * conversion as above, while passing K (black) unchanged.
+ * We assume build_ycc_rgb_table has been called.
+ */
+
+METHODDEF(void)
+ycck_cmyk_convert (j_decompress_ptr cinfo,
+		   JSAMPIMAGE input_buf, JDIMENSION input_row,
+		   JSAMPARRAY output_buf, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int y, cb, cr;
+  register JSAMPROW outptr;
+  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+  /* copy these pointers into registers if possible */
+  register JSAMPLE * range_limit = cinfo->sample_range_limit;
+  register int * Crrtab = cconvert->Cr_r_tab;
+  register int * Cbbtab = cconvert->Cb_b_tab;
+  register INT32 * Crgtab = cconvert->Cr_g_tab;
+  register INT32 * Cbgtab = cconvert->Cb_g_tab;
+  SHIFT_TEMPS
+
+  while (--num_rows >= 0) {
+    inptr0 = input_buf[0][input_row];
+    inptr1 = input_buf[1][input_row];
+    inptr2 = input_buf[2][input_row];
+    inptr3 = input_buf[3][input_row];
+    input_row++;
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      y  = GETJSAMPLE(inptr0[col]);
+      cb = GETJSAMPLE(inptr1[col]);
+      cr = GETJSAMPLE(inptr2[col]);
+      /* Range-limiting is essential due to noise introduced by DCT losses. */
+      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */
+      outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */
+			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
+						 SCALEBITS)))];
+      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];	/* blue */
+      /* K passes through unchanged */
+      outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */
+      outptr += 4;
+    }
+  }
+}
+
+
+/*
+ * Empty method for start_pass.
+ */
+
+METHODDEF(void)
+start_pass_dcolor (j_decompress_ptr cinfo)
+{
+  /* no work needed */
+}
+
+
+/*
+ * Module initialization routine for output colorspace conversion.
+ */
+
+GLOBAL(void)
+jinit_color_deconverter (j_decompress_ptr cinfo)
+{
+  my_cconvert_ptr cconvert;
+  int ci;
+
+  cconvert = (my_cconvert_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_color_deconverter));
+  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
+  cconvert->pub.start_pass = start_pass_dcolor;
+
+  /* Make sure num_components agrees with jpeg_color_space */
+  switch (cinfo->jpeg_color_space) {
+  case JCS_GRAYSCALE:
+    if (cinfo->num_components != 1)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    break;
+
+  case JCS_RGB:
+  case JCS_YCbCr:
+    if (cinfo->num_components != 3)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    break;
+
+  case JCS_CMYK:
+  case JCS_YCCK:
+    if (cinfo->num_components != 4)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    break;
+
+  default:			/* JCS_UNKNOWN can be anything */
+    if (cinfo->num_components < 1)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    break;
+  }
+
+  /* Set out_color_components and conversion method based on requested space.
+   * Also clear the component_needed flags for any unused components,
+   * so that earlier pipeline stages can avoid useless computation.
+   */
+
+  switch (cinfo->out_color_space) {
+  case JCS_GRAYSCALE:
+    cinfo->out_color_components = 1;
+    if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
+	cinfo->jpeg_color_space == JCS_YCbCr) {
+      cconvert->pub.color_convert = grayscale_convert;
+      /* For color->grayscale conversion, only the Y (0) component is needed */
+      for (ci = 1; ci < cinfo->num_components; ci++)
+	cinfo->comp_info[ci].component_needed = FALSE;
+    } else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  case JCS_RGB:
+    cinfo->out_color_components = RGB_PIXELSIZE;
+    if (cinfo->jpeg_color_space == JCS_YCbCr) {
+      cconvert->pub.color_convert = ycc_rgb_convert;
+      build_ycc_rgb_table(cinfo);
+    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
+      cconvert->pub.color_convert = gray_rgb_convert;
+    } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
+      cconvert->pub.color_convert = null_convert;
+    } else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  case JCS_CMYK:
+    cinfo->out_color_components = 4;
+    if (cinfo->jpeg_color_space == JCS_YCCK) {
+      cconvert->pub.color_convert = ycck_cmyk_convert;
+      build_ycc_rgb_table(cinfo);
+    } else if (cinfo->jpeg_color_space == JCS_CMYK) {
+      cconvert->pub.color_convert = null_convert;
+    } else
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+
+  default:
+    /* Permit null conversion to same output space */
+    if (cinfo->out_color_space == cinfo->jpeg_color_space) {
+      cinfo->out_color_components = cinfo->num_components;
+      cconvert->pub.color_convert = null_convert;
+    } else			/* unsupported non-null conversion */
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    break;
+  }
+
+  if (cinfo->quantize_colors)
+    cinfo->output_components = 1; /* single colormapped output component */
+  else
+    cinfo->output_components = cinfo->out_color_components;
+}
diff --git a/Utilities/FLTK/jpeg/jdct.h b/Utilities/FLTK/jpeg/jdct.h
new file mode 100644
index 0000000000000000000000000000000000000000..04192a266ae148072feecb5feff6bca796c2b71a
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdct.h
@@ -0,0 +1,176 @@
+/*
+ * jdct.h
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This include file contains common declarations for the forward and
+ * inverse DCT modules.  These declarations are private to the DCT managers
+ * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
+ * The individual DCT algorithms are kept in separate files to ease 
+ * machine-dependent tuning (e.g., assembly coding).
+ */
+
+
+/*
+ * A forward DCT routine is given a pointer to a work area of type DCTELEM[];
+ * the DCT is to be performed in-place in that buffer.  Type DCTELEM is int
+ * for 8-bit samples, INT32 for 12-bit samples.  (NOTE: Floating-point DCT
+ * implementations use an array of type FAST_FLOAT, instead.)
+ * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
+ * The DCT outputs are returned scaled up by a factor of 8; they therefore
+ * have a range of +-8K for 8-bit data, +-128K for 12-bit data.  This
+ * convention improves accuracy in integer implementations and saves some
+ * work in floating-point ones.
+ * Quantization of the output coefficients is done by jcdctmgr.c.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef int DCTELEM;		/* 16 or 32 bits is fine */
+#else
+typedef INT32 DCTELEM;		/* must have 32 bits */
+#endif
+
+typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
+typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
+
+
+/*
+ * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
+ * to an output sample array.  The routine must dequantize the input data as
+ * well as perform the IDCT; for dequantization, it uses the multiplier table
+ * pointed to by compptr->dct_table.  The output data is to be placed into the
+ * sample array starting at a specified column.  (Any row offset needed will
+ * be applied to the array pointer before it is passed to the IDCT code.)
+ * Note that the number of samples emitted by the IDCT routine is
+ * DCT_scaled_size * DCT_scaled_size.
+ */
+
+/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
+
+/*
+ * Each IDCT routine has its own ideas about the best dct_table element type.
+ */
+
+typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
+#if BITS_IN_JSAMPLE == 8
+typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
+#define IFAST_SCALE_BITS  2	/* fractional bits in scale factors */
+#else
+typedef INT32 IFAST_MULT_TYPE;	/* need 32 bits for scaled quantizers */
+#define IFAST_SCALE_BITS  13	/* fractional bits in scale factors */
+#endif
+typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
+
+
+/*
+ * Each IDCT routine is responsible for range-limiting its results and
+ * converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
+ * be quite far out of range if the input data is corrupt, so a bulletproof
+ * range-limiting step is required.  We use a mask-and-table-lookup method
+ * to do the combined operations quickly.  See the comments with
+ * prepare_range_limit_table (in jdmaster.c) for more info.
+ */
+
+#define IDCT_range_limit(cinfo)  ((cinfo)->sample_range_limit + CENTERJSAMPLE)
+
+#define RANGE_MASK  (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_fdct_islow		jFDislow
+#define jpeg_fdct_ifast		jFDifast
+#define jpeg_fdct_float		jFDfloat
+#define jpeg_idct_islow		jRDislow
+#define jpeg_idct_ifast		jRDifast
+#define jpeg_idct_float		jRDfloat
+#define jpeg_idct_4x4		jRD4x4
+#define jpeg_idct_2x2		jRD2x2
+#define jpeg_idct_1x1		jRD1x1
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+/* Extern declarations for the forward and inverse DCT routines. */
+
+EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
+EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
+EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
+
+EXTERN(void) jpeg_idct_islow
+    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_ifast
+    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_float
+    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_4x4
+    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_2x2
+    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_1x1
+    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+
+
+/*
+ * Macros for handling fixed-point arithmetic; these are used by many
+ * but not all of the DCT/IDCT modules.
+ *
+ * All values are expected to be of type INT32.
+ * Fractional constants are scaled left by CONST_BITS bits.
+ * CONST_BITS is defined within each module using these macros,
+ * and may differ from one module to the next.
+ */
+
+#define ONE	((INT32) 1)
+#define CONST_SCALE (ONE << CONST_BITS)
+
+/* Convert a positive real constant to an integer scaled by CONST_SCALE.
+ * Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
+ * thus causing a lot of useless floating-point operations at run time.
+ */
+
+#define FIX(x)	((INT32) ((x) * CONST_SCALE + 0.5))
+
+/* Descale and correctly round an INT32 value that's scaled by N bits.
+ * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
+ * the fudge factor is correct for either sign of X.
+ */
+
+#define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * This macro is used only when the two inputs will actually be no more than
+ * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
+ * full 32x32 multiply.  This provides a useful speedup on many machines.
+ * Unfortunately there is no way to specify a 16x16->32 multiply portably
+ * in C, but some C compilers will do the right thing if you provide the
+ * correct combination of casts.
+ */
+
+#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */
+#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT16) (const)))
+#endif
+#ifdef SHORTxLCONST_32		/* known to work with Microsoft C 6.0 */
+#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT32) (const)))
+#endif
+
+#ifndef MULTIPLY16C16		/* default definition */
+#define MULTIPLY16C16(var,const)  ((var) * (const))
+#endif
+
+/* Same except both inputs are variables. */
+
+#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */
+#define MULTIPLY16V16(var1,var2)  (((INT16) (var1)) * ((INT16) (var2)))
+#endif
+
+#ifndef MULTIPLY16V16		/* default definition */
+#define MULTIPLY16V16(var1,var2)  ((var1) * (var2))
+#endif
diff --git a/Utilities/FLTK/jpeg/jddctmgr.c b/Utilities/FLTK/jpeg/jddctmgr.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbf8d0e92fdd84ddaa0017a2df039d224a740898
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jddctmgr.c
@@ -0,0 +1,269 @@
+/*
+ * jddctmgr.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the inverse-DCT management logic.
+ * This code selects a particular IDCT implementation to be used,
+ * and it performs related housekeeping chores.  No code in this file
+ * is executed per IDCT step, only during output pass setup.
+ *
+ * Note that the IDCT routines are responsible for performing coefficient
+ * dequantization as well as the IDCT proper.  This module sets up the
+ * dequantization multiplier table needed by the IDCT routine.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+
+/*
+ * The decompressor input side (jdinput.c) saves away the appropriate
+ * quantization table for each component at the start of the first scan
+ * involving that component.  (This is necessary in order to correctly
+ * decode files that reuse Q-table slots.)
+ * When we are ready to make an output pass, the saved Q-table is converted
+ * to a multiplier table that will actually be used by the IDCT routine.
+ * The multiplier table contents are IDCT-method-dependent.  To support
+ * application changes in IDCT method between scans, we can remake the
+ * multiplier tables if necessary.
+ * In buffered-image mode, the first output pass may occur before any data
+ * has been seen for some components, and thus before their Q-tables have
+ * been saved away.  To handle this case, multiplier tables are preset
+ * to zeroes; the result of the IDCT will be a neutral gray level.
+ */
+
+
+/* Private subobject for this module */
+
+typedef struct {
+  struct jpeg_inverse_dct pub;	/* public fields */
+
+  /* This array contains the IDCT method code that each multiplier table
+   * is currently set up for, or -1 if it's not yet set up.
+   * The actual multiplier tables are pointed to by dct_table in the
+   * per-component comp_info structures.
+   */
+  int cur_method[MAX_COMPONENTS];
+} my_idct_controller;
+
+typedef my_idct_controller * my_idct_ptr;
+
+
+/* Allocated multiplier tables: big enough for any supported variant */
+
+typedef union {
+  ISLOW_MULT_TYPE islow_array[DCTSIZE2];
+#ifdef DCT_IFAST_SUPPORTED
+  IFAST_MULT_TYPE ifast_array[DCTSIZE2];
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+  FLOAT_MULT_TYPE float_array[DCTSIZE2];
+#endif
+} multiplier_table;
+
+
+/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
+ * so be sure to compile that code if either ISLOW or SCALING is requested.
+ */
+#ifdef DCT_ISLOW_SUPPORTED
+#define PROVIDE_ISLOW_TABLES
+#else
+#ifdef IDCT_SCALING_SUPPORTED
+#define PROVIDE_ISLOW_TABLES
+#endif
+#endif
+
+
+/*
+ * Prepare for an output pass.
+ * Here we select the proper IDCT routine for each component and build
+ * a matching multiplier table.
+ */
+
+METHODDEF(void)
+start_pass (j_decompress_ptr cinfo)
+{
+  my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
+  int ci, i;
+  jpeg_component_info *compptr;
+  int method = 0;
+  inverse_DCT_method_ptr method_ptr = NULL;
+  JQUANT_TBL * qtbl;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Select the proper IDCT routine for this component's scaling */
+    switch (compptr->DCT_scaled_size) {
+#ifdef IDCT_SCALING_SUPPORTED
+    case 1:
+      method_ptr = jpeg_idct_1x1;
+      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
+      break;
+    case 2:
+      method_ptr = jpeg_idct_2x2;
+      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
+      break;
+    case 4:
+      method_ptr = jpeg_idct_4x4;
+      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
+      break;
+#endif
+    case DCTSIZE:
+      switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+      case JDCT_ISLOW:
+	method_ptr = jpeg_idct_islow;
+	method = JDCT_ISLOW;
+	break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+      case JDCT_IFAST:
+	method_ptr = jpeg_idct_ifast;
+	method = JDCT_IFAST;
+	break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+      case JDCT_FLOAT:
+	method_ptr = jpeg_idct_float;
+	method = JDCT_FLOAT;
+	break;
+#endif
+      default:
+	ERREXIT(cinfo, JERR_NOT_COMPILED);
+	break;
+      }
+      break;
+    default:
+      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
+      break;
+    }
+    idct->pub.inverse_DCT[ci] = method_ptr;
+    /* Create multiplier table from quant table.
+     * However, we can skip this if the component is uninteresting
+     * or if we already built the table.  Also, if no quant table
+     * has yet been saved for the component, we leave the
+     * multiplier table all-zero; we'll be reading zeroes from the
+     * coefficient controller's buffer anyway.
+     */
+    if (! compptr->component_needed || idct->cur_method[ci] == method)
+      continue;
+    qtbl = compptr->quant_table;
+    if (qtbl == NULL)		/* happens if no data yet for component */
+      continue;
+    idct->cur_method[ci] = method;
+    switch (method) {
+#ifdef PROVIDE_ISLOW_TABLES
+    case JDCT_ISLOW:
+      {
+	/* For LL&M IDCT method, multipliers are equal to raw quantization
+	 * coefficients, but are stored as ints to ensure access efficiency.
+	 */
+	ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
+	for (i = 0; i < DCTSIZE2; i++) {
+	  ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
+	}
+      }
+      break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+    case JDCT_IFAST:
+      {
+	/* For AA&N IDCT method, multipliers are equal to quantization
+	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
+	 *   scalefactor[0] = 1
+	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
+	 * For integer operation, the multiplier table is to be scaled by
+	 * IFAST_SCALE_BITS.
+	 */
+	IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
+#define CONST_BITS 14
+	static const INT16 aanscales[DCTSIZE2] = {
+	  /* precomputed values scaled up by 14 bits */
+	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
+	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
+	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
+	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
+	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
+	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
+	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
+	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
+	};
+	SHIFT_TEMPS
+
+	for (i = 0; i < DCTSIZE2; i++) {
+	  ifmtbl[i] = (IFAST_MULT_TYPE)
+	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
+				  (INT32) aanscales[i]),
+		    CONST_BITS-IFAST_SCALE_BITS);
+	}
+      }
+      break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+    case JDCT_FLOAT:
+      {
+	/* For float AA&N IDCT method, multipliers are equal to quantization
+	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
+	 *   scalefactor[0] = 1
+	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
+	 */
+	FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
+	int row, col;
+	static const double aanscalefactor[DCTSIZE] = {
+	  1.0, 1.387039845, 1.306562965, 1.175875602,
+	  1.0, 0.785694958, 0.541196100, 0.275899379
+	};
+
+	i = 0;
+	for (row = 0; row < DCTSIZE; row++) {
+	  for (col = 0; col < DCTSIZE; col++) {
+	    fmtbl[i] = (FLOAT_MULT_TYPE)
+	      ((double) qtbl->quantval[i] *
+	       aanscalefactor[row] * aanscalefactor[col]);
+	    i++;
+	  }
+	}
+      }
+      break;
+#endif
+    default:
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+      break;
+    }
+  }
+}
+
+
+/*
+ * Initialize IDCT manager.
+ */
+
+GLOBAL(void)
+jinit_inverse_dct (j_decompress_ptr cinfo)
+{
+  my_idct_ptr idct;
+  int ci;
+  jpeg_component_info *compptr;
+
+  idct = (my_idct_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_idct_controller));
+  cinfo->idct = (struct jpeg_inverse_dct *) idct;
+  idct->pub.start_pass = start_pass;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Allocate and pre-zero a multiplier table for each component */
+    compptr->dct_table =
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(multiplier_table));
+    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
+    /* Mark multiplier table not yet set up for any method */
+    idct->cur_method[ci] = -1;
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jdhuff.c b/Utilities/FLTK/jpeg/jdhuff.c
new file mode 100644
index 0000000000000000000000000000000000000000..b5ba39f736a7ae4f059d4b0594f4cc8ff854e1f4
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdhuff.c
@@ -0,0 +1,651 @@
+/*
+ * jdhuff.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy decoding routines.
+ *
+ * Much of the complexity here has to do with supporting input suspension.
+ * If the data source module demands suspension, we want to be able to back
+ * up to the start of the current MCU.  To do this, we copy state variables
+ * into local working storage, and update them back to the permanent
+ * storage only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdhuff.h"		/* Declarations shared with jdphuff.c */
+
+
+/*
+ * Expanded entropy decoder object for Huffman decoding.
+ *
+ * The savable_state subrecord contains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment.  You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src)  ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src)  \
+	((dest).last_dc_val[0] = (src).last_dc_val[0], \
+	 (dest).last_dc_val[1] = (src).last_dc_val[1], \
+	 (dest).last_dc_val[2] = (src).last_dc_val[2], \
+	 (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+  struct jpeg_entropy_decoder pub; /* public fields */
+
+  /* These fields are loaded into local variables at start of each MCU.
+   * In case of suspension, we exit WITHOUT updating them.
+   */
+  bitread_perm_state bitstate;	/* Bit buffer at start of MCU */
+  savable_state saved;		/* Other state at start of MCU */
+
+  /* These fields are NOT loaded into local working state. */
+  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
+
+  /* Pointers to derived tables (these workspaces have image lifespan) */
+  d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
+  d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+
+  /* Precalculated info set up by start_pass for use in decode_mcu: */
+
+  /* Pointers to derived tables to be used for each block within an MCU */
+  d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+  d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+  /* Whether we care about the DC and AC coefficient values for each block */
+  boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
+  boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
+} huff_entropy_decoder;
+
+typedef huff_entropy_decoder * huff_entropy_ptr;
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass_huff_decoder (j_decompress_ptr cinfo)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  int ci, blkn, dctbl, actbl;
+  jpeg_component_info * compptr;
+
+  /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
+   * This ought to be an error condition, but we make it a warning because
+   * there are some baseline files out there with all zeroes in these bytes.
+   */
+  if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
+      cinfo->Ah != 0 || cinfo->Al != 0)
+    WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    dctbl = compptr->dc_tbl_no;
+    actbl = compptr->ac_tbl_no;
+    /* Compute derived values for Huffman tables */
+    /* We may do this more than once for a table, but it's not expensive */
+    jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
+			    & entropy->dc_derived_tbls[dctbl]);
+    jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
+			    & entropy->ac_derived_tbls[actbl]);
+    /* Initialize DC predictions to 0 */
+    entropy->saved.last_dc_val[ci] = 0;
+  }
+
+  /* Precalculate decoding info for each block in an MCU of this scan */
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+    /* Precalculate which table to use for each block */
+    entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
+    entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
+    /* Decide whether we really care about the coefficient values */
+    if (compptr->component_needed) {
+      entropy->dc_needed[blkn] = TRUE;
+      /* we don't need the ACs if producing a 1/8th-size image */
+      entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
+    } else {
+      entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
+    }
+  }
+
+  /* Initialize bitread state variables */
+  entropy->bitstate.bits_left = 0;
+  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
+  entropy->pub.insufficient_data = FALSE;
+
+  /* Initialize restart counter */
+  entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
+ * Note this is also used by jdphuff.c.
+ */
+
+GLOBAL(void)
+jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
+			 d_derived_tbl ** pdtbl)
+{
+  JHUFF_TBL *htbl;
+  d_derived_tbl *dtbl;
+  int p, i, l, si, numsymbols;
+  int lookbits, ctr;
+  char huffsize[257];
+  unsigned int huffcode[257];
+  unsigned int code;
+
+  /* Note that huffsize[] and huffcode[] are filled in code-length order,
+   * paralleling the order of the symbols themselves in htbl->huffval[].
+   */
+
+  /* Find the input Huffman table */
+  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+  htbl =
+    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+  if (htbl == NULL)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
+  /* Allocate a workspace if we haven't already done so. */
+  if (*pdtbl == NULL)
+    *pdtbl = (d_derived_tbl *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(d_derived_tbl));
+  dtbl = *pdtbl;
+  dtbl->pub = htbl;		/* fill in back link */
+  
+  /* Figure C.1: make table of Huffman code length for each symbol */
+
+  p = 0;
+  for (l = 1; l <= 16; l++) {
+    i = (int) htbl->bits[l];
+    if (i < 0 || p + i > 256)	/* protect against table overrun */
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    while (i--)
+      huffsize[p++] = (char) l;
+  }
+  huffsize[p] = 0;
+  numsymbols = p;
+  
+  /* Figure C.2: generate the codes themselves */
+  /* We also validate that the counts represent a legal Huffman code tree. */
+  
+  code = 0;
+  si = huffsize[0];
+  p = 0;
+  while (huffsize[p]) {
+    while (((int) huffsize[p]) == si) {
+      huffcode[p++] = code;
+      code++;
+    }
+    /* code is now 1 more than the last code used for codelength si; but
+     * it must still fit in si bits, since no code is allowed to be all ones.
+     */
+    if (((INT32) code) >= (((INT32) 1) << si))
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    code <<= 1;
+    si++;
+  }
+
+  /* Figure F.15: generate decoding tables for bit-sequential decoding */
+
+  p = 0;
+  for (l = 1; l <= 16; l++) {
+    if (htbl->bits[l]) {
+      /* valoffset[l] = huffval[] index of 1st symbol of code length l,
+       * minus the minimum code of length l
+       */
+      dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
+      p += htbl->bits[l];
+      dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
+    } else {
+      dtbl->maxcode[l] = -1;	/* -1 if no codes of this length */
+    }
+  }
+  dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
+
+  /* Compute lookahead tables to speed up decoding.
+   * First we set all the table entries to 0, indicating "too long";
+   * then we iterate through the Huffman codes that are short enough and
+   * fill in all the entries that correspond to bit sequences starting
+   * with that code.
+   */
+
+  MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
+
+  p = 0;
+  for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
+    for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
+      /* l = current code's length, p = its index in huffcode[] & huffval[]. */
+      /* Generate left-justified code followed by all possible bit sequences */
+      lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
+      for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
+	dtbl->look_nbits[lookbits] = l;
+	dtbl->look_sym[lookbits] = htbl->huffval[p];
+	lookbits++;
+      }
+    }
+  }
+
+  /* Validate symbols as being reasonable.
+   * For AC tables, we make no check, but accept all byte values 0..255.
+   * For DC tables, we require the symbols to be in range 0..15.
+   * (Tighter bounds could be applied depending on the data depth and mode,
+   * but this is sufficient to ensure safe decoding.)
+   */
+  if (isDC) {
+    for (i = 0; i < numsymbols; i++) {
+      int sym = htbl->huffval[i];
+      if (sym < 0 || sym > 15)
+	ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    }
+  }
+}
+
+
+/*
+ * Out-of-line code for bit fetching (shared with jdphuff.c).
+ * See jdhuff.h for info about usage.
+ * Note: current values of get_buffer and bits_left are passed as parameters,
+ * but are returned in the corresponding fields of the state struct.
+ *
+ * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
+ * of get_buffer to be used.  (On machines with wider words, an even larger
+ * buffer could be used.)  However, on some machines 32-bit shifts are
+ * quite slow and take time proportional to the number of places shifted.
+ * (This is true with most PC compilers, for instance.)  In this case it may
+ * be a win to set MIN_GET_BITS to the minimum value of 15.  This reduces the
+ * average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
+ */
+
+#ifdef SLOW_SHIFT_32
+#define MIN_GET_BITS  15	/* minimum allowable value */
+#else
+#define MIN_GET_BITS  (BIT_BUF_SIZE-7)
+#endif
+
+
+GLOBAL(boolean)
+jpeg_fill_bit_buffer (bitread_working_state * state,
+		      register bit_buf_type get_buffer, register int bits_left,
+		      int nbits)
+/* Load up the bit buffer to a depth of at least nbits */
+{
+  /* Copy heavily used state fields into locals (hopefully registers) */
+  register const JOCTET * next_input_byte = state->next_input_byte;
+  register size_t bytes_in_buffer = state->bytes_in_buffer;
+  j_decompress_ptr cinfo = state->cinfo;
+
+  /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
+  /* (It is assumed that no request will be for more than that many bits.) */
+  /* We fail to do so only if we hit a marker or are forced to suspend. */
+
+  if (cinfo->unread_marker == 0) {	/* cannot advance past a marker */
+    while (bits_left < MIN_GET_BITS) {
+      register int c;
+
+      /* Attempt to read a byte */
+      if (bytes_in_buffer == 0) {
+	if (! (*cinfo->src->fill_input_buffer) (cinfo))
+	  return FALSE;
+	next_input_byte = cinfo->src->next_input_byte;
+	bytes_in_buffer = cinfo->src->bytes_in_buffer;
+      }
+      bytes_in_buffer--;
+      c = GETJOCTET(*next_input_byte++);
+
+      /* If it's 0xFF, check and discard stuffed zero byte */
+      if (c == 0xFF) {
+	/* Loop here to discard any padding FF's on terminating marker,
+	 * so that we can save a valid unread_marker value.  NOTE: we will
+	 * accept multiple FF's followed by a 0 as meaning a single FF data
+	 * byte.  This data pattern is not valid according to the standard.
+	 */
+	do {
+	  if (bytes_in_buffer == 0) {
+	    if (! (*cinfo->src->fill_input_buffer) (cinfo))
+	      return FALSE;
+	    next_input_byte = cinfo->src->next_input_byte;
+	    bytes_in_buffer = cinfo->src->bytes_in_buffer;
+	  }
+	  bytes_in_buffer--;
+	  c = GETJOCTET(*next_input_byte++);
+	} while (c == 0xFF);
+
+	if (c == 0) {
+	  /* Found FF/00, which represents an FF data byte */
+	  c = 0xFF;
+	} else {
+	  /* Oops, it's actually a marker indicating end of compressed data.
+	   * Save the marker code for later use.
+	   * Fine point: it might appear that we should save the marker into
+	   * bitread working state, not straight into permanent state.  But
+	   * once we have hit a marker, we cannot need to suspend within the
+	   * current MCU, because we will read no more bytes from the data
+	   * source.  So it is OK to update permanent state right away.
+	   */
+	  cinfo->unread_marker = c;
+	  /* See if we need to insert some fake zero bits. */
+	  goto no_more_bytes;
+	}
+      }
+
+      /* OK, load c into get_buffer */
+      get_buffer = (get_buffer << 8) | c;
+      bits_left += 8;
+    } /* end while */
+  } else {
+  no_more_bytes:
+    /* We get here if we've read the marker that terminates the compressed
+     * data segment.  There should be enough bits in the buffer register
+     * to satisfy the request; if so, no problem.
+     */
+    if (nbits > bits_left) {
+      /* Uh-oh.  Report corrupted data to user and stuff zeroes into
+       * the data stream, so that we can produce some kind of image.
+       * We use a nonvolatile flag to ensure that only one warning message
+       * appears per data segment.
+       */
+      if (! cinfo->entropy->insufficient_data) {
+	WARNMS(cinfo, JWRN_HIT_MARKER);
+	cinfo->entropy->insufficient_data = TRUE;
+      }
+      /* Fill the buffer with zero bits */
+      get_buffer <<= MIN_GET_BITS - bits_left;
+      bits_left = MIN_GET_BITS;
+    }
+  }
+
+  /* Unload the local registers */
+  state->next_input_byte = next_input_byte;
+  state->bytes_in_buffer = bytes_in_buffer;
+  state->get_buffer = get_buffer;
+  state->bits_left = bits_left;
+
+  return TRUE;
+}
+
+
+/*
+ * Out-of-line code for Huffman code decoding.
+ * See jdhuff.h for info about usage.
+ */
+
+GLOBAL(int)
+jpeg_huff_decode (bitread_working_state * state,
+		  register bit_buf_type get_buffer, register int bits_left,
+		  d_derived_tbl * htbl, int min_bits)
+{
+  register int l = min_bits;
+  register INT32 code;
+
+  /* HUFF_DECODE has determined that the code is at least min_bits */
+  /* bits long, so fetch that many bits in one swoop. */
+
+  CHECK_BIT_BUFFER(*state, l, return -1);
+  code = GET_BITS(l);
+
+  /* Collect the rest of the Huffman code one bit at a time. */
+  /* This is per Figure F.16 in the JPEG spec. */
+
+  while (code > htbl->maxcode[l]) {
+    code <<= 1;
+    CHECK_BIT_BUFFER(*state, 1, return -1);
+    code |= GET_BITS(1);
+    l++;
+  }
+
+  /* Unload the local registers */
+  state->get_buffer = get_buffer;
+  state->bits_left = bits_left;
+
+  /* With garbage input we may reach the sentinel value l = 17. */
+
+  if (l > 16) {
+    WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
+    return 0;			/* fake a zero as the safest result */
+  }
+
+  return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
+}
+
+
+/*
+ * Figure F.12: extend sign bit.
+ * On some machines, a shift and add will be faster than a table lookup.
+ */
+
+#ifdef AVOID_TABLES
+
+#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
+
+#else
+
+#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
+
+static const int extend_test[16] =   /* entry n is 2**(n-1) */
+  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+
+static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
+  { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
+    ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
+    ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
+    ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
+
+#endif /* AVOID_TABLES */
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ * Returns FALSE if must suspend.
+ */
+
+LOCAL(boolean)
+process_restart (j_decompress_ptr cinfo)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  int ci;
+
+  /* Throw away any unused bits remaining in bit buffer; */
+  /* include any full bytes in next_marker's count of discarded bytes */
+  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
+  entropy->bitstate.bits_left = 0;
+
+  /* Advance past the RSTn marker */
+  if (! (*cinfo->marker->read_restart_marker) (cinfo))
+    return FALSE;
+
+  /* Re-initialize DC predictions to 0 */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+    entropy->saved.last_dc_val[ci] = 0;
+
+  /* Reset restart counter */
+  entropy->restarts_to_go = cinfo->restart_interval;
+
+  /* Reset out-of-data flag, unless read_restart_marker left us smack up
+   * against a marker.  In that case we will end up treating the next data
+   * segment as empty, and we can avoid producing bogus output pixels by
+   * leaving the flag set.
+   */
+  if (cinfo->unread_marker == 0)
+    entropy->pub.insufficient_data = FALSE;
+
+  return TRUE;
+}
+
+
+/*
+ * Decode and return one MCU's worth of Huffman-compressed coefficients.
+ * The coefficients are reordered from zigzag order into natural array order,
+ * but are not dequantized.
+ *
+ * The i'th block of the MCU is stored into the block pointed to by
+ * MCU_data[i].  WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
+ * (Wholesale zeroing is usually a little faster than retail...)
+ *
+ * Returns FALSE if data source requested suspension.  In that case no
+ * changes have been made to permanent state.  (Exception: some output
+ * coefficients may already have been assigned.  This is harmless for
+ * this module, since we'll just re-assign them on the next call.)
+ */
+
+METHODDEF(boolean)
+decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  int blkn;
+  BITREAD_STATE_VARS;
+  savable_state state;
+
+  /* Process restart marker if needed; may have to suspend */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0)
+      if (! process_restart(cinfo))
+	return FALSE;
+  }
+
+  /* If we've run out of data, just leave the MCU set to zeroes.
+   * This way, we return uniform gray for the remainder of the segment.
+   */
+  if (! entropy->pub.insufficient_data) {
+
+    /* Load up working state */
+    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(state, entropy->saved);
+
+    /* Outer loop handles each block in the MCU */
+
+    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+      JBLOCKROW block = MCU_data[blkn];
+      d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
+      d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
+      register int s, k, r;
+
+      /* Decode a single block's worth of coefficients */
+
+      /* Section F.2.2.1: decode the DC coefficient difference */
+      HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
+      if (s) {
+	CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	r = GET_BITS(s);
+	s = HUFF_EXTEND(r, s);
+      }
+
+      if (entropy->dc_needed[blkn]) {
+	/* Convert DC difference to actual value, update last_dc_val */
+	int ci = cinfo->MCU_membership[blkn];
+	s += state.last_dc_val[ci];
+	state.last_dc_val[ci] = s;
+	/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
+	(*block)[0] = (JCOEF) s;
+      }
+
+      if (entropy->ac_needed[blkn]) {
+
+	/* Section F.2.2.2: decode the AC coefficients */
+	/* Since zeroes are skipped, output area must be cleared beforehand */
+	for (k = 1; k < DCTSIZE2; k++) {
+	  HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
+      
+	  r = s >> 4;
+	  s &= 15;
+      
+	  if (s) {
+	    k += r;
+	    CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	    r = GET_BITS(s);
+	    s = HUFF_EXTEND(r, s);
+	    /* Output coefficient in natural (dezigzagged) order.
+	     * Note: the extra entries in jpeg_natural_order[] will save us
+	     * if k >= DCTSIZE2, which could happen if the data is corrupted.
+	     */
+	    (*block)[jpeg_natural_order[k]] = (JCOEF) s;
+	  } else {
+	    if (r != 15)
+	      break;
+	    k += 15;
+	  }
+	}
+
+      } else {
+
+	/* Section F.2.2.2: decode the AC coefficients */
+	/* In this path we just discard the values */
+	for (k = 1; k < DCTSIZE2; k++) {
+	  HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
+      
+	  r = s >> 4;
+	  s &= 15;
+      
+	  if (s) {
+	    k += r;
+	    CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	    DROP_BITS(s);
+	  } else {
+	    if (r != 15)
+	      break;
+	    k += 15;
+	  }
+	}
+
+      }
+    }
+
+    /* Completed MCU, so update state */
+    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(entropy->saved, state);
+  }
+
+  /* Account for restart interval (no-op if not using restarts) */
+  entropy->restarts_to_go--;
+
+  return TRUE;
+}
+
+
+/*
+ * Module initialization routine for Huffman entropy decoding.
+ */
+
+GLOBAL(void)
+jinit_huff_decoder (j_decompress_ptr cinfo)
+{
+  huff_entropy_ptr entropy;
+  int i;
+
+  entropy = (huff_entropy_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(huff_entropy_decoder));
+  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+  entropy->pub.start_pass = start_pass_huff_decoder;
+  entropy->pub.decode_mcu = decode_mcu;
+
+  /* Mark tables unallocated */
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jdhuff.h b/Utilities/FLTK/jpeg/jdhuff.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae19b6cafd7e81f94499d92876a6cf88bcafda86
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdhuff.h
@@ -0,0 +1,201 @@
+/*
+ * jdhuff.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains declarations for Huffman entropy decoding routines
+ * that are shared between the sequential decoder (jdhuff.c) and the
+ * progressive decoder (jdphuff.c).  No other modules need to see these.
+ */
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_make_d_derived_tbl	jMkDDerived
+#define jpeg_fill_bit_buffer	jFilBitBuf
+#define jpeg_huff_decode	jHufDecode
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Derived data constructed for each Huffman table */
+
+#define HUFF_LOOKAHEAD	8	/* # of bits of lookahead */
+
+typedef struct {
+  /* Basic tables: (element [0] of each array is unused) */
+  INT32 maxcode[18];		/* largest code of length k (-1 if none) */
+  /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
+  INT32 valoffset[17];		/* huffval[] offset for codes of length k */
+  /* valoffset[k] = huffval[] index of 1st symbol of code length k, less
+   * the smallest code of length k; so given a code of length k, the
+   * corresponding symbol is huffval[code + valoffset[k]]
+   */
+
+  /* Link to public Huffman table (needed only in jpeg_huff_decode) */
+  JHUFF_TBL *pub;
+
+  /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
+   * the input data stream.  If the next Huffman code is no more
+   * than HUFF_LOOKAHEAD bits long, we can obtain its length and
+   * the corresponding symbol directly from these tables.
+   */
+  int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
+  UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
+} d_derived_tbl;
+
+/* Expand a Huffman table definition into the derived format */
+EXTERN(void) jpeg_make_d_derived_tbl
+	JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
+	     d_derived_tbl ** pdtbl));
+
+
+/*
+ * Fetching the next N bits from the input stream is a time-critical operation
+ * for the Huffman decoders.  We implement it with a combination of inline
+ * macros and out-of-line subroutines.  Note that N (the number of bits
+ * demanded at one time) never exceeds 15 for JPEG use.
+ *
+ * We read source bytes into get_buffer and dole out bits as needed.
+ * If get_buffer already contains enough bits, they are fetched in-line
+ * by the macros CHECK_BIT_BUFFER and GET_BITS.  When there aren't enough
+ * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
+ * as full as possible (not just to the number of bits needed; this
+ * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
+ * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
+ * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
+ * at least the requested number of bits --- dummy zeroes are inserted if
+ * necessary.
+ */
+
+typedef INT32 bit_buf_type;	/* type of bit-extraction buffer */
+#define BIT_BUF_SIZE  32	/* size of buffer in bits */
+
+/* If long is > 32 bits on your machine, and shifting/masking longs is
+ * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
+ * appropriately should be a win.  Unfortunately we can't define the size
+ * with something like  #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
+ * because not all machines measure sizeof in 8-bit bytes.
+ */
+
+typedef struct {		/* Bitreading state saved across MCUs */
+  bit_buf_type get_buffer;	/* current bit-extraction buffer */
+  int bits_left;		/* # of unused bits in it */
+} bitread_perm_state;
+
+typedef struct {		/* Bitreading working state within an MCU */
+  /* Current data source location */
+  /* We need a copy, rather than munging the original, in case of suspension */
+  const JOCTET * next_input_byte; /* => next byte to read from source */
+  size_t bytes_in_buffer;	/* # of bytes remaining in source buffer */
+  /* Bit input buffer --- note these values are kept in register variables,
+   * not in this struct, inside the inner loops.
+   */
+  bit_buf_type get_buffer;	/* current bit-extraction buffer */
+  int bits_left;		/* # of unused bits in it */
+  /* Pointer needed by jpeg_fill_bit_buffer. */
+  j_decompress_ptr cinfo;	/* back link to decompress master record */
+} bitread_working_state;
+
+/* Macros to declare and load/save bitread local variables. */
+#define BITREAD_STATE_VARS  \
+	register bit_buf_type get_buffer;  \
+	register int bits_left;  \
+	bitread_working_state br_state
+
+#define BITREAD_LOAD_STATE(cinfop,permstate)  \
+	br_state.cinfo = cinfop; \
+	br_state.next_input_byte = cinfop->src->next_input_byte; \
+	br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
+	get_buffer = permstate.get_buffer; \
+	bits_left = permstate.bits_left;
+
+#define BITREAD_SAVE_STATE(cinfop,permstate)  \
+	cinfop->src->next_input_byte = br_state.next_input_byte; \
+	cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
+	permstate.get_buffer = get_buffer; \
+	permstate.bits_left = bits_left
+
+/*
+ * These macros provide the in-line portion of bit fetching.
+ * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
+ * before using GET_BITS, PEEK_BITS, or DROP_BITS.
+ * The variables get_buffer and bits_left are assumed to be locals,
+ * but the state struct might not be (jpeg_huff_decode needs this).
+ *	CHECK_BIT_BUFFER(state,n,action);
+ *		Ensure there are N bits in get_buffer; if suspend, take action.
+ *      val = GET_BITS(n);
+ *		Fetch next N bits.
+ *      val = PEEK_BITS(n);
+ *		Fetch next N bits without removing them from the buffer.
+ *	DROP_BITS(n);
+ *		Discard next N bits.
+ * The value N should be a simple variable, not an expression, because it
+ * is evaluated multiple times.
+ */
+
+#define CHECK_BIT_BUFFER(state,nbits,action) \
+	{ if (bits_left < (nbits)) {  \
+	    if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits))  \
+	      { action; }  \
+	    get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
+
+#define GET_BITS(nbits) \
+	(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
+
+#define PEEK_BITS(nbits) \
+	(((int) (get_buffer >> (bits_left -  (nbits)))) & ((1<<(nbits))-1))
+
+#define DROP_BITS(nbits) \
+	(bits_left -= (nbits))
+
+/* Load up the bit buffer to a depth of at least nbits */
+EXTERN(boolean) jpeg_fill_bit_buffer
+	JPP((bitread_working_state * state, register bit_buf_type get_buffer,
+	     register int bits_left, int nbits));
+
+
+/*
+ * Code for extracting next Huffman-coded symbol from input bit stream.
+ * Again, this is time-critical and we make the main paths be macros.
+ *
+ * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
+ * without looping.  Usually, more than 95% of the Huffman codes will be 8
+ * or fewer bits long.  The few overlength codes are handled with a loop,
+ * which need not be inline code.
+ *
+ * Notes about the HUFF_DECODE macro:
+ * 1. Near the end of the data segment, we may fail to get enough bits
+ *    for a lookahead.  In that case, we do it the hard way.
+ * 2. If the lookahead table contains no entry, the next code must be
+ *    more than HUFF_LOOKAHEAD bits long.
+ * 3. jpeg_huff_decode returns -1 if forced to suspend.
+ */
+
+#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
+{ register int nb, look; \
+  if (bits_left < HUFF_LOOKAHEAD) { \
+    if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
+    get_buffer = state.get_buffer; bits_left = state.bits_left; \
+    if (bits_left < HUFF_LOOKAHEAD) { \
+      nb = 1; goto slowlabel; \
+    } \
+  } \
+  look = PEEK_BITS(HUFF_LOOKAHEAD); \
+  if ((nb = htbl->look_nbits[look]) != 0) { \
+    DROP_BITS(nb); \
+    result = htbl->look_sym[look]; \
+  } else { \
+    nb = HUFF_LOOKAHEAD+1; \
+slowlabel: \
+    if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
+	{ failaction; } \
+    get_buffer = state.get_buffer; bits_left = state.bits_left; \
+  } \
+}
+
+/* Out-of-line case for Huffman code fetching */
+EXTERN(int) jpeg_huff_decode
+	JPP((bitread_working_state * state, register bit_buf_type get_buffer,
+	     register int bits_left, d_derived_tbl * htbl, int min_bits));
diff --git a/Utilities/FLTK/jpeg/jdinput.c b/Utilities/FLTK/jpeg/jdinput.c
new file mode 100644
index 0000000000000000000000000000000000000000..0c2ac8f120bca16bff13b989d8879ac9db85a011
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdinput.c
@@ -0,0 +1,381 @@
+/*
+ * jdinput.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains input control logic for the JPEG decompressor.
+ * These routines are concerned with controlling the decompressor's input
+ * processing (marker reading and coefficient decoding).  The actual input
+ * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private state */
+
+typedef struct {
+  struct jpeg_input_controller pub; /* public fields */
+
+  boolean inheaders;		/* TRUE until first SOS is reached */
+} my_input_controller;
+
+typedef my_input_controller * my_inputctl_ptr;
+
+
+/* Forward declarations */
+METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Routines to calculate various quantities related to the size of the image.
+ */
+
+LOCAL(void)
+initial_setup (j_decompress_ptr cinfo)
+/* Called once, when first SOS marker is reached */
+{
+  int ci;
+  jpeg_component_info *compptr;
+
+  /* Make sure image isn't bigger than I can handle */
+  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
+      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
+    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
+
+  /* For now, precision must match compiled-in value... */
+  if (cinfo->data_precision != BITS_IN_JSAMPLE)
+    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
+  /* Check that number of components won't exceed internal array sizes */
+  if (cinfo->num_components > MAX_COMPONENTS)
+    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+	     MAX_COMPONENTS);
+
+  /* Compute maximum sampling factors; check factor validity */
+  cinfo->max_h_samp_factor = 1;
+  cinfo->max_v_samp_factor = 1;
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+	compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+      ERREXIT(cinfo, JERR_BAD_SAMPLING);
+    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+				   compptr->h_samp_factor);
+    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+				   compptr->v_samp_factor);
+  }
+
+  /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
+   * In the full decompressor, this will be overridden by jdmaster.c;
+   * but in the transcoder, jdmaster.c is not used, so we must do it here.
+   */
+  cinfo->min_DCT_scaled_size = DCTSIZE;
+
+  /* Compute dimensions of components */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    compptr->DCT_scaled_size = DCTSIZE;
+    /* Size in DCT blocks */
+    compptr->width_in_blocks = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
+    compptr->height_in_blocks = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
+    /* downsampled_width and downsampled_height will also be overridden by
+     * jdmaster.c if we are doing full decompression.  The transcoder library
+     * doesn't use these values, but the calling application might.
+     */
+    /* Size in samples */
+    compptr->downsampled_width = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+		    (long) cinfo->max_h_samp_factor);
+    compptr->downsampled_height = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+		    (long) cinfo->max_v_samp_factor);
+    /* Mark component needed, until color conversion says otherwise */
+    compptr->component_needed = TRUE;
+    /* Mark no quantization table yet saved for component */
+    compptr->quant_table = NULL;
+  }
+
+  /* Compute number of fully interleaved MCU rows. */
+  cinfo->total_iMCU_rows = (JDIMENSION)
+    jdiv_round_up((long) cinfo->image_height,
+		  (long) (cinfo->max_v_samp_factor*DCTSIZE));
+
+  /* Decide whether file contains multiple scans */
+  if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
+    cinfo->inputctl->has_multiple_scans = TRUE;
+  else
+    cinfo->inputctl->has_multiple_scans = FALSE;
+}
+
+
+LOCAL(void)
+per_scan_setup (j_decompress_ptr cinfo)
+/* Do computations that are needed before processing a JPEG scan */
+/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
+{
+  int ci, mcublks, tmp;
+  jpeg_component_info *compptr;
+  
+  if (cinfo->comps_in_scan == 1) {
+    
+    /* Noninterleaved (single-component) scan */
+    compptr = cinfo->cur_comp_info[0];
+    
+    /* Overall image size in MCUs */
+    cinfo->MCUs_per_row = compptr->width_in_blocks;
+    cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
+    
+    /* For noninterleaved scan, always one block per MCU */
+    compptr->MCU_width = 1;
+    compptr->MCU_height = 1;
+    compptr->MCU_blocks = 1;
+    compptr->MCU_sample_width = compptr->DCT_scaled_size;
+    compptr->last_col_width = 1;
+    /* For noninterleaved scans, it is convenient to define last_row_height
+     * as the number of block rows present in the last iMCU row.
+     */
+    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+    if (tmp == 0) tmp = compptr->v_samp_factor;
+    compptr->last_row_height = tmp;
+    
+    /* Prepare array describing MCU composition */
+    cinfo->blocks_in_MCU = 1;
+    cinfo->MCU_membership[0] = 0;
+    
+  } else {
+    
+    /* Interleaved (multi-component) scan */
+    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
+	       MAX_COMPS_IN_SCAN);
+    
+    /* Overall image size in MCUs */
+    cinfo->MCUs_per_row = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width,
+		    (long) (cinfo->max_h_samp_factor*DCTSIZE));
+    cinfo->MCU_rows_in_scan = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height,
+		    (long) (cinfo->max_v_samp_factor*DCTSIZE));
+    
+    cinfo->blocks_in_MCU = 0;
+    
+    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+      compptr = cinfo->cur_comp_info[ci];
+      /* Sampling factors give # of blocks of component in each MCU */
+      compptr->MCU_width = compptr->h_samp_factor;
+      compptr->MCU_height = compptr->v_samp_factor;
+      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+      compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
+      /* Figure number of non-dummy blocks in last MCU column & row */
+      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
+      if (tmp == 0) tmp = compptr->MCU_width;
+      compptr->last_col_width = tmp;
+      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
+      if (tmp == 0) tmp = compptr->MCU_height;
+      compptr->last_row_height = tmp;
+      /* Prepare array describing MCU composition */
+      mcublks = compptr->MCU_blocks;
+      if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
+	ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
+      while (mcublks-- > 0) {
+	cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+      }
+    }
+    
+  }
+}
+
+
+/*
+ * Save away a copy of the Q-table referenced by each component present
+ * in the current scan, unless already saved during a prior scan.
+ *
+ * In a multiple-scan JPEG file, the encoder could assign different components
+ * the same Q-table slot number, but change table definitions between scans
+ * so that each component uses a different Q-table.  (The IJG encoder is not
+ * currently capable of doing this, but other encoders might.)  Since we want
+ * to be able to dequantize all the components at the end of the file, this
+ * means that we have to save away the table actually used for each component.
+ * We do this by copying the table at the start of the first scan containing
+ * the component.
+ * The JPEG spec prohibits the encoder from changing the contents of a Q-table
+ * slot between scans of a component using that slot.  If the encoder does so
+ * anyway, this decoder will simply use the Q-table values that were current
+ * at the start of the first scan for the component.
+ *
+ * The decompressor output side looks only at the saved quant tables,
+ * not at the current Q-table slots.
+ */
+
+LOCAL(void)
+latch_quant_tables (j_decompress_ptr cinfo)
+{
+  int ci, qtblno;
+  jpeg_component_info *compptr;
+  JQUANT_TBL * qtbl;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    /* No work if we already saved Q-table for this component */
+    if (compptr->quant_table != NULL)
+      continue;
+    /* Make sure specified quantization table is present */
+    qtblno = compptr->quant_tbl_no;
+    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
+	cinfo->quant_tbl_ptrs[qtblno] == NULL)
+      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
+    /* OK, save away the quantization table */
+    qtbl = (JQUANT_TBL *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(JQUANT_TBL));
+    MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
+    compptr->quant_table = qtbl;
+  }
+}
+
+
+/*
+ * Initialize the input modules to read a scan of compressed data.
+ * The first call to this is done by jdmaster.c after initializing
+ * the entire decompressor (during jpeg_start_decompress).
+ * Subsequent calls come from consume_markers, below.
+ */
+
+METHODDEF(void)
+start_input_pass (j_decompress_ptr cinfo)
+{
+  per_scan_setup(cinfo);
+  latch_quant_tables(cinfo);
+  (*cinfo->entropy->start_pass) (cinfo);
+  (*cinfo->coef->start_input_pass) (cinfo);
+  cinfo->inputctl->consume_input = cinfo->coef->consume_data;
+}
+
+
+/*
+ * Finish up after inputting a compressed-data scan.
+ * This is called by the coefficient controller after it's read all
+ * the expected data of the scan.
+ */
+
+METHODDEF(void)
+finish_input_pass (j_decompress_ptr cinfo)
+{
+  cinfo->inputctl->consume_input = consume_markers;
+}
+
+
+/*
+ * Read JPEG markers before, between, or after compressed-data scans.
+ * Change state as necessary when a new scan is reached.
+ * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ *
+ * The consume_input method pointer points either here or to the
+ * coefficient controller's consume_data routine, depending on whether
+ * we are reading a compressed data segment or inter-segment markers.
+ */
+
+METHODDEF(int)
+consume_markers (j_decompress_ptr cinfo)
+{
+  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
+  int val;
+
+  if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
+    return JPEG_REACHED_EOI;
+
+  val = (*cinfo->marker->read_markers) (cinfo);
+
+  switch (val) {
+  case JPEG_REACHED_SOS:	/* Found SOS */
+    if (inputctl->inheaders) {	/* 1st SOS */
+      initial_setup(cinfo);
+      inputctl->inheaders = FALSE;
+      /* Note: start_input_pass must be called by jdmaster.c
+       * before any more input can be consumed.  jdapimin.c is
+       * responsible for enforcing this sequencing.
+       */
+    } else {			/* 2nd or later SOS marker */
+      if (! inputctl->pub.has_multiple_scans)
+	ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
+      start_input_pass(cinfo);
+    }
+    break;
+  case JPEG_REACHED_EOI:	/* Found EOI */
+    inputctl->pub.eoi_reached = TRUE;
+    if (inputctl->inheaders) {	/* Tables-only datastream, apparently */
+      if (cinfo->marker->saw_SOF)
+	ERREXIT(cinfo, JERR_SOF_NO_SOS);
+    } else {
+      /* Prevent infinite loop in coef ctlr's decompress_data routine
+       * if user set output_scan_number larger than number of scans.
+       */
+      if (cinfo->output_scan_number > cinfo->input_scan_number)
+	cinfo->output_scan_number = cinfo->input_scan_number;
+    }
+    break;
+  case JPEG_SUSPENDED:
+    break;
+  }
+
+  return val;
+}
+
+
+/*
+ * Reset state to begin a fresh datastream.
+ */
+
+METHODDEF(void)
+reset_input_controller (j_decompress_ptr cinfo)
+{
+  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
+
+  inputctl->pub.consume_input = consume_markers;
+  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
+  inputctl->pub.eoi_reached = FALSE;
+  inputctl->inheaders = TRUE;
+  /* Reset other modules */
+  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+  (*cinfo->marker->reset_marker_reader) (cinfo);
+  /* Reset progression state -- would be cleaner if entropy decoder did this */
+  cinfo->coef_bits = NULL;
+}
+
+
+/*
+ * Initialize the input controller module.
+ * This is called only once, when the decompression object is created.
+ */
+
+GLOBAL(void)
+jinit_input_controller (j_decompress_ptr cinfo)
+{
+  my_inputctl_ptr inputctl;
+
+  /* Create subobject in permanent pool */
+  inputctl = (my_inputctl_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				SIZEOF(my_input_controller));
+  cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
+  /* Initialize method pointers */
+  inputctl->pub.consume_input = consume_markers;
+  inputctl->pub.reset_input_controller = reset_input_controller;
+  inputctl->pub.start_input_pass = start_input_pass;
+  inputctl->pub.finish_input_pass = finish_input_pass;
+  /* Initialize state: can't use reset_input_controller since we don't
+   * want to try to reset other modules yet.
+   */
+  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
+  inputctl->pub.eoi_reached = FALSE;
+  inputctl->inheaders = TRUE;
+}
diff --git a/Utilities/FLTK/jpeg/jdmainct.c b/Utilities/FLTK/jpeg/jdmainct.c
new file mode 100644
index 0000000000000000000000000000000000000000..da19c7e5e068076cd7c82981fb7d87d4ff44887c
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdmainct.c
@@ -0,0 +1,512 @@
+/*
+ * jdmainct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the main buffer controller for decompression.
+ * The main buffer lies between the JPEG decompressor proper and the
+ * post-processor; it holds downsampled data in the JPEG colorspace.
+ *
+ * Note that this code is bypassed in raw-data mode, since the application
+ * supplies the equivalent of the main buffer in that case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * In the current system design, the main buffer need never be a full-image
+ * buffer; any full-height buffers will be found inside the coefficient or
+ * postprocessing controllers.  Nonetheless, the main controller is not
+ * trivial.  Its responsibility is to provide context rows for upsampling/
+ * rescaling, and doing this in an efficient fashion is a bit tricky.
+ *
+ * Postprocessor input data is counted in "row groups".  A row group
+ * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
+ * sample rows of each component.  (We require DCT_scaled_size values to be
+ * chosen such that these numbers are integers.  In practice DCT_scaled_size
+ * values will likely be powers of two, so we actually have the stronger
+ * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
+ * Upsampling will typically produce max_v_samp_factor pixel rows from each
+ * row group (times any additional scale factor that the upsampler is
+ * applying).
+ *
+ * The coefficient controller will deliver data to us one iMCU row at a time;
+ * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
+ * exactly min_DCT_scaled_size row groups.  (This amount of data corresponds
+ * to one row of MCUs when the image is fully interleaved.)  Note that the
+ * number of sample rows varies across components, but the number of row
+ * groups does not.  Some garbage sample rows may be included in the last iMCU
+ * row at the bottom of the image.
+ *
+ * Depending on the vertical scaling algorithm used, the upsampler may need
+ * access to the sample row(s) above and below its current input row group.
+ * The upsampler is required to set need_context_rows TRUE at global selection
+ * time if so.  When need_context_rows is FALSE, this controller can simply
+ * obtain one iMCU row at a time from the coefficient controller and dole it
+ * out as row groups to the postprocessor.
+ *
+ * When need_context_rows is TRUE, this controller guarantees that the buffer
+ * passed to postprocessing contains at least one row group's worth of samples
+ * above and below the row group(s) being processed.  Note that the context
+ * rows "above" the first passed row group appear at negative row offsets in
+ * the passed buffer.  At the top and bottom of the image, the required
+ * context rows are manufactured by duplicating the first or last real sample
+ * row; this avoids having special cases in the upsampling inner loops.
+ *
+ * The amount of context is fixed at one row group just because that's a
+ * convenient number for this controller to work with.  The existing
+ * upsamplers really only need one sample row of context.  An upsampler
+ * supporting arbitrary output rescaling might wish for more than one row
+ * group of context when shrinking the image; tough, we don't handle that.
+ * (This is justified by the assumption that downsizing will be handled mostly
+ * by adjusting the DCT_scaled_size values, so that the actual scale factor at
+ * the upsample step needn't be much less than one.)
+ *
+ * To provide the desired context, we have to retain the last two row groups
+ * of one iMCU row while reading in the next iMCU row.  (The last row group
+ * can't be processed until we have another row group for its below-context,
+ * and so we have to save the next-to-last group too for its above-context.)
+ * We could do this most simply by copying data around in our buffer, but
+ * that'd be very slow.  We can avoid copying any data by creating a rather
+ * strange pointer structure.  Here's how it works.  We allocate a workspace
+ * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
+ * of row groups per iMCU row).  We create two sets of redundant pointers to
+ * the workspace.  Labeling the physical row groups 0 to M+1, the synthesized
+ * pointer lists look like this:
+ *                   M+1                          M-1
+ * master pointer --> 0         master pointer --> 0
+ *                    1                            1
+ *                   ...                          ...
+ *                   M-3                          M-3
+ *                   M-2                           M
+ *                   M-1                          M+1
+ *                    M                           M-2
+ *                   M+1                          M-1
+ *                    0                            0
+ * We read alternate iMCU rows using each master pointer; thus the last two
+ * row groups of the previous iMCU row remain un-overwritten in the workspace.
+ * The pointer lists are set up so that the required context rows appear to
+ * be adjacent to the proper places when we pass the pointer lists to the
+ * upsampler.
+ *
+ * The above pictures describe the normal state of the pointer lists.
+ * At top and bottom of the image, we diddle the pointer lists to duplicate
+ * the first or last sample row as necessary (this is cheaper than copying
+ * sample rows around).
+ *
+ * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that
+ * situation each iMCU row provides only one row group so the buffering logic
+ * must be different (eg, we must read two iMCU rows before we can emit the
+ * first row group).  For now, we simply do not support providing context
+ * rows when min_DCT_scaled_size is 1.  That combination seems unlikely to
+ * be worth providing --- if someone wants a 1/8th-size preview, they probably
+ * want it quick and dirty, so a context-free upsampler is sufficient.
+ */
+
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_d_main_controller pub; /* public fields */
+
+  /* Pointer to allocated workspace (M or M+2 row groups). */
+  JSAMPARRAY buffer[MAX_COMPONENTS];
+
+  boolean buffer_full;		/* Have we gotten an iMCU row from decoder? */
+  JDIMENSION rowgroup_ctr;	/* counts row groups output to postprocessor */
+
+  /* Remaining fields are only used in the context case. */
+
+  /* These are the master pointers to the funny-order pointer lists. */
+  JSAMPIMAGE xbuffer[2];	/* pointers to weird pointer lists */
+
+  int whichptr;			/* indicates which pointer set is now in use */
+  int context_state;		/* process_data state machine status */
+  JDIMENSION rowgroups_avail;	/* row groups available to postprocessor */
+  JDIMENSION iMCU_row_ctr;	/* counts iMCU rows to detect image top/bot */
+} my_main_controller;
+
+typedef my_main_controller * my_main_ptr;
+
+/* context_state values: */
+#define CTX_PREPARE_FOR_IMCU	0	/* need to prepare for MCU row */
+#define CTX_PROCESS_IMCU	1	/* feeding iMCU to postprocessor */
+#define CTX_POSTPONED_ROW	2	/* feeding postponed row group */
+
+
+/* Forward declarations */
+METHODDEF(void) process_data_simple_main
+	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+METHODDEF(void) process_data_context_main
+	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+#ifdef QUANT_2PASS_SUPPORTED
+METHODDEF(void) process_data_crank_post
+	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+#endif
+
+
+LOCAL(void)
+alloc_funny_pointers (j_decompress_ptr cinfo)
+/* Allocate space for the funny pointer lists.
+ * This is done only once, not once per pass.
+ */
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+  int ci, rgroup;
+  int M = cinfo->min_DCT_scaled_size;
+  jpeg_component_info *compptr;
+  JSAMPARRAY xbuf;
+
+  /* Get top-level space for component array pointers.
+   * We alloc both arrays with one call to save a few cycles.
+   */
+  jmain->xbuffer[0] = (JSAMPIMAGE)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
+  jmain->xbuffer[1] = jmain->xbuffer[0] + cinfo->num_components;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+      cinfo->min_DCT_scaled_size; /* height of a row group of component */
+    /* Get space for pointer lists --- M+4 row groups in each list.
+     * We alloc both pointer lists with one call to save a few cycles.
+     */
+    xbuf = (JSAMPARRAY)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
+    xbuf += rgroup;		/* want one row group at negative offsets */
+    jmain->xbuffer[0][ci] = xbuf;
+    xbuf += rgroup * (M + 4);
+    jmain->xbuffer[1][ci] = xbuf;
+  }
+}
+
+
+LOCAL(void)
+make_funny_pointers (j_decompress_ptr cinfo)
+/* Create the funny pointer lists discussed in the comments above.
+ * The actual workspace is already allocated (in jmain->buffer),
+ * and the space for the pointer lists is allocated too.
+ * This routine just fills in the curiously ordered lists.
+ * This will be repeated at the beginning of each pass.
+ */
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+  int ci, i, rgroup;
+  int M = cinfo->min_DCT_scaled_size;
+  jpeg_component_info *compptr;
+  JSAMPARRAY buf, xbuf0, xbuf1;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+      cinfo->min_DCT_scaled_size; /* height of a row group of component */
+    xbuf0 = jmain->xbuffer[0][ci];
+    xbuf1 = jmain->xbuffer[1][ci];
+    /* First copy the workspace pointers as-is */
+    buf = jmain->buffer[ci];
+    for (i = 0; i < rgroup * (M + 2); i++) {
+      xbuf0[i] = xbuf1[i] = buf[i];
+    }
+    /* In the second list, put the last four row groups in swapped order */
+    for (i = 0; i < rgroup * 2; i++) {
+      xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
+      xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
+    }
+    /* The wraparound pointers at top and bottom will be filled later
+     * (see set_wraparound_pointers, below).  Initially we want the "above"
+     * pointers to duplicate the first actual data line.  This only needs
+     * to happen in xbuffer[0].
+     */
+    for (i = 0; i < rgroup; i++) {
+      xbuf0[i - rgroup] = xbuf0[0];
+    }
+  }
+}
+
+
+LOCAL(void)
+set_wraparound_pointers (j_decompress_ptr cinfo)
+/* Set up the "wraparound" pointers at top and bottom of the pointer lists.
+ * This changes the pointer list state from top-of-image to the normal state.
+ */
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+  int ci, i, rgroup;
+  int M = cinfo->min_DCT_scaled_size;
+  jpeg_component_info *compptr;
+  JSAMPARRAY xbuf0, xbuf1;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+      cinfo->min_DCT_scaled_size; /* height of a row group of component */
+    xbuf0 = jmain->xbuffer[0][ci];
+    xbuf1 = jmain->xbuffer[1][ci];
+    for (i = 0; i < rgroup; i++) {
+      xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
+      xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
+      xbuf0[rgroup*(M+2) + i] = xbuf0[i];
+      xbuf1[rgroup*(M+2) + i] = xbuf1[i];
+    }
+  }
+}
+
+
+LOCAL(void)
+set_bottom_pointers (j_decompress_ptr cinfo)
+/* Change the pointer lists to duplicate the last sample row at the bottom
+ * of the image.  whichptr indicates which xbuffer holds the final iMCU row.
+ * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
+ */
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+  int ci, i, rgroup, iMCUheight, rows_left;
+  jpeg_component_info *compptr;
+  JSAMPARRAY xbuf;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Count sample rows in one iMCU row and in one row group */
+    iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
+    rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
+    /* Count nondummy sample rows remaining for this component */
+    rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
+    if (rows_left == 0) rows_left = iMCUheight;
+    /* Count nondummy row groups.  Should get same answer for each component,
+     * so we need only do it once.
+     */
+    if (ci == 0) {
+      jmain->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
+    }
+    /* Duplicate the last real sample row rgroup*2 times; this pads out the
+     * last partial rowgroup and ensures at least one full rowgroup of context.
+     */
+    xbuf = jmain->xbuffer[jmain->whichptr][ci];
+    for (i = 0; i < rgroup * 2; i++) {
+      xbuf[rows_left + i] = xbuf[rows_left-1];
+    }
+  }
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+
+  switch (pass_mode) {
+  case JBUF_PASS_THRU:
+    if (cinfo->upsample->need_context_rows) {
+      jmain->pub.process_data = process_data_context_main;
+      make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
+      jmain->whichptr = 0;	/* Read first iMCU row into xbuffer[0] */
+      jmain->context_state = CTX_PREPARE_FOR_IMCU;
+      jmain->iMCU_row_ctr = 0;
+    } else {
+      /* Simple case with no context needed */
+      jmain->pub.process_data = process_data_simple_main;
+    }
+    jmain->buffer_full = FALSE;	/* Mark buffer empty */
+    jmain->rowgroup_ctr = 0;
+    break;
+#ifdef QUANT_2PASS_SUPPORTED
+  case JBUF_CRANK_DEST:
+    /* For last pass of 2-pass quantization, just crank the postprocessor */
+    jmain->pub.process_data = process_data_crank_post;
+    break;
+#endif
+  default:
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    break;
+  }
+}
+
+
+/*
+ * Process some data.
+ * This handles the simple case where no context is required.
+ */
+
+METHODDEF(void)
+process_data_simple_main (j_decompress_ptr cinfo,
+			  JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+			  JDIMENSION out_rows_avail)
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+  JDIMENSION rowgroups_avail;
+
+  /* Read input data if we haven't filled the main buffer yet */
+  if (! jmain->buffer_full) {
+    if (! (*cinfo->coef->decompress_data) (cinfo, jmain->buffer))
+      return;			/* suspension forced, can do nothing more */
+    jmain->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
+  }
+
+  /* There are always min_DCT_scaled_size row groups in an iMCU row. */
+  rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
+  /* Note: at the bottom of the image, we may pass extra garbage row groups
+   * to the postprocessor.  The postprocessor has to check for bottom
+   * of image anyway (at row resolution), so no point in us doing it too.
+   */
+
+  /* Feed the postprocessor */
+  (*cinfo->post->post_process_data) (cinfo, jmain->buffer,
+				     &jmain->rowgroup_ctr, rowgroups_avail,
+				     output_buf, out_row_ctr, out_rows_avail);
+
+  /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
+  if (jmain->rowgroup_ctr >= rowgroups_avail) {
+    jmain->buffer_full = FALSE;
+    jmain->rowgroup_ctr = 0;
+  }
+}
+
+
+/*
+ * Process some data.
+ * This handles the case where context rows must be provided.
+ */
+
+METHODDEF(void)
+process_data_context_main (j_decompress_ptr cinfo,
+			   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+			   JDIMENSION out_rows_avail)
+{
+  my_main_ptr jmain = (my_main_ptr) cinfo->main;
+
+  /* Read input data if we haven't filled the main buffer yet */
+  if (! jmain->buffer_full) {
+    if (! (*cinfo->coef->decompress_data) (cinfo,
+					   jmain->xbuffer[jmain->whichptr]))
+      return;			/* suspension forced, can do nothing more */
+    jmain->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
+    jmain->iMCU_row_ctr++;	/* count rows received */
+  }
+
+  /* Postprocessor typically will not swallow all the input data it is handed
+   * in one call (due to filling the output buffer first).  Must be prepared
+   * to exit and restart.  This switch lets us keep track of how far we got.
+   * Note that each case falls through to the next on successful completion.
+   */
+  switch (jmain->context_state) {
+  case CTX_POSTPONED_ROW:
+    /* Call postprocessor using previously set pointers for postponed row */
+    (*cinfo->post->post_process_data) (cinfo, jmain->xbuffer[jmain->whichptr],
+			&jmain->rowgroup_ctr, jmain->rowgroups_avail,
+			output_buf, out_row_ctr, out_rows_avail);
+    if (jmain->rowgroup_ctr < jmain->rowgroups_avail)
+      return;			/* Need to suspend */
+    jmain->context_state = CTX_PREPARE_FOR_IMCU;
+    if (*out_row_ctr >= out_rows_avail)
+      return;			/* Postprocessor exactly filled output buf */
+    /*FALLTHROUGH*/
+  case CTX_PREPARE_FOR_IMCU:
+    /* Prepare to process first M-1 row groups of this iMCU row */
+    jmain->rowgroup_ctr = 0;
+    jmain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
+    /* Check for bottom of image: if so, tweak pointers to "duplicate"
+     * the last sample row, and adjust rowgroups_avail to ignore padding rows.
+     */
+    if (jmain->iMCU_row_ctr == cinfo->total_iMCU_rows)
+      set_bottom_pointers(cinfo);
+    jmain->context_state = CTX_PROCESS_IMCU;
+    /*FALLTHROUGH*/
+  case CTX_PROCESS_IMCU:
+    /* Call postprocessor using previously set pointers */
+    (*cinfo->post->post_process_data) (cinfo, jmain->xbuffer[jmain->whichptr],
+			&jmain->rowgroup_ctr, jmain->rowgroups_avail,
+			output_buf, out_row_ctr, out_rows_avail);
+    if (jmain->rowgroup_ctr < jmain->rowgroups_avail)
+      return;			/* Need to suspend */
+    /* After the first iMCU, change wraparound pointers to normal state */
+    if (jmain->iMCU_row_ctr == 1)
+      set_wraparound_pointers(cinfo);
+    /* Prepare to load new iMCU row using other xbuffer list */
+    jmain->whichptr ^= 1;	/* 0=>1 or 1=>0 */
+    jmain->buffer_full = FALSE;
+    /* Still need to process last row group of this iMCU row, */
+    /* which is saved at index M+1 of the other xbuffer */
+    jmain->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
+    jmain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
+    jmain->context_state = CTX_POSTPONED_ROW;
+  }
+}
+
+
+/*
+ * Process some data.
+ * Final pass of two-pass quantization: just call the postprocessor.
+ * Source data will be the postprocessor controller's internal buffer.
+ */
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+METHODDEF(void)
+process_data_crank_post (j_decompress_ptr cinfo,
+			 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+			 JDIMENSION out_rows_avail)
+{
+  (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
+				     (JDIMENSION *) NULL, (JDIMENSION) 0,
+				     output_buf, out_row_ctr, out_rows_avail);
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Initialize main buffer controller.
+ */
+
+GLOBAL(void)
+jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+  my_main_ptr jmain;
+  int ci, rgroup, ngroups;
+  jpeg_component_info *compptr;
+
+  jmain = (my_main_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_main_controller));
+  cinfo->main = (struct jpeg_d_main_controller *) jmain;
+  jmain->pub.start_pass = start_pass_main;
+
+  if (need_full_buffer)		/* shouldn't happen */
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+  /* Allocate the workspace.
+   * ngroups is the number of row groups we need.
+   */
+  if (cinfo->upsample->need_context_rows) {
+    if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
+      ERREXIT(cinfo, JERR_NOTIMPL);
+    alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
+    ngroups = cinfo->min_DCT_scaled_size + 2;
+  } else {
+    ngroups = cinfo->min_DCT_scaled_size;
+  }
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+      cinfo->min_DCT_scaled_size; /* height of a row group of component */
+    jmain->buffer[ci] = (*cinfo->mem->alloc_sarray)
+			((j_common_ptr) cinfo, JPOOL_IMAGE,
+			 compptr->width_in_blocks * compptr->DCT_scaled_size,
+			 (JDIMENSION) (rgroup * ngroups));
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jdmarker.c b/Utilities/FLTK/jpeg/jdmarker.c
new file mode 100644
index 0000000000000000000000000000000000000000..f4cca8cc835c271ce14920ca790461ffc7ba4640
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdmarker.c
@@ -0,0 +1,1360 @@
+/*
+ * jdmarker.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to decode JPEG datastream markers.
+ * Most of the complexity arises from our desire to support input
+ * suspension: if not all of the data for a marker is available,
+ * we must exit back to the application.  On resumption, we reprocess
+ * the marker.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+typedef enum {			/* JPEG marker codes */
+  M_SOF0  = 0xc0,
+  M_SOF1  = 0xc1,
+  M_SOF2  = 0xc2,
+  M_SOF3  = 0xc3,
+  
+  M_SOF5  = 0xc5,
+  M_SOF6  = 0xc6,
+  M_SOF7  = 0xc7,
+  
+  M_JPG   = 0xc8,
+  M_SOF9  = 0xc9,
+  M_SOF10 = 0xca,
+  M_SOF11 = 0xcb,
+  
+  M_SOF13 = 0xcd,
+  M_SOF14 = 0xce,
+  M_SOF15 = 0xcf,
+  
+  M_DHT   = 0xc4,
+  
+  M_DAC   = 0xcc,
+  
+  M_RST0  = 0xd0,
+  M_RST1  = 0xd1,
+  M_RST2  = 0xd2,
+  M_RST3  = 0xd3,
+  M_RST4  = 0xd4,
+  M_RST5  = 0xd5,
+  M_RST6  = 0xd6,
+  M_RST7  = 0xd7,
+  
+  M_SOI   = 0xd8,
+  M_EOI   = 0xd9,
+  M_SOS   = 0xda,
+  M_DQT   = 0xdb,
+  M_DNL   = 0xdc,
+  M_DRI   = 0xdd,
+  M_DHP   = 0xde,
+  M_EXP   = 0xdf,
+  
+  M_APP0  = 0xe0,
+  M_APP1  = 0xe1,
+  M_APP2  = 0xe2,
+  M_APP3  = 0xe3,
+  M_APP4  = 0xe4,
+  M_APP5  = 0xe5,
+  M_APP6  = 0xe6,
+  M_APP7  = 0xe7,
+  M_APP8  = 0xe8,
+  M_APP9  = 0xe9,
+  M_APP10 = 0xea,
+  M_APP11 = 0xeb,
+  M_APP12 = 0xec,
+  M_APP13 = 0xed,
+  M_APP14 = 0xee,
+  M_APP15 = 0xef,
+  
+  M_JPG0  = 0xf0,
+  M_JPG13 = 0xfd,
+  M_COM   = 0xfe,
+  
+  M_TEM   = 0x01,
+  
+  M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+/* Private state */
+
+typedef struct {
+  struct jpeg_marker_reader pub; /* public fields */
+
+  /* Application-overridable marker processing methods */
+  jpeg_marker_parser_method process_COM;
+  jpeg_marker_parser_method process_APPn[16];
+
+  /* Limit on marker data length to save for each marker type */
+  unsigned int length_limit_COM;
+  unsigned int length_limit_APPn[16];
+
+  /* Status of COM/APPn marker saving */
+  jpeg_saved_marker_ptr cur_marker;	/* NULL if not processing a marker */
+  unsigned int bytes_read;		/* data bytes read so far in marker */
+  /* Note: cur_marker is not linked into marker_list until it's all read. */
+} my_marker_reader;
+
+typedef my_marker_reader * my_marker_ptr;
+
+
+/*
+ * Macros for fetching data from the data source module.
+ *
+ * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
+ * the current restart point; we update them only when we have reached a
+ * suitable place to restart if a suspension occurs.
+ */
+
+/* Declare and initialize local copies of input pointer/count */
+#define INPUT_VARS(cinfo)  \
+	struct jpeg_source_mgr * datasrc = (cinfo)->src;  \
+	const JOCTET * next_input_byte = datasrc->next_input_byte;  \
+	size_t bytes_in_buffer = datasrc->bytes_in_buffer
+
+/* Unload the local copies --- do this only at a restart boundary */
+#define INPUT_SYNC(cinfo)  \
+	( datasrc->next_input_byte = next_input_byte,  \
+	  datasrc->bytes_in_buffer = bytes_in_buffer )
+
+/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
+#define INPUT_RELOAD(cinfo)  \
+	( next_input_byte = datasrc->next_input_byte,  \
+	  bytes_in_buffer = datasrc->bytes_in_buffer )
+
+/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
+ * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
+ * but we must reload the local copies after a successful fill.
+ */
+#define MAKE_BYTE_AVAIL(cinfo,action)  \
+	if (bytes_in_buffer == 0) {  \
+	  if (! (*datasrc->fill_input_buffer) (cinfo))  \
+	    { action; }  \
+	  INPUT_RELOAD(cinfo);  \
+	}
+
+/* Read a byte into variable V.
+ * If must suspend, take the specified action (typically "return FALSE").
+ */
+#define INPUT_BYTE(cinfo,V,action)  \
+	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+		  bytes_in_buffer--; \
+		  V = GETJOCTET(*next_input_byte++); )
+
+/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
+ * V should be declared unsigned int or perhaps INT32.
+ */
+#define INPUT_2BYTES(cinfo,V,action)  \
+	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+		  bytes_in_buffer--; \
+		  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
+		  MAKE_BYTE_AVAIL(cinfo,action); \
+		  bytes_in_buffer--; \
+		  V += GETJOCTET(*next_input_byte++); )
+
+
+/*
+ * Routines to process JPEG markers.
+ *
+ * Entry condition: JPEG marker itself has been read and its code saved
+ *   in cinfo->unread_marker; input restart point is just after the marker.
+ *
+ * Exit: if return TRUE, have read and processed any parameters, and have
+ *   updated the restart point to point after the parameters.
+ *   If return FALSE, was forced to suspend before reaching end of
+ *   marker parameters; restart point has not been moved.  Same routine
+ *   will be called again after application supplies more input data.
+ *
+ * This approach to suspension assumes that all of a marker's parameters
+ * can fit into a single input bufferload.  This should hold for "normal"
+ * markers.  Some COM/APPn markers might have large parameter segments
+ * that might not fit.  If we are simply dropping such a marker, we use
+ * skip_input_data to get past it, and thereby put the problem on the
+ * source manager's shoulders.  If we are saving the marker's contents
+ * into memory, we use a slightly different convention: when forced to
+ * suspend, the marker processor updates the restart point to the end of
+ * what it's consumed (ie, the end of the buffer) before returning FALSE.
+ * On resumption, cinfo->unread_marker still contains the marker code,
+ * but the data source will point to the next chunk of marker data.
+ * The marker processor must retain internal state to deal with this.
+ *
+ * Note that we don't bother to avoid duplicate trace messages if a
+ * suspension occurs within marker parameters.  Other side effects
+ * require more care.
+ */
+
+
+LOCAL(boolean)
+get_soi (j_decompress_ptr cinfo)
+/* Process an SOI marker */
+{
+  int i;
+  
+  TRACEMS(cinfo, 1, JTRC_SOI);
+
+  if (cinfo->marker->saw_SOI)
+    ERREXIT(cinfo, JERR_SOI_DUPLICATE);
+
+  /* Reset all parameters that are defined to be reset by SOI */
+
+  for (i = 0; i < NUM_ARITH_TBLS; i++) {
+    cinfo->arith_dc_L[i] = 0;
+    cinfo->arith_dc_U[i] = 1;
+    cinfo->arith_ac_K[i] = 5;
+  }
+  cinfo->restart_interval = 0;
+
+  /* Set initial assumptions for colorspace etc */
+
+  cinfo->jpeg_color_space = JCS_UNKNOWN;
+  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
+
+  cinfo->saw_JFIF_marker = FALSE;
+  cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
+  cinfo->JFIF_minor_version = 1;
+  cinfo->density_unit = 0;
+  cinfo->X_density = 1;
+  cinfo->Y_density = 1;
+  cinfo->saw_Adobe_marker = FALSE;
+  cinfo->Adobe_transform = 0;
+
+  cinfo->marker->saw_SOI = TRUE;
+
+  return TRUE;
+}
+
+
+LOCAL(boolean)
+get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
+/* Process a SOFn marker */
+{
+  INT32 length;
+  int c, ci;
+  jpeg_component_info * compptr;
+  INPUT_VARS(cinfo);
+
+  cinfo->progressive_mode = is_prog;
+  cinfo->arith_code = is_arith;
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+
+  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
+  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
+  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
+  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
+
+  length -= 8;
+
+  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
+	   (int) cinfo->image_width, (int) cinfo->image_height,
+	   cinfo->num_components);
+
+  if (cinfo->marker->saw_SOF)
+    ERREXIT(cinfo, JERR_SOF_DUPLICATE);
+
+  /* We don't support files in which the image height is initially specified */
+  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
+  /* might as well have a general sanity check. */
+  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
+      || cinfo->num_components <= 0)
+    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
+  if (length != (cinfo->num_components * 3))
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  if (cinfo->comp_info == NULL)	/* do only once, even if suspend */
+    cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
+			((j_common_ptr) cinfo, JPOOL_IMAGE,
+			 cinfo->num_components * SIZEOF(jpeg_component_info));
+  
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    compptr->component_index = ci;
+    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
+    INPUT_BYTE(cinfo, c, return FALSE);
+    compptr->h_samp_factor = (c >> 4) & 15;
+    compptr->v_samp_factor = (c     ) & 15;
+    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
+
+    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
+	     compptr->component_id, compptr->h_samp_factor,
+	     compptr->v_samp_factor, compptr->quant_tbl_no);
+  }
+
+  cinfo->marker->saw_SOF = TRUE;
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
+LOCAL(boolean)
+get_sos (j_decompress_ptr cinfo)
+/* Process a SOS marker */
+{
+  INT32 length;
+  int i, ci, n, c, cc;
+  jpeg_component_info * compptr;
+  INPUT_VARS(cinfo);
+
+  if (! cinfo->marker->saw_SOF)
+    ERREXIT(cinfo, JERR_SOS_NO_SOF);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+
+  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
+
+  TRACEMS1(cinfo, 1, JTRC_SOS, n);
+
+  if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  cinfo->comps_in_scan = n;
+
+  /* Collect the component-spec parameters */
+
+  for (i = 0; i < n; i++) {
+    INPUT_BYTE(cinfo, cc, return FALSE);
+    INPUT_BYTE(cinfo, c, return FALSE);
+    
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      if (cc == compptr->component_id)
+	goto id_found;
+    }
+
+    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
+
+  id_found:
+
+    cinfo->cur_comp_info[i] = compptr;
+    compptr->dc_tbl_no = (c >> 4) & 15;
+    compptr->ac_tbl_no = (c     ) & 15;
+    
+    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
+	     compptr->dc_tbl_no, compptr->ac_tbl_no);
+  }
+
+  /* Collect the additional scan parameters Ss, Se, Ah/Al. */
+  INPUT_BYTE(cinfo, c, return FALSE);
+  cinfo->Ss = c;
+  INPUT_BYTE(cinfo, c, return FALSE);
+  cinfo->Se = c;
+  INPUT_BYTE(cinfo, c, return FALSE);
+  cinfo->Ah = (c >> 4) & 15;
+  cinfo->Al = (c     ) & 15;
+
+  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
+	   cinfo->Ah, cinfo->Al);
+
+  /* Prepare to scan data & restart markers */
+  cinfo->marker->next_restart_num = 0;
+
+  /* Count another SOS marker */
+  cinfo->input_scan_number++;
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
+#ifdef D_ARITH_CODING_SUPPORTED
+
+LOCAL(boolean)
+get_dac (j_decompress_ptr cinfo)
+/* Process a DAC marker */
+{
+  INT32 length;
+  int index, val;
+  INPUT_VARS(cinfo);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+  length -= 2;
+  
+  while (length > 0) {
+    INPUT_BYTE(cinfo, index, return FALSE);
+    INPUT_BYTE(cinfo, val, return FALSE);
+
+    length -= 2;
+
+    TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
+
+    if (index < 0 || index >= (2*NUM_ARITH_TBLS))
+      ERREXIT1(cinfo, JERR_DAC_INDEX, index);
+
+    if (index >= NUM_ARITH_TBLS) { /* define AC table */
+      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
+    } else {			/* define DC table */
+      cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
+      cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
+      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
+	ERREXIT1(cinfo, JERR_DAC_VALUE, val);
+    }
+  }
+
+  if (length != 0)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+#else /* ! D_ARITH_CODING_SUPPORTED */
+
+#define get_dac(cinfo)  skip_variable(cinfo)
+
+#endif /* D_ARITH_CODING_SUPPORTED */
+
+
+LOCAL(boolean)
+get_dht (j_decompress_ptr cinfo)
+/* Process a DHT marker */
+{
+  INT32 length;
+  UINT8 bits[17];
+  UINT8 huffval[256];
+  int i, index, count;
+  JHUFF_TBL **htblptr;
+  INPUT_VARS(cinfo);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+  length -= 2;
+  
+  while (length > 16) {
+    INPUT_BYTE(cinfo, index, return FALSE);
+
+    TRACEMS1(cinfo, 1, JTRC_DHT, index);
+      
+    bits[0] = 0;
+    count = 0;
+    for (i = 1; i <= 16; i++) {
+      INPUT_BYTE(cinfo, bits[i], return FALSE);
+      count += bits[i];
+    }
+
+    length -= 1 + 16;
+
+    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
+	     bits[1], bits[2], bits[3], bits[4],
+	     bits[5], bits[6], bits[7], bits[8]);
+    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
+	     bits[9], bits[10], bits[11], bits[12],
+	     bits[13], bits[14], bits[15], bits[16]);
+
+    /* Here we just do minimal validation of the counts to avoid walking
+     * off the end of our table space.  jdhuff.c will check more carefully.
+     */
+    if (count > 256 || ((INT32) count) > length)
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+    for (i = 0; i < count; i++)
+      INPUT_BYTE(cinfo, huffval[i], return FALSE);
+
+    length -= count;
+
+    if (index & 0x10) {		/* AC table definition */
+      index -= 0x10;
+      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
+    } else {			/* DC table definition */
+      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
+    }
+
+    if (index < 0 || index >= NUM_HUFF_TBLS)
+      ERREXIT1(cinfo, JERR_DHT_INDEX, index);
+
+    if (*htblptr == NULL)
+      *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+  
+    MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
+    MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
+  }
+
+  if (length != 0)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
+LOCAL(boolean)
+get_dqt (j_decompress_ptr cinfo)
+/* Process a DQT marker */
+{
+  INT32 length;
+  int n, i, prec;
+  unsigned int tmp;
+  JQUANT_TBL *quant_ptr;
+  INPUT_VARS(cinfo);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+  length -= 2;
+
+  while (length > 0) {
+    INPUT_BYTE(cinfo, n, return FALSE);
+    prec = n >> 4;
+    n &= 0x0F;
+
+    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
+
+    if (n >= NUM_QUANT_TBLS)
+      ERREXIT1(cinfo, JERR_DQT_INDEX, n);
+      
+    if (cinfo->quant_tbl_ptrs[n] == NULL)
+      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
+    quant_ptr = cinfo->quant_tbl_ptrs[n];
+
+    for (i = 0; i < DCTSIZE2; i++) {
+      if (prec)
+	INPUT_2BYTES(cinfo, tmp, return FALSE);
+      else
+	INPUT_BYTE(cinfo, tmp, return FALSE);
+      /* We convert the zigzag-order table to natural array order. */
+      quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
+    }
+
+    if (cinfo->err->trace_level >= 2) {
+      for (i = 0; i < DCTSIZE2; i += 8) {
+	TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
+		 quant_ptr->quantval[i],   quant_ptr->quantval[i+1],
+		 quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
+		 quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
+		 quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
+      }
+    }
+
+    length -= DCTSIZE2+1;
+    if (prec) length -= DCTSIZE2;
+  }
+
+  if (length != 0)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
+LOCAL(boolean)
+get_dri (j_decompress_ptr cinfo)
+/* Process a DRI marker */
+{
+  INT32 length;
+  unsigned int tmp;
+  INPUT_VARS(cinfo);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+  
+  if (length != 4)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+
+  TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
+
+  cinfo->restart_interval = tmp;
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
+/*
+ * Routines for processing APPn and COM markers.
+ * These are either saved in memory or discarded, per application request.
+ * APP0 and APP14 are specially checked to see if they are
+ * JFIF and Adobe markers, respectively.
+ */
+
+#define APP0_DATA_LEN	14	/* Length of interesting data in APP0 */
+#define APP14_DATA_LEN	12	/* Length of interesting data in APP14 */
+#define APPN_DATA_LEN	14	/* Must be the largest of the above!! */
+
+
+LOCAL(void)
+examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
+	      unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP0.
+ * Take appropriate action if it is a JFIF marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+  INT32 totallen = (INT32) datalen + remaining;
+
+  if (datalen >= APP0_DATA_LEN &&
+      GETJOCTET(data[0]) == 0x4A &&
+      GETJOCTET(data[1]) == 0x46 &&
+      GETJOCTET(data[2]) == 0x49 &&
+      GETJOCTET(data[3]) == 0x46 &&
+      GETJOCTET(data[4]) == 0) {
+    /* Found JFIF APP0 marker: save info */
+    cinfo->saw_JFIF_marker = TRUE;
+    cinfo->JFIF_major_version = GETJOCTET(data[5]);
+    cinfo->JFIF_minor_version = GETJOCTET(data[6]);
+    cinfo->density_unit = GETJOCTET(data[7]);
+    cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
+    cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
+    /* Check version.
+     * Major version must be 1, anything else signals an incompatible change.
+     * (We used to treat this as an error, but now it's a nonfatal warning,
+     * because some bozo at Hijaak couldn't read the spec.)
+     * Minor version should be 0..2, but process anyway if newer.
+     */
+    if (cinfo->JFIF_major_version != 1)
+      WARNMS2(cinfo, JWRN_JFIF_MAJOR,
+	      cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
+    /* Generate trace messages */
+    TRACEMS5(cinfo, 1, JTRC_JFIF,
+	     cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
+	     cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
+    /* Validate thumbnail dimensions and issue appropriate messages */
+    if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
+      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
+	       GETJOCTET(data[12]), GETJOCTET(data[13]));
+    totallen -= APP0_DATA_LEN;
+    if (totallen !=
+	((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
+      TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
+  } else if (datalen >= 6 &&
+      GETJOCTET(data[0]) == 0x4A &&
+      GETJOCTET(data[1]) == 0x46 &&
+      GETJOCTET(data[2]) == 0x58 &&
+      GETJOCTET(data[3]) == 0x58 &&
+      GETJOCTET(data[4]) == 0) {
+    /* Found JFIF "JFXX" extension APP0 marker */
+    /* The library doesn't actually do anything with these,
+     * but we try to produce a helpful trace message.
+     */
+    switch (GETJOCTET(data[5])) {
+    case 0x10:
+      TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
+      break;
+    case 0x11:
+      TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
+      break;
+    case 0x13:
+      TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
+      break;
+    default:
+      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
+	       GETJOCTET(data[5]), (int) totallen);
+      break;
+    }
+  } else {
+    /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
+    TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
+  }
+}
+
+
+LOCAL(void)
+examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
+	       unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP14.
+ * Take appropriate action if it is an Adobe marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+  unsigned int version, flags0, flags1, transform;
+
+  if (datalen >= APP14_DATA_LEN &&
+      GETJOCTET(data[0]) == 0x41 &&
+      GETJOCTET(data[1]) == 0x64 &&
+      GETJOCTET(data[2]) == 0x6F &&
+      GETJOCTET(data[3]) == 0x62 &&
+      GETJOCTET(data[4]) == 0x65) {
+    /* Found Adobe APP14 marker */
+    version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
+    flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
+    flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
+    transform = GETJOCTET(data[11]);
+    TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
+    cinfo->saw_Adobe_marker = TRUE;
+    cinfo->Adobe_transform = (UINT8) transform;
+  } else {
+    /* Start of APP14 does not match "Adobe", or too short */
+    TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
+  }
+}
+
+
+METHODDEF(boolean)
+get_interesting_appn (j_decompress_ptr cinfo)
+/* Process an APP0 or APP14 marker without saving it */
+{
+  INT32 length;
+  JOCTET b[APPN_DATA_LEN];
+  unsigned int i, numtoread;
+  INPUT_VARS(cinfo);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+  length -= 2;
+
+  /* get the interesting part of the marker data */
+  if (length >= APPN_DATA_LEN)
+    numtoread = APPN_DATA_LEN;
+  else if (length > 0)
+    numtoread = (unsigned int) length;
+  else
+    numtoread = 0;
+  for (i = 0; i < numtoread; i++)
+    INPUT_BYTE(cinfo, b[i], return FALSE);
+  length -= numtoread;
+
+  /* process it */
+  switch (cinfo->unread_marker) {
+  case M_APP0:
+    examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
+    break;
+  case M_APP14:
+    examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
+    break;
+  default:
+    /* can't get here unless jpeg_save_markers chooses wrong processor */
+    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+    break;
+  }
+
+  /* skip any remaining data -- could be lots */
+  INPUT_SYNC(cinfo);
+  if (length > 0)
+    (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+  return TRUE;
+}
+
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+METHODDEF(boolean)
+save_marker (j_decompress_ptr cinfo)
+/* Save an APPn or COM marker into the marker list */
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+  jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
+  unsigned int bytes_read, data_length;
+  JOCTET FAR * data;
+  INT32 length = 0;
+  INPUT_VARS(cinfo);
+
+  if (cur_marker == NULL) {
+    /* begin reading a marker */
+    INPUT_2BYTES(cinfo, length, return FALSE);
+    length -= 2;
+    if (length >= 0) {		/* watch out for bogus length word */
+      /* figure out how much we want to save */
+      unsigned int limit;
+      if (cinfo->unread_marker == (int) M_COM)
+	limit = marker->length_limit_COM;
+      else
+	limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
+      if ((unsigned int) length < limit)
+	limit = (unsigned int) length;
+      /* allocate and initialize the marker item */
+      cur_marker = (jpeg_saved_marker_ptr)
+	(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				    SIZEOF(struct jpeg_marker_struct) + limit);
+      cur_marker->next = NULL;
+      cur_marker->marker = (UINT8) cinfo->unread_marker;
+      cur_marker->original_length = (unsigned int) length;
+      cur_marker->data_length = limit;
+      /* data area is just beyond the jpeg_marker_struct */
+      data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
+      marker->cur_marker = cur_marker;
+      marker->bytes_read = 0;
+      bytes_read = 0;
+      data_length = limit;
+    } else {
+      /* deal with bogus length word */
+      bytes_read = data_length = 0;
+      data = NULL;
+    }
+  } else {
+    /* resume reading a marker */
+    bytes_read = marker->bytes_read;
+    data_length = cur_marker->data_length;
+    data = cur_marker->data + bytes_read;
+  }
+
+  while (bytes_read < data_length) {
+    INPUT_SYNC(cinfo);		/* move the restart point to here */
+    marker->bytes_read = bytes_read;
+    /* If there's not at least one byte in buffer, suspend */
+    MAKE_BYTE_AVAIL(cinfo, return FALSE);
+    /* Copy bytes with reasonable rapidity */
+    while (bytes_read < data_length && bytes_in_buffer > 0) {
+      *data++ = *next_input_byte++;
+      bytes_in_buffer--;
+      bytes_read++;
+    }
+  }
+
+  /* Done reading what we want to read */
+  if (cur_marker != NULL) {	/* will be NULL if bogus length word */
+    /* Add new marker to end of list */
+    if (cinfo->marker_list == NULL) {
+      cinfo->marker_list = cur_marker;
+    } else {
+      jpeg_saved_marker_ptr prev = cinfo->marker_list;
+      while (prev->next != NULL)
+	prev = prev->next;
+      prev->next = cur_marker;
+    }
+    /* Reset pointer & calc remaining data length */
+    data = cur_marker->data;
+    length = cur_marker->original_length - data_length;
+  }
+  /* Reset to initial state for next marker */
+  marker->cur_marker = NULL;
+
+  /* Process the marker if interesting; else just make a generic trace msg */
+  switch (cinfo->unread_marker) {
+  case M_APP0:
+    examine_app0(cinfo, data, data_length, length);
+    break;
+  case M_APP14:
+    examine_app14(cinfo, data, data_length, length);
+    break;
+  default:
+    TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
+	     (int) (data_length + length));
+    break;
+  }
+
+  /* skip any remaining data -- could be lots */
+  INPUT_SYNC(cinfo);		/* do before skip_input_data */
+  if (length > 0)
+    (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+  return TRUE;
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
+METHODDEF(boolean)
+skip_variable (j_decompress_ptr cinfo)
+/* Skip over an unknown or uninteresting variable-length marker */
+{
+  INT32 length;
+  INPUT_VARS(cinfo);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+  length -= 2;
+  
+  TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
+
+  INPUT_SYNC(cinfo);		/* do before skip_input_data */
+  if (length > 0)
+    (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+  return TRUE;
+}
+
+
+/*
+ * Find the next JPEG marker, save it in cinfo->unread_marker.
+ * Returns FALSE if had to suspend before reaching a marker;
+ * in that case cinfo->unread_marker is unchanged.
+ *
+ * Note that the result might not be a valid marker code,
+ * but it will never be 0 or FF.
+ */
+
+LOCAL(boolean)
+next_marker (j_decompress_ptr cinfo)
+{
+  int c;
+  INPUT_VARS(cinfo);
+
+  for (;;) {
+    INPUT_BYTE(cinfo, c, return FALSE);
+    /* Skip any non-FF bytes.
+     * This may look a bit inefficient, but it will not occur in a valid file.
+     * We sync after each discarded byte so that a suspending data source
+     * can discard the byte from its buffer.
+     */
+    while (c != 0xFF) {
+      cinfo->marker->discarded_bytes++;
+      INPUT_SYNC(cinfo);
+      INPUT_BYTE(cinfo, c, return FALSE);
+    }
+    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
+     * pad bytes, so don't count them in discarded_bytes.  We assume there
+     * will not be so many consecutive FF bytes as to overflow a suspending
+     * data source's input buffer.
+     */
+    do {
+      INPUT_BYTE(cinfo, c, return FALSE);
+    } while (c == 0xFF);
+    if (c != 0)
+      break;			/* found a valid marker, exit loop */
+    /* Reach here if we found a stuffed-zero data sequence (FF/00).
+     * Discard it and loop back to try again.
+     */
+    cinfo->marker->discarded_bytes += 2;
+    INPUT_SYNC(cinfo);
+  }
+
+  if (cinfo->marker->discarded_bytes != 0) {
+    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
+    cinfo->marker->discarded_bytes = 0;
+  }
+
+  cinfo->unread_marker = c;
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
+LOCAL(boolean)
+first_marker (j_decompress_ptr cinfo)
+/* Like next_marker, but used to obtain the initial SOI marker. */
+/* For this marker, we do not allow preceding garbage or fill; otherwise,
+ * we might well scan an entire input file before realizing it ain't JPEG.
+ * If an application wants to process non-JFIF files, it must seek to the
+ * SOI before calling the JPEG library.
+ */
+{
+  int c, c2;
+  INPUT_VARS(cinfo);
+
+  INPUT_BYTE(cinfo, c, return FALSE);
+  INPUT_BYTE(cinfo, c2, return FALSE);
+  if (c != 0xFF || c2 != (int) M_SOI)
+    ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
+
+  cinfo->unread_marker = c2;
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
+/*
+ * Read markers until SOS or EOI.
+ *
+ * Returns same codes as are defined for jpeg_consume_input:
+ * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ */
+
+METHODDEF(int)
+read_markers (j_decompress_ptr cinfo)
+{
+  /* Outer loop repeats once for each marker. */
+  for (;;) {
+    /* Collect the marker proper, unless we already did. */
+    /* NB: first_marker() enforces the requirement that SOI appear first. */
+    if (cinfo->unread_marker == 0) {
+      if (! cinfo->marker->saw_SOI) {
+	if (! first_marker(cinfo))
+	  return JPEG_SUSPENDED;
+      } else {
+	if (! next_marker(cinfo))
+	  return JPEG_SUSPENDED;
+      }
+    }
+    /* At this point cinfo->unread_marker contains the marker code and the
+     * input point is just past the marker proper, but before any parameters.
+     * A suspension will cause us to return with this state still true.
+     */
+    switch (cinfo->unread_marker) {
+    case M_SOI:
+      if (! get_soi(cinfo))
+	return JPEG_SUSPENDED;
+      break;
+
+    case M_SOF0:		/* Baseline */
+    case M_SOF1:		/* Extended sequential, Huffman */
+      if (! get_sof(cinfo, FALSE, FALSE))
+	return JPEG_SUSPENDED;
+      break;
+
+    case M_SOF2:		/* Progressive, Huffman */
+      if (! get_sof(cinfo, TRUE, FALSE))
+	return JPEG_SUSPENDED;
+      break;
+
+    case M_SOF9:		/* Extended sequential, arithmetic */
+      if (! get_sof(cinfo, FALSE, TRUE))
+	return JPEG_SUSPENDED;
+      break;
+
+    case M_SOF10:		/* Progressive, arithmetic */
+      if (! get_sof(cinfo, TRUE, TRUE))
+	return JPEG_SUSPENDED;
+      break;
+
+    /* Currently unsupported SOFn types */
+    case M_SOF3:		/* Lossless, Huffman */
+    case M_SOF5:		/* Differential sequential, Huffman */
+    case M_SOF6:		/* Differential progressive, Huffman */
+    case M_SOF7:		/* Differential lossless, Huffman */
+    case M_JPG:			/* Reserved for JPEG extensions */
+    case M_SOF11:		/* Lossless, arithmetic */
+    case M_SOF13:		/* Differential sequential, arithmetic */
+    case M_SOF14:		/* Differential progressive, arithmetic */
+    case M_SOF15:		/* Differential lossless, arithmetic */
+      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
+      break;
+
+    case M_SOS:
+      if (! get_sos(cinfo))
+	return JPEG_SUSPENDED;
+      cinfo->unread_marker = 0;	/* processed the marker */
+      return JPEG_REACHED_SOS;
+    
+    case M_EOI:
+      TRACEMS(cinfo, 1, JTRC_EOI);
+      cinfo->unread_marker = 0;	/* processed the marker */
+      return JPEG_REACHED_EOI;
+      
+    case M_DAC:
+      if (! get_dac(cinfo))
+	return JPEG_SUSPENDED;
+      break;
+      
+    case M_DHT:
+      if (! get_dht(cinfo))
+	return JPEG_SUSPENDED;
+      break;
+      
+    case M_DQT:
+      if (! get_dqt(cinfo))
+	return JPEG_SUSPENDED;
+      break;
+      
+    case M_DRI:
+      if (! get_dri(cinfo))
+	return JPEG_SUSPENDED;
+      break;
+      
+    case M_APP0:
+    case M_APP1:
+    case M_APP2:
+    case M_APP3:
+    case M_APP4:
+    case M_APP5:
+    case M_APP6:
+    case M_APP7:
+    case M_APP8:
+    case M_APP9:
+    case M_APP10:
+    case M_APP11:
+    case M_APP12:
+    case M_APP13:
+    case M_APP14:
+    case M_APP15:
+      if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
+		cinfo->unread_marker - (int) M_APP0]) (cinfo))
+	return JPEG_SUSPENDED;
+      break;
+      
+    case M_COM:
+      if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
+	return JPEG_SUSPENDED;
+      break;
+
+    case M_RST0:		/* these are all parameterless */
+    case M_RST1:
+    case M_RST2:
+    case M_RST3:
+    case M_RST4:
+    case M_RST5:
+    case M_RST6:
+    case M_RST7:
+    case M_TEM:
+      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
+      break;
+
+    case M_DNL:			/* Ignore DNL ... perhaps the wrong thing */
+      if (! skip_variable(cinfo))
+	return JPEG_SUSPENDED;
+      break;
+
+    default:			/* must be DHP, EXP, JPGn, or RESn */
+      /* For now, we treat the reserved markers as fatal errors since they are
+       * likely to be used to signal incompatible JPEG Part 3 extensions.
+       * Once the JPEG 3 version-number marker is well defined, this code
+       * ought to change!
+       */
+      ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+      break;
+    }
+    /* Successfully processed marker, so reset state variable */
+    cinfo->unread_marker = 0;
+  } /* end loop */
+}
+
+
+/*
+ * Read a restart marker, which is expected to appear next in the datastream;
+ * if the marker is not there, take appropriate recovery action.
+ * Returns FALSE if suspension is required.
+ *
+ * This is called by the entropy decoder after it has read an appropriate
+ * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
+ * has already read a marker from the data source.  Under normal conditions
+ * cinfo->unread_marker will be reset to 0 before returning; if not reset,
+ * it holds a marker which the decoder will be unable to read past.
+ */
+
+METHODDEF(boolean)
+read_restart_marker (j_decompress_ptr cinfo)
+{
+  /* Obtain a marker unless we already did. */
+  /* Note that next_marker will complain if it skips any data. */
+  if (cinfo->unread_marker == 0) {
+    if (! next_marker(cinfo))
+      return FALSE;
+  }
+
+  if (cinfo->unread_marker ==
+      ((int) M_RST0 + cinfo->marker->next_restart_num)) {
+    /* Normal case --- swallow the marker and let entropy decoder continue */
+    TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
+    cinfo->unread_marker = 0;
+  } else {
+    /* Uh-oh, the restart markers have been messed up. */
+    /* Let the data source manager determine how to resync. */
+    if (! (*cinfo->src->resync_to_restart) (cinfo,
+					    cinfo->marker->next_restart_num))
+      return FALSE;
+  }
+
+  /* Update next-restart state */
+  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
+
+  return TRUE;
+}
+
+
+/*
+ * This is the default resync_to_restart method for data source managers
+ * to use if they don't have any better approach.  Some data source managers
+ * may be able to back up, or may have additional knowledge about the data
+ * which permits a more intelligent recovery strategy; such managers would
+ * presumably supply their own resync method.
+ *
+ * read_restart_marker calls resync_to_restart if it finds a marker other than
+ * the restart marker it was expecting.  (This code is *not* used unless
+ * a nonzero restart interval has been declared.)  cinfo->unread_marker is
+ * the marker code actually found (might be anything, except 0 or FF).
+ * The desired restart marker number (0..7) is passed as a parameter.
+ * This routine is supposed to apply whatever error recovery strategy seems
+ * appropriate in order to position the input stream to the next data segment.
+ * Note that cinfo->unread_marker is treated as a marker appearing before
+ * the current data-source input point; usually it should be reset to zero
+ * before returning.
+ * Returns FALSE if suspension is required.
+ *
+ * This implementation is substantially constrained by wanting to treat the
+ * input as a data stream; this means we can't back up.  Therefore, we have
+ * only the following actions to work with:
+ *   1. Simply discard the marker and let the entropy decoder resume at next
+ *      byte of file.
+ *   2. Read forward until we find another marker, discarding intervening
+ *      data.  (In theory we could look ahead within the current bufferload,
+ *      without having to discard data if we don't find the desired marker.
+ *      This idea is not implemented here, in part because it makes behavior
+ *      dependent on buffer size and chance buffer-boundary positions.)
+ *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
+ *      This will cause the entropy decoder to process an empty data segment,
+ *      inserting dummy zeroes, and then we will reprocess the marker.
+ *
+ * #2 is appropriate if we think the desired marker lies ahead, while #3 is
+ * appropriate if the found marker is a future restart marker (indicating
+ * that we have missed the desired restart marker, probably because it got
+ * corrupted).
+ * We apply #2 or #3 if the found marker is a restart marker no more than
+ * two counts behind or ahead of the expected one.  We also apply #2 if the
+ * found marker is not a legal JPEG marker code (it's certainly bogus data).
+ * If the found marker is a restart marker more than 2 counts away, we do #1
+ * (too much risk that the marker is erroneous; with luck we will be able to
+ * resync at some future point).
+ * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
+ * overrunning the end of a scan.  An implementation limited to single-scan
+ * files might find it better to apply #2 for markers other than EOI, since
+ * any other marker would have to be bogus data in that case.
+ */
+
+GLOBAL(boolean)
+jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
+{
+  int marker = cinfo->unread_marker;
+  int action = 1;
+  
+  /* Always put up a warning. */
+  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
+  
+  /* Outer loop handles repeated decision after scanning forward. */
+  for (;;) {
+    if (marker < (int) M_SOF0)
+      action = 2;		/* invalid marker */
+    else if (marker < (int) M_RST0 || marker > (int) M_RST7)
+      action = 3;		/* valid non-restart marker */
+    else {
+      if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
+	  marker == ((int) M_RST0 + ((desired+2) & 7)))
+	action = 3;		/* one of the next two expected restarts */
+      else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
+	       marker == ((int) M_RST0 + ((desired-2) & 7)))
+	action = 2;		/* a prior restart, so advance */
+      else
+	action = 1;		/* desired restart or too far away */
+    }
+    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
+    switch (action) {
+    case 1:
+      /* Discard marker and let entropy decoder resume processing. */
+      cinfo->unread_marker = 0;
+      return TRUE;
+    case 2:
+      /* Scan to the next marker, and repeat the decision loop. */
+      if (! next_marker(cinfo))
+	return FALSE;
+      marker = cinfo->unread_marker;
+      break;
+    case 3:
+      /* Return without advancing past this marker. */
+      /* Entropy decoder will be forced to process an empty segment. */
+      return TRUE;
+    }
+  } /* end loop */
+}
+
+
+/*
+ * Reset marker processing state to begin a fresh datastream.
+ */
+
+METHODDEF(void)
+reset_marker_reader (j_decompress_ptr cinfo)
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+  cinfo->comp_info = NULL;		/* until allocated by get_sof */
+  cinfo->input_scan_number = 0;		/* no SOS seen yet */
+  cinfo->unread_marker = 0;		/* no pending marker */
+  marker->pub.saw_SOI = FALSE;		/* set internal state too */
+  marker->pub.saw_SOF = FALSE;
+  marker->pub.discarded_bytes = 0;
+  marker->cur_marker = NULL;
+}
+
+
+/*
+ * Initialize the marker reader module.
+ * This is called only once, when the decompression object is created.
+ */
+
+GLOBAL(void)
+jinit_marker_reader (j_decompress_ptr cinfo)
+{
+  my_marker_ptr marker;
+  int i;
+
+  /* Create subobject in permanent pool */
+  marker = (my_marker_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				SIZEOF(my_marker_reader));
+  cinfo->marker = (struct jpeg_marker_reader *) marker;
+  /* Initialize public method pointers */
+  marker->pub.reset_marker_reader = reset_marker_reader;
+  marker->pub.read_markers = read_markers;
+  marker->pub.read_restart_marker = read_restart_marker;
+  /* Initialize COM/APPn processing.
+   * By default, we examine and then discard APP0 and APP14,
+   * but simply discard COM and all other APPn.
+   */
+  marker->process_COM = skip_variable;
+  marker->length_limit_COM = 0;
+  for (i = 0; i < 16; i++) {
+    marker->process_APPn[i] = skip_variable;
+    marker->length_limit_APPn[i] = 0;
+  }
+  marker->process_APPn[0] = get_interesting_appn;
+  marker->process_APPn[14] = get_interesting_appn;
+  /* Reset marker processing state */
+  reset_marker_reader(cinfo);
+}
+
+
+/*
+ * Control saving of COM and APPn markers into marker_list.
+ */
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+GLOBAL(void)
+jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
+		   unsigned int length_limit)
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+  long maxlength;
+  jpeg_marker_parser_method processor;
+
+  /* Length limit mustn't be larger than what we can allocate
+   * (should only be a concern in a 16-bit environment).
+   */
+  maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
+  if (((long) length_limit) > maxlength)
+    length_limit = (unsigned int) maxlength;
+
+  /* Choose processor routine to use.
+   * APP0/APP14 have special requirements.
+   */
+  if (length_limit) {
+    processor = save_marker;
+    /* If saving APP0/APP14, save at least enough for our internal use. */
+    if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
+      length_limit = APP0_DATA_LEN;
+    else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
+      length_limit = APP14_DATA_LEN;
+  } else {
+    processor = skip_variable;
+    /* If discarding APP0/APP14, use our regular on-the-fly processor. */
+    if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
+      processor = get_interesting_appn;
+  }
+
+  if (marker_code == (int) M_COM) {
+    marker->process_COM = processor;
+    marker->length_limit_COM = length_limit;
+  } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
+    marker->process_APPn[marker_code - (int) M_APP0] = processor;
+    marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
+  } else
+    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
+/*
+ * Install a special processing method for COM or APPn markers.
+ */
+
+GLOBAL(void)
+jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
+			   jpeg_marker_parser_method routine)
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+  if (marker_code == (int) M_COM)
+    marker->process_COM = routine;
+  else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
+    marker->process_APPn[marker_code - (int) M_APP0] = routine;
+  else
+    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
diff --git a/Utilities/FLTK/jpeg/jdmaster.c b/Utilities/FLTK/jpeg/jdmaster.c
new file mode 100644
index 0000000000000000000000000000000000000000..2802c5b7b29757e27b561ccccedba169deb9b42c
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdmaster.c
@@ -0,0 +1,557 @@
+/*
+ * jdmaster.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains master control logic for the JPEG decompressor.
+ * These routines are concerned with selecting the modules to be executed
+ * and with determining the number of passes and the work to be done in each
+ * pass.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private state */
+
+typedef struct {
+  struct jpeg_decomp_master pub; /* public fields */
+
+  int pass_number;		/* # of passes completed */
+
+  boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
+
+  /* Saved references to initialized quantizer modules,
+   * in case we need to switch modes.
+   */
+  struct jpeg_color_quantizer * quantizer_1pass;
+  struct jpeg_color_quantizer * quantizer_2pass;
+} my_decomp_master;
+
+typedef my_decomp_master * my_master_ptr;
+
+
+/*
+ * Determine whether merged upsample/color conversion should be used.
+ * CRUCIAL: this must match the actual capabilities of jdmerge.c!
+ */
+
+LOCAL(boolean)
+use_merged_upsample (j_decompress_ptr cinfo)
+{
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+  /* Merging is the equivalent of plain box-filter upsampling */
+  if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
+    return FALSE;
+  /* jdmerge.c only supports YCC=>RGB color conversion */
+  if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
+      cinfo->out_color_space != JCS_RGB ||
+      cinfo->out_color_components != RGB_PIXELSIZE)
+    return FALSE;
+  /* and it only handles 2h1v or 2h2v sampling ratios */
+  if (cinfo->comp_info[0].h_samp_factor != 2 ||
+      cinfo->comp_info[1].h_samp_factor != 1 ||
+      cinfo->comp_info[2].h_samp_factor != 1 ||
+      cinfo->comp_info[0].v_samp_factor >  2 ||
+      cinfo->comp_info[1].v_samp_factor != 1 ||
+      cinfo->comp_info[2].v_samp_factor != 1)
+    return FALSE;
+  /* furthermore, it doesn't work if we've scaled the IDCTs differently */
+  if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
+      cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
+      cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
+    return FALSE;
+  /* ??? also need to test for upsample-time rescaling, when & if supported */
+  return TRUE;			/* by golly, it'll work... */
+#else
+  return FALSE;
+#endif
+}
+
+
+/*
+ * Compute output image dimensions and related values.
+ * NOTE: this is exported for possible use by application.
+ * Hence it mustn't do anything that can't be done twice.
+ * Also note that it may be called before the master module is initialized!
+ */
+
+GLOBAL(void)
+jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
+/* Do computations that are needed before master selection phase */
+{
+#ifdef IDCT_SCALING_SUPPORTED
+  int ci;
+  jpeg_component_info *compptr;
+#endif
+
+  /* Prevent application from calling me at wrong times */
+  if (cinfo->global_state != DSTATE_READY)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+#ifdef IDCT_SCALING_SUPPORTED
+
+  /* Compute actual output image dimensions and DCT scaling choices. */
+  if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
+    /* Provide 1/8 scaling */
+    cinfo->output_width = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width, 8L);
+    cinfo->output_height = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height, 8L);
+    cinfo->min_DCT_scaled_size = 1;
+  } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
+    /* Provide 1/4 scaling */
+    cinfo->output_width = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width, 4L);
+    cinfo->output_height = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height, 4L);
+    cinfo->min_DCT_scaled_size = 2;
+  } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
+    /* Provide 1/2 scaling */
+    cinfo->output_width = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width, 2L);
+    cinfo->output_height = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height, 2L);
+    cinfo->min_DCT_scaled_size = 4;
+  } else {
+    /* Provide 1/1 scaling */
+    cinfo->output_width = cinfo->image_width;
+    cinfo->output_height = cinfo->image_height;
+    cinfo->min_DCT_scaled_size = DCTSIZE;
+  }
+  /* In selecting the actual DCT scaling for each component, we try to
+   * scale up the chroma components via IDCT scaling rather than upsampling.
+   * This saves time if the upsampler gets to use 1:1 scaling.
+   * Note this code assumes that the supported DCT scalings are powers of 2.
+   */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    int ssize = cinfo->min_DCT_scaled_size;
+    while (ssize < DCTSIZE &&
+	   (compptr->h_samp_factor * ssize * 2 <=
+	    cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
+	   (compptr->v_samp_factor * ssize * 2 <=
+	    cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
+      ssize = ssize * 2;
+    }
+    compptr->DCT_scaled_size = ssize;
+  }
+
+  /* Recompute downsampled dimensions of components;
+   * application needs to know these if using raw downsampled data.
+   */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Size in samples, after IDCT scaling */
+    compptr->downsampled_width = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_width *
+		    (long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
+		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
+    compptr->downsampled_height = (JDIMENSION)
+      jdiv_round_up((long) cinfo->image_height *
+		    (long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
+		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
+  }
+
+#else /* !IDCT_SCALING_SUPPORTED */
+
+  /* Hardwire it to "no scaling" */
+  cinfo->output_width = cinfo->image_width;
+  cinfo->output_height = cinfo->image_height;
+  /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
+   * and has computed unscaled downsampled_width and downsampled_height.
+   */
+
+#endif /* IDCT_SCALING_SUPPORTED */
+
+  /* Report number of components in selected colorspace. */
+  /* Probably this should be in the color conversion module... */
+  switch (cinfo->out_color_space) {
+  case JCS_GRAYSCALE:
+    cinfo->out_color_components = 1;
+    break;
+  case JCS_RGB:
+#if RGB_PIXELSIZE != 3
+    cinfo->out_color_components = RGB_PIXELSIZE;
+    break;
+#endif /* else share code with YCbCr */
+  case JCS_YCbCr:
+    cinfo->out_color_components = 3;
+    break;
+  case JCS_CMYK:
+  case JCS_YCCK:
+    cinfo->out_color_components = 4;
+    break;
+  default:			/* else must be same colorspace as in file */
+    cinfo->out_color_components = cinfo->num_components;
+    break;
+  }
+  cinfo->output_components = (cinfo->quantize_colors ? 1 :
+			      cinfo->out_color_components);
+
+  /* See if upsampler will want to emit more than one row at a time */
+  if (use_merged_upsample(cinfo))
+    cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
+  else
+    cinfo->rec_outbuf_height = 1;
+}
+
+
+/*
+ * Several decompression processes need to range-limit values to the range
+ * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
+ * due to noise introduced by quantization, roundoff error, etc.  These
+ * processes are inner loops and need to be as fast as possible.  On most
+ * machines, particularly CPUs with pipelines or instruction prefetch,
+ * a (subscript-check-less) C table lookup
+ *		x = sample_range_limit[x];
+ * is faster than explicit tests
+ *		if (x < 0)  x = 0;
+ *		else if (x > MAXJSAMPLE)  x = MAXJSAMPLE;
+ * These processes all use a common table prepared by the routine below.
+ *
+ * For most steps we can mathematically guarantee that the initial value
+ * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
+ * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient.  But for the initial
+ * limiting step (just after the IDCT), a wildly out-of-range value is 
+ * possible if the input data is corrupt.  To avoid any chance of indexing
+ * off the end of memory and getting a bad-pointer trap, we perform the
+ * post-IDCT limiting thus:
+ *		x = range_limit[x & MASK];
+ * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
+ * samples.  Under normal circumstances this is more than enough range and
+ * a correct output will be generated; with bogus input data the mask will
+ * cause wraparound, and we will safely generate a bogus-but-in-range output.
+ * For the post-IDCT step, we want to convert the data from signed to unsigned
+ * representation by adding CENTERJSAMPLE at the same time that we limit it.
+ * So the post-IDCT limiting table ends up looking like this:
+ *   CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
+ *   MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ *   0          (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ *   0,1,...,CENTERJSAMPLE-1
+ * Negative inputs select values from the upper half of the table after
+ * masking.
+ *
+ * We can save some space by overlapping the start of the post-IDCT table
+ * with the simpler range limiting table.  The post-IDCT table begins at
+ * sample_range_limit + CENTERJSAMPLE.
+ *
+ * Note that the table is allocated in near data space on PCs; it's small
+ * enough and used often enough to justify this.
+ */
+
+LOCAL(void)
+prepare_range_limit_table (j_decompress_ptr cinfo)
+/* Allocate and fill in the sample_range_limit table */
+{
+  JSAMPLE * table;
+  int i;
+
+  table = (JSAMPLE *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+		(5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
+  table += (MAXJSAMPLE+1);	/* allow negative subscripts of simple table */
+  cinfo->sample_range_limit = table;
+  /* First segment of "simple" table: limit[x] = 0 for x < 0 */
+  MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
+  /* Main part of "simple" table: limit[x] = x */
+  for (i = 0; i <= MAXJSAMPLE; i++)
+    table[i] = (JSAMPLE) i;
+  table += CENTERJSAMPLE;	/* Point to where post-IDCT table starts */
+  /* End of simple table, rest of first half of post-IDCT table */
+  for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
+    table[i] = MAXJSAMPLE;
+  /* Second half of post-IDCT table */
+  MEMZERO(table + (2 * (MAXJSAMPLE+1)),
+	  (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
+  MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
+	  cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
+}
+
+
+/*
+ * Master selection of decompression modules.
+ * This is done once at jpeg_start_decompress time.  We determine
+ * which modules will be used and give them appropriate initialization calls.
+ * We also initialize the decompressor input side to begin consuming data.
+ *
+ * Since jpeg_read_header has finished, we know what is in the SOF
+ * and (first) SOS markers.  We also have all the application parameter
+ * settings.
+ */
+
+LOCAL(void)
+master_selection (j_decompress_ptr cinfo)
+{
+  my_master_ptr master = (my_master_ptr) cinfo->master;
+  boolean use_c_buffer;
+  long samplesperrow;
+  JDIMENSION jd_samplesperrow;
+
+  /* Initialize dimensions and other stuff */
+  jpeg_calc_output_dimensions(cinfo);
+  prepare_range_limit_table(cinfo);
+
+  /* Width of an output scanline must be representable as JDIMENSION. */
+  samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
+  jd_samplesperrow = (JDIMENSION) samplesperrow;
+  if ((long) jd_samplesperrow != samplesperrow)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+
+  /* Initialize my private state */
+  master->pass_number = 0;
+  master->using_merged_upsample = use_merged_upsample(cinfo);
+
+  /* Color quantizer selection */
+  master->quantizer_1pass = NULL;
+  master->quantizer_2pass = NULL;
+  /* No mode changes if not using buffered-image mode. */
+  if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
+    cinfo->enable_1pass_quant = FALSE;
+    cinfo->enable_external_quant = FALSE;
+    cinfo->enable_2pass_quant = FALSE;
+  }
+  if (cinfo->quantize_colors) {
+    if (cinfo->raw_data_out)
+      ERREXIT(cinfo, JERR_NOTIMPL);
+    /* 2-pass quantizer only works in 3-component color space. */
+    if (cinfo->out_color_components != 3) {
+      cinfo->enable_1pass_quant = TRUE;
+      cinfo->enable_external_quant = FALSE;
+      cinfo->enable_2pass_quant = FALSE;
+      cinfo->colormap = NULL;
+    } else if (cinfo->colormap != NULL) {
+      cinfo->enable_external_quant = TRUE;
+    } else if (cinfo->two_pass_quantize) {
+      cinfo->enable_2pass_quant = TRUE;
+    } else {
+      cinfo->enable_1pass_quant = TRUE;
+    }
+
+    if (cinfo->enable_1pass_quant) {
+#ifdef QUANT_1PASS_SUPPORTED
+      jinit_1pass_quantizer(cinfo);
+      master->quantizer_1pass = cinfo->cquantize;
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    }
+
+    /* We use the 2-pass code to map to external colormaps. */
+    if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
+#ifdef QUANT_2PASS_SUPPORTED
+      jinit_2pass_quantizer(cinfo);
+      master->quantizer_2pass = cinfo->cquantize;
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    }
+    /* If both quantizers are initialized, the 2-pass one is left active;
+     * this is necessary for starting with quantization to an external map.
+     */
+  }
+
+  /* Post-processing: in particular, color conversion first */
+  if (! cinfo->raw_data_out) {
+    if (master->using_merged_upsample) {
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+      jinit_merged_upsampler(cinfo); /* does color conversion too */
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    } else {
+      jinit_color_deconverter(cinfo);
+      jinit_upsampler(cinfo);
+    }
+    jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
+  }
+  /* Inverse DCT */
+  jinit_inverse_dct(cinfo);
+  /* Entropy decoding: either Huffman or arithmetic coding. */
+  if (cinfo->arith_code) {
+    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+  } else {
+    if (cinfo->progressive_mode) {
+#ifdef D_PROGRESSIVE_SUPPORTED
+      jinit_phuff_decoder(cinfo);
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    } else
+      jinit_huff_decoder(cinfo);
+  }
+
+  /* Initialize principal buffer controllers. */
+  use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
+  jinit_d_coef_controller(cinfo, use_c_buffer);
+
+  if (! cinfo->raw_data_out)
+    jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
+
+  /* We can now tell the memory manager to allocate virtual arrays. */
+  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+  /* Initialize input side of decompressor to consume first scan. */
+  (*cinfo->inputctl->start_input_pass) (cinfo);
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+  /* If jpeg_start_decompress will read the whole file, initialize
+   * progress monitoring appropriately.  The input step is counted
+   * as one pass.
+   */
+  if (cinfo->progress != NULL && ! cinfo->buffered_image &&
+      cinfo->inputctl->has_multiple_scans) {
+    int nscans;
+    /* Estimate number of scans to set pass_limit. */
+    if (cinfo->progressive_mode) {
+      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
+      nscans = 2 + 3 * cinfo->num_components;
+    } else {
+      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
+      nscans = cinfo->num_components;
+    }
+    cinfo->progress->pass_counter = 0L;
+    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
+    cinfo->progress->completed_passes = 0;
+    cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
+    /* Count the input pass as done */
+    master->pass_number++;
+  }
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+}
+
+
+/*
+ * Per-pass setup.
+ * This is called at the beginning of each output pass.  We determine which
+ * modules will be active during this pass and give them appropriate
+ * start_pass calls.  We also set is_dummy_pass to indicate whether this
+ * is a "real" output pass or a dummy pass for color quantization.
+ * (In the latter case, jdapistd.c will crank the pass to completion.)
+ */
+
+METHODDEF(void)
+prepare_for_output_pass (j_decompress_ptr cinfo)
+{
+  my_master_ptr master = (my_master_ptr) cinfo->master;
+
+  if (master->pub.is_dummy_pass) {
+#ifdef QUANT_2PASS_SUPPORTED
+    /* Final pass of 2-pass quantization */
+    master->pub.is_dummy_pass = FALSE;
+    (*cinfo->cquantize->start_pass) (cinfo, FALSE);
+    (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
+    (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
+#else
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* QUANT_2PASS_SUPPORTED */
+  } else {
+    if (cinfo->quantize_colors && cinfo->colormap == NULL) {
+      /* Select new quantization method */
+      if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
+	cinfo->cquantize = master->quantizer_2pass;
+	master->pub.is_dummy_pass = TRUE;
+      } else if (cinfo->enable_1pass_quant) {
+	cinfo->cquantize = master->quantizer_1pass;
+      } else {
+	ERREXIT(cinfo, JERR_MODE_CHANGE);
+      }
+    }
+    (*cinfo->idct->start_pass) (cinfo);
+    (*cinfo->coef->start_output_pass) (cinfo);
+    if (! cinfo->raw_data_out) {
+      if (! master->using_merged_upsample)
+	(*cinfo->cconvert->start_pass) (cinfo);
+      (*cinfo->upsample->start_pass) (cinfo);
+      if (cinfo->quantize_colors)
+	(*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
+      (*cinfo->post->start_pass) (cinfo,
+	    (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
+      (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
+    }
+  }
+
+  /* Set up progress monitor's pass info if present */
+  if (cinfo->progress != NULL) {
+    cinfo->progress->completed_passes = master->pass_number;
+    cinfo->progress->total_passes = master->pass_number +
+				    (master->pub.is_dummy_pass ? 2 : 1);
+    /* In buffered-image mode, we assume one more output pass if EOI not
+     * yet reached, but no more passes if EOI has been reached.
+     */
+    if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
+      cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
+    }
+  }
+}
+
+
+/*
+ * Finish up at end of an output pass.
+ */
+
+METHODDEF(void)
+finish_output_pass (j_decompress_ptr cinfo)
+{
+  my_master_ptr master = (my_master_ptr) cinfo->master;
+
+  if (cinfo->quantize_colors)
+    (*cinfo->cquantize->finish_pass) (cinfo);
+  master->pass_number++;
+}
+
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Switch to a new external colormap between output passes.
+ */
+
+GLOBAL(void)
+jpeg_new_colormap (j_decompress_ptr cinfo)
+{
+  my_master_ptr master = (my_master_ptr) cinfo->master;
+
+  /* Prevent application from calling me at wrong times */
+  if (cinfo->global_state != DSTATE_BUFIMAGE)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  if (cinfo->quantize_colors && cinfo->enable_external_quant &&
+      cinfo->colormap != NULL) {
+    /* Select 2-pass quantizer for external colormap use */
+    cinfo->cquantize = master->quantizer_2pass;
+    /* Notify quantizer of colormap change */
+    (*cinfo->cquantize->new_color_map) (cinfo);
+    master->pub.is_dummy_pass = FALSE; /* just in case */
+  } else
+    ERREXIT(cinfo, JERR_MODE_CHANGE);
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+
+
+/*
+ * Initialize master decompression control and select active modules.
+ * This is performed at the start of jpeg_start_decompress.
+ */
+
+GLOBAL(void)
+jinit_master_decompress (j_decompress_ptr cinfo)
+{
+  my_master_ptr master;
+
+  master = (my_master_ptr)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(my_decomp_master));
+  cinfo->master = (struct jpeg_decomp_master *) master;
+  master->pub.prepare_for_output_pass = prepare_for_output_pass;
+  master->pub.finish_output_pass = finish_output_pass;
+
+  master->pub.is_dummy_pass = FALSE;
+
+  master_selection(cinfo);
+}
diff --git a/Utilities/FLTK/jpeg/jdmerge.c b/Utilities/FLTK/jpeg/jdmerge.c
new file mode 100644
index 0000000000000000000000000000000000000000..37444468c2370a71f1317a50ddaf3287e3e04969
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdmerge.c
@@ -0,0 +1,400 @@
+/*
+ * jdmerge.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains code for merged upsampling/color conversion.
+ *
+ * This file combines functions from jdsample.c and jdcolor.c;
+ * read those files first to understand what's going on.
+ *
+ * When the chroma components are to be upsampled by simple replication
+ * (ie, box filtering), we can save some work in color conversion by
+ * calculating all the output pixels corresponding to a pair of chroma
+ * samples at one time.  In the conversion equations
+ *	R = Y           + K1 * Cr
+ *	G = Y + K2 * Cb + K3 * Cr
+ *	B = Y + K4 * Cb
+ * only the Y term varies among the group of pixels corresponding to a pair
+ * of chroma samples, so the rest of the terms can be calculated just once.
+ * At typical sampling ratios, this eliminates half or three-quarters of the
+ * multiplications needed for color conversion.
+ *
+ * This file currently provides implementations for the following cases:
+ *	YCbCr => RGB color conversion only.
+ *	Sampling ratios of 2h1v or 2h2v.
+ *	No scaling needed at upsample time.
+ *	Corner-aligned (non-CCIR601) sampling alignment.
+ * Other special cases could be added, but in most applications these are
+ * the only common cases.  (For uncommon cases we fall back on the more
+ * general code in jdsample.c and jdcolor.c.)
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+
+
+/* Private subobject */
+
+typedef struct {
+  struct jpeg_upsampler pub;	/* public fields */
+
+  /* Pointer to routine to do actual upsampling/conversion of one row group */
+  JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
+			   JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+			   JSAMPARRAY output_buf));
+
+  /* Private state for YCC->RGB conversion */
+  int * Cr_r_tab;		/* => table for Cr to R conversion */
+  int * Cb_b_tab;		/* => table for Cb to B conversion */
+  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
+  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
+
+  /* For 2:1 vertical sampling, we produce two output rows at a time.
+   * We need a "spare" row buffer to hold the second output row if the
+   * application provides just a one-row buffer; we also use the spare
+   * to discard the dummy last row if the image height is odd.
+   */
+  JSAMPROW spare_row;
+  boolean spare_full;		/* T if spare buffer is occupied */
+
+  JDIMENSION out_row_width;	/* samples per output row */
+  JDIMENSION rows_to_go;	/* counts rows remaining in image */
+} my_upsampler;
+
+typedef my_upsampler * my_upsample_ptr;
+
+#define SCALEBITS	16	/* speediest right-shift on some machines */
+#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
+#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+
+/*
+ * Initialize tables for YCC->RGB colorspace conversion.
+ * This is taken directly from jdcolor.c; see that file for more info.
+ */
+
+LOCAL(void)
+build_ycc_rgb_table (j_decompress_ptr cinfo)
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+  int i;
+  INT32 x;
+  SHIFT_TEMPS
+
+  upsample->Cr_r_tab = (int *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(int));
+  upsample->Cb_b_tab = (int *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(int));
+  upsample->Cr_g_tab = (INT32 *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(INT32));
+  upsample->Cb_g_tab = (INT32 *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(INT32));
+
+  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
+    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+    /* Cr=>R value is nearest int to 1.40200 * x */
+    upsample->Cr_r_tab[i] = (int)
+		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
+    /* Cb=>B value is nearest int to 1.77200 * x */
+    upsample->Cb_b_tab[i] = (int)
+		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
+    /* Cr=>G value is scaled-up -0.71414 * x */
+    upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
+    /* Cb=>G value is scaled-up -0.34414 * x */
+    /* We also add in ONE_HALF so that need not do it in inner loop */
+    upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+  }
+}
+
+
+/*
+ * Initialize for an upsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_merged_upsample (j_decompress_ptr cinfo)
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+  /* Mark the spare buffer empty */
+  upsample->spare_full = FALSE;
+  /* Initialize total-height counter for detecting bottom of image */
+  upsample->rows_to_go = cinfo->output_height;
+}
+
+
+/*
+ * Control routine to do upsampling (and color conversion).
+ *
+ * The control routine just handles the row buffering considerations.
+ */
+
+METHODDEF(void)
+merged_2v_upsample (j_decompress_ptr cinfo,
+		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+		    JDIMENSION in_row_groups_avail,
+		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+		    JDIMENSION out_rows_avail)
+/* 2:1 vertical sampling case: may need a spare row. */
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+  JSAMPROW work_ptrs[2];
+  JDIMENSION num_rows;		/* number of rows returned to caller */
+
+  if (upsample->spare_full) {
+    /* If we have a spare row saved from a previous cycle, just return it. */
+    jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
+		      1, upsample->out_row_width);
+    num_rows = 1;
+    upsample->spare_full = FALSE;
+  } else {
+    /* Figure number of rows to return to caller. */
+    num_rows = 2;
+    /* Not more than the distance to the end of the image. */
+    if (num_rows > upsample->rows_to_go)
+      num_rows = upsample->rows_to_go;
+    /* And not more than what the client can accept: */
+    out_rows_avail -= *out_row_ctr;
+    if (num_rows > out_rows_avail)
+      num_rows = out_rows_avail;
+    /* Create output pointer array for upsampler. */
+    work_ptrs[0] = output_buf[*out_row_ctr];
+    if (num_rows > 1) {
+      work_ptrs[1] = output_buf[*out_row_ctr + 1];
+    } else {
+      work_ptrs[1] = upsample->spare_row;
+      upsample->spare_full = TRUE;
+    }
+    /* Now do the upsampling. */
+    (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
+  }
+
+  /* Adjust counts */
+  *out_row_ctr += num_rows;
+  upsample->rows_to_go -= num_rows;
+  /* When the buffer is emptied, declare this input row group consumed */
+  if (! upsample->spare_full)
+    (*in_row_group_ctr)++;
+}
+
+
+METHODDEF(void)
+merged_1v_upsample (j_decompress_ptr cinfo,
+		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+		    JDIMENSION in_row_groups_avail,
+		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+		    JDIMENSION out_rows_avail)
+/* 1:1 vertical sampling case: much easier, never need a spare row. */
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+  /* Just do the upsampling. */
+  (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
+			 output_buf + *out_row_ctr);
+  /* Adjust counts */
+  (*out_row_ctr)++;
+  (*in_row_group_ctr)++;
+}
+
+
+/*
+ * These are the routines invoked by the control routines to do
+ * the actual upsampling/conversion.  One row group is processed per call.
+ *
+ * Note: since we may be writing directly into application-supplied buffers,
+ * we have to be honest about the output width; we can't assume the buffer
+ * has been rounded up to an even width.
+ */
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
+ */
+
+METHODDEF(void)
+h2v1_merged_upsample (j_decompress_ptr cinfo,
+		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+		      JSAMPARRAY output_buf)
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+  register int y, cred, cgreen, cblue;
+  int cb, cr;
+  register JSAMPROW outptr;
+  JSAMPROW inptr0, inptr1, inptr2;
+  JDIMENSION col;
+  /* copy these pointers into registers if possible */
+  register JSAMPLE * range_limit = cinfo->sample_range_limit;
+  int * Crrtab = upsample->Cr_r_tab;
+  int * Cbbtab = upsample->Cb_b_tab;
+  INT32 * Crgtab = upsample->Cr_g_tab;
+  INT32 * Cbgtab = upsample->Cb_g_tab;
+  SHIFT_TEMPS
+
+  inptr0 = input_buf[0][in_row_group_ctr];
+  inptr1 = input_buf[1][in_row_group_ctr];
+  inptr2 = input_buf[2][in_row_group_ctr];
+  outptr = output_buf[0];
+  /* Loop for each pair of output pixels */
+  for (col = cinfo->output_width >> 1; col > 0; col--) {
+    /* Do the chroma part of the calculation */
+    cb = GETJSAMPLE(*inptr1++);
+    cr = GETJSAMPLE(*inptr2++);
+    cred = Crrtab[cr];
+    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+    cblue = Cbbtab[cb];
+    /* Fetch 2 Y values and emit 2 pixels */
+    y  = GETJSAMPLE(*inptr0++);
+    outptr[RGB_RED] =   range_limit[y + cred];
+    outptr[RGB_GREEN] = range_limit[y + cgreen];
+    outptr[RGB_BLUE] =  range_limit[y + cblue];
+    outptr += RGB_PIXELSIZE;
+    y  = GETJSAMPLE(*inptr0++);
+    outptr[RGB_RED] =   range_limit[y + cred];
+    outptr[RGB_GREEN] = range_limit[y + cgreen];
+    outptr[RGB_BLUE] =  range_limit[y + cblue];
+    outptr += RGB_PIXELSIZE;
+  }
+  /* If image width is odd, do the last output column separately */
+  if (cinfo->output_width & 1) {
+    cb = GETJSAMPLE(*inptr1);
+    cr = GETJSAMPLE(*inptr2);
+    cred = Crrtab[cr];
+    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+    cblue = Cbbtab[cb];
+    y  = GETJSAMPLE(*inptr0);
+    outptr[RGB_RED] =   range_limit[y + cred];
+    outptr[RGB_GREEN] = range_limit[y + cgreen];
+    outptr[RGB_BLUE] =  range_limit[y + cblue];
+  }
+}
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
+ */
+
+METHODDEF(void)
+h2v2_merged_upsample (j_decompress_ptr cinfo,
+		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+		      JSAMPARRAY output_buf)
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+  register int y, cred, cgreen, cblue;
+  int cb, cr;
+  register JSAMPROW outptr0, outptr1;
+  JSAMPROW inptr00, inptr01, inptr1, inptr2;
+  JDIMENSION col;
+  /* copy these pointers into registers if possible */
+  register JSAMPLE * range_limit = cinfo->sample_range_limit;
+  int * Crrtab = upsample->Cr_r_tab;
+  int * Cbbtab = upsample->Cb_b_tab;
+  INT32 * Crgtab = upsample->Cr_g_tab;
+  INT32 * Cbgtab = upsample->Cb_g_tab;
+  SHIFT_TEMPS
+
+  inptr00 = input_buf[0][in_row_group_ctr*2];
+  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
+  inptr1 = input_buf[1][in_row_group_ctr];
+  inptr2 = input_buf[2][in_row_group_ctr];
+  outptr0 = output_buf[0];
+  outptr1 = output_buf[1];
+  /* Loop for each group of output pixels */
+  for (col = cinfo->output_width >> 1; col > 0; col--) {
+    /* Do the chroma part of the calculation */
+    cb = GETJSAMPLE(*inptr1++);
+    cr = GETJSAMPLE(*inptr2++);
+    cred = Crrtab[cr];
+    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+    cblue = Cbbtab[cb];
+    /* Fetch 4 Y values and emit 4 pixels */
+    y  = GETJSAMPLE(*inptr00++);
+    outptr0[RGB_RED] =   range_limit[y + cred];
+    outptr0[RGB_GREEN] = range_limit[y + cgreen];
+    outptr0[RGB_BLUE] =  range_limit[y + cblue];
+    outptr0 += RGB_PIXELSIZE;
+    y  = GETJSAMPLE(*inptr00++);
+    outptr0[RGB_RED] =   range_limit[y + cred];
+    outptr0[RGB_GREEN] = range_limit[y + cgreen];
+    outptr0[RGB_BLUE] =  range_limit[y + cblue];
+    outptr0 += RGB_PIXELSIZE;
+    y  = GETJSAMPLE(*inptr01++);
+    outptr1[RGB_RED] =   range_limit[y + cred];
+    outptr1[RGB_GREEN] = range_limit[y + cgreen];
+    outptr1[RGB_BLUE] =  range_limit[y + cblue];
+    outptr1 += RGB_PIXELSIZE;
+    y  = GETJSAMPLE(*inptr01++);
+    outptr1[RGB_RED] =   range_limit[y + cred];
+    outptr1[RGB_GREEN] = range_limit[y + cgreen];
+    outptr1[RGB_BLUE] =  range_limit[y + cblue];
+    outptr1 += RGB_PIXELSIZE;
+  }
+  /* If image width is odd, do the last output column separately */
+  if (cinfo->output_width & 1) {
+    cb = GETJSAMPLE(*inptr1);
+    cr = GETJSAMPLE(*inptr2);
+    cred = Crrtab[cr];
+    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+    cblue = Cbbtab[cb];
+    y  = GETJSAMPLE(*inptr00);
+    outptr0[RGB_RED] =   range_limit[y + cred];
+    outptr0[RGB_GREEN] = range_limit[y + cgreen];
+    outptr0[RGB_BLUE] =  range_limit[y + cblue];
+    y  = GETJSAMPLE(*inptr01);
+    outptr1[RGB_RED] =   range_limit[y + cred];
+    outptr1[RGB_GREEN] = range_limit[y + cgreen];
+    outptr1[RGB_BLUE] =  range_limit[y + cblue];
+  }
+}
+
+
+/*
+ * Module initialization routine for merged upsampling/color conversion.
+ *
+ * NB: this is called under the conditions determined by use_merged_upsample()
+ * in jdmaster.c.  That routine MUST correspond to the actual capabilities
+ * of this module; no safety checks are made here.
+ */
+
+GLOBAL(void)
+jinit_merged_upsampler (j_decompress_ptr cinfo)
+{
+  my_upsample_ptr upsample;
+
+  upsample = (my_upsample_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_upsampler));
+  cinfo->upsample = (struct jpeg_upsampler *) upsample;
+  upsample->pub.start_pass = start_pass_merged_upsample;
+  upsample->pub.need_context_rows = FALSE;
+
+  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
+
+  if (cinfo->max_v_samp_factor == 2) {
+    upsample->pub.upsample = merged_2v_upsample;
+    upsample->upmethod = h2v2_merged_upsample;
+    /* Allocate a spare row buffer */
+    upsample->spare_row = (JSAMPROW)
+      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+		(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
+  } else {
+    upsample->pub.upsample = merged_1v_upsample;
+    upsample->upmethod = h2v1_merged_upsample;
+    /* No spare row needed */
+    upsample->spare_row = NULL;
+  }
+
+  build_ycc_rgb_table(cinfo);
+}
+
+#endif /* UPSAMPLE_MERGING_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jdphuff.c b/Utilities/FLTK/jpeg/jdphuff.c
new file mode 100644
index 0000000000000000000000000000000000000000..22678099451a7f606c5cb2652940d569ba7885d5
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdphuff.c
@@ -0,0 +1,668 @@
+/*
+ * jdphuff.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy decoding routines for progressive JPEG.
+ *
+ * Much of the complexity here has to do with supporting input suspension.
+ * If the data source module demands suspension, we want to be able to back
+ * up to the start of the current MCU.  To do this, we copy state variables
+ * into local working storage, and update them back to the permanent
+ * storage only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdhuff.h"		/* Declarations shared with jdhuff.c */
+
+
+#ifdef D_PROGRESSIVE_SUPPORTED
+
+/*
+ * Expanded entropy decoder object for progressive Huffman decoding.
+ *
+ * The savable_state subrecord contains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+  unsigned int EOBRUN;			/* remaining EOBs in EOBRUN */
+  int last_dc_val[MAX_COMPS_IN_SCAN];	/* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment.  You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src)  ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src)  \
+	((dest).EOBRUN = (src).EOBRUN, \
+	 (dest).last_dc_val[0] = (src).last_dc_val[0], \
+	 (dest).last_dc_val[1] = (src).last_dc_val[1], \
+	 (dest).last_dc_val[2] = (src).last_dc_val[2], \
+	 (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+  struct jpeg_entropy_decoder pub; /* public fields */
+
+  /* These fields are loaded into local variables at start of each MCU.
+   * In case of suspension, we exit WITHOUT updating them.
+   */
+  bitread_perm_state bitstate;	/* Bit buffer at start of MCU */
+  savable_state saved;		/* Other state at start of MCU */
+
+  /* These fields are NOT loaded into local working state. */
+  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
+
+  /* Pointers to derived tables (these workspaces have image lifespan) */
+  d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
+
+  d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
+} phuff_entropy_decoder;
+
+typedef phuff_entropy_decoder * phuff_entropy_ptr;
+
+/* Forward declarations */
+METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
+					    JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
+					    JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
+					     JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
+					     JBLOCKROW *MCU_data));
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass_phuff_decoder (j_decompress_ptr cinfo)
+{
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  boolean is_DC_band, bad;
+  int ci, coefi, tbl;
+  int *coef_bit_ptr;
+  jpeg_component_info * compptr;
+
+  is_DC_band = (cinfo->Ss == 0);
+
+  /* Validate scan parameters */
+  bad = FALSE;
+  if (is_DC_band) {
+    if (cinfo->Se != 0)
+      bad = TRUE;
+  } else {
+    /* need not check Ss/Se < 0 since they came from unsigned bytes */
+    if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
+      bad = TRUE;
+    /* AC scans may have only one component */
+    if (cinfo->comps_in_scan != 1)
+      bad = TRUE;
+  }
+  if (cinfo->Ah != 0) {
+    /* Successive approximation refinement scan: must have Al = Ah-1. */
+    if (cinfo->Al != cinfo->Ah-1)
+      bad = TRUE;
+  }
+  if (cinfo->Al > 13)		/* need not check for < 0 */
+    bad = TRUE;
+  /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
+   * but the spec doesn't say so, and we try to be liberal about what we
+   * accept.  Note: large Al values could result in out-of-range DC
+   * coefficients during early scans, leading to bizarre displays due to
+   * overflows in the IDCT math.  But we won't crash.
+   */
+  if (bad)
+    ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
+	     cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
+  /* Update progression status, and verify that scan order is legal.
+   * Note that inter-scan inconsistencies are treated as warnings
+   * not fatal errors ... not clear if this is right way to behave.
+   */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    int cindex = cinfo->cur_comp_info[ci]->component_index;
+    coef_bit_ptr = & cinfo->coef_bits[cindex][0];
+    if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
+      WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
+    for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
+      int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
+      if (cinfo->Ah != expected)
+	WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
+      coef_bit_ptr[coefi] = cinfo->Al;
+    }
+  }
+
+  /* Select MCU decoding routine */
+  if (cinfo->Ah == 0) {
+    if (is_DC_band)
+      entropy->pub.decode_mcu = decode_mcu_DC_first;
+    else
+      entropy->pub.decode_mcu = decode_mcu_AC_first;
+  } else {
+    if (is_DC_band)
+      entropy->pub.decode_mcu = decode_mcu_DC_refine;
+    else
+      entropy->pub.decode_mcu = decode_mcu_AC_refine;
+  }
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    /* Make sure requested tables are present, and compute derived tables.
+     * We may build same derived table more than once, but it's not expensive.
+     */
+    if (is_DC_band) {
+      if (cinfo->Ah == 0) {	/* DC refinement needs no table */
+	tbl = compptr->dc_tbl_no;
+	jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
+				& entropy->derived_tbls[tbl]);
+      }
+    } else {
+      tbl = compptr->ac_tbl_no;
+      jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
+			      & entropy->derived_tbls[tbl]);
+      /* remember the single active table */
+      entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
+    }
+    /* Initialize DC predictions to 0 */
+    entropy->saved.last_dc_val[ci] = 0;
+  }
+
+  /* Initialize bitread state variables */
+  entropy->bitstate.bits_left = 0;
+  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
+  entropy->pub.insufficient_data = FALSE;
+
+  /* Initialize private state variables */
+  entropy->saved.EOBRUN = 0;
+
+  /* Initialize restart counter */
+  entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Figure F.12: extend sign bit.
+ * On some machines, a shift and add will be faster than a table lookup.
+ */
+
+#ifdef AVOID_TABLES
+
+#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
+
+#else
+
+#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
+
+static const int extend_test[16] =   /* entry n is 2**(n-1) */
+  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+
+static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
+  { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
+    ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
+    ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
+    ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
+
+#endif /* AVOID_TABLES */
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ * Returns FALSE if must suspend.
+ */
+
+LOCAL(boolean)
+process_restart (j_decompress_ptr cinfo)
+{
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  int ci;
+
+  /* Throw away any unused bits remaining in bit buffer; */
+  /* include any full bytes in next_marker's count of discarded bytes */
+  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
+  entropy->bitstate.bits_left = 0;
+
+  /* Advance past the RSTn marker */
+  if (! (*cinfo->marker->read_restart_marker) (cinfo))
+    return FALSE;
+
+  /* Re-initialize DC predictions to 0 */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+    entropy->saved.last_dc_val[ci] = 0;
+  /* Re-init EOB run count, too */
+  entropy->saved.EOBRUN = 0;
+
+  /* Reset restart counter */
+  entropy->restarts_to_go = cinfo->restart_interval;
+
+  /* Reset out-of-data flag, unless read_restart_marker left us smack up
+   * against a marker.  In that case we will end up treating the next data
+   * segment as empty, and we can avoid producing bogus output pixels by
+   * leaving the flag set.
+   */
+  if (cinfo->unread_marker == 0)
+    entropy->pub.insufficient_data = FALSE;
+
+  return TRUE;
+}
+
+
+/*
+ * Huffman MCU decoding.
+ * Each of these routines decodes and returns one MCU's worth of
+ * Huffman-compressed coefficients. 
+ * The coefficients are reordered from zigzag order into natural array order,
+ * but are not dequantized.
+ *
+ * The i'th block of the MCU is stored into the block pointed to by
+ * MCU_data[i].  WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
+ *
+ * We return FALSE if data source requested suspension.  In that case no
+ * changes have been made to permanent state.  (Exception: some output
+ * coefficients may already have been assigned.  This is harmless for
+ * spectral selection, since we'll just re-assign them on the next call.
+ * Successive approximation AC refinement has to be more careful, however.)
+ */
+
+/*
+ * MCU decoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{   
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  int Al = cinfo->Al;
+  register int s, r;
+  int blkn, ci;
+  JBLOCKROW block;
+  BITREAD_STATE_VARS;
+  savable_state state;
+  d_derived_tbl * tbl;
+  jpeg_component_info * compptr;
+
+  /* Process restart marker if needed; may have to suspend */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0)
+      if (! process_restart(cinfo))
+	return FALSE;
+  }
+
+  /* If we've run out of data, just leave the MCU set to zeroes.
+   * This way, we return uniform gray for the remainder of the segment.
+   */
+  if (! entropy->pub.insufficient_data) {
+
+    /* Load up working state */
+    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(state, entropy->saved);
+
+    /* Outer loop handles each block in the MCU */
+
+    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+      block = MCU_data[blkn];
+      ci = cinfo->MCU_membership[blkn];
+      compptr = cinfo->cur_comp_info[ci];
+      tbl = entropy->derived_tbls[compptr->dc_tbl_no];
+
+      /* Decode a single block's worth of coefficients */
+
+      /* Section F.2.2.1: decode the DC coefficient difference */
+      HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
+      if (s) {
+	CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	r = GET_BITS(s);
+	s = HUFF_EXTEND(r, s);
+      }
+
+      /* Convert DC difference to actual value, update last_dc_val */
+      s += state.last_dc_val[ci];
+      state.last_dc_val[ci] = s;
+      /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
+      (*block)[0] = (JCOEF) (s << Al);
+    }
+
+    /* Completed MCU, so update state */
+    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(entropy->saved, state);
+  }
+
+  /* Account for restart interval (no-op if not using restarts) */
+  entropy->restarts_to_go--;
+
+  return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{   
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  int Se = cinfo->Se;
+  int Al = cinfo->Al;
+  register int s, k, r;
+  unsigned int EOBRUN;
+  JBLOCKROW block;
+  BITREAD_STATE_VARS;
+  d_derived_tbl * tbl;
+
+  /* Process restart marker if needed; may have to suspend */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0)
+      if (! process_restart(cinfo))
+	return FALSE;
+  }
+
+  /* If we've run out of data, just leave the MCU set to zeroes.
+   * This way, we return uniform gray for the remainder of the segment.
+   */
+  if (! entropy->pub.insufficient_data) {
+
+    /* Load up working state.
+     * We can avoid loading/saving bitread state if in an EOB run.
+     */
+    EOBRUN = entropy->saved.EOBRUN;	/* only part of saved state we need */
+
+    /* There is always only one block per MCU */
+
+    if (EOBRUN > 0)		/* if it's a band of zeroes... */
+      EOBRUN--;			/* ...process it now (we do nothing) */
+    else {
+      BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+      block = MCU_data[0];
+      tbl = entropy->ac_derived_tbl;
+
+      for (k = cinfo->Ss; k <= Se; k++) {
+	HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
+	r = s >> 4;
+	s &= 15;
+	if (s) {
+	  k += r;
+	  CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	  r = GET_BITS(s);
+	  s = HUFF_EXTEND(r, s);
+	  /* Scale and output coefficient in natural (dezigzagged) order */
+	  (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
+	} else {
+	  if (r == 15) {	/* ZRL */
+	    k += 15;		/* skip 15 zeroes in band */
+	  } else {		/* EOBr, run length is 2^r + appended bits */
+	    EOBRUN = 1 << r;
+	    if (r) {		/* EOBr, r > 0 */
+	      CHECK_BIT_BUFFER(br_state, r, return FALSE);
+	      r = GET_BITS(r);
+	      EOBRUN += r;
+	    }
+	    EOBRUN--;		/* this band is processed at this moment */
+	    break;		/* force end-of-band */
+	  }
+	}
+      }
+
+      BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    }
+
+    /* Completed MCU, so update state */
+    entropy->saved.EOBRUN = EOBRUN;	/* only part of saved state we need */
+  }
+
+  /* Account for restart interval (no-op if not using restarts) */
+  entropy->restarts_to_go--;
+
+  return TRUE;
+}
+
+
+/*
+ * MCU decoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component, although the spec
+ * is not very clear on the point.
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{   
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  int p1 = 1 << cinfo->Al;	/* 1 in the bit position being coded */
+  int blkn;
+  JBLOCKROW block;
+  BITREAD_STATE_VARS;
+
+  /* Process restart marker if needed; may have to suspend */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0)
+      if (! process_restart(cinfo))
+	return FALSE;
+  }
+
+  /* Not worth the cycles to check insufficient_data here,
+   * since we will not change the data anyway if we read zeroes.
+   */
+
+  /* Load up working state */
+  BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+
+  /* Outer loop handles each block in the MCU */
+
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    block = MCU_data[blkn];
+
+    /* Encoded data is simply the next bit of the two's-complement DC value */
+    CHECK_BIT_BUFFER(br_state, 1, return FALSE);
+    if (GET_BITS(1))
+      (*block)[0] |= p1;
+    /* Note: since we use |=, repeating the assignment later is safe */
+  }
+
+  /* Completed MCU, so update state */
+  BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+
+  /* Account for restart interval (no-op if not using restarts) */
+  entropy->restarts_to_go--;
+
+  return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{   
+  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+  int Se = cinfo->Se;
+  int p1 = 1 << cinfo->Al;	/* 1 in the bit position being coded */
+  int m1 = (-1) << cinfo->Al;	/* -1 in the bit position being coded */
+  register int s, k, r;
+  unsigned int EOBRUN;
+  JBLOCKROW block;
+  JCOEFPTR thiscoef;
+  BITREAD_STATE_VARS;
+  d_derived_tbl * tbl;
+  int num_newnz;
+  int newnz_pos[DCTSIZE2];
+
+  /* Process restart marker if needed; may have to suspend */
+  if (cinfo->restart_interval) {
+    if (entropy->restarts_to_go == 0)
+      if (! process_restart(cinfo))
+	return FALSE;
+  }
+
+  /* If we've run out of data, don't modify the MCU.
+   */
+  if (! entropy->pub.insufficient_data) {
+
+    /* Load up working state */
+    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+    EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
+
+    /* There is always only one block per MCU */
+    block = MCU_data[0];
+    tbl = entropy->ac_derived_tbl;
+
+    /* If we are forced to suspend, we must undo the assignments to any newly
+     * nonzero coefficients in the block, because otherwise we'd get confused
+     * next time about which coefficients were already nonzero.
+     * But we need not undo addition of bits to already-nonzero coefficients;
+     * instead, we can test the current bit to see if we already did it.
+     */
+    num_newnz = 0;
+
+    /* initialize coefficient loop counter to start of band */
+    k = cinfo->Ss;
+
+    if (EOBRUN == 0) {
+      for (; k <= Se; k++) {
+	HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
+	r = s >> 4;
+	s &= 15;
+	if (s) {
+	  if (s != 1)		/* size of new coef should always be 1 */
+	    WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
+	  CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+	  if (GET_BITS(1))
+	    s = p1;		/* newly nonzero coef is positive */
+	  else
+	    s = m1;		/* newly nonzero coef is negative */
+	} else {
+	  if (r != 15) {
+	    EOBRUN = 1 << r;	/* EOBr, run length is 2^r + appended bits */
+	    if (r) {
+	      CHECK_BIT_BUFFER(br_state, r, goto undoit);
+	      r = GET_BITS(r);
+	      EOBRUN += r;
+	    }
+	    break;		/* rest of block is handled by EOB logic */
+	  }
+	  /* note s = 0 for processing ZRL */
+	}
+	/* Advance over already-nonzero coefs and r still-zero coefs,
+	 * appending correction bits to the nonzeroes.  A correction bit is 1
+	 * if the absolute value of the coefficient must be increased.
+	 */
+	do {
+	  thiscoef = *block + jpeg_natural_order[k];
+	  if (*thiscoef != 0) {
+	    CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+	    if (GET_BITS(1)) {
+	      if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
+		if (*thiscoef >= 0)
+		  *thiscoef += p1;
+		else
+		  *thiscoef += m1;
+	      }
+	    }
+	  } else {
+	    if (--r < 0)
+	      break;		/* reached target zero coefficient */
+	  }
+	  k++;
+	} while (k <= Se);
+	if (s) {
+	  int pos = jpeg_natural_order[k];
+	  /* Output newly nonzero coefficient */
+	  (*block)[pos] = (JCOEF) s;
+	  /* Remember its position in case we have to suspend */
+	  newnz_pos[num_newnz++] = pos;
+	}
+      }
+    }
+
+    if (EOBRUN > 0) {
+      /* Scan any remaining coefficient positions after the end-of-band
+       * (the last newly nonzero coefficient, if any).  Append a correction
+       * bit to each already-nonzero coefficient.  A correction bit is 1
+       * if the absolute value of the coefficient must be increased.
+       */
+      for (; k <= Se; k++) {
+	thiscoef = *block + jpeg_natural_order[k];
+	if (*thiscoef != 0) {
+	  CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+	  if (GET_BITS(1)) {
+	    if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
+	      if (*thiscoef >= 0)
+		*thiscoef += p1;
+	      else
+		*thiscoef += m1;
+	    }
+	  }
+	}
+      }
+      /* Count one block completed in EOB run */
+      EOBRUN--;
+    }
+
+    /* Completed MCU, so update state */
+    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
+  }
+
+  /* Account for restart interval (no-op if not using restarts) */
+  entropy->restarts_to_go--;
+
+  return TRUE;
+
+undoit:
+  /* Re-zero any output coefficients that we made newly nonzero */
+  while (num_newnz > 0)
+    (*block)[newnz_pos[--num_newnz]] = 0;
+
+  return FALSE;
+}
+
+
+/*
+ * Module initialization routine for progressive Huffman entropy decoding.
+ */
+
+GLOBAL(void)
+jinit_phuff_decoder (j_decompress_ptr cinfo)
+{
+  phuff_entropy_ptr entropy;
+  int *coef_bit_ptr;
+  int ci, i;
+
+  entropy = (phuff_entropy_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(phuff_entropy_decoder));
+  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+  entropy->pub.start_pass = start_pass_phuff_decoder;
+
+  /* Mark derived tables unallocated */
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    entropy->derived_tbls[i] = NULL;
+  }
+
+  /* Create progression status table */
+  cinfo->coef_bits = (int (*)[DCTSIZE2])
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				cinfo->num_components*DCTSIZE2*SIZEOF(int));
+  coef_bit_ptr = & cinfo->coef_bits[0][0];
+  for (ci = 0; ci < cinfo->num_components; ci++) 
+    for (i = 0; i < DCTSIZE2; i++)
+      *coef_bit_ptr++ = -1;
+}
+
+#endif /* D_PROGRESSIVE_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jdpostct.c b/Utilities/FLTK/jpeg/jdpostct.c
new file mode 100644
index 0000000000000000000000000000000000000000..571563d728e7135996cc982b8f8dfba3d69a9846
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdpostct.c
@@ -0,0 +1,290 @@
+/*
+ * jdpostct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the decompression postprocessing controller.
+ * This controller manages the upsampling, color conversion, and color
+ * quantization/reduction steps; specifically, it controls the buffering
+ * between upsample/color conversion and color quantization/reduction.
+ *
+ * If no color quantization/reduction is required, then this module has no
+ * work to do, and it just hands off to the upsample/color conversion code.
+ * An integrated upsample/convert/quantize process would replace this module
+ * entirely.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_d_post_controller pub; /* public fields */
+
+  /* Color quantization source buffer: this holds output data from
+   * the upsample/color conversion step to be passed to the quantizer.
+   * For two-pass color quantization, we need a full-image buffer;
+   * for one-pass operation, a strip buffer is sufficient.
+   */
+  jvirt_sarray_ptr whole_image;	/* virtual array, or NULL if one-pass */
+  JSAMPARRAY buffer;		/* strip buffer, or current strip of virtual */
+  JDIMENSION strip_height;	/* buffer size in rows */
+  /* for two-pass mode only: */
+  JDIMENSION starting_row;	/* row # of first row in current strip */
+  JDIMENSION next_row;		/* index of next row to fill/empty in strip */
+} my_post_controller;
+
+typedef my_post_controller * my_post_ptr;
+
+
+/* Forward declarations */
+METHODDEF(void) post_process_1pass
+	JPP((j_decompress_ptr cinfo,
+	     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+	     JDIMENSION in_row_groups_avail,
+	     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+	     JDIMENSION out_rows_avail));
+#ifdef QUANT_2PASS_SUPPORTED
+METHODDEF(void) post_process_prepass
+	JPP((j_decompress_ptr cinfo,
+	     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+	     JDIMENSION in_row_groups_avail,
+	     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+	     JDIMENSION out_rows_avail));
+METHODDEF(void) post_process_2pass
+	JPP((j_decompress_ptr cinfo,
+	     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+	     JDIMENSION in_row_groups_avail,
+	     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+	     JDIMENSION out_rows_avail));
+#endif
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+  my_post_ptr post = (my_post_ptr) cinfo->post;
+
+  switch (pass_mode) {
+  case JBUF_PASS_THRU:
+    if (cinfo->quantize_colors) {
+      /* Single-pass processing with color quantization. */
+      post->pub.post_process_data = post_process_1pass;
+      /* We could be doing buffered-image output before starting a 2-pass
+       * color quantization; in that case, jinit_d_post_controller did not
+       * allocate a strip buffer.  Use the virtual-array buffer as workspace.
+       */
+      if (post->buffer == NULL) {
+	post->buffer = (*cinfo->mem->access_virt_sarray)
+	  ((j_common_ptr) cinfo, post->whole_image,
+	   (JDIMENSION) 0, post->strip_height, TRUE);
+      }
+    } else {
+      /* For single-pass processing without color quantization,
+       * I have no work to do; just call the upsampler directly.
+       */
+      post->pub.post_process_data = cinfo->upsample->upsample;
+    }
+    break;
+#ifdef QUANT_2PASS_SUPPORTED
+  case JBUF_SAVE_AND_PASS:
+    /* First pass of 2-pass quantization */
+    if (post->whole_image == NULL)
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    post->pub.post_process_data = post_process_prepass;
+    break;
+  case JBUF_CRANK_DEST:
+    /* Second pass of 2-pass quantization */
+    if (post->whole_image == NULL)
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    post->pub.post_process_data = post_process_2pass;
+    break;
+#endif /* QUANT_2PASS_SUPPORTED */
+  default:
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+    break;
+  }
+  post->starting_row = post->next_row = 0;
+}
+
+
+/*
+ * Process some data in the one-pass (strip buffer) case.
+ * This is used for color precision reduction as well as one-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_1pass (j_decompress_ptr cinfo,
+		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+		    JDIMENSION in_row_groups_avail,
+		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+		    JDIMENSION out_rows_avail)
+{
+  my_post_ptr post = (my_post_ptr) cinfo->post;
+  JDIMENSION num_rows, max_rows;
+
+  /* Fill the buffer, but not more than what we can dump out in one go. */
+  /* Note we rely on the upsampler to detect bottom of image. */
+  max_rows = out_rows_avail - *out_row_ctr;
+  if (max_rows > post->strip_height)
+    max_rows = post->strip_height;
+  num_rows = 0;
+  (*cinfo->upsample->upsample) (cinfo,
+		input_buf, in_row_group_ctr, in_row_groups_avail,
+		post->buffer, &num_rows, max_rows);
+  /* Quantize and emit data. */
+  (*cinfo->cquantize->color_quantize) (cinfo,
+		post->buffer, output_buf + *out_row_ctr, (int) num_rows);
+  *out_row_ctr += num_rows;
+}
+
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+/*
+ * Process some data in the first pass of 2-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_prepass (j_decompress_ptr cinfo,
+		      JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+		      JDIMENSION in_row_groups_avail,
+		      JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+		      JDIMENSION out_rows_avail)
+{
+  my_post_ptr post = (my_post_ptr) cinfo->post;
+  JDIMENSION old_next_row, num_rows;
+
+  /* Reposition virtual buffer if at start of strip. */
+  if (post->next_row == 0) {
+    post->buffer = (*cinfo->mem->access_virt_sarray)
+	((j_common_ptr) cinfo, post->whole_image,
+	 post->starting_row, post->strip_height, TRUE);
+  }
+
+  /* Upsample some data (up to a strip height's worth). */
+  old_next_row = post->next_row;
+  (*cinfo->upsample->upsample) (cinfo,
+		input_buf, in_row_group_ctr, in_row_groups_avail,
+		post->buffer, &post->next_row, post->strip_height);
+
+  /* Allow quantizer to scan new data.  No data is emitted, */
+  /* but we advance out_row_ctr so outer loop can tell when we're done. */
+  if (post->next_row > old_next_row) {
+    num_rows = post->next_row - old_next_row;
+    (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
+					 (JSAMPARRAY) NULL, (int) num_rows);
+    *out_row_ctr += num_rows;
+  }
+
+  /* Advance if we filled the strip. */
+  if (post->next_row >= post->strip_height) {
+    post->starting_row += post->strip_height;
+    post->next_row = 0;
+  }
+}
+
+
+/*
+ * Process some data in the second pass of 2-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_2pass (j_decompress_ptr cinfo,
+		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+		    JDIMENSION in_row_groups_avail,
+		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+		    JDIMENSION out_rows_avail)
+{
+  my_post_ptr post = (my_post_ptr) cinfo->post;
+  JDIMENSION num_rows, max_rows;
+
+  /* Reposition virtual buffer if at start of strip. */
+  if (post->next_row == 0) {
+    post->buffer = (*cinfo->mem->access_virt_sarray)
+	((j_common_ptr) cinfo, post->whole_image,
+	 post->starting_row, post->strip_height, FALSE);
+  }
+
+  /* Determine number of rows to emit. */
+  num_rows = post->strip_height - post->next_row; /* available in strip */
+  max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
+  if (num_rows > max_rows)
+    num_rows = max_rows;
+  /* We have to check bottom of image here, can't depend on upsampler. */
+  max_rows = cinfo->output_height - post->starting_row;
+  if (num_rows > max_rows)
+    num_rows = max_rows;
+
+  /* Quantize and emit data. */
+  (*cinfo->cquantize->color_quantize) (cinfo,
+		post->buffer + post->next_row, output_buf + *out_row_ctr,
+		(int) num_rows);
+  *out_row_ctr += num_rows;
+
+  /* Advance if we filled the strip. */
+  post->next_row += num_rows;
+  if (post->next_row >= post->strip_height) {
+    post->starting_row += post->strip_height;
+    post->next_row = 0;
+  }
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Initialize postprocessing controller.
+ */
+
+GLOBAL(void)
+jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+  my_post_ptr post;
+
+  post = (my_post_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_post_controller));
+  cinfo->post = (struct jpeg_d_post_controller *) post;
+  post->pub.start_pass = start_pass_dpost;
+  post->whole_image = NULL;	/* flag for no virtual arrays */
+  post->buffer = NULL;		/* flag for no strip buffer */
+
+  /* Create the quantization buffer, if needed */
+  if (cinfo->quantize_colors) {
+    /* The buffer strip height is max_v_samp_factor, which is typically
+     * an efficient number of rows for upsampling to return.
+     * (In the presence of output rescaling, we might want to be smarter?)
+     */
+    post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
+    if (need_full_buffer) {
+      /* Two-pass color quantization: need full-image storage. */
+      /* We round up the number of rows to a multiple of the strip height. */
+#ifdef QUANT_2PASS_SUPPORTED
+      post->whole_image = (*cinfo->mem->request_virt_sarray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+	 cinfo->output_width * cinfo->out_color_components,
+	 (JDIMENSION) jround_up((long) cinfo->output_height,
+				(long) post->strip_height),
+	 post->strip_height);
+#else
+      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif /* QUANT_2PASS_SUPPORTED */
+    } else {
+      /* One-pass color quantization: just make a strip buffer. */
+      post->buffer = (*cinfo->mem->alloc_sarray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE,
+	 cinfo->output_width * cinfo->out_color_components,
+	 post->strip_height);
+    }
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jdsample.c b/Utilities/FLTK/jpeg/jdsample.c
new file mode 100644
index 0000000000000000000000000000000000000000..80ffefb2a1ccf5ddc1530b921df0eef6e3e45c18
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdsample.c
@@ -0,0 +1,478 @@
+/*
+ * jdsample.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains upsampling routines.
+ *
+ * Upsampling input data is counted in "row groups".  A row group
+ * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
+ * sample rows of each component.  Upsampling will normally produce
+ * max_v_samp_factor pixel rows from each row group (but this could vary
+ * if the upsampler is applying a scale factor of its own).
+ *
+ * An excellent reference for image resampling is
+ *   Digital Image Warping, George Wolberg, 1990.
+ *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Pointer to routine to upsample a single component */
+typedef JMETHOD(void, upsample1_ptr,
+		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+/* Private subobject */
+
+typedef struct {
+  struct jpeg_upsampler pub;	/* public fields */
+
+  /* Color conversion buffer.  When using separate upsampling and color
+   * conversion steps, this buffer holds one upsampled row group until it
+   * has been color converted and output.
+   * Note: we do not allocate any storage for component(s) which are full-size,
+   * ie do not need rescaling.  The corresponding entry of color_buf[] is
+   * simply set to point to the input data array, thereby avoiding copying.
+   */
+  JSAMPARRAY color_buf[MAX_COMPONENTS];
+
+  /* Per-component upsampling method pointers */
+  upsample1_ptr methods[MAX_COMPONENTS];
+
+  int next_row_out;		/* counts rows emitted from color_buf */
+  JDIMENSION rows_to_go;	/* counts rows remaining in image */
+
+  /* Height of an input row group for each component. */
+  int rowgroup_height[MAX_COMPONENTS];
+
+  /* These arrays save pixel expansion factors so that int_expand need not
+   * recompute them each time.  They are unused for other upsampling methods.
+   */
+  UINT8 h_expand[MAX_COMPONENTS];
+  UINT8 v_expand[MAX_COMPONENTS];
+} my_upsampler;
+
+typedef my_upsampler * my_upsample_ptr;
+
+
+/*
+ * Initialize for an upsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_upsample (j_decompress_ptr cinfo)
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+  /* Mark the conversion buffer empty */
+  upsample->next_row_out = cinfo->max_v_samp_factor;
+  /* Initialize total-height counter for detecting bottom of image */
+  upsample->rows_to_go = cinfo->output_height;
+}
+
+
+/*
+ * Control routine to do upsampling (and color conversion).
+ *
+ * In this version we upsample each component independently.
+ * We upsample one row group into the conversion buffer, then apply
+ * color conversion a row at a time.
+ */
+
+METHODDEF(void)
+sep_upsample (j_decompress_ptr cinfo,
+	      JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+	      JDIMENSION in_row_groups_avail,
+	      JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+	      JDIMENSION out_rows_avail)
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+  int ci;
+  jpeg_component_info * compptr;
+  JDIMENSION num_rows;
+
+  /* Fill the conversion buffer, if it's empty */
+  if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
+    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+	 ci++, compptr++) {
+      /* Invoke per-component upsample method.  Notice we pass a POINTER
+       * to color_buf[ci], so that fullsize_upsample can change it.
+       */
+      (*upsample->methods[ci]) (cinfo, compptr,
+	input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
+	upsample->color_buf + ci);
+    }
+    upsample->next_row_out = 0;
+  }
+
+  /* Color-convert and emit rows */
+
+  /* How many we have in the buffer: */
+  num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
+  /* Not more than the distance to the end of the image.  Need this test
+   * in case the image height is not a multiple of max_v_samp_factor:
+   */
+  if (num_rows > upsample->rows_to_go) 
+    num_rows = upsample->rows_to_go;
+  /* And not more than what the client can accept: */
+  out_rows_avail -= *out_row_ctr;
+  if (num_rows > out_rows_avail)
+    num_rows = out_rows_avail;
+
+  (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
+				     (JDIMENSION) upsample->next_row_out,
+				     output_buf + *out_row_ctr,
+				     (int) num_rows);
+
+  /* Adjust counts */
+  *out_row_ctr += num_rows;
+  upsample->rows_to_go -= num_rows;
+  upsample->next_row_out += num_rows;
+  /* When the buffer is emptied, declare this input row group consumed */
+  if (upsample->next_row_out >= cinfo->max_v_samp_factor)
+    (*in_row_group_ctr)++;
+}
+
+
+/*
+ * These are the routines invoked by sep_upsample to upsample pixel values
+ * of a single component.  One row group is processed per call.
+ */
+
+
+/*
+ * For full-size components, we just make color_buf[ci] point at the
+ * input buffer, and thus avoid copying any data.  Note that this is
+ * safe only because sep_upsample doesn't declare the input row group
+ * "consumed" until we are done color converting and emitting it.
+ */
+
+METHODDEF(void)
+fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		   JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+  *output_data_ptr = input_data;
+}
+
+
+/*
+ * This is a no-op version used for "uninteresting" components.
+ * These components will not be referenced by color conversion.
+ */
+
+METHODDEF(void)
+noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+  *output_data_ptr = NULL;	/* safety check */
+}
+
+
+/*
+ * This version handles any integral sampling ratios.
+ * This is not used for typical JPEG files, so it need not be fast.
+ * Nor, for that matter, is it particularly accurate: the algorithm is
+ * simple replication of the input pixel onto the corresponding output
+ * pixels.  The hi-falutin sampling literature refers to this as a
+ * "box filter".  A box filter tends to introduce visible artifacts,
+ * so if you are actually going to use 3:1 or 4:1 sampling ratios
+ * you would be well advised to improve this code.
+ */
+
+METHODDEF(void)
+int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+  JSAMPARRAY output_data = *output_data_ptr;
+  register JSAMPROW inptr, outptr;
+  register JSAMPLE invalue;
+  register int h;
+  JSAMPROW outend;
+  int h_expand, v_expand;
+  int inrow, outrow;
+
+  h_expand = upsample->h_expand[compptr->component_index];
+  v_expand = upsample->v_expand[compptr->component_index];
+
+  inrow = outrow = 0;
+  while (outrow < cinfo->max_v_samp_factor) {
+    /* Generate one output row with proper horizontal expansion */
+    inptr = input_data[inrow];
+    outptr = output_data[outrow];
+    outend = outptr + cinfo->output_width;
+    while (outptr < outend) {
+      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
+      for (h = h_expand; h > 0; h--) {
+	*outptr++ = invalue;
+      }
+    }
+    /* Generate any additional output rows by duplicating the first one */
+    if (v_expand > 1) {
+      jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
+			v_expand-1, cinfo->output_width);
+    }
+    inrow++;
+    outrow += v_expand;
+  }
+}
+
+
+/*
+ * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
+ * It's still a box filter.
+ */
+
+METHODDEF(void)
+h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  register JSAMPROW inptr, outptr;
+  register JSAMPLE invalue;
+  JSAMPROW outend;
+  int inrow;
+
+  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
+    inptr = input_data[inrow];
+    outptr = output_data[inrow];
+    outend = outptr + cinfo->output_width;
+    while (outptr < outend) {
+      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
+      *outptr++ = invalue;
+      *outptr++ = invalue;
+    }
+  }
+}
+
+
+/*
+ * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
+ * It's still a box filter.
+ */
+
+METHODDEF(void)
+h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  register JSAMPROW inptr, outptr;
+  register JSAMPLE invalue;
+  JSAMPROW outend;
+  int inrow, outrow;
+
+  inrow = outrow = 0;
+  while (outrow < cinfo->max_v_samp_factor) {
+    inptr = input_data[inrow];
+    outptr = output_data[outrow];
+    outend = outptr + cinfo->output_width;
+    while (outptr < outend) {
+      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
+      *outptr++ = invalue;
+      *outptr++ = invalue;
+    }
+    jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
+		      1, cinfo->output_width);
+    inrow++;
+    outrow += 2;
+  }
+}
+
+
+/*
+ * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
+ *
+ * The upsampling algorithm is linear interpolation between pixel centers,
+ * also known as a "triangle filter".  This is a good compromise between
+ * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
+ * of the way between input pixel centers.
+ *
+ * A note about the "bias" calculations: when rounding fractional values to
+ * integer, we do not want to always round 0.5 up to the next integer.
+ * If we did that, we'd introduce a noticeable bias towards larger values.
+ * Instead, this code is arranged so that 0.5 will be rounded up or down at
+ * alternate pixel locations (a simple ordered dither pattern).
+ */
+
+METHODDEF(void)
+h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  register JSAMPROW inptr, outptr;
+  register int invalue;
+  register JDIMENSION colctr;
+  int inrow;
+
+  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
+    inptr = input_data[inrow];
+    outptr = output_data[inrow];
+    /* Special case for first column */
+    invalue = GETJSAMPLE(*inptr++);
+    *outptr++ = (JSAMPLE) invalue;
+    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
+
+    for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
+      /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
+      invalue = GETJSAMPLE(*inptr++) * 3;
+      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
+      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
+    }
+
+    /* Special case for last column */
+    invalue = GETJSAMPLE(*inptr);
+    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
+    *outptr++ = (JSAMPLE) invalue;
+  }
+}
+
+
+/*
+ * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
+ * Again a triangle filter; see comments for h2v1 case, above.
+ *
+ * It is OK for us to reference the adjacent input rows because we demanded
+ * context from the main buffer controller (see initialization code).
+ */
+
+METHODDEF(void)
+h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  register JSAMPROW inptr0, inptr1, outptr;
+#if BITS_IN_JSAMPLE == 8
+  register int thiscolsum, lastcolsum, nextcolsum;
+#else
+  register INT32 thiscolsum, lastcolsum, nextcolsum;
+#endif
+  register JDIMENSION colctr;
+  int inrow, outrow, v;
+
+  inrow = outrow = 0;
+  while (outrow < cinfo->max_v_samp_factor) {
+    for (v = 0; v < 2; v++) {
+      /* inptr0 points to nearest input row, inptr1 points to next nearest */
+      inptr0 = input_data[inrow];
+      if (v == 0)		/* next nearest is row above */
+	inptr1 = input_data[inrow-1];
+      else			/* next nearest is row below */
+	inptr1 = input_data[inrow+1];
+      outptr = output_data[outrow++];
+
+      /* Special case for first column */
+      thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+      nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
+      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
+      lastcolsum = thiscolsum; thiscolsum = nextcolsum;
+
+      for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
+	/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
+	/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
+	nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
+	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
+	lastcolsum = thiscolsum; thiscolsum = nextcolsum;
+      }
+
+      /* Special case for last column */
+      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
+      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
+    }
+    inrow++;
+  }
+}
+
+
+/*
+ * Module initialization routine for upsampling.
+ */
+
+GLOBAL(void)
+jinit_upsampler (j_decompress_ptr cinfo)
+{
+  my_upsample_ptr upsample;
+  int ci;
+  jpeg_component_info * compptr;
+  boolean need_buffer, do_fancy;
+  int h_in_group, v_in_group, h_out_group, v_out_group;
+
+  upsample = (my_upsample_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_upsampler));
+  cinfo->upsample = (struct jpeg_upsampler *) upsample;
+  upsample->pub.start_pass = start_pass_upsample;
+  upsample->pub.upsample = sep_upsample;
+  upsample->pub.need_context_rows = FALSE; /* until we find out differently */
+
+  if (cinfo->CCIR601_sampling)	/* this isn't supported */
+    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
+
+  /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
+   * so don't ask for it.
+   */
+  do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
+
+  /* Verify we can handle the sampling factors, select per-component methods,
+   * and create storage as needed.
+   */
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Compute size of an "input group" after IDCT scaling.  This many samples
+     * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
+     */
+    h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
+		 cinfo->min_DCT_scaled_size;
+    v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+		 cinfo->min_DCT_scaled_size;
+    h_out_group = cinfo->max_h_samp_factor;
+    v_out_group = cinfo->max_v_samp_factor;
+    upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
+    need_buffer = TRUE;
+    if (! compptr->component_needed) {
+      /* Don't bother to upsample an uninteresting component. */
+      upsample->methods[ci] = noop_upsample;
+      need_buffer = FALSE;
+    } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
+      /* Fullsize components can be processed without any work. */
+      upsample->methods[ci] = fullsize_upsample;
+      need_buffer = FALSE;
+    } else if (h_in_group * 2 == h_out_group &&
+	       v_in_group == v_out_group) {
+      /* Special cases for 2h1v upsampling */
+      if (do_fancy && compptr->downsampled_width > 2)
+	upsample->methods[ci] = h2v1_fancy_upsample;
+      else
+	upsample->methods[ci] = h2v1_upsample;
+    } else if (h_in_group * 2 == h_out_group &&
+	       v_in_group * 2 == v_out_group) {
+      /* Special cases for 2h2v upsampling */
+      if (do_fancy && compptr->downsampled_width > 2) {
+	upsample->methods[ci] = h2v2_fancy_upsample;
+	upsample->pub.need_context_rows = TRUE;
+      } else
+	upsample->methods[ci] = h2v2_upsample;
+    } else if ((h_out_group % h_in_group) == 0 &&
+	       (v_out_group % v_in_group) == 0) {
+      /* Generic integral-factors upsampling method */
+      upsample->methods[ci] = int_upsample;
+      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
+      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
+    } else
+      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
+    if (need_buffer) {
+      upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
+	((j_common_ptr) cinfo, JPOOL_IMAGE,
+	 (JDIMENSION) jround_up((long) cinfo->output_width,
+				(long) cinfo->max_h_samp_factor),
+	 (JDIMENSION) cinfo->max_v_samp_factor);
+    }
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jdtrans.c b/Utilities/FLTK/jpeg/jdtrans.c
new file mode 100644
index 0000000000000000000000000000000000000000..6c0ab715d32ab470950f6db9537381adced9741d
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jdtrans.c
@@ -0,0 +1,143 @@
+/*
+ * jdtrans.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains library routines for transcoding decompression,
+ * that is, reading raw DCT coefficient arrays from an input JPEG file.
+ * The routines in jdapimin.c will also be needed by a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Read the coefficient arrays from a JPEG file.
+ * jpeg_read_header must be completed before calling this.
+ *
+ * The entire image is read into a set of virtual coefficient-block arrays,
+ * one per component.  The return value is a pointer to the array of
+ * virtual-array descriptors.  These can be manipulated directly via the
+ * JPEG memory manager, or handed off to jpeg_write_coefficients().
+ * To release the memory occupied by the virtual arrays, call
+ * jpeg_finish_decompress() when done with the data.
+ *
+ * An alternative usage is to simply obtain access to the coefficient arrays
+ * during a buffered-image-mode decompression operation.  This is allowed
+ * after any jpeg_finish_output() call.  The arrays can be accessed until
+ * jpeg_finish_decompress() is called.  (Note that any call to the library
+ * may reposition the arrays, so don't rely on access_virt_barray() results
+ * to stay valid across library calls.)
+ *
+ * Returns NULL if suspended.  This case need be checked only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(jvirt_barray_ptr *)
+jpeg_read_coefficients (j_decompress_ptr cinfo)
+{
+  if (cinfo->global_state == DSTATE_READY) {
+    /* First call: initialize active modules */
+    transdecode_master_selection(cinfo);
+    cinfo->global_state = DSTATE_RDCOEFS;
+  }
+  if (cinfo->global_state == DSTATE_RDCOEFS) {
+    /* Absorb whole file into the coef buffer */
+    for (;;) {
+      int retcode;
+      /* Call progress monitor hook if present */
+      if (cinfo->progress != NULL)
+	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+      /* Absorb some more input */
+      retcode = (*cinfo->inputctl->consume_input) (cinfo);
+      if (retcode == JPEG_SUSPENDED)
+	return NULL;
+      if (retcode == JPEG_REACHED_EOI)
+	break;
+      /* Advance progress counter if appropriate */
+      if (cinfo->progress != NULL &&
+	  (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
+	if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
+	  /* startup underestimated number of scans; ratchet up one scan */
+	  cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+	}
+      }
+    }
+    /* Set state so that jpeg_finish_decompress does the right thing */
+    cinfo->global_state = DSTATE_STOPPING;
+  }
+  /* At this point we should be in state DSTATE_STOPPING if being used
+   * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
+   * to the coefficients during a full buffered-image-mode decompression.
+   */
+  if ((cinfo->global_state == DSTATE_STOPPING ||
+       cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
+    return cinfo->coef->coef_arrays;
+  }
+  /* Oops, improper usage */
+  ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  return NULL;			/* keep compiler happy */
+}
+
+
+/*
+ * Master selection of decompression modules for transcoding.
+ * This substitutes for jdmaster.c's initialization of the full decompressor.
+ */
+
+LOCAL(void)
+transdecode_master_selection (j_decompress_ptr cinfo)
+{
+  /* This is effectively a buffered-image operation. */
+  cinfo->buffered_image = TRUE;
+
+  /* Entropy decoding: either Huffman or arithmetic coding. */
+  if (cinfo->arith_code) {
+    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+  } else {
+    if (cinfo->progressive_mode) {
+#ifdef D_PROGRESSIVE_SUPPORTED
+      jinit_phuff_decoder(cinfo);
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    } else
+      jinit_huff_decoder(cinfo);
+  }
+
+  /* Always get a full-image coefficient buffer. */
+  jinit_d_coef_controller(cinfo, TRUE);
+
+  /* We can now tell the memory manager to allocate virtual arrays. */
+  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+  /* Initialize input side of decompressor to consume first scan. */
+  (*cinfo->inputctl->start_input_pass) (cinfo);
+
+  /* Initialize progress monitoring. */
+  if (cinfo->progress != NULL) {
+    int nscans;
+    /* Estimate number of scans to set pass_limit. */
+    if (cinfo->progressive_mode) {
+      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
+      nscans = 2 + 3 * cinfo->num_components;
+    } else if (cinfo->inputctl->has_multiple_scans) {
+      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
+      nscans = cinfo->num_components;
+    } else {
+      nscans = 1;
+    }
+    cinfo->progress->pass_counter = 0L;
+    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
+    cinfo->progress->completed_passes = 0;
+    cinfo->progress->total_passes = 1;
+  }
+}
diff --git a/Utilities/FLTK/jpeg/jerror.c b/Utilities/FLTK/jpeg/jerror.c
new file mode 100644
index 0000000000000000000000000000000000000000..a44463cf18386e94d4955c6c2dcc5cf6e749cf25
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jerror.c
@@ -0,0 +1,253 @@
+/*
+ * jerror.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains simple error-reporting and trace-message routines.
+ * These are suitable for Unix-like systems and others where writing to
+ * stderr is the right thing to do.  Many applications will want to replace
+ * some or all of these routines.
+ *
+ * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
+ * you get a Windows-specific hack to display error messages in a dialog box.
+ * It ain't much, but it beats dropping error messages into the bit bucket,
+ * which is what happens to output to stderr under most Windows C compilers.
+ *
+ * These routines are used by both the compression and decompression code.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jversion.h"
+#include "jerror.h"
+#include <stdlib.h>
+
+#ifdef USE_WINDOWS_MESSAGEBOX
+#include <windows.h>
+#endif
+
+#ifndef EXIT_FAILURE		/* define exit() codes if not provided */
+#define EXIT_FAILURE  1
+#endif
+
+
+/*
+ * Create the message string table.
+ * We do this from the master message list in jerror.h by re-reading
+ * jerror.h with a suitable definition for macro JMESSAGE.
+ * The message table is made an external symbol just in case any applications
+ * want to refer to it directly.
+ */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_std_message_table	jMsgTable
+#endif
+
+#define JMESSAGE(code,string)	string ,
+
+const char * const jpeg_std_message_table[] = {
+#include "jerror.h"
+  NULL
+};
+
+
+/*
+ * Error exit handler: must not return to caller.
+ *
+ * Applications may override this if they want to get control back after
+ * an error.  Typically one would longjmp somewhere instead of exiting.
+ * The setjmp buffer can be made a private field within an expanded error
+ * handler object.  Note that the info needed to generate an error message
+ * is stored in the error object, so you can generate the message now or
+ * later, at your convenience.
+ * You should make sure that the JPEG object is cleaned up (with jpeg_abort
+ * or jpeg_destroy) at some point.
+ */
+
+METHODDEF(void)
+error_exit (j_common_ptr cinfo)
+{
+  /* Always display the message */
+  (*cinfo->err->output_message) (cinfo);
+
+  /* Let the memory manager delete any temp files before we die */
+  jpeg_destroy(cinfo);
+
+  exit(EXIT_FAILURE);
+}
+
+
+/*
+ * Actual output of an error or trace message.
+ * Applications may override this method to send JPEG messages somewhere
+ * other than stderr.
+ *
+ * On Windows, printing to stderr is generally completely useless,
+ * so we provide optional code to produce an error-dialog popup.
+ * Most Windows applications will still prefer to override this routine,
+ * but if they don't, it'll do something at least marginally useful.
+ *
+ * NOTE: to use the library in an environment that doesn't support the
+ * C stdio library, you may have to delete the call to fprintf() entirely,
+ * not just not use this routine.
+ */
+
+METHODDEF(void)
+output_message (j_common_ptr cinfo)
+{
+  char buffer[JMSG_LENGTH_MAX];
+
+  /* Create the message */
+  (*cinfo->err->format_message) (cinfo, buffer);
+
+#ifdef USE_WINDOWS_MESSAGEBOX
+  /* Display it in a message dialog box */
+  MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
+	     MB_OK | MB_ICONERROR);
+#else
+  /* Send it to stderr, adding a newline */
+  fprintf(stderr, "%s\n", buffer);
+#endif
+}
+
+
+/*
+ * Decide whether to emit a trace or warning message.
+ * msg_level is one of:
+ *   -1: recoverable corrupt-data warning, may want to abort.
+ *    0: important advisory messages (always display to user).
+ *    1: first level of tracing detail.
+ *    2,3,...: successively more detailed tracing messages.
+ * An application might override this method if it wanted to abort on warnings
+ * or change the policy about which messages to display.
+ */
+
+METHODDEF(void)
+emit_message (j_common_ptr cinfo, int msg_level)
+{
+  struct jpeg_error_mgr * err = cinfo->err;
+
+  if (msg_level < 0) {
+    /* It's a warning message.  Since corrupt files may generate many warnings,
+     * the policy implemented here is to show only the first warning,
+     * unless trace_level >= 3.
+     */
+    if (err->num_warnings == 0 || err->trace_level >= 3)
+      (*err->output_message) (cinfo);
+    /* Always count warnings in num_warnings. */
+    err->num_warnings++;
+  } else {
+    /* It's a trace message.  Show it if trace_level >= msg_level. */
+    if (err->trace_level >= msg_level)
+      (*err->output_message) (cinfo);
+  }
+}
+
+
+/*
+ * Format a message string for the most recent JPEG error or message.
+ * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
+ * characters.  Note that no '\n' character is added to the string.
+ * Few applications should need to override this method.
+ */
+
+METHODDEF(void)
+format_message (j_common_ptr cinfo, char * buffer)
+{
+  struct jpeg_error_mgr * err = cinfo->err;
+  int msg_code = err->msg_code;
+  const char * msgtext = NULL;
+  const char * msgptr;
+  char ch;
+  boolean isstring;
+
+  /* Look up message string in proper table */
+  if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
+    msgtext = err->jpeg_message_table[msg_code];
+  } else if (err->addon_message_table != NULL &&
+	     msg_code >= err->first_addon_message &&
+	     msg_code <= err->last_addon_message) {
+    msgtext = err->addon_message_table[msg_code - err->first_addon_message];
+  }
+
+  /* Defend against bogus message number */
+  if (msgtext == NULL) {
+    err->msg_parm.i[0] = msg_code;
+    msgtext = err->jpeg_message_table[0];
+  }
+
+  /* Check for string parameter, as indicated by %s in the message text */
+  isstring = FALSE;
+  msgptr = msgtext;
+  while ((ch = *msgptr++) != '\0') {
+    if (ch == '%') {
+      if (*msgptr == 's') isstring = TRUE;
+      break;
+    }
+  }
+
+  /* Format the message into the passed buffer */
+  if (isstring)
+    sprintf(buffer, msgtext, err->msg_parm.s);
+  else
+    sprintf(buffer, msgtext,
+	    err->msg_parm.i[0], err->msg_parm.i[1],
+	    err->msg_parm.i[2], err->msg_parm.i[3],
+	    err->msg_parm.i[4], err->msg_parm.i[5],
+	    err->msg_parm.i[6], err->msg_parm.i[7]);
+}
+
+
+/*
+ * Reset error state variables at start of a new image.
+ * This is called during compression startup to reset trace/error
+ * processing to default state, without losing any application-specific
+ * method pointers.  An application might possibly want to override
+ * this method if it has additional error processing state.
+ */
+
+METHODDEF(void)
+reset_error_mgr (j_common_ptr cinfo)
+{
+  cinfo->err->num_warnings = 0;
+  /* trace_level is not reset since it is an application-supplied parameter */
+  cinfo->err->msg_code = 0;	/* may be useful as a flag for "no error" */
+}
+
+
+/*
+ * Fill in the standard error-handling methods in a jpeg_error_mgr object.
+ * Typical call is:
+ *	struct jpeg_compress_struct cinfo;
+ *	struct jpeg_error_mgr err;
+ *
+ *	cinfo.err = jpeg_std_error(&err);
+ * after which the application may override some of the methods.
+ */
+
+GLOBAL(struct jpeg_error_mgr *)
+jpeg_std_error (struct jpeg_error_mgr * err)
+{
+  err->error_exit = error_exit;
+  err->emit_message = emit_message;
+  err->output_message = output_message;
+  err->format_message = format_message;
+  err->reset_error_mgr = reset_error_mgr;
+
+  err->trace_level = 0;		/* default = no tracing */
+  err->num_warnings = 0;	/* no warnings emitted yet */
+  err->msg_code = 0;		/* may be useful as a flag for "no error" */
+
+  /* Initialize message table pointers */
+  err->jpeg_message_table = jpeg_std_message_table;
+  err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
+
+  err->addon_message_table = NULL;
+  err->first_addon_message = 0;	/* for safety */
+  err->last_addon_message = 0;
+
+  return err;
+}
diff --git a/Utilities/FLTK/jpeg/jerror.h b/Utilities/FLTK/jpeg/jerror.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc2fffeac297bcee557400beefb7b6ce790e79a7
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jerror.h
@@ -0,0 +1,291 @@
+/*
+ * jerror.h
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the error and message codes for the JPEG library.
+ * Edit this file to add new codes, or to translate the message strings to
+ * some other language.
+ * A set of error-reporting macros are defined too.  Some applications using
+ * the JPEG library may wish to include this file to get the error codes
+ * and/or the macros.
+ */
+
+/*
+ * To define the enum list of message codes, include this file without
+ * defining macro JMESSAGE.  To create a message string table, include it
+ * again with a suitable JMESSAGE definition (see jerror.c for an example).
+ */
+#ifndef JMESSAGE
+#ifndef JERROR_H
+/* First time through, define the enum list */
+#define JMAKE_ENUM_LIST
+#else
+/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
+#define JMESSAGE(code,string)
+#endif /* JERROR_H */
+#endif /* JMESSAGE */
+
+#ifdef JMAKE_ENUM_LIST
+
+typedef enum {
+
+#define JMESSAGE(code,string)	code ,
+
+#endif /* JMAKE_ENUM_LIST */
+
+JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
+
+/* For maintenance convenience, list is alphabetical by message code name */
+JMESSAGE(JERR_ARITH_NOTIMPL,
+	 "Sorry, there are legal restrictions on arithmetic coding")
+JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
+JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
+JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
+JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
+JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
+JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
+JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
+JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
+JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
+JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
+JMESSAGE(JERR_BAD_LIB_VERSION,
+	 "Wrong JPEG library version: library is %d, caller expects %d")
+JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
+JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
+JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
+JMESSAGE(JERR_BAD_PROGRESSION,
+	 "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
+JMESSAGE(JERR_BAD_PROG_SCRIPT,
+	 "Invalid progressive parameters at scan script entry %d")
+JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
+JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
+JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
+JMESSAGE(JERR_BAD_STRUCT_SIZE,
+	 "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
+JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
+JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
+JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
+JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
+JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
+JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
+JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
+JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
+JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
+JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
+JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
+JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
+JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
+JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
+JMESSAGE(JERR_FILE_READ, "Input file read error")
+JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
+JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
+JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
+JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
+JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
+JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
+JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
+JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
+	 "Cannot transcode due to multiple use of quantization table %d")
+JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
+JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
+JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
+JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
+JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
+JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
+JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
+JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
+JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
+JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
+JMESSAGE(JERR_QUANT_COMPONENTS,
+	 "Cannot quantize more than %d color components")
+JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
+JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
+JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
+JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
+JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
+JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
+JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
+JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
+JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
+JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
+JMESSAGE(JERR_TFILE_WRITE,
+	 "Write failed on temporary file --- out of disk space?")
+JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
+JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
+JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
+JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
+JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
+JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
+JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
+JMESSAGE(JMSG_VERSION, JVERSION)
+JMESSAGE(JTRC_16BIT_TABLES,
+	 "Caution: quantization tables are too coarse for baseline JPEG")
+JMESSAGE(JTRC_ADOBE,
+	 "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
+JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
+JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
+JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
+JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
+JMESSAGE(JTRC_DQT, "Define Quantization Table %d  precision %d")
+JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
+JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
+JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
+JMESSAGE(JTRC_EOI, "End Of Image")
+JMESSAGE(JTRC_HUFFBITS, "        %3d %3d %3d %3d %3d %3d %3d %3d")
+JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d  %d")
+JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
+	 "Warning: thumbnail image size does not match data length %u")
+JMESSAGE(JTRC_JFIF_EXTENSION,
+	 "JFIF extension marker: type 0x%02x, length %u")
+JMESSAGE(JTRC_JFIF_THUMBNAIL, "    with %d x %d thumbnail image")
+JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
+JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
+JMESSAGE(JTRC_QUANTVALS, "        %4u %4u %4u %4u %4u %4u %4u %4u")
+JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
+JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
+JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
+JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
+JMESSAGE(JTRC_RST, "RST%d")
+JMESSAGE(JTRC_SMOOTH_NOTIMPL,
+	 "Smoothing not supported with nonstandard sampling ratios")
+JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
+JMESSAGE(JTRC_SOF_COMPONENT, "    Component %d: %dhx%dv q=%d")
+JMESSAGE(JTRC_SOI, "Start of Image")
+JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
+JMESSAGE(JTRC_SOS_COMPONENT, "    Component %d: dc=%d ac=%d")
+JMESSAGE(JTRC_SOS_PARAMS, "  Ss=%d, Se=%d, Ah=%d, Al=%d")
+JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
+JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
+JMESSAGE(JTRC_THUMB_JPEG,
+	 "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_PALETTE,
+	 "JFIF extension marker: palette thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_RGB,
+	 "JFIF extension marker: RGB thumbnail image, length %u")
+JMESSAGE(JTRC_UNKNOWN_IDS,
+	 "Unrecognized component IDs %d %d %d, assuming YCbCr")
+JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
+JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
+JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
+JMESSAGE(JWRN_BOGUS_PROGRESSION,
+	 "Inconsistent progression sequence for component %d coefficient %d")
+JMESSAGE(JWRN_EXTRANEOUS_DATA,
+	 "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
+JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
+JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
+JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
+JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
+JMESSAGE(JWRN_MUST_RESYNC,
+	 "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
+JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
+JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
+
+#ifdef JMAKE_ENUM_LIST
+
+  JMSG_LASTMSGCODE
+} J_MESSAGE_CODE;
+
+#undef JMAKE_ENUM_LIST
+#endif /* JMAKE_ENUM_LIST */
+
+/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
+#undef JMESSAGE
+
+
+#ifndef JERROR_H
+#define JERROR_H
+
+/* Macros to simplify using the error and trace message stuff */
+/* The first parameter is either type of cinfo pointer */
+
+/* Fatal errors (print message and exit) */
+#define ERREXIT(cinfo,code)  \
+  ((cinfo)->err->msg_code = (code), \
+   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT1(cinfo,code,p1)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT2(cinfo,code,p1,p2)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (cinfo)->err->msg_parm.i[1] = (p2), \
+   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT3(cinfo,code,p1,p2,p3)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (cinfo)->err->msg_parm.i[1] = (p2), \
+   (cinfo)->err->msg_parm.i[2] = (p3), \
+   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT4(cinfo,code,p1,p2,p3,p4)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (cinfo)->err->msg_parm.i[1] = (p2), \
+   (cinfo)->err->msg_parm.i[2] = (p3), \
+   (cinfo)->err->msg_parm.i[3] = (p4), \
+   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXITS(cinfo,code,str)  \
+  ((cinfo)->err->msg_code = (code), \
+   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+
+#define MAKESTMT(stuff)		do { stuff } while (0)
+
+/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
+#define WARNMS(cinfo,code)  \
+  ((cinfo)->err->msg_code = (code), \
+   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS1(cinfo,code,p1)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS2(cinfo,code,p1,p2)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (cinfo)->err->msg_parm.i[1] = (p2), \
+   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+
+/* Informational/debugging messages */
+#define TRACEMS(cinfo,lvl,code)  \
+  ((cinfo)->err->msg_code = (code), \
+   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS1(cinfo,lvl,code,p1)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS2(cinfo,lvl,code,p1,p2)  \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (cinfo)->err->msg_parm.i[1] = (p2), \
+   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS3(cinfo,lvl,code,p1,p2,p3)  \
+  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
+	   (cinfo)->err->msg_code = (code); \
+	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4)  \
+  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+	   (cinfo)->err->msg_code = (code); \
+	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5)  \
+  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+	   _mp[4] = (p5); \
+	   (cinfo)->err->msg_code = (code); \
+	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8)  \
+  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+	   _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
+	   (cinfo)->err->msg_code = (code); \
+	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMSS(cinfo,lvl,code,str)  \
+  ((cinfo)->err->msg_code = (code), \
+   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+
+#endif /* JERROR_H */
diff --git a/Utilities/FLTK/jpeg/jfdctflt.c b/Utilities/FLTK/jpeg/jfdctflt.c
new file mode 100644
index 0000000000000000000000000000000000000000..79d7a0078749c33f7f05cf11de6e55717c3a0fbf
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jfdctflt.c
@@ -0,0 +1,168 @@
+/*
+ * jfdctflt.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a floating-point implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * This implementation should be more accurate than either of the integer
+ * DCT implementations.  However, it may not give the same results on all
+ * machines because of differences in roundoff behavior.  Speed will depend
+ * on the hardware's floating point capacity.
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column.  Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README).  The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs.  These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with a fixed-point
+ * implementation, accuracy is lost due to imprecise representation of the
+ * scaled quantization values.  However, that problem does not arise if
+ * we use floating point arithmetic.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_float (FAST_FLOAT * data)
+{
+  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
+  FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
+  FAST_FLOAT *dataptr;
+  int ctr;
+
+  /* Pass 1: process rows. */
+
+  dataptr = data;
+  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+    tmp0 = dataptr[0] + dataptr[7];
+    tmp7 = dataptr[0] - dataptr[7];
+    tmp1 = dataptr[1] + dataptr[6];
+    tmp6 = dataptr[1] - dataptr[6];
+    tmp2 = dataptr[2] + dataptr[5];
+    tmp5 = dataptr[2] - dataptr[5];
+    tmp3 = dataptr[3] + dataptr[4];
+    tmp4 = dataptr[3] - dataptr[4];
+    
+    /* Even part */
+    
+    tmp10 = tmp0 + tmp3;	/* phase 2 */
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    dataptr[0] = tmp10 + tmp11; /* phase 3 */
+    dataptr[4] = tmp10 - tmp11;
+    
+    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
+    dataptr[2] = tmp13 + z1;	/* phase 5 */
+    dataptr[6] = tmp13 - z1;
+    
+    /* Odd part */
+
+    tmp10 = tmp4 + tmp5;	/* phase 2 */
+    tmp11 = tmp5 + tmp6;
+    tmp12 = tmp6 + tmp7;
+
+    /* The rotator is modified from fig 4-8 to avoid extra negations. */
+    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
+    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
+    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
+    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
+
+    z11 = tmp7 + z3;		/* phase 5 */
+    z13 = tmp7 - z3;
+
+    dataptr[5] = z13 + z2;	/* phase 6 */
+    dataptr[3] = z13 - z2;
+    dataptr[1] = z11 + z4;
+    dataptr[7] = z11 - z4;
+
+    dataptr += DCTSIZE;		/* advance pointer to next row */
+  }
+
+  /* Pass 2: process columns. */
+
+  dataptr = data;
+  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+    
+    /* Even part */
+    
+    tmp10 = tmp0 + tmp3;	/* phase 2 */
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
+    dataptr[DCTSIZE*4] = tmp10 - tmp11;
+    
+    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
+    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
+    dataptr[DCTSIZE*6] = tmp13 - z1;
+    
+    /* Odd part */
+
+    tmp10 = tmp4 + tmp5;	/* phase 2 */
+    tmp11 = tmp5 + tmp6;
+    tmp12 = tmp6 + tmp7;
+
+    /* The rotator is modified from fig 4-8 to avoid extra negations. */
+    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
+    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
+    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
+    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
+
+    z11 = tmp7 + z3;		/* phase 5 */
+    z13 = tmp7 - z3;
+
+    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
+    dataptr[DCTSIZE*3] = z13 - z2;
+    dataptr[DCTSIZE*1] = z11 + z4;
+    dataptr[DCTSIZE*7] = z11 - z4;
+
+    dataptr++;			/* advance pointer to next column */
+  }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jfdctfst.c b/Utilities/FLTK/jpeg/jfdctfst.c
new file mode 100644
index 0000000000000000000000000000000000000000..ccb378a3b45339e05167514a038cc2db616e8fe7
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jfdctfst.c
@@ -0,0 +1,224 @@
+/*
+ * jfdctfst.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a fast, not so accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column.  Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README).  The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs.  These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with fixed-point math,
+ * accuracy is lost due to imprecise representation of the scaled
+ * quantization values.  The smaller the quantization table entry, the less
+ * precise the scaled value, so this implementation does worse with high-
+ * quality-setting files than with low-quality ones.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+#ifdef DCT_IFAST_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling decisions are generally the same as in the LL&M algorithm;
+ * see jfdctint.c for more details.  However, we choose to descale
+ * (right shift) multiplication products as soon as they are formed,
+ * rather than carrying additional fractional bits into subsequent additions.
+ * This compromises accuracy slightly, but it lets us save a few shifts.
+ * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
+ * everywhere except in the multiplications proper; this saves a good deal
+ * of work on 16-bit-int machines.
+ *
+ * Again to save a few shifts, the intermediate results between pass 1 and
+ * pass 2 are not upscaled, but are represented only to integral precision.
+ *
+ * A final compromise is to represent the multiplicative constants to only
+ * 8 fractional bits, rather than 13.  This saves some shifting work on some
+ * machines, and may also reduce the cost of multiplication (since there
+ * are fewer one-bits in the constants).
+ */
+
+#define CONST_BITS  8
+
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 8
+#define FIX_0_382683433  ((INT32)   98)		/* FIX(0.382683433) */
+#define FIX_0_541196100  ((INT32)  139)		/* FIX(0.541196100) */
+#define FIX_0_707106781  ((INT32)  181)		/* FIX(0.707106781) */
+#define FIX_1_306562965  ((INT32)  334)		/* FIX(1.306562965) */
+#else
+#define FIX_0_382683433  FIX(0.382683433)
+#define FIX_0_541196100  FIX(0.541196100)
+#define FIX_0_707106781  FIX(0.707106781)
+#define FIX_1_306562965  FIX(1.306562965)
+#endif
+
+
+/* We can gain a little more speed, with a further compromise in accuracy,
+ * by omitting the addition in a descaling shift.  This yields an incorrectly
+ * rounded result half the time...
+ */
+
+#ifndef USE_ACCURATE_ROUNDING
+#undef DESCALE
+#define DESCALE(x,n)  RIGHT_SHIFT(x, n)
+#endif
+
+
+/* Multiply a DCTELEM variable by an INT32 constant, and immediately
+ * descale to yield a DCTELEM result.
+ */
+
+#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_ifast (DCTELEM * data)
+{
+  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+  DCTELEM tmp10, tmp11, tmp12, tmp13;
+  DCTELEM z1, z2, z3, z4, z5, z11, z13;
+  DCTELEM *dataptr;
+  int ctr;
+  SHIFT_TEMPS
+
+  /* Pass 1: process rows. */
+
+  dataptr = data;
+  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+    tmp0 = dataptr[0] + dataptr[7];
+    tmp7 = dataptr[0] - dataptr[7];
+    tmp1 = dataptr[1] + dataptr[6];
+    tmp6 = dataptr[1] - dataptr[6];
+    tmp2 = dataptr[2] + dataptr[5];
+    tmp5 = dataptr[2] - dataptr[5];
+    tmp3 = dataptr[3] + dataptr[4];
+    tmp4 = dataptr[3] - dataptr[4];
+    
+    /* Even part */
+    
+    tmp10 = tmp0 + tmp3;	/* phase 2 */
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    dataptr[0] = tmp10 + tmp11; /* phase 3 */
+    dataptr[4] = tmp10 - tmp11;
+    
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+    dataptr[2] = tmp13 + z1;	/* phase 5 */
+    dataptr[6] = tmp13 - z1;
+    
+    /* Odd part */
+
+    tmp10 = tmp4 + tmp5;	/* phase 2 */
+    tmp11 = tmp5 + tmp6;
+    tmp12 = tmp6 + tmp7;
+
+    /* The rotator is modified from fig 4-8 to avoid extra negations. */
+    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+    z11 = tmp7 + z3;		/* phase 5 */
+    z13 = tmp7 - z3;
+
+    dataptr[5] = z13 + z2;	/* phase 6 */
+    dataptr[3] = z13 - z2;
+    dataptr[1] = z11 + z4;
+    dataptr[7] = z11 - z4;
+
+    dataptr += DCTSIZE;		/* advance pointer to next row */
+  }
+
+  /* Pass 2: process columns. */
+
+  dataptr = data;
+  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+    
+    /* Even part */
+    
+    tmp10 = tmp0 + tmp3;	/* phase 2 */
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
+    dataptr[DCTSIZE*4] = tmp10 - tmp11;
+    
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
+    dataptr[DCTSIZE*6] = tmp13 - z1;
+    
+    /* Odd part */
+
+    tmp10 = tmp4 + tmp5;	/* phase 2 */
+    tmp11 = tmp5 + tmp6;
+    tmp12 = tmp6 + tmp7;
+
+    /* The rotator is modified from fig 4-8 to avoid extra negations. */
+    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+    z11 = tmp7 + z3;		/* phase 5 */
+    z13 = tmp7 - z3;
+
+    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
+    dataptr[DCTSIZE*3] = z13 - z2;
+    dataptr[DCTSIZE*1] = z11 + z4;
+    dataptr[DCTSIZE*7] = z11 - z4;
+
+    dataptr++;			/* advance pointer to next column */
+  }
+}
+
+#endif /* DCT_IFAST_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jfdctint.c b/Utilities/FLTK/jpeg/jfdctint.c
new file mode 100644
index 0000000000000000000000000000000000000000..0a78b64aee8ffd7fc6c3469495ec577a59d44ed1
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jfdctint.c
@@ -0,0 +1,283 @@
+/*
+ * jfdctint.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a slow-but-accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column.  Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on an algorithm described in
+ *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path contains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+#ifdef DCT_ISLOW_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true DCT outputs.  The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm.  The advantage of
+ * this arrangement is that we save two multiplications per 1-D DCT,
+ * because the y0 and y4 outputs need not be divided by sqrt(N).
+ * In the IJG code, this factor of 8 is removed by the quantization step
+ * (in jcdctmgr.c), NOT in this module.
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic.  We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants).  After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output.  This division can be done
+ * cheaply as a right shift of CONST_BITS bits.  We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision.  These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling.  (For 12-bit sample data, the intermediate
+ * array is INT32 anyway.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26.  Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS  13
+#define PASS1_BITS  2
+#else
+#define CONST_BITS  13
+#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_298631336  ((INT32)  2446)	/* FIX(0.298631336) */
+#define FIX_0_390180644  ((INT32)  3196)	/* FIX(0.390180644) */
+#define FIX_0_541196100  ((INT32)  4433)	/* FIX(0.541196100) */
+#define FIX_0_765366865  ((INT32)  6270)	/* FIX(0.765366865) */
+#define FIX_0_899976223  ((INT32)  7373)	/* FIX(0.899976223) */
+#define FIX_1_175875602  ((INT32)  9633)	/* FIX(1.175875602) */
+#define FIX_1_501321110  ((INT32)  12299)	/* FIX(1.501321110) */
+#define FIX_1_847759065  ((INT32)  15137)	/* FIX(1.847759065) */
+#define FIX_1_961570560  ((INT32)  16069)	/* FIX(1.961570560) */
+#define FIX_2_053119869  ((INT32)  16819)	/* FIX(2.053119869) */
+#define FIX_2_562915447  ((INT32)  20995)	/* FIX(2.562915447) */
+#define FIX_3_072711026  ((INT32)  25172)	/* FIX(3.072711026) */
+#else
+#define FIX_0_298631336  FIX(0.298631336)
+#define FIX_0_390180644  FIX(0.390180644)
+#define FIX_0_541196100  FIX(0.541196100)
+#define FIX_0_765366865  FIX(0.765366865)
+#define FIX_0_899976223  FIX(0.899976223)
+#define FIX_1_175875602  FIX(1.175875602)
+#define FIX_1_501321110  FIX(1.501321110)
+#define FIX_1_847759065  FIX(1.847759065)
+#define FIX_1_961570560  FIX(1.961570560)
+#define FIX_2_053119869  FIX(2.053119869)
+#define FIX_2_562915447  FIX(2.562915447)
+#define FIX_3_072711026  FIX(3.072711026)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const)  ((var) * (const))
+#endif
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_islow (DCTELEM * data)
+{
+  INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+  INT32 tmp10, tmp11, tmp12, tmp13;
+  INT32 z1, z2, z3, z4, z5;
+  DCTELEM *dataptr;
+  int ctr;
+  SHIFT_TEMPS
+
+  /* Pass 1: process rows. */
+  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
+  /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+  dataptr = data;
+  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+    tmp0 = dataptr[0] + dataptr[7];
+    tmp7 = dataptr[0] - dataptr[7];
+    tmp1 = dataptr[1] + dataptr[6];
+    tmp6 = dataptr[1] - dataptr[6];
+    tmp2 = dataptr[2] + dataptr[5];
+    tmp5 = dataptr[2] - dataptr[5];
+    tmp3 = dataptr[3] + dataptr[4];
+    tmp4 = dataptr[3] - dataptr[4];
+    
+    /* Even part per LL&M figure 1 --- note that published figure is faulty;
+     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     */
+    
+    tmp10 = tmp0 + tmp3;
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
+    dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
+    
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+    dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+				   CONST_BITS-PASS1_BITS);
+    dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+				   CONST_BITS-PASS1_BITS);
+    
+    /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+     * cK represents cos(K*pi/16).
+     * i0..i3 in the paper are tmp4..tmp7 here.
+     */
+    
+    z1 = tmp4 + tmp7;
+    z2 = tmp5 + tmp6;
+    z3 = tmp4 + tmp6;
+    z4 = tmp5 + tmp7;
+    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+    
+    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    
+    z3 += z5;
+    z4 += z5;
+    
+    dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
+    dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
+    dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
+    
+    dataptr += DCTSIZE;		/* advance pointer to next row */
+  }
+
+  /* Pass 2: process columns.
+   * We remove the PASS1_BITS scaling, but leave the results scaled up
+   * by an overall factor of 8.
+   */
+
+  dataptr = data;
+  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+    
+    /* Even part per LL&M figure 1 --- note that published figure is faulty;
+     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     */
+    
+    tmp10 = tmp0 + tmp3;
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
+    dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
+    
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+    dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+					   CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+					   CONST_BITS+PASS1_BITS);
+    
+    /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+     * cK represents cos(K*pi/16).
+     * i0..i3 in the paper are tmp4..tmp7 here.
+     */
+    
+    z1 = tmp4 + tmp7;
+    z2 = tmp5 + tmp6;
+    z3 = tmp4 + tmp6;
+    z4 = tmp5 + tmp7;
+    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+    
+    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    
+    z3 += z5;
+    z4 += z5;
+    
+    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
+					   CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
+					   CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
+					   CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
+					   CONST_BITS+PASS1_BITS);
+    
+    dataptr++;			/* advance pointer to next column */
+  }
+}
+
+#endif /* DCT_ISLOW_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jidctflt.c b/Utilities/FLTK/jpeg/jidctflt.c
new file mode 100644
index 0000000000000000000000000000000000000000..0188ce3dfcd2ce2ebaa57c17da22101de01b6f2a
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jidctflt.c
@@ -0,0 +1,242 @@
+/*
+ * jidctflt.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a floating-point implementation of the
+ * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * This implementation should be more accurate than either of the integer
+ * IDCT implementations.  However, it may not give the same results on all
+ * machines because of differences in roundoff behavior.  Speed will depend
+ * on the hardware's floating point capacity.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time).  Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README).  The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs.  These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with a fixed-point
+ * implementation, accuracy is lost due to imprecise representation of the
+ * scaled quantization values.  However, that problem does not arise if
+ * we use floating point arithmetic.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce a float result.
+ */
+
+#define DEQUANTIZE(coef,quantval)  (((FAST_FLOAT) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		 JCOEFPTR coef_block,
+		 JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
+  FAST_FLOAT z5, z10, z11, z12, z13;
+  JCOEFPTR inptr;
+  FLOAT_MULT_TYPE * quantptr;
+  FAST_FLOAT * wsptr;
+  JSAMPROW outptr;
+  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+  int ctr;
+  FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
+  SHIFT_TEMPS
+
+  /* Pass 1: process columns from input, store into work array. */
+
+  inptr = coef_block;
+  quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
+  wsptr = workspace;
+  for (ctr = DCTSIZE; ctr > 0; ctr--) {
+    /* Due to quantization, we will usually find that many of the input
+     * coefficients are zero, especially the AC terms.  We can exploit this
+     * by short-circuiting the IDCT calculation for any column in which all
+     * the AC terms are zero.  In that case each output is equal to the
+     * DC coefficient (with scale factor as needed).
+     * With typical images and quantization tables, half or more of the
+     * column DCT calculations can be simplified this way.
+     */
+    
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+	inptr[DCTSIZE*7] == 0) {
+      /* AC terms all zero */
+      FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+      
+      wsptr[DCTSIZE*0] = dcval;
+      wsptr[DCTSIZE*1] = dcval;
+      wsptr[DCTSIZE*2] = dcval;
+      wsptr[DCTSIZE*3] = dcval;
+      wsptr[DCTSIZE*4] = dcval;
+      wsptr[DCTSIZE*5] = dcval;
+      wsptr[DCTSIZE*6] = dcval;
+      wsptr[DCTSIZE*7] = dcval;
+      
+      inptr++;			/* advance pointers to next column */
+      quantptr++;
+      wsptr++;
+      continue;
+    }
+    
+    /* Even part */
+
+    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+    tmp10 = tmp0 + tmp2;	/* phase 3 */
+    tmp11 = tmp0 - tmp2;
+
+    tmp13 = tmp1 + tmp3;	/* phases 5-3 */
+    tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
+
+    tmp0 = tmp10 + tmp13;	/* phase 2 */
+    tmp3 = tmp10 - tmp13;
+    tmp1 = tmp11 + tmp12;
+    tmp2 = tmp11 - tmp12;
+    
+    /* Odd part */
+
+    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+
+    z13 = tmp6 + tmp5;		/* phase 6 */
+    z10 = tmp6 - tmp5;
+    z11 = tmp4 + tmp7;
+    z12 = tmp4 - tmp7;
+
+    tmp7 = z11 + z13;		/* phase 5 */
+    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
+
+    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+    tmp6 = tmp12 - tmp7;	/* phase 2 */
+    tmp5 = tmp11 - tmp6;
+    tmp4 = tmp10 + tmp5;
+
+    wsptr[DCTSIZE*0] = tmp0 + tmp7;
+    wsptr[DCTSIZE*7] = tmp0 - tmp7;
+    wsptr[DCTSIZE*1] = tmp1 + tmp6;
+    wsptr[DCTSIZE*6] = tmp1 - tmp6;
+    wsptr[DCTSIZE*2] = tmp2 + tmp5;
+    wsptr[DCTSIZE*5] = tmp2 - tmp5;
+    wsptr[DCTSIZE*4] = tmp3 + tmp4;
+    wsptr[DCTSIZE*3] = tmp3 - tmp4;
+
+    inptr++;			/* advance pointers to next column */
+    quantptr++;
+    wsptr++;
+  }
+  
+  /* Pass 2: process rows from work array, store into output array. */
+  /* Note that we must descale the results by a factor of 8 == 2**3. */
+
+  wsptr = workspace;
+  for (ctr = 0; ctr < DCTSIZE; ctr++) {
+    outptr = output_buf[ctr] + output_col;
+    /* Rows of zeroes can be exploited in the same way as we did with columns.
+     * However, the column calculation has created many nonzero AC terms, so
+     * the simplification applies less often (typically 5% to 10% of the time).
+     * And testing floats for zero is relatively expensive, so we don't bother.
+     */
+    
+    /* Even part */
+
+    tmp10 = wsptr[0] + wsptr[4];
+    tmp11 = wsptr[0] - wsptr[4];
+
+    tmp13 = wsptr[2] + wsptr[6];
+    tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
+
+    tmp0 = tmp10 + tmp13;
+    tmp3 = tmp10 - tmp13;
+    tmp1 = tmp11 + tmp12;
+    tmp2 = tmp11 - tmp12;
+
+    /* Odd part */
+
+    z13 = wsptr[5] + wsptr[3];
+    z10 = wsptr[5] - wsptr[3];
+    z11 = wsptr[1] + wsptr[7];
+    z12 = wsptr[1] - wsptr[7];
+
+    tmp7 = z11 + z13;
+    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
+
+    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+    tmp6 = tmp12 - tmp7;
+    tmp5 = tmp11 - tmp6;
+    tmp4 = tmp10 + tmp5;
+
+    /* Final output stage: scale down by a factor of 8 and range-limit */
+
+    outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
+			    & RANGE_MASK];
+    outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
+			    & RANGE_MASK];
+    outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
+			    & RANGE_MASK];
+    outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
+			    & RANGE_MASK];
+    outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
+			    & RANGE_MASK];
+    outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
+			    & RANGE_MASK];
+    outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
+			    & RANGE_MASK];
+    outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
+			    & RANGE_MASK];
+    
+    wsptr += DCTSIZE;		/* advance pointer to next row */
+  }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jidctfst.c b/Utilities/FLTK/jpeg/jidctfst.c
new file mode 100644
index 0000000000000000000000000000000000000000..dba4216fb95e7148c24f2d6f6bba8309bb9be24e
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jidctfst.c
@@ -0,0 +1,368 @@
+/*
+ * jidctfst.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a fast, not so accurate integer implementation of the
+ * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time).  Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README).  The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs.  These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with fixed-point math,
+ * accuracy is lost due to imprecise representation of the scaled
+ * quantization values.  The smaller the quantization table entry, the less
+ * precise the scaled value, so this implementation does worse with high-
+ * quality-setting files than with low-quality ones.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+#ifdef DCT_IFAST_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling decisions are generally the same as in the LL&M algorithm;
+ * see jidctint.c for more details.  However, we choose to descale
+ * (right shift) multiplication products as soon as they are formed,
+ * rather than carrying additional fractional bits into subsequent additions.
+ * This compromises accuracy slightly, but it lets us save a few shifts.
+ * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
+ * everywhere except in the multiplications proper; this saves a good deal
+ * of work on 16-bit-int machines.
+ *
+ * The dequantized coefficients are not integers because the AA&N scaling
+ * factors have been incorporated.  We represent them scaled up by PASS1_BITS,
+ * so that the first and second IDCT rounds have the same input scaling.
+ * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
+ * avoid a descaling shift; this compromises accuracy rather drastically
+ * for small quantization table entries, but it saves a lot of shifts.
+ * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
+ * so we use a much larger scaling factor to preserve accuracy.
+ *
+ * A final compromise is to represent the multiplicative constants to only
+ * 8 fractional bits, rather than 13.  This saves some shifting work on some
+ * machines, and may also reduce the cost of multiplication (since there
+ * are fewer one-bits in the constants).
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS  8
+#define PASS1_BITS  2
+#else
+#define CONST_BITS  8
+#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 8
+#define FIX_1_082392200  ((INT32)  277)		/* FIX(1.082392200) */
+#define FIX_1_414213562  ((INT32)  362)		/* FIX(1.414213562) */
+#define FIX_1_847759065  ((INT32)  473)		/* FIX(1.847759065) */
+#define FIX_2_613125930  ((INT32)  669)		/* FIX(2.613125930) */
+#else
+#define FIX_1_082392200  FIX(1.082392200)
+#define FIX_1_414213562  FIX(1.414213562)
+#define FIX_1_847759065  FIX(1.847759065)
+#define FIX_2_613125930  FIX(2.613125930)
+#endif
+
+
+/* We can gain a little more speed, with a further compromise in accuracy,
+ * by omitting the addition in a descaling shift.  This yields an incorrectly
+ * rounded result half the time...
+ */
+
+#ifndef USE_ACCURATE_ROUNDING
+#undef DESCALE
+#define DESCALE(x,n)  RIGHT_SHIFT(x, n)
+#endif
+
+
+/* Multiply a DCTELEM variable by an INT32 constant, and immediately
+ * descale to yield a DCTELEM result.
+ */
+
+#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce a DCTELEM result.  For 8-bit data a 16x16->16
+ * multiplication will do.  For 12-bit data, the multiplier table is
+ * declared INT32, so a 32-bit multiply will be used.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define DEQUANTIZE(coef,quantval)  (((IFAST_MULT_TYPE) (coef)) * (quantval))
+#else
+#define DEQUANTIZE(coef,quantval)  \
+	DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
+#endif
+
+
+/* Like DESCALE, but applies to a DCTELEM and produces an int.
+ * We assume that int right shift is unsigned if INT32 right shift is.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define ISHIFT_TEMPS	DCTELEM ishift_temp;
+#if BITS_IN_JSAMPLE == 8
+#define DCTELEMBITS  16		/* DCTELEM may be 16 or 32 bits */
+#else
+#define DCTELEMBITS  32		/* DCTELEM must be 32 bits */
+#endif
+#define IRIGHT_SHIFT(x,shft)  \
+    ((ishift_temp = (x)) < 0 ? \
+     (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
+     (ishift_temp >> (shft)))
+#else
+#define ISHIFT_TEMPS
+#define IRIGHT_SHIFT(x,shft)	((x) >> (shft))
+#endif
+
+#ifdef USE_ACCURATE_ROUNDING
+#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
+#else
+#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT(x, n))
+#endif
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		 JCOEFPTR coef_block,
+		 JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+  DCTELEM tmp10, tmp11, tmp12, tmp13;
+  DCTELEM z5, z10, z11, z12, z13;
+  JCOEFPTR inptr;
+  IFAST_MULT_TYPE * quantptr;
+  int * wsptr;
+  JSAMPROW outptr;
+  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+  int ctr;
+  int workspace[DCTSIZE2];	/* buffers data between passes */
+  SHIFT_TEMPS			/* for DESCALE */
+  ISHIFT_TEMPS			/* for IDESCALE */
+
+  /* Pass 1: process columns from input, store into work array. */
+
+  inptr = coef_block;
+  quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
+  wsptr = workspace;
+  for (ctr = DCTSIZE; ctr > 0; ctr--) {
+    /* Due to quantization, we will usually find that many of the input
+     * coefficients are zero, especially the AC terms.  We can exploit this
+     * by short-circuiting the IDCT calculation for any column in which all
+     * the AC terms are zero.  In that case each output is equal to the
+     * DC coefficient (with scale factor as needed).
+     * With typical images and quantization tables, half or more of the
+     * column DCT calculations can be simplified this way.
+     */
+    
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+	inptr[DCTSIZE*7] == 0) {
+      /* AC terms all zero */
+      int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+
+      wsptr[DCTSIZE*0] = dcval;
+      wsptr[DCTSIZE*1] = dcval;
+      wsptr[DCTSIZE*2] = dcval;
+      wsptr[DCTSIZE*3] = dcval;
+      wsptr[DCTSIZE*4] = dcval;
+      wsptr[DCTSIZE*5] = dcval;
+      wsptr[DCTSIZE*6] = dcval;
+      wsptr[DCTSIZE*7] = dcval;
+      
+      inptr++;			/* advance pointers to next column */
+      quantptr++;
+      wsptr++;
+      continue;
+    }
+    
+    /* Even part */
+
+    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+    tmp10 = tmp0 + tmp2;	/* phase 3 */
+    tmp11 = tmp0 - tmp2;
+
+    tmp13 = tmp1 + tmp3;	/* phases 5-3 */
+    tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
+
+    tmp0 = tmp10 + tmp13;	/* phase 2 */
+    tmp3 = tmp10 - tmp13;
+    tmp1 = tmp11 + tmp12;
+    tmp2 = tmp11 - tmp12;
+    
+    /* Odd part */
+
+    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+
+    z13 = tmp6 + tmp5;		/* phase 6 */
+    z10 = tmp6 - tmp5;
+    z11 = tmp4 + tmp7;
+    z12 = tmp4 - tmp7;
+
+    tmp7 = z11 + z13;		/* phase 5 */
+    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+
+    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
+    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
+    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
+
+    tmp6 = tmp12 - tmp7;	/* phase 2 */
+    tmp5 = tmp11 - tmp6;
+    tmp4 = tmp10 + tmp5;
+
+    wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
+    wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
+    wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
+    wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
+    wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
+    wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
+    wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
+    wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
+
+    inptr++;			/* advance pointers to next column */
+    quantptr++;
+    wsptr++;
+  }
+  
+  /* Pass 2: process rows from work array, store into output array. */
+  /* Note that we must descale the results by a factor of 8 == 2**3, */
+  /* and also undo the PASS1_BITS scaling. */
+
+  wsptr = workspace;
+  for (ctr = 0; ctr < DCTSIZE; ctr++) {
+    outptr = output_buf[ctr] + output_col;
+    /* Rows of zeroes can be exploited in the same way as we did with columns.
+     * However, the column calculation has created many nonzero AC terms, so
+     * the simplification applies less often (typically 5% to 10% of the time).
+     * On machines with very fast multiplication, it's possible that the
+     * test takes more time than it's worth.  In that case this section
+     * may be commented out.
+     */
+    
+#ifndef NO_ZERO_ROW_TEST
+    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+      /* AC terms all zero */
+      JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
+				  & RANGE_MASK];
+      
+      outptr[0] = dcval;
+      outptr[1] = dcval;
+      outptr[2] = dcval;
+      outptr[3] = dcval;
+      outptr[4] = dcval;
+      outptr[5] = dcval;
+      outptr[6] = dcval;
+      outptr[7] = dcval;
+
+      wsptr += DCTSIZE;		/* advance pointer to next row */
+      continue;
+    }
+#endif
+    
+    /* Even part */
+
+    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
+    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
+
+    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
+    tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
+	    - tmp13;
+
+    tmp0 = tmp10 + tmp13;
+    tmp3 = tmp10 - tmp13;
+    tmp1 = tmp11 + tmp12;
+    tmp2 = tmp11 - tmp12;
+
+    /* Odd part */
+
+    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
+    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
+    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
+    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
+
+    tmp7 = z11 + z13;		/* phase 5 */
+    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+
+    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
+    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
+    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
+
+    tmp6 = tmp12 - tmp7;	/* phase 2 */
+    tmp5 = tmp11 - tmp6;
+    tmp4 = tmp10 + tmp5;
+
+    /* Final output stage: scale down by a factor of 8 and range-limit */
+
+    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
+			    & RANGE_MASK];
+
+    wsptr += DCTSIZE;		/* advance pointer to next row */
+  }
+}
+
+#endif /* DCT_IFAST_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jidctint.c b/Utilities/FLTK/jpeg/jidctint.c
new file mode 100644
index 0000000000000000000000000000000000000000..a72b3207caf5556457b8ed1f60f7446fa101f8f8
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jidctint.c
@@ -0,0 +1,389 @@
+/*
+ * jidctint.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a slow-but-accurate integer implementation of the
+ * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time).  Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on an algorithm described in
+ *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path contains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+#ifdef DCT_ISLOW_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true IDCT outputs.  The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm.  The advantage of
+ * this arrangement is that we save two multiplications per 1-D IDCT,
+ * because the y0 and y4 inputs need not be divided by sqrt(N).
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic.  We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants).  After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output.  This division can be done
+ * cheaply as a right shift of CONST_BITS bits.  We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision.  These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling.  (To scale up 12-bit sample data further, an
+ * intermediate INT32 array would be needed.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26.  Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS  13
+#define PASS1_BITS  2
+#else
+#define CONST_BITS  13
+#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_298631336  ((INT32)  2446)	/* FIX(0.298631336) */
+#define FIX_0_390180644  ((INT32)  3196)	/* FIX(0.390180644) */
+#define FIX_0_541196100  ((INT32)  4433)	/* FIX(0.541196100) */
+#define FIX_0_765366865  ((INT32)  6270)	/* FIX(0.765366865) */
+#define FIX_0_899976223  ((INT32)  7373)	/* FIX(0.899976223) */
+#define FIX_1_175875602  ((INT32)  9633)	/* FIX(1.175875602) */
+#define FIX_1_501321110  ((INT32)  12299)	/* FIX(1.501321110) */
+#define FIX_1_847759065  ((INT32)  15137)	/* FIX(1.847759065) */
+#define FIX_1_961570560  ((INT32)  16069)	/* FIX(1.961570560) */
+#define FIX_2_053119869  ((INT32)  16819)	/* FIX(2.053119869) */
+#define FIX_2_562915447  ((INT32)  20995)	/* FIX(2.562915447) */
+#define FIX_3_072711026  ((INT32)  25172)	/* FIX(3.072711026) */
+#else
+#define FIX_0_298631336  FIX(0.298631336)
+#define FIX_0_390180644  FIX(0.390180644)
+#define FIX_0_541196100  FIX(0.541196100)
+#define FIX_0_765366865  FIX(0.765366865)
+#define FIX_0_899976223  FIX(0.899976223)
+#define FIX_1_175875602  FIX(1.175875602)
+#define FIX_1_501321110  FIX(1.501321110)
+#define FIX_1_847759065  FIX(1.847759065)
+#define FIX_1_961570560  FIX(1.961570560)
+#define FIX_2_053119869  FIX(2.053119869)
+#define FIX_2_562915447  FIX(2.562915447)
+#define FIX_3_072711026  FIX(3.072711026)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const)  ((var) * (const))
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce an int result.  In this module, both inputs and result
+ * are 16 bits or less, so either int or short multiply will work.
+ */
+
+#define DEQUANTIZE(coef,quantval)  (((ISLOW_MULT_TYPE) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		 JCOEFPTR coef_block,
+		 JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  INT32 tmp0, tmp1, tmp2, tmp3;
+  INT32 tmp10, tmp11, tmp12, tmp13;
+  INT32 z1, z2, z3, z4, z5;
+  JCOEFPTR inptr;
+  ISLOW_MULT_TYPE * quantptr;
+  int * wsptr;
+  JSAMPROW outptr;
+  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+  int ctr;
+  int workspace[DCTSIZE2];	/* buffers data between passes */
+  SHIFT_TEMPS
+
+  /* Pass 1: process columns from input, store into work array. */
+  /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
+  /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+  inptr = coef_block;
+  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+  wsptr = workspace;
+  for (ctr = DCTSIZE; ctr > 0; ctr--) {
+    /* Due to quantization, we will usually find that many of the input
+     * coefficients are zero, especially the AC terms.  We can exploit this
+     * by short-circuiting the IDCT calculation for any column in which all
+     * the AC terms are zero.  In that case each output is equal to the
+     * DC coefficient (with scale factor as needed).
+     * With typical images and quantization tables, half or more of the
+     * column DCT calculations can be simplified this way.
+     */
+    
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+	inptr[DCTSIZE*7] == 0) {
+      /* AC terms all zero */
+      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+      
+      wsptr[DCTSIZE*0] = dcval;
+      wsptr[DCTSIZE*1] = dcval;
+      wsptr[DCTSIZE*2] = dcval;
+      wsptr[DCTSIZE*3] = dcval;
+      wsptr[DCTSIZE*4] = dcval;
+      wsptr[DCTSIZE*5] = dcval;
+      wsptr[DCTSIZE*6] = dcval;
+      wsptr[DCTSIZE*7] = dcval;
+      
+      inptr++;			/* advance pointers to next column */
+      quantptr++;
+      wsptr++;
+      continue;
+    }
+    
+    /* Even part: reverse the even part of the forward DCT. */
+    /* The rotator is sqrt(2)*c(-6). */
+    
+    z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+    z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+    
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+    tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
+    tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+    
+    z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+    z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+
+    tmp0 = (z2 + z3) << CONST_BITS;
+    tmp1 = (z2 - z3) << CONST_BITS;
+    
+    tmp10 = tmp0 + tmp3;
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    /* Odd part per figure 8; the matrix is unitary and hence its
+     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
+     */
+    
+    tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+    tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+    tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+    tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+    
+    z1 = tmp0 + tmp3;
+    z2 = tmp1 + tmp2;
+    z3 = tmp0 + tmp2;
+    z4 = tmp1 + tmp3;
+    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+    
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    
+    z3 += z5;
+    z4 += z5;
+    
+    tmp0 += z1 + z3;
+    tmp1 += z2 + z4;
+    tmp2 += z2 + z3;
+    tmp3 += z1 + z4;
+    
+    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+    
+    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+    wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+    wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+    wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+    wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+    wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+    wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+    wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+    
+    inptr++;			/* advance pointers to next column */
+    quantptr++;
+    wsptr++;
+  }
+  
+  /* Pass 2: process rows from work array, store into output array. */
+  /* Note that we must descale the results by a factor of 8 == 2**3, */
+  /* and also undo the PASS1_BITS scaling. */
+
+  wsptr = workspace;
+  for (ctr = 0; ctr < DCTSIZE; ctr++) {
+    outptr = output_buf[ctr] + output_col;
+    /* Rows of zeroes can be exploited in the same way as we did with columns.
+     * However, the column calculation has created many nonzero AC terms, so
+     * the simplification applies less often (typically 5% to 10% of the time).
+     * On machines with very fast multiplication, it's possible that the
+     * test takes more time than it's worth.  In that case this section
+     * may be commented out.
+     */
+    
+#ifndef NO_ZERO_ROW_TEST
+    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+      /* AC terms all zero */
+      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+				  & RANGE_MASK];
+      
+      outptr[0] = dcval;
+      outptr[1] = dcval;
+      outptr[2] = dcval;
+      outptr[3] = dcval;
+      outptr[4] = dcval;
+      outptr[5] = dcval;
+      outptr[6] = dcval;
+      outptr[7] = dcval;
+
+      wsptr += DCTSIZE;		/* advance pointer to next row */
+      continue;
+    }
+#endif
+    
+    /* Even part: reverse the even part of the forward DCT. */
+    /* The rotator is sqrt(2)*c(-6). */
+    
+    z2 = (INT32) wsptr[2];
+    z3 = (INT32) wsptr[6];
+    
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+    tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
+    tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+    
+    tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
+    tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
+    
+    tmp10 = tmp0 + tmp3;
+    tmp13 = tmp0 - tmp3;
+    tmp11 = tmp1 + tmp2;
+    tmp12 = tmp1 - tmp2;
+    
+    /* Odd part per figure 8; the matrix is unitary and hence its
+     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
+     */
+    
+    tmp0 = (INT32) wsptr[7];
+    tmp1 = (INT32) wsptr[5];
+    tmp2 = (INT32) wsptr[3];
+    tmp3 = (INT32) wsptr[1];
+    
+    z1 = tmp0 + tmp3;
+    z2 = tmp1 + tmp2;
+    z3 = tmp0 + tmp2;
+    z4 = tmp1 + tmp3;
+    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+    
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    
+    z3 += z5;
+    z4 += z5;
+    
+    tmp0 += z1 + z3;
+    tmp1 += z2 + z4;
+    tmp2 += z2 + z3;
+    tmp3 += z1 + z4;
+    
+    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+    
+    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
+					  CONST_BITS+PASS1_BITS+3)
+			    & RANGE_MASK];
+    
+    wsptr += DCTSIZE;		/* advance pointer to next row */
+  }
+}
+
+#endif /* DCT_ISLOW_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jidctred.c b/Utilities/FLTK/jpeg/jidctred.c
new file mode 100644
index 0000000000000000000000000000000000000000..421f3c7ca1ed2ebc9335aeb29c990a08840a5b1d
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jidctred.c
@@ -0,0 +1,398 @@
+/*
+ * jidctred.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains inverse-DCT routines that produce reduced-size output:
+ * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
+ *
+ * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
+ * algorithm used in jidctint.c.  We simply replace each 8-to-8 1-D IDCT step
+ * with an 8-to-4 step that produces the four averages of two adjacent outputs
+ * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
+ * These steps were derived by computing the corresponding values at the end
+ * of the normal LL&M code, then simplifying as much as possible.
+ *
+ * 1x1 is trivial: just take the DC coefficient divided by 8.
+ *
+ * See jidctint.c for additional comments.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h"		/* Private declarations for DCT subsystem */
+
+#ifdef IDCT_SCALING_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling is the same as in jidctint.c. */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS  13
+#define PASS1_BITS  2
+#else
+#define CONST_BITS  13
+#define PASS1_BITS  1		/* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_211164243  ((INT32)  1730)	/* FIX(0.211164243) */
+#define FIX_0_509795579  ((INT32)  4176)	/* FIX(0.509795579) */
+#define FIX_0_601344887  ((INT32)  4926)	/* FIX(0.601344887) */
+#define FIX_0_720959822  ((INT32)  5906)	/* FIX(0.720959822) */
+#define FIX_0_765366865  ((INT32)  6270)	/* FIX(0.765366865) */
+#define FIX_0_850430095  ((INT32)  6967)	/* FIX(0.850430095) */
+#define FIX_0_899976223  ((INT32)  7373)	/* FIX(0.899976223) */
+#define FIX_1_061594337  ((INT32)  8697)	/* FIX(1.061594337) */
+#define FIX_1_272758580  ((INT32)  10426)	/* FIX(1.272758580) */
+#define FIX_1_451774981  ((INT32)  11893)	/* FIX(1.451774981) */
+#define FIX_1_847759065  ((INT32)  15137)	/* FIX(1.847759065) */
+#define FIX_2_172734803  ((INT32)  17799)	/* FIX(2.172734803) */
+#define FIX_2_562915447  ((INT32)  20995)	/* FIX(2.562915447) */
+#define FIX_3_624509785  ((INT32)  29692)	/* FIX(3.624509785) */
+#else
+#define FIX_0_211164243  FIX(0.211164243)
+#define FIX_0_509795579  FIX(0.509795579)
+#define FIX_0_601344887  FIX(0.601344887)
+#define FIX_0_720959822  FIX(0.720959822)
+#define FIX_0_765366865  FIX(0.765366865)
+#define FIX_0_850430095  FIX(0.850430095)
+#define FIX_0_899976223  FIX(0.899976223)
+#define FIX_1_061594337  FIX(1.061594337)
+#define FIX_1_272758580  FIX(1.272758580)
+#define FIX_1_451774981  FIX(1.451774981)
+#define FIX_1_847759065  FIX(1.847759065)
+#define FIX_2_172734803  FIX(2.172734803)
+#define FIX_2_562915447  FIX(2.562915447)
+#define FIX_3_624509785  FIX(3.624509785)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const)  ((var) * (const))
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce an int result.  In this module, both inputs and result
+ * are 16 bits or less, so either int or short multiply will work.
+ */
+
+#define DEQUANTIZE(coef,quantval)  (((ISLOW_MULT_TYPE) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 4x4 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	       JCOEFPTR coef_block,
+	       JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  INT32 tmp0, tmp2, tmp10, tmp12;
+  INT32 z1, z2, z3, z4;
+  JCOEFPTR inptr;
+  ISLOW_MULT_TYPE * quantptr;
+  int * wsptr;
+  JSAMPROW outptr;
+  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+  int ctr;
+  int workspace[DCTSIZE*4];	/* buffers data between passes */
+  SHIFT_TEMPS
+
+  /* Pass 1: process columns from input, store into work array. */
+
+  inptr = coef_block;
+  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+  wsptr = workspace;
+  for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
+    /* Don't bother to process column 4, because second pass won't use it */
+    if (ctr == DCTSIZE-4)
+      continue;
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
+	inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
+      /* AC terms all zero; we need not examine term 4 for 4x4 output */
+      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+      
+      wsptr[DCTSIZE*0] = dcval;
+      wsptr[DCTSIZE*1] = dcval;
+      wsptr[DCTSIZE*2] = dcval;
+      wsptr[DCTSIZE*3] = dcval;
+      
+      continue;
+    }
+    
+    /* Even part */
+    
+    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+    tmp0 <<= (CONST_BITS+1);
+    
+    z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+    z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+    tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
+    
+    tmp10 = tmp0 + tmp2;
+    tmp12 = tmp0 - tmp2;
+    
+    /* Odd part */
+    
+    z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+    z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+    z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+    z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+    
+    tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+	 + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+	 + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+	 + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
+    
+    tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+	 + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+	 + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+	 + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
+
+    /* Final output stage */
+    
+    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
+    wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
+    wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
+    wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
+  }
+  
+  /* Pass 2: process 4 rows from work array, store into output array. */
+
+  wsptr = workspace;
+  for (ctr = 0; ctr < 4; ctr++) {
+    outptr = output_buf[ctr] + output_col;
+    /* It's not clear whether a zero row test is worthwhile here ... */
+
+#ifndef NO_ZERO_ROW_TEST
+    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
+	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+      /* AC terms all zero */
+      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+				  & RANGE_MASK];
+      
+      outptr[0] = dcval;
+      outptr[1] = dcval;
+      outptr[2] = dcval;
+      outptr[3] = dcval;
+      
+      wsptr += DCTSIZE;		/* advance pointer to next row */
+      continue;
+    }
+#endif
+    
+    /* Even part */
+    
+    tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
+    
+    tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
+	 + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
+    
+    tmp10 = tmp0 + tmp2;
+    tmp12 = tmp0 - tmp2;
+    
+    /* Odd part */
+    
+    z1 = (INT32) wsptr[7];
+    z2 = (INT32) wsptr[5];
+    z3 = (INT32) wsptr[3];
+    z4 = (INT32) wsptr[1];
+    
+    tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+	 + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+	 + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+	 + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
+    
+    tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+	 + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+	 + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+	 + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
+
+    /* Final output stage */
+    
+    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
+					  CONST_BITS+PASS1_BITS+3+1)
+			    & RANGE_MASK];
+    outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
+					  CONST_BITS+PASS1_BITS+3+1)
+			    & RANGE_MASK];
+    outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
+					  CONST_BITS+PASS1_BITS+3+1)
+			    & RANGE_MASK];
+    outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
+					  CONST_BITS+PASS1_BITS+3+1)
+			    & RANGE_MASK];
+    
+    wsptr += DCTSIZE;		/* advance pointer to next row */
+  }
+}
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 2x2 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	       JCOEFPTR coef_block,
+	       JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  INT32 tmp0, tmp10, z1;
+  JCOEFPTR inptr;
+  ISLOW_MULT_TYPE * quantptr;
+  int * wsptr;
+  JSAMPROW outptr;
+  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+  int ctr;
+  int workspace[DCTSIZE*2];	/* buffers data between passes */
+  SHIFT_TEMPS
+
+  /* Pass 1: process columns from input, store into work array. */
+
+  inptr = coef_block;
+  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+  wsptr = workspace;
+  for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
+    /* Don't bother to process columns 2,4,6 */
+    if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
+      continue;
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
+      /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
+      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+      
+      wsptr[DCTSIZE*0] = dcval;
+      wsptr[DCTSIZE*1] = dcval;
+      
+      continue;
+    }
+    
+    /* Even part */
+    
+    z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+    tmp10 = z1 << (CONST_BITS+2);
+    
+    /* Odd part */
+
+    z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+    tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
+    z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+    tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
+    z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+    tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
+    z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+    tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
+
+    /* Final output stage */
+    
+    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
+    wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
+  }
+  
+  /* Pass 2: process 2 rows from work array, store into output array. */
+
+  wsptr = workspace;
+  for (ctr = 0; ctr < 2; ctr++) {
+    outptr = output_buf[ctr] + output_col;
+    /* It's not clear whether a zero row test is worthwhile here ... */
+
+#ifndef NO_ZERO_ROW_TEST
+    if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
+      /* AC terms all zero */
+      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+				  & RANGE_MASK];
+      
+      outptr[0] = dcval;
+      outptr[1] = dcval;
+      
+      wsptr += DCTSIZE;		/* advance pointer to next row */
+      continue;
+    }
+#endif
+    
+    /* Even part */
+    
+    tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
+    
+    /* Odd part */
+
+    tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
+	 + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
+	 + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
+	 + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
+
+    /* Final output stage */
+    
+    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
+					  CONST_BITS+PASS1_BITS+3+2)
+			    & RANGE_MASK];
+    outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
+					  CONST_BITS+PASS1_BITS+3+2)
+			    & RANGE_MASK];
+    
+    wsptr += DCTSIZE;		/* advance pointer to next row */
+  }
+}
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 1x1 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+	       JCOEFPTR coef_block,
+	       JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  int dcval;
+  ISLOW_MULT_TYPE * quantptr;
+  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+  SHIFT_TEMPS
+
+  /* We hardly need an inverse DCT routine for this: just take the
+   * average pixel value, which is one-eighth of the DC coefficient.
+   */
+  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+  dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
+  dcval = (int) DESCALE((INT32) dcval, 3);
+
+  output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
+}
+
+#endif /* IDCT_SCALING_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jinclude.h b/Utilities/FLTK/jpeg/jinclude.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a4f15146aeb2070601838439e169509f6fe5b7d
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jinclude.h
@@ -0,0 +1,91 @@
+/*
+ * jinclude.h
+ *
+ * Copyright (C) 1991-1994, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file exists to provide a single place to fix any problems with
+ * including the wrong system include files.  (Common problems are taken
+ * care of by the standard jconfig symbols, but on really weird systems
+ * you may have to edit this file.)
+ *
+ * NOTE: this file is NOT intended to be included by applications using the
+ * JPEG library.  Most applications need only include jpeglib.h.
+ */
+
+
+/* Include auto-config file to find out which system include files we need. */
+
+#include "jconfig.h"		/* auto configuration options */
+#define JCONFIG_INCLUDED	/* so that jpeglib.h doesn't do it again */
+
+/*
+ * We need the NULL macro and size_t typedef.
+ * On an ANSI-conforming system it is sufficient to include <stddef.h>.
+ * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
+ * pull in <sys/types.h> as well.
+ * Note that the core JPEG library does not require <stdio.h>;
+ * only the default error handler and data source/destination modules do.
+ * But we must pull it in because of the references to FILE in jpeglib.h.
+ * You can remove those references if you want to compile without <stdio.h>.
+ */
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdio.h>
+
+/*
+ * We need memory copying and zeroing functions, plus strncpy().
+ * ANSI and System V implementations declare these in <string.h>.
+ * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
+ * Some systems may declare memset and memcpy in <memory.h>.
+ *
+ * NOTE: we assume the size parameters to these functions are of type size_t.
+ * Change the casts in these macros if not!
+ */
+
+#ifdef NEED_BSD_STRINGS
+
+#include <strings.h>
+#define MEMZERO(target,size)	bzero((void *)(target), (size_t)(size))
+#define MEMCOPY(dest,src,size)	bcopy((const void *)(src), (void *)(dest), (size_t)(size))
+
+#else /* not BSD, assume ANSI/SysV string lib */
+
+#include <string.h>
+#define MEMZERO(target,size)	memset((void *)(target), 0, (size_t)(size))
+#define MEMCOPY(dest,src,size)	memcpy((void *)(dest), (const void *)(src), (size_t)(size))
+
+#endif
+
+/*
+ * In ANSI C, and indeed any rational implementation, size_t is also the
+ * type returned by sizeof().  However, it seems there are some irrational
+ * implementations out there, in which sizeof() returns an int even though
+ * size_t is defined as long or unsigned long.  To ensure consistent results
+ * we always use this SIZEOF() macro in place of using sizeof() directly.
+ */
+
+#define SIZEOF(object)	((size_t) sizeof(object))
+
+/*
+ * The modules that use fread() and fwrite() always invoke them through
+ * these macros.  On some systems you may need to twiddle the argument casts.
+ * CAUTION: argument order is different from underlying functions!
+ */
+
+#define JFREAD(file,buf,sizeofbuf)  \
+  ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
+#define JFWRITE(file,buf,sizeofbuf)  \
+  ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
diff --git a/Utilities/FLTK/jpeg/jmemmgr.c b/Utilities/FLTK/jpeg/jmemmgr.c
new file mode 100644
index 0000000000000000000000000000000000000000..d801b322da05e0cd033159ba973676e4305101ef
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jmemmgr.c
@@ -0,0 +1,1118 @@
+/*
+ * jmemmgr.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the JPEG system-independent memory management
+ * routines.  This code is usable across a wide variety of machines; most
+ * of the system dependencies have been isolated in a separate file.
+ * The major functions provided here are:
+ *   * pool-based allocation and freeing of memory;
+ *   * policy decisions about how to divide available memory among the
+ *     virtual arrays;
+ *   * control logic for swapping virtual arrays between main memory and
+ *     backing storage.
+ * The separate system-dependent file provides the actual backing-storage
+ * access code, and it contains the policy decision about how much total
+ * main memory to use.
+ * This file is system-dependent in the sense that some of its functions
+ * are unnecessary in some systems.  For example, if there is enough virtual
+ * memory so that backing storage will never be used, much of the virtual
+ * array control logic could be removed.  (Of course, if you have that much
+ * memory then you shouldn't care about a little bit of unused code...)
+ */
+
+#define JPEG_INTERNALS
+#define AM_MEMORY_MANAGER	/* we define jvirt_Xarray_control structs */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jmemsys.h"		/* import the system-dependent declarations */
+
+#ifndef NO_GETENV
+#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare getenv() */
+extern char * getenv JPP((const char * name));
+#endif
+#endif
+
+
+/*
+ * Some important notes:
+ *   The allocation routines provided here must never return NULL.
+ *   They should exit to error_exit if unsuccessful.
+ *
+ *   It's not a good idea to try to merge the sarray and barray routines,
+ *   even though they are textually almost the same, because samples are
+ *   usually stored as bytes while coefficients are shorts or ints.  Thus,
+ *   in machines where byte pointers have a different representation from
+ *   word pointers, the resulting machine code could not be the same.
+ */
+
+
+/*
+ * Many machines require storage alignment: longs must start on 4-byte
+ * boundaries, doubles on 8-byte boundaries, etc.  On such machines, malloc()
+ * always returns pointers that are multiples of the worst-case alignment
+ * requirement, and we had better do so too.
+ * There isn't any really portable way to determine the worst-case alignment
+ * requirement.  This module assumes that the alignment requirement is
+ * multiples of sizeof(ALIGN_TYPE).
+ * By default, we define ALIGN_TYPE as double.  This is necessary on some
+ * workstations (where doubles really do need 8-byte alignment) and will work
+ * fine on nearly everything.  If your machine has lesser alignment needs,
+ * you can save a few bytes by making ALIGN_TYPE smaller.
+ * The only place I know of where this will NOT work is certain Macintosh
+ * 680x0 compilers that define double as a 10-byte IEEE extended float.
+ * Doing 10-byte alignment is counterproductive because longwords won't be
+ * aligned well.  Put "#define ALIGN_TYPE long" in jconfig.h if you have
+ * such a compiler.
+ */
+
+#ifndef ALIGN_TYPE		/* so can override from jconfig.h */
+#define ALIGN_TYPE  double
+#endif
+
+
+/*
+ * We allocate objects from "pools", where each pool is gotten with a single
+ * request to jpeg_get_small() or jpeg_get_large().  There is no per-object
+ * overhead within a pool, except for alignment padding.  Each pool has a
+ * header with a link to the next pool of the same class.
+ * Small and large pool headers are identical except that the latter's
+ * link pointer must be FAR on 80x86 machines.
+ * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
+ * field.  This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
+ * of the alignment requirement of ALIGN_TYPE.
+ */
+
+typedef union small_pool_struct * small_pool_ptr;
+
+typedef union small_pool_struct {
+  struct {
+    small_pool_ptr next;	/* next in list of pools */
+    size_t bytes_used;		/* how many bytes already used within pool */
+    size_t bytes_left;		/* bytes still available in this pool */
+  } hdr;
+  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
+} small_pool_hdr;
+
+typedef union large_pool_struct FAR * large_pool_ptr;
+
+typedef union large_pool_struct {
+  struct {
+    large_pool_ptr next;	/* next in list of pools */
+    size_t bytes_used;		/* how many bytes already used within pool */
+    size_t bytes_left;		/* bytes still available in this pool */
+  } hdr;
+  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
+} large_pool_hdr;
+
+
+/*
+ * Here is the full definition of a memory manager object.
+ */
+
+typedef struct {
+  struct jpeg_memory_mgr pub;	/* public fields */
+
+  /* Each pool identifier (lifetime class) names a linked list of pools. */
+  small_pool_ptr small_list[JPOOL_NUMPOOLS];
+  large_pool_ptr large_list[JPOOL_NUMPOOLS];
+
+  /* Since we only have one lifetime class of virtual arrays, only one
+   * linked list is necessary (for each datatype).  Note that the virtual
+   * array control blocks being linked together are actually stored somewhere
+   * in the small-pool list.
+   */
+  jvirt_sarray_ptr virt_sarray_list;
+  jvirt_barray_ptr virt_barray_list;
+
+  /* This counts total space obtained from jpeg_get_small/large */
+  long total_space_allocated;
+
+  /* alloc_sarray and alloc_barray set this value for use by virtual
+   * array routines.
+   */
+  JDIMENSION last_rowsperchunk;	/* from most recent alloc_sarray/barray */
+} my_memory_mgr;
+
+typedef my_memory_mgr * my_mem_ptr;
+
+
+/*
+ * The control blocks for virtual arrays.
+ * Note that these blocks are allocated in the "small" pool area.
+ * System-dependent info for the associated backing store (if any) is hidden
+ * inside the backing_store_info struct.
+ */
+
+struct jvirt_sarray_control {
+  JSAMPARRAY mem_buffer;	/* => the in-memory buffer */
+  JDIMENSION rows_in_array;	/* total virtual array height */
+  JDIMENSION samplesperrow;	/* width of array (and of memory buffer) */
+  JDIMENSION maxaccess;		/* max rows accessed by access_virt_sarray */
+  JDIMENSION rows_in_mem;	/* height of memory buffer */
+  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */
+  JDIMENSION cur_start_row;	/* first logical row # in the buffer */
+  JDIMENSION first_undef_row;	/* row # of first uninitialized row */
+  boolean pre_zero;		/* pre-zero mode requested? */
+  boolean dirty;		/* do current buffer contents need written? */
+  boolean b_s_open;		/* is backing-store data valid? */
+  jvirt_sarray_ptr next;	/* link to next virtual sarray control block */
+  backing_store_info b_s_info;	/* System-dependent control info */
+};
+
+struct jvirt_barray_control {
+  JBLOCKARRAY mem_buffer;	/* => the in-memory buffer */
+  JDIMENSION rows_in_array;	/* total virtual array height */
+  JDIMENSION blocksperrow;	/* width of array (and of memory buffer) */
+  JDIMENSION maxaccess;		/* max rows accessed by access_virt_barray */
+  JDIMENSION rows_in_mem;	/* height of memory buffer */
+  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */
+  JDIMENSION cur_start_row;	/* first logical row # in the buffer */
+  JDIMENSION first_undef_row;	/* row # of first uninitialized row */
+  boolean pre_zero;		/* pre-zero mode requested? */
+  boolean dirty;		/* do current buffer contents need written? */
+  boolean b_s_open;		/* is backing-store data valid? */
+  jvirt_barray_ptr next;	/* link to next virtual barray control block */
+  backing_store_info b_s_info;	/* System-dependent control info */
+};
+
+
+#ifdef MEM_STATS		/* optional extra stuff for statistics */
+
+LOCAL(void)
+print_mem_stats (j_common_ptr cinfo, int pool_id)
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  small_pool_ptr shdr_ptr;
+  large_pool_ptr lhdr_ptr;
+
+  /* Since this is only a debugging stub, we can cheat a little by using
+   * fprintf directly rather than going through the trace message code.
+   * This is helpful because message parm array can't handle longs.
+   */
+  fprintf(stderr, "Freeing pool %d, total space = %ld\n",
+	  pool_id, mem->total_space_allocated);
+
+  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
+       lhdr_ptr = lhdr_ptr->hdr.next) {
+    fprintf(stderr, "  Large chunk used %ld\n",
+	    (long) lhdr_ptr->hdr.bytes_used);
+  }
+
+  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
+       shdr_ptr = shdr_ptr->hdr.next) {
+    fprintf(stderr, "  Small chunk used %ld free %ld\n",
+	    (long) shdr_ptr->hdr.bytes_used,
+	    (long) shdr_ptr->hdr.bytes_left);
+  }
+}
+
+#endif /* MEM_STATS */
+
+
+LOCAL(void)
+out_of_memory (j_common_ptr cinfo, int which)
+/* Report an out-of-memory error and stop execution */
+/* If we compiled MEM_STATS support, report alloc requests before dying */
+{
+#ifdef MEM_STATS
+  cinfo->err->trace_level = 2;	/* force self_destruct to report stats */
+#endif
+  ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
+}
+
+
+/*
+ * Allocation of "small" objects.
+ *
+ * For these, we use pooled storage.  When a new pool must be created,
+ * we try to get enough space for the current request plus a "slop" factor,
+ * where the slop will be the amount of leftover space in the new pool.
+ * The speed vs. space tradeoff is largely determined by the slop values.
+ * A different slop value is provided for each pool class (lifetime),
+ * and we also distinguish the first pool of a class from later ones.
+ * NOTE: the values given work fairly well on both 16- and 32-bit-int
+ * machines, but may be too small if longs are 64 bits or more.
+ */
+
+static const size_t first_pool_slop[JPOOL_NUMPOOLS] = 
+{
+	1600,			/* first PERMANENT pool */
+	16000			/* first IMAGE pool */
+};
+
+static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = 
+{
+	0,			/* additional PERMANENT pools */
+	5000			/* additional IMAGE pools */
+};
+
+#define MIN_SLOP  50		/* greater than 0 to avoid futile looping */
+
+
+METHODDEF(void *)
+alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
+/* Allocate a "small" object */
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  small_pool_ptr hdr_ptr, prev_hdr_ptr;
+  char * data_ptr;
+  size_t odd_bytes, min_request, slop;
+
+  /* Check for unsatisfiable request (do now to ensure no overflow below) */
+  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
+    out_of_memory(cinfo, 1);	/* request exceeds malloc's ability */
+
+  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
+  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
+  if (odd_bytes > 0)
+    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
+
+  /* See if space is available in any existing pool */
+  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
+  prev_hdr_ptr = NULL;
+  hdr_ptr = mem->small_list[pool_id];
+  while (hdr_ptr != NULL) {
+    if (hdr_ptr->hdr.bytes_left >= sizeofobject)
+      break;			/* found pool with enough space */
+    prev_hdr_ptr = hdr_ptr;
+    hdr_ptr = hdr_ptr->hdr.next;
+  }
+
+  /* Time to make a new pool? */
+  if (hdr_ptr == NULL) {
+    /* min_request is what we need now, slop is what will be leftover */
+    min_request = sizeofobject + SIZEOF(small_pool_hdr);
+    if (prev_hdr_ptr == NULL)	/* first pool in class? */
+      slop = first_pool_slop[pool_id];
+    else
+      slop = extra_pool_slop[pool_id];
+    /* Don't ask for more than MAX_ALLOC_CHUNK */
+    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
+      slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
+    /* Try to get space, if fail reduce slop and try again */
+    for (;;) {
+      hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
+      if (hdr_ptr != NULL)
+	break;
+      slop /= 2;
+      if (slop < MIN_SLOP)	/* give up when it gets real small */
+	out_of_memory(cinfo, 2); /* jpeg_get_small failed */
+    }
+    mem->total_space_allocated += min_request + slop;
+    /* Success, initialize the new pool header and add to end of list */
+    hdr_ptr->hdr.next = NULL;
+    hdr_ptr->hdr.bytes_used = 0;
+    hdr_ptr->hdr.bytes_left = sizeofobject + slop;
+    if (prev_hdr_ptr == NULL)	/* first pool in class? */
+      mem->small_list[pool_id] = hdr_ptr;
+    else
+      prev_hdr_ptr->hdr.next = hdr_ptr;
+  }
+
+  /* OK, allocate the object from the current pool */
+  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
+  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
+  hdr_ptr->hdr.bytes_used += sizeofobject;
+  hdr_ptr->hdr.bytes_left -= sizeofobject;
+
+  return (void *) data_ptr;
+}
+
+
+/*
+ * Allocation of "large" objects.
+ *
+ * The external semantics of these are the same as "small" objects,
+ * except that FAR pointers are used on 80x86.  However the pool
+ * management heuristics are quite different.  We assume that each
+ * request is large enough that it may as well be passed directly to
+ * jpeg_get_large; the pool management just links everything together
+ * so that we can free it all on demand.
+ * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
+ * structures.  The routines that create these structures (see below)
+ * deliberately bunch rows together to ensure a large request size.
+ */
+
+METHODDEF(void FAR *)
+alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
+/* Allocate a "large" object */
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  large_pool_ptr hdr_ptr;
+  size_t odd_bytes;
+
+  /* Check for unsatisfiable request (do now to ensure no overflow below) */
+  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
+    out_of_memory(cinfo, 3);	/* request exceeds malloc's ability */
+
+  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
+  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
+  if (odd_bytes > 0)
+    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
+
+  /* Always make a new pool */
+  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
+
+  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
+					    SIZEOF(large_pool_hdr));
+  if (hdr_ptr == NULL)
+    out_of_memory(cinfo, 4);	/* jpeg_get_large failed */
+  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
+
+  /* Success, initialize the new pool header and add to list */
+  hdr_ptr->hdr.next = mem->large_list[pool_id];
+  /* We maintain space counts in each pool header for statistical purposes,
+   * even though they are not needed for allocation.
+   */
+  hdr_ptr->hdr.bytes_used = sizeofobject;
+  hdr_ptr->hdr.bytes_left = 0;
+  mem->large_list[pool_id] = hdr_ptr;
+
+  return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
+}
+
+
+/*
+ * Creation of 2-D sample arrays.
+ * The pointers are in near heap, the samples themselves in FAR heap.
+ *
+ * To minimize allocation overhead and to allow I/O of large contiguous
+ * blocks, we allocate the sample rows in groups of as many rows as possible
+ * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
+ * NB: the virtual array control routines, later in this file, know about
+ * this chunking of rows.  The rowsperchunk value is left in the mem manager
+ * object so that it can be saved away if this sarray is the workspace for
+ * a virtual array.
+ */
+
+METHODDEF(JSAMPARRAY)
+alloc_sarray (j_common_ptr cinfo, int pool_id,
+	      JDIMENSION samplesperrow, JDIMENSION numrows)
+/* Allocate a 2-D sample array */
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  JSAMPARRAY result;
+  JSAMPROW workspace;
+  JDIMENSION rowsperchunk, currow, i;
+  long ltemp;
+
+  /* Calculate max # of rows allowed in one allocation chunk */
+  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
+	  ((long) samplesperrow * SIZEOF(JSAMPLE));
+  if (ltemp <= 0)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+  if (ltemp < (long) numrows)
+    rowsperchunk = (JDIMENSION) ltemp;
+  else
+    rowsperchunk = numrows;
+  mem->last_rowsperchunk = rowsperchunk;
+
+  /* Get space for row pointers (small object) */
+  result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
+				    (size_t) (numrows * SIZEOF(JSAMPROW)));
+
+  /* Get the rows themselves (large objects) */
+  currow = 0;
+  while (currow < numrows) {
+    rowsperchunk = MIN(rowsperchunk, numrows - currow);
+    workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
+	(size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
+		  * SIZEOF(JSAMPLE)));
+    for (i = rowsperchunk; i > 0; i--) {
+      result[currow++] = workspace;
+      workspace += samplesperrow;
+    }
+  }
+
+  return result;
+}
+
+
+/*
+ * Creation of 2-D coefficient-block arrays.
+ * This is essentially the same as the code for sample arrays, above.
+ */
+
+METHODDEF(JBLOCKARRAY)
+alloc_barray (j_common_ptr cinfo, int pool_id,
+	      JDIMENSION blocksperrow, JDIMENSION numrows)
+/* Allocate a 2-D coefficient-block array */
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  JBLOCKARRAY result;
+  JBLOCKROW workspace;
+  JDIMENSION rowsperchunk, currow, i;
+  long ltemp;
+
+  /* Calculate max # of rows allowed in one allocation chunk */
+  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
+	  ((long) blocksperrow * SIZEOF(JBLOCK));
+  if (ltemp <= 0)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+  if (ltemp < (long) numrows)
+    rowsperchunk = (JDIMENSION) ltemp;
+  else
+    rowsperchunk = numrows;
+  mem->last_rowsperchunk = rowsperchunk;
+
+  /* Get space for row pointers (small object) */
+  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
+				     (size_t) (numrows * SIZEOF(JBLOCKROW)));
+
+  /* Get the rows themselves (large objects) */
+  currow = 0;
+  while (currow < numrows) {
+    rowsperchunk = MIN(rowsperchunk, numrows - currow);
+    workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
+	(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
+		  * SIZEOF(JBLOCK)));
+    for (i = rowsperchunk; i > 0; i--) {
+      result[currow++] = workspace;
+      workspace += blocksperrow;
+    }
+  }
+
+  return result;
+}
+
+
+/*
+ * About virtual array management:
+ *
+ * The above "normal" array routines are only used to allocate strip buffers
+ * (as wide as the image, but just a few rows high).  Full-image-sized buffers
+ * are handled as "virtual" arrays.  The array is still accessed a strip at a
+ * time, but the memory manager must save the whole array for repeated
+ * accesses.  The intended implementation is that there is a strip buffer in
+ * memory (as high as is possible given the desired memory limit), plus a
+ * backing file that holds the rest of the array.
+ *
+ * The request_virt_array routines are told the total size of the image and
+ * the maximum number of rows that will be accessed at once.  The in-memory
+ * buffer must be at least as large as the maxaccess value.
+ *
+ * The request routines create control blocks but not the in-memory buffers.
+ * That is postponed until realize_virt_arrays is called.  At that time the
+ * total amount of space needed is known (approximately, anyway), so free
+ * memory can be divided up fairly.
+ *
+ * The access_virt_array routines are responsible for making a specific strip
+ * area accessible (after reading or writing the backing file, if necessary).
+ * Note that the access routines are told whether the caller intends to modify
+ * the accessed strip; during a read-only pass this saves having to rewrite
+ * data to disk.  The access routines are also responsible for pre-zeroing
+ * any newly accessed rows, if pre-zeroing was requested.
+ *
+ * In current usage, the access requests are usually for nonoverlapping
+ * strips; that is, successive access start_row numbers differ by exactly
+ * num_rows = maxaccess.  This means we can get good performance with simple
+ * buffer dump/reload logic, by making the in-memory buffer be a multiple
+ * of the access height; then there will never be accesses across bufferload
+ * boundaries.  The code will still work with overlapping access requests,
+ * but it doesn't handle bufferload overlaps very efficiently.
+ */
+
+
+METHODDEF(jvirt_sarray_ptr)
+request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
+		     JDIMENSION samplesperrow, JDIMENSION numrows,
+		     JDIMENSION maxaccess)
+/* Request a virtual 2-D sample array */
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  jvirt_sarray_ptr result;
+
+  /* Only IMAGE-lifetime virtual arrays are currently supported */
+  if (pool_id != JPOOL_IMAGE)
+    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
+
+  /* get control block */
+  result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
+					  SIZEOF(struct jvirt_sarray_control));
+
+  result->mem_buffer = NULL;	/* marks array not yet realized */
+  result->rows_in_array = numrows;
+  result->samplesperrow = samplesperrow;
+  result->maxaccess = maxaccess;
+  result->pre_zero = pre_zero;
+  result->b_s_open = FALSE;	/* no associated backing-store object */
+  result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
+  mem->virt_sarray_list = result;
+
+  return result;
+}
+
+
+METHODDEF(jvirt_barray_ptr)
+request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
+		     JDIMENSION blocksperrow, JDIMENSION numrows,
+		     JDIMENSION maxaccess)
+/* Request a virtual 2-D coefficient-block array */
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  jvirt_barray_ptr result;
+
+  /* Only IMAGE-lifetime virtual arrays are currently supported */
+  if (pool_id != JPOOL_IMAGE)
+    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
+
+  /* get control block */
+  result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
+					  SIZEOF(struct jvirt_barray_control));
+
+  result->mem_buffer = NULL;	/* marks array not yet realized */
+  result->rows_in_array = numrows;
+  result->blocksperrow = blocksperrow;
+  result->maxaccess = maxaccess;
+  result->pre_zero = pre_zero;
+  result->b_s_open = FALSE;	/* no associated backing-store object */
+  result->next = mem->virt_barray_list; /* add to list of virtual arrays */
+  mem->virt_barray_list = result;
+
+  return result;
+}
+
+
+METHODDEF(void)
+realize_virt_arrays (j_common_ptr cinfo)
+/* Allocate the in-memory buffers for any unrealized virtual arrays */
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  long space_per_minheight, maximum_space, avail_mem;
+  long minheights, max_minheights;
+  jvirt_sarray_ptr sptr;
+  jvirt_barray_ptr bptr;
+
+  /* Compute the minimum space needed (maxaccess rows in each buffer)
+   * and the maximum space needed (full image height in each buffer).
+   * These may be of use to the system-dependent jpeg_mem_available routine.
+   */
+  space_per_minheight = 0;
+  maximum_space = 0;
+  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+    if (sptr->mem_buffer == NULL) { /* if not realized yet */
+      space_per_minheight += (long) sptr->maxaccess *
+			     (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
+      maximum_space += (long) sptr->rows_in_array *
+		       (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
+    }
+  }
+  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+    if (bptr->mem_buffer == NULL) { /* if not realized yet */
+      space_per_minheight += (long) bptr->maxaccess *
+			     (long) bptr->blocksperrow * SIZEOF(JBLOCK);
+      maximum_space += (long) bptr->rows_in_array *
+		       (long) bptr->blocksperrow * SIZEOF(JBLOCK);
+    }
+  }
+
+  if (space_per_minheight <= 0)
+    return;			/* no unrealized arrays, no work */
+
+  /* Determine amount of memory to actually use; this is system-dependent. */
+  avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
+				 mem->total_space_allocated);
+
+  /* If the maximum space needed is available, make all the buffers full
+   * height; otherwise parcel it out with the same number of minheights
+   * in each buffer.
+   */
+  if (avail_mem >= maximum_space)
+    max_minheights = 1000000000L;
+  else {
+    max_minheights = avail_mem / space_per_minheight;
+    /* If there doesn't seem to be enough space, try to get the minimum
+     * anyway.  This allows a "stub" implementation of jpeg_mem_available().
+     */
+    if (max_minheights <= 0)
+      max_minheights = 1;
+  }
+
+  /* Allocate the in-memory buffers and initialize backing store as needed. */
+
+  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+    if (sptr->mem_buffer == NULL) { /* if not realized yet */
+      minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
+      if (minheights <= max_minheights) {
+	/* This buffer fits in memory */
+	sptr->rows_in_mem = sptr->rows_in_array;
+      } else {
+	/* It doesn't fit in memory, create backing store. */
+	sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
+	jpeg_open_backing_store(cinfo, & sptr->b_s_info,
+				(long) sptr->rows_in_array *
+				(long) sptr->samplesperrow *
+				(long) SIZEOF(JSAMPLE));
+	sptr->b_s_open = TRUE;
+      }
+      sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
+				      sptr->samplesperrow, sptr->rows_in_mem);
+      sptr->rowsperchunk = mem->last_rowsperchunk;
+      sptr->cur_start_row = 0;
+      sptr->first_undef_row = 0;
+      sptr->dirty = FALSE;
+    }
+  }
+
+  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+    if (bptr->mem_buffer == NULL) { /* if not realized yet */
+      minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
+      if (minheights <= max_minheights) {
+	/* This buffer fits in memory */
+	bptr->rows_in_mem = bptr->rows_in_array;
+      } else {
+	/* It doesn't fit in memory, create backing store. */
+	bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
+	jpeg_open_backing_store(cinfo, & bptr->b_s_info,
+				(long) bptr->rows_in_array *
+				(long) bptr->blocksperrow *
+				(long) SIZEOF(JBLOCK));
+	bptr->b_s_open = TRUE;
+      }
+      bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
+				      bptr->blocksperrow, bptr->rows_in_mem);
+      bptr->rowsperchunk = mem->last_rowsperchunk;
+      bptr->cur_start_row = 0;
+      bptr->first_undef_row = 0;
+      bptr->dirty = FALSE;
+    }
+  }
+}
+
+
+LOCAL(void)
+do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
+/* Do backing store read or write of a virtual sample array */
+{
+  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
+
+  bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
+  file_offset = ptr->cur_start_row * bytesperrow;
+  /* Loop to read or write each allocation chunk in mem_buffer */
+  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
+    /* One chunk, but check for short chunk at end of buffer */
+    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
+    /* Transfer no more than is currently defined */
+    thisrow = (long) ptr->cur_start_row + i;
+    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
+    /* Transfer no more than fits in file */
+    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
+    if (rows <= 0)		/* this chunk might be past end of file! */
+      break;
+    byte_count = rows * bytesperrow;
+    if (writing)
+      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
+					    (void FAR *) ptr->mem_buffer[i],
+					    file_offset, byte_count);
+    else
+      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
+					   (void FAR *) ptr->mem_buffer[i],
+					   file_offset, byte_count);
+    file_offset += byte_count;
+  }
+}
+
+
+LOCAL(void)
+do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
+/* Do backing store read or write of a virtual coefficient-block array */
+{
+  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
+
+  bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
+  file_offset = ptr->cur_start_row * bytesperrow;
+  /* Loop to read or write each allocation chunk in mem_buffer */
+  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
+    /* One chunk, but check for short chunk at end of buffer */
+    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
+    /* Transfer no more than is currently defined */
+    thisrow = (long) ptr->cur_start_row + i;
+    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
+    /* Transfer no more than fits in file */
+    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
+    if (rows <= 0)		/* this chunk might be past end of file! */
+      break;
+    byte_count = rows * bytesperrow;
+    if (writing)
+      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
+					    (void FAR *) ptr->mem_buffer[i],
+					    file_offset, byte_count);
+    else
+      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
+					   (void FAR *) ptr->mem_buffer[i],
+					   file_offset, byte_count);
+    file_offset += byte_count;
+  }
+}
+
+
+METHODDEF(JSAMPARRAY)
+access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
+		    JDIMENSION start_row, JDIMENSION num_rows,
+		    boolean writable)
+/* Access the part of a virtual sample array starting at start_row */
+/* and extending for num_rows rows.  writable is true if  */
+/* caller intends to modify the accessed area. */
+{
+  JDIMENSION end_row = start_row + num_rows;
+  JDIMENSION undef_row;
+
+  /* debugging check */
+  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
+      ptr->mem_buffer == NULL)
+    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+
+  /* Make the desired part of the virtual array accessible */
+  if (start_row < ptr->cur_start_row ||
+      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
+    if (! ptr->b_s_open)
+      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
+    /* Flush old buffer contents if necessary */
+    if (ptr->dirty) {
+      do_sarray_io(cinfo, ptr, TRUE);
+      ptr->dirty = FALSE;
+    }
+    /* Decide what part of virtual array to access.
+     * Algorithm: if target address > current window, assume forward scan,
+     * load starting at target address.  If target address < current window,
+     * assume backward scan, load so that target area is top of window.
+     * Note that when switching from forward write to forward read, will have
+     * start_row = 0, so the limiting case applies and we load from 0 anyway.
+     */
+    if (start_row > ptr->cur_start_row) {
+      ptr->cur_start_row = start_row;
+    } else {
+      /* use long arithmetic here to avoid overflow & unsigned problems */
+      long ltemp;
+
+      ltemp = (long) end_row - (long) ptr->rows_in_mem;
+      if (ltemp < 0)
+	ltemp = 0;		/* don't fall off front end of file */
+      ptr->cur_start_row = (JDIMENSION) ltemp;
+    }
+    /* Read in the selected part of the array.
+     * During the initial write pass, we will do no actual read
+     * because the selected part is all undefined.
+     */
+    do_sarray_io(cinfo, ptr, FALSE);
+  }
+  /* Ensure the accessed part of the array is defined; prezero if needed.
+   * To improve locality of access, we only prezero the part of the array
+   * that the caller is about to access, not the entire in-memory array.
+   */
+  if (ptr->first_undef_row < end_row) {
+    if (ptr->first_undef_row < start_row) {
+      if (writable)		/* writer skipped over a section of array */
+	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+      undef_row = start_row;	/* but reader is allowed to read ahead */
+    } else {
+      undef_row = ptr->first_undef_row;
+    }
+    if (writable)
+      ptr->first_undef_row = end_row;
+    if (ptr->pre_zero) {
+      size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
+      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
+      end_row -= ptr->cur_start_row;
+      while (undef_row < end_row) {
+	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
+	undef_row++;
+      }
+    } else {
+      if (! writable)		/* reader looking at undefined data */
+	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+    }
+  }
+  /* Flag the buffer dirty if caller will write in it */
+  if (writable)
+    ptr->dirty = TRUE;
+  /* Return address of proper part of the buffer */
+  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
+}
+
+
+METHODDEF(JBLOCKARRAY)
+access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
+		    JDIMENSION start_row, JDIMENSION num_rows,
+		    boolean writable)
+/* Access the part of a virtual block array starting at start_row */
+/* and extending for num_rows rows.  writable is true if  */
+/* caller intends to modify the accessed area. */
+{
+  JDIMENSION end_row = start_row + num_rows;
+  JDIMENSION undef_row;
+
+  /* debugging check */
+  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
+      ptr->mem_buffer == NULL)
+    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+
+  /* Make the desired part of the virtual array accessible */
+  if (start_row < ptr->cur_start_row ||
+      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
+    if (! ptr->b_s_open)
+      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
+    /* Flush old buffer contents if necessary */
+    if (ptr->dirty) {
+      do_barray_io(cinfo, ptr, TRUE);
+      ptr->dirty = FALSE;
+    }
+    /* Decide what part of virtual array to access.
+     * Algorithm: if target address > current window, assume forward scan,
+     * load starting at target address.  If target address < current window,
+     * assume backward scan, load so that target area is top of window.
+     * Note that when switching from forward write to forward read, will have
+     * start_row = 0, so the limiting case applies and we load from 0 anyway.
+     */
+    if (start_row > ptr->cur_start_row) {
+      ptr->cur_start_row = start_row;
+    } else {
+      /* use long arithmetic here to avoid overflow & unsigned problems */
+      long ltemp;
+
+      ltemp = (long) end_row - (long) ptr->rows_in_mem;
+      if (ltemp < 0)
+	ltemp = 0;		/* don't fall off front end of file */
+      ptr->cur_start_row = (JDIMENSION) ltemp;
+    }
+    /* Read in the selected part of the array.
+     * During the initial write pass, we will do no actual read
+     * because the selected part is all undefined.
+     */
+    do_barray_io(cinfo, ptr, FALSE);
+  }
+  /* Ensure the accessed part of the array is defined; prezero if needed.
+   * To improve locality of access, we only prezero the part of the array
+   * that the caller is about to access, not the entire in-memory array.
+   */
+  if (ptr->first_undef_row < end_row) {
+    if (ptr->first_undef_row < start_row) {
+      if (writable)		/* writer skipped over a section of array */
+	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+      undef_row = start_row;	/* but reader is allowed to read ahead */
+    } else {
+      undef_row = ptr->first_undef_row;
+    }
+    if (writable)
+      ptr->first_undef_row = end_row;
+    if (ptr->pre_zero) {
+      size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
+      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
+      end_row -= ptr->cur_start_row;
+      while (undef_row < end_row) {
+	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
+	undef_row++;
+      }
+    } else {
+      if (! writable)		/* reader looking at undefined data */
+	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+    }
+  }
+  /* Flag the buffer dirty if caller will write in it */
+  if (writable)
+    ptr->dirty = TRUE;
+  /* Return address of proper part of the buffer */
+  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
+}
+
+
+/*
+ * Release all objects belonging to a specified pool.
+ */
+
+METHODDEF(void)
+free_pool (j_common_ptr cinfo, int pool_id)
+{
+  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+  small_pool_ptr shdr_ptr;
+  large_pool_ptr lhdr_ptr;
+  size_t space_freed;
+
+  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
+
+#ifdef MEM_STATS
+  if (cinfo->err->trace_level > 1)
+    print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
+#endif
+
+  /* If freeing IMAGE pool, close any virtual arrays first */
+  if (pool_id == JPOOL_IMAGE) {
+    jvirt_sarray_ptr sptr;
+    jvirt_barray_ptr bptr;
+
+    for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+      if (sptr->b_s_open) {	/* there may be no backing store */
+	sptr->b_s_open = FALSE;	/* prevent recursive close if error */
+	(*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
+      }
+    }
+    mem->virt_sarray_list = NULL;
+    for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+      if (bptr->b_s_open) {	/* there may be no backing store */
+	bptr->b_s_open = FALSE;	/* prevent recursive close if error */
+	(*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
+      }
+    }
+    mem->virt_barray_list = NULL;
+  }
+
+  /* Release large objects */
+  lhdr_ptr = mem->large_list[pool_id];
+  mem->large_list[pool_id] = NULL;
+
+  while (lhdr_ptr != NULL) {
+    large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
+    space_freed = lhdr_ptr->hdr.bytes_used +
+		  lhdr_ptr->hdr.bytes_left +
+		  SIZEOF(large_pool_hdr);
+    jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
+    mem->total_space_allocated -= space_freed;
+    lhdr_ptr = next_lhdr_ptr;
+  }
+
+  /* Release small objects */
+  shdr_ptr = mem->small_list[pool_id];
+  mem->small_list[pool_id] = NULL;
+
+  while (shdr_ptr != NULL) {
+    small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
+    space_freed = shdr_ptr->hdr.bytes_used +
+		  shdr_ptr->hdr.bytes_left +
+		  SIZEOF(small_pool_hdr);
+    jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
+    mem->total_space_allocated -= space_freed;
+    shdr_ptr = next_shdr_ptr;
+  }
+}
+
+
+/*
+ * Close up shop entirely.
+ * Note that this cannot be called unless cinfo->mem is non-NULL.
+ */
+
+METHODDEF(void)
+self_destruct (j_common_ptr cinfo)
+{
+  int pool;
+
+  /* Close all backing store, release all memory.
+   * Releasing pools in reverse order might help avoid fragmentation
+   * with some (brain-damaged) malloc libraries.
+   */
+  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
+    free_pool(cinfo, pool);
+  }
+
+  /* Release the memory manager control block too. */
+  jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
+  cinfo->mem = NULL;		/* ensures I will be called only once */
+
+  jpeg_mem_term(cinfo);		/* system-dependent cleanup */
+}
+
+
+/*
+ * Memory manager initialization.
+ * When this is called, only the error manager pointer is valid in cinfo!
+ */
+
+GLOBAL(void)
+jinit_memory_mgr (j_common_ptr cinfo)
+{
+  my_mem_ptr mem;
+  long max_to_use;
+  int pool;
+  size_t test_mac;
+
+  cinfo->mem = NULL;		/* for safety if init fails */
+
+  /* Check for configuration errors.
+   * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
+   * doesn't reflect any real hardware alignment requirement.
+   * The test is a little tricky: for X>0, X and X-1 have no one-bits
+   * in common if and only if X is a power of 2, ie has only one one-bit.
+   * Some compilers may give an "unreachable code" warning here; ignore it.
+   */
+  if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
+    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
+  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
+   * a multiple of SIZEOF(ALIGN_TYPE).
+   * Again, an "unreachable code" warning may be ignored here.
+   * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
+   */
+  test_mac = (size_t) MAX_ALLOC_CHUNK;
+  if ((long) test_mac != MAX_ALLOC_CHUNK ||
+      (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
+    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
+
+  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
+
+  /* Attempt to allocate memory manager's control block */
+  mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
+
+  if (mem == NULL) {
+    jpeg_mem_term(cinfo);	/* system-dependent cleanup */
+    ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
+  }
+
+  /* OK, fill in the method pointers */
+  mem->pub.alloc_small = alloc_small;
+  mem->pub.alloc_large = alloc_large;
+  mem->pub.alloc_sarray = alloc_sarray;
+  mem->pub.alloc_barray = alloc_barray;
+  mem->pub.request_virt_sarray = request_virt_sarray;
+  mem->pub.request_virt_barray = request_virt_barray;
+  mem->pub.realize_virt_arrays = realize_virt_arrays;
+  mem->pub.access_virt_sarray = access_virt_sarray;
+  mem->pub.access_virt_barray = access_virt_barray;
+  mem->pub.free_pool = free_pool;
+  mem->pub.self_destruct = self_destruct;
+
+  /* Make MAX_ALLOC_CHUNK accessible to other modules */
+  mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
+
+  /* Initialize working state */
+  mem->pub.max_memory_to_use = max_to_use;
+
+  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
+    mem->small_list[pool] = NULL;
+    mem->large_list[pool] = NULL;
+  }
+  mem->virt_sarray_list = NULL;
+  mem->virt_barray_list = NULL;
+
+  mem->total_space_allocated = SIZEOF(my_memory_mgr);
+
+  /* Declare ourselves open for business */
+  cinfo->mem = & mem->pub;
+
+  /* Check for an environment variable JPEGMEM; if found, override the
+   * default max_memory setting from jpeg_mem_init.  Note that the
+   * surrounding application may again override this value.
+   * If your system doesn't support getenv(), define NO_GETENV to disable
+   * this feature.
+   */
+#ifndef NO_GETENV
+  { char * memenv;
+
+    if ((memenv = getenv("JPEGMEM")) != NULL) {
+      char ch = 'x';
+
+      if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
+	if (ch == 'm' || ch == 'M')
+	  max_to_use *= 1000L;
+	mem->pub.max_memory_to_use = max_to_use * 1000L;
+      }
+    }
+  }
+#endif
+
+}
diff --git a/Utilities/FLTK/jpeg/jmemnobs.c b/Utilities/FLTK/jpeg/jmemnobs.c
new file mode 100644
index 0000000000000000000000000000000000000000..eb8c337725fd85f289b04eebbea8549d90d53c77
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jmemnobs.c
@@ -0,0 +1,109 @@
+/*
+ * jmemnobs.c
+ *
+ * Copyright (C) 1992-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file provides a really simple implementation of the system-
+ * dependent portion of the JPEG memory manager.  This implementation
+ * assumes that no backing-store files are needed: all required space
+ * can be obtained from malloc().
+ * This is very portable in the sense that it'll compile on almost anything,
+ * but you'd better have lots of main memory (or virtual memory) if you want
+ * to process big images.
+ * Note that the max_memory_to_use option is ignored by this implementation.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jmemsys.h"		/* import the system-dependent declarations */
+
+#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare malloc(),free() */
+extern void * malloc JPP((size_t size));
+extern void free JPP((void *ptr));
+#endif
+
+
+/*
+ * Memory allocation and freeing are controlled by the regular library
+ * routines malloc() and free().
+ */
+
+GLOBAL(void *)
+jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
+{
+  return (void *) malloc(sizeofobject);
+}
+
+GLOBAL(void)
+jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
+{
+  free(object);
+}
+
+
+/*
+ * "Large" objects are treated the same as "small" ones.
+ * NB: although we include FAR keywords in the routine declarations,
+ * this file won't actually work in 80x86 small/medium model; at least,
+ * you probably won't be able to process useful-size images in only 64KB.
+ */
+
+GLOBAL(void FAR *)
+jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
+{
+  return (void FAR *) malloc(sizeofobject);
+}
+
+GLOBAL(void)
+jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
+{
+  free(object);
+}
+
+
+/*
+ * This routine computes the total memory space available for allocation.
+ * Here we always say, "we got all you want bud!"
+ */
+
+GLOBAL(long)
+jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
+		    long max_bytes_needed, long already_allocated)
+{
+  return max_bytes_needed;
+}
+
+
+/*
+ * Backing store (temporary file) management.
+ * Since jpeg_mem_available always promised the moon,
+ * this should never be called and we can just error out.
+ */
+
+GLOBAL(void)
+jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
+			 long total_bytes_needed)
+{
+  ERREXIT(cinfo, JERR_NO_BACKING_STORE);
+}
+
+
+/*
+ * These routines take care of any system-dependent initialization and
+ * cleanup required.  Here, there isn't any.
+ */
+
+GLOBAL(long)
+jpeg_mem_init (j_common_ptr cinfo)
+{
+  return 0;			/* just set max_memory_to_use to 0 */
+}
+
+GLOBAL(void)
+jpeg_mem_term (j_common_ptr cinfo)
+{
+  /* no work */
+}
diff --git a/Utilities/FLTK/jpeg/jmemsys.h b/Utilities/FLTK/jpeg/jmemsys.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c3c6d348f2cf68149087f1906196a470136237e
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jmemsys.h
@@ -0,0 +1,198 @@
+/*
+ * jmemsys.h
+ *
+ * Copyright (C) 1992-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This include file defines the interface between the system-independent
+ * and system-dependent portions of the JPEG memory manager.  No other
+ * modules need include it.  (The system-independent portion is jmemmgr.c;
+ * there are several different versions of the system-dependent portion.)
+ *
+ * This file works as-is for the system-dependent memory managers supplied
+ * in the IJG distribution.  You may need to modify it if you write a
+ * custom memory manager.  If system-dependent changes are needed in
+ * this file, the best method is to #ifdef them based on a configuration
+ * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
+ * and USE_MAC_MEMMGR.
+ */
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_get_small		jGetSmall
+#define jpeg_free_small		jFreeSmall
+#define jpeg_get_large		jGetLarge
+#define jpeg_free_large		jFreeLarge
+#define jpeg_mem_available	jMemAvail
+#define jpeg_open_backing_store	jOpenBackStore
+#define jpeg_mem_init		jMemInit
+#define jpeg_mem_term		jMemTerm
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/*
+ * These two functions are used to allocate and release small chunks of
+ * memory.  (Typically the total amount requested through jpeg_get_small is
+ * no more than 20K or so; this will be requested in chunks of a few K each.)
+ * Behavior should be the same as for the standard library functions malloc
+ * and free; in particular, jpeg_get_small must return NULL on failure.
+ * On most systems, these ARE malloc and free.  jpeg_free_small is passed the
+ * size of the object being freed, just in case it's needed.
+ * On an 80x86 machine using small-data memory model, these manage near heap.
+ */
+
+EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
+EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
+				  size_t sizeofobject));
+
+/*
+ * These two functions are used to allocate and release large chunks of
+ * memory (up to the total free space designated by jpeg_mem_available).
+ * The interface is the same as above, except that on an 80x86 machine,
+ * far pointers are used.  On most other machines these are identical to
+ * the jpeg_get/free_small routines; but we keep them separate anyway,
+ * in case a different allocation strategy is desirable for large chunks.
+ */
+
+EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
+				       size_t sizeofobject));
+EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
+				  size_t sizeofobject));
+
+/*
+ * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
+ * be requested in a single call to jpeg_get_large (and jpeg_get_small for that
+ * matter, but that case should never come into play).  This macro is needed
+ * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
+ * On those machines, we expect that jconfig.h will provide a proper value.
+ * On machines with 32-bit flat address spaces, any large constant may be used.
+ *
+ * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
+ * size_t and will be a multiple of sizeof(align_type).
+ */
+
+#ifndef MAX_ALLOC_CHUNK		/* may be overridden in jconfig.h */
+#define MAX_ALLOC_CHUNK  1000000000L
+#endif
+
+/*
+ * This routine computes the total space still available for allocation by
+ * jpeg_get_large.  If more space than this is needed, backing store will be
+ * used.  NOTE: any memory already allocated must not be counted.
+ *
+ * There is a minimum space requirement, corresponding to the minimum
+ * feasible buffer sizes; jmemmgr.c will request that much space even if
+ * jpeg_mem_available returns zero.  The maximum space needed, enough to hold
+ * all working storage in memory, is also passed in case it is useful.
+ * Finally, the total space already allocated is passed.  If no better
+ * method is available, cinfo->mem->max_memory_to_use - already_allocated
+ * is often a suitable calculation.
+ *
+ * It is OK for jpeg_mem_available to underestimate the space available
+ * (that'll just lead to more backing-store access than is really necessary).
+ * However, an overestimate will lead to failure.  Hence it's wise to subtract
+ * a slop factor from the true available space.  5% should be enough.
+ *
+ * On machines with lots of virtual memory, any large constant may be returned.
+ * Conversely, zero may be returned to always use the minimum amount of memory.
+ */
+
+EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
+				     long min_bytes_needed,
+				     long max_bytes_needed,
+				     long already_allocated));
+
+
+/*
+ * This structure holds whatever state is needed to access a single
+ * backing-store object.  The read/write/close method pointers are called
+ * by jmemmgr.c to manipulate the backing-store object; all other fields
+ * are private to the system-dependent backing store routines.
+ */
+
+#define TEMP_NAME_LENGTH   64	/* max length of a temporary file's name */
+
+
+#ifdef USE_MSDOS_MEMMGR		/* DOS-specific junk */
+
+typedef unsigned short XMSH;	/* type of extended-memory handles */
+typedef unsigned short EMSH;	/* type of expanded-memory handles */
+
+typedef union {
+  short file_handle;		/* DOS file handle if it's a temp file */
+  XMSH xms_handle;		/* handle if it's a chunk of XMS */
+  EMSH ems_handle;		/* handle if it's a chunk of EMS */
+} handle_union;
+
+#endif /* USE_MSDOS_MEMMGR */
+
+#ifdef USE_MAC_MEMMGR		/* Mac-specific junk */
+#include <Files.h>
+#endif /* USE_MAC_MEMMGR */
+
+
+typedef struct backing_store_struct * backing_store_ptr;
+
+typedef struct backing_store_struct {
+  /* Methods for reading/writing/closing this backing-store object */
+  JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
+				     backing_store_ptr info,
+				     void FAR * buffer_address,
+				     long file_offset, long byte_count));
+  JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
+				      backing_store_ptr info,
+				      void FAR * buffer_address,
+				      long file_offset, long byte_count));
+  JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
+				      backing_store_ptr info));
+
+  /* Private fields for system-dependent backing-store management */
+#ifdef USE_MSDOS_MEMMGR
+  /* For the MS-DOS manager (jmemdos.c), we need: */
+  handle_union handle;		/* reference to backing-store storage object */
+  char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
+#else
+#ifdef USE_MAC_MEMMGR
+  /* For the Mac manager (jmemmac.c), we need: */
+  short temp_file;		/* file reference number to temp file */
+  FSSpec tempSpec;		/* the FSSpec for the temp file */
+  char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
+#else
+  /* For a typical implementation with temp files, we need: */
+  FILE * temp_file;		/* stdio reference to temp file */
+  char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
+#endif
+#endif
+} backing_store_info;
+
+
+/*
+ * Initial opening of a backing-store object.  This must fill in the
+ * read/write/close pointers in the object.  The read/write routines
+ * may take an error exit if the specified maximum file size is exceeded.
+ * (If jpeg_mem_available always returns a large value, this routine can
+ * just take an error exit.)
+ */
+
+EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
+					  backing_store_ptr info,
+					  long total_bytes_needed));
+
+
+/*
+ * These routines take care of any system-dependent initialization and
+ * cleanup required.  jpeg_mem_init will be called before anything is
+ * allocated (and, therefore, nothing in cinfo is of use except the error
+ * manager pointer).  It should return a suitable default value for
+ * max_memory_to_use; this may subsequently be overridden by the surrounding
+ * application.  (Note that max_memory_to_use is only important if
+ * jpeg_mem_available chooses to consult it ... no one else will.)
+ * jpeg_mem_term may assume that all requested memory has been freed and that
+ * all opened backing-store objects have been closed.
+ */
+
+EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
+EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
diff --git a/Utilities/FLTK/jpeg/jmorecfg.h b/Utilities/FLTK/jpeg/jmorecfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f491fc914028e5352202a1f133d777892dd76f8
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jmorecfg.h
@@ -0,0 +1,316 @@
+/*
+ * jmorecfg.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains additional configuration options that customize the
+ * JPEG software for special applications or support machine-dependent
+ * optimizations.  Most users will not need to touch this file.
+ */
+
+
+/*
+ * Define BITS_IN_JSAMPLE as either
+ *   8   for 8-bit sample values (the usual setting)
+ *   12  for 12-bit sample values
+ * Only 8 and 12 are legal data precisions for lossy JPEG according to the
+ * JPEG standard, and the IJG code does not support anything else!
+ * We do not support run-time selection of data precision, sorry.
+ */
+
+#define BITS_IN_JSAMPLE  8	/* use 8 or 12 */
+
+
+/*
+ * Maximum number of components (color channels) allowed in JPEG image.
+ * To meet the letter of the JPEG spec, set this to 255.  However, darn
+ * few applications need more than 4 channels (maybe 5 for CMYK + alpha
+ * mask).  We recommend 10 as a reasonable compromise; use 4 if you are
+ * really short on memory.  (Each allowed component costs a hundred or so
+ * bytes of storage, whether actually used in an image or not.)
+ */
+
+#define MAX_COMPONENTS  10	/* maximum number of image components */
+
+
+/*
+ * Basic data types.
+ * You may need to change these if you have a machine with unusual data
+ * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
+ * or "long" not 32 bits.  We don't care whether "int" is 16 or 32 bits,
+ * but it had better be at least 16.
+ */
+
+/* Representation of a single sample (pixel element value).
+ * We frequently allocate large arrays of these, so it's important to keep
+ * them small.  But if you have memory to burn and access to char or short
+ * arrays is very slow on your hardware, you might want to change these.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+/* JSAMPLE should be the smallest type that will hold the values 0..255.
+ * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
+ */
+
+typedef unsigned char JSAMPLE;
+#define GETJSAMPLE(value)  ((int) (value))
+
+#define MAXJSAMPLE	255
+#define CENTERJSAMPLE	128
+
+#endif /* BITS_IN_JSAMPLE == 8 */
+
+
+#if BITS_IN_JSAMPLE == 12
+/* JSAMPLE should be the smallest type that will hold the values 0..4095.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value)  ((int) (value))
+
+#define MAXJSAMPLE	4095
+#define CENTERJSAMPLE	2048
+
+#endif /* BITS_IN_JSAMPLE == 12 */
+
+
+/* Representation of a DCT frequency coefficient.
+ * This should be a signed value of at least 16 bits; "short" is usually OK.
+ * Again, we allocate large arrays of these, but you can change to int
+ * if you have memory to burn and "short" is really slow.
+ */
+
+typedef short JCOEF;
+
+
+/* Compressed datastreams are represented as arrays of JOCTET.
+ * These must be EXACTLY 8 bits wide, at least once they are written to
+ * external storage.  Note that when using the stdio data source/destination
+ * managers, this is also the data type passed to fread/fwrite.
+ */
+
+typedef unsigned char JOCTET;
+#define GETJOCTET(value)  (value)
+
+/* These typedefs are used for various table entries and so forth.
+ * They must be at least as wide as specified; but making them too big
+ * won't cost a huge amount of memory, so we don't provide special
+ * extraction code like we did for JSAMPLE.  (In other words, these
+ * typedefs live at a different point on the speed/space tradeoff curve.)
+ */
+
+/* UINT8 must hold at least the values 0..255. */
+
+typedef unsigned char UINT8;
+
+/* UINT16 must hold at least the values 0..65535. */
+
+typedef unsigned short UINT16;
+
+/* INT16 must hold at least the values -32768..32767. */
+
+#ifndef XMD_H			/* X11/xmd.h correctly defines INT16 */
+typedef short INT16;
+#endif
+
+/* INT32 must hold at least signed 32-bit values. */
+
+#ifndef XMD_H
+typedef int INT32;
+#endif
+
+/* Datatype used for image dimensions.  The JPEG standard only supports
+ * images up to 64K*64K due to 16-bit fields in SOF markers.  Therefore
+ * "unsigned int" is sufficient on all machines.  However, if you need to
+ * handle larger images and you don't mind deviating from the spec, you
+ * can change this datatype.
+ */
+
+typedef unsigned int JDIMENSION;
+
+#define JPEG_MAX_DIMENSION  65500L  /* a tad under 64K to prevent overflows */
+
+
+/* These macros are used in all function definitions and extern declarations.
+ * You could modify them if you need to change function linkage conventions;
+ * in particular, you'll need to do that to make the library a Windows DLL.
+ * Another application is to make all functions global for use with debuggers
+ * or code profilers that require it.
+ */
+
+/* a function called through method pointers: */
+#define METHODDEF(type)		static type
+/* a function used only in its module: */
+#define LOCAL(type)		static type
+/* a function referenced thru EXTERNs: */
+#define GLOBAL(type)		type
+/* a reference to a GLOBAL function: */
+#define EXTERN(type)		extern type
+
+
+/* This macro is used to declare a "method", that is, a function pointer.
+ * We want to supply prototype parameters if the compiler can cope.
+ * Note that the arglist parameter must be parenthesized!
+ * Again, you can customize this if you need special linkage keywords.
+ */
+
+#define JMETHOD(type,methodname,arglist)  type (*methodname) arglist
+
+/* Here is the pseudo-keyword for declaring pointers that must be "far"
+ * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
+ * by just saying "FAR *" where such a pointer is needed.  In a few places
+ * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
+ */
+
+#undef FAR
+#define FAR
+
+
+/*
+ * On a few systems, type boolean and/or its values FALSE, TRUE may appear
+ * in standard header files.  Or you may have conflicts with application-
+ * specific header files that you want to include together with these files.
+ * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
+ */
+
+#ifndef HAVE_BOOLEAN
+typedef char boolean;
+#endif
+#ifndef FALSE			/* in case these macros already exist */
+#define FALSE	0		/* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE	1
+#endif
+
+
+/*
+ * The remaining options affect code selection within the JPEG library,
+ * but they don't need to be visible to most applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+#define JPEG_INTERNAL_OPTIONS
+#endif
+
+#ifdef JPEG_INTERNAL_OPTIONS
+
+
+/*
+ * These defines indicate whether to include various optional functions.
+ * Undefining some of these symbols will produce a smaller but less capable
+ * library.  Note that you can leave certain source files out of the
+ * compilation/linking process if you've #undef'd the corresponding symbols.
+ * (You may HAVE to do that if your compiler doesn't like null source files.)
+ */
+
+/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
+
+/* Capability options common to encoder and decoder: */
+
+#define DCT_ISLOW_SUPPORTED	/* slow but accurate integer algorithm */
+#define DCT_IFAST_SUPPORTED	/* faster, less accurate integer method */
+#define DCT_FLOAT_SUPPORTED	/* floating-point: accurate, fast on fast HW */
+
+/* Encoder capability options: */
+
+#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
+#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
+#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
+/* Note: if you selected 12-bit data precision, it is dangerous to turn off
+ * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
+ * precision, so jchuff.c normally uses entropy optimization to compute
+ * usable tables for higher precision.  If you don't want to do optimization,
+ * you'll have to supply different default Huffman tables.
+ * The exact same statements apply for progressive JPEG: the default tables
+ * don't work for progressive mode.  (This may get fixed, however.)
+ */
+#define INPUT_SMOOTHING_SUPPORTED   /* Input image smoothing option? */
+
+/* Decoder capability options: */
+
+#undef  D_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
+#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define D_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
+#define SAVE_MARKERS_SUPPORTED	    /* jpeg_save_markers() needed? */
+#define BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
+#define IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */
+#undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
+#define UPSAMPLE_MERGING_SUPPORTED  /* Fast path for sloppy upsampling? */
+#define QUANT_1PASS_SUPPORTED	    /* 1-pass color quantization? */
+#define QUANT_2PASS_SUPPORTED	    /* 2-pass color quantization? */
+
+/* more capability options later, no doubt */
+
+
+/*
+ * Ordering of RGB data in scanlines passed to or from the application.
+ * If your application wants to deal with data in the order B,G,R, just
+ * change these macros.  You can also deal with formats such as R,G,B,X
+ * (one extra byte per pixel) by changing RGB_PIXELSIZE.  Note that changing
+ * the offsets will also change the order in which colormap data is organized.
+ * RESTRICTIONS:
+ * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
+ * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
+ *    useful if you are using JPEG color spaces other than YCbCr or grayscale.
+ * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
+ *    is not 3 (they don't understand about dummy color components!).  So you
+ *    can't use color quantization if you change that value.
+ */
+
+#define RGB_RED		0	/* Offset of Red in an RGB scanline element */
+#define RGB_GREEN	1	/* Offset of Green */
+#define RGB_BLUE	2	/* Offset of Blue */
+#define RGB_PIXELSIZE	3	/* JSAMPLEs per RGB scanline element */
+
+
+/* Definitions for speed-related optimizations. */
+
+
+/* If your compiler supports inline functions, define INLINE
+ * as the inline keyword; otherwise define it as empty.
+ */
+
+#ifndef INLINE
+#ifdef __GNUC__			/* for instance, GNU C knows about inline */
+#define INLINE __inline__
+#endif
+#ifndef INLINE
+#define INLINE			/* default is to define it as empty */
+#endif
+#endif
+
+
+/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
+ * two 16-bit shorts is faster than multiplying two ints.  Define MULTIPLIER
+ * as short on such a machine.  MULTIPLIER must be at least 16 bits wide.
+ */
+
+#ifndef MULTIPLIER
+#define MULTIPLIER  int		/* type for fastest integer multiply */
+#endif
+
+
+/* FAST_FLOAT should be either float or double, whichever is done faster
+ * by your compiler.  (Note that this type is only used in the floating point
+ * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
+ * Typically, float is faster in ANSI C compilers, while double is faster in
+ * pre-ANSI compilers (because they insist on converting to double anyway).
+ * The code below therefore chooses float if we have ANSI-style prototypes.
+ */
+
+#ifndef FAST_FLOAT
+#ifdef HAVE_PROTOTYPES
+#define FAST_FLOAT  float
+#else
+#define FAST_FLOAT  double
+#endif
+#endif
+
+#endif /* JPEG_INTERNAL_OPTIONS */
diff --git a/Utilities/FLTK/jpeg/jpegint.h b/Utilities/FLTK/jpeg/jpegint.h
new file mode 100644
index 0000000000000000000000000000000000000000..95b00d405caeca1dc971b37a94bbadc566f3074b
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jpegint.h
@@ -0,0 +1,392 @@
+/*
+ * jpegint.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file provides common declarations for the various JPEG modules.
+ * These declarations are considered internal to the JPEG library; most
+ * applications using the library shouldn't need to include this file.
+ */
+
+
+/* Declarations for both compression & decompression */
+
+typedef enum {			/* Operating modes for buffer controllers */
+	JBUF_PASS_THRU,		/* Plain stripwise operation */
+	/* Remaining modes require a full-image buffer to have been created */
+	JBUF_SAVE_SOURCE,	/* Run source subobject only, save output */
+	JBUF_CRANK_DEST,	/* Run dest subobject only, using saved data */
+	JBUF_SAVE_AND_PASS	/* Run both subobjects, save output */
+} J_BUF_MODE;
+
+/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
+#define CSTATE_START	100	/* after create_compress */
+#define CSTATE_SCANNING	101	/* start_compress done, write_scanlines OK */
+#define CSTATE_RAW_OK	102	/* start_compress done, write_raw_data OK */
+#define CSTATE_WRCOEFS	103	/* jpeg_write_coefficients done */
+#define DSTATE_START	200	/* after create_decompress */
+#define DSTATE_INHEADER	201	/* reading header markers, no SOS yet */
+#define DSTATE_READY	202	/* found SOS, ready for start_decompress */
+#define DSTATE_PRELOAD	203	/* reading multiscan file in start_decompress*/
+#define DSTATE_PRESCAN	204	/* performing dummy pass for 2-pass quant */
+#define DSTATE_SCANNING	205	/* start_decompress done, read_scanlines OK */
+#define DSTATE_RAW_OK	206	/* start_decompress done, read_raw_data OK */
+#define DSTATE_BUFIMAGE	207	/* expecting jpeg_start_output */
+#define DSTATE_BUFPOST	208	/* looking for SOS/EOI in jpeg_finish_output */
+#define DSTATE_RDCOEFS	209	/* reading file in jpeg_read_coefficients */
+#define DSTATE_STOPPING	210	/* looking for EOI in jpeg_finish_decompress */
+
+
+/* Declarations for compression modules */
+
+/* Master control module */
+struct jpeg_comp_master {
+  JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
+  JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
+  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
+
+  /* State variables made visible to other modules */
+  boolean call_pass_startup;	/* True if pass_startup must be called */
+  boolean is_last_pass;		/* True during last pass */
+};
+
+/* Main buffer control (downsampled-data buffer) */
+struct jpeg_c_main_controller {
+  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+  JMETHOD(void, process_data, (j_compress_ptr cinfo,
+			       JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+			       JDIMENSION in_rows_avail));
+};
+
+/* Compression preprocessing (downsampling input buffer control) */
+struct jpeg_c_prep_controller {
+  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+  JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
+				   JSAMPARRAY input_buf,
+				   JDIMENSION *in_row_ctr,
+				   JDIMENSION in_rows_avail,
+				   JSAMPIMAGE output_buf,
+				   JDIMENSION *out_row_group_ctr,
+				   JDIMENSION out_row_groups_avail));
+};
+
+/* Coefficient buffer control */
+struct jpeg_c_coef_controller {
+  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+  JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
+				   JSAMPIMAGE input_buf));
+};
+
+/* Colorspace conversion */
+struct jpeg_color_converter {
+  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
+  JMETHOD(void, color_convert, (j_compress_ptr cinfo,
+				JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+				JDIMENSION output_row, int num_rows));
+};
+
+/* Downsampling */
+struct jpeg_downsampler {
+  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
+  JMETHOD(void, downsample, (j_compress_ptr cinfo,
+			     JSAMPIMAGE input_buf, JDIMENSION in_row_index,
+			     JSAMPIMAGE output_buf,
+			     JDIMENSION out_row_group_index));
+
+  boolean need_context_rows;	/* TRUE if need rows above & below */
+};
+
+/* Forward DCT (also controls coefficient quantization) */
+struct jpeg_forward_dct {
+  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
+  /* perhaps this should be an array??? */
+  JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
+			      jpeg_component_info * compptr,
+			      JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+			      JDIMENSION start_row, JDIMENSION start_col,
+			      JDIMENSION num_blocks));
+};
+
+/* Entropy encoding */
+struct jpeg_entropy_encoder {
+  JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
+  JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
+  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
+};
+
+/* Marker writing */
+struct jpeg_marker_writer {
+  JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
+  JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
+  JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
+  JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
+  JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
+  /* These routines are exported to allow insertion of extra markers */
+  /* Probably only COM and APPn markers should be written this way */
+  JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
+				      unsigned int datalen));
+  JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
+};
+
+
+/* Declarations for decompression modules */
+
+/* Master control module */
+struct jpeg_decomp_master {
+  JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
+  JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
+
+  /* State variables made visible to other modules */
+  boolean is_dummy_pass;	/* True during 1st pass for 2-pass quant */
+};
+
+/* Input control module */
+struct jpeg_input_controller {
+  JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
+  JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
+  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
+  JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
+
+  /* State variables made visible to other modules */
+  boolean has_multiple_scans;	/* True if file has multiple scans */
+  boolean eoi_reached;		/* True when EOI has been consumed */
+};
+
+/* Main buffer control (downsampled-data buffer) */
+struct jpeg_d_main_controller {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
+  JMETHOD(void, process_data, (j_decompress_ptr cinfo,
+			       JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+			       JDIMENSION out_rows_avail));
+};
+
+/* Coefficient buffer control */
+struct jpeg_d_coef_controller {
+  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
+  JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
+  JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
+  JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
+				 JSAMPIMAGE output_buf));
+  /* Pointer to array of coefficient virtual arrays, or NULL if none */
+  jvirt_barray_ptr *coef_arrays;
+};
+
+/* Decompression postprocessing (color quantization buffer control) */
+struct jpeg_d_post_controller {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
+  JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
+				    JSAMPIMAGE input_buf,
+				    JDIMENSION *in_row_group_ctr,
+				    JDIMENSION in_row_groups_avail,
+				    JSAMPARRAY output_buf,
+				    JDIMENSION *out_row_ctr,
+				    JDIMENSION out_rows_avail));
+};
+
+/* Marker reading & parsing */
+struct jpeg_marker_reader {
+  JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
+  /* Read markers until SOS or EOI.
+   * Returns same codes as are defined for jpeg_consume_input:
+   * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+   */
+  JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
+  /* Read a restart marker --- exported for use by entropy decoder only */
+  jpeg_marker_parser_method read_restart_marker;
+
+  /* State of marker reader --- nominally internal, but applications
+   * supplying COM or APPn handlers might like to know the state.
+   */
+  boolean saw_SOI;		/* found SOI? */
+  boolean saw_SOF;		/* found SOF? */
+  int next_restart_num;		/* next restart number expected (0-7) */
+  unsigned int discarded_bytes;	/* # of bytes skipped looking for a marker */
+};
+
+/* Entropy decoding */
+struct jpeg_entropy_decoder {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+  JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
+				JBLOCKROW *MCU_data));
+
+  /* This is here to share code between baseline and progressive decoders; */
+  /* other modules probably should not use it */
+  boolean insufficient_data;	/* set TRUE after emitting warning */
+};
+
+/* Inverse DCT (also performs dequantization) */
+typedef JMETHOD(void, inverse_DCT_method_ptr,
+		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
+		 JCOEFPTR coef_block,
+		 JSAMPARRAY output_buf, JDIMENSION output_col));
+
+struct jpeg_inverse_dct {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+  /* It is useful to allow each component to have a separate IDCT method. */
+  inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
+};
+
+/* Upsampling (note that upsampler must also call color converter) */
+struct jpeg_upsampler {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+  JMETHOD(void, upsample, (j_decompress_ptr cinfo,
+			   JSAMPIMAGE input_buf,
+			   JDIMENSION *in_row_group_ctr,
+			   JDIMENSION in_row_groups_avail,
+			   JSAMPARRAY output_buf,
+			   JDIMENSION *out_row_ctr,
+			   JDIMENSION out_rows_avail));
+
+  boolean need_context_rows;	/* TRUE if need rows above & below */
+};
+
+/* Colorspace conversion */
+struct jpeg_color_deconverter {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+  JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
+				JSAMPIMAGE input_buf, JDIMENSION input_row,
+				JSAMPARRAY output_buf, int num_rows));
+};
+
+/* Color quantization or color precision reduction */
+struct jpeg_color_quantizer {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
+  JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
+				 JSAMPARRAY input_buf, JSAMPARRAY output_buf,
+				 int num_rows));
+  JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
+  JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
+};
+
+
+/* Miscellaneous useful macros */
+
+#undef MAX
+#define MAX(a,b)	((a) > (b) ? (a) : (b))
+#undef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+
+
+/* We assume that right shift corresponds to signed division by 2 with
+ * rounding towards minus infinity.  This is correct for typical "arithmetic
+ * shift" instructions that shift in copies of the sign bit.  But some
+ * C compilers implement >> with an unsigned shift.  For these machines you
+ * must define RIGHT_SHIFT_IS_UNSIGNED.
+ * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
+ * It is only applied with constant shift counts.  SHIFT_TEMPS must be
+ * included in the variables of any routine using RIGHT_SHIFT.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define SHIFT_TEMPS	INT32 shift_temp;
+#define RIGHT_SHIFT(x,shft)  \
+	((shift_temp = (x)) < 0 ? \
+	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
+	 (shift_temp >> (shft)))
+#else
+#define SHIFT_TEMPS
+#define RIGHT_SHIFT(x,shft)	((x) >> (shft))
+#endif
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jinit_compress_master	jICompress
+#define jinit_c_master_control	jICMaster
+#define jinit_c_main_controller	jICMainC
+#define jinit_c_prep_controller	jICPrepC
+#define jinit_c_coef_controller	jICCoefC
+#define jinit_color_converter	jICColor
+#define jinit_downsampler	jIDownsampler
+#define jinit_forward_dct	jIFDCT
+#define jinit_huff_encoder	jIHEncoder
+#define jinit_phuff_encoder	jIPHEncoder
+#define jinit_marker_writer	jIMWriter
+#define jinit_master_decompress	jIDMaster
+#define jinit_d_main_controller	jIDMainC
+#define jinit_d_coef_controller	jIDCoefC
+#define jinit_d_post_controller	jIDPostC
+#define jinit_input_controller	jIInCtlr
+#define jinit_marker_reader	jIMReader
+#define jinit_huff_decoder	jIHDecoder
+#define jinit_phuff_decoder	jIPHDecoder
+#define jinit_inverse_dct	jIIDCT
+#define jinit_upsampler		jIUpsampler
+#define jinit_color_deconverter	jIDColor
+#define jinit_1pass_quantizer	jI1Quant
+#define jinit_2pass_quantizer	jI2Quant
+#define jinit_merged_upsampler	jIMUpsampler
+#define jinit_memory_mgr	jIMemMgr
+#define jdiv_round_up		jDivRound
+#define jround_up		jRound
+#define jcopy_sample_rows	jCopySamples
+#define jcopy_block_row		jCopyBlocks
+#define jzero_far		jZeroFar
+#define jpeg_zigzag_order	jZIGTable
+#define jpeg_natural_order	jZAGTable
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Compression module initialization routines */
+EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
+					 boolean transcode_only));
+EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
+					  boolean need_full_buffer));
+EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
+					  boolean need_full_buffer));
+EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
+					  boolean need_full_buffer));
+EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
+/* Decompression module initialization routines */
+EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
+					  boolean need_full_buffer));
+EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
+					  boolean need_full_buffer));
+EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
+					  boolean need_full_buffer));
+EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
+/* Memory manager initialization */
+EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
+
+/* Utility routines in jutils.c */
+EXTERN(long) jdiv_round_up JPP((long a, long b));
+EXTERN(long) jround_up JPP((long a, long b));
+EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
+				    JSAMPARRAY output_array, int dest_row,
+				    int num_rows, JDIMENSION num_cols));
+EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
+				  JDIMENSION num_blocks));
+EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
+/* Constant tables in jutils.c */
+#if 0				/* This table is not actually needed in v6a */
+extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
+#endif
+extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
+
+/* Suppress undefined-structure complaints if necessary. */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef AM_MEMORY_MANAGER	/* only jmemmgr.c defines these */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+#endif
+#endif /* INCOMPLETE_TYPES_BROKEN */
diff --git a/Utilities/FLTK/jpeg/jpeglib.h b/Utilities/FLTK/jpeg/jpeglib.h
new file mode 100644
index 0000000000000000000000000000000000000000..d1be8ddeff1bfee59f56d3ea04379f4b6f4d1c0e
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jpeglib.h
@@ -0,0 +1,1096 @@
+/*
+ * jpeglib.h
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the application interface for the JPEG library.
+ * Most applications using the library need only include this file,
+ * and perhaps jerror.h if they want to know the exact error codes.
+ */
+
+#ifndef JPEGLIB_H
+#define JPEGLIB_H
+
+/*
+ * First we include the configuration files that record how this
+ * installation of the JPEG library is set up.  jconfig.h can be
+ * generated automatically for many systems.  jmorecfg.h contains
+ * manual configuration options that most people need not worry about.
+ */
+
+#ifndef JCONFIG_INCLUDED	/* in case jinclude.h already did */
+#include "jconfig.h"		/* widely used configuration options */
+#endif
+#include "jmorecfg.h"		/* seldom changed options */
+
+
+/* Version ID for the JPEG library.
+ * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
+ */
+
+#define JPEG_LIB_VERSION  62	/* Version 6b */
+
+
+/* Various constants determining the sizes of things.
+ * All of these are specified by the JPEG standard, so don't change them
+ * if you want to be compatible.
+ */
+
+#define DCTSIZE		    8	/* The basic DCT block is 8x8 samples */
+#define DCTSIZE2	    64	/* DCTSIZE squared; # of elements in a block */
+#define NUM_QUANT_TBLS      4	/* Quantization tables are numbered 0..3 */
+#define NUM_HUFF_TBLS       4	/* Huffman tables are numbered 0..3 */
+#define NUM_ARITH_TBLS      16	/* Arith-coding tables are numbered 0..15 */
+#define MAX_COMPS_IN_SCAN   4	/* JPEG limit on # of components in one scan */
+#define MAX_SAMP_FACTOR     4	/* JPEG limit on sampling factors */
+/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
+ * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
+ * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
+ * to handle it.  We even let you do this from the jconfig.h file.  However,
+ * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
+ * sometimes emits noncompliant files doesn't mean you should too.
+ */
+#define C_MAX_BLOCKS_IN_MCU   10 /* compressor's limit on blocks per MCU */
+#ifndef D_MAX_BLOCKS_IN_MCU
+#define D_MAX_BLOCKS_IN_MCU   10 /* decompressor's limit on blocks per MCU */
+#endif
+
+
+/* Data structures for images (arrays of samples and of DCT coefficients).
+ * On 80x86 machines, the image arrays are too big for near pointers,
+ * but the pointer arrays can fit in near memory.
+ */
+
+typedef JSAMPLE FAR *JSAMPROW;	/* ptr to one image row of pixel samples. */
+typedef JSAMPROW *JSAMPARRAY;	/* ptr to some rows (a 2-D sample array) */
+typedef JSAMPARRAY *JSAMPIMAGE;	/* a 3-D sample array: top index is color */
+
+typedef JCOEF JBLOCK[DCTSIZE2];	/* one block of coefficients */
+typedef JBLOCK FAR *JBLOCKROW;	/* pointer to one row of coefficient blocks */
+typedef JBLOCKROW *JBLOCKARRAY;		/* a 2-D array of coefficient blocks */
+typedef JBLOCKARRAY *JBLOCKIMAGE;	/* a 3-D array of coefficient blocks */
+
+typedef JCOEF FAR *JCOEFPTR;	/* useful in a couple of places */
+
+
+/* Types for JPEG compression parameters and working tables. */
+
+
+/* DCT coefficient quantization tables. */
+
+typedef struct {
+  /* This array gives the coefficient quantizers in natural array order
+   * (not the zigzag order in which they are stored in a JPEG DQT marker).
+   * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
+   */
+  UINT16 quantval[DCTSIZE2];	/* quantization step for each coefficient */
+  /* This field is used only during compression.  It's initialized FALSE when
+   * the table is created, and set TRUE when it's been output to the file.
+   * You could suppress output of a table by setting this to TRUE.
+   * (See jpeg_suppress_tables for an example.)
+   */
+  boolean sent_table;		/* TRUE when table has been output */
+} JQUANT_TBL;
+
+
+/* Huffman coding tables. */
+
+typedef struct {
+  /* These two fields directly represent the contents of a JPEG DHT marker */
+  UINT8 bits[17];		/* bits[k] = # of symbols with codes of */
+				/* length k bits; bits[0] is unused */
+  UINT8 huffval[256];		/* The symbols, in order of incr code length */
+  /* This field is used only during compression.  It's initialized FALSE when
+   * the table is created, and set TRUE when it's been output to the file.
+   * You could suppress output of a table by setting this to TRUE.
+   * (See jpeg_suppress_tables for an example.)
+   */
+  boolean sent_table;		/* TRUE when table has been output */
+} JHUFF_TBL;
+
+
+/* Basic info about one component (color channel). */
+
+typedef struct {
+  /* These values are fixed over the whole image. */
+  /* For compression, they must be supplied by parameter setup; */
+  /* for decompression, they are read from the SOF marker. */
+  int component_id;		/* identifier for this component (0..255) */
+  int component_index;		/* its index in SOF or cinfo->comp_info[] */
+  int h_samp_factor;		/* horizontal sampling factor (1..4) */
+  int v_samp_factor;		/* vertical sampling factor (1..4) */
+  int quant_tbl_no;		/* quantization table selector (0..3) */
+  /* These values may vary between scans. */
+  /* For compression, they must be supplied by parameter setup; */
+  /* for decompression, they are read from the SOS marker. */
+  /* The decompressor output side may not use these variables. */
+  int dc_tbl_no;		/* DC entropy table selector (0..3) */
+  int ac_tbl_no;		/* AC entropy table selector (0..3) */
+  
+  /* Remaining fields should be treated as private by applications. */
+  
+  /* These values are computed during compression or decompression startup: */
+  /* Component's size in DCT blocks.
+   * Any dummy blocks added to complete an MCU are not counted; therefore
+   * these values do not depend on whether a scan is interleaved or not.
+   */
+  JDIMENSION width_in_blocks;
+  JDIMENSION height_in_blocks;
+  /* Size of a DCT block in samples.  Always DCTSIZE for compression.
+   * For decompression this is the size of the output from one DCT block,
+   * reflecting any scaling we choose to apply during the IDCT step.
+   * Values of 1,2,4,8 are likely to be supported.  Note that different
+   * components may receive different IDCT scalings.
+   */
+  int DCT_scaled_size;
+  /* The downsampled dimensions are the component's actual, unpadded number
+   * of samples at the main buffer (preprocessing/compression interface), thus
+   * downsampled_width = ceil(image_width * Hi/Hmax)
+   * and similarly for height.  For decompression, IDCT scaling is included, so
+   * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
+   */
+  JDIMENSION downsampled_width;	 /* actual width in samples */
+  JDIMENSION downsampled_height; /* actual height in samples */
+  /* This flag is used only for decompression.  In cases where some of the
+   * components will be ignored (eg grayscale output from YCbCr image),
+   * we can skip most computations for the unused components.
+   */
+  boolean component_needed;	/* do we need the value of this component? */
+
+  /* These values are computed before starting a scan of the component. */
+  /* The decompressor output side may not use these variables. */
+  int MCU_width;		/* number of blocks per MCU, horizontally */
+  int MCU_height;		/* number of blocks per MCU, vertically */
+  int MCU_blocks;		/* MCU_width * MCU_height */
+  int MCU_sample_width;		/* MCU width in samples, MCU_width*DCT_scaled_size */
+  int last_col_width;		/* # of non-dummy blocks across in last MCU */
+  int last_row_height;		/* # of non-dummy blocks down in last MCU */
+
+  /* Saved quantization table for component; NULL if none yet saved.
+   * See jdinput.c comments about the need for this information.
+   * This field is currently used only for decompression.
+   */
+  JQUANT_TBL * quant_table;
+
+  /* Private per-component storage for DCT or IDCT subsystem. */
+  void * dct_table;
+} jpeg_component_info;
+
+
+/* The script for encoding a multiple-scan file is an array of these: */
+
+typedef struct {
+  int comps_in_scan;		/* number of components encoded in this scan */
+  int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
+  int Ss, Se;			/* progressive JPEG spectral selection parms */
+  int Ah, Al;			/* progressive JPEG successive approx. parms */
+} jpeg_scan_info;
+
+/* The decompressor can save APPn and COM markers in a list of these: */
+
+typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
+
+struct jpeg_marker_struct {
+  jpeg_saved_marker_ptr next;	/* next in list, or NULL */
+  UINT8 marker;			/* marker code: JPEG_COM, or JPEG_APP0+n */
+  unsigned int original_length;	/* # bytes of data in the file */
+  unsigned int data_length;	/* # bytes of data saved at data[] */
+  JOCTET FAR * data;		/* the data contained in the marker */
+  /* the marker length word is not counted in data_length or original_length */
+};
+
+/* Known color spaces. */
+
+typedef enum {
+	JCS_UNKNOWN,		/* error/unspecified */
+	JCS_GRAYSCALE,		/* monochrome */
+	JCS_RGB,		/* red/green/blue */
+	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV) */
+	JCS_CMYK,		/* C/M/Y/K */
+	JCS_YCCK		/* Y/Cb/Cr/K */
+} J_COLOR_SPACE;
+
+/* DCT/IDCT algorithm options. */
+
+typedef enum {
+	JDCT_ISLOW,		/* slow but accurate integer algorithm */
+	JDCT_IFAST,		/* faster, less accurate integer method */
+	JDCT_FLOAT		/* floating-point: accurate, fast on fast HW */
+} J_DCT_METHOD;
+
+#ifndef JDCT_DEFAULT		/* may be overridden in jconfig.h */
+#define JDCT_DEFAULT  JDCT_ISLOW
+#endif
+#ifndef JDCT_FASTEST		/* may be overridden in jconfig.h */
+#define JDCT_FASTEST  JDCT_IFAST
+#endif
+
+/* Dithering options for decompression. */
+
+typedef enum {
+	JDITHER_NONE,		/* no dithering */
+	JDITHER_ORDERED,	/* simple ordered dither */
+	JDITHER_FS		/* Floyd-Steinberg error diffusion dither */
+} J_DITHER_MODE;
+
+
+/* Common fields between JPEG compression and decompression master structs. */
+
+#define jpeg_common_fields \
+  struct jpeg_error_mgr * err;	/* Error handler module */\
+  struct jpeg_memory_mgr * mem;	/* Memory manager module */\
+  struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
+  void * client_data;		/* Available for use by application */\
+  boolean is_decompressor;	/* So common code can tell which is which */\
+  int global_state		/* For checking call sequence validity */
+
+/* Routines that are to be used by both halves of the library are declared
+ * to receive a pointer to this structure.  There are no actual instances of
+ * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
+ */
+struct jpeg_common_struct {
+  jpeg_common_fields;		/* Fields common to both master struct types */
+  /* Additional fields follow in an actual jpeg_compress_struct or
+   * jpeg_decompress_struct.  All three structs must agree on these
+   * initial fields!  (This would be a lot cleaner in C++.)
+   */
+};
+
+typedef struct jpeg_common_struct * j_common_ptr;
+typedef struct jpeg_compress_struct * j_compress_ptr;
+typedef struct jpeg_decompress_struct * j_decompress_ptr;
+
+
+/* Master record for a compression instance */
+
+struct jpeg_compress_struct {
+  jpeg_common_fields;		/* Fields shared with jpeg_decompress_struct */
+
+  /* Destination for compressed data */
+  struct jpeg_destination_mgr * dest;
+
+  /* Description of source image --- these fields must be filled in by
+   * outer application before starting compression.  in_color_space must
+   * be correct before you can even call jpeg_set_defaults().
+   */
+
+  JDIMENSION image_width;	/* input image width */
+  JDIMENSION image_height;	/* input image height */
+  int input_components;		/* # of color components in input image */
+  J_COLOR_SPACE in_color_space;	/* colorspace of input image */
+
+  double input_gamma;		/* image gamma of input image */
+
+  /* Compression parameters --- these fields must be set before calling
+   * jpeg_start_compress().  We recommend calling jpeg_set_defaults() to
+   * initialize everything to reasonable defaults, then changing anything
+   * the application specifically wants to change.  That way you won't get
+   * burnt when new parameters are added.  Also note that there are several
+   * helper routines to simplify changing parameters.
+   */
+
+  int data_precision;		/* bits of precision in image data */
+
+  int num_components;		/* # of color components in JPEG image */
+  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+  jpeg_component_info * comp_info;
+  /* comp_info[i] describes component that appears i'th in SOF */
+  
+  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
+  /* ptrs to coefficient quantization tables, or NULL if not defined */
+  
+  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+  /* ptrs to Huffman coding tables, or NULL if not defined */
+  
+  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+  int num_scans;		/* # of entries in scan_info array */
+  const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
+  /* The default value of scan_info is NULL, which causes a single-scan
+   * sequential JPEG file to be emitted.  To create a multi-scan file,
+   * set num_scans and scan_info to point to an array of scan definitions.
+   */
+
+  boolean raw_data_in;		/* TRUE=caller supplies downsampled data */
+  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */
+  boolean optimize_coding;	/* TRUE=optimize entropy encoding parms */
+  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
+  int smoothing_factor;		/* 1..100, or 0 for no input smoothing */
+  J_DCT_METHOD dct_method;	/* DCT algorithm selector */
+
+  /* The restart interval can be specified in absolute MCUs by setting
+   * restart_interval, or in MCU rows by setting restart_in_rows
+   * (in which case the correct restart_interval will be figured
+   * for each scan).
+   */
+  unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
+  int restart_in_rows;		/* if > 0, MCU rows per restart interval */
+
+  /* Parameters controlling emission of special markers. */
+
+  boolean write_JFIF_header;	/* should a JFIF marker be written? */
+  UINT8 JFIF_major_version;	/* What to write for the JFIF version number */
+  UINT8 JFIF_minor_version;
+  /* These three values are not used by the JPEG code, merely copied */
+  /* into the JFIF APP0 marker.  density_unit can be 0 for unknown, */
+  /* 1 for dots/inch, or 2 for dots/cm.  Note that the pixel aspect */
+  /* ratio is defined by X_density/Y_density even when density_unit=0. */
+  UINT8 density_unit;		/* JFIF code for pixel size units */
+  UINT16 X_density;		/* Horizontal pixel density */
+  UINT16 Y_density;		/* Vertical pixel density */
+  boolean write_Adobe_marker;	/* should an Adobe marker be written? */
+  
+  /* State variable: index of next scanline to be written to
+   * jpeg_write_scanlines().  Application may use this to control its
+   * processing loop, e.g., "while (next_scanline < image_height)".
+   */
+
+  JDIMENSION next_scanline;	/* 0 .. image_height-1  */
+
+  /* Remaining fields are known throughout compressor, but generally
+   * should not be touched by a surrounding application.
+   */
+
+  /*
+   * These fields are computed during compression startup
+   */
+  boolean progressive_mode;	/* TRUE if scan script uses progressive mode */
+  int max_h_samp_factor;	/* largest h_samp_factor */
+  int max_v_samp_factor;	/* largest v_samp_factor */
+
+  JDIMENSION total_iMCU_rows;	/* # of iMCU rows to be input to coef ctlr */
+  /* The coefficient controller receives data in units of MCU rows as defined
+   * for fully interleaved scans (whether the JPEG file is interleaved or not).
+   * There are v_samp_factor * DCTSIZE sample rows of each component in an
+   * "iMCU" (interleaved MCU) row.
+   */
+  
+  /*
+   * These fields are valid during any one scan.
+   * They describe the components and MCUs actually appearing in the scan.
+   */
+  int comps_in_scan;		/* # of JPEG components in this scan */
+  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+  /* *cur_comp_info[i] describes component that appears i'th in SOS */
+  
+  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */
+  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */
+  
+  int blocks_in_MCU;		/* # of DCT blocks per MCU */
+  int MCU_membership[C_MAX_BLOCKS_IN_MCU];
+  /* MCU_membership[i] is index in cur_comp_info of component owning */
+  /* i'th block in an MCU */
+
+  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */
+
+  /*
+   * Links to compression subobjects (methods and private variables of modules)
+   */
+  struct jpeg_comp_master * master;
+  struct jpeg_c_main_controller * main;
+  struct jpeg_c_prep_controller * prep;
+  struct jpeg_c_coef_controller * coef;
+  struct jpeg_marker_writer * marker;
+  struct jpeg_color_converter * cconvert;
+  struct jpeg_downsampler * downsample;
+  struct jpeg_forward_dct * fdct;
+  struct jpeg_entropy_encoder * entropy;
+  jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
+  int script_space_size;
+};
+
+
+/* Master record for a decompression instance */
+
+struct jpeg_decompress_struct {
+  jpeg_common_fields;		/* Fields shared with jpeg_compress_struct */
+
+  /* Source of compressed data */
+  struct jpeg_source_mgr * src;
+
+  /* Basic description of image --- filled in by jpeg_read_header(). */
+  /* Application may inspect these values to decide how to process image. */
+
+  JDIMENSION image_width;	/* nominal image width (from SOF marker) */
+  JDIMENSION image_height;	/* nominal image height */
+  int num_components;		/* # of color components in JPEG image */
+  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+  /* Decompression processing parameters --- these fields must be set before
+   * calling jpeg_start_decompress().  Note that jpeg_read_header() initializes
+   * them to default values.
+   */
+
+  J_COLOR_SPACE out_color_space; /* colorspace for output */
+
+  unsigned int scale_num, scale_denom; /* fraction by which to scale image */
+
+  double output_gamma;		/* image gamma wanted in output */
+
+  boolean buffered_image;	/* TRUE=multiple output passes */
+  boolean raw_data_out;		/* TRUE=downsampled data wanted */
+
+  J_DCT_METHOD dct_method;	/* IDCT algorithm selector */
+  boolean do_fancy_upsampling;	/* TRUE=apply fancy upsampling */
+  boolean do_block_smoothing;	/* TRUE=apply interblock smoothing */
+
+  boolean quantize_colors;	/* TRUE=colormapped output wanted */
+  /* the following are ignored if not quantize_colors: */
+  J_DITHER_MODE dither_mode;	/* type of color dithering to use */
+  boolean two_pass_quantize;	/* TRUE=use two-pass color quantization */
+  int desired_number_of_colors;	/* max # colors to use in created colormap */
+  /* these are significant only in buffered-image mode: */
+  boolean enable_1pass_quant;	/* enable future use of 1-pass quantizer */
+  boolean enable_external_quant;/* enable future use of external colormap */
+  boolean enable_2pass_quant;	/* enable future use of 2-pass quantizer */
+
+  /* Description of actual output image that will be returned to application.
+   * These fields are computed by jpeg_start_decompress().
+   * You can also use jpeg_calc_output_dimensions() to determine these values
+   * in advance of calling jpeg_start_decompress().
+   */
+
+  JDIMENSION output_width;	/* scaled image width */
+  JDIMENSION output_height;	/* scaled image height */
+  int out_color_components;	/* # of color components in out_color_space */
+  int output_components;	/* # of color components returned */
+  /* output_components is 1 (a colormap index) when quantizing colors;
+   * otherwise it equals out_color_components.
+   */
+  int rec_outbuf_height;	/* min recommended height of scanline buffer */
+  /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
+   * high, space and time will be wasted due to unnecessary data copying.
+   * Usually rec_outbuf_height will be 1 or 2, at most 4.
+   */
+
+  /* When quantizing colors, the output colormap is described by these fields.
+   * The application can supply a colormap by setting colormap non-NULL before
+   * calling jpeg_start_decompress; otherwise a colormap is created during
+   * jpeg_start_decompress or jpeg_start_output.
+   * The map has out_color_components rows and actual_number_of_colors columns.
+   */
+  int actual_number_of_colors;	/* number of entries in use */
+  JSAMPARRAY colormap;		/* The color map as a 2-D pixel array */
+
+  /* State variables: these variables indicate the progress of decompression.
+   * The application may examine these but must not modify them.
+   */
+
+  /* Row index of next scanline to be read from jpeg_read_scanlines().
+   * Application may use this to control its processing loop, e.g.,
+   * "while (output_scanline < output_height)".
+   */
+  JDIMENSION output_scanline;	/* 0 .. output_height-1  */
+
+  /* Current input scan number and number of iMCU rows completed in scan.
+   * These indicate the progress of the decompressor input side.
+   */
+  int input_scan_number;	/* Number of SOS markers seen so far */
+  JDIMENSION input_iMCU_row;	/* Number of iMCU rows completed */
+
+  /* The "output scan number" is the notional scan being displayed by the
+   * output side.  The decompressor will not allow output scan/row number
+   * to get ahead of input scan/row, but it can fall arbitrarily far behind.
+   */
+  int output_scan_number;	/* Nominal scan number being displayed */
+  JDIMENSION output_iMCU_row;	/* Number of iMCU rows read */
+
+  /* Current progression status.  coef_bits[c][i] indicates the precision
+   * with which component c's DCT coefficient i (in zigzag order) is known.
+   * It is -1 when no data has yet been received, otherwise it is the point
+   * transform (shift) value for the most recent scan of the coefficient
+   * (thus, 0 at completion of the progression).
+   * This pointer is NULL when reading a non-progressive file.
+   */
+  int (*coef_bits)[DCTSIZE2];	/* -1 or current Al value for each coef */
+
+  /* Internal JPEG parameters --- the application usually need not look at
+   * these fields.  Note that the decompressor output side may not use
+   * any parameters that can change between scans.
+   */
+
+  /* Quantization and Huffman tables are carried forward across input
+   * datastreams when processing abbreviated JPEG datastreams.
+   */
+
+  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
+  /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+  /* ptrs to Huffman coding tables, or NULL if not defined */
+
+  /* These parameters are never carried across datastreams, since they
+   * are given in SOF/SOS markers or defined to be reset by SOI.
+   */
+
+  int data_precision;		/* bits of precision in image data */
+
+  jpeg_component_info * comp_info;
+  /* comp_info[i] describes component that appears i'th in SOF */
+
+  boolean progressive_mode;	/* TRUE if SOFn specifies progressive mode */
+  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */
+
+  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+  unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
+
+  /* These fields record data obtained from optional markers recognized by
+   * the JPEG library.
+   */
+  boolean saw_JFIF_marker;	/* TRUE iff a JFIF APP0 marker was found */
+  /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
+  UINT8 JFIF_major_version;	/* JFIF version number */
+  UINT8 JFIF_minor_version;
+  UINT8 density_unit;		/* JFIF code for pixel size units */
+  UINT16 X_density;		/* Horizontal pixel density */
+  UINT16 Y_density;		/* Vertical pixel density */
+  boolean saw_Adobe_marker;	/* TRUE iff an Adobe APP14 marker was found */
+  UINT8 Adobe_transform;	/* Color transform code from Adobe marker */
+
+  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
+
+  /* Aside from the specific data retained from APPn markers known to the
+   * library, the uninterpreted contents of any or all APPn and COM markers
+   * can be saved in a list for examination by the application.
+   */
+  jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
+
+  /* Remaining fields are known throughout decompressor, but generally
+   * should not be touched by a surrounding application.
+   */
+
+  /*
+   * These fields are computed during decompression startup
+   */
+  int max_h_samp_factor;	/* largest h_samp_factor */
+  int max_v_samp_factor;	/* largest v_samp_factor */
+
+  int min_DCT_scaled_size;	/* smallest DCT_scaled_size of any component */
+
+  JDIMENSION total_iMCU_rows;	/* # of iMCU rows in image */
+  /* The coefficient controller's input and output progress is measured in
+   * units of "iMCU" (interleaved MCU) rows.  These are the same as MCU rows
+   * in fully interleaved JPEG scans, but are used whether the scan is
+   * interleaved or not.  We define an iMCU row as v_samp_factor DCT block
+   * rows of each component.  Therefore, the IDCT output contains
+   * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
+   */
+
+  JSAMPLE * sample_range_limit; /* table for fast range-limiting */
+
+  /*
+   * These fields are valid during any one scan.
+   * They describe the components and MCUs actually appearing in the scan.
+   * Note that the decompressor output side must not use these fields.
+   */
+  int comps_in_scan;		/* # of JPEG components in this scan */
+  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+  /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */
+  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */
+
+  int blocks_in_MCU;		/* # of DCT blocks per MCU */
+  int MCU_membership[D_MAX_BLOCKS_IN_MCU];
+  /* MCU_membership[i] is index in cur_comp_info of component owning */
+  /* i'th block in an MCU */
+
+  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */
+
+  /* This field is shared between entropy decoder and marker parser.
+   * It is either zero or the code of a JPEG marker that has been
+   * read from the data source, but has not yet been processed.
+   */
+  int unread_marker;
+
+  /*
+   * Links to decompression subobjects (methods, private variables of modules)
+   */
+  struct jpeg_decomp_master * master;
+  struct jpeg_d_main_controller * main;
+  struct jpeg_d_coef_controller * coef;
+  struct jpeg_d_post_controller * post;
+  struct jpeg_input_controller * inputctl;
+  struct jpeg_marker_reader * marker;
+  struct jpeg_entropy_decoder * entropy;
+  struct jpeg_inverse_dct * idct;
+  struct jpeg_upsampler * upsample;
+  struct jpeg_color_deconverter * cconvert;
+  struct jpeg_color_quantizer * cquantize;
+};
+
+
+/* "Object" declarations for JPEG modules that may be supplied or called
+ * directly by the surrounding application.
+ * As with all objects in the JPEG library, these structs only define the
+ * publicly visible methods and state variables of a module.  Additional
+ * private fields may exist after the public ones.
+ */
+
+
+/* Error handler object */
+
+struct jpeg_error_mgr {
+  /* Error exit handler: does not return to caller */
+  JMETHOD(void, error_exit, (j_common_ptr cinfo));
+  /* Conditionally emit a trace or warning message */
+  JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
+  /* Routine that actually outputs a trace or error message */
+  JMETHOD(void, output_message, (j_common_ptr cinfo));
+  /* Format a message string for the most recent JPEG error or message */
+  JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
+#define JMSG_LENGTH_MAX  200	/* recommended size of format_message buffer */
+  /* Reset error state variables at start of a new image */
+  JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
+  
+  /* The message ID code and any parameters are saved here.
+   * A message can have one string parameter or up to 8 int parameters.
+   */
+  int msg_code;
+#define JMSG_STR_PARM_MAX  80
+  union {
+    int i[8];
+    char s[JMSG_STR_PARM_MAX];
+  } msg_parm;
+  
+  /* Standard state variables for error facility */
+  
+  int trace_level;		/* max msg_level that will be displayed */
+  
+  /* For recoverable corrupt-data errors, we emit a warning message,
+   * but keep going unless emit_message chooses to abort.  emit_message
+   * should count warnings in num_warnings.  The surrounding application
+   * can check for bad data by seeing if num_warnings is nonzero at the
+   * end of processing.
+   */
+  long num_warnings;		/* number of corrupt-data warnings */
+
+  /* These fields point to the table(s) of error message strings.
+   * An application can change the table pointer to switch to a different
+   * message list (typically, to change the language in which errors are
+   * reported).  Some applications may wish to add additional error codes
+   * that will be handled by the JPEG library error mechanism; the second
+   * table pointer is used for this purpose.
+   *
+   * First table includes all errors generated by JPEG library itself.
+   * Error code 0 is reserved for a "no such error string" message.
+   */
+  const char * const * jpeg_message_table; /* Library errors */
+  int last_jpeg_message;    /* Table contains strings 0..last_jpeg_message */
+  /* Second table can be added by application (see cjpeg/djpeg for example).
+   * It contains strings numbered first_addon_message..last_addon_message.
+   */
+  const char * const * addon_message_table; /* Non-library errors */
+  int first_addon_message;	/* code for first string in addon table */
+  int last_addon_message;	/* code for last string in addon table */
+};
+
+
+/* Progress monitor object */
+
+struct jpeg_progress_mgr {
+  JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
+
+  long pass_counter;		/* work units completed in this pass */
+  long pass_limit;		/* total number of work units in this pass */
+  int completed_passes;		/* passes completed so far */
+  int total_passes;		/* total number of passes expected */
+};
+
+
+/* Data destination object for compression */
+
+struct jpeg_destination_mgr {
+  JOCTET * next_output_byte;	/* => next byte to write in buffer */
+  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */
+
+  JMETHOD(void, init_destination, (j_compress_ptr cinfo));
+  JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
+  JMETHOD(void, term_destination, (j_compress_ptr cinfo));
+};
+
+
+/* Data source object for decompression */
+
+struct jpeg_source_mgr {
+  const JOCTET * next_input_byte; /* => next byte to read from buffer */
+  size_t bytes_in_buffer;	/* # of bytes remaining in buffer */
+
+  JMETHOD(void, init_source, (j_decompress_ptr cinfo));
+  JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
+  JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
+  JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
+  JMETHOD(void, term_source, (j_decompress_ptr cinfo));
+};
+
+
+/* Memory manager object.
+ * Allocates "small" objects (a few K total), "large" objects (tens of K),
+ * and "really big" objects (virtual arrays with backing store if needed).
+ * The memory manager does not allow individual objects to be freed; rather,
+ * each created object is assigned to a pool, and whole pools can be freed
+ * at once.  This is faster and more convenient than remembering exactly what
+ * to free, especially where malloc()/free() are not too speedy.
+ * NB: alloc routines never return NULL.  They exit to error_exit if not
+ * successful.
+ */
+
+#define JPOOL_PERMANENT	0	/* lasts until master record is destroyed */
+#define JPOOL_IMAGE	1	/* lasts until done with image/datastream */
+#define JPOOL_NUMPOOLS	2
+
+typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
+typedef struct jvirt_barray_control * jvirt_barray_ptr;
+
+
+struct jpeg_memory_mgr {
+  /* Method pointers */
+  JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
+				size_t sizeofobject));
+  JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
+				     size_t sizeofobject));
+  JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
+				     JDIMENSION samplesperrow,
+				     JDIMENSION numrows));
+  JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
+				      JDIMENSION blocksperrow,
+				      JDIMENSION numrows));
+  JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
+						  int pool_id,
+						  boolean pre_zero,
+						  JDIMENSION samplesperrow,
+						  JDIMENSION numrows,
+						  JDIMENSION maxaccess));
+  JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
+						  int pool_id,
+						  boolean pre_zero,
+						  JDIMENSION blocksperrow,
+						  JDIMENSION numrows,
+						  JDIMENSION maxaccess));
+  JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
+  JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
+					   jvirt_sarray_ptr ptr,
+					   JDIMENSION start_row,
+					   JDIMENSION num_rows,
+					   boolean writable));
+  JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
+					    jvirt_barray_ptr ptr,
+					    JDIMENSION start_row,
+					    JDIMENSION num_rows,
+					    boolean writable));
+  JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
+  JMETHOD(void, self_destruct, (j_common_ptr cinfo));
+
+  /* Limit on memory allocation for this JPEG object.  (Note that this is
+   * merely advisory, not a guaranteed maximum; it only affects the space
+   * used for virtual-array buffers.)  May be changed by outer application
+   * after creating the JPEG object.
+   */
+  long max_memory_to_use;
+
+  /* Maximum allocation request accepted by alloc_large. */
+  long max_alloc_chunk;
+};
+
+
+/* Routine signature for application-supplied marker processing methods.
+ * Need not pass marker code since it is stored in cinfo->unread_marker.
+ */
+typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
+
+
+/* Declarations for routines called by application.
+ * The JPP macro hides prototype parameters from compilers that can't cope.
+ * Note JPP requires double parentheses.
+ */
+
+#ifdef HAVE_PROTOTYPES
+#define JPP(arglist)	arglist
+#else
+#define JPP(arglist)	()
+#endif
+
+
+/* Short forms of external names for systems with brain-damaged linkers.
+ * We shorten external names to be unique in the first six letters, which
+ * is good enough for all known systems.
+ * (If your compiler itself needs names to be unique in less than 15 
+ * characters, you are out of luck.  Get a better compiler.)
+ */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_std_error		jStdError
+#define jpeg_CreateCompress	jCreaCompress
+#define jpeg_CreateDecompress	jCreaDecompress
+#define jpeg_destroy_compress	jDestCompress
+#define jpeg_destroy_decompress	jDestDecompress
+#define jpeg_stdio_dest		jStdDest
+#define jpeg_stdio_src		jStdSrc
+#define jpeg_set_defaults	jSetDefaults
+#define jpeg_set_colorspace	jSetColorspace
+#define jpeg_default_colorspace	jDefColorspace
+#define jpeg_set_quality	jSetQuality
+#define jpeg_set_linear_quality	jSetLQuality
+#define jpeg_add_quant_table	jAddQuantTable
+#define jpeg_quality_scaling	jQualityScaling
+#define jpeg_simple_progression	jSimProgress
+#define jpeg_suppress_tables	jSuppressTables
+#define jpeg_alloc_quant_table	jAlcQTable
+#define jpeg_alloc_huff_table	jAlcHTable
+#define jpeg_start_compress	jStrtCompress
+#define jpeg_write_scanlines	jWrtScanlines
+#define jpeg_finish_compress	jFinCompress
+#define jpeg_write_raw_data	jWrtRawData
+#define jpeg_write_marker	jWrtMarker
+#define jpeg_write_m_header	jWrtMHeader
+#define jpeg_write_m_byte	jWrtMByte
+#define jpeg_write_tables	jWrtTables
+#define jpeg_read_header	jReadHeader
+#define jpeg_start_decompress	jStrtDecompress
+#define jpeg_read_scanlines	jReadScanlines
+#define jpeg_finish_decompress	jFinDecompress
+#define jpeg_read_raw_data	jReadRawData
+#define jpeg_has_multiple_scans	jHasMultScn
+#define jpeg_start_output	jStrtOutput
+#define jpeg_finish_output	jFinOutput
+#define jpeg_input_complete	jInComplete
+#define jpeg_new_colormap	jNewCMap
+#define jpeg_consume_input	jConsumeInput
+#define jpeg_calc_output_dimensions	jCalcDimensions
+#define jpeg_save_markers	jSaveMarkers
+#define jpeg_set_marker_processor	jSetMarker
+#define jpeg_read_coefficients	jReadCoefs
+#define jpeg_write_coefficients	jWrtCoefs
+#define jpeg_copy_critical_parameters	jCopyCrit
+#define jpeg_abort_compress	jAbrtCompress
+#define jpeg_abort_decompress	jAbrtDecompress
+#define jpeg_abort		jAbort
+#define jpeg_destroy		jDestroy
+#define jpeg_resync_to_restart	jResyncRestart
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Default error-management setup */
+EXTERN(struct jpeg_error_mgr *) jpeg_std_error
+	JPP((struct jpeg_error_mgr * err));
+
+/* Initialization of JPEG compression objects.
+ * jpeg_create_compress() and jpeg_create_decompress() are the exported
+ * names that applications should call.  These expand to calls on
+ * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
+ * passed for version mismatch checking.
+ * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
+ */
+#define jpeg_create_compress(cinfo) \
+    jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
+			(size_t) sizeof(struct jpeg_compress_struct))
+#define jpeg_create_decompress(cinfo) \
+    jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
+			  (size_t) sizeof(struct jpeg_decompress_struct))
+EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
+				      int version, size_t structsize));
+EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
+					int version, size_t structsize));
+/* Destruction of JPEG compression objects */
+EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
+
+/* Standard data source and destination managers: stdio streams. */
+/* Caller is responsible for opening the file before and closing after. */
+EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
+EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
+
+/* Default parameter setup for compression */
+EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
+/* Compression parameter setup aids */
+EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
+				      J_COLOR_SPACE colorspace));
+EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
+				   boolean force_baseline));
+EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
+					  int scale_factor,
+					  boolean force_baseline));
+EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
+				       const unsigned int *basic_table,
+				       int scale_factor,
+				       boolean force_baseline));
+EXTERN(int) jpeg_quality_scaling JPP((int quality));
+EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
+				       boolean suppress));
+EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
+EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
+
+/* Main entry points for compression */
+EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
+				      boolean write_all_tables));
+EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
+					     JSAMPARRAY scanlines,
+					     JDIMENSION num_lines));
+EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
+
+/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
+					    JSAMPIMAGE data,
+					    JDIMENSION num_lines));
+
+/* Write a special marker.  See libjpeg.doc concerning safe usage. */
+EXTERN(void) jpeg_write_marker
+	JPP((j_compress_ptr cinfo, int marker,
+	     const JOCTET * dataptr, unsigned int datalen));
+/* Same, but piecemeal. */
+EXTERN(void) jpeg_write_m_header
+	JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
+EXTERN(void) jpeg_write_m_byte
+	JPP((j_compress_ptr cinfo, int val));
+
+/* Alternate compression function: just write an abbreviated table file */
+EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
+
+/* Decompression startup: read start of JPEG datastream to see what's there */
+EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
+				  boolean require_image));
+/* Return value is one of: */
+#define JPEG_SUSPENDED		0 /* Suspended due to lack of input data */
+#define JPEG_HEADER_OK		1 /* Found valid image datastream */
+#define JPEG_HEADER_TABLES_ONLY	2 /* Found valid table-specs-only datastream */
+/* If you pass require_image = TRUE (normal case), you need not check for
+ * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
+ * JPEG_SUSPENDED is only possible if you use a data source module that can
+ * give a suspension return (the stdio source module doesn't).
+ */
+
+/* Main entry points for decompression */
+EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
+EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
+					    JSAMPARRAY scanlines,
+					    JDIMENSION max_lines));
+EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
+
+/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
+					   JSAMPIMAGE data,
+					   JDIMENSION max_lines));
+
+/* Additional entry points for buffered-image mode. */
+EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
+				       int scan_number));
+EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
+EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
+/* Return value is one of: */
+/* #define JPEG_SUSPENDED	0    Suspended due to lack of input data */
+#define JPEG_REACHED_SOS	1 /* Reached start of new scan */
+#define JPEG_REACHED_EOI	2 /* Reached end of image */
+#define JPEG_ROW_COMPLETED	3 /* Completed one iMCU row */
+#define JPEG_SCAN_COMPLETED	4 /* Completed last iMCU row of a scan */
+
+/* Precalculate output dimensions for current decompression parameters. */
+EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
+
+/* Control saving of COM and APPn markers into marker_list. */
+EXTERN(void) jpeg_save_markers
+	JPP((j_decompress_ptr cinfo, int marker_code,
+	     unsigned int length_limit));
+
+/* Install a special processing method for COM or APPn markers. */
+EXTERN(void) jpeg_set_marker_processor
+	JPP((j_decompress_ptr cinfo, int marker_code,
+	     jpeg_marker_parser_method routine));
+
+/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
+EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
+					  jvirt_barray_ptr * coef_arrays));
+EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
+						j_compress_ptr dstinfo));
+
+/* If you choose to abort compression or decompression before completing
+ * jpeg_finish_(de)compress, then you need to clean up to release memory,
+ * temporary files, etc.  You can just call jpeg_destroy_(de)compress
+ * if you're done with the JPEG object, but if you want to clean it up and
+ * reuse it, call this:
+ */
+EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
+
+/* Generic versions of jpeg_abort and jpeg_destroy that work on either
+ * flavor of JPEG object.  These may be more convenient in some places.
+ */
+EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
+EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
+
+/* Default restart-marker-resync procedure for use by data source modules */
+EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
+					    int desired));
+
+
+/* These marker codes are exported since applications and data source modules
+ * are likely to want to use them.
+ */
+
+#define JPEG_RST0	0xD0	/* RST0 marker code */
+#define JPEG_EOI	0xD9	/* EOI marker code */
+#define JPEG_APP0	0xE0	/* APP0 marker code */
+#define JPEG_COM	0xFE	/* COM marker code */
+
+
+/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
+ * for structure definitions that are never filled in, keep it quiet by
+ * supplying dummy definitions for the various substructures.
+ */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef JPEG_INTERNALS		/* will be defined in jpegint.h */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+struct jpeg_comp_master { long dummy; };
+struct jpeg_c_main_controller { long dummy; };
+struct jpeg_c_prep_controller { long dummy; };
+struct jpeg_c_coef_controller { long dummy; };
+struct jpeg_marker_writer { long dummy; };
+struct jpeg_color_converter { long dummy; };
+struct jpeg_downsampler { long dummy; };
+struct jpeg_forward_dct { long dummy; };
+struct jpeg_entropy_encoder { long dummy; };
+struct jpeg_decomp_master { long dummy; };
+struct jpeg_d_main_controller { long dummy; };
+struct jpeg_d_coef_controller { long dummy; };
+struct jpeg_d_post_controller { long dummy; };
+struct jpeg_input_controller { long dummy; };
+struct jpeg_marker_reader { long dummy; };
+struct jpeg_entropy_decoder { long dummy; };
+struct jpeg_inverse_dct { long dummy; };
+struct jpeg_upsampler { long dummy; };
+struct jpeg_color_deconverter { long dummy; };
+struct jpeg_color_quantizer { long dummy; };
+#endif /* JPEG_INTERNALS */
+#endif /* INCOMPLETE_TYPES_BROKEN */
+
+
+/*
+ * The JPEG library modules define JPEG_INTERNALS before including this file.
+ * The internal structure declarations are read only when that is true.
+ * Applications using the library should not include jpegint.h, but may wish
+ * to include jerror.h.
+ */
+
+#ifdef JPEG_INTERNALS
+#include "jpegint.h"		/* fetch private declarations */
+#include "jerror.h"		/* fetch error codes too */
+#endif
+
+#endif /* JPEGLIB_H */
diff --git a/Utilities/FLTK/jpeg/jquant1.c b/Utilities/FLTK/jpeg/jquant1.c
new file mode 100644
index 0000000000000000000000000000000000000000..b2f96aa15d25dd722c55b955bf0e475eb3160c15
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jquant1.c
@@ -0,0 +1,856 @@
+/*
+ * jquant1.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains 1-pass color quantization (color mapping) routines.
+ * These routines provide mapping to a fixed color map using equally spaced
+ * color values.  Optional Floyd-Steinberg or ordered dithering is available.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef QUANT_1PASS_SUPPORTED
+
+
+/*
+ * The main purpose of 1-pass quantization is to provide a fast, if not very
+ * high quality, colormapped output capability.  A 2-pass quantizer usually
+ * gives better visual quality; however, for quantized grayscale output this
+ * quantizer is perfectly adequate.  Dithering is highly recommended with this
+ * quantizer, though you can turn it off if you really want to.
+ *
+ * In 1-pass quantization the colormap must be chosen in advance of seeing the
+ * image.  We use a map consisting of all combinations of Ncolors[i] color
+ * values for the i'th component.  The Ncolors[] values are chosen so that
+ * their product, the total number of colors, is no more than that requested.
+ * (In most cases, the product will be somewhat less.)
+ *
+ * Since the colormap is orthogonal, the representative value for each color
+ * component can be determined without considering the other components;
+ * then these indexes can be combined into a colormap index by a standard
+ * N-dimensional-array-subscript calculation.  Most of the arithmetic involved
+ * can be precalculated and stored in the lookup table colorindex[].
+ * colorindex[i][j] maps pixel value j in component i to the nearest
+ * representative value (grid plane) for that component; this index is
+ * multiplied by the array stride for component i, so that the
+ * index of the colormap entry closest to a given pixel value is just
+ *    sum( colorindex[component-number][pixel-component-value] )
+ * Aside from being fast, this scheme allows for variable spacing between
+ * representative values with no additional lookup cost.
+ *
+ * If gamma correction has been applied in color conversion, it might be wise
+ * to adjust the color grid spacing so that the representative colors are
+ * equidistant in linear space.  At this writing, gamma correction is not
+ * implemented by jdcolor, so nothing is done here.
+ */
+
+
+/* Declarations for ordered dithering.
+ *
+ * We use a standard 16x16 ordered dither array.  The basic concept of ordered
+ * dithering is described in many references, for instance Dale Schumacher's
+ * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
+ * In place of Schumacher's comparisons against a "threshold" value, we add a
+ * "dither" value to the input pixel and then round the result to the nearest
+ * output value.  The dither value is equivalent to (0.5 - threshold) times
+ * the distance between output values.  For ordered dithering, we assume that
+ * the output colors are equally spaced; if not, results will probably be
+ * worse, since the dither may be too much or too little at a given point.
+ *
+ * The normal calculation would be to form pixel value + dither, range-limit
+ * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
+ * We can skip the separate range-limiting step by extending the colorindex
+ * table in both directions.
+ */
+
+#define ODITHER_SIZE  16	/* dimension of dither matrix */
+/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
+#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE)	/* # cells in matrix */
+#define ODITHER_MASK  (ODITHER_SIZE-1) /* mask for wrapping around counters */
+
+typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
+typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
+
+static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
+  /* Bayer's order-4 dither array.  Generated by the code given in
+   * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
+   * The values in this array must range from 0 to ODITHER_CELLS-1.
+   */
+  {   0,192, 48,240, 12,204, 60,252,  3,195, 51,243, 15,207, 63,255 },
+  { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
+  {  32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
+  { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
+  {   8,200, 56,248,  4,196, 52,244, 11,203, 59,251,  7,199, 55,247 },
+  { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
+  {  40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
+  { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
+  {   2,194, 50,242, 14,206, 62,254,  1,193, 49,241, 13,205, 61,253 },
+  { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
+  {  34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
+  { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
+  {  10,202, 58,250,  6,198, 54,246,  9,201, 57,249,  5,197, 53,245 },
+  { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
+  {  42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
+  { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
+};
+
+
+/* Declarations for Floyd-Steinberg dithering.
+ *
+ * Errors are accumulated into the array fserrors[], at a resolution of
+ * 1/16th of a pixel count.  The error at a given pixel is propagated
+ * to its not-yet-processed neighbors using the standard F-S fractions,
+ *		...	(here)	7/16
+ *		3/16	5/16	1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * We can get away with a single array (holding one row's worth of errors)
+ * by using it to store the current row's errors at pixel columns not yet
+ * processed, but the next row's errors at columns already processed.  We
+ * need only a few extra variables to hold the errors immediately around the
+ * current column.  (If we are lucky, those variables are in registers, but
+ * even if not, they're probably cheaper to access than array elements are.)
+ *
+ * The fserrors[] array is indexed [component#][position].
+ * We provide (#columns + 2) entries per component; the extra entry at each
+ * end saves us from special-casing the first and last pixels.
+ *
+ * Note: on a wide image, we might not have enough room in a PC's near data
+ * segment to hold the error array; so it is allocated with alloc_large.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef INT16 FSERROR;		/* 16 bits should be enough */
+typedef int LOCFSERROR;		/* use 'int' for calculation temps */
+#else
+typedef INT32 FSERROR;		/* may need more than 16 bits */
+typedef INT32 LOCFSERROR;	/* be sure calculation temps are big enough */
+#endif
+
+typedef FSERROR FAR *FSERRPTR;	/* pointer to error array (in FAR storage!) */
+
+
+/* Private subobject */
+
+#define MAX_Q_COMPS 4		/* max components I can handle */
+
+typedef struct {
+  struct jpeg_color_quantizer pub; /* public fields */
+
+  /* Initially allocated colormap is saved here */
+  JSAMPARRAY sv_colormap;	/* The color map as a 2-D pixel array */
+  int sv_actual;		/* number of entries in use */
+
+  JSAMPARRAY colorindex;	/* Precomputed mapping for speed */
+  /* colorindex[i][j] = index of color closest to pixel value j in component i,
+   * premultiplied as described above.  Since colormap indexes must fit into
+   * JSAMPLEs, the entries of this array will too.
+   */
+  boolean is_padded;		/* is the colorindex padded for odither? */
+
+  int Ncolors[MAX_Q_COMPS];	/* # of values alloced to each component */
+
+  /* Variables for ordered dithering */
+  int row_index;		/* cur row's vertical index in dither matrix */
+  ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */
+
+  /* Variables for Floyd-Steinberg dithering */
+  FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */
+  boolean on_odd_row;		/* flag to remember which row we are on */
+} my_cquantizer;
+
+typedef my_cquantizer * my_cquantize_ptr;
+
+
+/*
+ * Policy-making subroutines for create_colormap and create_colorindex.
+ * These routines determine the colormap to be used.  The rest of the module
+ * only assumes that the colormap is orthogonal.
+ *
+ *  * select_ncolors decides how to divvy up the available colors
+ *    among the components.
+ *  * output_value defines the set of representative values for a component.
+ *  * largest_input_value defines the mapping from input values to
+ *    representative values for a component.
+ * Note that the latter two routines may impose different policies for
+ * different components, though this is not currently done.
+ */
+
+
+LOCAL(int)
+select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
+/* Determine allocation of desired colors to components, */
+/* and fill in Ncolors[] array to indicate choice. */
+/* Return value is total number of colors (product of Ncolors[] values). */
+{
+  int nc = cinfo->out_color_components; /* number of color components */
+  int max_colors = cinfo->desired_number_of_colors;
+  int total_colors, iroot, i, j;
+  boolean changed;
+  long temp;
+  static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
+
+  /* We can allocate at least the nc'th root of max_colors per component. */
+  /* Compute floor(nc'th root of max_colors). */
+  iroot = 1;
+  do {
+    iroot++;
+    temp = iroot;		/* set temp = iroot ** nc */
+    for (i = 1; i < nc; i++)
+      temp *= iroot;
+  } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
+  iroot--;			/* now iroot = floor(root) */
+
+  /* Must have at least 2 color values per component */
+  if (iroot < 2)
+    ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp);
+
+  /* Initialize to iroot color values for each component */
+  total_colors = 1;
+  for (i = 0; i < nc; i++) {
+    Ncolors[i] = iroot;
+    total_colors *= iroot;
+  }
+  /* We may be able to increment the count for one or more components without
+   * exceeding max_colors, though we know not all can be incremented.
+   * Sometimes, the first component can be incremented more than once!
+   * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
+   * In RGB colorspace, try to increment G first, then R, then B.
+   */
+  do {
+    changed = FALSE;
+    for (i = 0; i < nc; i++) {
+      j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
+      /* calculate new total_colors if Ncolors[j] is incremented */
+      temp = total_colors / Ncolors[j];
+      temp *= Ncolors[j]+1;	/* done in long arith to avoid oflo */
+      if (temp > (long) max_colors)
+	break;			/* won't fit, done with this pass */
+      Ncolors[j]++;		/* OK, apply the increment */
+      total_colors = (int) temp;
+      changed = TRUE;
+    }
+  } while (changed);
+
+  return total_colors;
+}
+
+
+LOCAL(int)
+output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
+/* Return j'th output value, where j will range from 0 to maxj */
+/* The output values must fall in 0..MAXJSAMPLE in increasing order */
+{
+  /* We always provide values 0 and MAXJSAMPLE for each component;
+   * any additional values are equally spaced between these limits.
+   * (Forcing the upper and lower values to the limits ensures that
+   * dithering can't produce a color outside the selected gamut.)
+   */
+  return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj);
+}
+
+
+LOCAL(int)
+largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
+/* Return largest input value that should map to j'th output value */
+/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
+{
+  /* Breakpoints are halfway between values returned by output_value */
+  return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
+}
+
+
+/*
+ * Create the colormap.
+ */
+
+LOCAL(void)
+create_colormap (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  JSAMPARRAY colormap;		/* Created colormap */
+  int total_colors;		/* Number of distinct output colors */
+  int i,j,k, nci, blksize, blkdist, ptr, val;
+
+  /* Select number of colors for each component */
+  total_colors = select_ncolors(cinfo, cquantize->Ncolors);
+
+  /* Report selected color counts */
+  if (cinfo->out_color_components == 3)
+    TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
+	     total_colors, cquantize->Ncolors[0],
+	     cquantize->Ncolors[1], cquantize->Ncolors[2]);
+  else
+    TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
+
+  /* Allocate and fill in the colormap. */
+  /* The colors are ordered in the map in standard row-major order, */
+  /* i.e. rightmost (highest-indexed) color changes most rapidly. */
+
+  colormap = (*cinfo->mem->alloc_sarray)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE,
+     (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
+
+  /* blksize is number of adjacent repeated entries for a component */
+  /* blkdist is distance between groups of identical entries for a component */
+  blkdist = total_colors;
+
+  for (i = 0; i < cinfo->out_color_components; i++) {
+    /* fill in colormap entries for i'th color component */
+    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+    blksize = blkdist / nci;
+    for (j = 0; j < nci; j++) {
+      /* Compute j'th output value (out of nci) for component */
+      val = output_value(cinfo, i, j, nci-1);
+      /* Fill in all colormap entries that have this value of this component */
+      for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
+	/* fill in blksize entries beginning at ptr */
+	for (k = 0; k < blksize; k++)
+	  colormap[i][ptr+k] = (JSAMPLE) val;
+      }
+    }
+    blkdist = blksize;		/* blksize of this color is blkdist of next */
+  }
+
+  /* Save the colormap in private storage,
+   * where it will survive color quantization mode changes.
+   */
+  cquantize->sv_colormap = colormap;
+  cquantize->sv_actual = total_colors;
+}
+
+
+/*
+ * Create the color index table.
+ */
+
+LOCAL(void)
+create_colorindex (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  JSAMPROW indexptr;
+  int i,j,k, nci, blksize, val, pad;
+
+  /* For ordered dither, we pad the color index tables by MAXJSAMPLE in
+   * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
+   * This is not necessary in the other dithering modes.  However, we
+   * flag whether it was done in case user changes dithering mode.
+   */
+  if (cinfo->dither_mode == JDITHER_ORDERED) {
+    pad = MAXJSAMPLE*2;
+    cquantize->is_padded = TRUE;
+  } else {
+    pad = 0;
+    cquantize->is_padded = FALSE;
+  }
+
+  cquantize->colorindex = (*cinfo->mem->alloc_sarray)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE,
+     (JDIMENSION) (MAXJSAMPLE+1 + pad),
+     (JDIMENSION) cinfo->out_color_components);
+
+  /* blksize is number of adjacent repeated entries for a component */
+  blksize = cquantize->sv_actual;
+
+  for (i = 0; i < cinfo->out_color_components; i++) {
+    /* fill in colorindex entries for i'th color component */
+    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+    blksize = blksize / nci;
+
+    /* adjust colorindex pointers to provide padding at negative indexes. */
+    if (pad)
+      cquantize->colorindex[i] += MAXJSAMPLE;
+
+    /* in loop, val = index of current output value, */
+    /* and k = largest j that maps to current val */
+    indexptr = cquantize->colorindex[i];
+    val = 0;
+    k = largest_input_value(cinfo, i, 0, nci-1);
+    for (j = 0; j <= MAXJSAMPLE; j++) {
+      while (j > k)		/* advance val if past boundary */
+	k = largest_input_value(cinfo, i, ++val, nci-1);
+      /* premultiply so that no multiplication needed in main processing */
+      indexptr[j] = (JSAMPLE) (val * blksize);
+    }
+    /* Pad at both ends if necessary */
+    if (pad)
+      for (j = 1; j <= MAXJSAMPLE; j++) {
+	indexptr[-j] = indexptr[0];
+	indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
+      }
+  }
+}
+
+
+/*
+ * Create an ordered-dither array for a component having ncolors
+ * distinct output values.
+ */
+
+LOCAL(ODITHER_MATRIX_PTR)
+make_odither_array (j_decompress_ptr cinfo, int ncolors)
+{
+  ODITHER_MATRIX_PTR odither;
+  int j,k;
+  INT32 num,den;
+
+  odither = (ODITHER_MATRIX_PTR)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(ODITHER_MATRIX));
+  /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
+   * Hence the dither value for the matrix cell with fill order f
+   * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
+   * On 16-bit-int machine, be careful to avoid overflow.
+   */
+  den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
+  for (j = 0; j < ODITHER_SIZE; j++) {
+    for (k = 0; k < ODITHER_SIZE; k++) {
+      num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
+	    * MAXJSAMPLE;
+      /* Ensure round towards zero despite C's lack of consistency
+       * about rounding negative values in integer division...
+       */
+      odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
+    }
+  }
+  return odither;
+}
+
+
+/*
+ * Create the ordered-dither tables.
+ * Components having the same number of representative colors may 
+ * share a dither table.
+ */
+
+LOCAL(void)
+create_odither_tables (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  ODITHER_MATRIX_PTR odither;
+  int i, j, nci;
+
+  for (i = 0; i < cinfo->out_color_components; i++) {
+    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+    odither = NULL;		/* search for matching prior component */
+    for (j = 0; j < i; j++) {
+      if (nci == cquantize->Ncolors[j]) {
+	odither = cquantize->odither[j];
+	break;
+      }
+    }
+    if (odither == NULL)	/* need a new table? */
+      odither = make_odither_array(cinfo, nci);
+    cquantize->odither[i] = odither;
+  }
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ */
+
+METHODDEF(void)
+color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+		JSAMPARRAY output_buf, int num_rows)
+/* General case, no dithering */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  JSAMPARRAY colorindex = cquantize->colorindex;
+  register int pixcode, ci;
+  register JSAMPROW ptrin, ptrout;
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+  register int nc = cinfo->out_color_components;
+
+  for (row = 0; row < num_rows; row++) {
+    ptrin = input_buf[row];
+    ptrout = output_buf[row];
+    for (col = width; col > 0; col--) {
+      pixcode = 0;
+      for (ci = 0; ci < nc; ci++) {
+	pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
+      }
+      *ptrout++ = (JSAMPLE) pixcode;
+    }
+  }
+}
+
+
+METHODDEF(void)
+color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+		 JSAMPARRAY output_buf, int num_rows)
+/* Fast path for out_color_components==3, no dithering */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  register int pixcode;
+  register JSAMPROW ptrin, ptrout;
+  JSAMPROW colorindex0 = cquantize->colorindex[0];
+  JSAMPROW colorindex1 = cquantize->colorindex[1];
+  JSAMPROW colorindex2 = cquantize->colorindex[2];
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+
+  for (row = 0; row < num_rows; row++) {
+    ptrin = input_buf[row];
+    ptrout = output_buf[row];
+    for (col = width; col > 0; col--) {
+      pixcode  = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
+      pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
+      pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
+      *ptrout++ = (JSAMPLE) pixcode;
+    }
+  }
+}
+
+
+METHODDEF(void)
+quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+		     JSAMPARRAY output_buf, int num_rows)
+/* General case, with ordered dithering */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  register JSAMPROW input_ptr;
+  register JSAMPROW output_ptr;
+  JSAMPROW colorindex_ci;
+  int * dither;			/* points to active row of dither matrix */
+  int row_index, col_index;	/* current indexes into dither matrix */
+  int nc = cinfo->out_color_components;
+  int ci;
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+
+  for (row = 0; row < num_rows; row++) {
+    /* Initialize output values to 0 so can process components separately */
+    jzero_far((void FAR *) output_buf[row],
+	      (size_t) (width * SIZEOF(JSAMPLE)));
+    row_index = cquantize->row_index;
+    for (ci = 0; ci < nc; ci++) {
+      input_ptr = input_buf[row] + ci;
+      output_ptr = output_buf[row];
+      colorindex_ci = cquantize->colorindex[ci];
+      dither = cquantize->odither[ci][row_index];
+      col_index = 0;
+
+      for (col = width; col > 0; col--) {
+	/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
+	 * select output value, accumulate into output code for this pixel.
+	 * Range-limiting need not be done explicitly, as we have extended
+	 * the colorindex table to produce the right answers for out-of-range
+	 * inputs.  The maximum dither is +- MAXJSAMPLE; this sets the
+	 * required amount of padding.
+	 */
+	*output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
+	input_ptr += nc;
+	output_ptr++;
+	col_index = (col_index + 1) & ODITHER_MASK;
+      }
+    }
+    /* Advance row index for next row */
+    row_index = (row_index + 1) & ODITHER_MASK;
+    cquantize->row_index = row_index;
+  }
+}
+
+
+METHODDEF(void)
+quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+		      JSAMPARRAY output_buf, int num_rows)
+/* Fast path for out_color_components==3, with ordered dithering */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  register int pixcode;
+  register JSAMPROW input_ptr;
+  register JSAMPROW output_ptr;
+  JSAMPROW colorindex0 = cquantize->colorindex[0];
+  JSAMPROW colorindex1 = cquantize->colorindex[1];
+  JSAMPROW colorindex2 = cquantize->colorindex[2];
+  int * dither0;		/* points to active row of dither matrix */
+  int * dither1;
+  int * dither2;
+  int row_index, col_index;	/* current indexes into dither matrix */
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+
+  for (row = 0; row < num_rows; row++) {
+    row_index = cquantize->row_index;
+    input_ptr = input_buf[row];
+    output_ptr = output_buf[row];
+    dither0 = cquantize->odither[0][row_index];
+    dither1 = cquantize->odither[1][row_index];
+    dither2 = cquantize->odither[2][row_index];
+    col_index = 0;
+
+    for (col = width; col > 0; col--) {
+      pixcode  = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) +
+					dither0[col_index]]);
+      pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) +
+					dither1[col_index]]);
+      pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) +
+					dither2[col_index]]);
+      *output_ptr++ = (JSAMPLE) pixcode;
+      col_index = (col_index + 1) & ODITHER_MASK;
+    }
+    row_index = (row_index + 1) & ODITHER_MASK;
+    cquantize->row_index = row_index;
+  }
+}
+
+
+METHODDEF(void)
+quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+		    JSAMPARRAY output_buf, int num_rows)
+/* General case, with Floyd-Steinberg dithering */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  register LOCFSERROR cur;	/* current error or pixel value */
+  LOCFSERROR belowerr;		/* error for pixel below cur */
+  LOCFSERROR bpreverr;		/* error for below/prev col */
+  LOCFSERROR bnexterr;		/* error for below/next col */
+  LOCFSERROR delta;
+  register FSERRPTR errorptr;	/* => fserrors[] at column before current */
+  register JSAMPROW input_ptr;
+  register JSAMPROW output_ptr;
+  JSAMPROW colorindex_ci;
+  JSAMPROW colormap_ci;
+  int pixcode;
+  int nc = cinfo->out_color_components;
+  int dir;			/* 1 for left-to-right, -1 for right-to-left */
+  int dirnc;			/* dir * nc */
+  int ci;
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+  JSAMPLE *range_limit = cinfo->sample_range_limit;
+  SHIFT_TEMPS
+
+  for (row = 0; row < num_rows; row++) {
+    /* Initialize output values to 0 so can process components separately */
+    jzero_far((void FAR *) output_buf[row],
+	      (size_t) (width * SIZEOF(JSAMPLE)));
+    for (ci = 0; ci < nc; ci++) {
+      input_ptr = input_buf[row] + ci;
+      output_ptr = output_buf[row];
+      if (cquantize->on_odd_row) {
+	/* work right to left in this row */
+	input_ptr += (width-1) * nc; /* so point to rightmost pixel */
+	output_ptr += width-1;
+	dir = -1;
+	dirnc = -nc;
+	errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
+      } else {
+	/* work left to right in this row */
+	dir = 1;
+	dirnc = nc;
+	errorptr = cquantize->fserrors[ci]; /* => entry before first column */
+      }
+      colorindex_ci = cquantize->colorindex[ci];
+      colormap_ci = cquantize->sv_colormap[ci];
+      /* Preset error values: no error propagated to first pixel from left */
+      cur = 0;
+      /* and no error propagated to row below yet */
+      belowerr = bpreverr = 0;
+
+      for (col = width; col > 0; col--) {
+	/* cur holds the error propagated from the previous pixel on the
+	 * current line.  Add the error propagated from the previous line
+	 * to form the complete error correction term for this pixel, and
+	 * round the error term (which is expressed * 16) to an integer.
+	 * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
+	 * for either sign of the error value.
+	 * Note: errorptr points to *previous* column's array entry.
+	 */
+	cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
+	/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
+	 * The maximum error is +- MAXJSAMPLE; this sets the required size
+	 * of the range_limit array.
+	 */
+	cur += GETJSAMPLE(*input_ptr);
+	cur = GETJSAMPLE(range_limit[cur]);
+	/* Select output value, accumulate into output code for this pixel */
+	pixcode = GETJSAMPLE(colorindex_ci[cur]);
+	*output_ptr += (JSAMPLE) pixcode;
+	/* Compute actual representation error at this pixel */
+	/* Note: we can do this even though we don't have the final */
+	/* pixel code, because the colormap is orthogonal. */
+	cur -= GETJSAMPLE(colormap_ci[pixcode]);
+	/* Compute error fractions to be propagated to adjacent pixels.
+	 * Add these into the running sums, and simultaneously shift the
+	 * next-line error sums left by 1 column.
+	 */
+	bnexterr = cur;
+	delta = cur * 2;
+	cur += delta;		/* form error * 3 */
+	errorptr[0] = (FSERROR) (bpreverr + cur);
+	cur += delta;		/* form error * 5 */
+	bpreverr = belowerr + cur;
+	belowerr = bnexterr;
+	cur += delta;		/* form error * 7 */
+	/* At this point cur contains the 7/16 error value to be propagated
+	 * to the next pixel on the current line, and all the errors for the
+	 * next line have been shifted over. We are therefore ready to move on.
+	 */
+	input_ptr += dirnc;	/* advance input ptr to next column */
+	output_ptr += dir;	/* advance output ptr to next column */
+	errorptr += dir;	/* advance errorptr to current column */
+      }
+      /* Post-loop cleanup: we must unload the final error value into the
+       * final fserrors[] entry.  Note we need not unload belowerr because
+       * it is for the dummy column before or after the actual array.
+       */
+      errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
+    }
+    cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
+  }
+}
+
+
+/*
+ * Allocate workspace for Floyd-Steinberg errors.
+ */
+
+LOCAL(void)
+alloc_fs_workspace (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  size_t arraysize;
+  int i;
+
+  arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
+  for (i = 0; i < cinfo->out_color_components; i++) {
+    cquantize->fserrors[i] = (FSERRPTR)
+      (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
+  }
+}
+
+
+/*
+ * Initialize for one-pass color quantization.
+ */
+
+METHODDEF(void)
+start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  size_t arraysize;
+  int i;
+
+  /* Install my colormap. */
+  cinfo->colormap = cquantize->sv_colormap;
+  cinfo->actual_number_of_colors = cquantize->sv_actual;
+
+  /* Initialize for desired dithering mode. */
+  switch (cinfo->dither_mode) {
+  case JDITHER_NONE:
+    if (cinfo->out_color_components == 3)
+      cquantize->pub.color_quantize = color_quantize3;
+    else
+      cquantize->pub.color_quantize = color_quantize;
+    break;
+  case JDITHER_ORDERED:
+    if (cinfo->out_color_components == 3)
+      cquantize->pub.color_quantize = quantize3_ord_dither;
+    else
+      cquantize->pub.color_quantize = quantize_ord_dither;
+    cquantize->row_index = 0;	/* initialize state for ordered dither */
+    /* If user changed to ordered dither from another mode,
+     * we must recreate the color index table with padding.
+     * This will cost extra space, but probably isn't very likely.
+     */
+    if (! cquantize->is_padded)
+      create_colorindex(cinfo);
+    /* Create ordered-dither tables if we didn't already. */
+    if (cquantize->odither[0] == NULL)
+      create_odither_tables(cinfo);
+    break;
+  case JDITHER_FS:
+    cquantize->pub.color_quantize = quantize_fs_dither;
+    cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
+    /* Allocate Floyd-Steinberg workspace if didn't already. */
+    if (cquantize->fserrors[0] == NULL)
+      alloc_fs_workspace(cinfo);
+    /* Initialize the propagated errors to zero. */
+    arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
+    for (i = 0; i < cinfo->out_color_components; i++)
+      jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
+    break;
+  default:
+    ERREXIT(cinfo, JERR_NOT_COMPILED);
+    break;
+  }
+}
+
+
+/*
+ * Finish up at the end of the pass.
+ */
+
+METHODDEF(void)
+finish_pass_1_quant (j_decompress_ptr cinfo)
+{
+  /* no work in 1-pass case */
+}
+
+
+/*
+ * Switch to a new external colormap between output passes.
+ * Shouldn't get to this module!
+ */
+
+METHODDEF(void)
+new_color_map_1_quant (j_decompress_ptr cinfo)
+{
+  ERREXIT(cinfo, JERR_MODE_CHANGE);
+}
+
+
+/*
+ * Module initialization routine for 1-pass color quantization.
+ */
+
+GLOBAL(void)
+jinit_1pass_quantizer (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize;
+
+  cquantize = (my_cquantize_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_cquantizer));
+  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
+  cquantize->pub.start_pass = start_pass_1_quant;
+  cquantize->pub.finish_pass = finish_pass_1_quant;
+  cquantize->pub.new_color_map = new_color_map_1_quant;
+  cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
+  cquantize->odither[0] = NULL;	/* Also flag odither arrays not allocated */
+
+  /* Make sure my internal arrays won't overflow */
+  if (cinfo->out_color_components > MAX_Q_COMPS)
+    ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
+  /* Make sure colormap indexes can be represented by JSAMPLEs */
+  if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
+    ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
+
+  /* Create the colormap and color index table. */
+  create_colormap(cinfo);
+  create_colorindex(cinfo);
+
+  /* Allocate Floyd-Steinberg workspace now if requested.
+   * We do this now since it is FAR storage and may affect the memory
+   * manager's space calculations.  If the user changes to FS dither
+   * mode in a later pass, we will allocate the space then, and will
+   * possibly overrun the max_memory_to_use setting.
+   */
+  if (cinfo->dither_mode == JDITHER_FS)
+    alloc_fs_workspace(cinfo);
+}
+
+#endif /* QUANT_1PASS_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jquant2.c b/Utilities/FLTK/jpeg/jquant2.c
new file mode 100644
index 0000000000000000000000000000000000000000..af601e334b244f0a356e78826463b71e0848fe57
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jquant2.c
@@ -0,0 +1,1310 @@
+/*
+ * jquant2.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains 2-pass color quantization (color mapping) routines.
+ * These routines provide selection of a custom color map for an image,
+ * followed by mapping of the image to that color map, with optional
+ * Floyd-Steinberg dithering.
+ * It is also possible to use just the second pass to map to an arbitrary
+ * externally-given color map.
+ *
+ * Note: ordered dithering is not supported, since there isn't any fast
+ * way to compute intercolor distances; it's unclear that ordered dither's
+ * fundamental assumptions even hold with an irregularly spaced color map.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+
+/*
+ * This module implements the well-known Heckbert paradigm for color
+ * quantization.  Most of the ideas used here can be traced back to
+ * Heckbert's seminal paper
+ *   Heckbert, Paul.  "Color Image Quantization for Frame Buffer Display",
+ *   Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
+ *
+ * In the first pass over the image, we accumulate a histogram showing the
+ * usage count of each possible color.  To keep the histogram to a reasonable
+ * size, we reduce the precision of the input; typical practice is to retain
+ * 5 or 6 bits per color, so that 8 or 4 different input values are counted
+ * in the same histogram cell.
+ *
+ * Next, the color-selection step begins with a box representing the whole
+ * color space, and repeatedly splits the "largest" remaining box until we
+ * have as many boxes as desired colors.  Then the mean color in each
+ * remaining box becomes one of the possible output colors.
+ * 
+ * The second pass over the image maps each input pixel to the closest output
+ * color (optionally after applying a Floyd-Steinberg dithering correction).
+ * This mapping is logically trivial, but making it go fast enough requires
+ * considerable care.
+ *
+ * Heckbert-style quantizers vary a good deal in their policies for choosing
+ * the "largest" box and deciding where to cut it.  The particular policies
+ * used here have proved out well in experimental comparisons, but better ones
+ * may yet be found.
+ *
+ * In earlier versions of the IJG code, this module quantized in YCbCr color
+ * space, processing the raw upsampled data without a color conversion step.
+ * This allowed the color conversion math to be done only once per colormap
+ * entry, not once per pixel.  However, that optimization precluded other
+ * useful optimizations (such as merging color conversion with upsampling)
+ * and it also interfered with desired capabilities such as quantizing to an
+ * externally-supplied colormap.  We have therefore abandoned that approach.
+ * The present code works in the post-conversion color space, typically RGB.
+ *
+ * To improve the visual quality of the results, we actually work in scaled
+ * RGB space, giving G distances more weight than R, and R in turn more than
+ * B.  To do everything in integer math, we must use integer scale factors.
+ * The 2/3/1 scale factors used here correspond loosely to the relative
+ * weights of the colors in the NTSC grayscale equation.
+ * If you want to use this code to quantize a non-RGB color space, you'll
+ * probably need to change these scale factors.
+ */
+
+#define R_SCALE 2		/* scale R distances by this much */
+#define G_SCALE 3		/* scale G distances by this much */
+#define B_SCALE 1		/* and B by this much */
+
+/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
+ * in jmorecfg.h.  As the code stands, it will do the right thing for R,G,B
+ * and B,G,R orders.  If you define some other weird order in jmorecfg.h,
+ * you'll get compile errors until you extend this logic.  In that case
+ * you'll probably want to tweak the histogram sizes too.
+ */
+
+#if RGB_RED == 0
+#define C0_SCALE R_SCALE
+#endif
+#if RGB_BLUE == 0
+#define C0_SCALE B_SCALE
+#endif
+#if RGB_GREEN == 1
+#define C1_SCALE G_SCALE
+#endif
+#if RGB_RED == 2
+#define C2_SCALE R_SCALE
+#endif
+#if RGB_BLUE == 2
+#define C2_SCALE B_SCALE
+#endif
+
+
+/*
+ * First we have the histogram data structure and routines for creating it.
+ *
+ * The number of bits of precision can be adjusted by changing these symbols.
+ * We recommend keeping 6 bits for G and 5 each for R and B.
+ * If you have plenty of memory and cycles, 6 bits all around gives marginally
+ * better results; if you are short of memory, 5 bits all around will save
+ * some space but degrade the results.
+ * To maintain a fully accurate histogram, we'd need to allocate a "long"
+ * (preferably unsigned long) for each cell.  In practice this is overkill;
+ * we can get by with 16 bits per cell.  Few of the cell counts will overflow,
+ * and clamping those that do overflow to the maximum value will give close-
+ * enough results.  This reduces the recommended histogram size from 256Kb
+ * to 128Kb, which is a useful savings on PC-class machines.
+ * (In the second pass the histogram space is re-used for pixel mapping data;
+ * in that capacity, each cell must be able to store zero to the number of
+ * desired colors.  16 bits/cell is plenty for that too.)
+ * Since the JPEG code is intended to run in small memory model on 80x86
+ * machines, we can't just allocate the histogram in one chunk.  Instead
+ * of a true 3-D array, we use a row of pointers to 2-D arrays.  Each
+ * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
+ * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries.  Note that
+ * on 80x86 machines, the pointer row is in near memory but the actual
+ * arrays are in far memory (same arrangement as we use for image arrays).
+ */
+
+#define MAXNUMCOLORS  (MAXJSAMPLE+1) /* maximum size of colormap */
+
+/* These will do the right thing for either R,G,B or B,G,R color order,
+ * but you may not like the results for other color orders.
+ */
+#define HIST_C0_BITS  5		/* bits of precision in R/B histogram */
+#define HIST_C1_BITS  6		/* bits of precision in G histogram */
+#define HIST_C2_BITS  5		/* bits of precision in B/R histogram */
+
+/* Number of elements along histogram axes. */
+#define HIST_C0_ELEMS  (1<<HIST_C0_BITS)
+#define HIST_C1_ELEMS  (1<<HIST_C1_BITS)
+#define HIST_C2_ELEMS  (1<<HIST_C2_BITS)
+
+/* These are the amounts to shift an input value to get a histogram index. */
+#define C0_SHIFT  (BITS_IN_JSAMPLE-HIST_C0_BITS)
+#define C1_SHIFT  (BITS_IN_JSAMPLE-HIST_C1_BITS)
+#define C2_SHIFT  (BITS_IN_JSAMPLE-HIST_C2_BITS)
+
+
+typedef UINT16 histcell;	/* histogram cell; prefer an unsigned type */
+
+typedef histcell FAR * histptr;	/* for pointers to histogram cells */
+
+typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */
+typedef hist1d FAR * hist2d;	/* type for the 2nd-level pointers */
+typedef hist2d * hist3d;	/* type for top-level pointer */
+
+
+/* Declarations for Floyd-Steinberg dithering.
+ *
+ * Errors are accumulated into the array fserrors[], at a resolution of
+ * 1/16th of a pixel count.  The error at a given pixel is propagated
+ * to its not-yet-processed neighbors using the standard F-S fractions,
+ *		...	(here)	7/16
+ *		3/16	5/16	1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * We can get away with a single array (holding one row's worth of errors)
+ * by using it to store the current row's errors at pixel columns not yet
+ * processed, but the next row's errors at columns already processed.  We
+ * need only a few extra variables to hold the errors immediately around the
+ * current column.  (If we are lucky, those variables are in registers, but
+ * even if not, they're probably cheaper to access than array elements are.)
+ *
+ * The fserrors[] array has (#columns + 2) entries; the extra entry at
+ * each end saves us from special-casing the first and last pixels.
+ * Each entry is three values long, one value for each color component.
+ *
+ * Note: on a wide image, we might not have enough room in a PC's near data
+ * segment to hold the error array; so it is allocated with alloc_large.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef INT16 FSERROR;		/* 16 bits should be enough */
+typedef int LOCFSERROR;		/* use 'int' for calculation temps */
+#else
+typedef INT32 FSERROR;		/* may need more than 16 bits */
+typedef INT32 LOCFSERROR;	/* be sure calculation temps are big enough */
+#endif
+
+typedef FSERROR FAR *FSERRPTR;	/* pointer to error array (in FAR storage!) */
+
+
+/* Private subobject */
+
+typedef struct {
+  struct jpeg_color_quantizer pub; /* public fields */
+
+  /* Space for the eventually created colormap is stashed here */
+  JSAMPARRAY sv_colormap;	/* colormap allocated at init time */
+  int desired;			/* desired # of colors = size of colormap */
+
+  /* Variables for accumulating image statistics */
+  hist3d histogram;		/* pointer to the histogram */
+
+  boolean needs_zeroed;		/* TRUE if next pass must zero histogram */
+
+  /* Variables for Floyd-Steinberg dithering */
+  FSERRPTR fserrors;		/* accumulated errors */
+  boolean on_odd_row;		/* flag to remember which row we are on */
+  int * error_limiter;		/* table for clamping the applied error */
+} my_cquantizer;
+
+typedef my_cquantizer * my_cquantize_ptr;
+
+
+/*
+ * Prescan some rows of pixels.
+ * In this module the prescan simply updates the histogram, which has been
+ * initialized to zeroes by start_pass.
+ * An output_buf parameter is required by the method signature, but no data
+ * is actually output (in fact the buffer controller is probably passing a
+ * NULL pointer).
+ */
+
+METHODDEF(void)
+prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+		  JSAMPARRAY output_buf, int num_rows)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  register JSAMPROW ptr;
+  register histptr histp;
+  register hist3d histogram = cquantize->histogram;
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+
+  for (row = 0; row < num_rows; row++) {
+    ptr = input_buf[row];
+    for (col = width; col > 0; col--) {
+      /* get pixel value and index into the histogram */
+      histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
+			 [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
+			 [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
+      /* increment, check for overflow and undo increment if so. */
+      if (++(*histp) <= 0)
+	(*histp)--;
+      ptr += 3;
+    }
+  }
+}
+
+
+/*
+ * Next we have the really interesting routines: selection of a colormap
+ * given the completed histogram.
+ * These routines work with a list of "boxes", each representing a rectangular
+ * subset of the input color space (to histogram precision).
+ */
+
+typedef struct {
+  /* The bounds of the box (inclusive); expressed as histogram indexes */
+  int c0min, c0max;
+  int c1min, c1max;
+  int c2min, c2max;
+  /* The volume (actually 2-norm) of the box */
+  INT32 volume;
+  /* The number of nonzero histogram cells within this box */
+  long colorcount;
+} box;
+
+typedef box * boxptr;
+
+
+LOCAL(boxptr)
+find_biggest_color_pop (boxptr boxlist, int numboxes)
+/* Find the splittable box with the largest color population */
+/* Returns NULL if no splittable boxes remain */
+{
+  register boxptr boxp;
+  register int i;
+  register long maxc = 0;
+  boxptr which = NULL;
+  
+  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+    if (boxp->colorcount > maxc && boxp->volume > 0) {
+      which = boxp;
+      maxc = boxp->colorcount;
+    }
+  }
+  return which;
+}
+
+
+LOCAL(boxptr)
+find_biggest_volume (boxptr boxlist, int numboxes)
+/* Find the splittable box with the largest (scaled) volume */
+/* Returns NULL if no splittable boxes remain */
+{
+  register boxptr boxp;
+  register int i;
+  register INT32 maxv = 0;
+  boxptr which = NULL;
+  
+  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+    if (boxp->volume > maxv) {
+      which = boxp;
+      maxv = boxp->volume;
+    }
+  }
+  return which;
+}
+
+
+LOCAL(void)
+update_box (j_decompress_ptr cinfo, boxptr boxp)
+/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
+/* and recompute its volume and population */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  hist3d histogram = cquantize->histogram;
+  histptr histp;
+  int c0,c1,c2;
+  int c0min,c0max,c1min,c1max,c2min,c2max;
+  INT32 dist0,dist1,dist2;
+  long ccount;
+  
+  c0min = boxp->c0min;  c0max = boxp->c0max;
+  c1min = boxp->c1min;  c1max = boxp->c1max;
+  c2min = boxp->c2min;  c2max = boxp->c2max;
+  
+  if (c0max > c0min)
+    for (c0 = c0min; c0 <= c0max; c0++)
+      for (c1 = c1min; c1 <= c1max; c1++) {
+	histp = & histogram[c0][c1][c2min];
+	for (c2 = c2min; c2 <= c2max; c2++)
+	  if (*histp++ != 0) {
+	    boxp->c0min = c0min = c0;
+	    goto have_c0min;
+	  }
+      }
+ have_c0min:
+  if (c0max > c0min)
+    for (c0 = c0max; c0 >= c0min; c0--)
+      for (c1 = c1min; c1 <= c1max; c1++) {
+	histp = & histogram[c0][c1][c2min];
+	for (c2 = c2min; c2 <= c2max; c2++)
+	  if (*histp++ != 0) {
+	    boxp->c0max = c0max = c0;
+	    goto have_c0max;
+	  }
+      }
+ have_c0max:
+  if (c1max > c1min)
+    for (c1 = c1min; c1 <= c1max; c1++)
+      for (c0 = c0min; c0 <= c0max; c0++) {
+	histp = & histogram[c0][c1][c2min];
+	for (c2 = c2min; c2 <= c2max; c2++)
+	  if (*histp++ != 0) {
+	    boxp->c1min = c1min = c1;
+	    goto have_c1min;
+	  }
+      }
+ have_c1min:
+  if (c1max > c1min)
+    for (c1 = c1max; c1 >= c1min; c1--)
+      for (c0 = c0min; c0 <= c0max; c0++) {
+	histp = & histogram[c0][c1][c2min];
+	for (c2 = c2min; c2 <= c2max; c2++)
+	  if (*histp++ != 0) {
+	    boxp->c1max = c1max = c1;
+	    goto have_c1max;
+	  }
+      }
+ have_c1max:
+  if (c2max > c2min)
+    for (c2 = c2min; c2 <= c2max; c2++)
+      for (c0 = c0min; c0 <= c0max; c0++) {
+	histp = & histogram[c0][c1min][c2];
+	for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+	  if (*histp != 0) {
+	    boxp->c2min = c2min = c2;
+	    goto have_c2min;
+	  }
+      }
+ have_c2min:
+  if (c2max > c2min)
+    for (c2 = c2max; c2 >= c2min; c2--)
+      for (c0 = c0min; c0 <= c0max; c0++) {
+	histp = & histogram[c0][c1min][c2];
+	for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+	  if (*histp != 0) {
+	    boxp->c2max = c2max = c2;
+	    goto have_c2max;
+	  }
+      }
+ have_c2max:
+
+  /* Update box volume.
+   * We use 2-norm rather than real volume here; this biases the method
+   * against making long narrow boxes, and it has the side benefit that
+   * a box is splittable iff norm > 0.
+   * Since the differences are expressed in histogram-cell units,
+   * we have to shift back to JSAMPLE units to get consistent distances;
+   * after which, we scale according to the selected distance scale factors.
+   */
+  dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
+  dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
+  dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
+  boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
+  
+  /* Now scan remaining volume of box and compute population */
+  ccount = 0;
+  for (c0 = c0min; c0 <= c0max; c0++)
+    for (c1 = c1min; c1 <= c1max; c1++) {
+      histp = & histogram[c0][c1][c2min];
+      for (c2 = c2min; c2 <= c2max; c2++, histp++)
+	if (*histp != 0) {
+	  ccount++;
+	}
+    }
+  boxp->colorcount = ccount;
+}
+
+
+LOCAL(int)
+median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
+	    int desired_colors)
+/* Repeatedly select and split the largest box until we have enough boxes */
+{
+  int n,lb;
+  int c0,c1,c2,cmax;
+  register boxptr b1,b2;
+
+  while (numboxes < desired_colors) {
+    /* Select box to split.
+     * Current algorithm: by population for first half, then by volume.
+     */
+    if (numboxes*2 <= desired_colors) {
+      b1 = find_biggest_color_pop(boxlist, numboxes);
+    } else {
+      b1 = find_biggest_volume(boxlist, numboxes);
+    }
+    if (b1 == NULL)		/* no splittable boxes left! */
+      break;
+    b2 = &boxlist[numboxes];	/* where new box will go */
+    /* Copy the color bounds to the new box. */
+    b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
+    b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
+    /* Choose which axis to split the box on.
+     * Current algorithm: longest scaled axis.
+     * See notes in update_box about scaling distances.
+     */
+    c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
+    c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
+    c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
+    /* We want to break any ties in favor of green, then red, blue last.
+     * This code does the right thing for R,G,B or B,G,R color orders only.
+     */
+#if RGB_RED == 0
+    cmax = c1; n = 1;
+    if (c0 > cmax) { cmax = c0; n = 0; }
+    if (c2 > cmax) { n = 2; }
+#else
+    cmax = c1; n = 1;
+    if (c2 > cmax) { cmax = c2; n = 2; }
+    if (c0 > cmax) { n = 0; }
+#endif
+    /* Choose split point along selected axis, and update box bounds.
+     * Current algorithm: split at halfway point.
+     * (Since the box has been shrunk to minimum volume,
+     * any split will produce two nonempty subboxes.)
+     * Note that lb value is max for lower box, so must be < old max.
+     */
+    switch (n) {
+    case 0:
+      lb = (b1->c0max + b1->c0min) / 2;
+      b1->c0max = lb;
+      b2->c0min = lb+1;
+      break;
+    case 1:
+      lb = (b1->c1max + b1->c1min) / 2;
+      b1->c1max = lb;
+      b2->c1min = lb+1;
+      break;
+    case 2:
+      lb = (b1->c2max + b1->c2min) / 2;
+      b1->c2max = lb;
+      b2->c2min = lb+1;
+      break;
+    }
+    /* Update stats for boxes */
+    update_box(cinfo, b1);
+    update_box(cinfo, b2);
+    numboxes++;
+  }
+  return numboxes;
+}
+
+
+LOCAL(void)
+compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
+/* Compute representative color for a box, put it in colormap[icolor] */
+{
+  /* Current algorithm: mean weighted by pixels (not colors) */
+  /* Note it is important to get the rounding correct! */
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  hist3d histogram = cquantize->histogram;
+  histptr histp;
+  int c0,c1,c2;
+  int c0min,c0max,c1min,c1max,c2min,c2max;
+  long count;
+  long total = 0;
+  long c0total = 0;
+  long c1total = 0;
+  long c2total = 0;
+  
+  c0min = boxp->c0min;  c0max = boxp->c0max;
+  c1min = boxp->c1min;  c1max = boxp->c1max;
+  c2min = boxp->c2min;  c2max = boxp->c2max;
+  
+  for (c0 = c0min; c0 <= c0max; c0++)
+    for (c1 = c1min; c1 <= c1max; c1++) {
+      histp = & histogram[c0][c1][c2min];
+      for (c2 = c2min; c2 <= c2max; c2++) {
+	if ((count = *histp++) != 0) {
+	  total += count;
+	  c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count;
+	  c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count;
+	  c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count;
+	}
+      }
+    }
+  
+  cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
+  cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
+  cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
+}
+
+
+LOCAL(void)
+select_colors (j_decompress_ptr cinfo, int desired_colors)
+/* Master routine for color selection */
+{
+  boxptr boxlist;
+  int numboxes;
+  int i;
+
+  /* Allocate workspace for box list */
+  boxlist = (boxptr) (*cinfo->mem->alloc_small)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
+  /* Initialize one box containing whole space */
+  numboxes = 1;
+  boxlist[0].c0min = 0;
+  boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
+  boxlist[0].c1min = 0;
+  boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
+  boxlist[0].c2min = 0;
+  boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
+  /* Shrink it to actually-used volume and set its statistics */
+  update_box(cinfo, & boxlist[0]);
+  /* Perform median-cut to produce final box list */
+  numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
+  /* Compute the representative color for each box, fill colormap */
+  for (i = 0; i < numboxes; i++)
+    compute_color(cinfo, & boxlist[i], i);
+  cinfo->actual_number_of_colors = numboxes;
+  TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
+}
+
+
+/*
+ * These routines are concerned with the time-critical task of mapping input
+ * colors to the nearest color in the selected colormap.
+ *
+ * We re-use the histogram space as an "inverse color map", essentially a
+ * cache for the results of nearest-color searches.  All colors within a
+ * histogram cell will be mapped to the same colormap entry, namely the one
+ * closest to the cell's center.  This may not be quite the closest entry to
+ * the actual input color, but it's almost as good.  A zero in the cache
+ * indicates we haven't found the nearest color for that cell yet; the array
+ * is cleared to zeroes before starting the mapping pass.  When we find the
+ * nearest color for a cell, its colormap index plus one is recorded in the
+ * cache for future use.  The pass2 scanning routines call fill_inverse_cmap
+ * when they need to use an unfilled entry in the cache.
+ *
+ * Our method of efficiently finding nearest colors is based on the "locally
+ * sorted search" idea described by Heckbert and on the incremental distance
+ * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
+ * Gems II (James Arvo, ed.  Academic Press, 1991).  Thomas points out that
+ * the distances from a given colormap entry to each cell of the histogram can
+ * be computed quickly using an incremental method: the differences between
+ * distances to adjacent cells themselves differ by a constant.  This allows a
+ * fairly fast implementation of the "brute force" approach of computing the
+ * distance from every colormap entry to every histogram cell.  Unfortunately,
+ * it needs a work array to hold the best-distance-so-far for each histogram
+ * cell (because the inner loop has to be over cells, not colormap entries).
+ * The work array elements have to be INT32s, so the work array would need
+ * 256Kb at our recommended precision.  This is not feasible in DOS machines.
+ *
+ * To get around these problems, we apply Thomas' method to compute the
+ * nearest colors for only the cells within a small subbox of the histogram.
+ * The work array need be only as big as the subbox, so the memory usage
+ * problem is solved.  Furthermore, we need not fill subboxes that are never
+ * referenced in pass2; many images use only part of the color gamut, so a
+ * fair amount of work is saved.  An additional advantage of this
+ * approach is that we can apply Heckbert's locality criterion to quickly
+ * eliminate colormap entries that are far away from the subbox; typically
+ * three-fourths of the colormap entries are rejected by Heckbert's criterion,
+ * and we need not compute their distances to individual cells in the subbox.
+ * The speed of this approach is heavily influenced by the subbox size: too
+ * small means too much overhead, too big loses because Heckbert's criterion
+ * can't eliminate as many colormap entries.  Empirically the best subbox
+ * size seems to be about 1/512th of the histogram (1/8th in each direction).
+ *
+ * Thomas' article also describes a refined method which is asymptotically
+ * faster than the brute-force method, but it is also far more complex and
+ * cannot efficiently be applied to small subboxes.  It is therefore not
+ * useful for programs intended to be portable to DOS machines.  On machines
+ * with plenty of memory, filling the whole histogram in one shot with Thomas'
+ * refined method might be faster than the present code --- but then again,
+ * it might not be any faster, and it's certainly more complicated.
+ */
+
+
+/* log2(histogram cells in update box) for each axis; this can be adjusted */
+#define BOX_C0_LOG  (HIST_C0_BITS-3)
+#define BOX_C1_LOG  (HIST_C1_BITS-3)
+#define BOX_C2_LOG  (HIST_C2_BITS-3)
+
+#define BOX_C0_ELEMS  (1<<BOX_C0_LOG) /* # of hist cells in update box */
+#define BOX_C1_ELEMS  (1<<BOX_C1_LOG)
+#define BOX_C2_ELEMS  (1<<BOX_C2_LOG)
+
+#define BOX_C0_SHIFT  (C0_SHIFT + BOX_C0_LOG)
+#define BOX_C1_SHIFT  (C1_SHIFT + BOX_C1_LOG)
+#define BOX_C2_SHIFT  (C2_SHIFT + BOX_C2_LOG)
+
+
+/*
+ * The next three routines implement inverse colormap filling.  They could
+ * all be folded into one big routine, but splitting them up this way saves
+ * some stack space (the mindist[] and bestdist[] arrays need not coexist)
+ * and may allow some compilers to produce better code by registerizing more
+ * inner-loop variables.
+ */
+
+LOCAL(int)
+find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
+		    JSAMPLE colorlist[])
+/* Locate the colormap entries close enough to an update box to be candidates
+ * for the nearest entry to some cell(s) in the update box.  The update box
+ * is specified by the center coordinates of its first cell.  The number of
+ * candidate colormap entries is returned, and their colormap indexes are
+ * placed in colorlist[].
+ * This routine uses Heckbert's "locally sorted search" criterion to select
+ * the colors that need further consideration.
+ */
+{
+  int numcolors = cinfo->actual_number_of_colors;
+  int maxc0, maxc1, maxc2;
+  int centerc0, centerc1, centerc2;
+  int i, x, ncolors;
+  INT32 minmaxdist, min_dist, max_dist, tdist;
+  INT32 mindist[MAXNUMCOLORS];	/* min distance to colormap entry i */
+
+  /* Compute true coordinates of update box's upper corner and center.
+   * Actually we compute the coordinates of the center of the upper-corner
+   * histogram cell, which are the upper bounds of the volume we care about.
+   * Note that since ">>" rounds down, the "center" values may be closer to
+   * min than to max; hence comparisons to them must be "<=", not "<".
+   */
+  maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
+  centerc0 = (minc0 + maxc0) >> 1;
+  maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
+  centerc1 = (minc1 + maxc1) >> 1;
+  maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
+  centerc2 = (minc2 + maxc2) >> 1;
+
+  /* For each color in colormap, find:
+   *  1. its minimum squared-distance to any point in the update box
+   *     (zero if color is within update box);
+   *  2. its maximum squared-distance to any point in the update box.
+   * Both of these can be found by considering only the corners of the box.
+   * We save the minimum distance for each color in mindist[];
+   * only the smallest maximum distance is of interest.
+   */
+  minmaxdist = 0x7FFFFFFFL;
+
+  for (i = 0; i < numcolors; i++) {
+    /* We compute the squared-c0-distance term, then add in the other two. */
+    x = GETJSAMPLE(cinfo->colormap[0][i]);
+    if (x < minc0) {
+      tdist = (x - minc0) * C0_SCALE;
+      min_dist = tdist*tdist;
+      tdist = (x - maxc0) * C0_SCALE;
+      max_dist = tdist*tdist;
+    } else if (x > maxc0) {
+      tdist = (x - maxc0) * C0_SCALE;
+      min_dist = tdist*tdist;
+      tdist = (x - minc0) * C0_SCALE;
+      max_dist = tdist*tdist;
+    } else {
+      /* within cell range so no contribution to min_dist */
+      min_dist = 0;
+      if (x <= centerc0) {
+	tdist = (x - maxc0) * C0_SCALE;
+	max_dist = tdist*tdist;
+      } else {
+	tdist = (x - minc0) * C0_SCALE;
+	max_dist = tdist*tdist;
+      }
+    }
+
+    x = GETJSAMPLE(cinfo->colormap[1][i]);
+    if (x < minc1) {
+      tdist = (x - minc1) * C1_SCALE;
+      min_dist += tdist*tdist;
+      tdist = (x - maxc1) * C1_SCALE;
+      max_dist += tdist*tdist;
+    } else if (x > maxc1) {
+      tdist = (x - maxc1) * C1_SCALE;
+      min_dist += tdist*tdist;
+      tdist = (x - minc1) * C1_SCALE;
+      max_dist += tdist*tdist;
+    } else {
+      /* within cell range so no contribution to min_dist */
+      if (x <= centerc1) {
+	tdist = (x - maxc1) * C1_SCALE;
+	max_dist += tdist*tdist;
+      } else {
+	tdist = (x - minc1) * C1_SCALE;
+	max_dist += tdist*tdist;
+      }
+    }
+
+    x = GETJSAMPLE(cinfo->colormap[2][i]);
+    if (x < minc2) {
+      tdist = (x - minc2) * C2_SCALE;
+      min_dist += tdist*tdist;
+      tdist = (x - maxc2) * C2_SCALE;
+      max_dist += tdist*tdist;
+    } else if (x > maxc2) {
+      tdist = (x - maxc2) * C2_SCALE;
+      min_dist += tdist*tdist;
+      tdist = (x - minc2) * C2_SCALE;
+      max_dist += tdist*tdist;
+    } else {
+      /* within cell range so no contribution to min_dist */
+      if (x <= centerc2) {
+	tdist = (x - maxc2) * C2_SCALE;
+	max_dist += tdist*tdist;
+      } else {
+	tdist = (x - minc2) * C2_SCALE;
+	max_dist += tdist*tdist;
+      }
+    }
+
+    mindist[i] = min_dist;	/* save away the results */
+    if (max_dist < minmaxdist)
+      minmaxdist = max_dist;
+  }
+
+  /* Now we know that no cell in the update box is more than minmaxdist
+   * away from some colormap entry.  Therefore, only colors that are
+   * within minmaxdist of some part of the box need be considered.
+   */
+  ncolors = 0;
+  for (i = 0; i < numcolors; i++) {
+    if (mindist[i] <= minmaxdist)
+      colorlist[ncolors++] = (JSAMPLE) i;
+  }
+  return ncolors;
+}
+
+
+LOCAL(void)
+find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
+		  int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
+/* Find the closest colormap entry for each cell in the update box,
+ * given the list of candidate colors prepared by find_nearby_colors.
+ * Return the indexes of the closest entries in the bestcolor[] array.
+ * This routine uses Thomas' incremental distance calculation method to
+ * find the distance from a colormap entry to successive cells in the box.
+ */
+{
+  int ic0, ic1, ic2;
+  int i, icolor;
+  register INT32 * bptr;	/* pointer into bestdist[] array */
+  JSAMPLE * cptr;		/* pointer into bestcolor[] array */
+  INT32 dist0, dist1;		/* initial distance values */
+  register INT32 dist2;		/* current distance in inner loop */
+  INT32 xx0, xx1;		/* distance increments */
+  register INT32 xx2;
+  INT32 inc0, inc1, inc2;	/* initial values for increments */
+  /* This array holds the distance to the nearest-so-far color for each cell */
+  INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+  /* Initialize best-distance for each cell of the update box */
+  bptr = bestdist;
+  for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
+    *bptr++ = 0x7FFFFFFFL;
+  
+  /* For each color selected by find_nearby_colors,
+   * compute its distance to the center of each cell in the box.
+   * If that's less than best-so-far, update best distance and color number.
+   */
+  
+  /* Nominal steps between cell centers ("x" in Thomas article) */
+#define STEP_C0  ((1 << C0_SHIFT) * C0_SCALE)
+#define STEP_C1  ((1 << C1_SHIFT) * C1_SCALE)
+#define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)
+  
+  for (i = 0; i < numcolors; i++) {
+    icolor = GETJSAMPLE(colorlist[i]);
+    /* Compute (square of) distance from minc0/c1/c2 to this color */
+    inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
+    dist0 = inc0*inc0;
+    inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
+    dist0 += inc1*inc1;
+    inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
+    dist0 += inc2*inc2;
+    /* Form the initial difference increments */
+    inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
+    inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
+    inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
+    /* Now loop over all cells in box, updating distance per Thomas method */
+    bptr = bestdist;
+    cptr = bestcolor;
+    xx0 = inc0;
+    for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
+      dist1 = dist0;
+      xx1 = inc1;
+      for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
+	dist2 = dist1;
+	xx2 = inc2;
+	for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
+	  if (dist2 < *bptr) {
+	    *bptr = dist2;
+	    *cptr = (JSAMPLE) icolor;
+	  }
+	  dist2 += xx2;
+	  xx2 += 2 * STEP_C2 * STEP_C2;
+	  bptr++;
+	  cptr++;
+	}
+	dist1 += xx1;
+	xx1 += 2 * STEP_C1 * STEP_C1;
+      }
+      dist0 += xx0;
+      xx0 += 2 * STEP_C0 * STEP_C0;
+    }
+  }
+}
+
+
+LOCAL(void)
+fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
+/* Fill the inverse-colormap entries in the update box that contains */
+/* histogram cell c0/c1/c2.  (Only that one cell MUST be filled, but */
+/* we can fill as many others as we wish.) */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  hist3d histogram = cquantize->histogram;
+  int minc0, minc1, minc2;	/* lower left corner of update box */
+  int ic0, ic1, ic2;
+  register JSAMPLE * cptr;	/* pointer into bestcolor[] array */
+  register histptr cachep;	/* pointer into main cache array */
+  /* This array lists the candidate colormap indexes. */
+  JSAMPLE colorlist[MAXNUMCOLORS];
+  int numcolors;		/* number of candidate colors */
+  /* This array holds the actually closest colormap index for each cell. */
+  JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+  /* Convert cell coordinates to update box ID */
+  c0 >>= BOX_C0_LOG;
+  c1 >>= BOX_C1_LOG;
+  c2 >>= BOX_C2_LOG;
+
+  /* Compute true coordinates of update box's origin corner.
+   * Actually we compute the coordinates of the center of the corner
+   * histogram cell, which are the lower bounds of the volume we care about.
+   */
+  minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
+  minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
+  minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
+  
+  /* Determine which colormap entries are close enough to be candidates
+   * for the nearest entry to some cell in the update box.
+   */
+  numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
+
+  /* Determine the actually nearest colors. */
+  find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
+		   bestcolor);
+
+  /* Save the best color numbers (plus 1) in the main cache array */
+  c0 <<= BOX_C0_LOG;		/* convert ID back to base cell indexes */
+  c1 <<= BOX_C1_LOG;
+  c2 <<= BOX_C2_LOG;
+  cptr = bestcolor;
+  for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
+    for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
+      cachep = & histogram[c0+ic0][c1+ic1][c2];
+      for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
+	*cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
+      }
+    }
+  }
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ */
+
+METHODDEF(void)
+pass2_no_dither (j_decompress_ptr cinfo,
+		 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+/* This version performs no dithering */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  hist3d histogram = cquantize->histogram;
+  register JSAMPROW inptr, outptr;
+  register histptr cachep;
+  register int c0, c1, c2;
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+
+  for (row = 0; row < num_rows; row++) {
+    inptr = input_buf[row];
+    outptr = output_buf[row];
+    for (col = width; col > 0; col--) {
+      /* get pixel value and index into the cache */
+      c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
+      c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
+      c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
+      cachep = & histogram[c0][c1][c2];
+      /* If we have not seen this color before, find nearest colormap entry */
+      /* and update the cache */
+      if (*cachep == 0)
+	fill_inverse_cmap(cinfo, c0,c1,c2);
+      /* Now emit the colormap index for this cell */
+      *outptr++ = (JSAMPLE) (*cachep - 1);
+    }
+  }
+}
+
+
+METHODDEF(void)
+pass2_fs_dither (j_decompress_ptr cinfo,
+		 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+/* This version performs Floyd-Steinberg dithering */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  hist3d histogram = cquantize->histogram;
+  register LOCFSERROR cur0, cur1, cur2;	/* current error or pixel value */
+  LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
+  LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
+  register FSERRPTR errorptr;	/* => fserrors[] at column before current */
+  JSAMPROW inptr;		/* => current input pixel */
+  JSAMPROW outptr;		/* => current output pixel */
+  histptr cachep;
+  int dir;			/* +1 or -1 depending on direction */
+  int dir3;			/* 3*dir, for advancing inptr & errorptr */
+  int row;
+  JDIMENSION col;
+  JDIMENSION width = cinfo->output_width;
+  JSAMPLE *range_limit = cinfo->sample_range_limit;
+  int *error_limit = cquantize->error_limiter;
+  JSAMPROW colormap0 = cinfo->colormap[0];
+  JSAMPROW colormap1 = cinfo->colormap[1];
+  JSAMPROW colormap2 = cinfo->colormap[2];
+  SHIFT_TEMPS
+
+  for (row = 0; row < num_rows; row++) {
+    inptr = input_buf[row];
+    outptr = output_buf[row];
+    if (cquantize->on_odd_row) {
+      /* work right to left in this row */
+      inptr += (width-1) * 3;	/* so point to rightmost pixel */
+      outptr += width-1;
+      dir = -1;
+      dir3 = -3;
+      errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */
+      cquantize->on_odd_row = FALSE; /* flip for next time */
+    } else {
+      /* work left to right in this row */
+      dir = 1;
+      dir3 = 3;
+      errorptr = cquantize->fserrors; /* => entry before first real column */
+      cquantize->on_odd_row = TRUE; /* flip for next time */
+    }
+    /* Preset error values: no error propagated to first pixel from left */
+    cur0 = cur1 = cur2 = 0;
+    /* and no error propagated to row below yet */
+    belowerr0 = belowerr1 = belowerr2 = 0;
+    bpreverr0 = bpreverr1 = bpreverr2 = 0;
+
+    for (col = width; col > 0; col--) {
+      /* curN holds the error propagated from the previous pixel on the
+       * current line.  Add the error propagated from the previous line
+       * to form the complete error correction term for this pixel, and
+       * round the error term (which is expressed * 16) to an integer.
+       * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
+       * for either sign of the error value.
+       * Note: errorptr points to *previous* column's array entry.
+       */
+      cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
+      cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
+      cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
+      /* Limit the error using transfer function set by init_error_limit.
+       * See comments with init_error_limit for rationale.
+       */
+      cur0 = error_limit[cur0];
+      cur1 = error_limit[cur1];
+      cur2 = error_limit[cur2];
+      /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
+       * The maximum error is +- MAXJSAMPLE (or less with error limiting);
+       * this sets the required size of the range_limit array.
+       */
+      cur0 += GETJSAMPLE(inptr[0]);
+      cur1 += GETJSAMPLE(inptr[1]);
+      cur2 += GETJSAMPLE(inptr[2]);
+      cur0 = GETJSAMPLE(range_limit[cur0]);
+      cur1 = GETJSAMPLE(range_limit[cur1]);
+      cur2 = GETJSAMPLE(range_limit[cur2]);
+      /* Index into the cache with adjusted pixel value */
+      cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
+      /* If we have not seen this color before, find nearest colormap */
+      /* entry and update the cache */
+      if (*cachep == 0)
+	fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
+      /* Now emit the colormap index for this cell */
+      { register int pixcode = *cachep - 1;
+	*outptr = (JSAMPLE) pixcode;
+	/* Compute representation error for this pixel */
+	cur0 -= GETJSAMPLE(colormap0[pixcode]);
+	cur1 -= GETJSAMPLE(colormap1[pixcode]);
+	cur2 -= GETJSAMPLE(colormap2[pixcode]);
+      }
+      /* Compute error fractions to be propagated to adjacent pixels.
+       * Add these into the running sums, and simultaneously shift the
+       * next-line error sums left by 1 column.
+       */
+      { register LOCFSERROR bnexterr, delta;
+
+	bnexterr = cur0;	/* Process component 0 */
+	delta = cur0 * 2;
+	cur0 += delta;		/* form error * 3 */
+	errorptr[0] = (FSERROR) (bpreverr0 + cur0);
+	cur0 += delta;		/* form error * 5 */
+	bpreverr0 = belowerr0 + cur0;
+	belowerr0 = bnexterr;
+	cur0 += delta;		/* form error * 7 */
+	bnexterr = cur1;	/* Process component 1 */
+	delta = cur1 * 2;
+	cur1 += delta;		/* form error * 3 */
+	errorptr[1] = (FSERROR) (bpreverr1 + cur1);
+	cur1 += delta;		/* form error * 5 */
+	bpreverr1 = belowerr1 + cur1;
+	belowerr1 = bnexterr;
+	cur1 += delta;		/* form error * 7 */
+	bnexterr = cur2;	/* Process component 2 */
+	delta = cur2 * 2;
+	cur2 += delta;		/* form error * 3 */
+	errorptr[2] = (FSERROR) (bpreverr2 + cur2);
+	cur2 += delta;		/* form error * 5 */
+	bpreverr2 = belowerr2 + cur2;
+	belowerr2 = bnexterr;
+	cur2 += delta;		/* form error * 7 */
+      }
+      /* At this point curN contains the 7/16 error value to be propagated
+       * to the next pixel on the current line, and all the errors for the
+       * next line have been shifted over.  We are therefore ready to move on.
+       */
+      inptr += dir3;		/* Advance pixel pointers to next column */
+      outptr += dir;
+      errorptr += dir3;		/* advance errorptr to current column */
+    }
+    /* Post-loop cleanup: we must unload the final error values into the
+     * final fserrors[] entry.  Note we need not unload belowerrN because
+     * it is for the dummy column before or after the actual array.
+     */
+    errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
+    errorptr[1] = (FSERROR) bpreverr1;
+    errorptr[2] = (FSERROR) bpreverr2;
+  }
+}
+
+
+/*
+ * Initialize the error-limiting transfer function (lookup table).
+ * The raw F-S error computation can potentially compute error values of up to
+ * +- MAXJSAMPLE.  But we want the maximum correction applied to a pixel to be
+ * much less, otherwise obviously wrong pixels will be created.  (Typical
+ * effects include weird fringes at color-area boundaries, isolated bright
+ * pixels in a dark area, etc.)  The standard advice for avoiding this problem
+ * is to ensure that the "corners" of the color cube are allocated as output
+ * colors; then repeated errors in the same direction cannot cause cascading
+ * error buildup.  However, that only prevents the error from getting
+ * completely out of hand; Aaron Giles reports that error limiting improves
+ * the results even with corner colors allocated.
+ * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
+ * well, but the smoother transfer function used below is even better.  Thanks
+ * to Aaron Giles for this idea.
+ */
+
+LOCAL(void)
+init_error_limit (j_decompress_ptr cinfo)
+/* Allocate and fill in the error_limiter table */
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  int * table;
+  int in, out;
+
+  table = (int *) (*cinfo->mem->alloc_small)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int));
+  table += MAXJSAMPLE;		/* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
+  cquantize->error_limiter = table;
+
+#define STEPSIZE ((MAXJSAMPLE+1)/16)
+  /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
+  out = 0;
+  for (in = 0; in < STEPSIZE; in++, out++) {
+    table[in] = out; table[-in] = -out;
+  }
+  /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
+  for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) {
+    table[in] = out; table[-in] = -out;
+  }
+  /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
+  for (; in <= MAXJSAMPLE; in++) {
+    table[in] = out; table[-in] = -out;
+  }
+#undef STEPSIZE
+}
+
+
+/*
+ * Finish up at the end of each pass.
+ */
+
+METHODDEF(void)
+finish_pass1 (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+
+  /* Select the representative colors and fill in cinfo->colormap */
+  cinfo->colormap = cquantize->sv_colormap;
+  select_colors(cinfo, cquantize->desired);
+  /* Force next pass to zero the color index table */
+  cquantize->needs_zeroed = TRUE;
+}
+
+
+METHODDEF(void)
+finish_pass2 (j_decompress_ptr cinfo)
+{
+  /* no work */
+}
+
+
+/*
+ * Initialize for each processing pass.
+ */
+
+METHODDEF(void)
+start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  hist3d histogram = cquantize->histogram;
+  int i;
+
+  /* Only F-S dithering or no dithering is supported. */
+  /* If user asks for ordered dither, give him F-S. */
+  if (cinfo->dither_mode != JDITHER_NONE)
+    cinfo->dither_mode = JDITHER_FS;
+
+  if (is_pre_scan) {
+    /* Set up method pointers */
+    cquantize->pub.color_quantize = prescan_quantize;
+    cquantize->pub.finish_pass = finish_pass1;
+    cquantize->needs_zeroed = TRUE; /* Always zero histogram */
+  } else {
+    /* Set up method pointers */
+    if (cinfo->dither_mode == JDITHER_FS)
+      cquantize->pub.color_quantize = pass2_fs_dither;
+    else
+      cquantize->pub.color_quantize = pass2_no_dither;
+    cquantize->pub.finish_pass = finish_pass2;
+
+    /* Make sure color count is acceptable */
+    i = cinfo->actual_number_of_colors;
+    if (i < 1)
+      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
+    if (i > MAXNUMCOLORS)
+      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
+
+    if (cinfo->dither_mode == JDITHER_FS) {
+      size_t arraysize = (size_t) ((cinfo->output_width + 2) *
+				   (3 * SIZEOF(FSERROR)));
+      /* Allocate Floyd-Steinberg workspace if we didn't already. */
+      if (cquantize->fserrors == NULL)
+	cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+	  ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
+      /* Initialize the propagated errors to zero. */
+      jzero_far((void FAR *) cquantize->fserrors, arraysize);
+      /* Make the error-limit table if we didn't already. */
+      if (cquantize->error_limiter == NULL)
+	init_error_limit(cinfo);
+      cquantize->on_odd_row = FALSE;
+    }
+
+  }
+  /* Zero the histogram or inverse color map, if necessary */
+  if (cquantize->needs_zeroed) {
+    for (i = 0; i < HIST_C0_ELEMS; i++) {
+      jzero_far((void FAR *) histogram[i],
+		HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
+    }
+    cquantize->needs_zeroed = FALSE;
+  }
+}
+
+
+/*
+ * Switch to a new external colormap between output passes.
+ */
+
+METHODDEF(void)
+new_color_map_2_quant (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+
+  /* Reset the inverse color map */
+  cquantize->needs_zeroed = TRUE;
+}
+
+
+/*
+ * Module initialization routine for 2-pass color quantization.
+ */
+
+GLOBAL(void)
+jinit_2pass_quantizer (j_decompress_ptr cinfo)
+{
+  my_cquantize_ptr cquantize;
+  int i;
+
+  cquantize = (my_cquantize_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_cquantizer));
+  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
+  cquantize->pub.start_pass = start_pass_2_quant;
+  cquantize->pub.new_color_map = new_color_map_2_quant;
+  cquantize->fserrors = NULL;	/* flag optional arrays not allocated */
+  cquantize->error_limiter = NULL;
+
+  /* Make sure jdmaster didn't give me a case I can't handle */
+  if (cinfo->out_color_components != 3)
+    ERREXIT(cinfo, JERR_NOTIMPL);
+
+  /* Allocate the histogram/inverse colormap storage */
+  cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
+  for (i = 0; i < HIST_C0_ELEMS; i++) {
+    cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
+      ((j_common_ptr) cinfo, JPOOL_IMAGE,
+       HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
+  }
+  cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
+
+  /* Allocate storage for the completed colormap, if required.
+   * We do this now since it is FAR storage and may affect
+   * the memory manager's space calculations.
+   */
+  if (cinfo->enable_2pass_quant) {
+    /* Make sure color count is acceptable */
+    int desired = cinfo->desired_number_of_colors;
+    /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
+    if (desired < 8)
+      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
+    /* Make sure colormap indexes can be represented by JSAMPLEs */
+    if (desired > MAXNUMCOLORS)
+      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
+    cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
+      ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
+    cquantize->desired = desired;
+  } else
+    cquantize->sv_colormap = NULL;
+
+  /* Only F-S dithering or no dithering is supported. */
+  /* If user asks for ordered dither, give him F-S. */
+  if (cinfo->dither_mode != JDITHER_NONE)
+    cinfo->dither_mode = JDITHER_FS;
+
+  /* Allocate Floyd-Steinberg workspace if necessary.
+   * This isn't really needed until pass 2, but again it is FAR storage.
+   * Although we will cope with a later change in dither_mode,
+   * we do not promise to honor max_memory_to_use if dither_mode changes.
+   */
+  if (cinfo->dither_mode == JDITHER_FS) {
+    cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+      ((j_common_ptr) cinfo, JPOOL_IMAGE,
+       (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
+    /* Might as well create the error-limiting table too. */
+    init_error_limit(cinfo);
+  }
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
diff --git a/Utilities/FLTK/jpeg/jutils.c b/Utilities/FLTK/jpeg/jutils.c
new file mode 100644
index 0000000000000000000000000000000000000000..d18a9555621bae9dce0b814e8afc7c05e877a4cb
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jutils.c
@@ -0,0 +1,179 @@
+/*
+ * jutils.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains tables and miscellaneous utility routines needed
+ * for both compression and decompression.
+ * Note we prefix all global names with "j" to minimize conflicts with
+ * a surrounding application.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
+ * of a DCT block read in natural order (left to right, top to bottom).
+ */
+
+#if 0				/* This table is not actually needed in v6a */
+
+const int jpeg_zigzag_order[DCTSIZE2] = {
+   0,  1,  5,  6, 14, 15, 27, 28,
+   2,  4,  7, 13, 16, 26, 29, 42,
+   3,  8, 12, 17, 25, 30, 41, 43,
+   9, 11, 18, 24, 31, 40, 44, 53,
+  10, 19, 23, 32, 39, 45, 52, 54,
+  20, 22, 33, 38, 46, 51, 55, 60,
+  21, 34, 37, 47, 50, 56, 59, 61,
+  35, 36, 48, 49, 57, 58, 62, 63
+};
+
+#endif
+
+/*
+ * jpeg_natural_order[i] is the natural-order position of the i'th element
+ * of zigzag order.
+ *
+ * When reading corrupted data, the Huffman decoders could attempt
+ * to reference an entry beyond the end of this array (if the decoded
+ * zero run length reaches past the end of the block).  To prevent
+ * wild stores without adding an inner-loop test, we put some extra
+ * "63"s after the real entries.  This will cause the extra coefficient
+ * to be stored in location 63 of the block, not somewhere random.
+ * The worst case would be a run-length of 15, which means we need 16
+ * fake entries.
+ */
+
+const int jpeg_natural_order[DCTSIZE2+16] = {
+  0,  1,  8, 16,  9,  2,  3, 10,
+ 17, 24, 32, 25, 18, 11,  4,  5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13,  6,  7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
+ 63, 63, 63, 63, 63, 63, 63, 63
+};
+
+
+/*
+ * Arithmetic utilities
+ */
+
+GLOBAL(long)
+jdiv_round_up (long a, long b)
+/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
+/* Assumes a >= 0, b > 0 */
+{
+  return (a + b - 1L) / b;
+}
+
+
+GLOBAL(long)
+jround_up (long a, long b)
+/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
+/* Assumes a >= 0, b > 0 */
+{
+  a += b - 1L;
+  return a - (a % b);
+}
+
+
+/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
+ * and coefficient-block arrays.  This won't work on 80x86 because the arrays
+ * are FAR and we're assuming a small-pointer memory model.  However, some
+ * DOS compilers provide far-pointer versions of memcpy() and memset() even
+ * in the small-model libraries.  These will be used if USE_FMEM is defined.
+ * Otherwise, the routines below do it the hard way.  (The performance cost
+ * is not all that great, because these routines aren't very heavily used.)
+ */
+
+#ifndef NEED_FAR_POINTERS	/* normal case, same as regular macros */
+#define FMEMCOPY(dest,src,size)	MEMCOPY(dest,src,size)
+#define FMEMZERO(target,size)	MEMZERO(target,size)
+#else				/* 80x86 case, define if we can */
+#ifdef USE_FMEM
+#define FMEMCOPY(dest,src,size)	_fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
+#define FMEMZERO(target,size)	_fmemset((void FAR *)(target), 0, (size_t)(size))
+#endif
+#endif
+
+
+GLOBAL(void)
+jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
+		   JSAMPARRAY output_array, int dest_row,
+		   int num_rows, JDIMENSION num_cols)
+/* Copy some rows of samples from one place to another.
+ * num_rows rows are copied from input_array[source_row++]
+ * to output_array[dest_row++]; these areas may overlap for duplication.
+ * The source and destination arrays must be at least as wide as num_cols.
+ */
+{
+  register JSAMPROW inptr, outptr;
+#ifdef FMEMCOPY
+  register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
+#else
+  register JDIMENSION count;
+#endif
+  register int row;
+
+  input_array += source_row;
+  output_array += dest_row;
+
+  for (row = num_rows; row > 0; row--) {
+    inptr = *input_array++;
+    outptr = *output_array++;
+#ifdef FMEMCOPY
+    FMEMCOPY(outptr, inptr, count);
+#else
+    for (count = num_cols; count > 0; count--)
+      *outptr++ = *inptr++;	/* needn't bother with GETJSAMPLE() here */
+#endif
+  }
+}
+
+
+GLOBAL(void)
+jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
+		 JDIMENSION num_blocks)
+/* Copy a row of coefficient blocks from one place to another. */
+{
+#ifdef FMEMCOPY
+  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
+#else
+  register JCOEFPTR inptr, outptr;
+  register long count;
+
+  inptr = (JCOEFPTR) input_row;
+  outptr = (JCOEFPTR) output_row;
+  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
+    *outptr++ = *inptr++;
+  }
+#endif
+}
+
+
+GLOBAL(void)
+jzero_far (void FAR * target, size_t bytestozero)
+/* Zero out a chunk of FAR memory. */
+/* This might be sample-array data, block-array data, or alloc_large data. */
+{
+#ifdef FMEMZERO
+  FMEMZERO(target, bytestozero);
+#else
+  register char FAR * ptr = (char FAR *) target;
+  register size_t count;
+
+  for (count = bytestozero; count > 0; count--) {
+    *ptr++ = 0;
+  }
+#endif
+}
diff --git a/Utilities/FLTK/jpeg/jversion.h b/Utilities/FLTK/jpeg/jversion.h
new file mode 100644
index 0000000000000000000000000000000000000000..6472c58d351ac6a286443f692a8ec07a4a752877
--- /dev/null
+++ b/Utilities/FLTK/jpeg/jversion.h
@@ -0,0 +1,14 @@
+/*
+ * jversion.h
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains software version identification.
+ */
+
+
+#define JVERSION	"6b  27-Mar-1998"
+
+#define JCOPYRIGHT	"Copyright (C) 1998, Thomas G. Lane"
diff --git a/Utilities/FLTK/jpeg/libjpeg.doc b/Utilities/FLTK/jpeg/libjpeg.doc
new file mode 100644
index 0000000000000000000000000000000000000000..689b206c07fdfa03e915abaaf2d7aa458d8cf5bc
--- /dev/null
+++ b/Utilities/FLTK/jpeg/libjpeg.doc
@@ -0,0 +1,3006 @@
+USING THE IJG JPEG LIBRARY
+
+Copyright (C) 1994-1998, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+This file describes how to use the IJG JPEG library within an application
+program.  Read it if you want to write a program that uses the library.
+
+The file example.c provides heavily commented skeleton code for calling the
+JPEG library.  Also see jpeglib.h (the include file to be used by application
+programs) for full details about data structures and function parameter lists.
+The library source code, of course, is the ultimate reference.
+
+Note that there have been *major* changes from the application interface
+presented by IJG version 4 and earlier versions.  The old design had several
+inherent limitations, and it had accumulated a lot of cruft as we added
+features while trying to minimize application-interface changes.  We have
+sacrificed backward compatibility in the version 5 rewrite, but we think the
+improvements justify this.
+
+
+TABLE OF CONTENTS
+-----------------
+
+Overview:
+	Functions provided by the library
+	Outline of typical usage
+Basic library usage:
+	Data formats
+	Compression details
+	Decompression details
+	Mechanics of usage: include files, linking, etc
+Advanced features:
+	Compression parameter selection
+	Decompression parameter selection
+	Special color spaces
+	Error handling
+	Compressed data handling (source and destination managers)
+	I/O suspension
+	Progressive JPEG support
+	Buffered-image mode
+	Abbreviated datastreams and multiple images
+	Special markers
+	Raw (downsampled) image data
+	Really raw data: DCT coefficients
+	Progress monitoring
+	Memory management
+	Memory usage
+	Library compile-time options
+	Portability considerations
+	Notes for MS-DOS implementors
+
+You should read at least the overview and basic usage sections before trying
+to program with the library.  The sections on advanced features can be read
+if and when you need them.
+
+
+OVERVIEW
+========
+
+Functions provided by the library
+---------------------------------
+
+The IJG JPEG library provides C code to read and write JPEG-compressed image
+files.  The surrounding application program receives or supplies image data a
+scanline at a time, using a straightforward uncompressed image format.  All
+details of color conversion and other preprocessing/postprocessing can be
+handled by the library.
+
+The library includes a substantial amount of code that is not covered by the
+JPEG standard but is necessary for typical applications of JPEG.  These
+functions preprocess the image before JPEG compression or postprocess it after
+decompression.  They include colorspace conversion, downsampling/upsampling,
+and color quantization.  The application indirectly selects use of this code
+by specifying the format in which it wishes to supply or receive image data.
+For example, if colormapped output is requested, then the decompression
+library automatically invokes color quantization.
+
+A wide range of quality vs. speed tradeoffs are possible in JPEG processing,
+and even more so in decompression postprocessing.  The decompression library
+provides multiple implementations that cover most of the useful tradeoffs,
+ranging from very-high-quality down to fast-preview operation.  On the
+compression side we have generally not provided low-quality choices, since
+compression is normally less time-critical.  It should be understood that the
+low-quality modes may not meet the JPEG standard's accuracy requirements;
+nonetheless, they are useful for viewers.
+
+A word about functions *not* provided by the library.  We handle a subset of
+the ISO JPEG standard; most baseline, extended-sequential, and progressive
+JPEG processes are supported.  (Our subset includes all features now in common
+use.)  Unsupported ISO options include:
+	* Hierarchical storage
+	* Lossless JPEG
+	* Arithmetic entropy coding (unsupported for legal reasons)
+	* DNL marker
+	* Nonintegral subsampling ratios
+We support both 8- and 12-bit data precision, but this is a compile-time
+choice rather than a run-time choice; hence it is difficult to use both
+precisions in a single application.
+
+By itself, the library handles only interchange JPEG datastreams --- in
+particular the widely used JFIF file format.  The library can be used by
+surrounding code to process interchange or abbreviated JPEG datastreams that
+are embedded in more complex file formats.  (For example, this library is
+used by the free LIBTIFF library to support JPEG compression in TIFF.)
+
+
+Outline of typical usage
+------------------------
+
+The rough outline of a JPEG compression operation is:
+
+	Allocate and initialize a JPEG compression object
+	Specify the destination for the compressed data (eg, a file)
+	Set parameters for compression, including image size & colorspace
+	jpeg_start_compress(...);
+	while (scan lines remain to be written)
+		jpeg_write_scanlines(...);
+	jpeg_finish_compress(...);
+	Release the JPEG compression object
+
+A JPEG compression object holds parameters and working state for the JPEG
+library.  We make creation/destruction of the object separate from starting
+or finishing compression of an image; the same object can be re-used for a
+series of image compression operations.  This makes it easy to re-use the
+same parameter settings for a sequence of images.  Re-use of a JPEG object
+also has important implications for processing abbreviated JPEG datastreams,
+as discussed later.
+
+The image data to be compressed is supplied to jpeg_write_scanlines() from
+in-memory buffers.  If the application is doing file-to-file compression,
+reading image data from the source file is the application's responsibility.
+The library emits compressed data by calling a "data destination manager",
+which typically will write the data into a file; but the application can
+provide its own destination manager to do something else.
+
+Similarly, the rough outline of a JPEG decompression operation is:
+
+	Allocate and initialize a JPEG decompression object
+	Specify the source of the compressed data (eg, a file)
+	Call jpeg_read_header() to obtain image info
+	Set parameters for decompression
+	jpeg_start_decompress(...);
+	while (scan lines remain to be read)
+		jpeg_read_scanlines(...);
+	jpeg_finish_decompress(...);
+	Release the JPEG decompression object
+
+This is comparable to the compression outline except that reading the
+datastream header is a separate step.  This is helpful because information
+about the image's size, colorspace, etc is available when the application
+selects decompression parameters.  For example, the application can choose an
+output scaling ratio that will fit the image into the available screen size.
+
+The decompression library obtains compressed data by calling a data source
+manager, which typically will read the data from a file; but other behaviors
+can be obtained with a custom source manager.  Decompressed data is delivered
+into in-memory buffers passed to jpeg_read_scanlines().
+
+It is possible to abort an incomplete compression or decompression operation
+by calling jpeg_abort(); or, if you do not need to retain the JPEG object,
+simply release it by calling jpeg_destroy().
+
+JPEG compression and decompression objects are two separate struct types.
+However, they share some common fields, and certain routines such as
+jpeg_destroy() can work on either type of object.
+
+The JPEG library has no static variables: all state is in the compression
+or decompression object.  Therefore it is possible to process multiple
+compression and decompression operations concurrently, using multiple JPEG
+objects.
+
+Both compression and decompression can be done in an incremental memory-to-
+memory fashion, if suitable source/destination managers are used.  See the
+section on "I/O suspension" for more details.
+
+
+BASIC LIBRARY USAGE
+===================
+
+Data formats
+------------
+
+Before diving into procedural details, it is helpful to understand the
+image data format that the JPEG library expects or returns.
+
+The standard input image format is a rectangular array of pixels, with each
+pixel having the same number of "component" or "sample" values (color
+channels).  You must specify how many components there are and the colorspace
+interpretation of the components.  Most applications will use RGB data
+(three components per pixel) or grayscale data (one component per pixel).
+PLEASE NOTE THAT RGB DATA IS THREE SAMPLES PER PIXEL, GRAYSCALE ONLY ONE.
+A remarkable number of people manage to miss this, only to find that their
+programs don't work with grayscale JPEG files.
+
+There is no provision for colormapped input.  JPEG files are always full-color
+or full grayscale (or sometimes another colorspace such as CMYK).  You can
+feed in a colormapped image by expanding it to full-color format.  However
+JPEG often doesn't work very well with source data that has been colormapped,
+because of dithering noise.  This is discussed in more detail in the JPEG FAQ
+and the other references mentioned in the README file.
+
+Pixels are stored by scanlines, with each scanline running from left to
+right.  The component values for each pixel are adjacent in the row; for
+example, R,G,B,R,G,B,R,G,B,... for 24-bit RGB color.  Each scanline is an
+array of data type JSAMPLE --- which is typically "unsigned char", unless
+you've changed jmorecfg.h.  (You can also change the RGB pixel layout, say
+to B,G,R order, by modifying jmorecfg.h.  But see the restrictions listed in
+that file before doing so.)
+
+A 2-D array of pixels is formed by making a list of pointers to the starts of
+scanlines; so the scanlines need not be physically adjacent in memory.  Even
+if you process just one scanline at a time, you must make a one-element
+pointer array to conform to this structure.  Pointers to JSAMPLE rows are of
+type JSAMPROW, and the pointer to the pointer array is of type JSAMPARRAY.
+
+The library accepts or supplies one or more complete scanlines per call.
+It is not possible to process part of a row at a time.  Scanlines are always
+processed top-to-bottom.  You can process an entire image in one call if you
+have it all in memory, but usually it's simplest to process one scanline at
+a time.
+
+For best results, source data values should have the precision specified by
+BITS_IN_JSAMPLE (normally 8 bits).  For instance, if you choose to compress
+data that's only 6 bits/channel, you should left-justify each value in a
+byte before passing it to the compressor.  If you need to compress data
+that has more than 8 bits/channel, compile with BITS_IN_JSAMPLE = 12.
+(See "Library compile-time options", later.)
+
+
+The data format returned by the decompressor is the same in all details,
+except that colormapped output is supported.  (Again, a JPEG file is never
+colormapped.  But you can ask the decompressor to perform on-the-fly color
+quantization to deliver colormapped output.)  If you request colormapped
+output then the returned data array contains a single JSAMPLE per pixel;
+its value is an index into a color map.  The color map is represented as
+a 2-D JSAMPARRAY in which each row holds the values of one color component,
+that is, colormap[i][j] is the value of the i'th color component for pixel
+value (map index) j.  Note that since the colormap indexes are stored in
+JSAMPLEs, the maximum number of colors is limited by the size of JSAMPLE
+(ie, at most 256 colors for an 8-bit JPEG library).
+
+
+Compression details
+-------------------
+
+Here we revisit the JPEG compression outline given in the overview.
+
+1. Allocate and initialize a JPEG compression object.
+
+A JPEG compression object is a "struct jpeg_compress_struct".  (It also has
+a bunch of subsidiary structures which are allocated via malloc(), but the
+application doesn't control those directly.)  This struct can be just a local
+variable in the calling routine, if a single routine is going to execute the
+whole JPEG compression sequence.  Otherwise it can be static or allocated
+from malloc().
+
+You will also need a structure representing a JPEG error handler.  The part
+of this that the library cares about is a "struct jpeg_error_mgr".  If you
+are providing your own error handler, you'll typically want to embed the
+jpeg_error_mgr struct in a larger structure; this is discussed later under
+"Error handling".  For now we'll assume you are just using the default error
+handler.  The default error handler will print JPEG error/warning messages
+on stderr, and it will call exit() if a fatal error occurs.
+
+You must initialize the error handler structure, store a pointer to it into
+the JPEG object's "err" field, and then call jpeg_create_compress() to
+initialize the rest of the JPEG object.
+
+Typical code for this step, if you are using the default error handler, is
+
+	struct jpeg_compress_struct cinfo;
+	struct jpeg_error_mgr jerr;
+	...
+	cinfo.err = jpeg_std_error(&jerr);
+	jpeg_create_compress(&cinfo);
+
+jpeg_create_compress allocates a small amount of memory, so it could fail
+if you are out of memory.  In that case it will exit via the error handler;
+that's why the error handler must be initialized first.
+
+
+2. Specify the destination for the compressed data (eg, a file).
+
+As previously mentioned, the JPEG library delivers compressed data to a
+"data destination" module.  The library includes one data destination
+module which knows how to write to a stdio stream.  You can use your own
+destination module if you want to do something else, as discussed later.
+
+If you use the standard destination module, you must open the target stdio
+stream beforehand.  Typical code for this step looks like:
+
+	FILE * outfile;
+	...
+	if ((outfile = fopen(filename, "wb")) == NULL) {
+	    fprintf(stderr, "can't open %s\n", filename);
+	    exit(1);
+	}
+	jpeg_stdio_dest(&cinfo, outfile);
+
+where the last line invokes the standard destination module.
+
+WARNING: it is critical that the binary compressed data be delivered to the
+output file unchanged.  On non-Unix systems the stdio library may perform
+newline translation or otherwise corrupt binary data.  To suppress this
+behavior, you may need to use a "b" option to fopen (as shown above), or use
+setmode() or another routine to put the stdio stream in binary mode.  See
+cjpeg.c and djpeg.c for code that has been found to work on many systems.
+
+You can select the data destination after setting other parameters (step 3),
+if that's more convenient.  You may not change the destination between
+calling jpeg_start_compress() and jpeg_finish_compress().
+
+
+3. Set parameters for compression, including image size & colorspace.
+
+You must supply information about the source image by setting the following
+fields in the JPEG object (cinfo structure):
+
+	image_width		Width of image, in pixels
+	image_height		Height of image, in pixels
+	input_components	Number of color channels (samples per pixel)
+	in_color_space		Color space of source image
+
+The image dimensions are, hopefully, obvious.  JPEG supports image dimensions
+of 1 to 64K pixels in either direction.  The input color space is typically
+RGB or grayscale, and input_components is 3 or 1 accordingly.  (See "Special
+color spaces", later, for more info.)  The in_color_space field must be
+assigned one of the J_COLOR_SPACE enum constants, typically JCS_RGB or
+JCS_GRAYSCALE.
+
+JPEG has a large number of compression parameters that determine how the
+image is encoded.  Most applications don't need or want to know about all
+these parameters.  You can set all the parameters to reasonable defaults by
+calling jpeg_set_defaults(); then, if there are particular values you want
+to change, you can do so after that.  The "Compression parameter selection"
+section tells about all the parameters.
+
+You must set in_color_space correctly before calling jpeg_set_defaults(),
+because the defaults depend on the source image colorspace.  However the
+other three source image parameters need not be valid until you call
+jpeg_start_compress().  There's no harm in calling jpeg_set_defaults() more
+than once, if that happens to be convenient.
+
+Typical code for a 24-bit RGB source image is
+
+	cinfo.image_width = Width; 	/* image width and height, in pixels */
+	cinfo.image_height = Height;
+	cinfo.input_components = 3;	/* # of color components per pixel */
+	cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+
+	jpeg_set_defaults(&cinfo);
+	/* Make optional parameter settings here */
+
+
+4. jpeg_start_compress(...);
+
+After you have established the data destination and set all the necessary
+source image info and other parameters, call jpeg_start_compress() to begin
+a compression cycle.  This will initialize internal state, allocate working
+storage, and emit the first few bytes of the JPEG datastream header.
+
+Typical code:
+
+	jpeg_start_compress(&cinfo, TRUE);
+
+The "TRUE" parameter ensures that a complete JPEG interchange datastream
+will be written.  This is appropriate in most cases.  If you think you might
+want to use an abbreviated datastream, read the section on abbreviated
+datastreams, below.
+
+Once you have called jpeg_start_compress(), you may not alter any JPEG
+parameters or other fields of the JPEG object until you have completed
+the compression cycle.
+
+
+5. while (scan lines remain to be written)
+	jpeg_write_scanlines(...);
+
+Now write all the required image data by calling jpeg_write_scanlines()
+one or more times.  You can pass one or more scanlines in each call, up
+to the total image height.  In most applications it is convenient to pass
+just one or a few scanlines at a time.  The expected format for the passed
+data is discussed under "Data formats", above.
+
+Image data should be written in top-to-bottom scanline order.  The JPEG spec
+contains some weasel wording about how top and bottom are application-defined
+terms (a curious interpretation of the English language...) but if you want
+your files to be compatible with everyone else's, you WILL use top-to-bottom
+order.  If the source data must be read in bottom-to-top order, you can use
+the JPEG library's virtual array mechanism to invert the data efficiently.
+Examples of this can be found in the sample application cjpeg.
+
+The library maintains a count of the number of scanlines written so far
+in the next_scanline field of the JPEG object.  Usually you can just use
+this variable as the loop counter, so that the loop test looks like
+"while (cinfo.next_scanline < cinfo.image_height)".
+
+Code for this step depends heavily on the way that you store the source data.
+example.c shows the following code for the case of a full-size 2-D source
+array containing 3-byte RGB pixels:
+
+	JSAMPROW row_pointer[1];	/* pointer to a single row */
+	int row_stride;			/* physical row width in buffer */
+
+	row_stride = image_width * 3;	/* JSAMPLEs per row in image_buffer */
+
+	while (cinfo.next_scanline < cinfo.image_height) {
+	    row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
+	    jpeg_write_scanlines(&cinfo, row_pointer, 1);
+	}
+
+jpeg_write_scanlines() returns the number of scanlines actually written.
+This will normally be equal to the number passed in, so you can usually
+ignore the return value.  It is different in just two cases:
+  * If you try to write more scanlines than the declared image height,
+    the additional scanlines are ignored.
+  * If you use a suspending data destination manager, output buffer overrun
+    will cause the compressor to return before accepting all the passed lines.
+    This feature is discussed under "I/O suspension", below.  The normal
+    stdio destination manager will NOT cause this to happen.
+In any case, the return value is the same as the change in the value of
+next_scanline.
+
+
+6. jpeg_finish_compress(...);
+
+After all the image data has been written, call jpeg_finish_compress() to
+complete the compression cycle.  This step is ESSENTIAL to ensure that the
+last bufferload of data is written to the data destination.
+jpeg_finish_compress() also releases working memory associated with the JPEG
+object.
+
+Typical code:
+
+	jpeg_finish_compress(&cinfo);
+
+If using the stdio destination manager, don't forget to close the output
+stdio stream (if necessary) afterwards.
+
+If you have requested a multi-pass operating mode, such as Huffman code
+optimization, jpeg_finish_compress() will perform the additional passes using
+data buffered by the first pass.  In this case jpeg_finish_compress() may take
+quite a while to complete.  With the default compression parameters, this will
+not happen.
+
+It is an error to call jpeg_finish_compress() before writing the necessary
+total number of scanlines.  If you wish to abort compression, call
+jpeg_abort() as discussed below.
+
+After completing a compression cycle, you may dispose of the JPEG object
+as discussed next, or you may use it to compress another image.  In that case
+return to step 2, 3, or 4 as appropriate.  If you do not change the
+destination manager, the new datastream will be written to the same target.
+If you do not change any JPEG parameters, the new datastream will be written
+with the same parameters as before.  Note that you can change the input image
+dimensions freely between cycles, but if you change the input colorspace, you
+should call jpeg_set_defaults() to adjust for the new colorspace; and then
+you'll need to repeat all of step 3.
+
+
+7. Release the JPEG compression object.
+
+When you are done with a JPEG compression object, destroy it by calling
+jpeg_destroy_compress().  This will free all subsidiary memory (regardless of
+the previous state of the object).  Or you can call jpeg_destroy(), which
+works for either compression or decompression objects --- this may be more
+convenient if you are sharing code between compression and decompression
+cases.  (Actually, these routines are equivalent except for the declared type
+of the passed pointer.  To avoid gripes from ANSI C compilers, jpeg_destroy()
+should be passed a j_common_ptr.)
+
+If you allocated the jpeg_compress_struct structure from malloc(), freeing
+it is your responsibility --- jpeg_destroy() won't.  Ditto for the error
+handler structure.
+
+Typical code:
+
+	jpeg_destroy_compress(&cinfo);
+
+
+8. Aborting.
+
+If you decide to abort a compression cycle before finishing, you can clean up
+in either of two ways:
+
+* If you don't need the JPEG object any more, just call
+  jpeg_destroy_compress() or jpeg_destroy() to release memory.  This is
+  legitimate at any point after calling jpeg_create_compress() --- in fact,
+  it's safe even if jpeg_create_compress() fails.
+
+* If you want to re-use the JPEG object, call jpeg_abort_compress(), or call
+  jpeg_abort() which works on both compression and decompression objects.
+  This will return the object to an idle state, releasing any working memory.
+  jpeg_abort() is allowed at any time after successful object creation.
+
+Note that cleaning up the data destination, if required, is your
+responsibility; neither of these routines will call term_destination().
+(See "Compressed data handling", below, for more about that.)
+
+jpeg_destroy() and jpeg_abort() are the only safe calls to make on a JPEG
+object that has reported an error by calling error_exit (see "Error handling"
+for more info).  The internal state of such an object is likely to be out of
+whack.  Either of these two routines will return the object to a known state.
+
+
+Decompression details
+---------------------
+
+Here we revisit the JPEG decompression outline given in the overview.
+
+1. Allocate and initialize a JPEG decompression object.
+
+This is just like initialization for compression, as discussed above,
+except that the object is a "struct jpeg_decompress_struct" and you
+call jpeg_create_decompress().  Error handling is exactly the same.
+
+Typical code:
+
+	struct jpeg_decompress_struct cinfo;
+	struct jpeg_error_mgr jerr;
+	...
+	cinfo.err = jpeg_std_error(&jerr);
+	jpeg_create_decompress(&cinfo);
+
+(Both here and in the IJG code, we usually use variable name "cinfo" for
+both compression and decompression objects.)
+
+
+2. Specify the source of the compressed data (eg, a file).
+
+As previously mentioned, the JPEG library reads compressed data from a "data
+source" module.  The library includes one data source module which knows how
+to read from a stdio stream.  You can use your own source module if you want
+to do something else, as discussed later.
+
+If you use the standard source module, you must open the source stdio stream
+beforehand.  Typical code for this step looks like:
+
+	FILE * infile;
+	...
+	if ((infile = fopen(filename, "rb")) == NULL) {
+	    fprintf(stderr, "can't open %s\n", filename);
+	    exit(1);
+	}
+	jpeg_stdio_src(&cinfo, infile);
+
+where the last line invokes the standard source module.
+
+WARNING: it is critical that the binary compressed data be read unchanged.
+On non-Unix systems the stdio library may perform newline translation or
+otherwise corrupt binary data.  To suppress this behavior, you may need to use
+a "b" option to fopen (as shown above), or use setmode() or another routine to
+put the stdio stream in binary mode.  See cjpeg.c and djpeg.c for code that
+has been found to work on many systems.
+
+You may not change the data source between calling jpeg_read_header() and
+jpeg_finish_decompress().  If you wish to read a series of JPEG images from
+a single source file, you should repeat the jpeg_read_header() to
+jpeg_finish_decompress() sequence without reinitializing either the JPEG
+object or the data source module; this prevents buffered input data from
+being discarded.
+
+
+3. Call jpeg_read_header() to obtain image info.
+
+Typical code for this step is just
+
+	jpeg_read_header(&cinfo, TRUE);
+
+This will read the source datastream header markers, up to the beginning
+of the compressed data proper.  On return, the image dimensions and other
+info have been stored in the JPEG object.  The application may wish to
+consult this information before selecting decompression parameters.
+
+More complex code is necessary if
+  * A suspending data source is used --- in that case jpeg_read_header()
+    may return before it has read all the header data.  See "I/O suspension",
+    below.  The normal stdio source manager will NOT cause this to happen.
+  * Abbreviated JPEG files are to be processed --- see the section on
+    abbreviated datastreams.  Standard applications that deal only in
+    interchange JPEG files need not be concerned with this case either.
+
+It is permissible to stop at this point if you just wanted to find out the
+image dimensions and other header info for a JPEG file.  In that case,
+call jpeg_destroy() when you are done with the JPEG object, or call
+jpeg_abort() to return it to an idle state before selecting a new data
+source and reading another header.
+
+
+4. Set parameters for decompression.
+
+jpeg_read_header() sets appropriate default decompression parameters based on
+the properties of the image (in particular, its colorspace).  However, you
+may well want to alter these defaults before beginning the decompression.
+For example, the default is to produce full color output from a color file.
+If you want colormapped output you must ask for it.  Other options allow the
+returned image to be scaled and allow various speed/quality tradeoffs to be
+selected.  "Decompression parameter selection", below, gives details.
+
+If the defaults are appropriate, nothing need be done at this step.
+
+Note that all default values are set by each call to jpeg_read_header().
+If you reuse a decompression object, you cannot expect your parameter
+settings to be preserved across cycles, as you can for compression.
+You must set desired parameter values each time.
+
+
+5. jpeg_start_decompress(...);
+
+Once the parameter values are satisfactory, call jpeg_start_decompress() to
+begin decompression.  This will initialize internal state, allocate working
+memory, and prepare for returning data.
+
+Typical code is just
+
+	jpeg_start_decompress(&cinfo);
+
+If you have requested a multi-pass operating mode, such as 2-pass color
+quantization, jpeg_start_decompress() will do everything needed before data
+output can begin.  In this case jpeg_start_decompress() may take quite a while
+to complete.  With a single-scan (non progressive) JPEG file and default
+decompression parameters, this will not happen; jpeg_start_decompress() will
+return quickly.
+
+After this call, the final output image dimensions, including any requested
+scaling, are available in the JPEG object; so is the selected colormap, if
+colormapped output has been requested.  Useful fields include
+
+	output_width		image width and height, as scaled
+	output_height
+	out_color_components	# of color components in out_color_space
+	output_components	# of color components returned per pixel
+	colormap		the selected colormap, if any
+	actual_number_of_colors		number of entries in colormap
+
+output_components is 1 (a colormap index) when quantizing colors; otherwise it
+equals out_color_components.  It is the number of JSAMPLE values that will be
+emitted per pixel in the output arrays.
+
+Typically you will need to allocate data buffers to hold the incoming image.
+You will need output_width * output_components JSAMPLEs per scanline in your
+output buffer, and a total of output_height scanlines will be returned.
+
+Note: if you are using the JPEG library's internal memory manager to allocate
+data buffers (as djpeg does), then the manager's protocol requires that you
+request large buffers *before* calling jpeg_start_decompress().  This is a
+little tricky since the output_XXX fields are not normally valid then.  You
+can make them valid by calling jpeg_calc_output_dimensions() after setting the
+relevant parameters (scaling, output color space, and quantization flag).
+
+
+6. while (scan lines remain to be read)
+	jpeg_read_scanlines(...);
+
+Now you can read the decompressed image data by calling jpeg_read_scanlines()
+one or more times.  At each call, you pass in the maximum number of scanlines
+to be read (ie, the height of your working buffer); jpeg_read_scanlines()
+will return up to that many lines.  The return value is the number of lines
+actually read.  The format of the returned data is discussed under "Data
+formats", above.  Don't forget that grayscale and color JPEGs will return
+different data formats!
+
+Image data is returned in top-to-bottom scanline order.  If you must write
+out the image in bottom-to-top order, you can use the JPEG library's virtual
+array mechanism to invert the data efficiently.  Examples of this can be
+found in the sample application djpeg.
+
+The library maintains a count of the number of scanlines returned so far
+in the output_scanline field of the JPEG object.  Usually you can just use
+this variable as the loop counter, so that the loop test looks like
+"while (cinfo.output_scanline < cinfo.output_height)".  (Note that the test
+should NOT be against image_height, unless you never use scaling.  The
+image_height field is the height of the original unscaled image.)
+The return value always equals the change in the value of output_scanline.
+
+If you don't use a suspending data source, it is safe to assume that
+jpeg_read_scanlines() reads at least one scanline per call, until the
+bottom of the image has been reached.
+
+If you use a buffer larger than one scanline, it is NOT safe to assume that
+jpeg_read_scanlines() fills it.  (The current implementation returns only a
+few scanlines per call, no matter how large a buffer you pass.)  So you must
+always provide a loop that calls jpeg_read_scanlines() repeatedly until the
+whole image has been read.
+
+
+7. jpeg_finish_decompress(...);
+
+After all the image data has been read, call jpeg_finish_decompress() to
+complete the decompression cycle.  This causes working memory associated
+with the JPEG object to be released.
+
+Typical code:
+
+	jpeg_finish_decompress(&cinfo);
+
+If using the stdio source manager, don't forget to close the source stdio
+stream if necessary.
+
+It is an error to call jpeg_finish_decompress() before reading the correct
+total number of scanlines.  If you wish to abort decompression, call
+jpeg_abort() as discussed below.
+
+After completing a decompression cycle, you may dispose of the JPEG object as
+discussed next, or you may use it to decompress another image.  In that case
+return to step 2 or 3 as appropriate.  If you do not change the source
+manager, the next image will be read from the same source.
+
+
+8. Release the JPEG decompression object.
+
+When you are done with a JPEG decompression object, destroy it by calling
+jpeg_destroy_decompress() or jpeg_destroy().  The previous discussion of
+destroying compression objects applies here too.
+
+Typical code:
+
+	jpeg_destroy_decompress(&cinfo);
+
+
+9. Aborting.
+
+You can abort a decompression cycle by calling jpeg_destroy_decompress() or
+jpeg_destroy() if you don't need the JPEG object any more, or
+jpeg_abort_decompress() or jpeg_abort() if you want to reuse the object.
+The previous discussion of aborting compression cycles applies here too.
+
+
+Mechanics of usage: include files, linking, etc
+-----------------------------------------------
+
+Applications using the JPEG library should include the header file jpeglib.h
+to obtain declarations of data types and routines.  Before including
+jpeglib.h, include system headers that define at least the typedefs FILE and
+size_t.  On ANSI-conforming systems, including <stdio.h> is sufficient; on
+older Unix systems, you may need <sys/types.h> to define size_t.
+
+If the application needs to refer to individual JPEG library error codes, also
+include jerror.h to define those symbols.
+
+jpeglib.h indirectly includes the files jconfig.h and jmorecfg.h.  If you are
+installing the JPEG header files in a system directory, you will want to
+install all four files: jpeglib.h, jerror.h, jconfig.h, jmorecfg.h.
+
+The most convenient way to include the JPEG code into your executable program
+is to prepare a library file ("libjpeg.a", or a corresponding name on non-Unix
+machines) and reference it at your link step.  If you use only half of the
+library (only compression or only decompression), only that much code will be
+included from the library, unless your linker is hopelessly brain-damaged.
+The supplied makefiles build libjpeg.a automatically (see install.doc).
+
+While you can build the JPEG library as a shared library if the whim strikes
+you, we don't really recommend it.  The trouble with shared libraries is that
+at some point you'll probably try to substitute a new version of the library
+without recompiling the calling applications.  That generally doesn't work
+because the parameter struct declarations usually change with each new
+version.  In other words, the library's API is *not* guaranteed binary
+compatible across versions; we only try to ensure source-code compatibility.
+(In hindsight, it might have been smarter to hide the parameter structs from
+applications and introduce a ton of access functions instead.  Too late now,
+however.)
+
+On some systems your application may need to set up a signal handler to ensure
+that temporary files are deleted if the program is interrupted.  This is most
+critical if you are on MS-DOS and use the jmemdos.c memory manager back end;
+it will try to grab extended memory for temp files, and that space will NOT be
+freed automatically.  See cjpeg.c or djpeg.c for an example signal handler.
+
+It may be worth pointing out that the core JPEG library does not actually
+require the stdio library: only the default source/destination managers and
+error handler need it.  You can use the library in a stdio-less environment
+if you replace those modules and use jmemnobs.c (or another memory manager of
+your own devising).  More info about the minimum system library requirements
+may be found in jinclude.h.
+
+
+ADVANCED FEATURES
+=================
+
+Compression parameter selection
+-------------------------------
+
+This section describes all the optional parameters you can set for JPEG
+compression, as well as the "helper" routines provided to assist in this
+task.  Proper setting of some parameters requires detailed understanding
+of the JPEG standard; if you don't know what a parameter is for, it's best
+not to mess with it!  See REFERENCES in the README file for pointers to
+more info about JPEG.
+
+It's a good idea to call jpeg_set_defaults() first, even if you plan to set
+all the parameters; that way your code is more likely to work with future JPEG
+libraries that have additional parameters.  For the same reason, we recommend
+you use a helper routine where one is provided, in preference to twiddling
+cinfo fields directly.
+
+The helper routines are:
+
+jpeg_set_defaults (j_compress_ptr cinfo)
+	This routine sets all JPEG parameters to reasonable defaults, using
+	only the input image's color space (field in_color_space, which must
+	already be set in cinfo).  Many applications will only need to use
+	this routine and perhaps jpeg_set_quality().
+
+jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
+	Sets the JPEG file's colorspace (field jpeg_color_space) as specified,
+	and sets other color-space-dependent parameters appropriately.  See
+	"Special color spaces", below, before using this.  A large number of
+	parameters, including all per-component parameters, are set by this
+	routine; if you want to twiddle individual parameters you should call
+	jpeg_set_colorspace() before rather than after.
+
+jpeg_default_colorspace (j_compress_ptr cinfo)
+	Selects an appropriate JPEG colorspace based on cinfo->in_color_space,
+	and calls jpeg_set_colorspace().  This is actually a subroutine of
+	jpeg_set_defaults().  It's broken out in case you want to change
+	just the colorspace-dependent JPEG parameters.
+
+jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
+	Constructs JPEG quantization tables appropriate for the indicated
+	quality setting.  The quality value is expressed on the 0..100 scale
+	recommended by IJG (cjpeg's "-quality" switch uses this routine).
+	Note that the exact mapping from quality values to tables may change
+	in future IJG releases as more is learned about DCT quantization.
+	If the force_baseline parameter is TRUE, then the quantization table
+	entries are constrained to the range 1..255 for full JPEG baseline
+	compatibility.  In the current implementation, this only makes a
+	difference for quality settings below 25, and it effectively prevents
+	very small/low quality files from being generated.  The IJG decoder
+	is capable of reading the non-baseline files generated at low quality
+	settings when force_baseline is FALSE, but other decoders may not be.
+
+jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
+			 boolean force_baseline)
+	Same as jpeg_set_quality() except that the generated tables are the
+	sample tables given in the JPEC spec section K.1, multiplied by the
+	specified scale factor (which is expressed as a percentage; thus
+	scale_factor = 100 reproduces the spec's tables).  Note that larger
+	scale factors give lower quality.  This entry point is useful for
+	conforming to the Adobe PostScript DCT conventions, but we do not
+	recommend linear scaling as a user-visible quality scale otherwise.
+	force_baseline again constrains the computed table entries to 1..255.
+
+int jpeg_quality_scaling (int quality)
+	Converts a value on the IJG-recommended quality scale to a linear
+	scaling percentage.  Note that this routine may change or go away
+	in future releases --- IJG may choose to adopt a scaling method that
+	can't be expressed as a simple scalar multiplier, in which case the
+	premise of this routine collapses.  Caveat user.
+
+jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
+		      const unsigned int *basic_table,
+		      int scale_factor, boolean force_baseline)
+	Allows an arbitrary quantization table to be created.  which_tbl
+	indicates which table slot to fill.  basic_table points to an array
+	of 64 unsigned ints given in normal array order.  These values are
+	multiplied by scale_factor/100 and then clamped to the range 1..65535
+	(or to 1..255 if force_baseline is TRUE).
+	CAUTION: prior to library version 6a, jpeg_add_quant_table expected
+	the basic table to be given in JPEG zigzag order.  If you need to
+	write code that works with either older or newer versions of this
+	routine, you must check the library version number.  Something like
+	"#if JPEG_LIB_VERSION >= 61" is the right test.
+
+jpeg_simple_progression (j_compress_ptr cinfo)
+	Generates a default scan script for writing a progressive-JPEG file.
+	This is the recommended method of creating a progressive file,
+	unless you want to make a custom scan sequence.  You must ensure that
+	the JPEG color space is set correctly before calling this routine.
+
+
+Compression parameters (cinfo fields) include:
+
+J_DCT_METHOD dct_method
+	Selects the algorithm used for the DCT step.  Choices are:
+		JDCT_ISLOW: slow but accurate integer algorithm
+		JDCT_IFAST: faster, less accurate integer method
+		JDCT_FLOAT: floating-point method
+		JDCT_DEFAULT: default method (normally JDCT_ISLOW)
+		JDCT_FASTEST: fastest method (normally JDCT_IFAST)
+	The FLOAT method is very slightly more accurate than the ISLOW method,
+	but may give different results on different machines due to varying
+	roundoff behavior.  The integer methods should give the same results
+	on all machines.  On machines with sufficiently fast FP hardware, the
+	floating-point method may also be the fastest.  The IFAST method is
+	considerably less accurate than the other two; its use is not
+	recommended if high quality is a concern.  JDCT_DEFAULT and
+	JDCT_FASTEST are macros configurable by each installation.
+
+J_COLOR_SPACE jpeg_color_space
+int num_components
+	The JPEG color space and corresponding number of components; see
+	"Special color spaces", below, for more info.  We recommend using
+	jpeg_set_color_space() if you want to change these.
+
+boolean optimize_coding
+	TRUE causes the compressor to compute optimal Huffman coding tables
+	for the image.  This requires an extra pass over the data and
+	therefore costs a good deal of space and time.  The default is
+	FALSE, which tells the compressor to use the supplied or default
+	Huffman tables.  In most cases optimal tables save only a few percent
+	of file size compared to the default tables.  Note that when this is
+	TRUE, you need not supply Huffman tables at all, and any you do
+	supply will be overwritten.
+
+unsigned int restart_interval
+int restart_in_rows
+	To emit restart markers in the JPEG file, set one of these nonzero.
+	Set restart_interval to specify the exact interval in MCU blocks.
+	Set restart_in_rows to specify the interval in MCU rows.  (If
+	restart_in_rows is not 0, then restart_interval is set after the
+	image width in MCUs is computed.)  Defaults are zero (no restarts).
+	One restart marker per MCU row is often a good choice.
+	NOTE: the overhead of restart markers is higher in grayscale JPEG
+	files than in color files, and MUCH higher in progressive JPEGs.
+	If you use restarts, you may want to use larger intervals in those
+	cases.
+
+const jpeg_scan_info * scan_info
+int num_scans
+	By default, scan_info is NULL; this causes the compressor to write a
+	single-scan sequential JPEG file.  If not NULL, scan_info points to
+	an array of scan definition records of length num_scans.  The
+	compressor will then write a JPEG file having one scan for each scan
+	definition record.  This is used to generate noninterleaved or
+	progressive JPEG files.  The library checks that the scan array
+	defines a valid JPEG scan sequence.  (jpeg_simple_progression creates
+	a suitable scan definition array for progressive JPEG.)  This is
+	discussed further under "Progressive JPEG support".
+
+int smoothing_factor
+	If non-zero, the input image is smoothed; the value should be 1 for
+	minimal smoothing to 100 for maximum smoothing.  Consult jcsample.c
+	for details of the smoothing algorithm.  The default is zero.
+
+boolean write_JFIF_header
+	If TRUE, a JFIF APP0 marker is emitted.  jpeg_set_defaults() and
+	jpeg_set_colorspace() set this TRUE if a JFIF-legal JPEG color space
+	(ie, YCbCr or grayscale) is selected, otherwise FALSE.
+
+UINT8 JFIF_major_version
+UINT8 JFIF_minor_version
+	The version number to be written into the JFIF marker.
+	jpeg_set_defaults() initializes the version to 1.01 (major=minor=1).
+	You should set it to 1.02 (major=1, minor=2) if you plan to write
+	any JFIF 1.02 extension markers.
+
+UINT8 density_unit
+UINT16 X_density
+UINT16 Y_density
+	The resolution information to be written into the JFIF marker;
+	not used otherwise.  density_unit may be 0 for unknown,
+	1 for dots/inch, or 2 for dots/cm.  The default values are 0,1,1
+	indicating square pixels of unknown size.
+
+boolean write_Adobe_marker
+	If TRUE, an Adobe APP14 marker is emitted.  jpeg_set_defaults() and
+	jpeg_set_colorspace() set this TRUE if JPEG color space RGB, CMYK,
+	or YCCK is selected, otherwise FALSE.  It is generally a bad idea
+	to set both write_JFIF_header and write_Adobe_marker.  In fact,
+	you probably shouldn't change the default settings at all --- the
+	default behavior ensures that the JPEG file's color space can be
+	recognized by the decoder.
+
+JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]
+	Pointers to coefficient quantization tables, one per table slot,
+	or NULL if no table is defined for a slot.  Usually these should
+	be set via one of the above helper routines; jpeg_add_quant_table()
+	is general enough to define any quantization table.  The other
+	routines will set up table slot 0 for luminance quality and table
+	slot 1 for chrominance.
+
+JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]
+JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]
+	Pointers to Huffman coding tables, one per table slot, or NULL if
+	no table is defined for a slot.  Slots 0 and 1 are filled with the
+	JPEG sample tables by jpeg_set_defaults().  If you need to allocate
+	more table structures, jpeg_alloc_huff_table() may be used.
+	Note that optimal Huffman tables can be computed for an image
+	by setting optimize_coding, as discussed above; there's seldom
+	any need to mess with providing your own Huffman tables.
+
+There are some additional cinfo fields which are not documented here
+because you currently can't change them; for example, you can't set
+arith_code TRUE because arithmetic coding is unsupported.
+
+
+Per-component parameters are stored in the struct cinfo.comp_info[i] for
+component number i.  Note that components here refer to components of the
+JPEG color space, *not* the source image color space.  A suitably large
+comp_info[] array is allocated by jpeg_set_defaults(); if you choose not
+to use that routine, it's up to you to allocate the array.
+
+int component_id
+	The one-byte identifier code to be recorded in the JPEG file for
+	this component.  For the standard color spaces, we recommend you
+	leave the default values alone.
+
+int h_samp_factor
+int v_samp_factor
+	Horizontal and vertical sampling factors for the component; must
+	be 1..4 according to the JPEG standard.  Note that larger sampling
+	factors indicate a higher-resolution component; many people find
+	this behavior quite unintuitive.  The default values are 2,2 for
+	luminance components and 1,1 for chrominance components, except
+	for grayscale where 1,1 is used.
+
+int quant_tbl_no
+	Quantization table number for component.  The default value is
+	0 for luminance components and 1 for chrominance components.
+
+int dc_tbl_no
+int ac_tbl_no
+	DC and AC entropy coding table numbers.  The default values are
+	0 for luminance components and 1 for chrominance components.
+
+int component_index
+	Must equal the component's index in comp_info[].  (Beginning in
+	release v6, the compressor library will fill this in automatically;
+	you don't have to.)
+
+
+Decompression parameter selection
+---------------------------------
+
+Decompression parameter selection is somewhat simpler than compression
+parameter selection, since all of the JPEG internal parameters are
+recorded in the source file and need not be supplied by the application.
+(Unless you are working with abbreviated files, in which case see
+"Abbreviated datastreams", below.)  Decompression parameters control
+the postprocessing done on the image to deliver it in a format suitable
+for the application's use.  Many of the parameters control speed/quality
+tradeoffs, in which faster decompression may be obtained at the price of
+a poorer-quality image.  The defaults select the highest quality (slowest)
+processing.
+
+The following fields in the JPEG object are set by jpeg_read_header() and
+may be useful to the application in choosing decompression parameters:
+
+JDIMENSION image_width			Width and height of image
+JDIMENSION image_height
+int num_components			Number of color components
+J_COLOR_SPACE jpeg_color_space		Colorspace of image
+boolean saw_JFIF_marker			TRUE if a JFIF APP0 marker was seen
+  UINT8 JFIF_major_version		Version information from JFIF marker
+  UINT8 JFIF_minor_version
+  UINT8 density_unit			Resolution data from JFIF marker
+  UINT16 X_density
+  UINT16 Y_density
+boolean saw_Adobe_marker		TRUE if an Adobe APP14 marker was seen
+  UINT8 Adobe_transform			Color transform code from Adobe marker
+
+The JPEG color space, unfortunately, is something of a guess since the JPEG
+standard proper does not provide a way to record it.  In practice most files
+adhere to the JFIF or Adobe conventions, and the decoder will recognize these
+correctly.  See "Special color spaces", below, for more info.
+
+
+The decompression parameters that determine the basic properties of the
+returned image are:
+
+J_COLOR_SPACE out_color_space
+	Output color space.  jpeg_read_header() sets an appropriate default
+	based on jpeg_color_space; typically it will be RGB or grayscale.
+	The application can change this field to request output in a different
+	colorspace.  For example, set it to JCS_GRAYSCALE to get grayscale
+	output from a color file.  (This is useful for previewing: grayscale
+	output is faster than full color since the color components need not
+	be processed.)  Note that not all possible color space transforms are
+	currently implemented; you may need to extend jdcolor.c if you want an
+	unusual conversion.
+
+unsigned int scale_num, scale_denom
+	Scale the image by the fraction scale_num/scale_denom.  Default is
+	1/1, or no scaling.  Currently, the only supported scaling ratios
+	are 1/1, 1/2, 1/4, and 1/8.  (The library design allows for arbitrary
+	scaling ratios but this is not likely to be implemented any time soon.)
+	Smaller scaling ratios permit significantly faster decoding since
+	fewer pixels need be processed and a simpler IDCT method can be used.
+
+boolean quantize_colors
+	If set TRUE, colormapped output will be delivered.  Default is FALSE,
+	meaning that full-color output will be delivered.
+
+The next three parameters are relevant only if quantize_colors is TRUE.
+
+int desired_number_of_colors
+	Maximum number of colors to use in generating a library-supplied color
+	map (the actual number of colors is returned in a different field).
+	Default 256.  Ignored when the application supplies its own color map.
+
+boolean two_pass_quantize
+	If TRUE, an extra pass over the image is made to select a custom color
+	map for the image.  This usually looks a lot better than the one-size-
+	fits-all colormap that is used otherwise.  Default is TRUE.  Ignored
+	when the application supplies its own color map.
+
+J_DITHER_MODE dither_mode
+	Selects color dithering method.  Supported values are:
+		JDITHER_NONE	no dithering: fast, very low quality
+		JDITHER_ORDERED	ordered dither: moderate speed and quality
+		JDITHER_FS	Floyd-Steinberg dither: slow, high quality
+	Default is JDITHER_FS.  (At present, ordered dither is implemented
+	only in the single-pass, standard-colormap case.  If you ask for
+	ordered dither when two_pass_quantize is TRUE or when you supply
+	an external color map, you'll get F-S dithering.)
+
+When quantize_colors is TRUE, the target color map is described by the next
+two fields.  colormap is set to NULL by jpeg_read_header().  The application
+can supply a color map by setting colormap non-NULL and setting
+actual_number_of_colors to the map size.  Otherwise, jpeg_start_decompress()
+selects a suitable color map and sets these two fields itself.
+[Implementation restriction: at present, an externally supplied colormap is
+only accepted for 3-component output color spaces.]
+
+JSAMPARRAY colormap
+	The color map, represented as a 2-D pixel array of out_color_components
+	rows and actual_number_of_colors columns.  Ignored if not quantizing.
+	CAUTION: if the JPEG library creates its own colormap, the storage
+	pointed to by this field is released by jpeg_finish_decompress().
+	Copy the colormap somewhere else first, if you want to save it.
+
+int actual_number_of_colors
+	The number of colors in the color map.
+
+Additional decompression parameters that the application may set include:
+
+J_DCT_METHOD dct_method
+	Selects the algorithm used for the DCT step.  Choices are the same
+	as described above for compression.
+
+boolean do_fancy_upsampling
+	If TRUE, do careful upsampling of chroma components.  If FALSE,
+	a faster but sloppier method is used.  Default is TRUE.  The visual
+	impact of the sloppier method is often very small.
+
+boolean do_block_smoothing
+	If TRUE, interblock smoothing is applied in early stages of decoding
+	progressive JPEG files; if FALSE, not.  Default is TRUE.  Early
+	progression stages look "fuzzy" with smoothing, "blocky" without.
+	In any case, block smoothing ceases to be applied after the first few
+	AC coefficients are known to full accuracy, so it is relevant only
+	when using buffered-image mode for progressive images.
+
+boolean enable_1pass_quant
+boolean enable_external_quant
+boolean enable_2pass_quant
+	These are significant only in buffered-image mode, which is
+	described in its own section below.
+
+
+The output image dimensions are given by the following fields.  These are
+computed from the source image dimensions and the decompression parameters
+by jpeg_start_decompress().  You can also call jpeg_calc_output_dimensions()
+to obtain the values that will result from the current parameter settings.
+This can be useful if you are trying to pick a scaling ratio that will get
+close to a desired target size.  It's also important if you are using the
+JPEG library's memory manager to allocate output buffer space, because you
+are supposed to request such buffers *before* jpeg_start_decompress().
+
+JDIMENSION output_width		Actual dimensions of output image.
+JDIMENSION output_height
+int out_color_components	Number of color components in out_color_space.
+int output_components		Number of color components returned.
+int rec_outbuf_height		Recommended height of scanline buffer.
+
+When quantizing colors, output_components is 1, indicating a single color map
+index per pixel.  Otherwise it equals out_color_components.  The output arrays
+are required to be output_width * output_components JSAMPLEs wide.
+
+rec_outbuf_height is the recommended minimum height (in scanlines) of the
+buffer passed to jpeg_read_scanlines().  If the buffer is smaller, the
+library will still work, but time will be wasted due to unnecessary data
+copying.  In high-quality modes, rec_outbuf_height is always 1, but some
+faster, lower-quality modes set it to larger values (typically 2 to 4).
+If you are going to ask for a high-speed processing mode, you may as well
+go to the trouble of honoring rec_outbuf_height so as to avoid data copying.
+(An output buffer larger than rec_outbuf_height lines is OK, but won't
+provide any material speed improvement over that height.)
+
+
+Special color spaces
+--------------------
+
+The JPEG standard itself is "color blind" and doesn't specify any particular
+color space.  It is customary to convert color data to a luminance/chrominance
+color space before compressing, since this permits greater compression.  The
+existing de-facto JPEG file format standards specify YCbCr or grayscale data
+(JFIF), or grayscale, RGB, YCbCr, CMYK, or YCCK (Adobe).  For special
+applications such as multispectral images, other color spaces can be used,
+but it must be understood that such files will be unportable.
+
+The JPEG library can handle the most common colorspace conversions (namely
+RGB <=> YCbCr and CMYK <=> YCCK).  It can also deal with data of an unknown
+color space, passing it through without conversion.  If you deal extensively
+with an unusual color space, you can easily extend the library to understand
+additional color spaces and perform appropriate conversions.
+
+For compression, the source data's color space is specified by field
+in_color_space.  This is transformed to the JPEG file's color space given
+by jpeg_color_space.  jpeg_set_defaults() chooses a reasonable JPEG color
+space depending on in_color_space, but you can override this by calling
+jpeg_set_colorspace().  Of course you must select a supported transformation.
+jccolor.c currently supports the following transformations:
+	RGB => YCbCr
+	RGB => GRAYSCALE
+	YCbCr => GRAYSCALE
+	CMYK => YCCK
+plus the null transforms: GRAYSCALE => GRAYSCALE, RGB => RGB,
+YCbCr => YCbCr, CMYK => CMYK, YCCK => YCCK, and UNKNOWN => UNKNOWN.
+
+The de-facto file format standards (JFIF and Adobe) specify APPn markers that
+indicate the color space of the JPEG file.  It is important to ensure that
+these are written correctly, or omitted if the JPEG file's color space is not
+one of the ones supported by the de-facto standards.  jpeg_set_colorspace()
+will set the compression parameters to include or omit the APPn markers
+properly, so long as it is told the truth about the JPEG color space.
+For example, if you are writing some random 3-component color space without
+conversion, don't try to fake out the library by setting in_color_space and
+jpeg_color_space to JCS_YCbCr; use JCS_UNKNOWN.  You may want to write an
+APPn marker of your own devising to identify the colorspace --- see "Special
+markers", below.
+
+When told that the color space is UNKNOWN, the library will default to using
+luminance-quality compression parameters for all color components.  You may
+well want to change these parameters.  See the source code for
+jpeg_set_colorspace(), in jcparam.c, for details.
+
+For decompression, the JPEG file's color space is given in jpeg_color_space,
+and this is transformed to the output color space out_color_space.
+jpeg_read_header's setting of jpeg_color_space can be relied on if the file
+conforms to JFIF or Adobe conventions, but otherwise it is no better than a
+guess.  If you know the JPEG file's color space for certain, you can override
+jpeg_read_header's guess by setting jpeg_color_space.  jpeg_read_header also
+selects a default output color space based on (its guess of) jpeg_color_space;
+set out_color_space to override this.  Again, you must select a supported
+transformation.  jdcolor.c currently supports
+	YCbCr => GRAYSCALE
+	YCbCr => RGB
+	GRAYSCALE => RGB
+	YCCK => CMYK
+as well as the null transforms.  (Since GRAYSCALE=>RGB is provided, an
+application can force grayscale JPEGs to look like color JPEGs if it only
+wants to handle one case.)
+
+The two-pass color quantizer, jquant2.c, is specialized to handle RGB data
+(it weights distances appropriately for RGB colors).  You'll need to modify
+the code if you want to use it for non-RGB output color spaces.  Note that
+jquant2.c is used to map to an application-supplied colormap as well as for
+the normal two-pass colormap selection process.
+
+CAUTION: it appears that Adobe Photoshop writes inverted data in CMYK JPEG
+files: 0 represents 100% ink coverage, rather than 0% ink as you'd expect.
+This is arguably a bug in Photoshop, but if you need to work with Photoshop
+CMYK files, you will have to deal with it in your application.  We cannot
+"fix" this in the library by inverting the data during the CMYK<=>YCCK
+transform, because that would break other applications, notably Ghostscript.
+Photoshop versions prior to 3.0 write EPS files containing JPEG-encoded CMYK
+data in the same inverted-YCCK representation used in bare JPEG files, but
+the surrounding PostScript code performs an inversion using the PS image
+operator.  I am told that Photoshop 3.0 will write uninverted YCCK in
+EPS/JPEG files, and will omit the PS-level inversion.  (But the data
+polarity used in bare JPEG files will not change in 3.0.)  In either case,
+the JPEG library must not invert the data itself, or else Ghostscript would
+read these EPS files incorrectly.
+
+
+Error handling
+--------------
+
+When the default error handler is used, any error detected inside the JPEG
+routines will cause a message to be printed on stderr, followed by exit().
+You can supply your own error handling routines to override this behavior
+and to control the treatment of nonfatal warnings and trace/debug messages.
+The file example.c illustrates the most common case, which is to have the
+application regain control after an error rather than exiting.
+
+The JPEG library never writes any message directly; it always goes through
+the error handling routines.  Three classes of messages are recognized:
+  * Fatal errors: the library cannot continue.
+  * Warnings: the library can continue, but the data is corrupt, and a
+    damaged output image is likely to result.
+  * Trace/informational messages.  These come with a trace level indicating
+    the importance of the message; you can control the verbosity of the
+    program by adjusting the maximum trace level that will be displayed.
+
+You may, if you wish, simply replace the entire JPEG error handling module
+(jerror.c) with your own code.  However, you can avoid code duplication by
+only replacing some of the routines depending on the behavior you need.
+This is accomplished by calling jpeg_std_error() as usual, but then overriding
+some of the method pointers in the jpeg_error_mgr struct, as illustrated by
+example.c.
+
+All of the error handling routines will receive a pointer to the JPEG object
+(a j_common_ptr which points to either a jpeg_compress_struct or a
+jpeg_decompress_struct; if you need to tell which, test the is_decompressor
+field).  This struct includes a pointer to the error manager struct in its
+"err" field.  Frequently, custom error handler routines will need to access
+additional data which is not known to the JPEG library or the standard error
+handler.  The most convenient way to do this is to embed either the JPEG
+object or the jpeg_error_mgr struct in a larger structure that contains
+additional fields; then casting the passed pointer provides access to the
+additional fields.  Again, see example.c for one way to do it.  (Beginning
+with IJG version 6b, there is also a void pointer "client_data" in each
+JPEG object, which the application can also use to find related data.
+The library does not touch client_data at all.)
+
+The individual methods that you might wish to override are:
+
+error_exit (j_common_ptr cinfo)
+	Receives control for a fatal error.  Information sufficient to
+	generate the error message has been stored in cinfo->err; call
+	output_message to display it.  Control must NOT return to the caller;
+	generally this routine will exit() or longjmp() somewhere.
+	Typically you would override this routine to get rid of the exit()
+	default behavior.  Note that if you continue processing, you should
+	clean up the JPEG object with jpeg_abort() or jpeg_destroy().
+
+output_message (j_common_ptr cinfo)
+	Actual output of any JPEG message.  Override this to send messages
+	somewhere other than stderr.  Note that this method does not know
+	how to generate a message, only where to send it.
+
+format_message (j_common_ptr cinfo, char * buffer)
+	Constructs a readable error message string based on the error info
+	stored in cinfo->err.  This method is called by output_message.  Few
+	applications should need to override this method.  One possible
+	reason for doing so is to implement dynamic switching of error message
+	language.
+
+emit_message (j_common_ptr cinfo, int msg_level)
+	Decide whether or not to emit a warning or trace message; if so,
+	calls output_message.  The main reason for overriding this method
+	would be to abort on warnings.  msg_level is -1 for warnings,
+	0 and up for trace messages.
+
+Only error_exit() and emit_message() are called from the rest of the JPEG
+library; the other two are internal to the error handler.
+
+The actual message texts are stored in an array of strings which is pointed to
+by the field err->jpeg_message_table.  The messages are numbered from 0 to
+err->last_jpeg_message, and it is these code numbers that are used in the
+JPEG library code.  You could replace the message texts (for instance, with
+messages in French or German) by changing the message table pointer.  See
+jerror.h for the default texts.  CAUTION: this table will almost certainly
+change or grow from one library version to the next.
+
+It may be useful for an application to add its own message texts that are
+handled by the same mechanism.  The error handler supports a second "add-on"
+message table for this purpose.  To define an addon table, set the pointer
+err->addon_message_table and the message numbers err->first_addon_message and
+err->last_addon_message.  If you number the addon messages beginning at 1000
+or so, you won't have to worry about conflicts with the library's built-in
+messages.  See the sample applications cjpeg/djpeg for an example of using
+addon messages (the addon messages are defined in cderror.h).
+
+Actual invocation of the error handler is done via macros defined in jerror.h:
+	ERREXITn(...)	for fatal errors
+	WARNMSn(...)	for corrupt-data warnings
+	TRACEMSn(...)	for trace and informational messages.
+These macros store the message code and any additional parameters into the
+error handler struct, then invoke the error_exit() or emit_message() method.
+The variants of each macro are for varying numbers of additional parameters.
+The additional parameters are inserted into the generated message using
+standard printf() format codes.
+
+See jerror.h and jerror.c for further details.
+
+
+Compressed data handling (source and destination managers)
+----------------------------------------------------------
+
+The JPEG compression library sends its compressed data to a "destination
+manager" module.  The default destination manager just writes the data to a
+stdio stream, but you can provide your own manager to do something else.
+Similarly, the decompression library calls a "source manager" to obtain the
+compressed data; you can provide your own source manager if you want the data
+to come from somewhere other than a stdio stream.
+
+In both cases, compressed data is processed a bufferload at a time: the
+destination or source manager provides a work buffer, and the library invokes
+the manager only when the buffer is filled or emptied.  (You could define a
+one-character buffer to force the manager to be invoked for each byte, but
+that would be rather inefficient.)  The buffer's size and location are
+controlled by the manager, not by the library.  For example, if you desired to
+decompress a JPEG datastream that was all in memory, you could just make the
+buffer pointer and length point to the original data in memory.  Then the
+buffer-reload procedure would be invoked only if the decompressor ran off the
+end of the datastream, which would indicate an erroneous datastream.
+
+The work buffer is defined as an array of datatype JOCTET, which is generally
+"char" or "unsigned char".  On a machine where char is not exactly 8 bits
+wide, you must define JOCTET as a wider data type and then modify the data
+source and destination modules to transcribe the work arrays into 8-bit units
+on external storage.
+
+A data destination manager struct contains a pointer and count defining the
+next byte to write in the work buffer and the remaining free space:
+
+	JOCTET * next_output_byte;  /* => next byte to write in buffer */
+	size_t free_in_buffer;      /* # of byte spaces remaining in buffer */
+
+The library increments the pointer and decrements the count until the buffer
+is filled.  The manager's empty_output_buffer method must reset the pointer
+and count.  The manager is expected to remember the buffer's starting address
+and total size in private fields not visible to the library.
+
+A data destination manager provides three methods:
+
+init_destination (j_compress_ptr cinfo)
+	Initialize destination.  This is called by jpeg_start_compress()
+	before any data is actually written.  It must initialize
+	next_output_byte and free_in_buffer.  free_in_buffer must be
+	initialized to a positive value.
+
+empty_output_buffer (j_compress_ptr cinfo)
+	This is called whenever the buffer has filled (free_in_buffer
+	reaches zero).  In typical applications, it should write out the
+	*entire* buffer (use the saved start address and buffer length;
+	ignore the current state of next_output_byte and free_in_buffer).
+	Then reset the pointer & count to the start of the buffer, and
+	return TRUE indicating that the buffer has been dumped.
+	free_in_buffer must be set to a positive value when TRUE is
+	returned.  A FALSE return should only be used when I/O suspension is
+	desired (this operating mode is discussed in the next section).
+
+term_destination (j_compress_ptr cinfo)
+	Terminate destination --- called by jpeg_finish_compress() after all
+	data has been written.  In most applications, this must flush any
+	data remaining in the buffer.  Use either next_output_byte or
+	free_in_buffer to determine how much data is in the buffer.
+
+term_destination() is NOT called by jpeg_abort() or jpeg_destroy().  If you
+want the destination manager to be cleaned up during an abort, you must do it
+yourself.
+
+You will also need code to create a jpeg_destination_mgr struct, fill in its
+method pointers, and insert a pointer to the struct into the "dest" field of
+the JPEG compression object.  This can be done in-line in your setup code if
+you like, but it's probably cleaner to provide a separate routine similar to
+the jpeg_stdio_dest() routine of the supplied destination manager.
+
+Decompression source managers follow a parallel design, but with some
+additional frammishes.  The source manager struct contains a pointer and count
+defining the next byte to read from the work buffer and the number of bytes
+remaining:
+
+	const JOCTET * next_input_byte; /* => next byte to read from buffer */
+	size_t bytes_in_buffer;         /* # of bytes remaining in buffer */
+
+The library increments the pointer and decrements the count until the buffer
+is emptied.  The manager's fill_input_buffer method must reset the pointer and
+count.  In most applications, the manager must remember the buffer's starting
+address and total size in private fields not visible to the library.
+
+A data source manager provides five methods:
+
+init_source (j_decompress_ptr cinfo)
+	Initialize source.  This is called by jpeg_read_header() before any
+	data is actually read.  Unlike init_destination(), it may leave
+	bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
+	will occur immediately).
+
+fill_input_buffer (j_decompress_ptr cinfo)
+	This is called whenever bytes_in_buffer has reached zero and more
+	data is wanted.  In typical applications, it should read fresh data
+	into the buffer (ignoring the current state of next_input_byte and
+	bytes_in_buffer), reset the pointer & count to the start of the
+	buffer, and return TRUE indicating that the buffer has been reloaded.
+	It is not necessary to fill the buffer entirely, only to obtain at
+	least one more byte.  bytes_in_buffer MUST be set to a positive value
+	if TRUE is returned.  A FALSE return should only be used when I/O
+	suspension is desired (this mode is discussed in the next section).
+
+skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+	Skip num_bytes worth of data.  The buffer pointer and count should
+	be advanced over num_bytes input bytes, refilling the buffer as
+	needed.  This is used to skip over a potentially large amount of
+	uninteresting data (such as an APPn marker).  In some applications
+	it may be possible to optimize away the reading of the skipped data,
+	but it's not clear that being smart is worth much trouble; large
+	skips are uncommon.  bytes_in_buffer may be zero on return.
+	A zero or negative skip count should be treated as a no-op.
+
+resync_to_restart (j_decompress_ptr cinfo, int desired)
+	This routine is called only when the decompressor has failed to find
+	a restart (RSTn) marker where one is expected.  Its mission is to
+	find a suitable point for resuming decompression.  For most
+	applications, we recommend that you just use the default resync
+	procedure, jpeg_resync_to_restart().  However, if you are able to back
+	up in the input data stream, or if you have a-priori knowledge about
+	the likely location of restart markers, you may be able to do better.
+	Read the read_restart_marker() and jpeg_resync_to_restart() routines
+	in jdmarker.c if you think you'd like to implement your own resync
+	procedure.
+
+term_source (j_decompress_ptr cinfo)
+	Terminate source --- called by jpeg_finish_decompress() after all
+	data has been read.  Often a no-op.
+
+For both fill_input_buffer() and skip_input_data(), there is no such thing
+as an EOF return.  If the end of the file has been reached, the routine has
+a choice of exiting via ERREXIT() or inserting fake data into the buffer.
+In most cases, generating a warning message and inserting a fake EOI marker
+is the best course of action --- this will allow the decompressor to output
+however much of the image is there.  In pathological cases, the decompressor
+may swallow the EOI and again demand data ... just keep feeding it fake EOIs.
+jdatasrc.c illustrates the recommended error recovery behavior.
+
+term_source() is NOT called by jpeg_abort() or jpeg_destroy().  If you want
+the source manager to be cleaned up during an abort, you must do it yourself.
+
+You will also need code to create a jpeg_source_mgr struct, fill in its method
+pointers, and insert a pointer to the struct into the "src" field of the JPEG
+decompression object.  This can be done in-line in your setup code if you
+like, but it's probably cleaner to provide a separate routine similar to the
+jpeg_stdio_src() routine of the supplied source manager.
+
+For more information, consult the stdio source and destination managers
+in jdatasrc.c and jdatadst.c.
+
+
+I/O suspension
+--------------
+
+Some applications need to use the JPEG library as an incremental memory-to-
+memory filter: when the compressed data buffer is filled or emptied, they want
+control to return to the outer loop, rather than expecting that the buffer can
+be emptied or reloaded within the data source/destination manager subroutine.
+The library supports this need by providing an "I/O suspension" mode, which we
+describe in this section.
+
+The I/O suspension mode is not a panacea: nothing is guaranteed about the
+maximum amount of time spent in any one call to the library, so it will not
+eliminate response-time problems in single-threaded applications.  If you
+need guaranteed response time, we suggest you "bite the bullet" and implement
+a real multi-tasking capability.
+
+To use I/O suspension, cooperation is needed between the calling application
+and the data source or destination manager; you will always need a custom
+source/destination manager.  (Please read the previous section if you haven't
+already.)  The basic idea is that the empty_output_buffer() or
+fill_input_buffer() routine is a no-op, merely returning FALSE to indicate
+that it has done nothing.  Upon seeing this, the JPEG library suspends
+operation and returns to its caller.  The surrounding application is
+responsible for emptying or refilling the work buffer before calling the
+JPEG library again.
+
+Compression suspension:
+
+For compression suspension, use an empty_output_buffer() routine that returns
+FALSE; typically it will not do anything else.  This will cause the
+compressor to return to the caller of jpeg_write_scanlines(), with the return
+value indicating that not all the supplied scanlines have been accepted.
+The application must make more room in the output buffer, adjust the output
+buffer pointer/count appropriately, and then call jpeg_write_scanlines()
+again, pointing to the first unconsumed scanline.
+
+When forced to suspend, the compressor will backtrack to a convenient stopping
+point (usually the start of the current MCU); it will regenerate some output
+data when restarted.  Therefore, although empty_output_buffer() is only
+called when the buffer is filled, you should NOT write out the entire buffer
+after a suspension.  Write only the data up to the current position of
+next_output_byte/free_in_buffer.  The data beyond that point will be
+regenerated after resumption.
+
+Because of the backtracking behavior, a good-size output buffer is essential
+for efficiency; you don't want the compressor to suspend often.  (In fact, an
+overly small buffer could lead to infinite looping, if a single MCU required
+more data than would fit in the buffer.)  We recommend a buffer of at least
+several Kbytes.  You may want to insert explicit code to ensure that you don't
+call jpeg_write_scanlines() unless there is a reasonable amount of space in
+the output buffer; in other words, flush the buffer before trying to compress
+more data.
+
+The compressor does not allow suspension while it is trying to write JPEG
+markers at the beginning and end of the file.  This means that:
+  * At the beginning of a compression operation, there must be enough free
+    space in the output buffer to hold the header markers (typically 600 or
+    so bytes).  The recommended buffer size is bigger than this anyway, so
+    this is not a problem as long as you start with an empty buffer.  However,
+    this restriction might catch you if you insert large special markers, such
+    as a JFIF thumbnail image, without flushing the buffer afterwards.
+  * When you call jpeg_finish_compress(), there must be enough space in the
+    output buffer to emit any buffered data and the final EOI marker.  In the
+    current implementation, half a dozen bytes should suffice for this, but
+    for safety's sake we recommend ensuring that at least 100 bytes are free
+    before calling jpeg_finish_compress().
+
+A more significant restriction is that jpeg_finish_compress() cannot suspend.
+This means you cannot use suspension with multi-pass operating modes, namely
+Huffman code optimization and multiple-scan output.  Those modes write the
+whole file during jpeg_finish_compress(), which will certainly result in
+buffer overrun.  (Note that this restriction applies only to compression,
+not decompression.  The decompressor supports input suspension in all of its
+operating modes.)
+
+Decompression suspension:
+
+For decompression suspension, use a fill_input_buffer() routine that simply
+returns FALSE (except perhaps during error recovery, as discussed below).
+This will cause the decompressor to return to its caller with an indication
+that suspension has occurred.  This can happen at four places:
+  * jpeg_read_header(): will return JPEG_SUSPENDED.
+  * jpeg_start_decompress(): will return FALSE, rather than its usual TRUE.
+  * jpeg_read_scanlines(): will return the number of scanlines already
+	completed (possibly 0).
+  * jpeg_finish_decompress(): will return FALSE, rather than its usual TRUE.
+The surrounding application must recognize these cases, load more data into
+the input buffer, and repeat the call.  In the case of jpeg_read_scanlines(),
+increment the passed pointers past any scanlines successfully read.
+
+Just as with compression, the decompressor will typically backtrack to a
+convenient restart point before suspending.  When fill_input_buffer() is
+called, next_input_byte/bytes_in_buffer point to the current restart point,
+which is where the decompressor will backtrack to if FALSE is returned.
+The data beyond that position must NOT be discarded if you suspend; it needs
+to be re-read upon resumption.  In most implementations, you'll need to shift
+this data down to the start of your work buffer and then load more data after
+it.  Again, this behavior means that a several-Kbyte work buffer is essential
+for decent performance; furthermore, you should load a reasonable amount of
+new data before resuming decompression.  (If you loaded, say, only one new
+byte each time around, you could waste a LOT of cycles.)
+
+The skip_input_data() source manager routine requires special care in a
+suspension scenario.  This routine is NOT granted the ability to suspend the
+decompressor; it can decrement bytes_in_buffer to zero, but no more.  If the
+requested skip distance exceeds the amount of data currently in the input
+buffer, then skip_input_data() must set bytes_in_buffer to zero and record the
+additional skip distance somewhere else.  The decompressor will immediately
+call fill_input_buffer(), which should return FALSE, which will cause a
+suspension return.  The surrounding application must then arrange to discard
+the recorded number of bytes before it resumes loading the input buffer.
+(Yes, this design is rather baroque, but it avoids complexity in the far more
+common case where a non-suspending source manager is used.)
+
+If the input data has been exhausted, we recommend that you emit a warning
+and insert dummy EOI markers just as a non-suspending data source manager
+would do.  This can be handled either in the surrounding application logic or
+within fill_input_buffer(); the latter is probably more efficient.  If
+fill_input_buffer() knows that no more data is available, it can set the
+pointer/count to point to a dummy EOI marker and then return TRUE just as
+though it had read more data in a non-suspending situation.
+
+The decompressor does not attempt to suspend within standard JPEG markers;
+instead it will backtrack to the start of the marker and reprocess the whole
+marker next time.  Hence the input buffer must be large enough to hold the
+longest standard marker in the file.  Standard JPEG markers should normally
+not exceed a few hundred bytes each (DHT tables are typically the longest).
+We recommend at least a 2K buffer for performance reasons, which is much
+larger than any correct marker is likely to be.  For robustness against
+damaged marker length counts, you may wish to insert a test in your
+application for the case that the input buffer is completely full and yet
+the decoder has suspended without consuming any data --- otherwise, if this
+situation did occur, it would lead to an endless loop.  (The library can't
+provide this test since it has no idea whether "the buffer is full", or
+even whether there is a fixed-size input buffer.)
+
+The input buffer would need to be 64K to allow for arbitrary COM or APPn
+markers, but these are handled specially: they are either saved into allocated
+memory, or skipped over by calling skip_input_data().  In the former case,
+suspension is handled correctly, and in the latter case, the problem of
+buffer overrun is placed on skip_input_data's shoulders, as explained above.
+Note that if you provide your own marker handling routine for large markers,
+you should consider how to deal with buffer overflow.
+
+Multiple-buffer management:
+
+In some applications it is desirable to store the compressed data in a linked
+list of buffer areas, so as to avoid data copying.  This can be handled by
+having empty_output_buffer() or fill_input_buffer() set the pointer and count
+to reference the next available buffer; FALSE is returned only if no more
+buffers are available.  Although seemingly straightforward, there is a
+pitfall in this approach: the backtrack that occurs when FALSE is returned
+could back up into an earlier buffer.  For example, when fill_input_buffer()
+is called, the current pointer & count indicate the backtrack restart point.
+Since fill_input_buffer() will set the pointer and count to refer to a new
+buffer, the restart position must be saved somewhere else.  Suppose a second
+call to fill_input_buffer() occurs in the same library call, and no
+additional input data is available, so fill_input_buffer must return FALSE.
+If the JPEG library has not moved the pointer/count forward in the current
+buffer, then *the correct restart point is the saved position in the prior
+buffer*.  Prior buffers may be discarded only after the library establishes
+a restart point within a later buffer.  Similar remarks apply for output into
+a chain of buffers.
+
+The library will never attempt to backtrack over a skip_input_data() call,
+so any skipped data can be permanently discarded.  You still have to deal
+with the case of skipping not-yet-received data, however.
+
+It's much simpler to use only a single buffer; when fill_input_buffer() is
+called, move any unconsumed data (beyond the current pointer/count) down to
+the beginning of this buffer and then load new data into the remaining buffer
+space.  This approach requires a little more data copying but is far easier
+to get right.
+
+
+Progressive JPEG support
+------------------------
+
+Progressive JPEG rearranges the stored data into a series of scans of
+increasing quality.  In situations where a JPEG file is transmitted across a
+slow communications link, a decoder can generate a low-quality image very
+quickly from the first scan, then gradually improve the displayed quality as
+more scans are received.  The final image after all scans are complete is
+identical to that of a regular (sequential) JPEG file of the same quality
+setting.  Progressive JPEG files are often slightly smaller than equivalent
+sequential JPEG files, but the possibility of incremental display is the main
+reason for using progressive JPEG.
+
+The IJG encoder library generates progressive JPEG files when given a
+suitable "scan script" defining how to divide the data into scans.
+Creation of progressive JPEG files is otherwise transparent to the encoder.
+Progressive JPEG files can also be read transparently by the decoder library.
+If the decoding application simply uses the library as defined above, it
+will receive a final decoded image without any indication that the file was
+progressive.  Of course, this approach does not allow incremental display.
+To perform incremental display, an application needs to use the decoder
+library's "buffered-image" mode, in which it receives a decoded image
+multiple times.
+
+Each displayed scan requires about as much work to decode as a full JPEG
+image of the same size, so the decoder must be fairly fast in relation to the
+data transmission rate in order to make incremental display useful.  However,
+it is possible to skip displaying the image and simply add the incoming bits
+to the decoder's coefficient buffer.  This is fast because only Huffman
+decoding need be done, not IDCT, upsampling, colorspace conversion, etc.
+The IJG decoder library allows the application to switch dynamically between
+displaying the image and simply absorbing the incoming bits.  A properly
+coded application can automatically adapt the number of display passes to
+suit the time available as the image is received.  Also, a final
+higher-quality display cycle can be performed from the buffered data after
+the end of the file is reached.
+
+Progressive compression:
+
+To create a progressive JPEG file (or a multiple-scan sequential JPEG file),
+set the scan_info cinfo field to point to an array of scan descriptors, and
+perform compression as usual.  Instead of constructing your own scan list,
+you can call the jpeg_simple_progression() helper routine to create a
+recommended progression sequence; this method should be used by all
+applications that don't want to get involved in the nitty-gritty of
+progressive scan sequence design.  (If you want to provide user control of
+scan sequences, you may wish to borrow the scan script reading code found
+in rdswitch.c, so that you can read scan script files just like cjpeg's.)
+When scan_info is not NULL, the compression library will store DCT'd data
+into a buffer array as jpeg_write_scanlines() is called, and will emit all
+the requested scans during jpeg_finish_compress().  This implies that
+multiple-scan output cannot be created with a suspending data destination
+manager, since jpeg_finish_compress() does not support suspension.  We
+should also note that the compressor currently forces Huffman optimization
+mode when creating a progressive JPEG file, because the default Huffman
+tables are unsuitable for progressive files.
+
+Progressive decompression:
+
+When buffered-image mode is not used, the decoder library will read all of
+a multi-scan file during jpeg_start_decompress(), so that it can provide a
+final decoded image.  (Here "multi-scan" means either progressive or
+multi-scan sequential.)  This makes multi-scan files transparent to the
+decoding application.  However, existing applications that used suspending
+input with version 5 of the IJG library will need to be modified to check
+for a suspension return from jpeg_start_decompress().
+
+To perform incremental display, an application must use the library's
+buffered-image mode.  This is described in the next section.
+
+
+Buffered-image mode
+-------------------
+
+In buffered-image mode, the library stores the partially decoded image in a
+coefficient buffer, from which it can be read out as many times as desired.
+This mode is typically used for incremental display of progressive JPEG files,
+but it can be used with any JPEG file.  Each scan of a progressive JPEG file
+adds more data (more detail) to the buffered image.  The application can
+display in lockstep with the source file (one display pass per input scan),
+or it can allow input processing to outrun display processing.  By making
+input and display processing run independently, it is possible for the
+application to adapt progressive display to a wide range of data transmission
+rates.
+
+The basic control flow for buffered-image decoding is
+
+	jpeg_create_decompress()
+	set data source
+	jpeg_read_header()
+	set overall decompression parameters
+	cinfo.buffered_image = TRUE;	/* select buffered-image mode */
+	jpeg_start_decompress()
+	for (each output pass) {
+	    adjust output decompression parameters if required
+	    jpeg_start_output()		/* start a new output pass */
+	    for (all scanlines in image) {
+	        jpeg_read_scanlines()
+	        display scanlines
+	    }
+	    jpeg_finish_output()	/* terminate output pass */
+	}
+	jpeg_finish_decompress()
+	jpeg_destroy_decompress()
+
+This differs from ordinary unbuffered decoding in that there is an additional
+level of looping.  The application can choose how many output passes to make
+and how to display each pass.
+
+The simplest approach to displaying progressive images is to do one display
+pass for each scan appearing in the input file.  In this case the outer loop
+condition is typically
+	while (! jpeg_input_complete(&cinfo))
+and the start-output call should read
+	jpeg_start_output(&cinfo, cinfo.input_scan_number);
+The second parameter to jpeg_start_output() indicates which scan of the input
+file is to be displayed; the scans are numbered starting at 1 for this
+purpose.  (You can use a loop counter starting at 1 if you like, but using
+the library's input scan counter is easier.)  The library automatically reads
+data as necessary to complete each requested scan, and jpeg_finish_output()
+advances to the next scan or end-of-image marker (hence input_scan_number
+will be incremented by the time control arrives back at jpeg_start_output()).
+With this technique, data is read from the input file only as needed, and
+input and output processing run in lockstep.
+
+After reading the final scan and reaching the end of the input file, the
+buffered image remains available; it can be read additional times by
+repeating the jpeg_start_output()/jpeg_read_scanlines()/jpeg_finish_output()
+sequence.  For example, a useful technique is to use fast one-pass color
+quantization for display passes made while the image is arriving, followed by
+a final display pass using two-pass quantization for highest quality.  This
+is done by changing the library parameters before the final output pass.
+Changing parameters between passes is discussed in detail below.
+
+In general the last scan of a progressive file cannot be recognized as such
+until after it is read, so a post-input display pass is the best approach if
+you want special processing in the final pass.
+
+When done with the image, be sure to call jpeg_finish_decompress() to release
+the buffered image (or just use jpeg_destroy_decompress()).
+
+If input data arrives faster than it can be displayed, the application can
+cause the library to decode input data in advance of what's needed to produce
+output.  This is done by calling the routine jpeg_consume_input().
+The return value is one of the following:
+	JPEG_REACHED_SOS:    reached an SOS marker (the start of a new scan)
+	JPEG_REACHED_EOI:    reached the EOI marker (end of image)
+	JPEG_ROW_COMPLETED:  completed reading one MCU row of compressed data
+	JPEG_SCAN_COMPLETED: completed reading last MCU row of current scan
+	JPEG_SUSPENDED:      suspended before completing any of the above
+(JPEG_SUSPENDED can occur only if a suspending data source is used.)  This
+routine can be called at any time after initializing the JPEG object.  It
+reads some additional data and returns when one of the indicated significant
+events occurs.  (If called after the EOI marker is reached, it will
+immediately return JPEG_REACHED_EOI without attempting to read more data.)
+
+The library's output processing will automatically call jpeg_consume_input()
+whenever the output processing overtakes the input; thus, simple lockstep
+display requires no direct calls to jpeg_consume_input().  But by adding
+calls to jpeg_consume_input(), you can absorb data in advance of what is
+being displayed.  This has two benefits:
+  * You can limit buildup of unprocessed data in your input buffer.
+  * You can eliminate extra display passes by paying attention to the
+    state of the library's input processing.
+
+The first of these benefits only requires interspersing calls to
+jpeg_consume_input() with your display operations and any other processing
+you may be doing.  To avoid wasting cycles due to backtracking, it's best to
+call jpeg_consume_input() only after a hundred or so new bytes have arrived.
+This is discussed further under "I/O suspension", above.  (Note: the JPEG
+library currently is not thread-safe.  You must not call jpeg_consume_input()
+from one thread of control if a different library routine is working on the
+same JPEG object in another thread.)
+
+When input arrives fast enough that more than one new scan is available
+before you start a new output pass, you may as well skip the output pass
+corresponding to the completed scan.  This occurs for free if you pass
+cinfo.input_scan_number as the target scan number to jpeg_start_output().
+The input_scan_number field is simply the index of the scan currently being
+consumed by the input processor.  You can ensure that this is up-to-date by
+emptying the input buffer just before calling jpeg_start_output(): call
+jpeg_consume_input() repeatedly until it returns JPEG_SUSPENDED or
+JPEG_REACHED_EOI.
+
+The target scan number passed to jpeg_start_output() is saved in the
+cinfo.output_scan_number field.  The library's output processing calls
+jpeg_consume_input() whenever the current input scan number and row within
+that scan is less than or equal to the current output scan number and row.
+Thus, input processing can "get ahead" of the output processing but is not
+allowed to "fall behind".  You can achieve several different effects by
+manipulating this interlock rule.  For example, if you pass a target scan
+number greater than the current input scan number, the output processor will
+wait until that scan starts to arrive before producing any output.  (To avoid
+an infinite loop, the target scan number is automatically reset to the last
+scan number when the end of image is reached.  Thus, if you specify a large
+target scan number, the library will just absorb the entire input file and
+then perform an output pass.  This is effectively the same as what
+jpeg_start_decompress() does when you don't select buffered-image mode.)
+When you pass a target scan number equal to the current input scan number,
+the image is displayed no faster than the current input scan arrives.  The
+final possibility is to pass a target scan number less than the current input
+scan number; this disables the input/output interlock and causes the output
+processor to simply display whatever it finds in the image buffer, without
+waiting for input.  (However, the library will not accept a target scan
+number less than one, so you can't avoid waiting for the first scan.)
+
+When data is arriving faster than the output display processing can advance
+through the image, jpeg_consume_input() will store data into the buffered
+image beyond the point at which the output processing is reading data out
+again.  If the input arrives fast enough, it may "wrap around" the buffer to
+the point where the input is more than one whole scan ahead of the output.
+If the output processing simply proceeds through its display pass without
+paying attention to the input, the effect seen on-screen is that the lower
+part of the image is one or more scans better in quality than the upper part.
+Then, when the next output scan is started, you have a choice of what target
+scan number to use.  The recommended choice is to use the current input scan
+number at that time, which implies that you've skipped the output scans
+corresponding to the input scans that were completed while you processed the
+previous output scan.  In this way, the decoder automatically adapts its
+speed to the arriving data, by skipping output scans as necessary to keep up
+with the arriving data.
+
+When using this strategy, you'll want to be sure that you perform a final
+output pass after receiving all the data; otherwise your last display may not
+be full quality across the whole screen.  So the right outer loop logic is
+something like this:
+	do {
+	    absorb any waiting input by calling jpeg_consume_input()
+	    final_pass = jpeg_input_complete(&cinfo);
+	    adjust output decompression parameters if required
+	    jpeg_start_output(&cinfo, cinfo.input_scan_number);
+	    ...
+	    jpeg_finish_output()
+	} while (! final_pass);
+rather than quitting as soon as jpeg_input_complete() returns TRUE.  This
+arrangement makes it simple to use higher-quality decoding parameters
+for the final pass.  But if you don't want to use special parameters for
+the final pass, the right loop logic is like this:
+	for (;;) {
+	    absorb any waiting input by calling jpeg_consume_input()
+	    jpeg_start_output(&cinfo, cinfo.input_scan_number);
+	    ...
+	    jpeg_finish_output()
+	    if (jpeg_input_complete(&cinfo) &&
+	        cinfo.input_scan_number == cinfo.output_scan_number)
+	      break;
+	}
+In this case you don't need to know in advance whether an output pass is to
+be the last one, so it's not necessary to have reached EOF before starting
+the final output pass; rather, what you want to test is whether the output
+pass was performed in sync with the final input scan.  This form of the loop
+will avoid an extra output pass whenever the decoder is able (or nearly able)
+to keep up with the incoming data.
+
+When the data transmission speed is high, you might begin a display pass,
+then find that much or all of the file has arrived before you can complete
+the pass.  (You can detect this by noting the JPEG_REACHED_EOI return code
+from jpeg_consume_input(), or equivalently by testing jpeg_input_complete().)
+In this situation you may wish to abort the current display pass and start a
+new one using the newly arrived information.  To do so, just call
+jpeg_finish_output() and then start a new pass with jpeg_start_output().
+
+A variant strategy is to abort and restart display if more than one complete
+scan arrives during an output pass; this can be detected by noting
+JPEG_REACHED_SOS returns and/or examining cinfo.input_scan_number.  This
+idea should be employed with caution, however, since the display process
+might never get to the bottom of the image before being aborted, resulting
+in the lower part of the screen being several passes worse than the upper.
+In most cases it's probably best to abort an output pass only if the whole
+file has arrived and you want to begin the final output pass immediately.
+
+When receiving data across a communication link, we recommend always using
+the current input scan number for the output target scan number; if a
+higher-quality final pass is to be done, it should be started (aborting any
+incomplete output pass) as soon as the end of file is received.  However,
+many other strategies are possible.  For example, the application can examine
+the parameters of the current input scan and decide whether to display it or
+not.  If the scan contains only chroma data, one might choose not to use it
+as the target scan, expecting that the scan will be small and will arrive
+quickly.  To skip to the next scan, call jpeg_consume_input() until it
+returns JPEG_REACHED_SOS or JPEG_REACHED_EOI.  Or just use the next higher
+number as the target scan for jpeg_start_output(); but that method doesn't
+let you inspect the next scan's parameters before deciding to display it.
+
+
+In buffered-image mode, jpeg_start_decompress() never performs input and
+thus never suspends.  An application that uses input suspension with
+buffered-image mode must be prepared for suspension returns from these
+routines:
+* jpeg_start_output() performs input only if you request 2-pass quantization
+  and the target scan isn't fully read yet.  (This is discussed below.)
+* jpeg_read_scanlines(), as always, returns the number of scanlines that it
+  was able to produce before suspending.
+* jpeg_finish_output() will read any markers following the target scan,
+  up to the end of the file or the SOS marker that begins another scan.
+  (But it reads no input if jpeg_consume_input() has already reached the
+  end of the file or a SOS marker beyond the target output scan.)
+* jpeg_finish_decompress() will read until the end of file, and thus can
+  suspend if the end hasn't already been reached (as can be tested by
+  calling jpeg_input_complete()).
+jpeg_start_output(), jpeg_finish_output(), and jpeg_finish_decompress()
+all return TRUE if they completed their tasks, FALSE if they had to suspend.
+In the event of a FALSE return, the application must load more input data
+and repeat the call.  Applications that use non-suspending data sources need
+not check the return values of these three routines.
+
+
+It is possible to change decoding parameters between output passes in the
+buffered-image mode.  The decoder library currently supports only very
+limited changes of parameters.  ONLY THE FOLLOWING parameter changes are
+allowed after jpeg_start_decompress() is called:
+* dct_method can be changed before each call to jpeg_start_output().
+  For example, one could use a fast DCT method for early scans, changing
+  to a higher quality method for the final scan.
+* dither_mode can be changed before each call to jpeg_start_output();
+  of course this has no impact if not using color quantization.  Typically
+  one would use ordered dither for initial passes, then switch to
+  Floyd-Steinberg dither for the final pass.  Caution: changing dither mode
+  can cause more memory to be allocated by the library.  Although the amount
+  of memory involved is not large (a scanline or so), it may cause the
+  initial max_memory_to_use specification to be exceeded, which in the worst
+  case would result in an out-of-memory failure.
+* do_block_smoothing can be changed before each call to jpeg_start_output().
+  This setting is relevant only when decoding a progressive JPEG image.
+  During the first DC-only scan, block smoothing provides a very "fuzzy" look
+  instead of the very "blocky" look seen without it; which is better seems a
+  matter of personal taste.  But block smoothing is nearly always a win
+  during later stages, especially when decoding a successive-approximation
+  image: smoothing helps to hide the slight blockiness that otherwise shows
+  up on smooth gradients until the lowest coefficient bits are sent.
+* Color quantization mode can be changed under the rules described below.
+  You *cannot* change between full-color and quantized output (because that
+  would alter the required I/O buffer sizes), but you can change which
+  quantization method is used.
+
+When generating color-quantized output, changing quantization method is a
+very useful way of switching between high-speed and high-quality display.
+The library allows you to change among its three quantization methods:
+1. Single-pass quantization to a fixed color cube.
+   Selected by cinfo.two_pass_quantize = FALSE and cinfo.colormap = NULL.
+2. Single-pass quantization to an application-supplied colormap.
+   Selected by setting cinfo.colormap to point to the colormap (the value of
+   two_pass_quantize is ignored); also set cinfo.actual_number_of_colors.
+3. Two-pass quantization to a colormap chosen specifically for the image.
+   Selected by cinfo.two_pass_quantize = TRUE and cinfo.colormap = NULL.
+   (This is the default setting selected by jpeg_read_header, but it is
+   probably NOT what you want for the first pass of progressive display!)
+These methods offer successively better quality and lesser speed.  However,
+only the first method is available for quantizing in non-RGB color spaces.
+
+IMPORTANT: because the different quantizer methods have very different
+working-storage requirements, the library requires you to indicate which
+one(s) you intend to use before you call jpeg_start_decompress().  (If we did
+not require this, the max_memory_to_use setting would be a complete fiction.)
+You do this by setting one or more of these three cinfo fields to TRUE:
+	enable_1pass_quant		Fixed color cube colormap
+	enable_external_quant		Externally-supplied colormap
+	enable_2pass_quant		Two-pass custom colormap
+All three are initialized FALSE by jpeg_read_header().  But
+jpeg_start_decompress() automatically sets TRUE the one selected by the
+current two_pass_quantize and colormap settings, so you only need to set the
+enable flags for any other quantization methods you plan to change to later.
+
+After setting the enable flags correctly at jpeg_start_decompress() time, you
+can change to any enabled quantization method by setting two_pass_quantize
+and colormap properly just before calling jpeg_start_output().  The following
+special rules apply:
+1. You must explicitly set cinfo.colormap to NULL when switching to 1-pass
+   or 2-pass mode from a different mode, or when you want the 2-pass
+   quantizer to be re-run to generate a new colormap.
+2. To switch to an external colormap, or to change to a different external
+   colormap than was used on the prior pass, you must call
+   jpeg_new_colormap() after setting cinfo.colormap.
+NOTE: if you want to use the same colormap as was used in the prior pass,
+you should not do either of these things.  This will save some nontrivial
+switchover costs.
+(These requirements exist because cinfo.colormap will always be non-NULL
+after completing a prior output pass, since both the 1-pass and 2-pass
+quantizers set it to point to their output colormaps.  Thus you have to
+do one of these two things to notify the library that something has changed.
+Yup, it's a bit klugy, but it's necessary to do it this way for backwards
+compatibility.)
+
+Note that in buffered-image mode, the library generates any requested colormap
+during jpeg_start_output(), not during jpeg_start_decompress().
+
+When using two-pass quantization, jpeg_start_output() makes a pass over the
+buffered image to determine the optimum color map; it therefore may take a
+significant amount of time, whereas ordinarily it does little work.  The
+progress monitor hook is called during this pass, if defined.  It is also
+important to realize that if the specified target scan number is greater than
+or equal to the current input scan number, jpeg_start_output() will attempt
+to consume input as it makes this pass.  If you use a suspending data source,
+you need to check for a FALSE return from jpeg_start_output() under these
+conditions.  The combination of 2-pass quantization and a not-yet-fully-read
+target scan is the only case in which jpeg_start_output() will consume input.
+
+
+Application authors who support buffered-image mode may be tempted to use it
+for all JPEG images, even single-scan ones.  This will work, but it is
+inefficient: there is no need to create an image-sized coefficient buffer for
+single-scan images.  Requesting buffered-image mode for such an image wastes
+memory.  Worse, it can cost time on large images, since the buffered data has
+to be swapped out or written to a temporary file.  If you are concerned about
+maximum performance on baseline JPEG files, you should use buffered-image
+mode only when the incoming file actually has multiple scans.  This can be
+tested by calling jpeg_has_multiple_scans(), which will return a correct
+result at any time after jpeg_read_header() completes.
+
+It is also worth noting that when you use jpeg_consume_input() to let input
+processing get ahead of output processing, the resulting pattern of access to
+the coefficient buffer is quite nonsequential.  It's best to use the memory
+manager jmemnobs.c if you can (ie, if you have enough real or virtual main
+memory).  If not, at least make sure that max_memory_to_use is set as high as
+possible.  If the JPEG memory manager has to use a temporary file, you will
+probably see a lot of disk traffic and poor performance.  (This could be
+improved with additional work on the memory manager, but we haven't gotten
+around to it yet.)
+
+In some applications it may be convenient to use jpeg_consume_input() for all
+input processing, including reading the initial markers; that is, you may
+wish to call jpeg_consume_input() instead of jpeg_read_header() during
+startup.  This works, but note that you must check for JPEG_REACHED_SOS and
+JPEG_REACHED_EOI return codes as the equivalent of jpeg_read_header's codes.
+Once the first SOS marker has been reached, you must call
+jpeg_start_decompress() before jpeg_consume_input() will consume more input;
+it'll just keep returning JPEG_REACHED_SOS until you do.  If you read a
+tables-only file this way, jpeg_consume_input() will return JPEG_REACHED_EOI
+without ever returning JPEG_REACHED_SOS; be sure to check for this case.
+If this happens, the decompressor will not read any more input until you call
+jpeg_abort() to reset it.  It is OK to call jpeg_consume_input() even when not
+using buffered-image mode, but in that case it's basically a no-op after the
+initial markers have been read: it will just return JPEG_SUSPENDED.
+
+
+Abbreviated datastreams and multiple images
+-------------------------------------------
+
+A JPEG compression or decompression object can be reused to process multiple
+images.  This saves a small amount of time per image by eliminating the
+"create" and "destroy" operations, but that isn't the real purpose of the
+feature.  Rather, reuse of an object provides support for abbreviated JPEG
+datastreams.  Object reuse can also simplify processing a series of images in
+a single input or output file.  This section explains these features.
+
+A JPEG file normally contains several hundred bytes worth of quantization
+and Huffman tables.  In a situation where many images will be stored or
+transmitted with identical tables, this may represent an annoying overhead.
+The JPEG standard therefore permits tables to be omitted.  The standard
+defines three classes of JPEG datastreams:
+  * "Interchange" datastreams contain an image and all tables needed to decode
+     the image.  These are the usual kind of JPEG file.
+  * "Abbreviated image" datastreams contain an image, but are missing some or
+    all of the tables needed to decode that image.
+  * "Abbreviated table specification" (henceforth "tables-only") datastreams
+    contain only table specifications.
+To decode an abbreviated image, it is necessary to load the missing table(s)
+into the decoder beforehand.  This can be accomplished by reading a separate
+tables-only file.  A variant scheme uses a series of images in which the first
+image is an interchange (complete) datastream, while subsequent ones are
+abbreviated and rely on the tables loaded by the first image.  It is assumed
+that once the decoder has read a table, it will remember that table until a
+new definition for the same table number is encountered.
+
+It is the application designer's responsibility to figure out how to associate
+the correct tables with an abbreviated image.  While abbreviated datastreams
+can be useful in a closed environment, their use is strongly discouraged in
+any situation where data exchange with other applications might be needed.
+Caveat designer.
+
+The JPEG library provides support for reading and writing any combination of
+tables-only datastreams and abbreviated images.  In both compression and
+decompression objects, a quantization or Huffman table will be retained for
+the lifetime of the object, unless it is overwritten by a new table definition.
+
+
+To create abbreviated image datastreams, it is only necessary to tell the
+compressor not to emit some or all of the tables it is using.  Each
+quantization and Huffman table struct contains a boolean field "sent_table",
+which normally is initialized to FALSE.  For each table used by the image, the
+header-writing process emits the table and sets sent_table = TRUE unless it is
+already TRUE.  (In normal usage, this prevents outputting the same table
+definition multiple times, as would otherwise occur because the chroma
+components typically share tables.)  Thus, setting this field to TRUE before
+calling jpeg_start_compress() will prevent the table from being written at
+all.
+
+If you want to create a "pure" abbreviated image file containing no tables,
+just call "jpeg_suppress_tables(&cinfo, TRUE)" after constructing all the
+tables.  If you want to emit some but not all tables, you'll need to set the
+individual sent_table fields directly.
+
+To create an abbreviated image, you must also call jpeg_start_compress()
+with a second parameter of FALSE, not TRUE.  Otherwise jpeg_start_compress()
+will force all the sent_table fields to FALSE.  (This is a safety feature to
+prevent abbreviated images from being created accidentally.)
+
+To create a tables-only file, perform the same parameter setup that you
+normally would, but instead of calling jpeg_start_compress() and so on, call
+jpeg_write_tables(&cinfo).  This will write an abbreviated datastream
+containing only SOI, DQT and/or DHT markers, and EOI.  All the quantization
+and Huffman tables that are currently defined in the compression object will
+be emitted unless their sent_tables flag is already TRUE, and then all the
+sent_tables flags will be set TRUE.
+
+A sure-fire way to create matching tables-only and abbreviated image files
+is to proceed as follows:
+
+	create JPEG compression object
+	set JPEG parameters
+	set destination to tables-only file
+	jpeg_write_tables(&cinfo);
+	set destination to image file
+	jpeg_start_compress(&cinfo, FALSE);
+	write data...
+	jpeg_finish_compress(&cinfo);
+
+Since the JPEG parameters are not altered between writing the table file and
+the abbreviated image file, the same tables are sure to be used.  Of course,
+you can repeat the jpeg_start_compress() ... jpeg_finish_compress() sequence
+many times to produce many abbreviated image files matching the table file.
+
+You cannot suppress output of the computed Huffman tables when Huffman
+optimization is selected.  (If you could, there'd be no way to decode the
+image...)  Generally, you don't want to set optimize_coding = TRUE when
+you are trying to produce abbreviated files.
+
+In some cases you might want to compress an image using tables which are
+not stored in the application, but are defined in an interchange or
+tables-only file readable by the application.  This can be done by setting up
+a JPEG decompression object to read the specification file, then copying the
+tables into your compression object.  See jpeg_copy_critical_parameters()
+for an example of copying quantization tables.
+
+
+To read abbreviated image files, you simply need to load the proper tables
+into the decompression object before trying to read the abbreviated image.
+If the proper tables are stored in the application program, you can just
+allocate the table structs and fill in their contents directly.  For example,
+to load a fixed quantization table into table slot "n":
+
+    if (cinfo.quant_tbl_ptrs[n] == NULL)
+      cinfo.quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) &cinfo);
+    quant_ptr = cinfo.quant_tbl_ptrs[n];	/* quant_ptr is JQUANT_TBL* */
+    for (i = 0; i < 64; i++) {
+      /* Qtable[] is desired quantization table, in natural array order */
+      quant_ptr->quantval[i] = Qtable[i];
+    }
+
+Code to load a fixed Huffman table is typically (for AC table "n"):
+
+    if (cinfo.ac_huff_tbl_ptrs[n] == NULL)
+      cinfo.ac_huff_tbl_ptrs[n] = jpeg_alloc_huff_table((j_common_ptr) &cinfo);
+    huff_ptr = cinfo.ac_huff_tbl_ptrs[n];	/* huff_ptr is JHUFF_TBL* */
+    for (i = 1; i <= 16; i++) {
+      /* counts[i] is number of Huffman codes of length i bits, i=1..16 */
+      huff_ptr->bits[i] = counts[i];
+    }
+    for (i = 0; i < 256; i++) {
+      /* symbols[] is the list of Huffman symbols, in code-length order */
+      huff_ptr->huffval[i] = symbols[i];
+    }
+
+(Note that trying to set cinfo.quant_tbl_ptrs[n] to point directly at a
+constant JQUANT_TBL object is not safe.  If the incoming file happened to
+contain a quantization table definition, your master table would get
+overwritten!  Instead allocate a working table copy and copy the master table
+into it, as illustrated above.  Ditto for Huffman tables, of course.)
+
+You might want to read the tables from a tables-only file, rather than
+hard-wiring them into your application.  The jpeg_read_header() call is
+sufficient to read a tables-only file.  You must pass a second parameter of
+FALSE to indicate that you do not require an image to be present.  Thus, the
+typical scenario is
+
+	create JPEG decompression object
+	set source to tables-only file
+	jpeg_read_header(&cinfo, FALSE);
+	set source to abbreviated image file
+	jpeg_read_header(&cinfo, TRUE);
+	set decompression parameters
+	jpeg_start_decompress(&cinfo);
+	read data...
+	jpeg_finish_decompress(&cinfo);
+
+In some cases, you may want to read a file without knowing whether it contains
+an image or just tables.  In that case, pass FALSE and check the return value
+from jpeg_read_header(): it will be JPEG_HEADER_OK if an image was found,
+JPEG_HEADER_TABLES_ONLY if only tables were found.  (A third return value,
+JPEG_SUSPENDED, is possible when using a suspending data source manager.)
+Note that jpeg_read_header() will not complain if you read an abbreviated
+image for which you haven't loaded the missing tables; the missing-table check
+occurs later, in jpeg_start_decompress().
+
+
+It is possible to read a series of images from a single source file by
+repeating the jpeg_read_header() ... jpeg_finish_decompress() sequence,
+without releasing/recreating the JPEG object or the data source module.
+(If you did reinitialize, any partial bufferload left in the data source
+buffer at the end of one image would be discarded, causing you to lose the
+start of the next image.)  When you use this method, stored tables are
+automatically carried forward, so some of the images can be abbreviated images
+that depend on tables from earlier images.
+
+If you intend to write a series of images into a single destination file,
+you might want to make a specialized data destination module that doesn't
+flush the output buffer at term_destination() time.  This would speed things
+up by some trifling amount.  Of course, you'd need to remember to flush the
+buffer after the last image.  You can make the later images be abbreviated
+ones by passing FALSE to jpeg_start_compress().
+
+
+Special markers
+---------------
+
+Some applications may need to insert or extract special data in the JPEG
+datastream.  The JPEG standard provides marker types "COM" (comment) and
+"APP0" through "APP15" (application) to hold application-specific data.
+Unfortunately, the use of these markers is not specified by the standard.
+COM markers are fairly widely used to hold user-supplied text.  The JFIF file
+format spec uses APP0 markers with specified initial strings to hold certain
+data.  Adobe applications use APP14 markers beginning with the string "Adobe"
+for miscellaneous data.  Other APPn markers are rarely seen, but might
+contain almost anything.
+
+If you wish to store user-supplied text, we recommend you use COM markers
+and place readable 7-bit ASCII text in them.  Newline conventions are not
+standardized --- expect to find LF (Unix style), CR/LF (DOS style), or CR
+(Mac style).  A robust COM reader should be able to cope with random binary
+garbage, including nulls, since some applications generate COM markers
+containing non-ASCII junk.  (But yours should not be one of them.)
+
+For program-supplied data, use an APPn marker, and be sure to begin it with an
+identifying string so that you can tell whether the marker is actually yours.
+It's probably best to avoid using APP0 or APP14 for any private markers.
+(NOTE: the upcoming SPIFF standard will use APP8 markers; we recommend you
+not use APP8 markers for any private purposes, either.)
+
+Keep in mind that at most 65533 bytes can be put into one marker, but you
+can have as many markers as you like.
+
+By default, the IJG compression library will write a JFIF APP0 marker if the
+selected JPEG colorspace is grayscale or YCbCr, or an Adobe APP14 marker if
+the selected colorspace is RGB, CMYK, or YCCK.  You can disable this, but
+we don't recommend it.  The decompression library will recognize JFIF and
+Adobe markers and will set the JPEG colorspace properly when one is found.
+
+
+You can write special markers immediately following the datastream header by
+calling jpeg_write_marker() after jpeg_start_compress() and before the first
+call to jpeg_write_scanlines().  When you do this, the markers appear after
+the SOI and the JFIF APP0 and Adobe APP14 markers (if written), but before
+all else.  Specify the marker type parameter as "JPEG_COM" for COM or
+"JPEG_APP0 + n" for APPn.  (Actually, jpeg_write_marker will let you write
+any marker type, but we don't recommend writing any other kinds of marker.)
+For example, to write a user comment string pointed to by comment_text:
+	jpeg_write_marker(cinfo, JPEG_COM, comment_text, strlen(comment_text));
+
+If it's not convenient to store all the marker data in memory at once,
+you can instead call jpeg_write_m_header() followed by multiple calls to
+jpeg_write_m_byte().  If you do it this way, it's your responsibility to
+call jpeg_write_m_byte() exactly the number of times given in the length
+parameter to jpeg_write_m_header().  (This method lets you empty the
+output buffer partway through a marker, which might be important when
+using a suspending data destination module.  In any case, if you are using
+a suspending destination, you should flush its buffer after inserting
+any special markers.  See "I/O suspension".)
+
+Or, if you prefer to synthesize the marker byte sequence yourself,
+you can just cram it straight into the data destination module.
+
+If you are writing JFIF 1.02 extension markers (thumbnail images), don't
+forget to set cinfo.JFIF_minor_version = 2 so that the encoder will write the
+correct JFIF version number in the JFIF header marker.  The library's default
+is to write version 1.01, but that's wrong if you insert any 1.02 extension
+markers.  (We could probably get away with just defaulting to 1.02, but there
+used to be broken decoders that would complain about unknown minor version
+numbers.  To reduce compatibility risks it's safest not to write 1.02 unless
+you are actually using 1.02 extensions.)
+
+
+When reading, two methods of handling special markers are available:
+1. You can ask the library to save the contents of COM and/or APPn markers
+into memory, and then examine them at your leisure afterwards.
+2. You can supply your own routine to process COM and/or APPn markers
+on-the-fly as they are read.
+The first method is simpler to use, especially if you are using a suspending
+data source; writing a marker processor that copes with input suspension is
+not easy (consider what happens if the marker is longer than your available
+input buffer).  However, the second method conserves memory since the marker
+data need not be kept around after it's been processed.
+
+For either method, you'd normally set up marker handling after creating a
+decompression object and before calling jpeg_read_header(), because the
+markers of interest will typically be near the head of the file and so will
+be scanned by jpeg_read_header.  Once you've established a marker handling
+method, it will be used for the life of that decompression object
+(potentially many datastreams), unless you change it.  Marker handling is
+determined separately for COM markers and for each APPn marker code.
+
+
+To save the contents of special markers in memory, call
+	jpeg_save_markers(cinfo, marker_code, length_limit)
+where marker_code is the marker type to save, JPEG_COM or JPEG_APP0+n.
+(To arrange to save all the special marker types, you need to call this
+routine 17 times, for COM and APP0-APP15.)  If the incoming marker is longer
+than length_limit data bytes, only length_limit bytes will be saved; this
+parameter allows you to avoid chewing up memory when you only need to see the
+first few bytes of a potentially large marker.  If you want to save all the
+data, set length_limit to 0xFFFF; that is enough since marker lengths are only
+16 bits.  As a special case, setting length_limit to 0 prevents that marker
+type from being saved at all.  (That is the default behavior, in fact.)
+
+After jpeg_read_header() completes, you can examine the special markers by
+following the cinfo->marker_list pointer chain.  All the special markers in
+the file appear in this list, in order of their occurrence in the file (but
+omitting any markers of types you didn't ask for).  Both the original data
+length and the saved data length are recorded for each list entry; the latter
+will not exceed length_limit for the particular marker type.  Note that these
+lengths exclude the marker length word, whereas the stored representation
+within the JPEG file includes it.  (Hence the maximum data length is really
+only 65533.)
+
+It is possible that additional special markers appear in the file beyond the
+SOS marker at which jpeg_read_header stops; if so, the marker list will be
+extended during reading of the rest of the file.  This is not expected to be
+common, however.  If you are short on memory you may want to reset the length
+limit to zero for all marker types after finishing jpeg_read_header, to
+ensure that the max_memory_to_use setting cannot be exceeded due to addition
+of later markers.
+
+The marker list remains stored until you call jpeg_finish_decompress or
+jpeg_abort, at which point the memory is freed and the list is set to empty.
+(jpeg_destroy also releases the storage, of course.)
+
+Note that the library is internally interested in APP0 and APP14 markers;
+if you try to set a small nonzero length limit on these types, the library
+will silently force the length up to the minimum it wants.  (But you can set
+a zero length limit to prevent them from being saved at all.)  Also, in a
+16-bit environment, the maximum length limit may be constrained to less than
+65533 by malloc() limitations.  It is therefore best not to assume that the
+effective length limit is exactly what you set it to be.
+
+
+If you want to supply your own marker-reading routine, you do it by calling
+jpeg_set_marker_processor().  A marker processor routine must have the
+signature
+	boolean jpeg_marker_parser_method (j_decompress_ptr cinfo)
+Although the marker code is not explicitly passed, the routine can find it
+in cinfo->unread_marker.  At the time of call, the marker proper has been
+read from the data source module.  The processor routine is responsible for
+reading the marker length word and the remaining parameter bytes, if any.
+Return TRUE to indicate success.  (FALSE should be returned only if you are
+using a suspending data source and it tells you to suspend.  See the standard
+marker processors in jdmarker.c for appropriate coding methods if you need to
+use a suspending data source.)
+
+If you override the default APP0 or APP14 processors, it is up to you to
+recognize JFIF and Adobe markers if you want colorspace recognition to occur
+properly.  We recommend copying and extending the default processors if you
+want to do that.  (A better idea is to save these marker types for later
+examination by calling jpeg_save_markers(); that method doesn't interfere
+with the library's own processing of these markers.)
+
+jpeg_set_marker_processor() and jpeg_save_markers() are mutually exclusive
+--- if you call one it overrides any previous call to the other, for the
+particular marker type specified.
+
+A simple example of an external COM processor can be found in djpeg.c.
+Also, see jpegtran.c for an example of using jpeg_save_markers.
+
+
+Raw (downsampled) image data
+----------------------------
+
+Some applications need to supply already-downsampled image data to the JPEG
+compressor, or to receive raw downsampled data from the decompressor.  The
+library supports this requirement by allowing the application to write or
+read raw data, bypassing the normal preprocessing or postprocessing steps.
+The interface is different from the standard one and is somewhat harder to
+use.  If your interest is merely in bypassing color conversion, we recommend
+that you use the standard interface and simply set jpeg_color_space =
+in_color_space (or jpeg_color_space = out_color_space for decompression).
+The mechanism described in this section is necessary only to supply or
+receive downsampled image data, in which not all components have the same
+dimensions.
+
+
+To compress raw data, you must supply the data in the colorspace to be used
+in the JPEG file (please read the earlier section on Special color spaces)
+and downsampled to the sampling factors specified in the JPEG parameters.
+You must supply the data in the format used internally by the JPEG library,
+namely a JSAMPIMAGE array.  This is an array of pointers to two-dimensional
+arrays, each of type JSAMPARRAY.  Each 2-D array holds the values for one
+color component.  This structure is necessary since the components are of
+different sizes.  If the image dimensions are not a multiple of the MCU size,
+you must also pad the data correctly (usually, this is done by replicating
+the last column and/or row).  The data must be padded to a multiple of a DCT
+block in each component: that is, each downsampled row must contain a
+multiple of 8 valid samples, and there must be a multiple of 8 sample rows
+for each component.  (For applications such as conversion of digital TV
+images, the standard image size is usually a multiple of the DCT block size,
+so that no padding need actually be done.)
+
+The procedure for compression of raw data is basically the same as normal
+compression, except that you call jpeg_write_raw_data() in place of
+jpeg_write_scanlines().  Before calling jpeg_start_compress(), you must do
+the following:
+  * Set cinfo->raw_data_in to TRUE.  (It is set FALSE by jpeg_set_defaults().)
+    This notifies the library that you will be supplying raw data.
+  * Ensure jpeg_color_space is correct --- an explicit jpeg_set_colorspace()
+    call is a good idea.  Note that since color conversion is bypassed,
+    in_color_space is ignored, except that jpeg_set_defaults() uses it to
+    choose the default jpeg_color_space setting.
+  * Ensure the sampling factors, cinfo->comp_info[i].h_samp_factor and
+    cinfo->comp_info[i].v_samp_factor, are correct.  Since these indicate the
+    dimensions of the data you are supplying, it's wise to set them
+    explicitly, rather than assuming the library's defaults are what you want.
+
+To pass raw data to the library, call jpeg_write_raw_data() in place of
+jpeg_write_scanlines().  The two routines work similarly except that
+jpeg_write_raw_data takes a JSAMPIMAGE data array rather than JSAMPARRAY.
+The scanlines count passed to and returned from jpeg_write_raw_data is
+measured in terms of the component with the largest v_samp_factor.
+
+jpeg_write_raw_data() processes one MCU row per call, which is to say
+v_samp_factor*DCTSIZE sample rows of each component.  The passed num_lines
+value must be at least max_v_samp_factor*DCTSIZE, and the return value will
+be exactly that amount (or possibly some multiple of that amount, in future
+library versions).  This is true even on the last call at the bottom of the
+image; don't forget to pad your data as necessary.
+
+The required dimensions of the supplied data can be computed for each
+component as
+	cinfo->comp_info[i].width_in_blocks*DCTSIZE  samples per row
+	cinfo->comp_info[i].height_in_blocks*DCTSIZE rows in image
+after jpeg_start_compress() has initialized those fields.  If the valid data
+is smaller than this, it must be padded appropriately.  For some sampling
+factors and image sizes, additional dummy DCT blocks are inserted to make
+the image a multiple of the MCU dimensions.  The library creates such dummy
+blocks itself; it does not read them from your supplied data.  Therefore you
+need never pad by more than DCTSIZE samples.  An example may help here.
+Assume 2h2v downsampling of YCbCr data, that is
+	cinfo->comp_info[0].h_samp_factor = 2		for Y
+	cinfo->comp_info[0].v_samp_factor = 2
+	cinfo->comp_info[1].h_samp_factor = 1		for Cb
+	cinfo->comp_info[1].v_samp_factor = 1
+	cinfo->comp_info[2].h_samp_factor = 1		for Cr
+	cinfo->comp_info[2].v_samp_factor = 1
+and suppose that the nominal image dimensions (cinfo->image_width and
+cinfo->image_height) are 101x101 pixels.  Then jpeg_start_compress() will
+compute downsampled_width = 101 and width_in_blocks = 13 for Y,
+downsampled_width = 51 and width_in_blocks = 7 for Cb and Cr (and the same
+for the height fields).  You must pad the Y data to at least 13*8 = 104
+columns and rows, the Cb/Cr data to at least 7*8 = 56 columns and rows.  The
+MCU height is max_v_samp_factor = 2 DCT rows so you must pass at least 16
+scanlines on each call to jpeg_write_raw_data(), which is to say 16 actual
+sample rows of Y and 8 each of Cb and Cr.  A total of 7 MCU rows are needed,
+so you must pass a total of 7*16 = 112 "scanlines".  The last DCT block row
+of Y data is dummy, so it doesn't matter what you pass for it in the data
+arrays, but the scanlines count must total up to 112 so that all of the Cb
+and Cr data gets passed.
+
+Output suspension is supported with raw-data compression: if the data
+destination module suspends, jpeg_write_raw_data() will return 0.
+In this case the same data rows must be passed again on the next call.
+
+
+Decompression with raw data output implies bypassing all postprocessing:
+you cannot ask for rescaling or color quantization, for instance.  More
+seriously, you must deal with the color space and sampling factors present in
+the incoming file.  If your application only handles, say, 2h1v YCbCr data,
+you must check for and fail on other color spaces or other sampling factors.
+The library will not convert to a different color space for you.
+
+To obtain raw data output, set cinfo->raw_data_out = TRUE before
+jpeg_start_decompress() (it is set FALSE by jpeg_read_header()).  Be sure to
+verify that the color space and sampling factors are ones you can handle.
+Then call jpeg_read_raw_data() in place of jpeg_read_scanlines().  The
+decompression process is otherwise the same as usual.
+
+jpeg_read_raw_data() returns one MCU row per call, and thus you must pass a
+buffer of at least max_v_samp_factor*DCTSIZE scanlines (scanline counting is
+the same as for raw-data compression).  The buffer you pass must be large
+enough to hold the actual data plus padding to DCT-block boundaries.  As with
+compression, any entirely dummy DCT blocks are not processed so you need not
+allocate space for them, but the total scanline count includes them.  The
+above example of computing buffer dimensions for raw-data compression is
+equally valid for decompression.
+
+Input suspension is supported with raw-data decompression: if the data source
+module suspends, jpeg_read_raw_data() will return 0.  You can also use
+buffered-image mode to read raw data in multiple passes.
+
+
+Really raw data: DCT coefficients
+---------------------------------
+
+It is possible to read or write the contents of a JPEG file as raw DCT
+coefficients.  This facility is mainly intended for use in lossless
+transcoding between different JPEG file formats.  Other possible applications
+include lossless cropping of a JPEG image, lossless reassembly of a
+multi-strip or multi-tile TIFF/JPEG file into a single JPEG datastream, etc.
+
+To read the contents of a JPEG file as DCT coefficients, open the file and do
+jpeg_read_header() as usual.  But instead of calling jpeg_start_decompress()
+and jpeg_read_scanlines(), call jpeg_read_coefficients().  This will read the
+entire image into a set of virtual coefficient-block arrays, one array per
+component.  The return value is a pointer to an array of virtual-array
+descriptors.  Each virtual array can be accessed directly using the JPEG
+memory manager's access_virt_barray method (see Memory management, below,
+and also read structure.doc's discussion of virtual array handling).  Or,
+for simple transcoding to a different JPEG file format, the array list can
+just be handed directly to jpeg_write_coefficients().
+
+Each block in the block arrays contains quantized coefficient values in
+normal array order (not JPEG zigzag order).  The block arrays contain only
+DCT blocks containing real data; any entirely-dummy blocks added to fill out
+interleaved MCUs at the right or bottom edges of the image are discarded
+during reading and are not stored in the block arrays.  (The size of each
+block array can be determined from the width_in_blocks and height_in_blocks
+fields of the component's comp_info entry.)  This is also the data format
+expected by jpeg_write_coefficients().
+
+When you are done using the virtual arrays, call jpeg_finish_decompress()
+to release the array storage and return the decompression object to an idle
+state; or just call jpeg_destroy() if you don't need to reuse the object.
+
+If you use a suspending data source, jpeg_read_coefficients() will return
+NULL if it is forced to suspend; a non-NULL return value indicates successful
+completion.  You need not test for a NULL return value when using a
+non-suspending data source.
+
+It is also possible to call jpeg_read_coefficients() to obtain access to the
+decoder's coefficient arrays during a normal decode cycle in buffered-image
+mode.  This frammish might be useful for progressively displaying an incoming
+image and then re-encoding it without loss.  To do this, decode in buffered-
+image mode as discussed previously, then call jpeg_read_coefficients() after
+the last jpeg_finish_output() call.  The arrays will be available for your use
+until you call jpeg_finish_decompress().
+
+
+To write the contents of a JPEG file as DCT coefficients, you must provide
+the DCT coefficients stored in virtual block arrays.  You can either pass
+block arrays read from an input JPEG file by jpeg_read_coefficients(), or
+allocate virtual arrays from the JPEG compression object and fill them
+yourself.  In either case, jpeg_write_coefficients() is substituted for
+jpeg_start_compress() and jpeg_write_scanlines().  Thus the sequence is
+  * Create compression object
+  * Set all compression parameters as necessary
+  * Request virtual arrays if needed
+  * jpeg_write_coefficients()
+  * jpeg_finish_compress()
+  * Destroy or re-use compression object
+jpeg_write_coefficients() is passed a pointer to an array of virtual block
+array descriptors; the number of arrays is equal to cinfo.num_components.
+
+The virtual arrays need only have been requested, not realized, before
+jpeg_write_coefficients() is called.  A side-effect of
+jpeg_write_coefficients() is to realize any virtual arrays that have been
+requested from the compression object's memory manager.  Thus, when obtaining
+the virtual arrays from the compression object, you should fill the arrays
+after calling jpeg_write_coefficients().  The data is actually written out
+when you call jpeg_finish_compress(); jpeg_write_coefficients() only writes
+the file header.
+
+When writing raw DCT coefficients, it is crucial that the JPEG quantization
+tables and sampling factors match the way the data was encoded, or the
+resulting file will be invalid.  For transcoding from an existing JPEG file,
+we recommend using jpeg_copy_critical_parameters().  This routine initializes
+all the compression parameters to default values (like jpeg_set_defaults()),
+then copies the critical information from a source decompression object.
+The decompression object should have just been used to read the entire
+JPEG input file --- that is, it should be awaiting jpeg_finish_decompress().
+
+jpeg_write_coefficients() marks all tables stored in the compression object
+as needing to be written to the output file (thus, it acts like
+jpeg_start_compress(cinfo, TRUE)).  This is for safety's sake, to avoid
+emitting abbreviated JPEG files by accident.  If you really want to emit an
+abbreviated JPEG file, call jpeg_suppress_tables(), or set the tables'
+individual sent_table flags, between calling jpeg_write_coefficients() and
+jpeg_finish_compress().
+
+
+Progress monitoring
+-------------------
+
+Some applications may need to regain control from the JPEG library every so
+often.  The typical use of this feature is to produce a percent-done bar or
+other progress display.  (For a simple example, see cjpeg.c or djpeg.c.)
+Although you do get control back frequently during the data-transferring pass
+(the jpeg_read_scanlines or jpeg_write_scanlines loop), any additional passes
+will occur inside jpeg_finish_compress or jpeg_start_decompress; those
+routines may take a long time to execute, and you don't get control back
+until they are done.
+
+You can define a progress-monitor routine which will be called periodically
+by the library.  No guarantees are made about how often this call will occur,
+so we don't recommend you use it for mouse tracking or anything like that.
+At present, a call will occur once per MCU row, scanline, or sample row
+group, whichever unit is convenient for the current processing mode; so the
+wider the image, the longer the time between calls.  During the data
+transferring pass, only one call occurs per call of jpeg_read_scanlines or
+jpeg_write_scanlines, so don't pass a large number of scanlines at once if
+you want fine resolution in the progress count.  (If you really need to use
+the callback mechanism for time-critical tasks like mouse tracking, you could
+insert additional calls inside some of the library's inner loops.)
+
+To establish a progress-monitor callback, create a struct jpeg_progress_mgr,
+fill in its progress_monitor field with a pointer to your callback routine,
+and set cinfo->progress to point to the struct.  The callback will be called
+whenever cinfo->progress is non-NULL.  (This pointer is set to NULL by
+jpeg_create_compress or jpeg_create_decompress; the library will not change
+it thereafter.  So if you allocate dynamic storage for the progress struct,
+make sure it will live as long as the JPEG object does.  Allocating from the
+JPEG memory manager with lifetime JPOOL_PERMANENT will work nicely.)  You
+can use the same callback routine for both compression and decompression.
+
+The jpeg_progress_mgr struct contains four fields which are set by the library:
+	long pass_counter;	/* work units completed in this pass */
+	long pass_limit;	/* total number of work units in this pass */
+	int completed_passes;	/* passes completed so far */
+	int total_passes;	/* total number of passes expected */
+During any one pass, pass_counter increases from 0 up to (not including)
+pass_limit; the step size is usually but not necessarily 1.  The pass_limit
+value may change from one pass to another.  The expected total number of
+passes is in total_passes, and the number of passes already completed is in
+completed_passes.  Thus the fraction of work completed may be estimated as
+		completed_passes + (pass_counter/pass_limit)
+		--------------------------------------------
+				total_passes
+ignoring the fact that the passes may not be equal amounts of work.
+
+When decompressing, pass_limit can even change within a pass, because it
+depends on the number of scans in the JPEG file, which isn't always known in
+advance.  The computed fraction-of-work-done may jump suddenly (if the library
+discovers it has overestimated the number of scans) or even decrease (in the
+opposite case).  It is not wise to put great faith in the work estimate.
+
+When using the decompressor's buffered-image mode, the progress monitor work
+estimate is likely to be completely unhelpful, because the library has no way
+to know how many output passes will be demanded of it.  Currently, the library
+sets total_passes based on the assumption that there will be one more output
+pass if the input file end hasn't yet been read (jpeg_input_complete() isn't
+TRUE), but no more output passes if the file end has been reached when the
+output pass is started.  This means that total_passes will rise as additional
+output passes are requested.  If you have a way of determining the input file
+size, estimating progress based on the fraction of the file that's been read
+will probably be more useful than using the library's value.
+
+
+Memory management
+-----------------
+
+This section covers some key facts about the JPEG library's built-in memory
+manager.  For more info, please read structure.doc's section about the memory
+manager, and consult the source code if necessary.
+
+All memory and temporary file allocation within the library is done via the
+memory manager.  If necessary, you can replace the "back end" of the memory
+manager to control allocation yourself (for example, if you don't want the
+library to use malloc() and free() for some reason).
+
+Some data is allocated "permanently" and will not be freed until the JPEG
+object is destroyed.  Most data is allocated "per image" and is freed by
+jpeg_finish_compress, jpeg_finish_decompress, or jpeg_abort.  You can call the
+memory manager yourself to allocate structures that will automatically be
+freed at these times.  Typical code for this is
+  ptr = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, size);
+Use JPOOL_PERMANENT to get storage that lasts as long as the JPEG object.
+Use alloc_large instead of alloc_small for anything bigger than a few Kbytes.
+There are also alloc_sarray and alloc_barray routines that automatically
+build 2-D sample or block arrays.
+
+The library's minimum space requirements to process an image depend on the
+image's width, but not on its height, because the library ordinarily works
+with "strip" buffers that are as wide as the image but just a few rows high.
+Some operating modes (eg, two-pass color quantization) require full-image
+buffers.  Such buffers are treated as "virtual arrays": only the current strip
+need be in memory, and the rest can be swapped out to a temporary file.
+
+If you use the simplest memory manager back end (jmemnobs.c), then no
+temporary files are used; virtual arrays are simply malloc()'d.  Images bigger
+than memory can be processed only if your system supports virtual memory.
+The other memory manager back ends support temporary files of various flavors
+and thus work in machines without virtual memory.  They may also be useful on
+Unix machines if you need to process images that exceed available swap space.
+
+When using temporary files, the library will make the in-memory buffers for
+its virtual arrays just big enough to stay within a "maximum memory" setting.
+Your application can set this limit by setting cinfo->mem->max_memory_to_use
+after creating the JPEG object.  (Of course, there is still a minimum size for
+the buffers, so the max-memory setting is effective only if it is bigger than
+the minimum space needed.)  If you allocate any large structures yourself, you
+must allocate them before jpeg_start_compress() or jpeg_start_decompress() in
+order to have them counted against the max memory limit.  Also keep in mind
+that space allocated with alloc_small() is ignored, on the assumption that
+it's too small to be worth worrying about; so a reasonable safety margin
+should be left when setting max_memory_to_use.
+
+If you use the jmemname.c or jmemdos.c memory manager back end, it is
+important to clean up the JPEG object properly to ensure that the temporary
+files get deleted.  (This is especially crucial with jmemdos.c, where the
+"temporary files" may be extended-memory segments; if they are not freed,
+DOS will require a reboot to recover the memory.)  Thus, with these memory
+managers, it's a good idea to provide a signal handler that will trap any
+early exit from your program.  The handler should call either jpeg_abort()
+or jpeg_destroy() for any active JPEG objects.  A handler is not needed with
+jmemnobs.c, and shouldn't be necessary with jmemansi.c or jmemmac.c either,
+since the C library is supposed to take care of deleting files made with
+tmpfile().
+
+
+Memory usage
+------------
+
+Working memory requirements while performing compression or decompression
+depend on image dimensions, image characteristics (such as colorspace and
+JPEG process), and operating mode (application-selected options).
+
+As of v6b, the decompressor requires:
+ 1. About 24K in more-or-less-fixed-size data.  This varies a bit depending
+    on operating mode and image characteristics (particularly color vs.
+    grayscale), but it doesn't depend on image dimensions.
+ 2. Strip buffers (of size proportional to the image width) for IDCT and
+    upsampling results.  The worst case for commonly used sampling factors
+    is about 34 bytes * width in pixels for a color image.  A grayscale image
+    only needs about 8 bytes per pixel column.
+ 3. A full-image DCT coefficient buffer is needed to decode a multi-scan JPEG
+    file (including progressive JPEGs), or whenever you select buffered-image
+    mode.  This takes 2 bytes/coefficient.  At typical 2x2 sampling, that's
+    3 bytes per pixel for a color image.  Worst case (1x1 sampling) requires
+    6 bytes/pixel.  For grayscale, figure 2 bytes/pixel.
+ 4. To perform 2-pass color quantization, the decompressor also needs a
+    128K color lookup table and a full-image pixel buffer (3 bytes/pixel).
+This does not count any memory allocated by the application, such as a
+buffer to hold the final output image.
+
+The above figures are valid for 8-bit JPEG data precision and a machine with
+32-bit ints.  For 12-bit JPEG data, double the size of the strip buffers and
+quantization pixel buffer.  The "fixed-size" data will be somewhat smaller
+with 16-bit ints, larger with 64-bit ints.  Also, CMYK or other unusual
+color spaces will require different amounts of space.
+
+The full-image coefficient and pixel buffers, if needed at all, do not
+have to be fully RAM resident; you can have the library use temporary
+files instead when the total memory usage would exceed a limit you set.
+(But if your OS supports virtual memory, it's probably better to just use
+jmemnobs and let the OS do the swapping.)
+
+The compressor's memory requirements are similar, except that it has no need
+for color quantization.  Also, it needs a full-image DCT coefficient buffer
+if Huffman-table optimization is asked for, even if progressive mode is not
+requested.
+
+If you need more detailed information about memory usage in a particular
+situation, you can enable the MEM_STATS code in jmemmgr.c.
+
+
+Library compile-time options
+----------------------------
+
+A number of compile-time options are available by modifying jmorecfg.h.
+
+The JPEG standard provides for both the baseline 8-bit DCT process and
+a 12-bit DCT process.  The IJG code supports 12-bit lossy JPEG if you define
+BITS_IN_JSAMPLE as 12 rather than 8.  Note that this causes JSAMPLE to be
+larger than a char, so it affects the surrounding application's image data.
+The sample applications cjpeg and djpeg can support 12-bit mode only for PPM
+and GIF file formats; you must disable the other file formats to compile a
+12-bit cjpeg or djpeg.  (install.doc has more information about that.)
+At present, a 12-bit library can handle *only* 12-bit images, not both
+precisions.  (If you need to include both 8- and 12-bit libraries in a single
+application, you could probably do it by defining NEED_SHORT_EXTERNAL_NAMES
+for just one of the copies.  You'd have to access the 8-bit and 12-bit copies
+from separate application source files.  This is untested ... if you try it,
+we'd like to hear whether it works!)
+
+Note that a 12-bit library always compresses in Huffman optimization mode,
+in order to generate valid Huffman tables.  This is necessary because our
+default Huffman tables only cover 8-bit data.  If you need to output 12-bit
+files in one pass, you'll have to supply suitable default Huffman tables.
+You may also want to supply your own DCT quantization tables; the existing
+quality-scaling code has been developed for 8-bit use, and probably doesn't
+generate especially good tables for 12-bit.
+
+The maximum number of components (color channels) in the image is determined
+by MAX_COMPONENTS.  The JPEG standard allows up to 255 components, but we
+expect that few applications will need more than four or so.
+
+On machines with unusual data type sizes, you may be able to improve
+performance or reduce memory space by tweaking the various typedefs in
+jmorecfg.h.  In particular, on some RISC CPUs, access to arrays of "short"s
+is quite slow; consider trading memory for speed by making JCOEF, INT16, and
+UINT16 be "int" or "unsigned int".  UINT8 is also a candidate to become int.
+You probably don't want to make JSAMPLE be int unless you have lots of memory
+to burn.
+
+You can reduce the size of the library by compiling out various optional
+functions.  To do this, undefine xxx_SUPPORTED symbols as necessary.
+
+You can also save a few K by not having text error messages in the library;
+the standard error message table occupies about 5Kb.  This is particularly
+reasonable for embedded applications where there's no good way to display 
+a message anyway.  To do this, remove the creation of the message table
+(jpeg_std_message_table[]) from jerror.c, and alter format_message to do
+something reasonable without it.  You could output the numeric value of the
+message code number, for example.  If you do this, you can also save a couple
+more K by modifying the TRACEMSn() macros in jerror.h to expand to nothing;
+you don't need trace capability anyway, right?
+
+
+Portability considerations
+--------------------------
+
+The JPEG library has been written to be extremely portable; the sample
+applications cjpeg and djpeg are slightly less so.  This section summarizes
+the design goals in this area.  (If you encounter any bugs that cause the
+library to be less portable than is claimed here, we'd appreciate hearing
+about them.)
+
+The code works fine on ANSI C, C++, and pre-ANSI C compilers, using any of
+the popular system include file setups, and some not-so-popular ones too.
+See install.doc for configuration procedures.
+
+The code is not dependent on the exact sizes of the C data types.  As
+distributed, we make the assumptions that
+	char	is at least 8 bits wide
+	short	is at least 16 bits wide
+	int	is at least 16 bits wide
+	long	is at least 32 bits wide
+(These are the minimum requirements of the ANSI C standard.)  Wider types will
+work fine, although memory may be used inefficiently if char is much larger
+than 8 bits or short is much bigger than 16 bits.  The code should work
+equally well with 16- or 32-bit ints.
+
+In a system where these assumptions are not met, you may be able to make the
+code work by modifying the typedefs in jmorecfg.h.  However, you will probably
+have difficulty if int is less than 16 bits wide, since references to plain
+int abound in the code.
+
+char can be either signed or unsigned, although the code runs faster if an
+unsigned char type is available.  If char is wider than 8 bits, you will need
+to redefine JOCTET and/or provide custom data source/destination managers so
+that JOCTET represents exactly 8 bits of data on external storage.
+
+The JPEG library proper does not assume ASCII representation of characters.
+But some of the image file I/O modules in cjpeg/djpeg do have ASCII
+dependencies in file-header manipulation; so does cjpeg's select_file_type()
+routine.
+
+The JPEG library does not rely heavily on the C library.  In particular, C
+stdio is used only by the data source/destination modules and the error
+handler, all of which are application-replaceable.  (cjpeg/djpeg are more
+heavily dependent on stdio.)  malloc and free are called only from the memory
+manager "back end" module, so you can use a different memory allocator by
+replacing that one file.
+
+The code generally assumes that C names must be unique in the first 15
+characters.  However, global function names can be made unique in the
+first 6 characters by defining NEED_SHORT_EXTERNAL_NAMES.
+
+More info about porting the code may be gleaned by reading jconfig.doc,
+jmorecfg.h, and jinclude.h.
+
+
+Notes for MS-DOS implementors
+-----------------------------
+
+The IJG code is designed to work efficiently in 80x86 "small" or "medium"
+memory models (i.e., data pointers are 16 bits unless explicitly declared
+"far"; code pointers can be either size).  You may be able to use small
+model to compile cjpeg or djpeg by itself, but you will probably have to use
+medium model for any larger application.  This won't make much difference in
+performance.  You *will* take a noticeable performance hit if you use a
+large-data memory model (perhaps 10%-25%), and you should avoid "huge" model
+if at all possible.
+
+The JPEG library typically needs 2Kb-3Kb of stack space.  It will also
+malloc about 20K-30K of near heap space while executing (and lots of far
+heap, but that doesn't count in this calculation).  This figure will vary
+depending on selected operating mode, and to a lesser extent on image size.
+There is also about 5Kb-6Kb of constant data which will be allocated in the
+near data segment (about 4Kb of this is the error message table).
+Thus you have perhaps 20K available for other modules' static data and near
+heap space before you need to go to a larger memory model.  The C library's
+static data will account for several K of this, but that still leaves a good
+deal for your needs.  (If you are tight on space, you could reduce the sizes
+of the I/O buffers allocated by jdatasrc.c and jdatadst.c, say from 4K to
+1K.  Another possibility is to move the error message table to far memory;
+this should be doable with only localized hacking on jerror.c.)
+
+About 2K of the near heap space is "permanent" memory that will not be
+released until you destroy the JPEG object.  This is only an issue if you
+save a JPEG object between compression or decompression operations.
+
+Far data space may also be a tight resource when you are dealing with large
+images.  The most memory-intensive case is decompression with two-pass color
+quantization, or single-pass quantization to an externally supplied color
+map.  This requires a 128Kb color lookup table plus strip buffers amounting
+to about 40 bytes per column for typical sampling ratios (eg, about 25600
+bytes for a 640-pixel-wide image).  You may not be able to process wide
+images if you have large data structures of your own.
+
+Of course, all of these concerns vanish if you use a 32-bit flat-memory-model
+compiler, such as DJGPP or Watcom C.  We highly recommend flat model if you
+can use it; the JPEG library is significantly faster in flat model.
diff --git a/Utilities/FLTK/jpeg/makedepend b/Utilities/FLTK/jpeg/makedepend
new file mode 100644
index 0000000000000000000000000000000000000000..ecf2b024c80b654ca58e718b8411298f7da69ab3
--- /dev/null
+++ b/Utilities/FLTK/jpeg/makedepend
@@ -0,0 +1,94 @@
+# DO NOT DELETE
+
+jmemnobs.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jmemnobs.o: jerror.h jmemsys.h
+jcapimin.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcapimin.o: jerror.h
+jcapistd.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcapistd.o: jerror.h
+jccoefct.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jccoefct.o: jerror.h
+jccolor.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jccolor.o: jerror.h
+jcdctmgr.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcdctmgr.o: jerror.h jdct.h
+jchuff.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jchuff.o: jerror.h jchuff.h
+jcinit.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcinit.o: jerror.h
+jcmainct.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcmainct.o: jerror.h
+jcmarker.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcmarker.o: jerror.h
+jcmaster.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcmaster.o: jerror.h
+jcomapi.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcomapi.o: jerror.h
+jcparam.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcparam.o: jerror.h
+jcphuff.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcphuff.o: jerror.h jchuff.h
+jcprepct.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcprepct.o: jerror.h
+jcsample.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jcsample.o: jerror.h
+jctrans.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jctrans.o: jerror.h
+jdapimin.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdapimin.o: jerror.h
+jdapistd.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdapistd.o: jerror.h
+jdatadst.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdatadst.o: jerror.h
+jdatasrc.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdatasrc.o: jerror.h
+jdcoefct.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdcoefct.o: jerror.h
+jdcolor.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdcolor.o: jerror.h
+jddctmgr.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jddctmgr.o: jerror.h jdct.h
+jdhuff.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdhuff.o: jerror.h jdhuff.h
+jdinput.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdinput.o: jerror.h
+jdmainct.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdmainct.o: jerror.h
+jdmarker.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdmarker.o: jerror.h
+jdmaster.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdmaster.o: jerror.h
+jdmerge.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdmerge.o: jerror.h
+jdphuff.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdphuff.o: jerror.h jdhuff.h
+jdpostct.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdpostct.o: jerror.h
+jdsample.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdsample.o: jerror.h
+jdtrans.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jdtrans.o: jerror.h
+jerror.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jerror.o: jerror.h jversion.h
+jfdctflt.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jfdctflt.o: jerror.h jdct.h
+jfdctfst.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jfdctfst.o: jerror.h jdct.h
+jfdctint.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jfdctint.o: jerror.h jdct.h
+jidctflt.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jidctflt.o: jerror.h jdct.h
+jidctfst.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jidctfst.o: jerror.h jdct.h
+jidctint.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jidctint.o: jerror.h jdct.h
+jidctred.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jidctred.o: jerror.h jdct.h
+jquant1.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jquant1.o: jerror.h
+jquant2.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jquant2.o: jerror.h
+jutils.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jutils.o: jerror.h
+jmemmgr.o: jinclude.h jconfig.h ../config.h jpeglib.h jmorecfg.h jpegint.h
+jmemmgr.o: jerror.h jmemsys.h
diff --git a/Utilities/FLTK/jpeg/makefile.wat b/Utilities/FLTK/jpeg/makefile.wat
new file mode 100644
index 0000000000000000000000000000000000000000..0f8b9f43ea8a689518283f768468b550b754e2aa
--- /dev/null
+++ b/Utilities/FLTK/jpeg/makefile.wat
@@ -0,0 +1,67 @@
+#
+# "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $"
+#
+# JPEG library makefile for the Fast Light Toolkit (FLTK).
+#
+# Copyright 1997-2004 by Easy Software Products.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+LIBNAMEROOT=ftlk_jpeg
+
+!include ../watcom.mif
+
+
+#
+# Object files...
+#
+
+LIBOBJS = jmemnobs.obj &
+          jcapimin.obj jcapistd.obj jccoefct.obj jccolor.obj jcdctmgr.obj &
+          jchuff.obj jcinit.obj jcmainct.obj jcmarker.obj jcmaster.obj jcomapi.obj &
+          jcparam.obj jcphuff.obj jcprepct.obj jcsample.obj jctrans.obj &
+          jdapimin.obj jdapistd.obj jdatadst.obj jdatasrc.obj jdcoefct.obj &
+          jdcolor.obj jddctmgr.obj jdhuff.obj jdinput.obj jdmainct.obj jdmarker.obj &
+          jdmaster.obj jdmerge.obj jdphuff.obj jdpostct.obj jdsample.obj &
+          jdtrans.obj jerror.obj jfdctflt.obj jfdctfst.obj jfdctint.obj &
+          jidctflt.obj jidctfst.obj jidctint.obj jidctred.obj jquant1.obj &
+          jquant2.obj jutils.obj jmemmgr.obj
+
+#
+# Make all targets...
+#
+
+all: $(LIBNAME)
+
+$(LIBNAME): $(LIBOBJS)
+    $(LIB) $(LIBOPTS) $@ $<
+
+#
+# Clean all directories
+#
+clean : .SYMBOLIC
+    @echo Cleaning up.
+CLEANEXTS = obj
+    @for %a in ($(CLEANEXTS)) do -rm -f $(ODIR)\*.%a
+    -rm -f *.err
+    -rm -f $(LIBNAME)
+
+#
+# End of "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $".
+#
diff --git a/Utilities/FLTK/jpeg/structure.doc b/Utilities/FLTK/jpeg/structure.doc
new file mode 100644
index 0000000000000000000000000000000000000000..51c9def7e5d0cbbf81ea8e3fc8d6e9cb7e7ff173
--- /dev/null
+++ b/Utilities/FLTK/jpeg/structure.doc
@@ -0,0 +1,948 @@
+IJG JPEG LIBRARY:  SYSTEM ARCHITECTURE
+
+Copyright (C) 1991-1995, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+This file provides an overview of the architecture of the IJG JPEG software;
+that is, the functions of the various modules in the system and the interfaces
+between modules.  For more precise details about any data structure or calling
+convention, see the include files and comments in the source code.
+
+We assume that the reader is already somewhat familiar with the JPEG standard.
+The README file includes references for learning about JPEG.  The file
+libjpeg.doc describes the library from the viewpoint of an application
+programmer using the library; it's best to read that file before this one.
+Also, the file coderules.doc describes the coding style conventions we use.
+
+In this document, JPEG-specific terminology follows the JPEG standard:
+  A "component" means a color channel, e.g., Red or Luminance.
+  A "sample" is a single component value (i.e., one number in the image data).
+  A "coefficient" is a frequency coefficient (a DCT transform output number).
+  A "block" is an 8x8 group of samples or coefficients.
+  An "MCU" (minimum coded unit) is an interleaved set of blocks of size
+	determined by the sampling factors, or a single block in a
+	noninterleaved scan.
+We do not use the terms "pixel" and "sample" interchangeably.  When we say
+pixel, we mean an element of the full-size image, while a sample is an element
+of the downsampled image.  Thus the number of samples may vary across
+components while the number of pixels does not.  (This terminology is not used
+rigorously throughout the code, but it is used in places where confusion would
+otherwise result.)
+
+
+*** System features ***
+
+The IJG distribution contains two parts:
+  * A subroutine library for JPEG compression and decompression.
+  * cjpeg/djpeg, two sample applications that use the library to transform
+    JFIF JPEG files to and from several other image formats.
+cjpeg/djpeg are of no great intellectual complexity: they merely add a simple
+command-line user interface and I/O routines for several uncompressed image
+formats.  This document concentrates on the library itself.
+
+We desire the library to be capable of supporting all JPEG baseline, extended
+sequential, and progressive DCT processes.  Hierarchical processes are not
+supported.
+
+The library does not support the lossless (spatial) JPEG process.  Lossless
+JPEG shares little or no code with lossy JPEG, and would normally be used
+without the extensive pre- and post-processing provided by this library.
+We feel that lossless JPEG is better handled by a separate library.
+
+Within these limits, any set of compression parameters allowed by the JPEG
+spec should be readable for decompression.  (We can be more restrictive about
+what formats we can generate.)  Although the system design allows for all
+parameter values, some uncommon settings are not yet implemented and may
+never be; nonintegral sampling ratios are the prime example.  Furthermore,
+we treat 8-bit vs. 12-bit data precision as a compile-time switch, not a
+run-time option, because most machines can store 8-bit pixels much more
+compactly than 12-bit.
+
+For legal reasons, JPEG arithmetic coding is not currently supported, but
+extending the library to include it would be straightforward.
+
+By itself, the library handles only interchange JPEG datastreams --- in
+particular the widely used JFIF file format.  The library can be used by
+surrounding code to process interchange or abbreviated JPEG datastreams that
+are embedded in more complex file formats.  (For example, libtiff uses this
+library to implement JPEG compression within the TIFF file format.)
+
+The library includes a substantial amount of code that is not covered by the
+JPEG standard but is necessary for typical applications of JPEG.  These
+functions preprocess the image before JPEG compression or postprocess it after
+decompression.  They include colorspace conversion, downsampling/upsampling,
+and color quantization.  This code can be omitted if not needed.
+
+A wide range of quality vs. speed tradeoffs are possible in JPEG processing,
+and even more so in decompression postprocessing.  The decompression library
+provides multiple implementations that cover most of the useful tradeoffs,
+ranging from very-high-quality down to fast-preview operation.  On the
+compression side we have generally not provided low-quality choices, since
+compression is normally less time-critical.  It should be understood that the
+low-quality modes may not meet the JPEG standard's accuracy requirements;
+nonetheless, they are useful for viewers.
+
+
+*** Portability issues ***
+
+Portability is an essential requirement for the library.  The key portability
+issues that show up at the level of system architecture are:
+
+1.  Memory usage.  We want the code to be able to run on PC-class machines
+with limited memory.  Images should therefore be processed sequentially (in
+strips), to avoid holding the whole image in memory at once.  Where a
+full-image buffer is necessary, we should be able to use either virtual memory
+or temporary files.
+
+2.  Near/far pointer distinction.  To run efficiently on 80x86 machines, the
+code should distinguish "small" objects (kept in near data space) from
+"large" ones (kept in far data space).  This is an annoying restriction, but
+fortunately it does not impact code quality for less brain-damaged machines,
+and the source code clutter turns out to be minimal with sufficient use of
+pointer typedefs.
+
+3. Data precision.  We assume that "char" is at least 8 bits, "short" and
+"int" at least 16, "long" at least 32.  The code will work fine with larger
+data sizes, although memory may be used inefficiently in some cases.  However,
+the JPEG compressed datastream must ultimately appear on external storage as a
+sequence of 8-bit bytes if it is to conform to the standard.  This may pose a
+problem on machines where char is wider than 8 bits.  The library represents
+compressed data as an array of values of typedef JOCTET.  If no data type
+exactly 8 bits wide is available, custom data source and data destination
+modules must be written to unpack and pack the chosen JOCTET datatype into
+8-bit external representation.
+
+
+*** System overview ***
+
+The compressor and decompressor are each divided into two main sections:
+the JPEG compressor or decompressor proper, and the preprocessing or
+postprocessing functions.  The interface between these two sections is the
+image data that the official JPEG spec regards as its input or output: this
+data is in the colorspace to be used for compression, and it is downsampled
+to the sampling factors to be used.  The preprocessing and postprocessing
+steps are responsible for converting a normal image representation to or from
+this form.  (Those few applications that want to deal with YCbCr downsampled
+data can skip the preprocessing or postprocessing step.)
+
+Looking more closely, the compressor library contains the following main
+elements:
+
+  Preprocessing:
+    * Color space conversion (e.g., RGB to YCbCr).
+    * Edge expansion and downsampling.  Optionally, this step can do simple
+      smoothing --- this is often helpful for low-quality source data.
+  JPEG proper:
+    * MCU assembly, DCT, quantization.
+    * Entropy coding (sequential or progressive, Huffman or arithmetic).
+
+In addition to these modules we need overall control, marker generation,
+and support code (memory management & error handling).  There is also a
+module responsible for physically writing the output data --- typically
+this is just an interface to fwrite(), but some applications may need to
+do something else with the data.
+
+The decompressor library contains the following main elements:
+
+  JPEG proper:
+    * Entropy decoding (sequential or progressive, Huffman or arithmetic).
+    * Dequantization, inverse DCT, MCU disassembly.
+  Postprocessing:
+    * Upsampling.  Optionally, this step may be able to do more general
+      rescaling of the image.
+    * Color space conversion (e.g., YCbCr to RGB).  This step may also
+      provide gamma adjustment [ currently it does not ].
+    * Optional color quantization (e.g., reduction to 256 colors).
+    * Optional color precision reduction (e.g., 24-bit to 15-bit color).
+      [This feature is not currently implemented.]
+
+We also need overall control, marker parsing, and a data source module.
+The support code (memory management & error handling) can be shared with
+the compression half of the library.
+
+There may be several implementations of each of these elements, particularly
+in the decompressor, where a wide range of speed/quality tradeoffs is very
+useful.  It must be understood that some of the best speedups involve
+merging adjacent steps in the pipeline.  For example, upsampling, color space
+conversion, and color quantization might all be done at once when using a
+low-quality ordered-dither technique.  The system architecture is designed to
+allow such merging where appropriate.
+
+
+Note: it is convenient to regard edge expansion (padding to block boundaries)
+as a preprocessing/postprocessing function, even though the JPEG spec includes
+it in compression/decompression.  We do this because downsampling/upsampling
+can be simplified a little if they work on padded data: it's not necessary to
+have special cases at the right and bottom edges.  Therefore the interface
+buffer is always an integral number of blocks wide and high, and we expect
+compression preprocessing to pad the source data properly.  Padding will occur
+only to the next block (8-sample) boundary.  In an interleaved-scan situation,
+additional dummy blocks may be used to fill out MCUs, but the MCU assembly and
+disassembly logic will create or discard these blocks internally.  (This is
+advantageous for speed reasons, since we avoid DCTing the dummy blocks.
+It also permits a small reduction in file size, because the compressor can
+choose dummy block contents so as to minimize their size in compressed form.
+Finally, it makes the interface buffer specification independent of whether
+the file is actually interleaved or not.)  Applications that wish to deal
+directly with the downsampled data must provide similar buffering and padding
+for odd-sized images.
+
+
+*** Poor man's object-oriented programming ***
+
+It should be clear by now that we have a lot of quasi-independent processing
+steps, many of which have several possible behaviors.  To avoid cluttering the
+code with lots of switch statements, we use a simple form of object-style
+programming to separate out the different possibilities.
+
+For example, two different color quantization algorithms could be implemented
+as two separate modules that present the same external interface; at runtime,
+the calling code will access the proper module indirectly through an "object".
+
+We can get the limited features we need while staying within portable C.
+The basic tool is a function pointer.  An "object" is just a struct
+containing one or more function pointer fields, each of which corresponds to
+a method name in real object-oriented languages.  During initialization we
+fill in the function pointers with references to whichever module we have
+determined we need to use in this run.  Then invocation of the module is done
+by indirecting through a function pointer; on most machines this is no more
+expensive than a switch statement, which would be the only other way of
+making the required run-time choice.  The really significant benefit, of
+course, is keeping the source code clean and well structured.
+
+We can also arrange to have private storage that varies between different
+implementations of the same kind of object.  We do this by making all the
+module-specific object structs be separately allocated entities, which will
+be accessed via pointers in the master compression or decompression struct.
+The "public" fields or methods for a given kind of object are specified by
+a commonly known struct.  But a module's initialization code can allocate
+a larger struct that contains the common struct as its first member, plus
+additional private fields.  With appropriate pointer casting, the module's
+internal functions can access these private fields.  (For a simple example,
+see jdatadst.c, which implements the external interface specified by struct
+jpeg_destination_mgr, but adds extra fields.)
+
+(Of course this would all be a lot easier if we were using C++, but we are
+not yet prepared to assume that everyone has a C++ compiler.)
+
+An important benefit of this scheme is that it is easy to provide multiple
+versions of any method, each tuned to a particular case.  While a lot of
+precalculation might be done to select an optimal implementation of a method,
+the cost per invocation is constant.  For example, the upsampling step might
+have a "generic" method, plus one or more "hardwired" methods for the most
+popular sampling factors; the hardwired methods would be faster because they'd
+use straight-line code instead of for-loops.  The cost to determine which
+method to use is paid only once, at startup, and the selection criteria are
+hidden from the callers of the method.
+
+This plan differs a little bit from usual object-oriented structures, in that
+only one instance of each object class will exist during execution.  The
+reason for having the class structure is that on different runs we may create
+different instances (choose to execute different modules).  You can think of
+the term "method" as denoting the common interface presented by a particular
+set of interchangeable functions, and "object" as denoting a group of related
+methods, or the total shared interface behavior of a group of modules.
+
+
+*** Overall control structure ***
+
+We previously mentioned the need for overall control logic in the compression
+and decompression libraries.  In IJG implementations prior to v5, overall
+control was mostly provided by "pipeline control" modules, which proved to be
+large, unwieldy, and hard to understand.  To improve the situation, the
+control logic has been subdivided into multiple modules.  The control modules
+consist of:
+
+1. Master control for module selection and initialization.  This has two
+responsibilities:
+
+   1A.  Startup initialization at the beginning of image processing.
+        The individual processing modules to be used in this run are selected
+        and given initialization calls.
+
+   1B.  Per-pass control.  This determines how many passes will be performed
+        and calls each active processing module to configure itself
+        appropriately at the beginning of each pass.  End-of-pass processing,
+	where necessary, is also invoked from the master control module.
+
+   Method selection is partially distributed, in that a particular processing
+   module may contain several possible implementations of a particular method,
+   which it will select among when given its initialization call.  The master
+   control code need only be concerned with decisions that affect more than
+   one module.
+ 
+2. Data buffering control.  A separate control module exists for each
+   inter-processing-step data buffer.  This module is responsible for
+   invoking the processing steps that write or read that data buffer.
+
+Each buffer controller sees the world as follows:
+
+input data => processing step A => buffer => processing step B => output data
+                      |              |               |
+              ------------------ controller ------------------
+
+The controller knows the dataflow requirements of steps A and B: how much data
+they want to accept in one chunk and how much they output in one chunk.  Its
+function is to manage its buffer and call A and B at the proper times.
+
+A data buffer control module may itself be viewed as a processing step by a
+higher-level control module; thus the control modules form a binary tree with
+elementary processing steps at the leaves of the tree.
+
+The control modules are objects.  A considerable amount of flexibility can
+be had by replacing implementations of a control module.  For example:
+* Merging of adjacent steps in the pipeline is done by replacing a control
+  module and its pair of processing-step modules with a single processing-
+  step module.  (Hence the possible merges are determined by the tree of
+  control modules.)
+* In some processing modes, a given interstep buffer need only be a "strip"
+  buffer large enough to accommodate the desired data chunk sizes.  In other
+  modes, a full-image buffer is needed and several passes are required.
+  The control module determines which kind of buffer is used and manipulates
+  virtual array buffers as needed.  One or both processing steps may be
+  unaware of the multi-pass behavior.
+
+In theory, we might be able to make all of the data buffer controllers
+interchangeable and provide just one set of implementations for all.  In
+practice, each one contains considerable special-case processing for its
+particular job.  The buffer controller concept should be regarded as an
+overall system structuring principle, not as a complete description of the
+task performed by any one controller.
+
+
+*** Compression object structure ***
+
+Here is a sketch of the logical structure of the JPEG compression library:
+
+                                                 |-- Colorspace conversion
+                  |-- Preprocessing controller --|
+                  |                              |-- Downsampling
+Main controller --|
+                  |                            |-- Forward DCT, quantize
+                  |-- Coefficient controller --|
+                                               |-- Entropy encoding
+
+This sketch also describes the flow of control (subroutine calls) during
+typical image data processing.  Each of the components shown in the diagram is
+an "object" which may have several different implementations available.  One
+or more source code files contain the actual implementation(s) of each object.
+
+The objects shown above are:
+
+* Main controller: buffer controller for the subsampled-data buffer, which
+  holds the preprocessed input data.  This controller invokes preprocessing to
+  fill the subsampled-data buffer, and JPEG compression to empty it.  There is
+  usually no need for a full-image buffer here; a strip buffer is adequate.
+
+* Preprocessing controller: buffer controller for the downsampling input data
+  buffer, which lies between colorspace conversion and downsampling.  Note
+  that a unified conversion/downsampling module would probably replace this
+  controller entirely.
+
+* Colorspace conversion: converts application image data into the desired
+  JPEG color space; also changes the data from pixel-interleaved layout to
+  separate component planes.  Processes one pixel row at a time.
+
+* Downsampling: performs reduction of chroma components as required.
+  Optionally may perform pixel-level smoothing as well.  Processes a "row
+  group" at a time, where a row group is defined as Vmax pixel rows of each
+  component before downsampling, and Vk sample rows afterwards (remember Vk
+  differs across components).  Some downsampling or smoothing algorithms may
+  require context rows above and below the current row group; the
+  preprocessing controller is responsible for supplying these rows via proper
+  buffering.  The downsampler is responsible for edge expansion at the right
+  edge (i.e., extending each sample row to a multiple of 8 samples); but the
+  preprocessing controller is responsible for vertical edge expansion (i.e.,
+  duplicating the bottom sample row as needed to make a multiple of 8 rows).
+
+* Coefficient controller: buffer controller for the DCT-coefficient data.
+  This controller handles MCU assembly, including insertion of dummy DCT
+  blocks when needed at the right or bottom edge.  When performing
+  Huffman-code optimization or emitting a multiscan JPEG file, this
+  controller is responsible for buffering the full image.  The equivalent of
+  one fully interleaved MCU row of subsampled data is processed per call,
+  even when the JPEG file is noninterleaved.
+
+* Forward DCT and quantization: Perform DCT, quantize, and emit coefficients.
+  Works on one or more DCT blocks at a time.  (Note: the coefficients are now
+  emitted in normal array order, which the entropy encoder is expected to
+  convert to zigzag order as necessary.  Prior versions of the IJG code did
+  the conversion to zigzag order within the quantization step.)
+
+* Entropy encoding: Perform Huffman or arithmetic entropy coding and emit the
+  coded data to the data destination module.  Works on one MCU per call.
+  For progressive JPEG, the same DCT blocks are fed to the entropy coder
+  during each pass, and the coder must emit the appropriate subset of
+  coefficients.
+
+In addition to the above objects, the compression library includes these
+objects:
+
+* Master control: determines the number of passes required, controls overall
+  and per-pass initialization of the other modules.
+
+* Marker writing: generates JPEG markers (except for RSTn, which is emitted
+  by the entropy encoder when needed).
+
+* Data destination manager: writes the output JPEG datastream to its final
+  destination (e.g., a file).  The destination manager supplied with the
+  library knows how to write to a stdio stream; for other behaviors, the
+  surrounding application may provide its own destination manager.
+
+* Memory manager: allocates and releases memory, controls virtual arrays
+  (with backing store management, where required).
+
+* Error handler: performs formatting and output of error and trace messages;
+  determines handling of nonfatal errors.  The surrounding application may
+  override some or all of this object's methods to change error handling.
+
+* Progress monitor: supports output of "percent-done" progress reports.
+  This object represents an optional callback to the surrounding application:
+  if wanted, it must be supplied by the application.
+
+The error handler, destination manager, and progress monitor objects are
+defined as separate objects in order to simplify application-specific
+customization of the JPEG library.  A surrounding application may override
+individual methods or supply its own all-new implementation of one of these
+objects.  The object interfaces for these objects are therefore treated as
+part of the application interface of the library, whereas the other objects
+are internal to the library.
+
+The error handler and memory manager are shared by JPEG compression and
+decompression; the progress monitor, if used, may be shared as well.
+
+
+*** Decompression object structure ***
+
+Here is a sketch of the logical structure of the JPEG decompression library:
+
+                                               |-- Entropy decoding
+                  |-- Coefficient controller --|
+                  |                            |-- Dequantize, Inverse DCT
+Main controller --|
+                  |                               |-- Upsampling
+                  |-- Postprocessing controller --|   |-- Colorspace conversion
+                                                  |-- Color quantization
+                                                  |-- Color precision reduction
+
+As before, this diagram also represents typical control flow.  The objects
+shown are:
+
+* Main controller: buffer controller for the subsampled-data buffer, which
+  holds the output of JPEG decompression proper.  This controller's primary
+  task is to feed the postprocessing procedure.  Some upsampling algorithms
+  may require context rows above and below the current row group; when this
+  is true, the main controller is responsible for managing its buffer so as
+  to make context rows available.  In the current design, the main buffer is
+  always a strip buffer; a full-image buffer is never required.
+
+* Coefficient controller: buffer controller for the DCT-coefficient data.
+  This controller handles MCU disassembly, including deletion of any dummy
+  DCT blocks at the right or bottom edge.  When reading a multiscan JPEG
+  file, this controller is responsible for buffering the full image.
+  (Buffering DCT coefficients, rather than samples, is necessary to support
+  progressive JPEG.)  The equivalent of one fully interleaved MCU row of
+  subsampled data is processed per call, even when the source JPEG file is
+  noninterleaved.
+
+* Entropy decoding: Read coded data from the data source module and perform
+  Huffman or arithmetic entropy decoding.  Works on one MCU per call.
+  For progressive JPEG decoding, the coefficient controller supplies the prior
+  coefficients of each MCU (initially all zeroes), which the entropy decoder
+  modifies in each scan.
+
+* Dequantization and inverse DCT: like it says.  Note that the coefficients
+  buffered by the coefficient controller have NOT been dequantized; we
+  merge dequantization and inverse DCT into a single step for speed reasons.
+  When scaled-down output is asked for, simplified DCT algorithms may be used
+  that emit only 1x1, 2x2, or 4x4 samples per DCT block, not the full 8x8.
+  Works on one DCT block at a time.
+
+* Postprocessing controller: buffer controller for the color quantization
+  input buffer, when quantization is in use.  (Without quantization, this
+  controller just calls the upsampler.)  For two-pass quantization, this
+  controller is responsible for buffering the full-image data.
+
+* Upsampling: restores chroma components to full size.  (May support more
+  general output rescaling, too.  Note that if undersized DCT outputs have
+  been emitted by the DCT module, this module must adjust so that properly
+  sized outputs are created.)  Works on one row group at a time.  This module
+  also calls the color conversion module, so its top level is effectively a
+  buffer controller for the upsampling->color conversion buffer.  However, in
+  all but the highest-quality operating modes, upsampling and color
+  conversion are likely to be merged into a single step.
+
+* Colorspace conversion: convert from JPEG color space to output color space,
+  and change data layout from separate component planes to pixel-interleaved.
+  Works on one pixel row at a time.
+
+* Color quantization: reduce the data to colormapped form, using either an
+  externally specified colormap or an internally generated one.  This module
+  is not used for full-color output.  Works on one pixel row at a time; may
+  require two passes to generate a color map.  Note that the output will
+  always be a single component representing colormap indexes.  In the current
+  design, the output values are JSAMPLEs, so an 8-bit compilation cannot
+  quantize to more than 256 colors.  This is unlikely to be a problem in
+  practice.
+
+* Color reduction: this module handles color precision reduction, e.g.,
+  generating 15-bit color (5 bits/primary) from JPEG's 24-bit output.
+  Not quite clear yet how this should be handled... should we merge it with
+  colorspace conversion???
+
+Note that some high-speed operating modes might condense the entire
+postprocessing sequence to a single module (upsample, color convert, and
+quantize in one step).
+
+In addition to the above objects, the decompression library includes these
+objects:
+
+* Master control: determines the number of passes required, controls overall
+  and per-pass initialization of the other modules.  This is subdivided into
+  input and output control: jdinput.c controls only input-side processing,
+  while jdmaster.c handles overall initialization and output-side control.
+
+* Marker reading: decodes JPEG markers (except for RSTn).
+
+* Data source manager: supplies the input JPEG datastream.  The source
+  manager supplied with the library knows how to read from a stdio stream;
+  for other behaviors, the surrounding application may provide its own source
+  manager.
+
+* Memory manager: same as for compression library.
+
+* Error handler: same as for compression library.
+
+* Progress monitor: same as for compression library.
+
+As with compression, the data source manager, error handler, and progress
+monitor are candidates for replacement by a surrounding application.
+
+
+*** Decompression input and output separation ***
+
+To support efficient incremental display of progressive JPEG files, the
+decompressor is divided into two sections that can run independently:
+
+1. Data input includes marker parsing, entropy decoding, and input into the
+   coefficient controller's DCT coefficient buffer.  Note that this
+   processing is relatively cheap and fast.
+
+2. Data output reads from the DCT coefficient buffer and performs the IDCT
+   and all postprocessing steps.
+
+For a progressive JPEG file, the data input processing is allowed to get
+arbitrarily far ahead of the data output processing.  (This occurs only
+if the application calls jpeg_consume_input(); otherwise input and output
+run in lockstep, since the input section is called only when the output
+section needs more data.)  In this way the application can avoid making
+extra display passes when data is arriving faster than the display pass
+can run.  Furthermore, it is possible to abort an output pass without
+losing anything, since the coefficient buffer is read-only as far as the
+output section is concerned.  See libjpeg.doc for more detail.
+
+A full-image coefficient array is only created if the JPEG file has multiple
+scans (or if the application specifies buffered-image mode anyway).  When
+reading a single-scan file, the coefficient controller normally creates only
+a one-MCU buffer, so input and output processing must run in lockstep in this
+case.  jpeg_consume_input() is effectively a no-op in this situation.
+
+The main impact of dividing the decompressor in this fashion is that we must
+be very careful with shared variables in the cinfo data structure.  Each
+variable that can change during the course of decompression must be
+classified as belonging to data input or data output, and each section must
+look only at its own variables.  For example, the data output section may not
+depend on any of the variables that describe the current scan in the JPEG
+file, because these may change as the data input section advances into a new
+scan.
+
+The progress monitor is (somewhat arbitrarily) defined to treat input of the
+file as one pass when buffered-image mode is not used, and to ignore data
+input work completely when buffered-image mode is used.  Note that the
+library has no reliable way to predict the number of passes when dealing
+with a progressive JPEG file, nor can it predict the number of output passes
+in buffered-image mode.  So the work estimate is inherently bogus anyway.
+
+No comparable division is currently made in the compression library, because
+there isn't any real need for it.
+
+
+*** Data formats ***
+
+Arrays of pixel sample values use the following data structure:
+
+    typedef something JSAMPLE;		a pixel component value, 0..MAXJSAMPLE
+    typedef JSAMPLE *JSAMPROW;		ptr to a row of samples
+    typedef JSAMPROW *JSAMPARRAY;	ptr to a list of rows
+    typedef JSAMPARRAY *JSAMPIMAGE;	ptr to a list of color-component arrays
+
+The basic element type JSAMPLE will typically be one of unsigned char,
+(signed) char, or short.  Short will be used if samples wider than 8 bits are
+to be supported (this is a compile-time option).  Otherwise, unsigned char is
+used if possible.  If the compiler only supports signed chars, then it is
+necessary to mask off the value when reading.  Thus, all reads of JSAMPLE
+values must be coded as "GETJSAMPLE(value)", where the macro will be defined
+as "((value) & 0xFF)" on signed-char machines and "((int) (value))" elsewhere.
+
+With these conventions, JSAMPLE values can be assumed to be >= 0.  This helps
+simplify correct rounding during downsampling, etc.  The JPEG standard's
+specification that sample values run from -128..127 is accommodated by
+subtracting 128 just as the sample value is copied into the source array for
+the DCT step (this will be an array of signed ints).  Similarly, during
+decompression the output of the IDCT step will be immediately shifted back to
+0..255.  (NB: different values are required when 12-bit samples are in use.
+The code is written in terms of MAXJSAMPLE and CENTERJSAMPLE, which will be
+defined as 255 and 128 respectively in an 8-bit implementation, and as 4095
+and 2048 in a 12-bit implementation.)
+
+We use a pointer per row, rather than a two-dimensional JSAMPLE array.  This
+choice costs only a small amount of memory and has several benefits:
+* Code using the data structure doesn't need to know the allocated width of
+  the rows.  This simplifies edge expansion/compression, since we can work
+  in an array that's wider than the logical picture width.
+* Indexing doesn't require multiplication; this is a performance win on many
+  machines.
+* Arrays with more than 64K total elements can be supported even on machines
+  where malloc() cannot allocate chunks larger than 64K.
+* The rows forming a component array may be allocated at different times
+  without extra copying.  This trick allows some speedups in smoothing steps
+  that need access to the previous and next rows.
+
+Note that each color component is stored in a separate array; we don't use the
+traditional layout in which the components of a pixel are stored together.
+This simplifies coding of modules that work on each component independently,
+because they don't need to know how many components there are.  Furthermore,
+we can read or write each component to a temporary file independently, which
+is helpful when dealing with noninterleaved JPEG files.
+
+In general, a specific sample value is accessed by code such as
+	GETJSAMPLE(image[colorcomponent][row][col])
+where col is measured from the image left edge, but row is measured from the
+first sample row currently in memory.  Either of the first two indexings can
+be precomputed by copying the relevant pointer.
+
+
+Since most image-processing applications prefer to work on images in which
+the components of a pixel are stored together, the data passed to or from the
+surrounding application uses the traditional convention: a single pixel is
+represented by N consecutive JSAMPLE values, and an image row is an array of
+(# of color components)*(image width) JSAMPLEs.  One or more rows of data can
+be represented by a pointer of type JSAMPARRAY in this scheme.  This scheme is
+converted to component-wise storage inside the JPEG library.  (Applications
+that want to skip JPEG preprocessing or postprocessing will have to contend
+with component-wise storage.)
+
+
+Arrays of DCT-coefficient values use the following data structure:
+
+    typedef short JCOEF;		a 16-bit signed integer
+    typedef JCOEF JBLOCK[DCTSIZE2];	an 8x8 block of coefficients
+    typedef JBLOCK *JBLOCKROW;		ptr to one horizontal row of 8x8 blocks
+    typedef JBLOCKROW *JBLOCKARRAY;	ptr to a list of such rows
+    typedef JBLOCKARRAY *JBLOCKIMAGE;	ptr to a list of color component arrays
+
+The underlying type is at least a 16-bit signed integer; while "short" is big
+enough on all machines of interest, on some machines it is preferable to use
+"int" for speed reasons, despite the storage cost.  Coefficients are grouped
+into 8x8 blocks (but we always use #defines DCTSIZE and DCTSIZE2 rather than
+"8" and "64").
+
+The contents of a coefficient block may be in either "natural" or zigzagged
+order, and may be true values or divided by the quantization coefficients,
+depending on where the block is in the processing pipeline.  In the current
+library, coefficient blocks are kept in natural order everywhere; the entropy
+codecs zigzag or dezigzag the data as it is written or read.  The blocks
+contain quantized coefficients everywhere outside the DCT/IDCT subsystems.
+(This latter decision may need to be revisited to support variable
+quantization a la JPEG Part 3.)
+
+Notice that the allocation unit is now a row of 8x8 blocks, corresponding to
+eight rows of samples.  Otherwise the structure is much the same as for
+samples, and for the same reasons.
+
+On machines where malloc() can't handle a request bigger than 64Kb, this data
+structure limits us to rows of less than 512 JBLOCKs, or a picture width of
+4000+ pixels.  This seems an acceptable restriction.
+
+
+On 80x86 machines, the bottom-level pointer types (JSAMPROW and JBLOCKROW)
+must be declared as "far" pointers, but the upper levels can be "near"
+(implying that the pointer lists are allocated in the DS segment).
+We use a #define symbol FAR, which expands to the "far" keyword when
+compiling on 80x86 machines and to nothing elsewhere.
+
+
+*** Suspendable processing ***
+
+In some applications it is desirable to use the JPEG library as an
+incremental, memory-to-memory filter.  In this situation the data source or
+destination may be a limited-size buffer, and we can't rely on being able to
+empty or refill the buffer at arbitrary times.  Instead the application would
+like to have control return from the library at buffer overflow/underrun, and
+then resume compression or decompression at a later time.
+
+This scenario is supported for simple cases.  (For anything more complex, we
+recommend that the application "bite the bullet" and develop real multitasking
+capability.)  The libjpeg.doc file goes into more detail about the usage and
+limitations of this capability; here we address the implications for library
+structure.
+
+The essence of the problem is that the entropy codec (coder or decoder) must
+be prepared to stop at arbitrary times.  In turn, the controllers that call
+the entropy codec must be able to stop before having produced or consumed all
+the data that they normally would handle in one call.  That part is reasonably
+straightforward: we make the controller call interfaces include "progress
+counters" which indicate the number of data chunks successfully processed, and
+we require callers to test the counter rather than just assume all of the data
+was processed.
+
+Rather than trying to restart at an arbitrary point, the current Huffman
+codecs are designed to restart at the beginning of the current MCU after a
+suspension due to buffer overflow/underrun.  At the start of each call, the
+codec's internal state is loaded from permanent storage (in the JPEG object
+structures) into local variables.  On successful completion of the MCU, the
+permanent state is updated.  (This copying is not very expensive, and may even
+lead to *improved* performance if the local variables can be registerized.)
+If a suspension occurs, the codec simply returns without updating the state,
+thus effectively reverting to the start of the MCU.  Note that this implies
+leaving some data unprocessed in the source/destination buffer (ie, the
+compressed partial MCU).  The data source/destination module interfaces are
+specified so as to make this possible.  This also implies that the data buffer
+must be large enough to hold a worst-case compressed MCU; a couple thousand
+bytes should be enough.
+
+In a successive-approximation AC refinement scan, the progressive Huffman
+decoder has to be able to undo assignments of newly nonzero coefficients if it
+suspends before the MCU is complete, since decoding requires distinguishing
+previously-zero and previously-nonzero coefficients.  This is a bit tedious
+but probably won't have much effect on performance.  Other variants of Huffman
+decoding need not worry about this, since they will just store the same values
+again if forced to repeat the MCU.
+
+This approach would probably not work for an arithmetic codec, since its
+modifiable state is quite large and couldn't be copied cheaply.  Instead it
+would have to suspend and resume exactly at the point of the buffer end.
+
+The JPEG marker reader is designed to cope with suspension at an arbitrary
+point.  It does so by backing up to the start of the marker parameter segment,
+so the data buffer must be big enough to hold the largest marker of interest.
+Again, a couple KB should be adequate.  (A special "skip" convention is used
+to bypass COM and APPn markers, so these can be larger than the buffer size
+without causing problems; otherwise a 64K buffer would be needed in the worst
+case.)
+
+The JPEG marker writer currently does *not* cope with suspension.  I feel that
+this is not necessary; it is much easier simply to require the application to
+ensure there is enough buffer space before starting.  (An empty 2K buffer is
+more than sufficient for the header markers; and ensuring there are a dozen or
+two bytes available before calling jpeg_finish_compress() will suffice for the
+trailer.)  This would not work for writing multi-scan JPEG files, but
+we simply do not intend to support that capability with suspension.
+
+
+*** Memory manager services ***
+
+The JPEG library's memory manager controls allocation and deallocation of
+memory, and it manages large "virtual" data arrays on machines where the
+operating system does not provide virtual memory.  Note that the same
+memory manager serves both compression and decompression operations.
+
+In all cases, allocated objects are tied to a particular compression or
+decompression master record, and they will be released when that master
+record is destroyed.
+
+The memory manager does not provide explicit deallocation of objects.
+Instead, objects are created in "pools" of free storage, and a whole pool
+can be freed at once.  This approach helps prevent storage-leak bugs, and
+it speeds up operations whenever malloc/free are slow (as they often are).
+The pools can be regarded as lifetime identifiers for objects.  Two
+pools/lifetimes are defined:
+  * JPOOL_PERMANENT	lasts until master record is destroyed
+  * JPOOL_IMAGE		lasts until done with image (JPEG datastream)
+Permanent lifetime is used for parameters and tables that should be carried
+across from one datastream to another; this includes all application-visible
+parameters.  Image lifetime is used for everything else.  (A third lifetime,
+JPOOL_PASS = one processing pass, was originally planned.  However it was
+dropped as not being worthwhile.  The actual usage patterns are such that the
+peak memory usage would be about the same anyway; and having per-pass storage
+substantially complicates the virtual memory allocation rules --- see below.)
+
+The memory manager deals with three kinds of object:
+1. "Small" objects.  Typically these require no more than 10K-20K total.
+2. "Large" objects.  These may require tens to hundreds of K depending on
+   image size.  Semantically they behave the same as small objects, but we
+   distinguish them for two reasons:
+     * On MS-DOS machines, large objects are referenced by FAR pointers,
+       small objects by NEAR pointers.
+     * Pool allocation heuristics may differ for large and small objects.
+   Note that individual "large" objects cannot exceed the size allowed by
+   type size_t, which may be 64K or less on some machines.
+3. "Virtual" objects.  These are large 2-D arrays of JSAMPLEs or JBLOCKs
+   (typically large enough for the entire image being processed).  The
+   memory manager provides stripwise access to these arrays.  On machines
+   without virtual memory, the rest of the array may be swapped out to a
+   temporary file.
+
+(Note: JSAMPARRAY and JBLOCKARRAY data structures are a combination of large
+objects for the data proper and small objects for the row pointers.  For
+convenience and speed, the memory manager provides single routines to create
+these structures.  Similarly, virtual arrays include a small control block
+and a JSAMPARRAY or JBLOCKARRAY working buffer, all created with one call.)
+
+In the present implementation, virtual arrays are only permitted to have image
+lifespan.  (Permanent lifespan would not be reasonable, and pass lifespan is
+not very useful since a virtual array's raison d'etre is to store data for
+multiple passes through the image.)  We also expect that only "small" objects
+will be given permanent lifespan, though this restriction is not required by
+the memory manager.
+
+In a non-virtual-memory machine, some performance benefit can be gained by
+making the in-memory buffers for virtual arrays be as large as possible.
+(For small images, the buffers might fit entirely in memory, so blind
+swapping would be very wasteful.)  The memory manager will adjust the height
+of the buffers to fit within a prespecified maximum memory usage.  In order
+to do this in a reasonably optimal fashion, the manager needs to allocate all
+of the virtual arrays at once.  Therefore, there isn't a one-step allocation
+routine for virtual arrays; instead, there is a "request" routine that simply
+allocates the control block, and a "realize" routine (called just once) that
+determines space allocation and creates all of the actual buffers.  The
+realize routine must allow for space occupied by non-virtual large objects.
+(We don't bother to factor in the space needed for small objects, on the
+grounds that it isn't worth the trouble.)
+
+To support all this, we establish the following protocol for doing business
+with the memory manager:
+  1. Modules must request virtual arrays (which may have only image lifespan)
+     during the initial setup phase, i.e., in their jinit_xxx routines.
+  2. All "large" objects (including JSAMPARRAYs and JBLOCKARRAYs) must also be
+     allocated during initial setup.
+  3. realize_virt_arrays will be called at the completion of initial setup.
+     The above conventions ensure that sufficient information is available
+     for it to choose a good size for virtual array buffers.
+Small objects of any lifespan may be allocated at any time.  We expect that
+the total space used for small objects will be small enough to be negligible
+in the realize_virt_arrays computation.
+
+In a virtual-memory machine, we simply pretend that the available space is
+infinite, thus causing realize_virt_arrays to decide that it can allocate all
+the virtual arrays as full-size in-memory buffers.  The overhead of the
+virtual-array access protocol is very small when no swapping occurs.
+
+A virtual array can be specified to be "pre-zeroed"; when this flag is set,
+never-yet-written sections of the array are set to zero before being made
+available to the caller.  If this flag is not set, never-written sections
+of the array contain garbage.  (This feature exists primarily because the
+equivalent logic would otherwise be needed in jdcoefct.c for progressive
+JPEG mode; we may as well make it available for possible other uses.)
+
+The first write pass on a virtual array is required to occur in top-to-bottom
+order; read passes, as well as any write passes after the first one, may
+access the array in any order.  This restriction exists partly to simplify
+the virtual array control logic, and partly because some file systems may not
+support seeking beyond the current end-of-file in a temporary file.  The main
+implication of this restriction is that rearrangement of rows (such as
+converting top-to-bottom data order to bottom-to-top) must be handled while
+reading data out of the virtual array, not while putting it in.
+
+
+*** Memory manager internal structure ***
+
+To isolate system dependencies as much as possible, we have broken the
+memory manager into two parts.  There is a reasonably system-independent
+"front end" (jmemmgr.c) and a "back end" that contains only the code
+likely to change across systems.  All of the memory management methods
+outlined above are implemented by the front end.  The back end provides
+the following routines for use by the front end (none of these routines
+are known to the rest of the JPEG code):
+
+jpeg_mem_init, jpeg_mem_term	system-dependent initialization/shutdown
+
+jpeg_get_small, jpeg_free_small	interface to malloc and free library routines
+				(or their equivalents)
+
+jpeg_get_large, jpeg_free_large	interface to FAR malloc/free in MSDOS machines;
+				else usually the same as
+				jpeg_get_small/jpeg_free_small
+
+jpeg_mem_available		estimate available memory
+
+jpeg_open_backing_store		create a backing-store object
+
+read_backing_store,		manipulate a backing-store object
+write_backing_store,
+close_backing_store
+
+On some systems there will be more than one type of backing-store object
+(specifically, in MS-DOS a backing store file might be an area of extended
+memory as well as a disk file).  jpeg_open_backing_store is responsible for
+choosing how to implement a given object.  The read/write/close routines
+are method pointers in the structure that describes a given object; this
+lets them be different for different object types.
+
+It may be necessary to ensure that backing store objects are explicitly
+released upon abnormal program termination.  For example, MS-DOS won't free
+extended memory by itself.  To support this, we will expect the main program
+or surrounding application to arrange to call self_destruct (typically via
+jpeg_destroy) upon abnormal termination.  This may require a SIGINT signal
+handler or equivalent.  We don't want to have the back end module install its
+own signal handler, because that would pre-empt the surrounding application's
+ability to control signal handling.
+
+The IJG distribution includes several memory manager back end implementations.
+Usually the same back end should be suitable for all applications on a given
+system, but it is possible for an application to supply its own back end at
+need.
+
+
+*** Implications of DNL marker ***
+
+Some JPEG files may use a DNL marker to postpone definition of the image
+height (this would be useful for a fax-like scanner's output, for instance).
+In these files the SOF marker claims the image height is 0, and you only
+find out the true image height at the end of the first scan.
+
+We could read these files as follows:
+1. Upon seeing zero image height, replace it by 65535 (the maximum allowed).
+2. When the DNL is found, update the image height in the global image
+   descriptor.
+This implies that control modules must avoid making copies of the image
+height, and must re-test for termination after each MCU row.  This would
+be easy enough to do.
+
+In cases where image-size data structures are allocated, this approach will
+result in very inefficient use of virtual memory or much-larger-than-necessary
+temporary files.  This seems acceptable for something that probably won't be a
+mainstream usage.  People might have to forgo use of memory-hogging options
+(such as two-pass color quantization or noninterleaved JPEG files) if they
+want efficient conversion of such files.  (One could improve efficiency by
+demanding a user-supplied upper bound for the height, less than 65536; in most
+cases it could be much less.)
+
+The standard also permits the SOF marker to overestimate the image height,
+with a DNL to give the true, smaller height at the end of the first scan.
+This would solve the space problems if the overestimate wasn't too great.
+However, it implies that you don't even know whether DNL will be used.
+
+This leads to a couple of very serious objections:
+1. Testing for a DNL marker must occur in the inner loop of the decompressor's
+   Huffman decoder; this implies a speed penalty whether the feature is used
+   or not.
+2. There is no way to hide the last-minute change in image height from an
+   application using the decoder.  Thus *every* application using the IJG
+   library would suffer a complexity penalty whether it cared about DNL or
+   not.
+We currently do not support DNL because of these problems.
+
+A different approach is to insist that DNL-using files be preprocessed by a
+separate program that reads ahead to the DNL, then goes back and fixes the SOF
+marker.  This is a much simpler solution and is probably far more efficient.
+Even if one wants piped input, buffering the first scan of the JPEG file needs
+a lot smaller temp file than is implied by the maximum-height method.  For
+this approach we'd simply treat DNL as a no-op in the decompressor (at most,
+check that it matches the SOF image height).
+
+We will not worry about making the compressor capable of outputting DNL.
+Something similar to the first scheme above could be applied if anyone ever
+wants to make that work.
diff --git a/Utilities/FLTK/jpeg/usage.doc b/Utilities/FLTK/jpeg/usage.doc
new file mode 100644
index 0000000000000000000000000000000000000000..8c4970af0518f212e386805c125009faba7089e3
--- /dev/null
+++ b/Utilities/FLTK/jpeg/usage.doc
@@ -0,0 +1,562 @@
+USAGE instructions for the Independent JPEG Group's JPEG software
+=================================================================
+
+This file describes usage of the JPEG conversion programs cjpeg and djpeg,
+as well as the utility programs jpegtran, rdjpgcom and wrjpgcom.  (See
+the other documentation files if you wish to use the JPEG library within
+your own programs.)
+
+If you are on a Unix machine you may prefer to read the Unix-style manual
+pages in files cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1.
+
+
+INTRODUCTION
+
+These programs implement JPEG image compression and decompression.  JPEG
+(pronounced "jay-peg") is a standardized compression method for full-color
+and gray-scale images.  JPEG is designed to handle "real-world" scenes,
+for example scanned photographs.  Cartoons, line drawings, and other
+non-realistic images are not JPEG's strong suit; on that sort of material
+you may get poor image quality and/or little compression.
+
+JPEG is lossy, meaning that the output image is not necessarily identical to
+the input image.  Hence you should not use JPEG if you have to have identical
+output bits.  However, on typical real-world images, very good compression
+levels can be obtained with no visible change, and amazingly high compression
+is possible if you can tolerate a low-quality image.  You can trade off image
+quality against file size by adjusting the compressor's "quality" setting.
+
+
+GENERAL USAGE
+
+We provide two programs, cjpeg to compress an image file into JPEG format,
+and djpeg to decompress a JPEG file back into a conventional image format.
+
+On Unix-like systems, you say:
+	cjpeg [switches] [imagefile] >jpegfile
+or
+	djpeg [switches] [jpegfile]  >imagefile
+The programs read the specified input file, or standard input if none is
+named.  They always write to standard output (with trace/error messages to
+standard error).  These conventions are handy for piping images between
+programs.
+
+On most non-Unix systems, you say:
+	cjpeg [switches] imagefile jpegfile
+or
+	djpeg [switches] jpegfile  imagefile
+i.e., both the input and output files are named on the command line.  This
+style is a little more foolproof, and it loses no functionality if you don't
+have pipes.  (You can get this style on Unix too, if you prefer, by defining
+TWO_FILE_COMMANDLINE when you compile the programs; see install.doc.)
+
+You can also say:
+	cjpeg [switches] -outfile jpegfile  imagefile
+or
+	djpeg [switches] -outfile imagefile  jpegfile
+This syntax works on all systems, so it is useful for scripts.
+
+The currently supported image file formats are: PPM (PBMPLUS color format),
+PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster Toolkit
+format).  (RLE is supported only if the URT library is available.)
+cjpeg recognizes the input image format automatically, with the exception
+of some Targa-format files.  You have to tell djpeg which format to generate.
+
+JPEG files are in the defacto standard JFIF file format.  There are other,
+less widely used JPEG-based file formats, but we don't support them.
+
+All switch names may be abbreviated; for example, -grayscale may be written
+-gray or -gr.  Most of the "basic" switches can be abbreviated to as little as
+one letter.  Upper and lower case are equivalent (-BMP is the same as -bmp).
+British spellings are also accepted (e.g., -greyscale), though for brevity
+these are not mentioned below.
+
+
+CJPEG DETAILS
+
+The basic command line switches for cjpeg are:
+
+	-quality N	Scale quantization tables to adjust image quality.
+			Quality is 0 (worst) to 100 (best); default is 75.
+			(See below for more info.)
+
+	-grayscale	Create monochrome JPEG file from color input.
+			Be sure to use this switch when compressing a grayscale
+			BMP file, because cjpeg isn't bright enough to notice
+			whether a BMP file uses only shades of gray.  By
+			saying -grayscale, you'll get a smaller JPEG file that
+			takes less time to process.
+
+	-optimize	Perform optimization of entropy encoding parameters.
+			Without this, default encoding parameters are used.
+			-optimize usually makes the JPEG file a little smaller,
+			but cjpeg runs somewhat slower and needs much more
+			memory.  Image quality and speed of decompression are
+			unaffected by -optimize.
+
+	-progressive	Create progressive JPEG file (see below).
+
+	-targa		Input file is Targa format.  Targa files that contain
+			an "identification" field will not be automatically
+			recognized by cjpeg; for such files you must specify
+			-targa to make cjpeg treat the input as Targa format.
+			For most Targa files, you won't need this switch.
+
+The -quality switch lets you trade off compressed file size against quality of
+the reconstructed image: the higher the quality setting, the larger the JPEG
+file, and the closer the output image will be to the original input.  Normally
+you want to use the lowest quality setting (smallest file) that decompresses
+into something visually indistinguishable from the original image.  For this
+purpose the quality setting should be between 50 and 95; the default of 75 is
+often about right.  If you see defects at -quality 75, then go up 5 or 10
+counts at a time until you are happy with the output image.  (The optimal
+setting will vary from one image to another.)
+
+-quality 100 will generate a quantization table of all 1's, minimizing loss
+in the quantization step (but there is still information loss in subsampling,
+as well as roundoff error).  This setting is mainly of interest for
+experimental purposes.  Quality values above about 95 are NOT recommended for
+normal use; the compressed file size goes up dramatically for hardly any gain
+in output image quality.
+
+In the other direction, quality values below 50 will produce very small files
+of low image quality.  Settings around 5 to 10 might be useful in preparing an
+index of a large image library, for example.  Try -quality 2 (or so) for some
+amusing Cubist effects.  (Note: quality values below about 25 generate 2-byte
+quantization tables, which are considered optional in the JPEG standard.
+cjpeg emits a warning message when you give such a quality value, because some
+other JPEG programs may be unable to decode the resulting file.  Use -baseline
+if you need to ensure compatibility at low quality values.)
+
+The -progressive switch creates a "progressive JPEG" file.  In this type of
+JPEG file, the data is stored in multiple scans of increasing quality.  If the
+file is being transmitted over a slow communications link, the decoder can use
+the first scan to display a low-quality image very quickly, and can then
+improve the display with each subsequent scan.  The final image is exactly
+equivalent to a standard JPEG file of the same quality setting, and the total
+file size is about the same --- often a little smaller.  CAUTION: progressive
+JPEG is not yet widely implemented, so many decoders will be unable to view a
+progressive JPEG file at all.
+
+Switches for advanced users:
+
+	-dct int	Use integer DCT method (default).
+	-dct fast	Use fast integer DCT (less accurate).
+	-dct float	Use floating-point DCT method.
+			The float method is very slightly more accurate than
+			the int method, but is much slower unless your machine
+			has very fast floating-point hardware.  Also note that
+			results of the floating-point method may vary slightly
+			across machines, while the integer methods should give
+			the same results everywhere.  The fast integer method
+			is much less accurate than the other two.
+
+	-restart N	Emit a JPEG restart marker every N MCU rows, or every
+			N MCU blocks if "B" is attached to the number.
+			-restart 0 (the default) means no restart markers.
+
+	-smooth N	Smooth the input image to eliminate dithering noise.
+			N, ranging from 1 to 100, indicates the strength of
+			smoothing.  0 (the default) means no smoothing.
+
+	-maxmemory N	Set limit for amount of memory to use in processing
+			large images.  Value is in thousands of bytes, or
+			millions of bytes if "M" is attached to the number.
+			For example, -max 4m selects 4000000 bytes.  If more
+			space is needed, temporary files will be used.
+
+	-verbose	Enable debug printout.  More -v's give more printout.
+	or  -debug	Also, version information is printed at startup.
+
+The -restart option inserts extra markers that allow a JPEG decoder to
+resynchronize after a transmission error.  Without restart markers, any damage
+to a compressed file will usually ruin the image from the point of the error
+to the end of the image; with restart markers, the damage is usually confined
+to the portion of the image up to the next restart marker.  Of course, the
+restart markers occupy extra space.  We recommend -restart 1 for images that
+will be transmitted across unreliable networks such as Usenet.
+
+The -smooth option filters the input to eliminate fine-scale noise.  This is
+often useful when converting dithered images to JPEG: a moderate smoothing
+factor of 10 to 50 gets rid of dithering patterns in the input file, resulting
+in a smaller JPEG file and a better-looking image.  Too large a smoothing
+factor will visibly blur the image, however.
+
+Switches for wizards:
+
+	-baseline	Force baseline-compatible quantization tables to be
+			generated.  This clamps quantization values to 8 bits
+			even at low quality settings.  (This switch is poorly
+			named, since it does not ensure that the output is
+			actually baseline JPEG.  For example, you can use
+			-baseline and -progressive together.)
+
+	-qtables file	Use the quantization tables given in the specified
+			text file.
+
+	-qslots N[,...] Select which quantization table to use for each color
+			component.
+
+	-sample HxV[,...]  Set JPEG sampling factors for each color component.
+
+	-scans file	Use the scan script given in the specified text file.
+
+The "wizard" switches are intended for experimentation with JPEG.  If you
+don't know what you are doing, DON'T USE THEM.  These switches are documented
+further in the file wizard.doc.
+
+
+DJPEG DETAILS
+
+The basic command line switches for djpeg are:
+
+	-colors N	Reduce image to at most N colors.  This reduces the
+	or -quantize N	number of colors used in the output image, so that it
+			can be displayed on a colormapped display or stored in
+			a colormapped file format.  For example, if you have
+			an 8-bit display, you'd need to reduce to 256 or fewer
+			colors.  (-colors is the recommended name, -quantize
+			is provided only for backwards compatibility.)
+
+	-fast		Select recommended processing options for fast, low
+			quality output.  (The default options are chosen for
+			highest quality output.)  Currently, this is equivalent
+			to "-dct fast -nosmooth -onepass -dither ordered".
+
+	-grayscale	Force gray-scale output even if JPEG file is color.
+			Useful for viewing on monochrome displays; also,
+			djpeg runs noticeably faster in this mode.
+
+	-scale M/N	Scale the output image by a factor M/N.  Currently
+			the scale factor must be 1/1, 1/2, 1/4, or 1/8.
+			Scaling is handy if the image is larger than your
+			screen; also, djpeg runs much faster when scaling
+			down the output.
+
+	-bmp		Select BMP output format (Windows flavor).  8-bit
+			colormapped format is emitted if -colors or -grayscale
+			is specified, or if the JPEG file is gray-scale;
+			otherwise, 24-bit full-color format is emitted.
+
+	-gif		Select GIF output format.  Since GIF does not support
+			more than 256 colors, -colors 256 is assumed (unless
+			you specify a smaller number of colors).  If you
+			specify -fast, the default number of colors is 216.
+
+	-os2		Select BMP output format (OS/2 1.x flavor).  8-bit
+			colormapped format is emitted if -colors or -grayscale
+			is specified, or if the JPEG file is gray-scale;
+			otherwise, 24-bit full-color format is emitted.
+
+	-pnm		Select PBMPLUS (PPM/PGM) output format (this is the
+			default format).  PGM is emitted if the JPEG file is
+			gray-scale or if -grayscale is specified; otherwise
+			PPM is emitted.
+
+	-rle		Select RLE output format.  (Requires URT library.)
+
+	-targa		Select Targa output format.  Gray-scale format is
+			emitted if the JPEG file is gray-scale or if
+			-grayscale is specified; otherwise, colormapped format
+			is emitted if -colors is specified; otherwise, 24-bit
+			full-color format is emitted.
+
+Switches for advanced users:
+
+	-dct int	Use integer DCT method (default).
+	-dct fast	Use fast integer DCT (less accurate).
+	-dct float	Use floating-point DCT method.
+			The float method is very slightly more accurate than
+			the int method, but is much slower unless your machine
+			has very fast floating-point hardware.  Also note that
+			results of the floating-point method may vary slightly
+			across machines, while the integer methods should give
+			the same results everywhere.  The fast integer method
+			is much less accurate than the other two.
+
+	-dither fs	Use Floyd-Steinberg dithering in color quantization.
+	-dither ordered	Use ordered dithering in color quantization.
+	-dither none	Do not use dithering in color quantization.
+			By default, Floyd-Steinberg dithering is applied when
+			quantizing colors; this is slow but usually produces
+			the best results.  Ordered dither is a compromise
+			between speed and quality; no dithering is fast but
+			usually looks awful.  Note that these switches have
+			no effect unless color quantization is being done.
+			Ordered dither is only available in -onepass mode.
+
+	-map FILE	Quantize to the colors used in the specified image
+			file.  This is useful for producing multiple files
+			with identical color maps, or for forcing a predefined
+			set of colors to be used.  The FILE must be a GIF
+			or PPM file.  This option overrides -colors and
+			-onepass.
+
+	-nosmooth	Use a faster, lower-quality upsampling routine.
+
+	-onepass	Use one-pass instead of two-pass color quantization.
+			The one-pass method is faster and needs less memory,
+			but it produces a lower-quality image.  -onepass is
+			ignored unless you also say -colors N.  Also,
+			the one-pass method is always used for gray-scale
+			output (the two-pass method is no improvement then).
+
+	-maxmemory N	Set limit for amount of memory to use in processing
+			large images.  Value is in thousands of bytes, or
+			millions of bytes if "M" is attached to the number.
+			For example, -max 4m selects 4000000 bytes.  If more
+			space is needed, temporary files will be used.
+
+	-verbose	Enable debug printout.  More -v's give more printout.
+	or  -debug	Also, version information is printed at startup.
+
+
+HINTS FOR CJPEG
+
+Color GIF files are not the ideal input for JPEG; JPEG is really intended for
+compressing full-color (24-bit) images.  In particular, don't try to convert
+cartoons, line drawings, and other images that have only a few distinct
+colors.  GIF works great on these, JPEG does not.  If you want to convert a
+GIF to JPEG, you should experiment with cjpeg's -quality and -smooth options
+to get a satisfactory conversion.  -smooth 10 or so is often helpful.
+
+Avoid running an image through a series of JPEG compression/decompression
+cycles.  Image quality loss will accumulate; after ten or so cycles the image
+may be noticeably worse than it was after one cycle.  It's best to use a
+lossless format while manipulating an image, then convert to JPEG format when
+you are ready to file the image away.
+
+The -optimize option to cjpeg is worth using when you are making a "final"
+version for posting or archiving.  It's also a win when you are using low
+quality settings to make very small JPEG files; the percentage improvement
+is often a lot more than it is on larger files.  (At present, -optimize
+mode is always selected when generating progressive JPEG files.)
+
+GIF input files are no longer supported, to avoid the Unisys LZW patent.
+Use a Unisys-licensed program if you need to read a GIF file.  (Conversion
+of GIF files to JPEG is usually a bad idea anyway.)
+
+
+HINTS FOR DJPEG
+
+To get a quick preview of an image, use the -grayscale and/or -scale switches.
+"-grayscale -scale 1/8" is the fastest case.
+
+Several options are available that trade off image quality to gain speed.
+"-fast" turns on the recommended settings.
+
+"-dct fast" and/or "-nosmooth" gain speed at a small sacrifice in quality.
+When producing a color-quantized image, "-onepass -dither ordered" is fast but
+much lower quality than the default behavior.  "-dither none" may give
+acceptable results in two-pass mode, but is seldom tolerable in one-pass mode.
+
+If you are fortunate enough to have very fast floating point hardware,
+"-dct float" may be even faster than "-dct fast".  But on most machines
+"-dct float" is slower than "-dct int"; in this case it is not worth using,
+because its theoretical accuracy advantage is too small to be significant
+in practice.
+
+Two-pass color quantization requires a good deal of memory; on MS-DOS machines
+it may run out of memory even with -maxmemory 0.  In that case you can still
+decompress, with some loss of image quality, by specifying -onepass for
+one-pass quantization.
+
+To avoid the Unisys LZW patent, djpeg produces uncompressed GIF files.  These
+are larger than they should be, but are readable by standard GIF decoders.
+
+
+HINTS FOR BOTH PROGRAMS
+
+If more space is needed than will fit in the available main memory (as
+determined by -maxmemory), temporary files will be used.  (MS-DOS versions
+will try to get extended or expanded memory first.)  The temporary files are
+often rather large: in typical cases they occupy three bytes per pixel, for
+example 3*800*600 = 1.44Mb for an 800x600 image.  If you don't have enough
+free disk space, leave out -progressive and -optimize (for cjpeg) or specify
+-onepass (for djpeg).
+
+On MS-DOS, the temporary files are created in the directory named by the TMP
+or TEMP environment variable, or in the current directory if neither of those
+exist.  Amiga implementations put the temp files in the directory named by
+JPEGTMP:, so be sure to assign JPEGTMP: to a disk partition with adequate free
+space.
+
+The default memory usage limit (-maxmemory) is set when the software is
+compiled.  If you get an "insufficient memory" error, try specifying a smaller
+-maxmemory value, even -maxmemory 0 to use the absolute minimum space.  You
+may want to recompile with a smaller default value if this happens often.
+
+On machines that have "environment" variables, you can define the environment
+variable JPEGMEM to set the default memory limit.  The value is specified as
+described for the -maxmemory switch.  JPEGMEM overrides the default value
+specified when the program was compiled, and itself is overridden by an
+explicit -maxmemory switch.
+
+On MS-DOS machines, -maxmemory is the amount of main (conventional) memory to
+use.  (Extended or expanded memory is also used if available.)  Most
+DOS-specific versions of this software do their own memory space estimation
+and do not need you to specify -maxmemory.
+
+
+JPEGTRAN
+
+jpegtran performs various useful transformations of JPEG files.
+It can translate the coded representation from one variant of JPEG to another,
+for example from baseline JPEG to progressive JPEG or vice versa.  It can also
+perform some rearrangements of the image data, for example turning an image
+from landscape to portrait format by rotation.
+
+jpegtran works by rearranging the compressed data (DCT coefficients), without
+ever fully decoding the image.  Therefore, its transformations are lossless:
+there is no image degradation at all, which would not be true if you used
+djpeg followed by cjpeg to accomplish the same conversion.  But by the same
+token, jpegtran cannot perform lossy operations such as changing the image
+quality.
+
+jpegtran uses a command line syntax similar to cjpeg or djpeg.
+On Unix-like systems, you say:
+	jpegtran [switches] [inputfile] >outputfile
+On most non-Unix systems, you say:
+	jpegtran [switches] inputfile outputfile
+where both the input and output files are JPEG files.
+
+To specify the coded JPEG representation used in the output file,
+jpegtran accepts a subset of the switches recognized by cjpeg:
+	-optimize	Perform optimization of entropy encoding parameters.
+	-progressive	Create progressive JPEG file.
+	-restart N	Emit a JPEG restart marker every N MCU rows, or every
+			N MCU blocks if "B" is attached to the number.
+	-scans file	Use the scan script given in the specified text file.
+See the previous discussion of cjpeg for more details about these switches.
+If you specify none of these switches, you get a plain baseline-JPEG output
+file.  The quality setting and so forth are determined by the input file.
+
+The image can be losslessly transformed by giving one of these switches:
+	-flip horizontal	Mirror image horizontally (left-right).
+	-flip vertical		Mirror image vertically (top-bottom).
+	-rotate 90		Rotate image 90 degrees clockwise.
+	-rotate 180		Rotate image 180 degrees.
+	-rotate 270		Rotate image 270 degrees clockwise (or 90 ccw).
+	-transpose		Transpose image (across UL-to-LR axis).
+	-transverse		Transverse transpose (across UR-to-LL axis).
+
+The transpose transformation has no restrictions regarding image dimensions.
+The other transformations operate rather oddly if the image dimensions are not
+a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
+transform complete blocks of DCT coefficient data in the desired way.
+
+jpegtran's default behavior when transforming an odd-size image is designed
+to preserve exact reversibility and mathematical consistency of the
+transformation set.  As stated, transpose is able to flip the entire image
+area.  Horizontal mirroring leaves any partial iMCU column at the right edge
+untouched, but is able to flip all rows of the image.  Similarly, vertical
+mirroring leaves any partial iMCU row at the bottom edge untouched, but is
+able to flip all columns.  The other transforms can be built up as sequences
+of transpose and flip operations; for consistency, their actions on edge
+pixels are defined to be the same as the end result of the corresponding
+transpose-and-flip sequence.
+
+For practical use, you may prefer to discard any untransformable edge pixels
+rather than having a strange-looking strip along the right and/or bottom edges
+of a transformed image.  To do this, add the -trim switch:
+	-trim		Drop non-transformable edge blocks.
+Obviously, a transformation with -trim is not reversible, so strictly speaking
+jpegtran with this switch is not lossless.  Also, the expected mathematical
+equivalences between the transformations no longer hold.  For example,
+"-rot 270 -trim" trims only the bottom edge, but "-rot 90 -trim" followed by
+"-rot 180 -trim" trims both edges.
+
+Another not-strictly-lossless transformation switch is:
+	-grayscale	Force grayscale output.
+This option discards the chrominance channels if the input image is YCbCr
+(ie, a standard color JPEG), resulting in a grayscale JPEG file.  The
+luminance channel is preserved exactly, so this is a better method of reducing
+to grayscale than decompression, conversion, and recompression.  This switch
+is particularly handy for fixing a monochrome picture that was mistakenly
+encoded as a color JPEG.  (In such a case, the space savings from getting rid
+of the near-empty chroma channels won't be large; but the decoding time for
+a grayscale JPEG is substantially less than that for a color JPEG.)
+
+jpegtran also recognizes these switches that control what to do with "extra"
+markers, such as comment blocks:
+	-copy none	Copy no extra markers from source file.  This setting
+			suppresses all comments and other excess baggage
+			present in the source file.
+	-copy comments	Copy only comment markers.  This setting copies
+			comments from the source file, but discards
+			any other inessential data. 
+	-copy all	Copy all extra markers.  This setting preserves
+			miscellaneous markers found in the source file, such
+			as JFIF thumbnails and Photoshop settings.  In some
+			files these extra markers can be sizable.
+The default behavior is -copy comments.  (Note: in IJG releases v6 and v6a,
+jpegtran always did the equivalent of -copy none.)
+
+Additional switches recognized by jpegtran are:
+	-outfile filename
+	-maxmemory N
+	-verbose
+	-debug
+These work the same as in cjpeg or djpeg.
+
+
+THE COMMENT UTILITIES
+
+The JPEG standard allows "comment" (COM) blocks to occur within a JPEG file.
+Although the standard doesn't actually define what COM blocks are for, they
+are widely used to hold user-supplied text strings.  This lets you add
+annotations, titles, index terms, etc to your JPEG files, and later retrieve
+them as text.  COM blocks do not interfere with the image stored in the JPEG
+file.  The maximum size of a COM block is 64K, but you can have as many of
+them as you like in one JPEG file.
+
+We provide two utility programs to display COM block contents and add COM
+blocks to a JPEG file.
+
+rdjpgcom searches a JPEG file and prints the contents of any COM blocks on
+standard output.  The command line syntax is
+	rdjpgcom [-verbose] [inputfilename]
+The switch "-verbose" (or just "-v") causes rdjpgcom to also display the JPEG
+image dimensions.  If you omit the input file name from the command line,
+the JPEG file is read from standard input.  (This may not work on some
+operating systems, if binary data can't be read from stdin.)
+
+wrjpgcom adds a COM block, containing text you provide, to a JPEG file.
+Ordinarily, the COM block is added after any existing COM blocks, but you
+can delete the old COM blocks if you wish.  wrjpgcom produces a new JPEG
+file; it does not modify the input file.  DO NOT try to overwrite the input
+file by directing wrjpgcom's output back into it; on most systems this will
+just destroy your file.
+
+The command line syntax for wrjpgcom is similar to cjpeg's.  On Unix-like
+systems, it is
+	wrjpgcom [switches] [inputfilename]
+The output file is written to standard output.  The input file comes from
+the named file, or from standard input if no input file is named.
+
+On most non-Unix systems, the syntax is
+	wrjpgcom [switches] inputfilename outputfilename
+where both input and output file names must be given explicitly.
+
+wrjpgcom understands three switches:
+	-replace		 Delete any existing COM blocks from the file.
+	-comment "Comment text"	 Supply new COM text on command line.
+	-cfile name		 Read text for new COM block from named file.
+(Switch names can be abbreviated.)  If you have only one line of comment text
+to add, you can provide it on the command line with -comment.  The comment
+text must be surrounded with quotes so that it is treated as a single
+argument.  Longer comments can be read from a text file.
+
+If you give neither -comment nor -cfile, then wrjpgcom will read the comment
+text from standard input.  (In this case an input image file name MUST be
+supplied, so that the source JPEG file comes from somewhere else.)  You can
+enter multiple lines, up to 64KB worth.  Type an end-of-file indicator
+(usually control-D or control-Z) to terminate the comment text entry.
+
+wrjpgcom will not add a COM block if the provided comment string is empty.
+Therefore -replace -comment "" can be used to delete all COM blocks from a
+file.
+
+These utility programs do not depend on the IJG JPEG library.  In
+particular, the source code for rdjpgcom is intended as an illustration of
+the minimum amount of code required to parse a JPEG file header correctly.
diff --git a/Utilities/FLTK/jpeg/wizard.doc b/Utilities/FLTK/jpeg/wizard.doc
new file mode 100644
index 0000000000000000000000000000000000000000..54170b227df0b22d3c011ec16b72826464200a5f
--- /dev/null
+++ b/Utilities/FLTK/jpeg/wizard.doc
@@ -0,0 +1,211 @@
+Advanced usage instructions for the Independent JPEG Group's JPEG software
+==========================================================================
+
+This file describes cjpeg's "switches for wizards".
+
+The "wizard" switches are intended for experimentation with JPEG by persons
+who are reasonably knowledgeable about the JPEG standard.  If you don't know
+what you are doing, DON'T USE THESE SWITCHES.  You'll likely produce files
+with worse image quality and/or poorer compression than you'd get from the
+default settings.  Furthermore, these switches must be used with caution
+when making files intended for general use, because not all JPEG decoders
+will support unusual JPEG parameter settings.
+
+
+Quantization Table Adjustment
+-----------------------------
+
+Ordinarily, cjpeg starts with a default set of tables (the same ones given
+as examples in the JPEG standard) and scales them up or down according to
+the -quality setting.  The details of the scaling algorithm can be found in
+jcparam.c.  At very low quality settings, some quantization table entries
+can get scaled up to values exceeding 255.  Although 2-byte quantization
+values are supported by the IJG software, this feature is not in baseline
+JPEG and is not supported by all implementations.  If you need to ensure
+wide compatibility of low-quality files, you can constrain the scaled
+quantization values to no more than 255 by giving the -baseline switch.
+Note that use of -baseline will result in poorer quality for the same file
+size, since more bits than necessary are expended on higher AC coefficients.
+
+You can substitute a different set of quantization values by using the
+-qtables switch:
+
+	-qtables file	Use the quantization tables given in the named file.
+
+The specified file should be a text file containing decimal quantization
+values.  The file should contain one to four tables, each of 64 elements.
+The tables are implicitly numbered 0,1,etc. in order of appearance.  Table
+entries appear in normal array order (NOT in the zigzag order in which they
+will be stored in the JPEG file).
+
+Quantization table files are free format, in that arbitrary whitespace can
+appear between numbers.  Also, comments can be included: a comment starts
+with '#' and extends to the end of the line.  Here is an example file that
+duplicates the default quantization tables:
+
+	# Quantization tables given in JPEG spec, section K.1
+
+	# This is table 0 (the luminance table):
+	  16  11  10  16  24  40  51  61
+	  12  12  14  19  26  58  60  55
+	  14  13  16  24  40  57  69  56
+	  14  17  22  29  51  87  80  62
+	  18  22  37  56  68 109 103  77
+	  24  35  55  64  81 104 113  92
+	  49  64  78  87 103 121 120 101
+	  72  92  95  98 112 100 103  99
+
+	# This is table 1 (the chrominance table):
+	  17  18  24  47  99  99  99  99
+	  18  21  26  66  99  99  99  99
+	  24  26  56  99  99  99  99  99
+	  47  66  99  99  99  99  99  99
+	  99  99  99  99  99  99  99  99
+	  99  99  99  99  99  99  99  99
+	  99  99  99  99  99  99  99  99
+	  99  99  99  99  99  99  99  99
+
+If the -qtables switch is used without -quality, then the specified tables
+are used exactly as-is.  If both -qtables and -quality are used, then the
+tables taken from the file are scaled in the same fashion that the default
+tables would be scaled for that quality setting.  If -baseline appears, then
+the quantization values are constrained to the range 1-255.
+
+By default, cjpeg will use quantization table 0 for luminance components and
+table 1 for chrominance components.  To override this choice, use the -qslots
+switch:
+
+	-qslots N[,...]		Select which quantization table to use for
+				each color component.
+
+The -qslots switch specifies a quantization table number for each color
+component, in the order in which the components appear in the JPEG SOF marker.
+For example, to create a separate table for each of Y,Cb,Cr, you could
+provide a -qtables file that defines three quantization tables and say
+"-qslots 0,1,2".  If -qslots gives fewer table numbers than there are color
+components, then the last table number is repeated as necessary.
+
+
+Sampling Factor Adjustment
+--------------------------
+
+By default, cjpeg uses 2:1 horizontal and vertical downsampling when
+compressing YCbCr data, and no downsampling for all other color spaces.
+You can override this default with the -sample switch:
+
+	-sample HxV[,...]	Set JPEG sampling factors for each color
+				component.
+
+The -sample switch specifies the JPEG sampling factors for each color
+component, in the order in which they appear in the JPEG SOF marker.
+If you specify fewer HxV pairs than there are components, the remaining
+components are set to 1x1 sampling.  For example, the default YCbCr setting
+is equivalent to "-sample 2x2,1x1,1x1", which can be abbreviated to
+"-sample 2x2".
+
+There are still some JPEG decoders in existence that support only 2x1
+sampling (also called 4:2:2 sampling).  Compatibility with such decoders can
+be achieved by specifying "-sample 2x1".  This is not recommended unless
+really necessary, since it increases file size and encoding/decoding time
+with very little quality gain.
+
+
+Multiple Scan / Progression Control
+-----------------------------------
+
+By default, cjpeg emits a single-scan sequential JPEG file.  The
+-progressive switch generates a progressive JPEG file using a default series
+of progression parameters.  You can create multiple-scan sequential JPEG
+files or progressive JPEG files with custom progression parameters by using
+the -scans switch:
+
+	-scans file	Use the scan sequence given in the named file.
+
+The specified file should be a text file containing a "scan script".
+The script specifies the contents and ordering of the scans to be emitted.
+Each entry in the script defines one scan.  A scan definition specifies
+the components to be included in the scan, and for progressive JPEG it also
+specifies the progression parameters Ss,Se,Ah,Al for the scan.  Scan
+definitions are separated by semicolons (';').  A semicolon after the last
+scan definition is optional.
+
+Each scan definition contains one to four component indexes, optionally
+followed by a colon (':') and the four progressive-JPEG parameters.  The
+component indexes denote which color component(s) are to be transmitted in
+the scan.  Components are numbered in the order in which they appear in the
+JPEG SOF marker, with the first component being numbered 0.  (Note that these
+indexes are not the "component ID" codes assigned to the components, just
+positional indexes.)
+
+The progression parameters for each scan are:
+	Ss	Zigzag index of first coefficient included in scan
+	Se	Zigzag index of last coefficient included in scan
+	Ah	Zero for first scan of a coefficient, else Al of prior scan
+	Al	Successive approximation low bit position for scan
+If the progression parameters are omitted, the values 0,63,0,0 are used,
+producing a sequential JPEG file.  cjpeg automatically determines whether
+the script represents a progressive or sequential file, by observing whether
+Ss and Se values other than 0 and 63 appear.  (The -progressive switch is
+not needed to specify this; in fact, it is ignored when -scans appears.)
+The scan script must meet the JPEG restrictions on progression sequences.
+(cjpeg checks that the spec's requirements are obeyed.)
+
+Scan script files are free format, in that arbitrary whitespace can appear
+between numbers and around punctuation.  Also, comments can be included: a
+comment starts with '#' and extends to the end of the line.  For additional
+legibility, commas or dashes can be placed between values.  (Actually, any
+single punctuation character other than ':' or ';' can be inserted.)  For
+example, the following two scan definitions are equivalent:
+	0 1 2: 0 63 0 0;
+	0,1,2 : 0-63, 0,0 ;
+
+Here is an example of a scan script that generates a partially interleaved
+sequential JPEG file:
+
+	0;			# Y only in first scan
+	1 2;			# Cb and Cr in second scan
+
+Here is an example of a progressive scan script using only spectral selection
+(no successive approximation):
+
+	# Interleaved DC scan for Y,Cb,Cr:
+	0,1,2: 0-0,   0, 0 ;
+	# AC scans:
+	0:     1-2,   0, 0 ;	# First two Y AC coefficients
+	0:     3-5,   0, 0 ;	# Three more
+	1:     1-63,  0, 0 ;	# All AC coefficients for Cb
+	2:     1-63,  0, 0 ;	# All AC coefficients for Cr
+	0:     6-9,   0, 0 ;	# More Y coefficients
+	0:     10-63, 0, 0 ;	# Remaining Y coefficients
+
+Here is an example of a successive-approximation script.  This is equivalent
+to the default script used by "cjpeg -progressive" for YCbCr images:
+
+	# Initial DC scan for Y,Cb,Cr (lowest bit not sent)
+	0,1,2: 0-0,   0, 1 ;
+	# First AC scan: send first 5 Y AC coefficients, minus 2 lowest bits:
+	0:     1-5,   0, 2 ;
+	# Send all Cr,Cb AC coefficients, minus lowest bit:
+	# (chroma data is usually too small to be worth subdividing further;
+	#  but note we send Cr first since eye is least sensitive to Cb)
+	2:     1-63,  0, 1 ;
+	1:     1-63,  0, 1 ;
+	# Send remaining Y AC coefficients, minus 2 lowest bits:
+	0:     6-63,  0, 2 ;
+	# Send next-to-lowest bit of all Y AC coefficients:
+	0:     1-63,  2, 1 ;
+	# At this point we've sent all but the lowest bit of all coefficients.
+	# Send lowest bit of DC coefficients
+	0,1,2: 0-0,   1, 0 ;
+	# Send lowest bit of AC coefficients
+	2:     1-63,  1, 0 ;
+	1:     1-63,  1, 0 ;
+	# Y AC lowest bit scan is last; it's usually the largest scan
+	0:     1-63,  1, 0 ;
+
+It may be worth pointing out that this script is tuned for quality settings
+of around 50 to 75.  For lower quality settings, you'd probably want to use
+a script with fewer stages of successive approximation (otherwise the
+initial scans will be really bad).  For higher quality settings, you might
+want to use more stages of successive approximation (so that the initial
+scans are not too large).
diff --git a/Utilities/FLTK/lib/README.lib b/Utilities/FLTK/lib/README.lib
new file mode 100644
index 0000000000000000000000000000000000000000..61779843f0a9af3e045956910987196eeac82b20
--- /dev/null
+++ b/Utilities/FLTK/lib/README.lib
@@ -0,0 +1,16 @@
+README.lib
+----------
+
+This README file is a placeholder for library files on your
+system.
+
+Under Microsoft Windows a successful build of all projects and
+configurations will contain debug and release libraries for you
+to link to - all are built using the multi-threaded DLL
+settings.  The DLL files (fltkdll.dll and fltkdlld.dll) required
+for a complete DLL-based binary distribution are located in the
+"visualc" directory.
+
+Under UNIX a single set of library files will be built, with or
+without debug information depending on the options you provided
+to the configure script.
diff --git a/Utilities/FLTK/png/ANNOUNCE b/Utilities/FLTK/png/ANNOUNCE
new file mode 100644
index 0000000000000000000000000000000000000000..6370130a757839196ad6d5da6ddc2f75b08c6650
--- /dev/null
+++ b/Utilities/FLTK/png/ANNOUNCE
@@ -0,0 +1,28 @@
+
+Libpng 1.2.7 - September 12, 2004
+
+This is a public release of libpng, intended for use in production codes.
+
+Changes since the last public release (1.2.6):
+
+  Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1.
+  Removed unused pngasmrd.h file.
+  Removed references to uu.net for archived files.  Added references to
+    PNG Spec (second edition) and the PNG ISO/IEC Standard.
+  Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR.
+  Fixed bug with "optimized window size" in the IDAT datastream, that
+    causes libpng to write PNG files with incorrect zlib header bytes.
+  Fixed bug with sCAL chunk and big-endian machines (David Munro).
+  Undid new code added in 1.2.6 to update the color_type in
+    png_set_filler().
+  Added png_set_add_alpha() that updates color type.
+  Revised png_set_strip_filler() to not remove alpha if color_type has alpha.
+  Added makefile.hp64
+  Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin
+
+Send comments/corrections/commendations to
+png-implement@ccrc.wustl.edu (subscription required; write to
+majordomo@ccrc.wustl.edu with "subscribe png-implement" in the message)
+or to glennrp@users.sourceforge.net
+
+Glenn R-P
diff --git a/Utilities/FLTK/png/CHANGES b/Utilities/FLTK/png/CHANGES
new file mode 100644
index 0000000000000000000000000000000000000000..b34597fc5e86749cb7ef51d451d084cc59656cc6
--- /dev/null
+++ b/Utilities/FLTK/png/CHANGES
@@ -0,0 +1,1373 @@
+
+CHANGES - changes for libpng
+
+version 0.2
+  added reader into png.h
+  fixed small problems in stub file
+
+version 0.3
+  added pull reader
+  split up pngwrite.c to several files
+  added pnglib.txt
+  added example.c
+  cleaned up writer, adding a few new tranformations
+  fixed some bugs in writer
+  interfaced with zlib 0.5
+  added K&R support
+  added check for 64 KB blocks for 16 bit machines
+
+version 0.4
+  cleaned up code and commented code
+  simplified time handling into png_time
+  created png_color_16 and png_color_8 to handle color needs
+  cleaned up color type defines
+  fixed various bugs
+  made various names more consistant
+  interfaced with zlib 0.71
+  cleaned up zTXt reader and writer (using zlib's Reset functions)
+  split transformations into pngrtran.c and pngwtran.c
+
+version 0.5
+  interfaced with zlib 0.8
+  fixed many reading and writing bugs
+  saved using 3 spaces instead of tabs
+
+version 0.6
+  added png_large_malloc() and png_large_free()
+  added png_size_t
+  cleaned up some compiler warnings
+  added png_start_read_image()
+
+version 0.7
+  cleaned up lots of bugs
+  finished dithering and other stuff
+  added test program
+  changed name from pnglib to libpng
+
+version 0.71 [June, 1995]
+  changed pngtest.png for zlib 0.93
+  fixed error in libpng.txt and example.c
+
+version 0.8
+  cleaned up some bugs
+  added png_set_filler()
+  split up pngstub.c into pngmem.c, pngio.c, and pngerror.c
+  added #define's to remove unwanted code
+  moved png_info_init() to png.c
+  added old_size into png_realloc()
+  added functions to manually set filtering and compression info
+  changed compression parameters based on image type
+  optimized filter selection code
+  added version info
+  changed external functions passing floats to doubles (k&r problems?)
+  put all the configurable stuff in pngconf.h
+  enabled png_set_shift to work with paletted images on read
+  added png_read_update_info() - updates info structure with
+     transformations
+
+version 0.81 [August, 1995]
+  incorporated Tim Wegner's medium model code (thanks, Tim)
+
+version 0.82 [September, 1995]
+  [unspecified changes]
+
+version 0.85 [December, 1995]
+  added more medium model code (almost everything's a far)
+  added i/o, error, and memory callback functions
+  fixed some bugs (16 bit, 4 bit interlaced, etc.)
+  added first run progressive reader (barely tested)
+
+version 0.86 [January, 1996]
+  fixed bugs
+  improved documentation
+
+version 0.87 [January, 1996]
+  fixed medium model bugs
+  fixed other bugs introduced in 0.85 and 0.86
+  added some minor documentation
+
+version 0.88 [January, 1996]
+  fixed progressive bugs
+  replaced tabs with spaces
+  cleaned up documentation
+  added callbacks for read/write and warning/error functions
+
+version 0.89 [July, 1996]
+  added new initialization API to make libpng work better with shared libs
+     we now have png_create_read_struct(), png_create_write_struct(),
+     png_create_info_struct(), png_destroy_read_struct(), and
+     png_destroy_write_struct() instead of the separate calls to
+     malloc and png_read_init(), png_info_init(), and png_write_init()
+  changed warning/error callback functions to fix bug - this means you
+     should use the new initialization API if you were using the old
+     png_set_message_fn() calls, and that the old API no longer exists
+     so that people are aware that they need to change their code
+  changed filter selection API to allow selection of multiple filters
+     since it didn't work in previous versions of libpng anyways
+  optimized filter selection code
+  fixed png_set_background() to allow using an arbitrary RGB color for
+     paletted images
+  fixed gamma and background correction for paletted images, so
+     png_correct_palette is not needed unless you are correcting an
+     external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED
+     in pngconf.h) - if nobody uses this, it may disappear in the future.
+  fixed bug with Borland 64K memory allocation (Alexander Lehmann)
+  fixed bug in interlace handling (Smarasderagd, I think)
+  added more error checking for writing and image to reduce invalid files
+  separated read and write functions so that they won't both be linked
+     into a binary when only reading or writing functionality is used
+  new pngtest image also has interlacing and zTXt
+  updated documentation to reflect new API
+
+version 0.90 [January, 1997]
+  made CRC errors/warnings on critical and ancillary chunks configurable
+  libpng will use the zlib CRC routines by (compile-time) default
+  changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
+  added external C++ wrapper statements to png.h (Gilles Dauphin)
+  allow PNG file to be read when some or all of file signature has already
+     been read from the beginning of the stream.  ****This affects the size
+     of info_struct and invalidates all programs that use a shared libpng****
+  fixed png_filler() declarations
+  fixed? background color conversions
+  fixed order of error function pointers to match documentation
+  current chunk name is now available in png_struct to reduce the number
+     of nearly identical error messages (will simplify multi-lingual
+     support when available)
+  try to get ready for unknown-chunk callback functions:
+     - previously read critical chunks are flagged, so the chunk handling
+       routines can determine if the chunk is in the right place
+     - all chunk handling routines have the same prototypes, so we will
+       be able to handle all chunks via a callback mechanism
+  try to fix Linux "setjmp" buffer size problems
+  removed png_large_malloc, png_large_free, and png_realloc functions.
+
+version 0.95 [March, 1997]
+  fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
+  fixed bug in PNG file signature compares when start != 0
+  changed parameter type of png_set_filler(...filler...) from png_byte
+     to png_uint_32
+  added test for MACOS to ensure that both math.h and fp.h are not #included
+  added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
+  added "packswap" transformation, which changes the endianness of
+     packed-pixel bytes (Kevin Bracey)
+  added "strip_alpha" transformation, which removes the alpha channel of
+     input images without using it (not neccesarily a good idea)
+  added "swap_alpha" transformation, which puts the alpha channel in front
+     of the color bytes instead of after
+  removed all implicit variable tests which assume NULL == 0 (I think)
+  changed several variables to "png_size_t" to show 16/32-bit limitations
+  added new pCAL chunk read/write support
+  added experimental filter selection weighting (Greg Roelofs)
+  removed old png_set_rgbx() and png_set_xrgb() functions that have been
+     obsolete for about 2 years now (use png_set_filler() instead)
+  added macros to read 16- and 32-bit ints directly from buffer, to be
+     used only on those systems that support it (namely PowerPC and 680x0)
+     With some testing, this may become the default for MACOS/PPC systems.
+  only calculate CRC on data if we are going to use it
+  added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
+  added macros for simple libpng debugging output selectable at compile time
+  removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
+  more description of info_struct in libpng.txt and png.h
+  more instructions in example.c
+  more chunk types tested in pngtest.c
+  renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be
+     png_set_<chunk>.  We now have corresponding png_get_<chunk>
+     functions in pngget.c to get infomation in info_ptr.  This isolates
+     the application from the internal organization of png_info_struct
+     (good for shared library implementations).
+
+version 0.96 [May, 1997]
+  fixed serious bug with < 8bpp images introduced in 0.95
+  fixed 256-color transparency bug (Greg Roelofs)
+  fixed up documentation (Greg Roelofs, Laszlo Nyul)
+  fixed "error" in pngconf.h for Linux setjmp() behaviour
+  fixed DOS medium model support (Tim Wegner)
+  fixed png_check_keyword() for case with error in static string text
+  added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)
+  added typecasts to quiet compiler errors
+  added more debugging info
+
+version 0.97 [January, 1998]
+  removed PNG_USE_OWN_CRC capability
+  relocated png_set_crc_action from pngrutil.c to pngrtran.c
+  fixed typecasts of "new_key", etc. (Andreas Dilger)
+  added RFC 1152 [sic] date support
+  fixed bug in gamma handling of 4-bit grayscale
+  added 2-bit grayscale gamma handling (Glenn R-P)
+  added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P)
+  minor corrections in libpng.txt
+  added simple sRGB support (Glenn R-P)
+  easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;
+     all configurable options can be selected from command-line instead
+     of having to edit pngconf.h (Glenn R-P)
+  fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)
+  added more conditions for png_do_background, to avoid changing
+     black pixels to background when a background is supplied and
+     no pixels are transparent
+  repaired PNG_NO_STDIO behaviour
+  tested NODIV support and made it default behaviour (Greg Roelofs)
+  added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler)
+  regularized version numbering scheme and bumped shared-library major
+     version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs)
+
+version 0.98 [January, 1998]
+  cleaned up some typos in libpng.txt and in code documentation
+  fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)
+  cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c
+  changed recommendation about file_gamma for PC images to .51 from .45,
+     in example.c and libpng.txt, added comments to distinguish between
+     screen_gamma, viewing_gamma, and display_gamma.
+  changed all references to RFC1152 to read RFC1123 and changed the
+     PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED
+  added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent)
+  changed srgb_intent from png_byte to int to avoid compiler bugs
+
+version 0.99 [January 30, 1998]
+  free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler)
+  fixed a longstanding "packswap" bug in pngtrans.c
+  fixed some inconsistencies in pngconf.h that prevented compiling with
+     PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined
+  fixed some typos and made other minor rearrangement of libpng.txt (Andreas)
+  changed recommendation about file_gamma for PC images to .50 from .51 in
+     example.c and libpng.txt, and changed file_gamma for sRGB images to .45
+  added a number of functions to access information from the png structure
+     png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit)
+  added TARGET_MACOS similar to zlib-1.0.8
+  define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined
+  added type casting to all png_malloc() function calls
+version 0.99a [January 31, 1998]
+  Added type casts and parentheses to all returns that return a value.(Tim W.)
+version 0.99b [February 4, 1998]
+  Added type cast png_uint_32 on malloc function calls where needed.
+  Changed type of num_hist from png_uint_32 to int (same as num_palette).
+  Added checks for rowbytes overflow, in case png_size_t is less than 32 bits.
+  Renamed makefile.elf to makefile.lnx.
+version 0.99c [February 7, 1998]
+  More type casting.  Removed erroneous overflow test in pngmem.c.
+  Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes.
+  Added UNIX manual pages libpng.3 (incorporating libpng.txt) and  png.5.
+version 0.99d [February 11, 1998]
+  Renamed "far_to_near()" "png_far_to_near()"
+  Revised libpng.3
+  Version 99c "buffered" operations didn't work as intended.  Replaced them
+    with png_memcpy_check() and png_memset_check().
+  Added many "if (png_ptr == NULL) return" to quell compiler warnings about
+    unused png_ptr, mostly in pngget.c and pngset.c.
+  Check for overlength tRNS chunk present when indexed-color PLTE is read.
+  Cleaned up spelling errors in libpng.3/libpng.txt
+  Corrected a problem with png_get_tRNS() which returned undefined trans array
+version 0.99e [February 28, 1998]
+  Corrected png_get_tRNS() again.
+  Add parentheses for easier reading of pngget.c, fixed "||" should be "&&".
+  Touched up example.c to make more of it compileable, although the entire
+    file still can't be compiled (Willem van Schaik)
+  Fixed a bug in png_do_shift() (Bryan Tsai)
+  Added a space in png.h prototype for png_write_chunk_start()
+  Replaced pngtest.png with one created with zlib 1.1.1
+  Changed pngtest to report PASS even when file size is different (Jean-loup G.)
+  Corrected some logic errors in png_do_invert_alpha() (Chris Patterson)
+version 0.99f [March 5, 1998]
+  Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey)
+  Moved makefiles into a "scripts" directory, and added INSTALL instruction file
+  Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok)
+  Added pointers to "note on libpng versions" in makefile.lnx and README
+  Added row callback feature when reading and writing nonprogressive rows
+     and added a test of this feature in pngtest.c
+  Added user transform callbacks, with test of the feature in pngtest.c
+version 0.99g [March 6, 1998, morning]
+  Minor changes to pngtest.c to suppress compiler warnings.
+  Removed "beta" language from documentation.
+version 0.99h [March 6, 1998, evening]
+  Minor changes to previous minor changes to pngtest.c
+  Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED
+  and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro
+  Added user transform capability
+
+version 1.00 [March 7, 1998]
+  Changed several typedefs in pngrutil.c
+  Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)
+  replaced "while(1)" with "for(;;)"
+  added PNGARG() to prototypes in pngtest.c and removed some prototypes
+  updated some of the makefiles (Tom Lane)
+  changed some typedefs (s_start, etc.) in pngrutil.c
+  fixed dimensions of "short_months" array in pngwrite.c
+  Replaced ansi2knr.c with the one from jpeg-v6
+
+version 1.0.0 [March 8, 1998]
+  Changed name from 1.00 to 1.0.0 (Adam Costello)
+  Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert)
+version 1.0.0a [March 9, 1998]
+  Fixed three bugs in pngrtran.c to make gamma+background handling consistent
+  (Greg Roelofs)
+  Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz
+  for major, minor, and bugfix releases.  This is 10001. (Adam Costello,
+  Tom Lane)
+  Make months range from 1-12 in png_convert_to_rfc1123
+version 1.0.0b [March 13, 1998]
+  Quieted compiler complaints about two empty "for" loops in pngrutil.c
+  Minor changes to makefile.s2x
+  Removed #ifdef/#endif around a png_free() in pngread.c
+
+version 1.0.1 [March 14, 1998]
+  Changed makefile.s2x to reduce security risk of using a relative pathname
+  Fixed some typos in the documentation (Greg).
+  Fixed a problem with value of "channels" returned by png_read_update_info()
+version 1.0.1a [April 21, 1998]
+  Optimized Paeth calculations by replacing abs() function calls with intrinsics
+  plus other loop optimizations. Improves avg decoding speed by about 20%.
+  Commented out i386istic "align" compiler flags in makefile.lnx.
+  Reduced the default warning level in some makefiles, to make them consistent.
+  Removed references to IJG and JPEG in the ansi2knr.c copyright statement.
+  Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation.
+  Added grayscale and 16-bit capability to png_do_read_filler().
+  Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes
+    too large when writing an image with bit_depth < 8 (Bob Dellaca).
+  Corrected some bugs in the experimental weighted filtering heuristics.
+  Moved a misplaced pngrutil code block that truncates tRNS if it has more
+    than num_palette entries -- test was done before num_palette was defined.
+  Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins).
+  Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen).
+version 1.0.1b [May 2, 1998]
+  Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg).
+  Relocated the png_composite macros from pngrtran.c to png.h (Greg).
+  Added makefile.sco (contributed by Mike Hopkirk).
+  Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a.
+  Fixed a bug in pngrtran.c that would set channels=5 under some circumstances.
+  More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert).
+  More work on loop optimization which may help when compiled with C++ compilers.
+  Added warnings when people try to use transforms they've defined out.
+  Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran.
+  Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg)
+version 1.0.1c [May 11, 1998]
+  Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for
+    filler bytes should have been 0xff instead of 0xf.
+  Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images.
+  Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED
+    out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h
+  Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED,
+    for consistency, in pngconf.h
+  Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier
+    to remove unwanted capabilities via the compile line
+  Made some corrections to grammar (which, it's) in documentation (Greg).
+  Corrected example.c, use of row_pointers in png_write_image().
+version 1.0.1d [May 24, 1998]
+  Corrected several statements that used side effects illegally in pngrutil.c
+    and pngtrans.c, that were introduced in version 1.0.1b
+  Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert)
+  More corrections to example.c, use of row_pointers in png_write_image()
+    and png_read_rows().
+  Added pngdll.mak and pngdef.pas to scripts directory, contributed by
+    Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5
+  Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.)
+  Changed several loops from count-down to count-up, for consistency.
+version 1.0.1e [June 6, 1998]
+  Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and
+    added warnings when people try to set png_read_fn and png_write_fn in
+    the same structure.
+  Added a test such that png_do_gamma will be done when num_trans==0
+    for truecolor images that have defined a background.  This corrects an
+    error that was introduced in libpng-0.90 that can cause gamma processing
+    to be skipped.
+  Added tests in png.h to include "trans" and "trans_values" in structures
+    when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined.
+  Add png_free(png_ptr->time_buffer) in png_destroy_read_struct()
+  Moved png_convert_to_rfc_1123() from pngwrite.c to png.c
+  Added capability for user-provided malloc_fn() and free_fn() functions,
+    and revised pngtest.c to demonstrate their use, replacing the
+    PNGTEST_DEBUG_MEM feature.
+  Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner).
+
+version 1.0.2 [June 14, 1998]
+  Fixed two bugs in makefile.bor .
+version 1.0.2a [December 30, 1998]
+  Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
+  Fixed a bug in png_do_filler() that made it fail to write filler bytes in
+    the left-most pixel of each row (Kevin Bracey).
+  Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
+    in pngtest.c (Duncan Simpson).
+  Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
+    even when no tIME chunk was present in the source file.
+  Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
+  Fixed a problem in png_read_push_finish_row(), which would not skip some
+    passes that it should skip, for images that are less than 3 pixels high.
+  Interchanged the order of calls to png_do_swap() and png_do_shift()
+    in pngwtran.c (John Cromer).
+  Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
+  Changed "bad adaptive filter type" from error to warning in pngrutil.c .
+  Fixed a documentation error about default filtering with 8-bit indexed-color.
+  Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
+    (L. Peter Deutsch).
+  Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
+  Added png_get_copyright() and png_get_header_version() functions.
+  Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
+  Added information about debugging in libpng.txt and libpng.3 .
+  Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
+  Removed lines after Dynamic Dependencies" in makefile.aco .
+  Revised makefile.dec to make a shared library (Jeremie Petit).
+  Removed trailing blanks from all files.
+version 1.0.2a [January 6, 1999]
+  Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
+  Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
+  Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
+  Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
+    which is obsolete.
+
+version 1.0.3 [January 14, 1999]
+  Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
+  Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO.
+version 1.0.3a [August 12, 1999]
+  Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning
+     if an attempt is made to read an interlaced image when it's not supported.
+  Added check if png_ptr->trans is defined before freeing it in pngread.c
+  Modified the Y2K statement to include versions back to version 0.71
+  Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c
+  Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments)
+  Replaced leading blanks with tab characters in makefile.hux
+  Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents.
+  Changed (float)red and (float)green to (double)red, (double)green
+     in png_set_rgb_to_gray() to avoid "promotion" problems in AIX.
+  Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey).
+  Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).
+  Updated documentation to refer to the PNG-1.2 specification.
+  Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c
+    in makefile.knr, INSTALL, and README (L. Peter Deutsch)
+  Fixed bugs in calculation of the length of rowbytes when adding alpha
+    channels to 16-bit images, in pngrtran.c (Chris Nokleberg)
+  Added function png_set_user_transform_info() to store user_transform_ptr,
+    user_depth, and user_channels into the png_struct, and a function
+    png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)
+  Added function png_set_empty_plte_permitted() to make libpng useable
+    in MNG applications.
+  Corrected the typedef for png_free_ptr in png.h (Jesse Jones).
+  Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be
+    consistent with PNG-1.2, and allow variance of 500 before complaining.
+  Added assembler code contributed by Intel in file pngvcrd.c and modified
+    makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant)
+  Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy.
+  Added some aliases for png_set_expand() in pngrtran.c, namely
+    png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS()
+    (Greg Roelofs, in "PNG: The Definitive Guide").
+  Added makefile.beo for BEOS on X86, contributed by Sander Stok.
+version 1.0.3b [August 26, 1999]
+  Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h
+  Changed leading blanks to tabs in all makefiles.
+  Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.
+  Made alternate versions of  png_set_expand() in pngrtran.c, namely
+    png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha
+    (Greg Roelofs, in "PNG: The Definitive Guide").  Deleted the 1.0.3a aliases.
+  Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h
+  Revised calculation of num_blocks in pngmem.c to avoid a potentially
+    negative shift distance, whose results are undefined in the C language.
+  Added a check in pngset.c to prevent writing multiple tIME chunks.
+  Added a check in pngwrite.c to detect invalid small window_bits sizes.
+version 1.0.3d [September 4, 1999]
+  Fixed type casting of igamma in pngrutil.c
+  Added new png_expand functions to scripts/pngdef.pas and pngos2.def
+  Added a demo read_user_transform_fn that examines the row filters in pngtest.c
+
+version 1.0.4 [September 24, 1999]
+  Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
+  Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h
+  Made several minor corrections to pngtest.c
+  Renamed the makefiles with longer but more user friendly extensions.
+  Copied the PNG copyright and license to a separate LICENSE file.
+  Revised documentation, png.h, and example.c to remove reference to
+    "viewing_gamma" which no longer appears in the PNG specification.
+  Revised pngvcrd.c to use MMX code for interlacing only on the final pass.
+  Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a
+  Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX
+    assembler code) and makefile.vcwin32 (doesn't).
+  Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING)
+  Added a copy of pngnow.png to the distribution.
+version 1.0.4a [September 25, 1999]
+  Increase max_pixel_depth in pngrutil.c if a user transform needs it.
+  Changed several division operations to right-shifts in pngvcrd.c
+version 1.0.4b [September 30, 1999]
+  Added parentheses in line 3732 of pngvcrd.c
+  Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1
+version 1.0.4c [October 1, 1999]
+  Added a "png_check_version" function in png.c and pngtest.c that will generate
+    a helpful compiler error if an old png.h is found in the search path.
+  Changed type of png_user_transform_depth|channels from int to png_byte.
+version 1.0.4d [October 6, 1999]
+  Changed 0.45 to 0.45455 in png_set_sRGB()
+  Removed unused PLTE entries from pngnow.png
+  Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly.
+version 1.0.4e [October 10, 1999]
+  Fixed sign error in pngvcrd.c (Greg Roelofs)
+  Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P)
+version 1.0.4f [October 15, 1999]
+  Surrounded example.c code with #if 0 .. #endif to prevent people from
+    inadvertently trying to compile it.
+  Changed png_get_header_version() from a function to a macro in png.h
+  Added type casting mostly in pngrtran.c and pngwtran.c
+  Removed some pointless "ptr = NULL" in pngmem.c
+  Added a "contrib" directory containing the source code from Greg's book.
+
+version 1.0.5 [October 15, 1999]
+  Minor editing of the INSTALL and README files.
+version 1.0.5a [October 23, 1999]
+  Added contrib/pngsuite and contrib/pngminus (Willem van Schaik)
+  Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans)
+  Further optimization and bugfix of pngvcrd.c
+  Revised pngset.c so that it does not allocate or free memory in the user's
+    text_ptr structure.  Instead, it makes its own copy.
+  Created separate write_end_info_struct in pngtest.c for a more severe test.
+  Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak.
+version 1.0.5b [November 23, 1999]
+  Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and
+    PNG_FLAG_WROTE_tIME from flags to mode.
+  Added png_write_info_before_PLTE() function.
+  Fixed some typecasting in contrib/gregbook/*.c
+  Updated scripts/makevms.com and added makevms.com to contrib/gregbook
+    and contrib/pngminus (Martin Zinser)
+version 1.0.5c [November 26, 1999]
+  Moved png_get_header_version from png.h to png.c, to accomodate ansi2knr.
+  Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to
+    accomodate making DLL's: Moved usr_png_ver from global variable to function
+    png_get_header_ver() in png.c.  Moved png_sig to png_sig_bytes in png.c and
+    eliminated use of png_sig in pngwutil.c.  Moved the various png_CHNK arrays
+    into pngtypes.h.  Eliminated use of global png_pass arrays.  Declared the
+    png_CHNK and png_pass arrays to be "const".  Made the global arrays
+    available to applications (although none are used in libpng itself) when
+    PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined.
+  Removed some extraneous "-I" from contrib/pngminus/makefile.std
+  Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2.
+  Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3
+version 1.0.5d [November 29, 1999]
+  Add type cast (png_const_charp) two places in png.c
+  Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays.
+  Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available
+    to applications a macro "PNG_USE_LOCAL_ARRAYS".
+  #ifdef out all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined.
+  Added PNG_EXPORT_VAR macro to accommodate making DLL's.
+version 1.0.5e [November 30, 1999]
+  Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text
+    structure; refactored the inflate/deflate support to make adding new chunks
+    with trailing compressed parts easier in the future, and added new functions
+    png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
+    png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
+  NOTE: Applications that write text chunks MUST define png_text->lang
+    before calling png_set_text(). It must be set to NULL if you want to
+    write tEXt or zTXt chunks.  If you want your application to be able to
+    run with older versions of libpng, use
+
+      #ifdef PNG_iTXt_SUPPORTED
+         png_text[i].lang = NULL;
+      #endif
+
+  Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned
+    offsets (Eric S. Raymond).
+  Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into
+    PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED
+    macros, leaving the separate macros also available.
+  Removed comments on #endifs at the end of many short, non-nested #if-blocks.
+version 1.0.5f [December 6, 1999]
+  Changed makefile.solaris to issue a warning about potential problems when
+    the ucb "ld" is in the path ahead of the ccs "ld".
+  Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3.
+  Added sCAL chunk support (Eric S. Raymond).
+version 1.0.5g [December 7, 1999]
+  Fixed "png_free_spallettes" typo in png.h
+  Added code to handle new chunks in pngpread.c
+  Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block
+  Added "translated_key" to png_text structure and png_write_iTXt().
+  Added code in pngwrite.c to work around a newly discovered zlib bug.
+version 1.0.5h [December 10, 1999]
+  NOTE: regarding the note for version 1.0.5e, the following must also
+    be included in your code:
+        png_text[i].translated_key = NULL;
+  Unknown chunk handling is now supported.
+  Option to eliminate all floating point support was added.  Some new
+    fixed-point functions such as png_set_gAMA_fixed() were added.
+  Expanded tabs and removed trailing blanks in source files.
+version 1.0.5i [December 13, 1999]
+  Added some type casts to silence compiler warnings.
+  Renamed "png_free_spalette" to "png_free_spalettes" for consistency.
+  Removed leading blanks from a #define in pngvcrd.c
+  Added some parameters to the new png_set_keep_unknown_chunks() function.
+  Added a test for up->location != 0 in the first instance of writing
+    unknown chunks in pngwrite.c
+  Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to
+    prevent recursion.
+  Added png_free_hIST() function.
+  Various patches to fix bugs in the sCAL and integer cHRM processing,
+    and to add some convenience macros for use with sCAL.
+version 1.0.5j [December 21, 1999]
+  Changed "unit" parameter of png_write_sCAL from png_byte to int, to work
+    around buggy compilers.
+  Added new type "png_fixed_point" for integers that hold float*100000 values
+  Restored backward compatibility of tEXt/zTXt chunk processing:
+    Restored the first four members of png_text to the same order as v.1.0.5d.
+    Added members "lang_key" and "itxt_length" to png_text struct.  Set
+    text_length=0 when "text" contains iTXt data.  Use the "compression"
+    member to distinguish among tEXt/zTXt/iTXt types.  Added
+    PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros.
+    The "Note" above, about backward incompatibility of libpng-1.0.5e, no
+    longer applies.
+  Fixed png_read|write_iTXt() to read|write parameters in the right order,
+    and to write the iTXt chunk after IDAT if it appears in the end_ptr.
+  Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs)
+  Reversed the order of trying to write floating-point and fixed-point gAMA.
+version 1.0.5k [December 27, 1999]
+  Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))"
+  Added png_handle_as_unknown() function (Glenn)
+  Added png_free_chunk_list() function and chunk_list and num_chunk_list members
+    of png_ptr.
+  Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE.
+  Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings
+    about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored)
+  Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR).
+  Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is.
+  Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP().
+version 1.0.5l [January 1, 2000]
+  Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr()
+    for setting a callback function to handle unknown chunks and for
+    retrieving the associated user pointer (Glenn).
+version 1.0.5m [January 7, 2000]
+  Added high-level functions png_read_png(), png_write_png(), png_free_pixels().
+version 1.0.5n [January 9, 2000]
+  Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its
+    own memory for info_ptr->palette.  This makes it safe for the calling
+    application to free its copy of the palette any time after it calls
+    png_set_PLTE().
+version 1.0.5o [January 20, 2000]
+  Cosmetic changes only (removed some trailing blanks and TABs)
+version 1.0.5p [January 31, 2000]
+  Renamed pngdll.mak to makefile.bd32
+  Cosmetic changes in pngtest.c
+version 1.0.5q [February 5, 2000]
+  Relocated the makefile.solaris warning about PATH problems.
+  Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg)
+  Revised makefile.gcmmx
+  Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros
+version 1.0.5r [February 7, 2000]
+  Removed superfluous prototype for png_get_itxt from png.h
+  Fixed a bug in pngrtran.c that improperly expanded the background color.
+  Return *num_text=0 from png_get_text() when appropriate, and fix documentation
+    of png_get_text() in libpng.txt/libpng.3.
+version 1.0.5s [February 18, 2000]
+  Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the
+    new error handler that's planned for the next libpng release, and changed
+    example.c, pngtest.c, and contrib programs to use this macro.
+  Revised some of the DLL-export macros in pngconf.h (Greg Roelofs)
+  Fixed a bug in png_read_png() that caused it to fail to expand some images
+    that it should have expanded.
+  Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions
+    in pngget.c
+  Changed the allocation of palette, history, and trans arrays back to
+    the version 1.0.5 method (linking instead of copying) which restores
+    backward compatibility with version 1.0.5.  Added some remarks about
+    that in example.c.  Added "free_me" member to info_ptr and png_ptr
+    and added png_free_data() function.
+  Updated makefile.linux and makefile.gccmmx to make directories conditionally.
+  Made cosmetic changes to pngasmrd.h
+  Added png_set_rows() and png_get_rows(), for use with png_read|write_png().
+  Modified png_read_png() to allocate info_ptr->row_pointers only if it
+    hasn't already been allocated.
+version 1.0.5t [March 4, 2000]
+  Changed png_jmp_env() migration aiding macro to png_jmpbuf().
+  Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c
+  Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when
+    PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b
+  Files in contrib/gregbook were revised to use png_jmpbuf() and to select
+    a 24-bit visual if one is available, and to allow abbreviated options.
+  Files in contrib/pngminus were revised to use the png_jmpbuf() macro.
+  Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s
+version 1.0.5u [March 5, 2000]
+  Simplified the code that detects old png.h in png.c and pngtest.c
+  Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp)
+  Increased precision of rgb_to_gray calculations from 8 to 15 bits and
+    added png_set_rgb_to_gray_fixed() function.
+  Added makefile.bc32 (32-bit Borland C++, C mode)
+version 1.0.5v [March 11, 2000]
+  Added some parentheses to the png_jmpbuf macro definition.
+  Updated references to the zlib home page, which has moved to freesoftware.com.
+  Corrected bugs in documentation regarding png_read_row() and png_write_row().
+  Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt.
+  Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3,
+    revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin)
+
+version 1.0.6 [March 20, 2000]
+  Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c
+  Added makefile.sggcc (SGI IRIX with gcc)
+version 1.0.6d [April 7, 2000]
+  Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO
+  Added data_length parameter to png_decompress_chunk() function
+  Revised documentation to remove reference to abandoned png_free_chnk functions
+  Fixed an error in png_rgb_to_gray_fixed()
+  Revised example.c, usage of png_destroy_write_struct().
+  Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file
+  Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c
+  Simplify png_sig_bytes() function to remove use of non-ISO-C strdup().
+version 1.0.6e [April 9, 2000]
+  Added png_data_freer() function.
+  In the code that checks for over-length tRNS chunks, added check of
+    info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann)
+  Minor revisions of libpng.txt/libpng.3.
+  Check for existing data and free it if the free_me flag is set, in png_set_*()
+    and png_handle_*().
+  Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED
+    is defined.
+  Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c
+    and mentioned the purposes of the two macros in libpng.txt/libpng.3.
+version 1.0.6f [April 14, 2000]
+  Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data.
+  Add checks in png_set_text() for NULL members of the input text structure.
+  Revised libpng.txt/libpng.3.
+  Removed superfluous prototype for png_set_itxt from png.h
+  Removed "else" from pngread.c, after png_error(), and changed "0" to "length".
+  Changed several png_errors about malformed ancillary chunks to png_warnings.
+version 1.0.6g [April 24, 2000]
+  Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined.
+  Relocated paragraph about png_set_background() in libpng.3/libpng.txt
+    and other revisions (Matthias Benckmann)
+  Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and
+    png_ptr members to restore binary compatibility with libpng-1.0.5
+    (breaks compatibility with libpng-1.0.6).
+version 1.0.6h [April 24, 2000]
+  Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds
+    libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h)
+    This is a temporary change for test purposes.
+version 1.0.6i [May 2, 2000]
+  Rearranged some members at the end of png_info and png_struct, to put
+    unknown_chunks_num and free_me within the original size of the png_structs
+    and free_me, png_read_user_fn, and png_free_fn within the original png_info,
+    because some old applications allocate the structs directly instead of
+    using png_create_*().
+  Added documentation of user memory functions in libpng.txt/libpng.3
+  Modified png_read_png so that it will use user_allocated row_pointers
+    if present, unless free_me directs that it be freed, and added description
+    of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3.
+  Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version
+    1.00) members of png_struct and png_info, to regain binary compatibility
+    when you define this macro.  Capabilities lost in this event
+    are user transforms (new in version 1.0.0),the user transform pointer
+    (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT,
+    the high-level interface, and unknown chunks support (all new in 1.0.6).
+    This was necessary because of old applications that allocate the structs
+    directly as authors were instructed to do in libpng-0.88 and earlier,
+    instead of using png_create_*().
+  Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which
+    can be used to detect codes that directly allocate the structs, and
+    code to check these modes in png_read_init() and png_write_init() and
+    generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED
+    was not defined.
+  Added makefile.intel and updated makefile.watcom (Pawel Mrochen)
+version 1.0.6j [May 3, 2000]
+  Overloaded png_read_init() and png_write_init() with macros that convert
+    calls to png_read_init_2() or png_write_init_2() that check the version
+    and structure sizes.
+version 1.0.7beta11 [May 7, 2000]
+  Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
+    which are no longer used.
+  Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is
+    defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED
+    is defined.
+  Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
+    overrun when old applications fill the info_ptr->text structure directly.
+  Added PNGAPI macro, and added it to the definitions of all exported functions.
+  Relocated version macro definitions ahead of the includes of zlib.h and
+    pngconf.h in png.h.
+version 1.0.7beta12 [May 12, 2000]
+  Revised pngset.c to avoid a problem with expanding the png_debug macro.
+  Deleted some extraneous defines from pngconf.h
+  Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined.
+  Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined.
+  Added png_access_version_number() function.
+  Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data().
+  Expanded libpng.3/libpng.txt information about png_data_freer().
+version 1.0.7beta14 [May 17, 2000] (beta13 was not published)
+  Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as
+    warnings instead of errors, as pngrutil.c does.
+  Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png()
+    will actually write IDATs.
+  Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32.
+  Make png_free_data() ignore its final parameter except when freeing data
+    that can have multiple instances (text, sPLT, unknowns).
+  Fixed a new bug in png_set_rows().
+  Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5.
+  Added png_set_invalid() function.
+  Fixed incorrect illustrations of png_destroy_write_struct() in example.c.
+version 1.0.7beta15 [May 30, 2000]
+  Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce
+    fewer error messages.
+  Rearranged checks for Z_OK to check the most likely path first in pngpread.c
+    and pngwutil.c.
+  Added checks in pngtest.c for png_create_*() returning NULL, and mentioned
+    in libpng.txt/libpng.3 the need for applications to check this.
+  Changed names of png_default_*() functions in pngtest to pngtest_*().
+  Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32.
+  Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c
+  Set each pointer to NULL after freeing it in png_free_data().
+  Worked around a problem in pngconf.h; AIX's strings.h defines an "index"
+    macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos)
+  Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux).
+version 1.0.7beta16 [June 4, 2000]
+  Revised the workaround of AIX string.h "index" bug.
+  Added a check for overlength PLTE chunk in pngrutil.c.
+  Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer
+    indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler.
+  Added a warning in png_decompress_chunk() when it runs out of data, e.g.
+    when it tries to read an erroneous PhotoShop iCCP chunk.
+  Added PNG_USE_DLL macro.
+  Revised the copyright/disclaimer/license notice.
+  Added contrib/msvctest directory
+version 1.0.7rc1 [June 9, 2000]
+  Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA  (0x0400 not 0x0200)
+  Added contrib/visupng directory (Willem van Schaik)
+version 1.0.7beta18 [June 23, 2000]
+  Revised PNGAPI definition, and pngvcrd.c to work with __GCC__
+    and do not redefine PNGAPI if it is passed in via a compiler directive.
+  Revised visupng/PngFile.c to remove returns from within the Try block.
+  Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros.
+  Updated contrib/visupng/cexcept.h to version 1.0.0.
+  Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks.
+version 1.0.7rc2 [June 28, 2000]
+  Updated license to include disclaimers required by UCITA.
+  Fixed "DJBPP" typo in pnggccrd.c introduced in beta18.
+
+version 1.0.7 [July 1, 2000]
+  Revised the definition of "trans_values" in libpng.3/libpng.txt
+version 1.0.8beta1 [July 8, 2000]
+  Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks.
+  Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and
+     pngwutil.c.
+  Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h.
+  Removed unused "#include <assert.h>" from png.c
+  Added WindowsCE support.
+  Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment.
+version 1.0.8beta2 [July 10, 2000]
+  Added project files to the wince directory and made further revisions
+     of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE.
+version 1.0.8beta3 [July 11, 2000]
+  Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS()
+     for indexed-color input files to avoid potential double-freeing trans array
+     under some unusual conditions; problem was introduced in version 1.0.6f.
+  Further revisions to pngtest.c and files in the wince subdirectory.
+version 1.0.8beta4 [July 14, 2000]
+  Added the files pngbar.png and pngbar.jpg to the distribution.
+  Added makefile.cygwin, and cygwin support in pngconf.h
+  Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory)
+version 1.0.8rc1 [July 16, 2000]
+  Revised png_debug() macros and statements to eliminate compiler warnings.
+
+version 1.0.8 [July 24, 2000]
+  Added png_flush() in pngwrite.c, after png_write_IEND().
+  Updated makefile.hpux to build a shared library.
+version 1.0.9beta1 [November 10, 2000]
+  Fixed typo in scripts/makefile.hpux
+  Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)
+  Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
+  Changed "cdrom.com" in documentation to "libpng.org"
+  Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).
+  Changed type of "params" from voidp to png_voidp in png_read|write_png().
+  Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h.
+  Revised the 3 instances of WRITEFILE in pngtest.c.
+  Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory.
+  Updated png.rc in dll/msvc project
+  Revised makefile.dec to define and use LIBPATH and INCPATH
+  Increased size of global png_libpng_ver[] array from 12 to 18 chars.
+  Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const.
+  Removed duplicate png_crc_finish() from png_handle_bKGD() function.
+  Added a warning when application calls png_read_update_info() multiple times.
+  Revised makefile.cygwin
+  Fixed bugs in iCCP support in pngrutil.c and pngwutil.c.
+  Replaced png_set_empty_plte_permitted() with png_permit_mng_features().
+version 1.0.9beta2 [November 19, 2000]
+  Renamed the "dll" subdirectory "projects".
+  Added borland project files to "projects" subdirectory.
+  Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate.
+  Add error message in png_set_compression_buffer_size() when malloc fails.
+version 1.0.9beta3 [November 23, 2000]
+  Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project.
+  Removed the png_flush() in pngwrite.c that crashes some applications
+    that don't set png_output_flush_fn.
+  Added makefile.macosx and makefile.aix to scripts directory.
+version 1.0.9beta4 [December 1, 2000]
+  Change png_chunk_warning to png_warning in png_check_keyword().
+  Increased the first part of msg buffer from 16 to 18 in png_chunk_error().
+version 1.0.9beta5 [December 15, 2000]
+  Added support for filter method 64 (for PNG datastreams embedded in MNG).
+version 1.0.9beta6 [December 18, 2000]
+  Revised png_set_filter() to accept filter method 64 when appropriate.
+  Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to
+    help prevent applications from using MNG features in PNG datastreams.
+  Added png_permit_mng_features() function.
+  Revised libpng.3/libpng.txt.  Changed "filter type" to "filter method".
+version 1.0.9rc1 [December 23, 2000]
+  Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c
+  Fixed error handling of unknown compression type in png_decompress_chunk().
+  In pngconf.h, define __cdecl when _MSC_VER is defined.
+version 1.0.9beta7 [December 28, 2000]
+  Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places.
+  Revised memory management in png_set_hIST and png_handle_hIST in a backward
+    compatible manner.  PLTE and tRNS were revised similarly.
+  Revised the iCCP chunk reader to ignore trailing garbage.
+version 1.0.9beta8 [January 12, 2001]
+  Moved pngasmrd.h into pngconf.h.
+  Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop.
+version 1.0.9beta9 [January 15, 2001]
+  Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to
+    wince and msvc project module definition files.
+  Minor revision of makefile.cygwin.
+  Fixed bug with progressive reading of narrow interlaced images in pngpread.c
+version 1.0.9beta10 [January 16, 2001]
+  Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined.
+  Fixed "png_mmx_supported" typo in project definition files.
+version 1.0.9beta11 [January 19, 2001]
+  Updated makefile.sgi to make shared library.
+  Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED
+    by default, for the benefit of DLL forward compatibility.  These will
+    be re-enabled in version 1.2.0.
+version 1.0.9rc2 [January 22, 2001]
+  Revised cygwin support.
+
+version 1.0.9 [January 31, 2001]
+  Added check of cygwin's ALL_STATIC in pngconf.h
+  Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos.
+version 1.0.10beta1 [March 14, 2001]
+  Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc.
+  Reformatted libpng.3 to eliminate bad line breaks.
+  Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c
+  Added prototype for png_mmx_support() near the top of pnggccrd.c
+  Moved some error checking from png_handle_IHDR to png_set_IHDR.
+  Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros.
+  Revised png_mmx_support() function in pnggccrd.c
+  Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c
+  Fixed memory leak in contrib/visupng/PngFile.c
+  Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version)
+  Added warnings when retrieving or setting gamma=0.
+  Increased the first part of msg buffer from 16 to 18 in png_chunk_warning().
+version 1.0.10rc1 [March 23, 2001]
+  Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy,
+    and png_strlen.
+  Revised png_mmx_supported() function in pnggccrd.c to return proper value.
+  Fixed bug in progressive reading (pngpread.c) with small images (height < 8).
+
+version 1.0.10 [March 30, 2001]
+  Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin
+  Added beos project files (Chris Herborth)
+version 1.0.11beta1 [April 3, 2001]
+  Added type casts on several png_malloc() calls (Dimitri Papadapoulos).
+  Removed a no-longer needed AIX work-around from pngconf.h
+  Changed several "//" single-line comments to C-style in pnggccrd.c
+version 1.0.11beta2 [April 11, 2001]
+  Removed PNGAPI from several functions whose prototypes did not have PNGAPI.
+  Updated scripts/pngos2.def
+version 1.0.11beta3 [April 14, 2001]
+  Added checking the results of many instances of png_malloc() for NULL
+version 1.0.11beta4 [April 20, 2001]
+  Undid the changes from version 1.0.11beta3.  Added a check for NULL return
+    from user's malloc_fn().
+  Removed some useless type casts of the NULL pointer.
+  Added makefile.netbsd
+
+version 1.0.11 [April 27, 2001]
+  Revised makefile.netbsd
+version 1.0.12beta1 [May 14, 2001]
+  Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot)
+  Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h
+  Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings.
+  Eliminated the png_error about apps using png_read|write_init().  Instead,
+    libpng will reallocate the png_struct and info_struct if they are too small.
+    This retains future binary compatibility for old applications written for
+    libpng-0.88 and earlier.
+version 1.2.0beta1 [May 6, 2001]
+  Bumped DLLNUM to 2.
+  Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED
+    by default.
+  Added runtime selection of MMX features.
+  Added png_set_strip_error_numbers function and related macros.
+version 1.2.0beta2 [May 7, 2001]
+  Finished merging 1.2.0beta1 with version 1.0.11
+  Added a check for attempts to read or write PLTE in grayscale PNG datastreams.
+version 1.2.0beta3 [May 17, 2001]
+  Enabled user memory function by default.
+  Modified png_create_struct so it passes user mem_ptr to user memory allocator.
+  Increased png_mng_features flag from png_byte to png_uint_32.
+  Bumped shared-library (so-number) and dll-number to 3.
+version 1.2.0beta4 [June 23, 2001]
+  Check for missing profile length field in iCCP chunk and free chunk_data
+     in case of truncated iCCP chunk.
+  Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc
+  Bumped dll-number from 2 to 3 in makefile.cygwin
+  Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly
+     if user attempts to run it on an 8-bit display.
+  Updated contrib/gregbook
+  Use png_malloc instead of png_zalloc to allocate palette in pngset.c
+  Updated makefile.ibmc
+  Added some typecasts to eliminate gcc 3.0 warnings.  Changed prototypes
+     of png_write_oFFS width and height from png_uint_32 to png_int_32.
+  Updated example.c
+  Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c
+version 1.2.0beta5 [August 8, 2001]
+  Revised contrib/gregbook
+  Revised makefile.gcmmx
+  Revised pnggccrd.c to conditionally compile some thread-unsafe code only
+     when PNG_THREAD_UNSAFE_OK is defined.
+  Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with
+     value exceeding 2^bit_depth-1
+  Revised makefile.sgi and makefile.sggcc
+  Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c
+  Removed restriction that do_invert_mono only operate on 1-bit opaque files
+
+version 1.2.0 [September 1, 2001]
+  Changed a png_warning() to png_debug() in pnggccrd.c
+  Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC().
+version 1.2.1beta1 [October 19, 2001]
+  Revised makefile.std in contrib/pngminus
+  Include background_1 in png_struct regardless of gamma support.
+  Revised makefile.netbsd and makefile.macosx, added makefile.darwin.
+  Revised example.c to provide more details about using row_callback().
+version 1.2.1beta2 [October 25, 2001]
+  Added type cast to each NULL appearing in a function call, except for
+    WINCE functions.
+  Added makefile.so9.
+version 1.2.1beta3 [October 27, 2001]
+  Removed type casts from all NULLs.
+  Simplified png_create_struct_2().
+version 1.2.1beta4 [November 7, 2001]
+  Revised png_create_info_struct() and png_creat_struct_2().
+  Added error message if png_write_info() was omitted.
+  Type cast NULLs appearing in function calls when _NO_PROTO or
+    PNG_TYPECAST_NULL is defined.
+version 1.2.1rc1 [November 24, 2001]
+  Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL
+    is defined.
+  Changed typecast of "size" argument to png_size_t in pngmem.c calls to
+    the user malloc_fn, to agree with the prototype in png.h
+  Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev)
+  Updated makefile.sgi to recognize LIBPATH and INCPATH.
+  Updated various makefiles so "make clean" does not remove previous major
+    version of the shared library.
+version 1.2.1rc2 [December 4, 2001]
+  Always allocate 256-entry internal palette, hist, and trans arrays, to
+    avoid out-of-bounds memory reference caused by invalid PNG datastreams.
+  Added a check for prefix_length > data_length in iCCP chunk handler.
+
+version 1.2.1 [December 7, 2001]
+  None.
+version 1.2.2beta1 [February 22, 2002]
+  Fixed a bug with reading the length of iCCP profiles (Larry Reeves).
+  Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate
+    libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h
+  Revised makefile.darwin to remove "-undefined suppress" option.
+  Added checks for gamma and chromaticity values over 21474.83, which exceed
+    the limit for PNG unsigned 32-bit integers when encoded.
+  Revised calls to png_create_read_struct() and png_create_write_struct()
+    for simpler debugging.
+  Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK)
+version 1.2.2beta2 [February 23, 2002]
+  Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths.
+  Check for invalid image dimensions in png_get_IHDR.
+  Added missing "fi;" in the install target of the SGI makefiles.
+  Added install-static to all makefiles that make shared libraries.
+  Always do gamma compensation when image is partially transparent.
+version 1.2.2beta3 [March 7, 2002]
+  Compute background.gray and background_1.gray even when color_type is RGB
+    in case image gets reduced to gray later.
+  Modified shared-library makefiles to install pkgconfig/libpngNN.pc.
+  Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown
+  Removed unused png_write_destroy_info prototype from png.h
+  Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case
+  Added install-shared target to all makefiles that make shared libraries.
+  Stopped a double free of palette, hist, and trans when not using free_me.
+  Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64.
+version 1.2.2beta4 [March 8, 2002]
+  Compute background.gray and background_1.gray even when color_type is RGB
+    in case image gets reduced to gray later (Jason Summers).
+  Relocated a misplaced /bin/rm in the "install-shared" makefile targets
+  Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library.
+version 1.2.2beta5 [March 26, 2002]
+  Added missing PNGAPI to several function definitions.
+  Check for invalid bit_depth or color_type in png_get_IHDR(), and
+    check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen).
+  Revised iTXt support to accept NULL for lang and lang_key.
+  Compute gamma for color components of background even when color_type is gray.
+  Changed "()" to "{}" in scripts/libpng.pc.in.
+  Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN
+  Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so
+version 1.2.2beta6 [March 31, 2002]
+version 1.0.13beta1 [March 31, 2002]
+  Prevent png_zalloc() from trying to memset memory that it failed to acquire.
+  Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate).
+  Ensure that the right function (user or default) is used to free the
+    png_struct after an error in png_create_read_struct_2().
+version 1.2.2rc1 [April 7, 2002]
+version 1.0.13rc1 [April 7, 2002]
+  Save the ebx register in pnggccrd.c (Sami Farin)
+  Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner).
+  Updated makefiles to put headers in include/libpng and remove old include/*.h.
+
+version 1.2.2 [April 15, 2002]
+version 1.0.13 [April 15, 2002]
+  Revised description of png_set_filter() in libpng.3/libpng.txt.
+  Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd
+version 1.0.13patch01 [April 17, 2002]
+version 1.2.2patch01 [April 17, 2002]
+  Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and makefile.sggcc
+  Fixed VER -> PNGVER typo in makefile.macosx and added install-static to install
+  Added install: target to makefile.32sunu and makefile.64sunu
+version 1.0.13patch03 [April 18, 2002]
+version 1.2.2patch03 [April 18, 2002]
+  Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng
+  subdirectory to libpngNN subdirectory without the full pathname.
+  Moved generation of libpng.pc from "install" to "all" in 15 makefiles.
+version 1.2.3rc1 [April 28, 2002]
+  Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos).
+  Added $(DESTDIR) feature to 24 makefiles (Tim Mooney)
+  Fixed bug with $prefix, should be $(prefix) in makefile.hpux.
+  Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin
+  Added a link from libpngNN.pc to libpng.pc in 15 makefiles.
+  Added links from include/libpngNN/*.h to include/*.h in 24 makefiles.
+  Revised makefile.darwin to make relative links without full pathname.
+  Added setjmp() at the end of png_create_*_struct_2() in case user forgets
+    to put one in their application.
+  Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and
+    removed them from module definition files.
+version 1.2.3rc2 [May 1, 2002]
+  Fixed bug in reporting number of channels in pngget.c and pngset.c,
+    that was introduced in version 1.2.2beta5.
+  Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(),
+    png_default_flush(), and png_push_fill_buffer() and included them in
+    module definition files.
+  Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles.
+version 1.2.3rc3 [May 1, 2002]
+  Revised prototype for png_default_flush()
+  Remove old libpng.pc and libpngNN.pc before installing new ones.
+version 1.2.3rc4 [May 2, 2002]
+  Typos in *.def files (png_default_read|write -> png_default_read|write_data)
+  In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc
+  Added libpng-config and libpngNN-config and modified makefiles to install them.
+  Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles
+  Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp
+version 1.2.3rc5 [May 11, 2002]
+  Changed "error" and "message" in prototypes to "error_message" and
+    "warning_message" to avoid namespace conflict.
+  Revised 15 makefiles to build libpng-config from libpng-config-*.in
+  Once more restored png_zalloc and png_zfree to regular nonexported form.
+  Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer
+    to nonexported form, but with PNGAPI, and removed them from module def files.
+version 1.2.3rc6 [May 14, 2002]
+  Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c
+  Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp.
+  Removed leftover libpng-config "sed" script from four makefiles.
+  Revised libpng-config creating script in 16 makefiles.
+
+version 1.2.3 [May 22, 2002]
+  Revised libpng-config target in makefile.cygwin.
+  Removed description of png_set_mem_fn() from documentation.
+  Revised makefile.freebsd.
+  Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR).
+  Revised projects/msvc/README.txt
+  Changed -lpng to -lpngNN in LDFLAGS in several makefiles.
+version 1.2.4beta1 [May 24, 2002]
+  Added libpng.pc and libpng-config to "all:" target in 16 makefiles.
+  Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH)
+  Added missing "\" before closing double quote in makefile.gcmmx.
+  Plugged various memory leaks; added png_malloc_warn() and png_set_text_2()
+    functions.
+version 1.2.4beta2 [June 25, 2002]
+  Plugged memory leak of png_ptr->current_text (Matt Holgate).
+  Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison)
+  Added -soname to the loader flags in makefile.dec, makefile.sgi, and
+    makefile.sggcc.
+  Added "test-installed" target to makefile.linux, makefile.gcmmx,
+    makefile.sgi, and makefile.sggcc.
+version 1.2.4beta3 [June 28, 2002]
+  Plugged memory leak of row_buf in pngtest.c when there is a png_error().
+  Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data.
+  Added "test-installed" target to makefile.32sunu, makefile.64sunu,
+    makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, 
+    makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9.
+version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002]
+  Added "test-installed" target to makefile.cygwin and makefile.sco.
+  Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro.
+
+version 1.2.4 and 1.0.14 [July 8, 2002]
+  Changed png_warning() to png_error() when width is too large to process.
+version 1.2.4patch01 [July 20, 2002]
+  Revised makefile.cygwin to use DLL number 12 instead of 13.
+version 1.2.5beta1 [August 6, 2002]
+  Added code to contrib/gregbook/readpng2.c to ignore unused chunks.
+  Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11)
+  Removed some stray *.o files from contrib/gregbook.
+  Changed png_error() to png_warning() about "Too much data" in pngpread.c
+    and about "Extra compressed data" in pngrutil.c.
+  Prevent png_ptr->pass from exceeding 7 in png_push_finish_row().
+  Updated makefile.hpgcc
+  Updated png.c and pnggccrd.c handling of return from png_mmx_support()
+version 1.2.5beta2 [August 15, 2002]
+  Only issue png_warning() about "Too much data" in pngpread.c when avail_in
+    is nonzero.
+  Updated makefiles to install a separate libpng.so.3 with its own rpath.
+version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002]
+  Revised makefiles to not remove previous minor versions of shared libraries.
+version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002]
+  Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared
+    library loader directive.
+  Added missing "$OBJSDLL" line to makefile.gcmmx.
+  Added missing "; fi" to makefile.32sunu.
+version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002]
+  Revised libpng-config script.
+
+version 1.2.5 and 1.0.15 [October 3, 2002]
+  Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux,
+    and makefile.aix.
+  Relocated two misplaced PNGAPI lines in pngtest.c
+version 1.2.6beta1 [October 22, 2002]
+  Commented out warning about uninitialized mmx_support in pnggccrd.c.
+  Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h.
+  Relocated two more misplaced PNGAPI lines in pngtest.c
+  Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams,
+    introduced in version 1.0.2.
+  Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu.
+version 1.2.6beta2 [November 1, 2002]
+  Added libpng-config "--ldopts" output.
+  Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)"
+    in makefiles.
+version 1.2.6beta3 [July 18, 2004]
+  Reverted makefile changes from version 1.2.6beta2 and some of the changes
+    from version 1.2.6beta1; these will be postponed until version 1.2.7.
+    Version 1.2.6 is going to be a simple bugfix release.
+  Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile.
+  Fixed potential overrun in pngerror.c by using strncpy instead of memcpy.
+  Added "#!/bin/sh" at the top of configure, for recognition of the
+    'x' flag under Cygwin (Cosmin).
+  Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin).
+  Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin).
+  Fixed the special memory handler for Borland C under DOS, in pngmem.c
+    (Cosmin).
+  Removed some spurious assignments in pngrutil.c (Cosmin).
+  Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings
+    on 16-bit platforms (Cosmin).
+  Enclosed shift op expressions in parentheses, to silence warnings (Cosmin).
+  Used proper type png_fixed_point, to avoid problems on 16-bit platforms,
+    in png_handle_sRGB() (Cosmin).
+  Added compression_type to png_struct, and optimized the window size
+    inside the deflate stream (Cosmin).
+  Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin).
+  Fixed handling of unknown chunks that come after IDAT (Cosmin).
+  Allowed png_error() and png_warning() to work even if png_ptr == NULL
+    (Cosmin).
+  Replaced row_info->rowbytes with row_bytes in png_write_find_filter()
+    (Cosmin).
+  Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre).
+  Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded
+    values in png.c (Simon-Pierre, Cosmin).
+  Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre).
+  Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc
+    (Simon-Pierre).
+  Moved the definition of PNG_HEADER_VERSION_STRING near the definitions
+    of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin).
+  Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin).
+  Updated scripts/makefile.vc(a)win32 (Cosmin).
+  Updated the MSVC project (Simon-Pierre, Cosmin).
+  Updated the Borland C++ Builder project (Cosmin).
+  Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin).
+  Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin).
+  Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin).
+  Added extra guard around inclusion of Turbo C memory headers, in pngconf.h
+    (Cosmin).
+  Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to
+    projects/cbuilder5/ (Cosmin).
+  Moved projects/visualc6/png32ms.def to scripts/pngw32.def,
+    and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin).
+  Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin).
+  Changed line endings to DOS style in cbuilder5 and visualc6 files, even
+    in the tar.* distributions (Cosmin).
+  Updated contrib/visupng/VisualPng.dsp (Cosmin).
+  Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin).
+  Added a separate distribution with "configure" and supporting files (Junichi).
+version 1.2.6beta4 [July 28, 2004]
+  Added user ability to change png_size_t via a PNG_SIZE_T macro.
+  Added png_sizeof() and png_convert_size() functions.
+  Added PNG_SIZE_MAX (maximum value of a png_size_t variable.
+  Added check in png_malloc_default() for (size_t)size != (png_uint_32)size
+    which would indicate an overflow.
+  Changed sPLT failure action from png_error to png_warning and abandon chunk.
+  Changed sCAL and iCCP failures from png_error to png_warning and abandon.
+  Added png_get_uint_31(png_ptr, buf) function.
+  Added PNG_UINT_32_MAX macro.
+  Renamed PNG_MAX_UINT to PNG_UINT_31_MAX.
+  Made png_zalloc() issue a png_warning and return NULL on potential
+    overflow.
+  Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x
+  Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4.
+  Revised Borland portion of png_malloc() to return NULL or issue
+    png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK.
+  Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove
+    sequential read support.
+  Added some "#if PNG_WRITE_SUPPORTED" blocks.
+  #ifdef'ed out some redundancy in png_malloc_default().
+  Use png_malloc instead of png_zalloc to allocate the pallete.
+version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004]
+  Fixed buffer overflow vulnerability in png_handle_tRNS()
+  Fixed integer arithmetic overflow vulnerability in png_read_png().
+  Fixed some harmless bugs in png_handle_sBIT, etc, that would cause
+    duplicate chunk types to go undetected.
+  Fixed some timestamps in the -config version
+  Rearranged order of processing of color types in png_handle_tRNS().
+  Added ROWBYTES macro to calculate rowbytes without integer overflow.
+  Updated makefile.darwin and removed makefile.macosx from scripts directory.
+  Imposed default one million column, one-million row limits on the image
+    dimensions, and added png_set_user_limits() function to override them.
+  Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro.
+  Fixed wrong cast of returns from png_get_user_width|height_max().
+  Changed some "keep the compiler happy" from empty statements to returns,
+  Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution
+version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004]
+  Revised makefile.darwin and makefile.solaris.  Removed makefile.macosx.
+  Revised pngtest's png_debug_malloc() to use png_malloc() instead of
+    png_malloc_default() which is not supposed to be exported.
+  Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in
+    pngpread.c.  Bug was introduced in 1.2.6rc1.
+  Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1.
+  Fixed old bug in RGB to Gray transformation.
+  Fixed problem with 64-bit compilers by casting arguments to abs()
+    to png_int_32.
+  Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9).
+  Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin)
+  Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles.
+  Added code to update the row_info->colortype in png_do_read_filler() (MSB).
+version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004]
+  Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid
+    trouble with some 64-bit compilers.  Created PNG_OUT_OF_RANGE() macro.
+  Revised documentation of png_set_keep_unknown_chunks().
+  Check handle_as_unknown status in pngpread.c, as in pngread.c previously.
+  Moved  "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h
+  Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c
+version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004]
+  Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of
+    "pinfo" was out of place).
+version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004]
+  Moved  "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED
+     section of png.h where they were inadvertently placed in version rc3.
+
+version 1.0.16 and 1.2.6 [August 15, 2004]
+  Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1.
+version 1.2.7beta1 [August 26, 2004]
+  Removed unused pngasmrd.h file.
+  Removed references to uu.net for archived files.  Added references to
+    PNG Spec (second edition) and the PNG ISO/IEC Standard.
+  Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR.
+  Fixed bug with "optimized window size" in the IDAT datastream, that
+    causes libpng to write PNG files with incorrect zlib header bytes.
+version 1.2.7beta2 [August 28, 2004]
+  Fixed bug with sCAL chunk and big-endian machines (David Munro).
+  Undid new code added in 1.2.6rc2 to update the color_type in
+    png_set_filler().
+  Added png_set_add_alpha() that updates color type.
+version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004]
+  Revised png_set_strip_filler() to not remove alpha if color_type has alpha.
+version 1.0.17 and 1.2.7 [September 12, 2004]
+  Added makefile.hp64
+  Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin
+
+Send comments/corrections/commendations to
+png-implement@ccrc.wustl.edu (subscription required; write to
+majordomo@ccrc.wustl.edu with "subscribe png-implement" in the message)
+or to glennrp@users.sourceforge.net
+
+Glenn R-P
diff --git a/Utilities/FLTK/png/CMakeLists.txt b/Utilities/FLTK/png/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..eb298488584fb4db4b51f5acc75fb4330f35d5c6
--- /dev/null
+++ b/Utilities/FLTK/png/CMakeLists.txt
@@ -0,0 +1,30 @@
+PROJECT(FLTKPNG)
+INCLUDE_REGULAR_EXPRESSION("^png.*$")
+
+INCLUDE_DIRECTORIES(${FLTKZLIB_SOURCE_DIR})
+
+IF(ZLIB_INCLUDE_DIR)
+  INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
+ENDIF(ZLIB_INCLUDE_DIR)
+
+INCLUDE_DIRECTORIES(${FLTKPNG_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${FLTKPNG_BINARY_DIR})
+
+# source files for png
+SET(PNG_SRCS
+  pngget.c    pngrio.c    pngwrite.c
+  png.c       pngmem.c    pngrtran.c  pngtrans.c  pngwtran.c
+  pngerror.c  pngpread.c  pngrutil.c  pngwutil.c
+  pngread.c   pngset.c   pngwio.c
+  )
+
+ADD_LIBRARY(fltk_png ${PNG_SRCS})
+INSTALL_TARGETS(/lib fltk_png)
+
+
+IF(UNIX)
+  TARGET_LINK_LIBRARIES(fltk_png ${FLTK_ZLIB_LIBRARIES} -lm)
+ELSE(UNIX)
+  TARGET_LINK_LIBRARIES(fltk_png ${FLTK_ZLIB_LIBRARIES})
+ENDIF(UNIX)
+
diff --git a/Utilities/FLTK/png/INSTALL b/Utilities/FLTK/png/INSTALL
new file mode 100644
index 0000000000000000000000000000000000000000..9876e9d30e01939f68b27e9cd15e1dbdb7cea3c5
--- /dev/null
+++ b/Utilities/FLTK/png/INSTALL
@@ -0,0 +1,167 @@
+
+Installing libpng version 1.2.7 - September 12, 2004
+
+Before installing libpng, you must first install zlib.  zlib
+can usually be found wherever you got libpng.  zlib can be
+placed in another directory, at the same level as libpng.
+Note that your system might already have a preinstalled
+zlib, but you will still need to have access to the
+zlib.h and zconf.h include files that correspond to the
+version of zlib that's installed.
+
+You can rename the directories that you downloaded (they
+might be called "libpng-1.2.7" or "lpng109" and "zlib-1.2.1"
+or "zlib121") so that you have directories called "zlib" and "libpng".
+
+Your directory structure should look like this:
+
+   ..       (the parent directory)
+      libpng  (this directory)
+          INSTALL (this file)
+          README
+          *.h
+          *.c
+          contrib
+             gregbook
+             pngminus
+             pngsuite
+             visupng
+          projects
+             beos
+             c5builder (Borland)
+             visualc6 (msvc)
+             netware.txt
+             wince.txt
+          scripts
+             makefile.*
+          pngtest.png
+          etc.
+      zlib
+          README
+          *.h
+          *.c
+          contrib
+          etc.
+
+If the line endings in the files look funny, you may wish to get the other
+distribution of libpng.  It is available in both tar.gz (UNIX style line
+endings) and zip (DOS style line endings) formats.
+
+
+If you are building libpng with MSVC, you can enter the
+libpng projects\visualc6 directory and follow the instructions in
+projects\visualc6\README.txt.
+
+You can build libpng for WindowsCE by downloading and installing
+the projects\wince directory as instructed in the projects\wince.txt file, and
+then following the instructions in the README* files.  Similarly, you can
+build libpng for Netware or Beos as instructed in projects\netware.txt
+or projects\beos.
+
+Else enter the zlib directory and follow the instructions in zlib/README,
+then come back here and choose the appropriate makefile.sys in the scripts
+directory.
+
+The files that are presently available in the scripts directory
+include
+
+ makefile.std      =>  Generic UNIX makefile (cc, creates static libpng.a)
+ makefile.linux    =>  Linux/ELF makefile
+                       (gcc, creates libpng12.so.0.1.2.7)
+ makefile.gcmmx    =>  Linux/ELF makefile
+                       (gcc, creates libpng12.so.0.1.2.7,
+                       uses assembler code tuned for Intel MMX platform)
+ makefile.gcc      =>  Generic makefile (gcc, creates static libpng.a)
+ makefile.knr      =>  Archaic UNIX Makefile that converts files with
+                       ansi2knr (Requires ansi2knr.c from
+                       ftp://ftp.cs.wisc.edu/ghost)
+ makefile.aix      =>  AIX/gcc makefile
+ makefile.cygwin   =>  Cygwin/gcc makefile
+ makefile.darwin   =>  Darwin makefile, can use on MacosX
+ makefile.dec      =>  DEC Alpha UNIX makefile
+ makefile.freebsd  =>  FreeBSD makefile
+ makefile.hpgcc    =>  HPUX makefile using gcc
+ makefile.hpux     =>  HPUX (10.20 and 11.00) makefile
+ makefile.hp64     =>  HPUX (10.20 and 11.00) makefile, 64-bit
+ makefile.ibmc     =>  IBM C/C++ version 3.x for Win32 and OS/2 (static)
+ makefile.intel    =>  Intel C/C++ version 4.0 and later
+ libpng.icc        =>  Project file for IBM VisualAge/C++ version 4.0 or later
+ makefile.netbsd   =>  NetBSD/cc makefile, uses PNGGCCRD, makes libpng.so.
+ makefile.ne12bsd  =>  NetBSD/cc makefile, uses PNGGCCRD,
+                       makes libpng12.so
+ makefile.openbsd  =>  OpenBSD makefile
+ makefile.sgi      =>  Silicon Graphics IRIX makefile (cc, creates static lib)
+ makefile.sggcc    =>  Silicon Graphics (gcc,
+                       creates libpng12.so.0.1.2.7)
+ makefile.sunos    =>  Sun makefile
+ makefile.solaris  =>  Solaris 2.X makefile (gcc,
+                       creates libpng12.so.0.1.2.7)
+ makefile.so9      =>  Solaris 9 makefile (gcc,
+                       creates libpng12.so.0.1.2.7)
+ makefile.32sunu   =>  Sun Ultra 32-bit makefile
+ makefile.64sunu   =>  Sun Ultra 64-bit makefile
+ makefile.sco      =>  For SCO OSr5  ELF and Unixware 7 with Native cc
+ makefile.mips     =>  MIPS makefile
+ makefile.acorn    =>  Acorn makefile
+ makefile.amiga    =>  Amiga makefile
+ smakefile.ppc     =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
+                       (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
+ makefile.atari    =>  Atari makefile
+ makefile.beos     =>  BEOS makefile for X86
+ makefile.bor      =>  Borland makefile (uses bcc)
+ makefile.bc32     =>  32-bit Borland C++ (all modules compiled in C mode)
+ makefile.tc3      =>  Turbo C 3.0 makefile
+ makefile.dj2      =>  DJGPP 2 makefile
+ makefile.msc      =>  Microsoft C makefile
+ makefile.vcawin32 =>  makefile for Microsoft Visual C++ 5.0 and later (uses
+                       assembler code tuned for Intel MMX platform)
+ makefile.vcwin32  =>  makefile for Microsoft Visual C++ 4.0 and later (does
+                       not use assembler code)
+ makefile.os2      =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
+ pngos2.def        =>  OS/2 module definition file used by makefile.os2
+ makefile.watcom   =>  Watcom 10a+ Makefile, 32-bit flat memory model
+ makevms.com       =>  VMS build script
+ descrip.mms       =>  VMS makefile for MMS or MMK
+ SCOPTIONS.ppc     =>  Used with smakefile.ppc
+
+Copy the file (or files) that you need from the
+scripts directory into this directory, for example
+
+   MSDOS example: copy scripts\makefile.msc makefile
+   UNIX example:    cp scripts/makefile.std makefile
+
+Read the makefile to see if you need to change any source or
+target directories to match your preferences.
+
+Then read pngconf.h to see if you want to make any configuration
+changes.
+
+Then just run "make" which will create the libpng library in
+this directory and "make test" which will run a quick test that reads
+the "pngtest.png" file and writes a "pngout.png" file that should be
+identical to it.  Look for "9782 zero samples" in the output of the
+test.  For more confidence, you can run another test by typing
+"pngtest pngnow.png" and looking for "289 zero samples" in the output.
+Also, you can run "pngtest -m contrib/pngsuite/*.png" and compare
+your output with the result shown in contrib/pngsuite/README.
+
+Most of the makefiles will allow you to run "make install" to
+put the library in its final resting place (if you want to
+do that, run "make install" in the zlib directory first if necessary).
+Some also allow you to run "make test-installed" after you have
+run "make install".
+
+If you encounter a compiler error message complaining about the
+lines
+      __png.h__ already includes setjmp.h;
+      __dont__ include it again.;
+This means you have compiled another module that includes setjmp.h,
+which is hazardous because the two modules might not include exactly
+the same setjmp.h.  If you are sure that you know what you are doing
+and that they are exactly the same, then you can comment out or
+delete the two lines.  Better yet, use the cexcept interface
+instead, as demonstrated in contrib/visupng of the libpng distribution.
+
+Further information can be found in the README and libpng.txt
+files, in the individual makefiles, in png.h, and the manual pages
+libpng.3 and png.5.
diff --git a/Utilities/FLTK/png/KNOWNBUG b/Utilities/FLTK/png/KNOWNBUG
new file mode 100644
index 0000000000000000000000000000000000000000..53235270022687b76bcfb162618ad498ec98df80
--- /dev/null
+++ b/Utilities/FLTK/png/KNOWNBUG
@@ -0,0 +1,11 @@
+
+Known bugs in libpng version 1.2.7
+
+1. April 22, 2001: pnggccrd.c has been reported to crash on NetBSD when
+   reading interlaced PNG files, when assembler code is enabled but running
+   on a non-MMX i386 platform.
+
+   STATUS: Under investigation.  The change to pnggccrd.c in libpng-1.2.1
+   fixed a problem under FreeBSD but not the problem with NetBSD, which
+   still fails as of libpng-1.2.2rc1.
+
diff --git a/Utilities/FLTK/png/LICENSE b/Utilities/FLTK/png/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..3e5a36abb9675eb1a7af60dd93d78604f3a27e0f
--- /dev/null
+++ b/Utilities/FLTK/png/LICENSE
@@ -0,0 +1,109 @@
+
+This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng version 1.2.6, September 12, 2004, is
+Copyright (c) 2004 Glenn Randers-Pehrson, and is
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+   Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your enjoyment of the
+   library or against infringement.  There is no warranty that our
+   efforts or the library will fulfill any of your particular purposes
+   or needs.  This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and effort is with
+   the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+   be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+   source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products.  If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp@users.sourceforge.net
+September 12, 2004
diff --git a/Utilities/FLTK/png/Makefile b/Utilities/FLTK/png/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bdd48526fd470d6ad240cc8876e9f24f32962a79
--- /dev/null
+++ b/Utilities/FLTK/png/Makefile
@@ -0,0 +1,107 @@
+#
+# "$Id: Makefile 4052 2005-02-24 21:55:12Z mike $"
+#
+# PNG library makefile for the Fast Light Toolkit (FLTK).
+#
+# Copyright 1997-2005 by Easy Software Products.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+include ../makeinclude
+
+#
+# Object files...
+#
+
+OBJS	=	png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+		pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+		pngwtran.o pngmem.o pngerror.o pngpread.o
+
+LIBPNG	=	../lib/libfltk_png$(LIBEXT)
+
+
+#
+# Make all of the targets...
+#
+
+all:	$(LIBPNG)
+
+
+#
+# Clean all of the targets and object files...
+#
+
+clean:
+	$(RM) $(OBJS)
+	$(RM) $(LIBPNG)
+
+
+#
+# Install everything...
+#
+
+install: $(LIBPNG)
+	echo "Installing libfltk_png$(LIBEXT) in $(libdir)..."
+	-$(MKDIR) $(libdir)
+	$(RM) $(libdir)/libfltk_png$(LIBEXT)
+	$(CP) $(LIBPNG) $(libdir)
+	$(RANLIB) $(libdir)/libfltk_png$(LIBEXT)
+	echo "Installing png headers in $(includedir)/FL/images..."
+	-$(MKDIR) $(includedir)/FL/images
+	$(CP) png.h pngconf.h $(includedir)/FL/images
+
+
+#
+# Uninstall everything...
+#
+
+uninstall:
+	echo "Uninstalling libfltk_png$(LIBEXT) in $(libdir)..."
+	$(RM) $(libdir)/libfltk_png$(LIBEXT)
+	echo "Uninstalling png headers in $(includedir)/FL/images..."
+	$(RM) $(includedir)/FL/images/png.h
+	$(RM) $(includedir)/FL/images/pngconf.h
+
+
+#
+# libfltk_png.a
+#
+
+$(LIBPNG):	$(OBJS)
+	echo Archiving $@...
+	$(RM) $@
+	$(LIBCOMMAND) $@ $(OBJS)
+	$(RANLIB) $@
+
+
+#
+# Make dependencies...
+#
+
+depend:	$(OBJS:.o=.c)
+	makedepend -Y -I.. -f makedepend $(OBJS:.o=.c)
+
+include makedepend
+
+$(OBJS):	../makeinclude
+
+
+#
+# End of "$Id: Makefile 4052 2005-02-24 21:55:12Z mike $".
+#
diff --git a/Utilities/FLTK/png/README b/Utilities/FLTK/png/README
new file mode 100644
index 0000000000000000000000000000000000000000..7109660f138c697b653539dbf9edf5f04aad0ac1
--- /dev/null
+++ b/Utilities/FLTK/png/README
@@ -0,0 +1,260 @@
+README for libpng version 1.2.7 - September 12, 2004 (shared library 12.0)
+See the note about version numbers near the top of png.h
+
+See INSTALL for instructions on how to install libpng.
+
+Libpng comes in several distribution formats.  Get libpng-*.tar.gz
+or libpng-*.tar.bz2 if you want UNIX-style line endings in the text
+files, or lpng*.zip if you want DOS-style line endings.
+
+Version 0.89 was the first official release of libpng.  Don't let the
+fact that it's the first release fool you.  The libpng library has been in
+extensive use and testing since mid-1995.  By late 1997 it had
+finally gotten to the stage where there hadn't been significant
+changes to the API in some time, and people have a bad feeling about
+libraries with versions < 1.0.  Version 1.0.0 was released in
+March 1998.
+
+****
+Note that some of the changes to the png_info structure render this
+version of the library binary incompatible with libpng-0.89 or
+earlier versions if you are using a shared library.  The type of the
+"filler" parameter for png_set_filler() has changed from png_byte to
+png_uint_32, which will affect shared-library applications that use
+this function.
+
+To avoid problems with changes to the internals of png_info_struct,
+new APIs have been made available in 0.95 to avoid direct application
+access to info_ptr.  These functions are the png_set_<chunk> and
+png_get_<chunk> functions.  These functions should be used when
+accessing/storing the info_struct data, rather than manipulating it
+directly, to avoid such problems in the future.
+
+It is important to note that the APIs do not make current programs
+that access the info struct directly incompatible with the new
+library.  However, it is strongly suggested that new programs use
+the new APIs (as shown in example.c and pngtest.c), and older programs
+be converted to the new format, to facilitate upgrades in the future.
+****
+
+Additions since 0.90 include the ability to compile libpng as a
+Windows DLL, and new APIs for accessing data in the info struct.
+Experimental functions include the ability to set weighting and cost
+factors for row filter selection, direct reads of integers from buffers
+on big-endian processors that support misaligned data access, faster
+methods of doing alpha composition, and more accurate 16->8 bit color
+conversion.
+
+The additions since 0.89 include the ability to read from a PNG stream
+which has had some (or all) of the signature bytes read by the calling
+application.  This also allows the reading of embedded PNG streams that
+do not have the PNG file signature.  As well, it is now possible to set
+the library action on the detection of chunk CRC errors.  It is possible
+to set different actions based on whether the CRC error occurred in a
+critical or an ancillary chunk.
+
+The changes made to the library, and bugs fixed are based on discussions
+on the PNG-implement mailing list
+and not on material submitted privately to Guy, Andreas, or Glenn.  They will
+forward any good suggestions to the list.
+
+For a detailed description on using libpng, read libpng.txt.  For
+examples of libpng in a program, see example.c and pngtest.c.  For usage
+information and restrictions (what little they are) on libpng, see
+png.h.  For a description on using zlib (the compression library used by
+libpng) and zlib's restrictions, see zlib.h
+
+I have included a general makefile, as well as several machine and
+compiler specific ones, but you may have to modify one for your own needs.
+
+You should use zlib 1.0.4 or later to run this, but it MAY work with
+versions as old as zlib 0.95.  Even so, there are bugs in older zlib
+versions which can cause the output of invalid compression streams for
+some images.  You will definitely need zlib 1.0.4 or later if you are
+taking advantage of the MS-DOS "far" structure allocation for the small
+and medium memory models.  You should also note that zlib is a
+compression library that is useful for more things than just PNG files.
+You can use zlib as a drop-in replacement for fread() and fwrite() if
+you are so inclined.
+
+zlib should be available at the same place that libpng is, or at.
+ftp://ftp.info-zip.org/pub/infozip/zlib
+
+You may also want a copy of the PNG specification.  It is available
+as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
+these at http://www.libpng.org/pub/png/documents/
+
+This code is currently being archived at libpng.sf.net in the
+[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT)
+at GO GRAPHSUP.  If you can't find it in any of those places,
+e-mail me, and I'll help you find it.
+
+If you have any code changes, requests, problems, etc., please e-mail
+them to me.  Also, I'd appreciate any make files or project files,
+and any modifications you needed to make to get libpng to compile,
+along with a #define variable to tell what compiler/system you are on.
+If you needed to add transformations to libpng, or wish libpng would
+provide the image in a different way, drop me a note (and code, if
+possible), so I can consider supporting the transformation.
+Finally, if you get any warning messages when compiling libpng
+(note: not zlib), and they are easy to fix, I'd appreciate the
+fix.  Please mention "libpng" somewhere in the subject line.  Thanks.
+
+This release was created and will be supported by myself (of course
+based in a large way on Guy's and Andreas' earlier work), and the PNG group.
+
+glennrp@users.sourceforge.net
+png-implement@ccrc.wustl.edu (subscription required; write to
+majordomo@ccrc.wustl.edu with "subscribe png-implement" in the message).
+
+You can't reach Guy, the original libpng author, at the addresses
+given in previous versions of this document.  He and Andreas will read mail
+addressed to the png-implement list, however.
+
+Please do not send general questions about PNG.  Send them to
+the (png-list@ccrc.wustl.edu, subscription required, write to
+majordomo@ccrc.wustl.edu with "subscribe png-list" in your message).
+On the other hand,
+please do not send libpng questions to that address, send them to me
+or to the png-implement list.  I'll
+get them in the end anyway.  If you have a question about something
+in the PNG specification that is related to using libpng, send it
+to me.  Send me any questions that start with "I was using libpng,
+and ...".  If in doubt, send questions to me.  I'll bounce them
+to others, if necessary.
+
+Please do not send suggestions on how to change PNG.  We have
+been discussing PNG for nine years now, and it is official and
+finished.  If you have suggestions for libpng, however, I'll
+gladly listen.  Even if your suggestion is not used immediately,
+it may be used later.
+
+Files in this distribution:
+
+      ANNOUNCE      =>  Announcement of this version, with recent changes
+      CHANGES       =>  Description of changes between libpng versions
+      KNOWNBUG      =>  List of known bugs and deficiencies
+      LICENSE       =>  License to use and redistribute libpng
+      README        =>  This file
+      TODO          =>  Things not implemented in the current library
+      Y2KINFO       =>  Statement of Y2K compliance
+      example.c     =>  Example code for using libpng functions
+      libpng.3      =>  manual page for libpng (includes libpng.txt)
+      libpng.txt    =>  Description of libpng and its functions
+      libpngpf.3    =>  manual page for libpng's private functions
+      png.5         =>  manual page for the PNG format
+      png.c         =>  Basic interface functions common to library
+      png.h         =>  Library function and interface declarations
+      pngconf.h     =>  System specific library configuration
+      pngasmrd.h    =>  Header file for assembler-coded functions
+      pngerror.c    =>  Error/warning message I/O functions
+      pngget.c      =>  Functions for retrieving info from struct
+      pngmem.c      =>  Memory handling functions
+      pngbar.png    =>  PNG logo, 88x31
+      pngnow.png    =>  PNG logo, 98x31
+      pngpread.c    =>  Progressive reading functions
+      pngread.c     =>  Read data/helper high-level functions
+      pngrio.c      =>  Lowest-level data read I/O functions
+      pngrtran.c    =>  Read data transformation functions
+      pngrutil.c    =>  Read data utility functions
+      pngset.c      =>  Functions for storing data into the info_struct
+      pngtest.c     =>  Library test program
+      pngtest.png   =>  Library test sample image
+      pngtrans.c    =>  Common data transformation functions
+      pngwio.c      =>  Lowest-level write I/O functions
+      pngwrite.c    =>  High-level write functions
+      pngwtran.c    =>  Write data transformations
+      pngwutil.c    =>  Write utility functions
+      contrib       =>  Contributions
+       gregbook         =>  source code for PNG reading and writing, from
+                            Greg Roelofs' "PNG: The Definitive Guide",
+                            O'Reilly, 1999
+       msvctest     =>  Builds and runs pngtest using a MSVC workspace
+       pngminus     =>  Simple pnm2png and png2pnm programs
+       pngsuite     =>  Test images
+       visupng      =>  Contains a MSVC workspace for VisualPng
+      projects      =>  Contains project files and workspaces for building DLL
+       beos             =>  Contains a Beos workspace for building libpng
+       c5builder        =>  Contains a Borland workspace for building libpng
+                            and zlib
+       visualc6         =>  Contains a Microsoft Visual C++ (MSVC) workspace
+                            for building libpng and zlib
+       netware.txt      =>  Contains instructions for downloading a set of
+                            project files for building libpng and zlib on
+                            Netware.
+       wince.txt        =>  Contains instructions for downloading a Microsoft
+                            Visual C++ (Windows CD Toolkit) workspace for
+                            building libpng and zlib on WindowsCE
+      scripts       =>  Directory containing scripts for building libpng:
+       descrip.mms      =>  VMS makefile for MMS or MMK
+       makefile.std     =>  Generic UNIX makefile (cc, creates static libpng.a)
+       makefile.linux   =>  Linux/ELF makefile
+                            (gcc, creates libpng12.so.0.1.2.7)
+       makefile.gcmmx   =>  Linux/ELF makefile
+                            (gcc, creates libpng12.so.0.1.2.7,
+                            uses assembler code tuned for Intel MMX platform)
+       makefile.gcc     =>  Generic makefile (gcc, creates static libpng.a)
+       makefile.knr     =>  Archaic UNIX Makefile that converts files with
+                            ansi2knr (Requires ansi2knr.c from
+                            ftp://ftp.cs.wisc.edu/ghost)
+       makefile.aix     =>  AIX makefile
+       makefile.cygwin  =>  Cygwin/gcc makefile
+       makefile.darwin  =>  Darwin makefile
+       makefile.dec     =>  DEC Alpha UNIX makefile
+       makefile.freebsd =>  FreeBSD makefile
+       makefile.hpgcc   =>  HPUX makefile using gcc
+       makefile.hpux    =>  HPUX (10.20 and 11.00) makefile
+       makefile.hp64    =>  HPUX (10.20 and 11.00) makefile, 64 bit
+       makefile.ibmc    =>  IBM C/C++ version 3.x for Win32 and OS/2 (static)
+       makefile.intel   =>  Intel C/C++ version 4.0 and later
+       libpng.icc       =>  Project file, IBM VisualAge/C++ 4.0 or later
+       makefile.netbsd  =>  NetBSD/cc makefile, PNGGCCRD, makes libpng.so.
+       makefile.ne12bsd  =>  NetBSD/cc makefile, PNGGCCRD, makes libpng12.so
+       makefile.openbsd =>  OpenBSD makefile
+       makefile.sgi     =>  Silicon Graphics IRIX (cc, creates static lib)
+       makefile.sggcc   =>  Silicon Graphics
+                            (gcc, creates libpng12.so.0.1.2.7)
+       makefile.sunos   =>  Sun makefile
+       makefile.solaris =>  Solaris 2.X makefile
+                            (gcc, creates libpng12.so.0.1.2.7)
+       makefile.so9     =>  Solaris 9 makefile
+                            (gcc, creates libpng12.so.0.1.2.7)
+       makefile.32sunu  =>  Sun Ultra 32-bit makefile
+       makefile.64sunu  =>  Sun Ultra 64-bit makefile
+       makefile.sco     =>  For SCO OSr5  ELF and Unixware 7 with Native cc
+       makefile.mips    =>  MIPS makefile
+       makefile.acorn   =>  Acorn makefile
+       makefile.amiga   =>  Amiga makefile
+       smakefile.ppc    =>  AMIGA smakefile for SAS C V6.58/7.00 PPC
+                            compiler (Requires SCOPTIONS, copied from
+                            scripts/SCOPTIONS.ppc)
+       makefile.atari   =>  Atari makefile
+       makefile.beos    =>  BEOS makefile for X86
+       makefile.bor     =>  Borland makefile (uses bcc)
+       makefile.bc32    =>  32-bit Borland C++ (all modules compiled in C mode)
+       makefile.tc3     =>  Turbo C 3.0 makefile
+       makefile.dj2     =>  DJGPP 2 makefile
+       makefile.msc     =>  Microsoft C makefile
+       makefile.vcawin32=>  makefile for Microsoft Visual C++ 5.0 and
+                            later (uses assembler code tuned for Intel MMX
+                            platform)
+       makefile.vcwin32 =>  makefile for Microsoft Visual C++ 4.0 and
+                            later (does not use assembler code)
+       makefile.os2     =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
+       pngos2.def       =>  OS/2 module definition file used by makefile.os2
+       makefile.watcom  =>  Watcom 10a+ Makefile, 32-bit flat memory model
+       makevms.com      =>  VMS build script
+       SCOPTIONS.ppc    =>  Used with smakefile.ppc
+
+Good luck, and happy coding.
+
+-Glenn Randers-Pehrson (current maintainer)
+ Internet: glennrp@users.sourceforge.net
+
+-Andreas Eric Dilger (former maintainer, 1996-1997)
+ Internet: adilger@enel.ucalgary.ca
+ Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
+
+-Guy Eric Schalnat (original author and former maintainer, 1995-1996)
+ (formerly of Group 42, Inc)
+ Internet: gschal@infinet.com
diff --git a/Utilities/FLTK/png/TODO b/Utilities/FLTK/png/TODO
new file mode 100644
index 0000000000000000000000000000000000000000..a5f639577dd6c4aceae5cb90e9c0beaa717e70fe
--- /dev/null
+++ b/Utilities/FLTK/png/TODO
@@ -0,0 +1,24 @@
+TODO - list of things to do for libpng:
+
+Final bug fixes.
+Improve API by hiding the png_struct and png_info structs.
+Finish work on the no-floating-point version (including gamma compensation)
+Better C++ wrapper/full C++ implementation?
+Fix problem with C++ and EXTERN "C".
+cHRM transformation.
+Improve setjmp/longjmp usage or remove it in favor of returning error codes.
+Add "grayscale->palette" transformation and "palette->grayscale" detection.
+Improved dithering.
+Multi-lingual error and warning message support.
+Complete sRGB transformation (presently it simply uses gamma=0.45455).
+Man pages for function calls.
+Better documentation.
+Better filter selection
+   (counting huffman bits/precompression?  filter inertia?  filter costs?).
+Histogram creation.
+Text conversion between different code pages (Latin-1 -> Mac and DOS).
+Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety?
+Build gamma tables using fixed point (and do away with floating point entirely).
+Use greater precision when changing to linear gamma for compositing against
+  background and doing rgb-to-gray transformation.
+Investigate pre-incremented loop counters and other loop constructions.
diff --git a/Utilities/FLTK/png/Y2KINFO b/Utilities/FLTK/png/Y2KINFO
new file mode 100644
index 0000000000000000000000000000000000000000..5d1f2f7ac9c7d19e018694f787e34d94630fb540
--- /dev/null
+++ b/Utilities/FLTK/png/Y2KINFO
@@ -0,0 +1,55 @@
+   Y2K compliance in libpng:
+   =========================
+
+      September 12, 2004
+
+      Since the PNG Development group is an ad-hoc body, we can't make
+      an official declaration.
+
+      This is your unofficial assurance that libpng from version 0.71 and
+      upward through 1.2.7 are Y2K compliant.  It is my belief that earlier
+      versions were also Y2K compliant.
+
+      Libpng only has three year fields.  One is a 2-byte unsigned integer
+      that will hold years up to 65535.  The other two hold the date in text
+      format, and will hold years up to 9999.
+
+      The integer is
+          "png_uint_16 year" in png_time_struct.
+
+      The strings are
+          "png_charp time_buffer" in png_struct and
+          "near_time_buffer", which is a local character string in png.c.
+
+      There are seven time-related functions:
+
+          png_convert_to_rfc_1123() in png.c
+            (formerly png_convert_to_rfc_1152() in error)
+          png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+          png_convert_from_time_t() in pngwrite.c
+          png_get_tIME() in pngget.c
+          png_handle_tIME() in pngrutil.c, called in pngread.c
+          png_set_tIME() in pngset.c
+          png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+      All appear to handle dates properly in a Y2K environment.  The
+      png_convert_from_time_t() function calls gmtime() to convert from system
+      clock time, which returns (year - 1900), which we properly convert to
+      the full 4-digit year.  There is a possibility that applications using
+      libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+      function, or that they are incorrectly passing only a 2-digit year
+      instead of "year - 1900" into the png_convert_from_struct_tm() function,
+      but this is not under our control.  The libpng documentation has always
+      stated that it works with 4-digit years, and the APIs have been
+      documented as such.
+
+      The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+      integer to hold the year, and can hold years as large as 65535.
+
+      zlib, upon which libpng depends, is also Y2K compliant.  It contains
+      no date-related code.
+
+
+         Glenn Randers-Pehrson
+         libpng maintainer
+         PNG Development Group
diff --git a/Utilities/FLTK/png/libpng.3 b/Utilities/FLTK/png/libpng.3
new file mode 100644
index 0000000000000000000000000000000000000000..0d4d82958f34f4ae159d35f1d19ea83962d8d032
--- /dev/null
+++ b/Utilities/FLTK/png/libpng.3
@@ -0,0 +1,4016 @@
+.TH LIBPNG 3 "September 12, 2004"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library 1.2.7
+.SH SYNOPSIS
+\fI\fB
+
+\fB#include <png.h>\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_charpp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_libpng_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr)
+
+\fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytepp png_get_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_chunk_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_user_height_max( png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_user_width_max (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_compression_buffer_size (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fB#if \fI!defined(PNG_1_0_X)
+
+\fBvoid png_set_add_alpha (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
+
+\fI\fB#endif
+
+\fI\fB
+
+\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fImask\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_fixed_point \fP\fIred\fP\fB, png_fixed_point \fIgreen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_unknown_chunk_location(png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_user_limits (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIuser_width_max\fP\fB, png_uint_32 \fIuser_height_max\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_buffer_size(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP
+
+\fI\fB
+
+.SH DESCRIPTION
+The
+.I libpng
+library supports encoding, decoding, and various manipulations of
+the Portable Network Graphics (PNG) format image files.  It uses the
+.IR zlib(3)
+compression library.
+Following is a copy of the libpng.txt file that accompanies libpng.
+.SH LIBPNG.TXT
+libpng.txt - A description on how to use and modify libpng
+
+ libpng version 1.2.7 - September 12, 2004
+ Updated and distributed by Glenn Randers-Pehrson
+ <glennrp@users.sourceforge.net>
+ Copyright (c) 1998-2004 Glenn Randers-Pehrson
+ For conditions of distribution and use, see copyright
+ notice in png.h.
+
+ based on:
+
+ libpng 1.0 beta 6  version 0.96 May 28, 1997
+ Updated and distributed by Andreas Dilger
+ Copyright (c) 1996, 1997 Andreas Dilger
+
+ libpng 1.0 beta 2 - version 0.88  January 26, 1996
+ For conditions of distribution and use, see copyright
+ notice in png.h. Copyright (c) 1995, 1996 Guy Eric
+ Schalnat, Group 42, Inc.
+
+ Updated/rewritten per request in the libpng FAQ
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
+
+.SH I. Introduction
+
+This file describes how to use and modify the PNG reference library
+(known as libpng) for your own use.  There are five sections to this
+file: introduction, structures, reading, writing, and modification and
+configuration notes for various special platforms.  In addition to this
+file, example.c is a good starting point for using the library, as
+it is heavily commented and should include everything most people
+will need.  We assume that libpng is already installed; see the
+INSTALL file for instructions on how to install libpng.
+
+Libpng was written as a companion to the PNG specification, as a way
+of reducing the amount of time and effort it takes to support the PNG
+file format in application programs.
+
+The PNG specification (second edition), November 2003, is available as
+a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at
+<http://www.w3.org/TR/2003/REC-PNG-20031110/
+The W3C and ISO documents have identical technical content.
+
+The PNG-1.2 specification is available at
+<http://www.libpng.org/pub/png/documents/>
+
+The PNG-1.0 specification is available
+as RFC 2083 <http://www.libpng.org/pub/png/documents/> and as a
+W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
+additional chunks are described in the special-purpose public chunks
+documents at <http://www.libpng.org/pub/png/documents/>.
+
+Other information
+about PNG, and the latest version of libpng, can be found at the PNG home
+page, <http://www.libpng.org/pub/png/>.
+
+Most users will not have to modify the library significantly; advanced
+users may want to modify it more.  All attempts were made to make it as
+complete as possible, while keeping the code easy to understand.
+Currently, this library only supports C.  Support for other languages
+is being considered.
+
+Libpng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
+to use.  The ultimate goal of libpng is to promote the acceptance of
+the PNG file format in whatever way possible.  While there is still
+work to be done (see the TODO file), libpng should cover the
+majority of the needs of its users.
+
+Libpng uses zlib for its compression and decompression of PNG files.
+Further information about zlib, and the latest version of zlib, can
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than PNG files, and can be used without libpng.
+See the documentation delivered with zlib for more details.
+You can usually find the source files for the zlib utility wherever you
+find the libpng source files.
+
+Libpng is thread safe, provided the threads are using different
+instances of the structures.  Each thread should have its own
+png_struct and png_info instances, and thus its own image.
+Libpng does not protect itself against two threads using the
+same instance of a structure.  Note: thread safety may be defeated
+by use of some of the MMX assembler code in pnggccrd.c, which is only
+compiled when the user defines PNG_THREAD_UNSAFE_OK.
+
+.SH II. Structures
+
+There are two main structures that are important to libpng, png_struct
+and png_info.  The first, png_struct, is an internal structure that
+will not, for the most part, be used by a user except as the first
+variable passed to every libpng function call.
+
+The png_info structure is designed to provide information about the
+PNG file.  At one time, the fields of png_info were intended to be
+directly accessible to the user.  However, this tended to cause problems
+with applications using dynamically loaded libraries, and as a result
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed.  The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order.  In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5.  Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
+
+The png.h header file is an invaluable reference for programming with libpng.
+And while I'm on the topic, make sure you include the libpng header file:
+
+#include <png.h>
+
+.SH III. Reading
+
+We'll now walk you through the possible functions to call when reading
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one.  See example.c and png.h for more detail.  While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+.SS Setup
+
+You will want to do the I/O initialization(*) before you get into libpng,
+so if it doesn't work, you don't have much to undo.  Of course, you
+will also want to insure that you are, in fact, dealing with a PNG
+file.  Libpng provides a simple check to see if a file is a PNG file.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 if the bytes match the corresponding
+bytes of the PNG signature, or nonzero otherwise.  Of course, the more bytes
+you pass in, the greater the accuracy of the prediction.
+
+If you are intending to keep the file pointer open for use in libpng,
+you must ensure you don't read more than 8 bytes from the beginning
+of the file, and you also have to make a call to png_set_sig_bytes_read()
+with the number of bytes you read from the beginning.  Libpng will
+then only check the bytes (if any) that your program didn't read.
+
+(*): If you are not using the standard I/O functions, you will need
+to replace them with custom functions.  See the discussion under
+Customizing libpng.
+
+
+    FILE *fp = fopen(file_name, "rb");
+    if (!fp)
+    {
+        return (ERROR);
+    }
+    fread(header, 1, number, fp);
+    is_png = !png_sig_cmp(header, 0, number);
+    if (!is_png)
+    {
+        return (NOT_PNG);
+    }
+
+
+Next, png_struct and png_info need to be allocated and initialized.  In
+order to ensure that the size of these structures is correct even with a
+dynamically linked libpng, there are functions to initialize and
+allocate the structures.  We also pass the library version, optional
+pointers to error handling functions, and a pointer to a data struct for
+use by the error functions, if necessary (the pointer and functions can
+be NULL if the default error handlers are to be used).  See the section
+on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
+
+    png_structp png_ptr = png_create_read_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr,
+           (png_infopp)NULL, (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    png_infop end_info = png_create_info_struct(png_ptr);
+    if (!end_info)
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+          (png_infopp)NULL);
+        return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_read_struct_2() instead of png_create_read_struct():
+
+    png_structp png_ptr = png_create_read_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+The error handling routines passed to png_create_read_struct()
+and the memory alloc/free routines passed to png_create_struct_2()
+are only necessary if you are not using the libpng supplied error
+handling and memory alloc/free functions.
+
+When libpng encounters an error, it expects to longjmp back
+to your routine.  Therefore, you will need to call setjmp and pass
+your png_jmpbuf(png_ptr).  If you read the file from different
+routines, you will need to update the jmpbuf field every time you enter
+a new routine that will call a png_*() function.
+
+See your documentation of setjmp/longjmp for your compiler for more
+information on setjmp/longjmp.  See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling.  If an error occurs, and libpng longjmp's
+back to your setjmp, you will want to call png_destroy_read_struct() to
+free any memory.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           &end_info);
+        fclose(fp);
+        return (ERROR);
+    }
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the input code.  The default for libpng is to
+use the C function fread().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  If you wish to handle reading data in another
+way, you need not call the png_init_io() function, but you must then
+implement the libpng I/O methods discussed in the Customizing Libpng
+section below.
+
+    png_init_io(png_ptr, fp);
+
+If you had previously opened the file and read any of the signature from
+the beginning in order to see if this was a PNG file, you need to let
+libpng know that there are some bytes missing from the start of the file.
+
+    png_set_sig_bytes(png_ptr, number);
+
+.SS Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+    read_chunk_callback(png_ptr ptr,
+         png_unknown_chunkp chunk);
+    {
+       /* The unknown chunk structure contains your
+          chunk data: */
+           png_byte name[5];
+           png_byte *data;
+           png_size_t size;
+       /* Note that libpng has already taken care of
+          the CRC handling */
+
+       /* put your code here.  Return one of the
+          following: */
+
+       return (-n); /* chunk had an error */
+       return (0); /* did not recognize */
+       return (n); /* success */
+    }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+        read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+    png_get_user_chunk_ptr(png_ptr);
+
+At this point, you can set up a callback function that will be
+called after each row has been read, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void read_row_callback(png_ptr ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "read_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_status_fn(png_ptr, read_row_callback);
+
+.SS Width and height limits
+
+The PNG specification allows the width and height of an image to be as
+large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
+Since very few applications really need to process such large images,
+we have imposed an arbitrary 1-million limit on rows and columns.
+Larger images will be rejected immediately with a png_error() call. If
+you wish to override this limit, you can use
+
+   png_set_user_limits(png_ptr, width_max, height_max);
+
+to set your own limits, or use width_max = height_max = 0x7fffffffL
+to allow all valid dimensions (libpng may reject some very large images
+anyway because of potential buffer overflow conditions).
+
+You should put this statement after you create the PNG structure and
+before calling png_read_info(), png_read_png(), or png_process_data().
+If you need to retrieve the limits that are being applied, use
+
+   width_max = png_get_user_width_max(png_ptr);
+   height_max = png_get_user_height_max(png_ptr);
+
+.SS Unknown-chunk handling
+
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read.  Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members; unknown chunks will be discarded. To change
+this, you can call:
+
+    png_set_keep_unknown_chunks(png_ptr, keep,
+        chunk_list, num_chunks);
+    keep       - 0: do not handle as unknown
+                 1: do not keep
+                 2: keep only if safe-to-copy
+                 3: keep even if unsafe-to-copy
+               You can use these definitions:
+                 PNG_HANDLE_CHUNK_AS_DEFAULT   0
+                 PNG_HANDLE_CHUNK_NEVER        1
+                 PNG_HANDLE_CHUNK_IF_SAFE      2
+                 PNG_HANDLE_CHUNK_ALWAYS       3
+    chunk_list - list of chunks affected (a byte string,
+                 five bytes per chunk, NULL or '\0' if
+                 num_chunks is 0)
+    num_chunks - number of chunks affected; if 0, all
+                 unknown chunks are affected.  If nonzero,
+                 only the chunks in the list are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures.  If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive.  If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.  The IHDR and IEND chunks should not be named in
+chunk_list; if they are, libpng will process them normally anyway.
+
+.SS The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to
+                                8 bits
+    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
+    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit
+                                samples to bytes
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_EXPAND        Perform set_expand()
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.)  If this is the case, simply do this:
+
+    png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of
+some set of transformation flags.  This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform mask,
+then png_read_image(), and finally png_read_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future input transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_read_png().
+
+After you have called png_read_png(), you can retrieve the image data
+with
+
+   row_pointers = png_get_rows(png_ptr, info_ptr);
+
+where row_pointers is an array of pointers to the pixel data for each row:
+
+   png_bytep row_pointers[height];
+
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+   if (height > PNG_UINT_32_MAX/png_sizeof(png_byte))
+      png_error (png_ptr,
+         "Image is too tall to process in memory");
+   if (width > PNG_UINT_32_MAX/pixel_size)
+      png_error (png_ptr,
+         "Image is too wide to process in memory");
+   row_pointers = png_malloc(png_ptr,
+      height*png_sizeof(png_bytep));
+   for (int i=0; i<height, i++)
+      row_pointers[i]=png_malloc(png_ptr,
+         width*pixel_size);
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
+
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
+
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+.SS The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data.  You do this with a
+call to png_read_info().
+
+    png_read_info(png_ptr, info_ptr);
+
+This will process all chunks up to but not including the image data.
+
+.SS Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read.  Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
+
+    png_get_IHDR(png_ptr, info_ptr, &width, &height,
+       &bit_depth, &color_type, &interlace_type,
+       &compression_type, &filter_method);
+
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.  (valid values are
+                     1, 2, 4, 8, 16 and depend also on
+                     the color_type.  See also
+                     significant bits (sBIT) below).
+    color_type     - describes which color/alpha channels
+                         are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    filter_method  - (must be PNG_FILTER_TYPE_BASE
+                     for PNG 1.0, and can also be
+                     PNG_INTRAPIXEL_DIFFERENCING if
+                     the PNG datastream is embedded in
+                     a MNG-1.0 datastream)
+    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
+                     for PNG 1.0)
+    interlace_type - (PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7)
+    Any or all of interlace_type, compression_type, of
+    filter_method can be NULL if you are
+    not interested in their values.
+
+    channels = png_get_channels(png_ptr, info_ptr);
+    channels       - number of channels of info for the
+                     color type (valid values are 1 (GRAY,
+                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
+                     4 (RGB_ALPHA or RGB + filler byte))
+    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+    rowbytes       - number of bytes needed to hold a row
+
+    signature = png_get_signature(png_ptr, info_ptr);
+    signature      - holds the signature read from the
+                     file (if any).  The data is kept in
+                     the same offset it would be if the
+                     whole signature were read (i.e. if an
+                     application had already read in 4
+                     bytes of signature before starting
+                     libpng, the remaining 4 bytes would
+                     be in signature[4] through signature[7]
+                     (see png_set_sig_bytes())).
+
+
+    width            = png_get_image_width(png_ptr,
+                         info_ptr);
+    height           = png_get_image_height(png_ptr,
+                         info_ptr);
+    bit_depth        = png_get_bit_depth(png_ptr,
+                         info_ptr);
+    color_type       = png_get_color_type(png_ptr,
+                         info_ptr);
+    filter_method    = png_get_filter_type(png_ptr,
+                         info_ptr);
+    compression_type = png_get_compression_type(png_ptr,
+                         info_ptr);
+    interlace_type   = png_get_interlace_type(png_ptr,
+                         info_ptr);
+
+
+These are also important, but their validity depends on whether the chunk
+has been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
+png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
+data has been read, or zero if it is missing.  The parameters to the
+png_get_<chunk> are set directly if they are simple data types, or a pointer
+into the info_ptr is returned for any complex types.
+
+    png_get_PLTE(png_ptr, info_ptr, &palette,
+                     &num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_get_gAMA(png_ptr, info_ptr, &gamma);
+    gamma          - the gamma the file is written
+                     at (PNG_INFO_gAMA)
+
+    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
+    srgb_intent    - the rendering intent (PNG_INFO_sRGB)
+                     The presence of the sRGB chunk
+                     means that the pixel data is in the
+                     sRGB color space.  This chunk also
+                     implies specific values of gAMA and
+                     cHRM.
+
+    png_get_iCCP(png_ptr, info_ptr, &name,
+       &compression_type, &profile, &proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray,
+                     red, green, and blue channels,
+                     whichever are appropriate for the
+                     given color type (png_color_16)
+
+    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
+                     &trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_get_hIST(png_ptr, info_ptr, &hist);
+                     (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_get_tIME(png_ptr, info_ptr, &mod_time);
+    mod_time       - time image was last modified
+                    (PNG_VALID_tIME)
+
+    png_get_bKGD(png_ptr, info_ptr, &background);
+    background     - background color (PNG_VALID_bKGD)
+                     valid 16-bit red, green and blue
+                     values, regardless of color_type
+
+    num_comments   = png_get_text(png_ptr, info_ptr,
+                     &text_ptr, &num_text);
+    num_comments   - number of comments
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                         1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (empty
+                         string for unknown).
+    text_ptr[i].lang_key  - keyword in UTF-8
+                         (empty string for unknown).
+    num_text       - number of comments (same as
+                     num_comments; you can put NULL here
+                     to avoid the duplication)
+    Note while png_set_text() will accept text, language,
+    and translated keywords that can be NULL pointers, the
+    structure returned by png_get_text will always contain
+    regular zero-terminated C strings.  They might be
+    empty strings but they will never be NULL pointers.
+
+    num_spalettes = png_get_sPLT(png_ptr, info_ptr,
+       &palette_ptr);
+    palette_ptr    - array of palette structures holding
+                     contents of one or more sPLT chunks
+                     read.
+    num_spalettes  - number of sPLT chunks read.
+
+    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
+       &unit_type);
+    offset_x       - positive offset from the left edge
+                     of the screen
+    offset_y       - positive offset from the top edge
+                     of the screen
+    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
+       &unit_type);
+    res_x          - pixels/unit physical resolution in
+                     x direction
+    res_y          - pixels/unit physical resolution in
+                     x direction
+    unit_type      - PNG_RESOLUTION_UNKNOWN,
+                     PNG_RESOLUTION_METER
+
+    png_get_sCAL(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are doubles)
+
+    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    num_unknown_chunks = png_get_unknown_chunks(png_ptr,
+       info_ptr, &unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position of chunk in file
+
+    The value of "i" corresponds to the order in which the
+    chunks were read from the PNG file or inserted with the
+    png_set_unknown_chunks() function.
+
+The data from the pHYs chunk can be retrieved in several convenient
+forms:
+
+    res_x = png_get_x_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x = png_get_x_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_inch(png_ptr,
+       info_ptr)
+    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
+       info_ptr)
+
+   (Each of these returns 0 [signifying "unknown"] if
+       the data is not present or if res_x is 0;
+       res_x_and_y is 0 if res_x != res_y)
+
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+   (Each of these returns 0 [signifying "unknown" if both
+       x and y are 0] if the data is not present or if the
+       chunk is present but the unit is the pixel)
+
+For more information, see the png_info definition in png.h and the
+PNG specification for chunk contents.  Be careful with trusting
+rowbytes, as some of the transformations could increase the space
+needed to hold a row (expand, filler, gray_to_rgb, etc.).
+See png_read_update_info(), below.
+
+A quick word about text_ptr and num_text.  PNG stores comments in
+keyword/text pairs, one pair per chunk, with no limit on the number
+of text chunks, and a 2^31 byte limit on their size.  While there are
+suggested keywords, there is no requirement to restrict the use to these
+strings.  It is strongly suggested that keywords and text be sensible
+to humans (that's the point), so don't use abbreviations.  Non-printing
+symbols are not allowed.  See the PNG specification for more details.
+There is also no requirement to have text after the keyword.
+
+Keywords should be limited to 79 Latin-1 characters without leading or
+trailing spaces, but non-consecutive spaces are allowed within the
+keyword.  It is possible to have the same keyword any number of times.
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string.  The text string, language code, and translated
+keyword may be empty or NULL pointers.  The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image.  This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+.SS Input transformations
+
+After you've read the header information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+The colors used for the background and transparency values should be
+supplied in the same format/depth as the current image data.  They
+are stored in the same format/depth as the image data in a bKGD or tRNS
+chunk, so this is what libpng expects for this data.  The colors are
+transformed to keep in sync with the image data when an application
+calls the png_read_update_info() routine (see below).
+
+Data will be decoded into the supplied row buffers packed into bytes
+unless the library has been told to transform it into another format.
+For example, 4 bit/pixel paletted or grayscale data will be returned
+2 pixels/byte with the leftmost pixel in the high-order bits of the
+byte, unless png_set_packing() is called.  8-bit RGB data will be stored
+in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha()
+is called to insert filler bytes, either before or after each RGB triplet.
+16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant
+byte of the color value first, unless png_set_strip_16() is called to
+transform it to regular RGB RGB triplets, or png_set_filler|add alpha()
+is called to insert filler bytes, either before or after each RRGGBB
+triplet.  Similarly, 8-bit or 16-bit grayscale data can be modified with
+png_set_filler(), png_set_add_alpha(), or png_set_strip_16().
+
+The following code transforms grayscale images of less than 8 to 8 bits,
+changes paletted images to RGB, and adds a full alpha channel if there is
+transparency information in a tRNS chunk.  This is most useful on
+grayscale images with bit depths of 2 or 4 or if there is a multiple-image
+viewing application that wishes to treat all images in the same way.
+
+    if (color_type == PNG_COLOR_TYPE_PALETTE)
+        png_set_palette_to_rgb(png_ptr);
+
+    if (color_type == PNG_COLOR_TYPE_GRAY &&
+        bit_depth < 8) png_set_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);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
+
+PNG can have files with 16 bits per channel.  If you only can handle
+8 bits per channel, this will strip the pixels down to 8 bit.
+
+    if (bit_depth == 16)
+        png_set_strip_16(png_ptr);
+
+If, for some reason, you don't need the alpha channel on an image,
+and you want to remove it rather than combining it with the background
+(but the image author certainly had in mind that you *would* combine
+it with the background, so that's what you should probably do):
+
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+        png_set_strip_alpha(png_ptr);
+
+In PNG files, the alpha channel in an image
+is the level of opacity.  If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transparent, with
+
+    png_set_invert_alpha(png_ptr);
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit
+files.  This code expands to 1 pixel per byte without changing the
+values of the pixels:
+
+    if (bit_depth < 8)
+        png_set_packing(png_ptr);
+
+PNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels
+stored in a PNG image have been "scaled" or "shifted" up to the next
+higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
+8 bits/sample in the range [0, 255]).  However, it is also possible to
+convert the PNG pixel data back to the original bit depth of the image.
+This call reduces the pixels back down to the original bit depth:
+
+    png_color_8p sig_bit;
+
+    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
+        png_set_shift(png_ptr, sig_bit);
+
+PNG files store 3-color pixels in red, green, blue order.  This code
+changes the storage of the pixels to blue, green, red:
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_bgr(png_ptr);
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them
+into 4 or 8 bytes for windowing systems that need them in this format:
+
+    if (color_type == PNG_COLOR_TYPE_RGB)
+        png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);
+
+where "filler" is the 8 or 16-bit number to fill with, and the location is
+either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
+you want the filler before the RGB or after.  This transformation
+does not affect images that already have full alpha channels.  To add an
+opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which
+will generate RGBA pixels.
+
+Note that png_set_filler() does not change the color type.  If you want
+to do that, you can add a true alpha channel with
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+           color_type == PNG_COLOR_TYPE_GRAY)
+    png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
+
+where "filler" contains the alpha value to assign to each pixel.
+This function became available in libpng-1.2.7.
+
+If you are reading an image with an alpha channel, and you need the
+data as ARGB instead of the normal PNG format RGBA:
+
+    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_swap_alpha(png_ptr);
+
+For some uses, you may want a grayscale image to be represented as
+RGB.  This code will do that conversion:
+
+    if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+          png_set_gray_to_rgb(png_ptr);
+
+Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
+with alpha.
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+          png_set_rgb_to_gray_fixed(png_ptr, error_action,
+             int red_weight, int green_weight);
+
+    error_action = 1: silently do the conversion
+    error_action = 2: issue a warning if the original
+                      image has any pixel where
+                      red != green or red != blue
+    error_action = 3: issue an error and abort the
+                      conversion if the original
+                      image has any pixel where
+                      red != green or red != blue
+
+    red_weight:       weight of red component times 100000
+    green_weight:     weight of green component times 100000
+                      If either weight is negative, default
+                      weights (21268, 71514) are used.
+
+If you have set error_action = 1 or 2, you can
+later check whether the image really was gray, after processing
+the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
+It will return a png_byte that is zero if the image was gray or
+1 if there were any non-gray pixels.  bKGD and sBIT data
+will be silently converted to grayscale, using the green channel
+data, regardless of the error_action setting.
+
+With red_weight+green_weight<=100000,
+the normalized graylevel is computed:
+
+    int rw = red_weight * 65536;
+    int gw = green_weight * 65536;
+    int bw = 65536 - (rw + gw);
+    gray = (rw*red + gw*green + bw*blue)/65536;
+
+The default values approximate those recommended in the Charles
+Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
+Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
+
+    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+
+Libpng approximates this with
+
+    Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
+
+which can be expressed with integers as
+
+    Y = (6969 * R + 23434 * G + 2365 * B)/32768
+
+The calculation is done in a linear colorspace, if the image gamma
+is known.
+
+If you have a grayscale and you are using png_set_expand_depth(),
+png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to
+a higher bit-depth, you must either supply the background color as a gray
+value at the original file bit-depth (need_expand = 1) or else supply the
+background color as an RGB triplet at the final, expanded bit depth
+(need_expand = 0).  Similarly, if you are reading a paletted image, you
+must either supply the background color as a palette index (need_expand = 1)
+or as an RGB triplet that may or may not be in the palette (need_expand = 0).
+
+    png_color_16 my_background;
+    png_color_16p image_background;
+
+    if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+        png_set_background(png_ptr, image_background,
+          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+    else
+        png_set_background(png_ptr, &my_background,
+          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page).  You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
+To properly display PNG images on any kind of system, the application needs
+to know what the display gamma is.  Ideally, the user will know this, and
+the application will allow them to set it.  One method of allowing the user
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment.  In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+   double gamma, screen_gamma;
+
+   if (/* We have a user-defined screen
+       gamma value */)
+   {
+      screen_gamma = user_defined_screen_gamma;
+   }
+   /* One way that applications can share the same
+      screen gamma value */
+   else if ((gamma_str = getenv("SCREEN_GAMMA"))
+      != NULL)
+   {
+      screen_gamma = (double)atof(gamma_str);
+   }
+   /* If we don't have another value */
+   else
+   {
+      screen_gamma = 2.2; /* A good guess for a
+           PC monitor in a bright office or a dim room */
+      screen_gamma = 2.0; /* A good guess for a
+           PC monitor in a dark room */
+      screen_gamma = 1.7 or 1.0;  /* A good
+           guess for Mac systems */
+   }
+
+The png_set_gamma() function handles gamma transformations of the data.
+Pass both the file gamma and the current screen_gamma.  If the file does
+not have a gamma value, you can pass one anyway if you have an idea what
+it is (usually 0.45455 is a good guess for GIF images on PCs).  Note
+that file gammas are inverted from screen gammas.  See the discussions
+on gamma in the PNG specification for an excellent description of what
+gamma is, and why all applications should support it.  It is strongly
+recommended that PNG viewers support gamma correction.
+
+   if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+      png_set_gamma(png_ptr, screen_gamma, gamma);
+   else
+      png_set_gamma(png_ptr, screen_gamma, 0.45455);
+
+If you need to reduce an RGB file to a paletted file, or if a paletted
+file has more entries then will fit on your screen, png_set_dither()
+will do that.  Note that this is a simple match dither that merely
+finds the closest color available.  This should work fairly well with
+optimized palettes, and fairly badly with linear color cubes.  If you
+pass a palette that is larger then maximum_colors, the file will
+reduce the number of colors in the palette so it will fit into
+maximum_colors.  If there is a histogram, it will use it to make
+more intelligent choices when reducing the palette.  If there is no
+histogram, it may not do as good a job.
+
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      if (png_get_valid(png_ptr, info_ptr,
+         PNG_INFO_PLTE))
+      {
+         png_uint_16p histogram = NULL;
+
+         png_get_hIST(png_ptr, info_ptr,
+            &histogram);
+         png_set_dither(png_ptr, palette, num_palette,
+            max_screen_colors, histogram, 1);
+      }
+      else
+      {
+         png_color std_color_cube[MAX_SCREEN_COLORS] =
+            { ... colors ... };
+
+         png_set_dither(png_ptr, std_color_cube,
+            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
+            NULL,0);
+      }
+   }
+
+PNG files describe monochrome as black being zero and white being one.
+The following code will reverse this (make black be one and white be
+zero):
+
+   if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)
+      png_set_invert_mono(png_ptr);
+
+This function can also be used to invert grayscale and gray-alpha images:
+
+   if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      png_set_invert_mono(png_ptr);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code changes the storage to the
+other way (little-endian, i.e. least significant bits first, the
+way PCs store them):
+
+    if (bit_depth == 16)
+        png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_read_user_transform_fn(png_ptr,
+       read_transform_fn);
+
+You must supply the function
+
+    void read_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+The last thing to handle is interlacing; this is covered in detail below,
+but you must call the function here if you want libpng to handle expansion
+of the interlaced image.
+
+    number_of_passes = png_set_interlace_handling(png_ptr);
+
+After setting the transformations, libpng can update your png_info
+structure to reflect any transformations you've requested with this
+call.  This is most useful to update the info structure's rowbytes
+field so you can use it to allocate your image memory.  This function
+will also update your palette with the correct screen_gamma and
+background if these have been given with the calls above.
+
+    png_read_update_info(png_ptr, info_ptr);
+
+After you call png_read_update_info(), you can allocate any
+memory you need to hold the image.  The row data is simply
+raw byte data for all forms of images.  As the actual allocation
+varies among applications, no example will be given.  If you
+are allocating one large chunk, you will need to build an
+array of pointers to each row, as it will be needed for some
+of the functions below.
+
+.SS Reading image data
+
+After you've allocated memory, you can read the image data.
+The simplest way to do this is in one function call.  If you are
+allocating enough memory to hold the whole image, you can just
+call png_read_image() and libpng will read in all the image data
+and put it in the memory area supplied.  You will need to pass in
+an array of pointers to each row.
+
+This function automatically handles interlacing, so you don't need
+to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_read_rows().
+
+   png_read_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+   png_bytep row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to read in the whole image at once, you can
+use png_read_rows() instead.  If there is no interlacing (check
+interlace_type == PNG_INTERLACE_NONE), this is simple:
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+where row_pointers is the same as in the png_read_image() call.
+
+If you are doing this just one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+    png_read_row(png_ptr, row_pointer, NULL);
+
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder.  The only current (PNG Specification version 1.2)
+interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
+is a somewhat complicated 2D interlace scheme, known as Adam7, that
+breaks down an image into seven smaller images of varying size, based
+on an 8x8 grid.
+
+libpng can fill out those images or it can give them to you "as is".
+If you want them filled out, there are two ways to do that.  The one
+mentioned in the PNG specification is to expand each pixel to cover
+those pixels that have not been read yet (the "rectangle" method).
+This results in a blocky image for the first pass, which gradually
+smooths out as more pixels are read.  The other method is the "sparkle"
+method, where pixels are drawn only in their final locations, with the
+rest of the image remaining whatever colors they were initialized to
+before the start of the read.  The first method usually looks better,
+but tends to be slower, as there are more pixels to put in the rows.
+
+If you don't want libpng to handle the interlacing details, just call
+png_read_rows() seven times to read in all seven images.  Each of the
+images is a valid image by itself, or they can all be combined on an
+8x8 grid to form a single image (although if you intend to combine them
+you would be far better off using the libpng interlace handling).
+
+The first pass will return an image 1/8 as wide as the entire image
+(every 8th column starting in column 0) and 1/8 as high as the original
+(every 8th row starting in row 0), the second will be 1/8 as wide
+(starting in column 4) and 1/8 as high (also starting in row 0).  The
+third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
+1/8 as high (every 8th row starting in row 4), and the fourth pass will
+be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
+and every 4th row starting in row 0).  The fifth pass will return an
+image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
+while the sixth pass will be 1/2 as wide and 1/2 as high as the original
+(starting in column 1 and row 0).  The seventh and final pass will be as
+wide as the original, and 1/2 as high, containing all of the odd
+numbered scanlines.  Phew!
+
+If you want libpng to expand the images, call this before calling
+png_start_read_image() or png_read_update_info():
+
+    if (interlace_type == PNG_INTERLACE_ADAM7)
+        number_of_passes
+           = png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+This function can be called even if the file is not interlaced,
+where it will return one pass.
+
+If you are not going to display the image after each pass, but are
+going to wait until the entire image is read in, use the sparkle
+effect.  This effect is faster and the end result of either method
+is exactly the same.  If you are planning on displaying the image
+after each pass, the "rectangle" effect is generally considered the
+better looking one.
+
+If you only want the "sparkle" effect, just call png_read_rows() as
+normal, with the third parameter NULL.  Make sure you make pass over
+the image number_of_passes times, and you don't change the data in the
+rows between calls.  You can change the locations of the data, just
+not the data.  Each pass only writes the pixels appropriate for that
+pass, and assumes the data from previous passes is still valid.
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+If you only want the first effect (the rectangles), do the same as
+before except pass the row buffer in the third parameter, and leave
+the second parameter NULL.
+
+    png_read_rows(png_ptr, NULL, row_pointers,
+       number_of_rows);
+
+.SS Finishing a sequential read
+
+After you are finished reading the image through either the high- or
+low-level interfaces, you can finish reading the file.  If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate.  If you are not interested, you can pass NULL.
+
+   png_read_end(png_ptr, end_info);
+
+When you are done, you can free all memory allocated by libpng like this:
+
+   png_destroy_read_struct(&png_ptr, &info_ptr,
+       &end_info);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask - identifies data to be freed, a mask
+           containing the logical OR of one or
+           more of
+             PNG_FREE_PLTE, PNG_FREE_TRNS,
+             PNG_FREE_HIST, PNG_FREE_ICCP,
+             PNG_FREE_PCAL, PNG_FREE_ROWS,
+             PNG_FREE_SCAL, PNG_FREE_SPLT,
+             PNG_FREE_TEXT, PNG_FREE_UNKN,
+           or simply PNG_FREE_ALL
+    seq  - sequence number of item to be freed
+           (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng,  and will in those
+cases do nothing.  The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data.  When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees.  If you need to turn the flag off for a chunk that was freed by your
+application instead of by libpng, you can use
+
+    png_set_invalid(png_ptr, info_ptr, mask);
+    mask - identifies the chunks to be made invalid,
+           containing the logical OR of one or
+           more of
+             PNG_INFO_gAMA, PNG_INFO_sBIT,
+             PNG_INFO_cHRM, PNG_INFO_PLTE,
+             PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_hIST, PNG_INFO_pHYs,
+             PNG_INFO_oFFs, PNG_INFO_tIME,
+             PNG_INFO_pCAL, PNG_INFO_sRGB,
+             PNG_INFO_iCCP, PNG_INFO_sPLT,
+             PNG_INFO_sCAL, PNG_INFO_IDAT
+
+For a more compact example of reading a PNG image, see the file example.c.
+
+.SS Reading PNG files progressively
+
+The progressive reader is slightly different then the non-progressive
+reader.  Instead of calling png_read_info(), png_read_rows(), and
+png_read_end(), you make one call to png_process_data(), which calls
+callbacks when it has the info, a row, or the end of the image.  You
+set up these callbacks with png_set_progressive_read_fn().  You don't
+have to worry about the input/output functions of libpng, as you are
+giving the library the data directly in png_process_data().  I will
+assume that you have read the section on reading PNG files above,
+so I will only highlight the differences (although I will show
+all of the code).
+
+png_structp png_ptr;
+png_infop info_ptr;
+
+ /*  An example code fragment of how you would
+     initialize the progressive reader in your
+     application. */
+ int
+ initialize_png_reader()
+ {
+    png_ptr = png_create_read_struct
+        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+         user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+    info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new.  You can provide functions
+       to be called when the header info is valid,
+       when each row is completed, and when the image
+       is finished.  If you aren't using all functions,
+       you can specify NULL parameters.  Even when all
+       three functions are NULL, you need to call
+       png_set_progressive_read_fn().  You can use
+       any struct as the user_ptr (cast to a void pointer
+       for the function call), and retrieve the pointer
+       from inside the callbacks using the function
+
+          png_get_progressive_ptr(png_ptr);
+
+       which will return a void pointer, which you have
+       to cast appropriately.
+     */
+    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
+        info_callback, row_callback, end_callback);
+
+    return 0;
+ }
+
+ /* A code fragment that you call as you receive blocks
+   of data */
+ int
+ process_data(png_bytep buffer, png_uint_32 length)
+ {
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new also.  Simply give it a chunk
+       of data from the file stream (in order, of
+       course).  On machines with segmented memory
+       models machines, don't give it any more than
+       64K.  The library seems to run fine with sizes
+       of 4K. Although you can give it much less if
+       necessary (I assume you can give it chunks of
+       1 byte, I haven't tried less then 256 bytes
+       yet).  When this function returns, you may
+       want to display any rows that were generated
+       in the row callback if you don't already do
+       so there.
+     */
+    png_process_data(png_ptr, info_ptr, buffer, length);
+    return 0;
+ }
+
+ /* This function is called (as set by
+    png_set_progressive_read_fn() above) when enough data
+    has been supplied so all of the header has been
+    read.
+ */
+ void
+ info_callback(png_structp png_ptr, png_infop info)
+ {
+    /* Do any setup here, including setting any of
+       the transformations mentioned in the Reading
+       PNG files section.  For now, you _must_ call
+       either png_start_read_image() or
+       png_read_update_info() after all the
+       transformations are set (even if you don't set
+       any).  You may start getting rows before
+       png_process_data() returns, so this is your
+       last chance to prepare for that.
+     */
+ }
+
+ /* This function is called when each row of image
+    data is complete */
+ void
+ row_callback(png_structp png_ptr, png_bytep new_row,
+    png_uint_32 row_num, int pass)
+ {
+    /* If the image is interlaced, and you turned
+       on the interlace handler, this function will
+       be called for every row in every pass.  Some
+       of these rows will not be changed from the
+       previous pass.  When the row is not changed,
+       the new_row variable will be NULL.  The rows
+       and passes are called in order, so you don't
+       really need the row_num and pass, but I'm
+       supplying them because it may make your life
+       easier.
+
+       For the non-NULL rows of interlaced images,
+       you must call png_progressive_combine_row()
+       passing in the row and the old row.  You can
+       call this function for NULL rows (it will just
+       return) and for non-interlaced images (it just
+       does the memcpy for you) if it will make the
+       code easier.  Thus, you can just do this for
+       all cases:
+     */
+
+        png_progressive_combine_row(png_ptr, old_row,
+          new_row);
+
+    /* where old_row is what was displayed for
+       previously for the row.  Note that the first
+       pass (pass == 0, really) will completely cover
+       the old row, so the rows do not have to be
+       initialized.  After the first pass (and only
+       for interlaced images), you will have to pass
+       the current row, and the function will combine
+       the old row and the new row.
+    */
+ }
+
+ void
+ end_callback(png_structp png_ptr, png_infop info)
+ {
+    /* This function is called after the whole image
+       has been read, including any chunks after the
+       image (up to and including the IEND).  You
+       will usually have the same info chunk as you
+       had in the header, although some data may have
+       been added to the comments and time fields.
+
+       Most people won't do much here, perhaps setting
+       a flag that marks the image as finished.
+     */
+ }
+
+
+
+.SH IV. Writing
+
+Much of this is very similar to reading.  However, everything of
+importance is repeated here, so you won't have to constantly look
+back up in the reading section to understand writing.
+
+.SS Setup
+
+You will want to do the I/O initialization before you get into libpng,
+so if it doesn't work, you don't have anything to undo. If you are not
+using the standard I/O functions, you will need to replace them with
+custom writing functions.  See the discussion under Customizing libpng.
+
+    FILE *fp = fopen(file_name, "wb");
+    if (!fp)
+    {
+       return (ERROR);
+    }
+
+Next, png_struct and png_info need to be allocated and initialized.
+As these can be both relatively large, you may not want to store these
+on the stack, unless you have stack space to spare.  Of course, you
+will want to check if they return NULL.  If you are also reading,
+you won't want to name your read structure and your write structure
+both "png_ptr"; you can call them anything you like, such as
+"read_ptr" and "write_ptr".  Look at pngtest.c, for example.
+
+    png_structp png_ptr = png_create_write_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+       return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+       png_destroy_write_struct(&png_ptr,
+         (png_infopp)NULL);
+       return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_write_struct_2() instead of png_create_write_struct():
+
+    png_structp png_ptr = png_create_write_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+After you have these structures, you will need to set up the
+error handling.  When libpng encounters an error, it expects to
+longjmp() back to your routine.  Therefore, you will need to call
+setjmp() and pass the png_jmpbuf(png_ptr).  If you
+write the file from different routines, you will need to update
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function.  See your documentation of setjmp/longjmp
+for your compiler for more information on setjmp/longjmp.  See
+the discussion on libpng error handling in the Customizing Libpng
+section below for more information on the libpng error handling.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+       png_destroy_write_struct(&png_ptr, &info_ptr);
+       fclose(fp);
+       return (ERROR);
+    }
+    ...
+    return;
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the output code.  The default for libpng is to
+use the C function fwrite().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  Again, if you wish to handle writing data in
+another way, see the discussion on libpng I/O handling in the Customizing
+Libpng section below.
+
+    png_init_io(png_ptr, fp);
+
+.SS Write callbacks
+
+At this point, you can set up a callback function that will be
+called after each row has been written, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void write_row_callback(png_ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "write_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_write_status_fn(png_ptr, write_row_callback);
+
+You now have the option of modifying how the compression library will
+run.  The following functions are mainly for testing, but may be useful
+in some cases, like if you need to write PNG files extremely fast and
+are willing to give up some compression, or if you want to get the
+maximum possible compression at the expense of slower writing.  If you
+have no special needs in this area, let the library do what it wants by
+not calling this function at all, as it has been tuned to deliver a good
+speed/compression ratio. The second parameter to png_set_filter() is
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream).  The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline.  See the PNG specification for details on the specific filter
+types.
+
+
+    /* turn on or off filtering, and/or choose
+       specific filters.  You can use either a single
+       PNG_FILTER_VALUE_NAME or the logical OR of one
+       or more PNG_FILTER_NAME masks. */
+    png_set_filter(png_ptr, 0,
+       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
+       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
+       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
+       PNG_FILTER_AVE   | PNG_FILTER_VALUE_AVE  |
+       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+       PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
+
+The png_set_compression_*() functions interface to the zlib compression
+library, and should mostly be ignored unless you really know what you are
+doing.  The only generally useful call is png_set_compression_level()
+which changes how much time zlib spends on trying to compress the image
+data.  See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
+
+    /* set the zlib compression level */
+    png_set_compression_level(png_ptr,
+        Z_BEST_COMPRESSION);
+
+    /* set other zlib parameters */
+    png_set_compression_mem_level(png_ptr, 8);
+    png_set_compression_strategy(png_ptr,
+        Z_DEFAULT_STRATEGY);
+    png_set_compression_window_bits(png_ptr, 15);
+    png_set_compression_method(png_ptr, 8);
+    png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+.SS Setting the contents of info for output
+
+You now need to fill in the png_info structure with all the data you
+wish to write before the actual image.  Note that the only thing you
+are allowed to write after the image is the text chunks and the time
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
+the latest PNG specification for more information on that.  If you
+wish to write them before the image, fill them in now, and flag that
+data as being valid.  If you want to wait until after the data, don't
+fill them until png_write_end().  For all the fields in png_info and
+their data types, see png.h.  For explanations of what the fields
+contain, see the PNG specification.
+
+Some of the more important parts of the png_info are:
+
+    png_set_IHDR(png_ptr, info_ptr, width, height,
+       bit_depth, color_type, interlace_type,
+       compression_type, filter_method)
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.
+                     (valid values are 1, 2, 4, 8, 16
+                     and depend also on the
+                     color_type.  See also significant
+                     bits (sBIT) below).
+    color_type     - describes which color/alpha
+                     channels are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    interlace_type - PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7
+    compression_type - (must be
+                     PNG_COMPRESSION_TYPE_DEFAULT)
+    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT
+                     or, if you are writing a PNG to
+                     be embedded in a MNG datastream,
+                     can also be
+                     PNG_INTRAPIXEL_DIFFERENCING)
+
+    png_set_PLTE(png_ptr, info_ptr, palette,
+       num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_set_gAMA(png_ptr, info_ptr, gamma);
+    gamma          - the gamma the image was created
+                     at (PNG_INFO_gAMA)
+
+    png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of
+                     the sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This chunk also implies specific
+                     values of gAMA and cHRM.  Rendering
+                     intent is the CSS-1 property that
+                     has been defined by the International
+                     Color Consortium
+                     (http://www.color.org).
+                     It can be one of
+                     PNG_sRGB_INTENT_SATURATION,
+                     PNG_sRGB_INTENT_PERCEPTUAL,
+                     PNG_sRGB_INTENT_ABSOLUTE, or
+                     PNG_sRGB_INTENT_RELATIVE.
+
+
+    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
+       srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of the
+                     sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This function also causes gAMA and
+                     cHRM chunks with the specific values
+                     that are consistent with sRGB to be
+                     written.
+
+    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+                      profile, proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_set_sBIT(png_ptr, info_ptr, sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray, red,
+                     green, and blue channels, whichever are
+                     appropriate for the given color type
+                     (png_color_16)
+
+    png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
+       trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_set_hIST(png_ptr, info_ptr, hist);
+                    (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_set_tIME(png_ptr, info_ptr, mod_time);
+    mod_time       - time image was last modified
+                     (PNG_VALID_tIME)
+
+    png_set_bKGD(png_ptr, info_ptr, background);
+    background     - background color (PNG_VALID_bKGD)
+
+    png_set_text(png_ptr, info_ptr, text_ptr, num_text);
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                 1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be NULL or empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (NULL or
+                         empty for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
+                         or empty for unknown).
+    num_text       - number of comments
+
+    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
+       num_spalettes);
+    palette_ptr    - array of png_sPLT_struct structures
+                     to be added to the list of palettes
+                     in the info structure.
+    num_spalettes  - number of palette structures to be
+                     added.
+
+    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
+        unit_type);
+    offset_x  - positive offset from the left
+                     edge of the screen
+    offset_y  - positive offset from the top
+                     edge of the screen
+    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
+        unit_type);
+    res_x       - pixels/unit physical resolution
+                  in x direction
+    res_y       - pixels/unit physical resolution
+                  in y direction
+    unit_type   - PNG_RESOLUTION_UNKNOWN,
+                  PNG_RESOLUTION_METER
+
+    png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                  (width and height are doubles)
+
+    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,
+       num_unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position to write chunk in file
+                           0: do not write chunk
+                           PNG_HAVE_IHDR: before PLTE
+                           PNG_HAVE_PLTE: before IDAT
+                           PNG_AFTER_IDAT: after IDAT
+
+The "location" member is set automatically according to
+what part of the output file has already been written.
+You can change its value after calling png_set_unknown_chunks()
+as demonstrated in pngtest.c.  Within each of the "locations",
+the chunks are sequenced according to their position in the
+structure (that is, the value of "i", which is the order in which
+the chunk was either read from the input file or defined with
+png_set_unknown_chunks).
+
+A quick word about text and num_text.  text is an array of png_text
+structures.  num_text is the number of valid structures in the array.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
+The compression types have the same valid numbers as the compression
+types of the image data.  Currently, the only valid number is zero.
+However, you can store text either compressed or uncompressed, unlike
+images, which always have to be compressed.  So if you don't want the
+text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
+Until text gets around 1000 bytes, it is not worth compressing it.
+After the text has been written out to the file, the compression type
+is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
+so that it isn't written out again at the end (in case you are calling
+png_write_end() with the same struct.
+
+The keywords that are given in the PNG Specification are:
+
+    Title            Short (one line) title or
+                     caption for image
+    Author           Name of image's creator
+    Description      Description of image (possibly long)
+    Copyright        Copyright notice
+    Creation Time    Time of original image creation
+                     (usually RFC 1123 format, see below)
+    Software         Software used to create the image
+    Disclaimer       Legal disclaimer
+    Warning          Warning of nature of content
+    Source           Device used to create the image
+    Comment          Miscellaneous comment; conversion
+                     from other image format
+
+The keyword-text pairs work like this.  Keywords should be short
+simple descriptions of what the comment is about.  Some typical
+keywords are found in the PNG specification, as is some recommendations
+on keywords.  You can repeat keywords in a file.  You can even write
+some text before the image and some after.  For example, you may want
+to put a description of the image before the image, but leave the
+disclaimer until after, so viewers working over modem connections
+don't have to wait for the disclaimer to go over the modem before
+they start seeing the image.  Finally, keywords should be full
+words, not abbreviations.  Keywords and text are in the ISO 8859-1
+(Latin-1) character set (a superset of regular ASCII) and can not
+contain NUL characters, and should not contain control or other
+unprintable characters.  To make the comments widely readable, stick
+with basic ASCII, and avoid machine specific character set extensions
+like the IBM-PC character set.  The keyword must be present, but
+you can leave off the text string on non-compressed pairs.
+Compressed pairs must have a text string, as only the text string
+is compressed anyway, so the compression would be meaningless.
+
+PNG supports modification time via the png_time structure.  Two
+conversion routines are provided, png_convert_from_time_t() for
+time_t and png_convert_from_struct_tm() for struct tm.  The
+time_t routine uses gmtime().  You don't have to use either of
+these, but if you wish to fill in the png_time structure directly,
+you should provide the time in universal time (GMT) if possible
+instead of your local time.  Note that the year number is the full
+year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
+that months start with 1.
+
+If you want to store the time of the original image creation, you should
+use a plain tEXt chunk with the "Creation Time" keyword.  This is
+necessary because the "creation time" of a PNG image is somewhat vague,
+depending on whether you mean the PNG file, the time the image was
+created in a non-PNG format, a still photo from which the image was
+scanned, or possibly the subject matter itself.  In order to facilitate
+machine-readable dates, it is recommended that the "Creation Time"
+tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
+although this isn't a requirement.  Unlike the tIME chunk, the
+"Creation Time" tEXt chunk is not expected to be automatically changed
+by the software.  To facilitate the use of RFC 1123 dates, a function
+png_convert_to_rfc1123(png_timep) is provided to convert from PNG
+time to an RFC 1123 format string.
+
+.SS Writing unknown chunks
+
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing.  You give it a chunk name, raw data, and a size; that's
+all there is to it.  The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+.SS The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure.  All defined output
+transformations are permitted, enabled by the following masks.
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+    PNG_TRANSFORM_STRIP_FILLER  Strip out filler bytes.
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+    png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of some set of
+transformation flags.  This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform mask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future output transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_write_png().
+
+.SS The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data.  You do
+this with a call to png_write_info().
+
+    png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info().  In PNG files, the alpha channel in an image is the
+level of opacity.  If your data is supplied as a level of
+transparency, you can invert the alpha channel before you write it, so
+that 0 is fully transparent and 255 (in 8-bit or paletted images) or
+65535 (in 16-bit images) is fully opaque, with
+
+    png_set_invert_alpha(png_ptr);
+
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written.  If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+    png_write_info_before_PLTE(png_ptr, info_ptr);
+    png_set_unknown_chunks(png_ptr, info_ptr, ...);
+    png_write_info(png_ptr, info_ptr);
+
+After you've written the file information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+PNG files store RGB pixels packed into 3 or 6 bytes.  This code tells
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
+
+    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit files.
+If the data is supplied at 1 pixel per byte, use this code, which will
+correctly pack the pixels into a single byte:
+
+    png_set_packing(png_ptr);
+
+PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
+data is of another bit depth, you can write an sBIT chunk into the
+file so that decoders can recover the original data if desired.
+
+    /* Set the true bit depth of the image data */
+    if (color_type & PNG_COLOR_MASK_COLOR)
+    {
+        sig_bit.red = true_bit_depth;
+        sig_bit.green = true_bit_depth;
+        sig_bit.blue = true_bit_depth;
+    }
+    else
+    {
+        sig_bit.gray = true_bit_depth;
+    }
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+    {
+        sig_bit.alpha = true_bit_depth;
+    }
+
+    png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+If the data is stored in the row buffer in a bit depth other than
+one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
+this will scale the values to appear to be the correct bit depth as
+is required by PNG.
+
+    png_set_shift(png_ptr, &sig_bit);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code would be used if they are
+supplied the other way (little-endian, i.e. least significant bits
+first, the way PCs store them):
+
+    if (bit_depth > 8)
+       png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+PNG files store 3 color pixels in red, green, blue order.  This code
+would be used if they are supplied as blue, green, red:
+
+    png_set_bgr(png_ptr);
+
+PNG files describe monochrome as black being zero and white being
+one. This code would be used if the pixels are supplied with this reversed
+(black being one and white being zero):
+
+    png_set_invert_mono(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_write_user_transform_fn(png_ptr,
+       write_transform_fn);
+
+You must supply the function
+
+    void write_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+It is possible to have libpng flush any pending output, either manually,
+or automatically after a certain number of lines have been written.  To
+flush the output stream a single time call:
+
+    png_write_flush(png_ptr);
+
+and to have libpng flush the output stream periodically after a certain
+number of scanlines have been written, call:
+
+    png_set_flush(png_ptr, nrows);
+
+Note that the distance between rows is from the last time png_write_flush()
+was called, or the first row of the image if it has never been called.
+So if you write 50 lines, and then png_set_flush 25, it will flush the
+output on the next scanline, and every 25 lines thereafter, unless
+png_write_flush() is called before 25 more lines have been written.
+If nrows is too small (less than about 10 lines for a 640 pixel wide
+RGB image) the image compression may decrease noticeably (although this
+may be acceptable for real-time applications).  Infrequent flushing will
+only degrade the compression performance by a few percent over images
+that do not use flushing.
+
+.SS Writing the image data
+
+That's it for the transformations.  Now you can write the image data.
+The simplest way to do this is in one function call.  If you have the
+whole image in memory, you can just call png_write_image() and libpng
+will write the image.  You will need to pass in an array of pointers to
+each row.  This function automatically handles interlacing, so you don't
+need to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_write_rows().
+
+    png_write_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+    png_byte *row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to write the whole image at once, you can
+use png_write_rows() instead.  If the file is not interlaced,
+this is simple:
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+row_pointers is the same as in the png_write_image() call.
+
+If you are just writing one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+
+    png_write_row(png_ptr, row_pointer);
+
+When the file is interlaced, things can get a good deal more
+complicated.  The only currently (as of the PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
+is the "Adam7" interlace scheme, that breaks down an
+image into seven smaller images of varying size.  libpng will build
+these images for you, or you can do them yourself.  If you want to
+build them yourself, see the PNG specification for details of which
+pixels to write when.
+
+If you don't want libpng to handle the interlacing details, just
+use png_set_interlace_handling() and call png_write_rows() the
+correct number of times to write all seven sub-images.
+
+If you want libpng to build the sub-images, call this before you start
+writing any rows:
+
+    number_of_passes =
+       png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+
+Then write the complete image number_of_passes times.
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+As some of these rows are not used, and thus return immediately,
+you may want to read about interlacing in the PNG specification,
+and only update the rows that are actually used.
+
+.SS Finishing a sequential write
+
+After you are finished writing the image, you should finish writing
+the file.  If you are interested in writing comments or time, you should
+pass an appropriately filled png_info pointer.  If you are not interested,
+you can pass NULL.
+
+    png_write_end(png_ptr, info_ptr);
+
+When you are done, you can free all memory used by libpng like this:
+
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask  - identifies data to be freed, a mask
+            containing the logical OR of one or
+            more of
+              PNG_FREE_PLTE, PNG_FREE_TRNS,
+              PNG_FREE_HIST, PNG_FREE_ICCP,
+              PNG_FREE_PCAL, PNG_FREE_ROWS,
+              PNG_FREE_SCAL, PNG_FREE_SPLT,
+              PNG_FREE_TEXT, PNG_FREE_UNKN,
+            or simply PNG_FREE_ALL
+    seq   - sequence number of item to be freed
+            (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user  and not by libpng,  and will in those
+cases do nothing.  The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+If you allocated data such as a palette that you passed
+in to libpng with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+    png_data_freer(read_ptr, read_info_ptr,
+       PNG_USER_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+    png_data_freer(write_ptr, write_info_ptr,
+       PNG_DESTROY_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function.  Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+For a more compact example of writing a PNG image, see the file example.c.
+
+.SH V. Modifying/Customizing libpng:
+
+There are three issues here.  The first is changing how libpng does
+standard things like memory allocation, input/output, and error handling.
+The second deals with more complicated things like adding new chunks,
+adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them.  The third is a
+run-time issue:  choosing between and/or tuning one or more alternate
+versions of computationally intensive routines; specifically, optimized
+assembly-language (and therefore compiler- and platform-dependent)
+versions.
+
+Memory allocation, input/output, and error handling
+
+All of the memory allocation, input/output, and error handling in libpng
+goes through callbacks that are user-settable.  The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc()
+and png_free().  These currently just call the standard C functions.  If
+your pointers can't access more then 64K at a time, you will want to set
+MAXSEG_64K in zlib.h.  Since it is unlikely that the method of handling
+memory allocation on a platform will change between applications, these
+functions must be modified in the library at compile time.  If you prefer
+to use a different method of allocating and freeing data, you can use
+png_create_read_struct_2() or png_create_write_struct_2() to register
+your own functions as described above.
+These functions also provide a void pointer that can be retrieved via
+
+    mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your replacement memory functions must have prototypes as follows:
+
+    png_voidp malloc_fn(png_structp png_ptr,
+       png_size_t size);
+    void free_fn(png_structp png_ptr, png_voidp ptr);
+
+Your malloc_fn() must return NULL in case of failure.  The png_malloc()
+function will normally call png_error() if it receives a NULL from the
+system memory allocator or from your replacement malloc_fn().
+
+Input/Output in libpng is done through png_read() and png_write(),
+which currently just call fread() and fwrite().  The FILE * is stored in
+png_struct and is initialized via png_init_io().  If you wish to change
+the method of I/O, the library supplies callbacks that you can set
+through the function png_set_read_fn() and png_set_write_fn() at run
+time, instead of calling the png_init_io() function.  These functions
+also provide a void pointer that can be retrieved via the function
+png_get_io_ptr().  For example:
+
+    png_set_read_fn(png_structp read_ptr,
+        voidp read_io_ptr, png_rw_ptr read_data_fn)
+
+    png_set_write_fn(png_structp write_ptr,
+        voidp write_io_ptr, png_rw_ptr write_data_fn,
+        png_flush_ptr output_flush_fn);
+
+    voidp read_io_ptr = png_get_io_ptr(read_ptr);
+    voidp write_io_ptr = png_get_io_ptr(write_ptr);
+
+The replacement I/O functions must have prototypes as follows:
+
+    void user_read_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_write_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_flush_data(png_structp png_ptr);
+
+Supplying NULL for the read, write, or flush functions sets them back
+to using the default C stream functions.  It is an error to read from
+a write stream, and vice versa.
+
+Error handling in libpng is done through png_error() and png_warning().
+Errors handled through png_error() are fatal, meaning that png_error()
+should never return to its caller.  Currently, this is handled via
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
+to print a warning message, and then control returns to the calling code.
+By default png_error() and png_warning() print a message on stderr via
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available).  If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks.  These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own replacement
+functions after png_create_*_struct() has been called by calling:
+
+    png_set_error_fn(png_structp png_ptr,
+        png_voidp error_ptr, png_error_ptr error_fn,
+        png_error_ptr warning_fn);
+
+    png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
+If NULL is supplied for either error_fn or warning_fn, then the libpng
+default function will be used, calling fprintf() and/or longjmp() if a
+problem is encountered.  The replacement error functions should have
+parameters as follows:
+
+    void user_error_fn(png_structp png_ptr,
+        png_const_charp error_msg);
+    void user_warning_fn(png_structp png_ptr,
+        png_const_charp warning_msg);
+
+The motivation behind using setjmp() and longjmp() is the C++ throw and
+catch exception handling methods.  This makes the code much easier to write,
+as there is no need to check every return code of every function call.
+However, there are some uncertainties about the status of local variables
+after a longjmp, so the user may want to be careful about doing anything after
+setjmp returns non-zero besides returning itself.  Consult your compiler
+documentation for more details.  For an alternative approach, you may wish
+to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+.SS Custom chunks
+
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code.  The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks.  Hoewver, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of
+understanding of how it works.  Pay particular attention to the
+sections that describe chunk names, and look at how other chunks were
+designed, so you can do things similarly.  Second, check out the
+sections of libpng that read and write chunks.  Try to find a chunk
+that is similar to yours and use it as a template.  More details can
+be found in the comments inside the code.  It is best to handle unknown
+chunks in a generic method, via callback functions, instead of by
+modifying libpng functions.
+
+If you wish to write your own transformation for the data, look through
+the part of the code that does the transformations, and check out some of
+the simpler ones to get an idea of how they work.  Try to find a similar
+transformation to the one you want to add and copy off of it.  More details
+can be found in the comments inside the code itself.
+
+.SS Configuring for 16 bit platforms
+
+You will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time.  Even if you can, the memory
+won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+.SS Configuring for DOS
+
+For DOS users who only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call.  See zlib.h or zconf.h in the zlib library for more information.
+
+.SS Configuring for Medium Model
+
+Libpng's support for medium model has been tested on most of the popular
+compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set.  Everything in the library (except for zlib's structure) is
+expecting far data.  You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful).  Make
+note that the rows of data are defined as png_bytepp, which is an
+unsigned char far * far *.
+
+.SS Configuring for gui/windowing platforms:
+
+You will need to write new error and warning functions that use the GUI
+interface, as described previously, and set them to be the error and
+warning functions at the time that png_create_*_struct() is called,
+in order to have them available during the structure initialization.
+They can be changed later via png_set_error_fn().  On some compilers,
+you may also have to change the memory allocators (png_malloc, etc.).
+
+.SS Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h.  If you need to add/change/delete
+an include, this is the place to do it.  The includes that are not
+needed outside libpng are protected by the PNG_INTERNAL definition,
+which is only defined for those routines inside libpng itself.  The
+files in libpng proper only include png.h, which includes pngconf.h.
+
+.SS Configuring zlib:
+
+There are special functions to configure the compression.  Perhaps the
+most useful one changes the compression level, which currently uses
+input compression values in the range 0 - 9.  The library normally
+uses the default compression level (Z_DEFAULT_COMPRESSION = 6).  Tests
+have shown that for a large majority of images, compression values in
+the range 3-6 compress nearly as well as higher levels, and do so much
+faster.  For online applications it may be desirable to have maximum speed
+(Z_BEST_SPEED = 1).  With versions of zlib after v0.99, you can also
+specify no compression (Z_NO_COMPRESSION = 0), but this would create
+files larger than just storing the raw bitmap.  You can specify the
+compression level by calling:
+
+    png_set_compression_level(png_ptr, level);
+
+Another useful one is to reduce the memory level used by the library.
+The memory level defaults to 8, but it can be lowered if you are
+short on memory (running DOS, for example, where you only have 640K).
+Note that the memory level does have an effect on compression; among
+other things, lower levels will result in sections of incompressible
+data being emitted in smaller stored blocks, with a correspondingly
+larger relative overhead of up to 15% in the worst case.
+
+    png_set_compression_mem_level(png_ptr, level);
+
+The other functions are for configuring zlib.  They are not recommended
+for normal use and may result in writing an invalid PNG file.  See
+zlib.h for more information on what these mean.
+
+    png_set_compression_strategy(png_ptr,
+        strategy);
+    png_set_compression_window_bits(png_ptr,
+        window_bits);
+    png_set_compression_method(png_ptr, method);
+    png_set_compression_buffer_size(png_ptr, size);
+
+.SS Controlling row filtering
+
+If you want to control whether libpng uses filtering or not, which
+filters are used, and how it goes about picking row filters, you
+can call one of these functions.  The selection and configuration
+of row filters can have a significant impact on the size and
+encoding speed and a somewhat lesser impact on the decoding speed
+of an image.  Filtering is enabled by default for RGB and grayscale
+images (with and without alpha), but not for paletted images nor
+for any images with bit depths less than 8 bits/pixel.
+
+The 'method' parameter sets the main filtering method, which is
+currently only '0' in the PNG 1.2 specification.  The 'filters'
+parameter sets which filter(s), if any, should be used for each
+scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
+to turn filtering on and off, respectively.
+
+Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
+PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.
+If you intend to change the filter type during the course of writing
+the image, you should start with flags set for all of the filters
+you intend to use so that libpng can initialize its internal
+structures appropriately for all of the filter types.  (Note that this
+means the first row must always be adaptively filtered, because libpng
+currently does not allocate the filter buffers until png_write_row()
+is called for the first time.)
+
+    filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+              PNG_FILTER_UP | PNG_FILTER_AVE |
+              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+
+    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
+       filters);
+              The second parameter can also be
+              PNG_INTRAPIXEL_DIFFERENCING if you are
+              writing a PNG to be embedded in a MNG
+              datastream.  This parameter must be the
+              same as the value of filter_method used
+              in png_set_IHDR().
+
+It is also possible to influence how libpng chooses from among the
+available filters.  This is done in one or both of two ways - by
+telling it how important it is to keep the same filter for successive
+rows, and by telling it the relative computational costs of the filters.
+
+    double weights[3] = {1.5, 1.3, 1.1},
+       costs[PNG_FILTER_VALUE_LAST] =
+       {1.0, 1.3, 1.3, 1.5, 1.7};
+
+    png_set_filter_heuristics(png_ptr,
+       PNG_FILTER_HEURISTIC_WEIGHTED, 3,
+       weights, costs);
+
+The weights are multiplying factors that indicate to libpng that the
+row filter should be the same for successive rows unless another row filter
+is that many times better than the previous filter.  In the above example,
+if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
+"sum of absolute differences" 1.5 x 1.3 times higher than other filters
+and still be chosen, while the NONE filter could have a sum 1.1 times
+higher than other filters and still be chosen.  Unspecified weights are
+taken to be 1.0, and the specified weights should probably be declining
+like those above in order to emphasize recent filters over older filters.
+
+The filter costs specify for each filter type a relative decoding cost
+to be considered when selecting row filters.  This means that filters
+with higher costs are less likely to be chosen over filters with lower
+costs, unless their "sum of absolute differences" is that much smaller.
+The costs do not necessarily reflect the exact computational speeds of
+the various filters, since this would unduly influence the final image
+size.
+
+Note that the numbers above were invented purely for this example and
+are given only to help explain the function usage.  Little testing has
+been done to find optimum values for either the costs or the weights.
+
+.SS Removing unwanted object code
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled.  All the defines end in _SUPPORTED.  If you are
+never going to use a capability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space, or
+you can turn off individual capabilities with defines that begin with
+PNG_NO_.
+
+You can also turn all of the transforms and ancillary chunk capabilities
+off en masse with compiler directives that define
+PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
+or all four,
+along with directives to turn on any of the capabilities that you do
+want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
+the extra transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks
+Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
+produces a library that is incapable of reading or writing ancillary chunks.
+If you are not using the progressive reading capability, you can
+turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse
+this with the INTERLACING capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs.  However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with pngr and all the writing files start with
+pngw.  The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections that are actually used will be loaded into memory.
+
+.SS Requesting debug printout
+
+The macro definition PNG_DEBUG can be used to request debugging
+printout.  Set it to an integer value in the range 0 to 3.  Higher
+numbers result in increasing amounts of debugging information.  The
+information is printed to the "stderr" file, unless another file
+name is specified in the PNG_DEBUG_FILE macro definition.
+
+When PNG_DEBUG > 0, the following functions (macros) become available:
+
+   png_debug(level, message)
+   png_debug1(level, message, p1)
+   png_debug2(level, message, p1, p2)
+
+in which "level" is compared to PNG_DEBUG to decide whether to print
+the message, "message" is the formatted string to be printed,
+and p1 and p2 are parameters that are to be embedded in the string
+according to printf-style formatting directives.  For example,
+
+   png_debug1(2, "foo=%d\n", foo);
+
+is expanded to
+
+   if(PNG_DEBUG > 2)
+     fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
+
+When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
+can still use PNG_DEBUG to control your own debugging:
+
+   #ifdef PNG_DEBUG
+       fprintf(stderr, ...
+   #endif
+
+When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
+having level = 0 will be printed.  There aren't any such statements in
+this version of libpng, but if you insert some they will be printed.
+
+.SH VI.  Runtime optimization
+
+A new feature in libpng 1.2.0 is the ability to dynamically switch between
+standard and optimized versions of some routines.  Currently these are
+limited to three computationally intensive tasks when reading PNG files:
+decoding row filters, expanding interlacing, and combining interlaced or
+transparent row data with previous row data.  Currently the optimized
+versions are available only for x86 (Intel, AMD, etc.) platforms with
+MMX support, though this may change in future versions.  (For example,
+the non-MMX assembler optimizations for zlib might become similarly
+runtime-selectable in future releases, in which case libpng could be
+extended to support them.  Alternatively, the compile-time choice of
+floating-point versus integer routines for gamma correction might become
+runtime-selectable.)
+
+Because such optimizations tend to be very platform- and compiler-dependent,
+both in how they are written and in how they perform, the new runtime code
+in libpng has been written to allow programs to query, enable, and disable
+either specific optimizations or all such optimizations.  For example, to
+enable all possible optimizations (bearing in mind that some "optimizations"
+may actually run more slowly in rare cases):
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       png_uint_32 mask, flags;
+
+       flags = png_get_asm_flags(png_ptr);
+       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+       png_set_asm_flags(png_ptr, flags | mask);
+    #endif
+
+To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ
+by itself when calling png_get_asm_flagmask(); similarly for optimizing
+only writing.  To disable all optimizations:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       flags = png_get_asm_flags(png_ptr);
+       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+       png_set_asm_flags(png_ptr, flags & ~mask);
+    #endif
+
+To enable or disable only MMX-related features, use png_get_mmx_flagmask()
+in place of png_get_asm_flagmask().  The mmx version takes one additional
+parameter:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
+       int compilerID;
+
+       mask = png_get_mmx_flagmask(selection, &compilerID);
+    #endif
+
+On return, compilerID will indicate which version of the MMX assembler
+optimizations was compiled.  Currently two flavors exist:  Microsoft
+Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2).
+On non-x86 platforms or on systems compiled without MMX optimizations, a
+value of -1 is used.
+
+Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return
+all valid, settable optimization bits for the version of the library that's
+currently in use.  In the case of shared (dynamically linked) libraries,
+this may include optimizations that did not exist at the time the code was
+written and compiled.  It is also possible, of course, to enable only known,
+specific optimizations; for example:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+             | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+       png_set_asm_flags(png_ptr, flags);
+    #endif
+
+This method would enable only the MMX read-optimizations available at the
+time of libpng 1.2.0's release, regardless of whether a later version of
+the DLL were actually being used.  (Also note that these functions did not
+exist in versions older than 1.2.0, so any attempt to run a dynamically
+linked app on such an older version would fail.)
+
+To determine whether the processor supports MMX instructions at all, use
+the png_mmx_support() function:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       mmxsupport = png_mmx_support();
+    #endif
+
+It returns -1 if MMX support is not compiled into libpng, 0 if MMX code
+is compiled but MMX is not supported by the processor, or 1 if MMX support
+is fully available.  Note that png_mmx_support(), png_get_mmx_flagmask(),
+and png_get_asm_flagmask() all may be called without allocating and ini-
+tializing any PNG structures (for example, as part of a usage screen or
+"about" box).
+
+The following code can be used to prevent an application from using the
+thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK
+defined:
+
+#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
+  && defined(PNG_THREAD_UNSAFE_OK)
+    /* Disable thread-unsafe features of pnggccrd */
+    if (png_access_version() >= 10200)
+    {
+      png_uint_32 mmx_disable_mask = 0;
+      png_uint_32 asm_flags;
+
+      mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
+      asm_flags = png_get_asm_flags(png_ptr);
+      png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
+    }
+#endif
+
+For more extensive examples of runtime querying, enabling and disabling
+of optimized features, see contrib/gregbook/readpng2.c in the libpng
+source-code distribution.
+
+.SH VII.  MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions.  To enable them, use the
+png_permit_mng_features() function:
+
+   feature_set = png_permit_mng_features(png_ptr, mask)
+   mask is a png_uint_32 containing the logical OR of the
+        features you want to enable.  These include
+        PNG_FLAG_MNG_EMPTY_PLTE
+        PNG_FLAG_MNG_FILTER_64
+        PNG_ALL_MNG_FEATURES
+   feature_set is a png_uint_32 that is the logical AND of
+      your mask with the set of MNG features that is
+      supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped
+in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks.  Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them.  You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+.SH VIII.  Changes to Libpng from version 0.88
+
+It should be noted that versions of libpng later than 0.96 are not
+distributed by the original libpng author, Guy Schalnat, nor by
+Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
+distributed versions 0.89 through 0.96, but rather by another member
+of the original PNG Group, Glenn Randers-Pehrson.  Guy and Andreas are
+still alive and well, but they have moved on to other things.
+
+The old libpng functions png_read_init(), png_write_init(),
+png_info_init(), png_read_destroy(), and png_write_destroy() have been
+moved to PNG_INTERNAL in version 0.95 to discourage their use.  These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
+via the png_create_read_struct(), png_create_write_struct(), and
+png_create_info_struct() because they isolate the size of the structures
+from the application, allow version error checking, and also allow the
+use of custom error handling routines during the initialization, which
+the old functions do not.  The functions png_read_destroy() and
+png_write_destroy() do not actually free the memory that libpng
+allocated for these structs, but just reset the data structures, so they
+can be used instead of png_destroy_read_struct() and
+png_destroy_write_struct() if you feel there is too much system overhead
+allocating and freeing the png_struct for each image read.
+
+Setting the error callbacks via png_set_message_fn() before
+png_read_init() as was suggested in libpng-0.88 is no longer supported
+because this caused applications that do not use custom error functions
+to fail if the png_ptr was not initialized to zero.  It is still possible
+to set the error callbacks AFTER png_read_init(), or to change them with
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can find out which version of the library
+you are using at run-time:
+
+   png_uint_32 libpng_vn = png_access_version_number();
+
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
+
+You can also check which version of png.h you used when compiling your
+application:
+
+   png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+.SH IX. Y2K Compliance in libpng
+
+September 12, 2004
+
+Since the PNG Development group is an ad-hoc body, we can't make
+an official declaration.
+
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.2.7 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
+
+Libpng only has three year fields.  One is a 2-byte unsigned integer that
+will hold years up to 65535.  The other two hold the date in text
+format, and will hold years up to 9999.
+
+The integer is
+    "png_uint_16 year" in png_time_struct.
+
+The strings are
+    "png_charp time_buffer" in png_struct and
+    "near_time_buffer", which is a local character string in png.c.
+
+There are seven time-related functions:
+
+    png_convert_to_rfc_1123() in png.c
+      (formerly png_convert_to_rfc_1152() in error)
+    png_convert_from_struct_tm() in pngwrite.c, called
+      in pngwrite.c
+    png_convert_from_time_t() in pngwrite.c
+    png_get_tIME() in pngget.c
+    png_handle_tIME() in pngrutil.c, called in pngread.c
+    png_set_tIME() in pngset.c
+    png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+All appear to handle dates properly in a Y2K environment.  The
+png_convert_from_time_t() function calls gmtime() to convert from system
+clock time, which returns (year - 1900), which we properly convert to
+the full 4-digit year.  There is a possibility that applications using
+libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
+
+The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+integer to hold the year, and can hold years as large as 65535.
+
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
+
+   Glenn Randers-Pehrson
+   libpng maintainer
+   PNG Development Group
+
+.SH NOTE
+
+Note about libpng version numbers:
+
+Due to various miscommunications, unforeseen code incompatibilities
+and occasional factors outside the authors' control, version numbering
+on the library has not always been consistent and straightforward.
+The following table summarizes matters since version 0.89c, which was
+the first widely used release:
+
+ source             png.h  png.h  shared-lib
+ version            string   int  version
+ -------            ------  ----- ----------
+ 0.89c ("beta 3")  0.89       89  1.0.89
+ 0.90  ("beta 4")  0.90       90  0.90
+ 0.95  ("beta 5")  0.95       95  0.95
+ 0.96  ("beta 6")  0.96       96  0.96
+ 0.97b ("beta 7")  1.00.97    97  1.0.1
+ 0.97c             0.97       97  2.0.97
+ 0.98              0.98       98  2.0.98
+ 0.99              0.99       98  2.0.99
+ 0.99a-m           0.99       99  2.0.99
+ 1.00              1.00      100  2.1.0
+ 1.0.0             1.0.0     100  2.1.0
+ 1.0.0   (from here on, the  100  2.1.0
+ 1.0.1    png.h string is  10001  2.1.0
+ 1.0.1a-e identical to the 10002  from here on, the
+ 1.0.2    source version)  10002  shared library is 2.V
+ 1.0.2a-b                  10003  where V is the source
+ 1.0.1                     10001  code version except as
+ 1.0.1a-e                  10002  2.1.0.1a-e   noted.
+ 1.0.2                     10002  2.1.0.2
+ 1.0.2a-b                  10003  2.1.0.2a-b
+ 1.0.3                     10003  2.1.0.3
+ 1.0.3a-d                  10004  2.1.0.3a-d
+ 1.0.4                     10004  2.1.0.4
+ 1.0.4a-f                  10005  2.1.0.4a-f
+ 1.0.5 (+ 2 patches)       10005  2.1.0.5
+ 1.0.5a-d                  10006  2.1.0.5a-d
+ 1.0.5e-r                  10100  2.1.0.5e-r
+ 1.0.5s-v                  10006  2.1.0.5s-v
+ 1.0.6 (+ 3 patches)       10006  2.1.0.6
+ 1.0.6d-g                  10007  2.1.0.6d-g
+ 1.0.6h                    10007  10.6h
+ 1.0.6i                    10007  10.6i
+ 1.0.6j                    10007  2.1.0.6j
+ 1.0.7beta11-14    DLLNUM  10007  2.1.0.7beta11-14
+ 1.0.7beta15-18       1    10007  2.1.0.7beta15-18
+ 1.0.7rc1-2           1    10007  2.1.0.7rc1-2
+ 1.0.7                1    10007  2.1.0.7
+ 1.0.8beta1-4         1    10008  2.1.0.8beta1-4
+ 1.0.8rc1             1    10008  2.1.0.8rc1
+ 1.0.8                1    10008  2.1.0.8
+ 1.0.9beta1-6         1    10009  2.1.0.9beta1-6
+ 1.0.9rc1             1    10009  2.1.0.9rc1
+ 1.0.9beta7-10        1    10009  2.1.0.9beta7-10
+ 1.0.9rc2             1    10009  2.1.0.9rc2
+ 1.0.9                1    10009  2.1.0.9
+ 1.0.10beta1          1    10010  2.1.0.10beta1
+ 1.0.10rc1            1    10010  2.1.0.10rc1
+ 1.0.10               1    10010  2.1.0.10
+ 1.0.11beta1-3        1    10011  2.1.0.11beta1-3
+ 1.0.11rc1            1    10011  2.1.0.11rc1
+ 1.0.11               1    10011  2.1.0.11
+ 1.0.12beta1-2        2    10012  2.1.0.12beta1-2
+ 1.0.12rc1            2    10012  2.1.0.12rc1
+ 1.0.12               2    10012  2.1.0.12
+ 1.1.0a-f             -    10100  2.1.1.0a-f abandoned
+ 1.2.0beta1-2         2    10200  2.1.2.0beta1-2
+ 1.2.0beta3-5         3    10200  3.1.2.0beta3-5
+ 1.2.0rc1             3    10200  3.1.2.0rc1
+ 1.2.0                3    10200  3.1.2.0
+ 1.2.1beta-4          3    10201  3.1.2.1beta1-4
+ 1.2.1rc1-2           3    10201  3.1.2.1rc1-2
+ 1.2.1                3    10201  3.1.2.1
+ 1.2.2beta1-6        12    10202  12.so.0.1.2.2beta1-6
+ 1.0.13beta1         10    10013  10.so.0.1.0.13beta1
+ 1.0.13rc1           10    10013  10.so.0.1.0.13rc1
+ 1.2.2rc1            12    10202  12.so.0.1.2.2rc1
+ 1.0.13              10    10013  10.so.0.1.0.13
+ 1.2.2               12    10202  12.so.0.1.2.2
+ 1.2.3rc1-6          12    10203  12.so.0.1.2.3rc1-6
+ 1.2.3               12    10203  12.so.0.1.2.3
+ 1.2.4beta1-3        13    10204  12.so.0.1.2.4beta1-3
+ 1.2.4rc1            13    10204  12.so.0.1.2.4rc1
+ 1.0.14              10    10014  10.so.0.1.0.14
+ 1.2.4               13    10204  12.so.0.1.2.4
+ 1.2.5beta1-2        13    10205  12.so.0.1.2.5beta1-2
+ 1.0.15rc1           10    10015  10.so.0.1.0.15rc1
+ 1.0.15              10    10015  10.so.0.1.0.15
+ 1.2.5               13    10205  12.so.0.1.2.5
+ 1.2.6beta1-4        13    10206  12.so.0.1.2.6beta1-4
+ 1.2.6rc1-5          13    10206  12.so.0.1.2.6rc1-5
+ 1.0.16              10    10016  10.so.0.1.0.16
+ 1.2.6               13    10206  12.so.0.1.2.6
+ 1.2.7beta1-2        13    10207  12.so.0.1.2.7beta1-2
+ 1.0.17rc1           10    10017  12.so.0.1.0.17rc1
+ 1.2.7rc1            13    10207  12.so.0.1.2.7rc1
+ 1.0.17              10    10017  12.so.0.1.0.17
+ 1.2.7               13    10207  12.so.0.1.2.7
+
+Henceforth the source version will match the shared-library minor
+and patch numbers; the shared-library major version number will be
+used for changes in backward compatibility, as it is intended.  The
+PNG_PNGLIB_VER macro, which is not used within libpng but is available
+for applications, is an unsigned integer of the form xyyzz corresponding
+to the source version x.y.z (leading zeros in y and z).  Beta versions
+were given the previous public release number plus a letter, until
+version 1.0.6j; from then on they were given the upcoming public
+release number plus "betaNN" or "rcN".
+
+.SH "SEE ALSO"
+libpngpf(3), png(5)
+.LP
+.IR libpng :
+.IP
+http://libpng.sourceforge.net (follow the [DOWNLOAD] link)
+http://www.libpng.org/pub/png
+
+.LP
+.IR zlib :
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ftp.info-zip.org/pub/infozip/zlib
+
+.LP
+.IR PNG specification: RFC 2083
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ds.internic.net/rfc/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+
+.LP
+In the case of any inconsistency between the PNG specification
+and this library, the specification takes precedence.
+
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+<glennrp@users.sourceforge.net>
+
+The contributing authors would like to thank all those who helped
+with testing, bug fixes, and patience.  This wouldn't have been
+possible without all of you.
+
+Thanks to Frank J. T. Wojcik for helping with the documentation.
+
+Libpng version 1.2.7 - September 12, 2004:
+Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
+Currently maintained by Glenn Randers-Pehrson (glennrp@users.sourceforge.net).
+
+Supported by the PNG development group
+.br
+png-implement@ccrc.wustl.edu (subscription required; write to
+majordomo@ccrc.wustl.edu with "subscribe png-implement" in the message).
+
+.SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+(This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.)
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng version 1.2.6, September 12, 2004, is
+Copyright (c) 2004 Glenn Randers-Pehrson, and is
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+   Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your
+   enjoyment of the library or against infringement.
+   There is no warranty that our efforts or the library
+   will fulfill any of your particular purposes or needs.
+   This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and
+   effort is with the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+Distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and
+   must not be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from
+   any source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products.  If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp@users.sourceforge.net
+September 12, 2004
+
+.\" end of man page
+
diff --git a/Utilities/FLTK/png/libpng.txt b/Utilities/FLTK/png/libpng.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4dec2dd3aed76729e1878994a108765ff55b43fc
--- /dev/null
+++ b/Utilities/FLTK/png/libpng.txt
@@ -0,0 +1,2958 @@
+libpng.txt - A description on how to use and modify libpng
+
+ libpng version 1.2.7 - September 12, 2004
+ Updated and distributed by Glenn Randers-Pehrson
+ <glennrp@users.sourceforge.net>
+ Copyright (c) 1998-2004 Glenn Randers-Pehrson
+ For conditions of distribution and use, see copyright
+ notice in png.h.
+
+ based on:
+
+ libpng 1.0 beta 6  version 0.96 May 28, 1997
+ Updated and distributed by Andreas Dilger
+ Copyright (c) 1996, 1997 Andreas Dilger
+
+ libpng 1.0 beta 2 - version 0.88  January 26, 1996
+ For conditions of distribution and use, see copyright
+ notice in png.h. Copyright (c) 1995, 1996 Guy Eric
+ Schalnat, Group 42, Inc.
+
+ Updated/rewritten per request in the libpng FAQ
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
+
+I. Introduction
+
+This file describes how to use and modify the PNG reference library
+(known as libpng) for your own use.  There are five sections to this
+file: introduction, structures, reading, writing, and modification and
+configuration notes for various special platforms.  In addition to this
+file, example.c is a good starting point for using the library, as
+it is heavily commented and should include everything most people
+will need.  We assume that libpng is already installed; see the
+INSTALL file for instructions on how to install libpng.
+
+Libpng was written as a companion to the PNG specification, as a way
+of reducing the amount of time and effort it takes to support the PNG
+file format in application programs.
+
+The PNG specification (second edition), November 2003, is available as
+a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at
+<http://www.w3.org/TR/2003/REC-PNG-20031110/
+The W3C and ISO documents have identical technical content.
+
+The PNG-1.2 specification is available at
+<http://www.libpng.org/pub/png/documents/>
+
+The PNG-1.0 specification is available
+as RFC 2083 <http://www.libpng.org/pub/png/documents/> and as a
+W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
+additional chunks are described in the special-purpose public chunks
+documents at <http://www.libpng.org/pub/png/documents/>.
+
+Other information
+about PNG, and the latest version of libpng, can be found at the PNG home
+page, <http://www.libpng.org/pub/png/>.
+
+Most users will not have to modify the library significantly; advanced
+users may want to modify it more.  All attempts were made to make it as
+complete as possible, while keeping the code easy to understand.
+Currently, this library only supports C.  Support for other languages
+is being considered.
+
+Libpng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
+to use.  The ultimate goal of libpng is to promote the acceptance of
+the PNG file format in whatever way possible.  While there is still
+work to be done (see the TODO file), libpng should cover the
+majority of the needs of its users.
+
+Libpng uses zlib for its compression and decompression of PNG files.
+Further information about zlib, and the latest version of zlib, can
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than PNG files, and can be used without libpng.
+See the documentation delivered with zlib for more details.
+You can usually find the source files for the zlib utility wherever you
+find the libpng source files.
+
+Libpng is thread safe, provided the threads are using different
+instances of the structures.  Each thread should have its own
+png_struct and png_info instances, and thus its own image.
+Libpng does not protect itself against two threads using the
+same instance of a structure.  Note: thread safety may be defeated
+by use of some of the MMX assembler code in pnggccrd.c, which is only
+compiled when the user defines PNG_THREAD_UNSAFE_OK.
+
+II. Structures
+
+There are two main structures that are important to libpng, png_struct
+and png_info.  The first, png_struct, is an internal structure that
+will not, for the most part, be used by a user except as the first
+variable passed to every libpng function call.
+
+The png_info structure is designed to provide information about the
+PNG file.  At one time, the fields of png_info were intended to be
+directly accessible to the user.  However, this tended to cause problems
+with applications using dynamically loaded libraries, and as a result
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed.  The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order.  In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5.  Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
+
+The png.h header file is an invaluable reference for programming with libpng.
+And while I'm on the topic, make sure you include the libpng header file:
+
+#include <png.h>
+
+III. Reading
+
+We'll now walk you through the possible functions to call when reading
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one.  See example.c and png.h for more detail.  While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+Setup
+
+You will want to do the I/O initialization(*) before you get into libpng,
+so if it doesn't work, you don't have much to undo.  Of course, you
+will also want to insure that you are, in fact, dealing with a PNG
+file.  Libpng provides a simple check to see if a file is a PNG file.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 if the bytes match the corresponding
+bytes of the PNG signature, or nonzero otherwise.  Of course, the more bytes
+you pass in, the greater the accuracy of the prediction.
+
+If you are intending to keep the file pointer open for use in libpng,
+you must ensure you don't read more than 8 bytes from the beginning
+of the file, and you also have to make a call to png_set_sig_bytes_read()
+with the number of bytes you read from the beginning.  Libpng will
+then only check the bytes (if any) that your program didn't read.
+
+(*): If you are not using the standard I/O functions, you will need
+to replace them with custom functions.  See the discussion under
+Customizing libpng.
+
+
+    FILE *fp = fopen(file_name, "rb");
+    if (!fp)
+    {
+        return (ERROR);
+    }
+    fread(header, 1, number, fp);
+    is_png = !png_sig_cmp(header, 0, number);
+    if (!is_png)
+    {
+        return (NOT_PNG);
+    }
+
+
+Next, png_struct and png_info need to be allocated and initialized.  In
+order to ensure that the size of these structures is correct even with a
+dynamically linked libpng, there are functions to initialize and
+allocate the structures.  We also pass the library version, optional
+pointers to error handling functions, and a pointer to a data struct for
+use by the error functions, if necessary (the pointer and functions can
+be NULL if the default error handlers are to be used).  See the section
+on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
+
+    png_structp png_ptr = png_create_read_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr,
+           (png_infopp)NULL, (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    png_infop end_info = png_create_info_struct(png_ptr);
+    if (!end_info)
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+          (png_infopp)NULL);
+        return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_read_struct_2() instead of png_create_read_struct():
+
+    png_structp png_ptr = png_create_read_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+The error handling routines passed to png_create_read_struct()
+and the memory alloc/free routines passed to png_create_struct_2()
+are only necessary if you are not using the libpng supplied error
+handling and memory alloc/free functions.
+
+When libpng encounters an error, it expects to longjmp back
+to your routine.  Therefore, you will need to call setjmp and pass
+your png_jmpbuf(png_ptr).  If you read the file from different
+routines, you will need to update the jmpbuf field every time you enter
+a new routine that will call a png_*() function.
+
+See your documentation of setjmp/longjmp for your compiler for more
+information on setjmp/longjmp.  See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling.  If an error occurs, and libpng longjmp's
+back to your setjmp, you will want to call png_destroy_read_struct() to
+free any memory.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           &end_info);
+        fclose(fp);
+        return (ERROR);
+    }
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the input code.  The default for libpng is to
+use the C function fread().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  If you wish to handle reading data in another
+way, you need not call the png_init_io() function, but you must then
+implement the libpng I/O methods discussed in the Customizing Libpng
+section below.
+
+    png_init_io(png_ptr, fp);
+
+If you had previously opened the file and read any of the signature from
+the beginning in order to see if this was a PNG file, you need to let
+libpng know that there are some bytes missing from the start of the file.
+
+    png_set_sig_bytes(png_ptr, number);
+
+Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+    read_chunk_callback(png_ptr ptr,
+         png_unknown_chunkp chunk);
+    {
+       /* The unknown chunk structure contains your
+          chunk data: */
+           png_byte name[5];
+           png_byte *data;
+           png_size_t size;
+       /* Note that libpng has already taken care of
+          the CRC handling */
+
+       /* put your code here.  Return one of the
+          following: */
+
+       return (-n); /* chunk had an error */
+       return (0); /* did not recognize */
+       return (n); /* success */
+    }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+        read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+    png_get_user_chunk_ptr(png_ptr);
+
+At this point, you can set up a callback function that will be
+called after each row has been read, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void read_row_callback(png_ptr ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "read_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_status_fn(png_ptr, read_row_callback);
+
+Width and height limits
+
+The PNG specification allows the width and height of an image to be as
+large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
+Since very few applications really need to process such large images,
+we have imposed an arbitrary 1-million limit on rows and columns.
+Larger images will be rejected immediately with a png_error() call. If
+you wish to override this limit, you can use
+
+   png_set_user_limits(png_ptr, width_max, height_max);
+
+to set your own limits, or use width_max = height_max = 0x7fffffffL
+to allow all valid dimensions (libpng may reject some very large images
+anyway because of potential buffer overflow conditions).
+
+You should put this statement after you create the PNG structure and
+before calling png_read_info(), png_read_png(), or png_process_data().
+If you need to retrieve the limits that are being applied, use
+
+   width_max = png_get_user_width_max(png_ptr);
+   height_max = png_get_user_height_max(png_ptr);
+
+Unknown-chunk handling
+
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read.  Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members; unknown chunks will be discarded. To change
+this, you can call:
+
+    png_set_keep_unknown_chunks(png_ptr, keep,
+        chunk_list, num_chunks);
+    keep       - 0: do not handle as unknown
+                 1: do not keep
+                 2: keep only if safe-to-copy
+                 3: keep even if unsafe-to-copy
+               You can use these definitions:
+                 PNG_HANDLE_CHUNK_AS_DEFAULT   0
+                 PNG_HANDLE_CHUNK_NEVER        1
+                 PNG_HANDLE_CHUNK_IF_SAFE      2
+                 PNG_HANDLE_CHUNK_ALWAYS       3
+    chunk_list - list of chunks affected (a byte string,
+                 five bytes per chunk, NULL or '\0' if
+                 num_chunks is 0)
+    num_chunks - number of chunks affected; if 0, all
+                 unknown chunks are affected.  If nonzero,
+                 only the chunks in the list are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures.  If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive.  If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.  The IHDR and IEND chunks should not be named in
+chunk_list; if they are, libpng will process them normally anyway.
+
+The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to
+                                8 bits
+    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
+    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit
+                                samples to bytes
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_EXPAND        Perform set_expand()
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.)  If this is the case, simply do this:
+
+    png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of
+some set of transformation flags.  This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform mask,
+then png_read_image(), and finally png_read_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future input transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_read_png().
+
+After you have called png_read_png(), you can retrieve the image data
+with
+
+   row_pointers = png_get_rows(png_ptr, info_ptr);
+
+where row_pointers is an array of pointers to the pixel data for each row:
+
+   png_bytep row_pointers[height];
+
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+   if (height > PNG_UINT_32_MAX/png_sizeof(png_byte))
+      png_error (png_ptr,
+         "Image is too tall to process in memory");
+   if (width > PNG_UINT_32_MAX/pixel_size)
+      png_error (png_ptr,
+         "Image is too wide to process in memory");
+   row_pointers = png_malloc(png_ptr,
+      height*png_sizeof(png_bytep));
+   for (int i=0; i<height, i++)
+      row_pointers[i]=png_malloc(png_ptr,
+         width*pixel_size);
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
+
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
+
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data.  You do this with a
+call to png_read_info().
+
+    png_read_info(png_ptr, info_ptr);
+
+This will process all chunks up to but not including the image data.
+
+Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read.  Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
+
+    png_get_IHDR(png_ptr, info_ptr, &width, &height,
+       &bit_depth, &color_type, &interlace_type,
+       &compression_type, &filter_method);
+
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.  (valid values are
+                     1, 2, 4, 8, 16 and depend also on
+                     the color_type.  See also
+                     significant bits (sBIT) below).
+    color_type     - describes which color/alpha channels
+                         are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    filter_method  - (must be PNG_FILTER_TYPE_BASE
+                     for PNG 1.0, and can also be
+                     PNG_INTRAPIXEL_DIFFERENCING if
+                     the PNG datastream is embedded in
+                     a MNG-1.0 datastream)
+    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
+                     for PNG 1.0)
+    interlace_type - (PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7)
+    Any or all of interlace_type, compression_type, of
+    filter_method can be NULL if you are
+    not interested in their values.
+
+    channels = png_get_channels(png_ptr, info_ptr);
+    channels       - number of channels of info for the
+                     color type (valid values are 1 (GRAY,
+                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
+                     4 (RGB_ALPHA or RGB + filler byte))
+    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+    rowbytes       - number of bytes needed to hold a row
+
+    signature = png_get_signature(png_ptr, info_ptr);
+    signature      - holds the signature read from the
+                     file (if any).  The data is kept in
+                     the same offset it would be if the
+                     whole signature were read (i.e. if an
+                     application had already read in 4
+                     bytes of signature before starting
+                     libpng, the remaining 4 bytes would
+                     be in signature[4] through signature[7]
+                     (see png_set_sig_bytes())).
+
+
+    width            = png_get_image_width(png_ptr,
+                         info_ptr);
+    height           = png_get_image_height(png_ptr,
+                         info_ptr);
+    bit_depth        = png_get_bit_depth(png_ptr,
+                         info_ptr);
+    color_type       = png_get_color_type(png_ptr,
+                         info_ptr);
+    filter_method    = png_get_filter_type(png_ptr,
+                         info_ptr);
+    compression_type = png_get_compression_type(png_ptr,
+                         info_ptr);
+    interlace_type   = png_get_interlace_type(png_ptr,
+                         info_ptr);
+
+
+These are also important, but their validity depends on whether the chunk
+has been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
+png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
+data has been read, or zero if it is missing.  The parameters to the
+png_get_<chunk> are set directly if they are simple data types, or a pointer
+into the info_ptr is returned for any complex types.
+
+    png_get_PLTE(png_ptr, info_ptr, &palette,
+                     &num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_get_gAMA(png_ptr, info_ptr, &gamma);
+    gamma          - the gamma the file is written
+                     at (PNG_INFO_gAMA)
+
+    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
+    srgb_intent    - the rendering intent (PNG_INFO_sRGB)
+                     The presence of the sRGB chunk
+                     means that the pixel data is in the
+                     sRGB color space.  This chunk also
+                     implies specific values of gAMA and
+                     cHRM.
+
+    png_get_iCCP(png_ptr, info_ptr, &name,
+       &compression_type, &profile, &proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray,
+                     red, green, and blue channels,
+                     whichever are appropriate for the
+                     given color type (png_color_16)
+
+    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
+                     &trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_get_hIST(png_ptr, info_ptr, &hist);
+                     (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_get_tIME(png_ptr, info_ptr, &mod_time);
+    mod_time       - time image was last modified
+                    (PNG_VALID_tIME)
+
+    png_get_bKGD(png_ptr, info_ptr, &background);
+    background     - background color (PNG_VALID_bKGD)
+                     valid 16-bit red, green and blue
+                     values, regardless of color_type
+
+    num_comments   = png_get_text(png_ptr, info_ptr,
+                     &text_ptr, &num_text);
+    num_comments   - number of comments
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                         1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (empty
+                         string for unknown).
+    text_ptr[i].lang_key  - keyword in UTF-8
+                         (empty string for unknown).
+    num_text       - number of comments (same as
+                     num_comments; you can put NULL here
+                     to avoid the duplication)
+    Note while png_set_text() will accept text, language,
+    and translated keywords that can be NULL pointers, the
+    structure returned by png_get_text will always contain
+    regular zero-terminated C strings.  They might be
+    empty strings but they will never be NULL pointers.
+
+    num_spalettes = png_get_sPLT(png_ptr, info_ptr,
+       &palette_ptr);
+    palette_ptr    - array of palette structures holding
+                     contents of one or more sPLT chunks
+                     read.
+    num_spalettes  - number of sPLT chunks read.
+
+    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
+       &unit_type);
+    offset_x       - positive offset from the left edge
+                     of the screen
+    offset_y       - positive offset from the top edge
+                     of the screen
+    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
+       &unit_type);
+    res_x          - pixels/unit physical resolution in
+                     x direction
+    res_y          - pixels/unit physical resolution in
+                     x direction
+    unit_type      - PNG_RESOLUTION_UNKNOWN,
+                     PNG_RESOLUTION_METER
+
+    png_get_sCAL(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are doubles)
+
+    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    num_unknown_chunks = png_get_unknown_chunks(png_ptr,
+       info_ptr, &unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position of chunk in file
+
+    The value of "i" corresponds to the order in which the
+    chunks were read from the PNG file or inserted with the
+    png_set_unknown_chunks() function.
+
+The data from the pHYs chunk can be retrieved in several convenient
+forms:
+
+    res_x = png_get_x_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x = png_get_x_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_inch(png_ptr,
+       info_ptr)
+    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
+       info_ptr)
+
+   (Each of these returns 0 [signifying "unknown"] if
+       the data is not present or if res_x is 0;
+       res_x_and_y is 0 if res_x != res_y)
+
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+   (Each of these returns 0 [signifying "unknown" if both
+       x and y are 0] if the data is not present or if the
+       chunk is present but the unit is the pixel)
+
+For more information, see the png_info definition in png.h and the
+PNG specification for chunk contents.  Be careful with trusting
+rowbytes, as some of the transformations could increase the space
+needed to hold a row (expand, filler, gray_to_rgb, etc.).
+See png_read_update_info(), below.
+
+A quick word about text_ptr and num_text.  PNG stores comments in
+keyword/text pairs, one pair per chunk, with no limit on the number
+of text chunks, and a 2^31 byte limit on their size.  While there are
+suggested keywords, there is no requirement to restrict the use to these
+strings.  It is strongly suggested that keywords and text be sensible
+to humans (that's the point), so don't use abbreviations.  Non-printing
+symbols are not allowed.  See the PNG specification for more details.
+There is also no requirement to have text after the keyword.
+
+Keywords should be limited to 79 Latin-1 characters without leading or
+trailing spaces, but non-consecutive spaces are allowed within the
+keyword.  It is possible to have the same keyword any number of times.
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string.  The text string, language code, and translated
+keyword may be empty or NULL pointers.  The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image.  This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+Input transformations
+
+After you've read the header information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+The colors used for the background and transparency values should be
+supplied in the same format/depth as the current image data.  They
+are stored in the same format/depth as the image data in a bKGD or tRNS
+chunk, so this is what libpng expects for this data.  The colors are
+transformed to keep in sync with the image data when an application
+calls the png_read_update_info() routine (see below).
+
+Data will be decoded into the supplied row buffers packed into bytes
+unless the library has been told to transform it into another format.
+For example, 4 bit/pixel paletted or grayscale data will be returned
+2 pixels/byte with the leftmost pixel in the high-order bits of the
+byte, unless png_set_packing() is called.  8-bit RGB data will be stored
+in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha()
+is called to insert filler bytes, either before or after each RGB triplet.
+16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant
+byte of the color value first, unless png_set_strip_16() is called to
+transform it to regular RGB RGB triplets, or png_set_filler|add alpha()
+is called to insert filler bytes, either before or after each RRGGBB
+triplet.  Similarly, 8-bit or 16-bit grayscale data can be modified with
+png_set_filler(), png_set_add_alpha(), or png_set_strip_16().
+
+The following code transforms grayscale images of less than 8 to 8 bits,
+changes paletted images to RGB, and adds a full alpha channel if there is
+transparency information in a tRNS chunk.  This is most useful on
+grayscale images with bit depths of 2 or 4 or if there is a multiple-image
+viewing application that wishes to treat all images in the same way.
+
+    if (color_type == PNG_COLOR_TYPE_PALETTE)
+        png_set_palette_to_rgb(png_ptr);
+
+    if (color_type == PNG_COLOR_TYPE_GRAY &&
+        bit_depth < 8) png_set_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);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
+
+PNG can have files with 16 bits per channel.  If you only can handle
+8 bits per channel, this will strip the pixels down to 8 bit.
+
+    if (bit_depth == 16)
+        png_set_strip_16(png_ptr);
+
+If, for some reason, you don't need the alpha channel on an image,
+and you want to remove it rather than combining it with the background
+(but the image author certainly had in mind that you *would* combine
+it with the background, so that's what you should probably do):
+
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+        png_set_strip_alpha(png_ptr);
+
+In PNG files, the alpha channel in an image
+is the level of opacity.  If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transparent, with
+
+    png_set_invert_alpha(png_ptr);
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit
+files.  This code expands to 1 pixel per byte without changing the
+values of the pixels:
+
+    if (bit_depth < 8)
+        png_set_packing(png_ptr);
+
+PNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels
+stored in a PNG image have been "scaled" or "shifted" up to the next
+higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
+8 bits/sample in the range [0, 255]).  However, it is also possible to
+convert the PNG pixel data back to the original bit depth of the image.
+This call reduces the pixels back down to the original bit depth:
+
+    png_color_8p sig_bit;
+
+    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
+        png_set_shift(png_ptr, sig_bit);
+
+PNG files store 3-color pixels in red, green, blue order.  This code
+changes the storage of the pixels to blue, green, red:
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_bgr(png_ptr);
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them
+into 4 or 8 bytes for windowing systems that need them in this format:
+
+    if (color_type == PNG_COLOR_TYPE_RGB)
+        png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);
+
+where "filler" is the 8 or 16-bit number to fill with, and the location is
+either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
+you want the filler before the RGB or after.  This transformation
+does not affect images that already have full alpha channels.  To add an
+opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which
+will generate RGBA pixels.
+
+Note that png_set_filler() does not change the color type.  If you want
+to do that, you can add a true alpha channel with
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+           color_type == PNG_COLOR_TYPE_GRAY)
+    png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
+
+where "filler" contains the alpha value to assign to each pixel.
+This function became available in libpng-1.2.7.
+
+If you are reading an image with an alpha channel, and you need the
+data as ARGB instead of the normal PNG format RGBA:
+
+    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_swap_alpha(png_ptr);
+
+For some uses, you may want a grayscale image to be represented as
+RGB.  This code will do that conversion:
+
+    if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+          png_set_gray_to_rgb(png_ptr);
+
+Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
+with alpha.
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+          png_set_rgb_to_gray_fixed(png_ptr, error_action,
+             int red_weight, int green_weight);
+
+    error_action = 1: silently do the conversion
+    error_action = 2: issue a warning if the original
+                      image has any pixel where
+                      red != green or red != blue
+    error_action = 3: issue an error and abort the
+                      conversion if the original
+                      image has any pixel where
+                      red != green or red != blue
+
+    red_weight:       weight of red component times 100000
+    green_weight:     weight of green component times 100000
+                      If either weight is negative, default
+                      weights (21268, 71514) are used.
+
+If you have set error_action = 1 or 2, you can
+later check whether the image really was gray, after processing
+the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
+It will return a png_byte that is zero if the image was gray or
+1 if there were any non-gray pixels.  bKGD and sBIT data
+will be silently converted to grayscale, using the green channel
+data, regardless of the error_action setting.
+
+With red_weight+green_weight<=100000,
+the normalized graylevel is computed:
+
+    int rw = red_weight * 65536;
+    int gw = green_weight * 65536;
+    int bw = 65536 - (rw + gw);
+    gray = (rw*red + gw*green + bw*blue)/65536;
+
+The default values approximate those recommended in the Charles
+Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
+Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
+
+    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+
+Libpng approximates this with
+
+    Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
+
+which can be expressed with integers as
+
+    Y = (6969 * R + 23434 * G + 2365 * B)/32768
+
+The calculation is done in a linear colorspace, if the image gamma
+is known.
+
+If you have a grayscale and you are using png_set_expand_depth(),
+png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to
+a higher bit-depth, you must either supply the background color as a gray
+value at the original file bit-depth (need_expand = 1) or else supply the
+background color as an RGB triplet at the final, expanded bit depth
+(need_expand = 0).  Similarly, if you are reading a paletted image, you
+must either supply the background color as a palette index (need_expand = 1)
+or as an RGB triplet that may or may not be in the palette (need_expand = 0).
+
+    png_color_16 my_background;
+    png_color_16p image_background;
+
+    if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+        png_set_background(png_ptr, image_background,
+          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+    else
+        png_set_background(png_ptr, &my_background,
+          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page).  You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
+To properly display PNG images on any kind of system, the application needs
+to know what the display gamma is.  Ideally, the user will know this, and
+the application will allow them to set it.  One method of allowing the user
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment.  In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+   double gamma, screen_gamma;
+
+   if (/* We have a user-defined screen
+       gamma value */)
+   {
+      screen_gamma = user_defined_screen_gamma;
+   }
+   /* One way that applications can share the same
+      screen gamma value */
+   else if ((gamma_str = getenv("SCREEN_GAMMA"))
+      != NULL)
+   {
+      screen_gamma = (double)atof(gamma_str);
+   }
+   /* If we don't have another value */
+   else
+   {
+      screen_gamma = 2.2; /* A good guess for a
+           PC monitor in a bright office or a dim room */
+      screen_gamma = 2.0; /* A good guess for a
+           PC monitor in a dark room */
+      screen_gamma = 1.7 or 1.0;  /* A good
+           guess for Mac systems */
+   }
+
+The png_set_gamma() function handles gamma transformations of the data.
+Pass both the file gamma and the current screen_gamma.  If the file does
+not have a gamma value, you can pass one anyway if you have an idea what
+it is (usually 0.45455 is a good guess for GIF images on PCs).  Note
+that file gammas are inverted from screen gammas.  See the discussions
+on gamma in the PNG specification for an excellent description of what
+gamma is, and why all applications should support it.  It is strongly
+recommended that PNG viewers support gamma correction.
+
+   if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+      png_set_gamma(png_ptr, screen_gamma, gamma);
+   else
+      png_set_gamma(png_ptr, screen_gamma, 0.45455);
+
+If you need to reduce an RGB file to a paletted file, or if a paletted
+file has more entries then will fit on your screen, png_set_dither()
+will do that.  Note that this is a simple match dither that merely
+finds the closest color available.  This should work fairly well with
+optimized palettes, and fairly badly with linear color cubes.  If you
+pass a palette that is larger then maximum_colors, the file will
+reduce the number of colors in the palette so it will fit into
+maximum_colors.  If there is a histogram, it will use it to make
+more intelligent choices when reducing the palette.  If there is no
+histogram, it may not do as good a job.
+
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      if (png_get_valid(png_ptr, info_ptr,
+         PNG_INFO_PLTE))
+      {
+         png_uint_16p histogram = NULL;
+
+         png_get_hIST(png_ptr, info_ptr,
+            &histogram);
+         png_set_dither(png_ptr, palette, num_palette,
+            max_screen_colors, histogram, 1);
+      }
+      else
+      {
+         png_color std_color_cube[MAX_SCREEN_COLORS] =
+            { ... colors ... };
+
+         png_set_dither(png_ptr, std_color_cube,
+            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
+            NULL,0);
+      }
+   }
+
+PNG files describe monochrome as black being zero and white being one.
+The following code will reverse this (make black be one and white be
+zero):
+
+   if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)
+      png_set_invert_mono(png_ptr);
+
+This function can also be used to invert grayscale and gray-alpha images:
+
+   if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      png_set_invert_mono(png_ptr);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code changes the storage to the
+other way (little-endian, i.e. least significant bits first, the
+way PCs store them):
+
+    if (bit_depth == 16)
+        png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_read_user_transform_fn(png_ptr,
+       read_transform_fn);
+
+You must supply the function
+
+    void read_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+The last thing to handle is interlacing; this is covered in detail below,
+but you must call the function here if you want libpng to handle expansion
+of the interlaced image.
+
+    number_of_passes = png_set_interlace_handling(png_ptr);
+
+After setting the transformations, libpng can update your png_info
+structure to reflect any transformations you've requested with this
+call.  This is most useful to update the info structure's rowbytes
+field so you can use it to allocate your image memory.  This function
+will also update your palette with the correct screen_gamma and
+background if these have been given with the calls above.
+
+    png_read_update_info(png_ptr, info_ptr);
+
+After you call png_read_update_info(), you can allocate any
+memory you need to hold the image.  The row data is simply
+raw byte data for all forms of images.  As the actual allocation
+varies among applications, no example will be given.  If you
+are allocating one large chunk, you will need to build an
+array of pointers to each row, as it will be needed for some
+of the functions below.
+
+Reading image data
+
+After you've allocated memory, you can read the image data.
+The simplest way to do this is in one function call.  If you are
+allocating enough memory to hold the whole image, you can just
+call png_read_image() and libpng will read in all the image data
+and put it in the memory area supplied.  You will need to pass in
+an array of pointers to each row.
+
+This function automatically handles interlacing, so you don't need
+to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_read_rows().
+
+   png_read_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+   png_bytep row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to read in the whole image at once, you can
+use png_read_rows() instead.  If there is no interlacing (check
+interlace_type == PNG_INTERLACE_NONE), this is simple:
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+where row_pointers is the same as in the png_read_image() call.
+
+If you are doing this just one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+    png_read_row(png_ptr, row_pointer, NULL);
+
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder.  The only current (PNG Specification version 1.2)
+interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
+is a somewhat complicated 2D interlace scheme, known as Adam7, that
+breaks down an image into seven smaller images of varying size, based
+on an 8x8 grid.
+
+libpng can fill out those images or it can give them to you "as is".
+If you want them filled out, there are two ways to do that.  The one
+mentioned in the PNG specification is to expand each pixel to cover
+those pixels that have not been read yet (the "rectangle" method).
+This results in a blocky image for the first pass, which gradually
+smooths out as more pixels are read.  The other method is the "sparkle"
+method, where pixels are drawn only in their final locations, with the
+rest of the image remaining whatever colors they were initialized to
+before the start of the read.  The first method usually looks better,
+but tends to be slower, as there are more pixels to put in the rows.
+
+If you don't want libpng to handle the interlacing details, just call
+png_read_rows() seven times to read in all seven images.  Each of the
+images is a valid image by itself, or they can all be combined on an
+8x8 grid to form a single image (although if you intend to combine them
+you would be far better off using the libpng interlace handling).
+
+The first pass will return an image 1/8 as wide as the entire image
+(every 8th column starting in column 0) and 1/8 as high as the original
+(every 8th row starting in row 0), the second will be 1/8 as wide
+(starting in column 4) and 1/8 as high (also starting in row 0).  The
+third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
+1/8 as high (every 8th row starting in row 4), and the fourth pass will
+be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
+and every 4th row starting in row 0).  The fifth pass will return an
+image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
+while the sixth pass will be 1/2 as wide and 1/2 as high as the original
+(starting in column 1 and row 0).  The seventh and final pass will be as
+wide as the original, and 1/2 as high, containing all of the odd
+numbered scanlines.  Phew!
+
+If you want libpng to expand the images, call this before calling
+png_start_read_image() or png_read_update_info():
+
+    if (interlace_type == PNG_INTERLACE_ADAM7)
+        number_of_passes
+           = png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+This function can be called even if the file is not interlaced,
+where it will return one pass.
+
+If you are not going to display the image after each pass, but are
+going to wait until the entire image is read in, use the sparkle
+effect.  This effect is faster and the end result of either method
+is exactly the same.  If you are planning on displaying the image
+after each pass, the "rectangle" effect is generally considered the
+better looking one.
+
+If you only want the "sparkle" effect, just call png_read_rows() as
+normal, with the third parameter NULL.  Make sure you make pass over
+the image number_of_passes times, and you don't change the data in the
+rows between calls.  You can change the locations of the data, just
+not the data.  Each pass only writes the pixels appropriate for that
+pass, and assumes the data from previous passes is still valid.
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+If you only want the first effect (the rectangles), do the same as
+before except pass the row buffer in the third parameter, and leave
+the second parameter NULL.
+
+    png_read_rows(png_ptr, NULL, row_pointers,
+       number_of_rows);
+
+Finishing a sequential read
+
+After you are finished reading the image through either the high- or
+low-level interfaces, you can finish reading the file.  If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate.  If you are not interested, you can pass NULL.
+
+   png_read_end(png_ptr, end_info);
+
+When you are done, you can free all memory allocated by libpng like this:
+
+   png_destroy_read_struct(&png_ptr, &info_ptr,
+       &end_info);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask - identifies data to be freed, a mask
+           containing the logical OR of one or
+           more of
+             PNG_FREE_PLTE, PNG_FREE_TRNS,
+             PNG_FREE_HIST, PNG_FREE_ICCP,
+             PNG_FREE_PCAL, PNG_FREE_ROWS,
+             PNG_FREE_SCAL, PNG_FREE_SPLT,
+             PNG_FREE_TEXT, PNG_FREE_UNKN,
+           or simply PNG_FREE_ALL
+    seq  - sequence number of item to be freed
+           (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng,  and will in those
+cases do nothing.  The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data.  When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees.  If you need to turn the flag off for a chunk that was freed by your
+application instead of by libpng, you can use
+
+    png_set_invalid(png_ptr, info_ptr, mask);
+    mask - identifies the chunks to be made invalid,
+           containing the logical OR of one or
+           more of
+             PNG_INFO_gAMA, PNG_INFO_sBIT,
+             PNG_INFO_cHRM, PNG_INFO_PLTE,
+             PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_hIST, PNG_INFO_pHYs,
+             PNG_INFO_oFFs, PNG_INFO_tIME,
+             PNG_INFO_pCAL, PNG_INFO_sRGB,
+             PNG_INFO_iCCP, PNG_INFO_sPLT,
+             PNG_INFO_sCAL, PNG_INFO_IDAT
+
+For a more compact example of reading a PNG image, see the file example.c.
+
+Reading PNG files progressively
+
+The progressive reader is slightly different then the non-progressive
+reader.  Instead of calling png_read_info(), png_read_rows(), and
+png_read_end(), you make one call to png_process_data(), which calls
+callbacks when it has the info, a row, or the end of the image.  You
+set up these callbacks with png_set_progressive_read_fn().  You don't
+have to worry about the input/output functions of libpng, as you are
+giving the library the data directly in png_process_data().  I will
+assume that you have read the section on reading PNG files above,
+so I will only highlight the differences (although I will show
+all of the code).
+
+png_structp png_ptr;
+png_infop info_ptr;
+
+ /*  An example code fragment of how you would
+     initialize the progressive reader in your
+     application. */
+ int
+ initialize_png_reader()
+ {
+    png_ptr = png_create_read_struct
+        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+         user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+    info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new.  You can provide functions
+       to be called when the header info is valid,
+       when each row is completed, and when the image
+       is finished.  If you aren't using all functions,
+       you can specify NULL parameters.  Even when all
+       three functions are NULL, you need to call
+       png_set_progressive_read_fn().  You can use
+       any struct as the user_ptr (cast to a void pointer
+       for the function call), and retrieve the pointer
+       from inside the callbacks using the function
+
+          png_get_progressive_ptr(png_ptr);
+
+       which will return a void pointer, which you have
+       to cast appropriately.
+     */
+    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
+        info_callback, row_callback, end_callback);
+
+    return 0;
+ }
+
+ /* A code fragment that you call as you receive blocks
+   of data */
+ int
+ process_data(png_bytep buffer, png_uint_32 length)
+ {
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new also.  Simply give it a chunk
+       of data from the file stream (in order, of
+       course).  On machines with segmented memory
+       models machines, don't give it any more than
+       64K.  The library seems to run fine with sizes
+       of 4K. Although you can give it much less if
+       necessary (I assume you can give it chunks of
+       1 byte, I haven't tried less then 256 bytes
+       yet).  When this function returns, you may
+       want to display any rows that were generated
+       in the row callback if you don't already do
+       so there.
+     */
+    png_process_data(png_ptr, info_ptr, buffer, length);
+    return 0;
+ }
+
+ /* This function is called (as set by
+    png_set_progressive_read_fn() above) when enough data
+    has been supplied so all of the header has been
+    read.
+ */
+ void
+ info_callback(png_structp png_ptr, png_infop info)
+ {
+    /* Do any setup here, including setting any of
+       the transformations mentioned in the Reading
+       PNG files section.  For now, you _must_ call
+       either png_start_read_image() or
+       png_read_update_info() after all the
+       transformations are set (even if you don't set
+       any).  You may start getting rows before
+       png_process_data() returns, so this is your
+       last chance to prepare for that.
+     */
+ }
+
+ /* This function is called when each row of image
+    data is complete */
+ void
+ row_callback(png_structp png_ptr, png_bytep new_row,
+    png_uint_32 row_num, int pass)
+ {
+    /* If the image is interlaced, and you turned
+       on the interlace handler, this function will
+       be called for every row in every pass.  Some
+       of these rows will not be changed from the
+       previous pass.  When the row is not changed,
+       the new_row variable will be NULL.  The rows
+       and passes are called in order, so you don't
+       really need the row_num and pass, but I'm
+       supplying them because it may make your life
+       easier.
+
+       For the non-NULL rows of interlaced images,
+       you must call png_progressive_combine_row()
+       passing in the row and the old row.  You can
+       call this function for NULL rows (it will just
+       return) and for non-interlaced images (it just
+       does the memcpy for you) if it will make the
+       code easier.  Thus, you can just do this for
+       all cases:
+     */
+
+        png_progressive_combine_row(png_ptr, old_row,
+          new_row);
+
+    /* where old_row is what was displayed for
+       previously for the row.  Note that the first
+       pass (pass == 0, really) will completely cover
+       the old row, so the rows do not have to be
+       initialized.  After the first pass (and only
+       for interlaced images), you will have to pass
+       the current row, and the function will combine
+       the old row and the new row.
+    */
+ }
+
+ void
+ end_callback(png_structp png_ptr, png_infop info)
+ {
+    /* This function is called after the whole image
+       has been read, including any chunks after the
+       image (up to and including the IEND).  You
+       will usually have the same info chunk as you
+       had in the header, although some data may have
+       been added to the comments and time fields.
+
+       Most people won't do much here, perhaps setting
+       a flag that marks the image as finished.
+     */
+ }
+
+
+
+IV. Writing
+
+Much of this is very similar to reading.  However, everything of
+importance is repeated here, so you won't have to constantly look
+back up in the reading section to understand writing.
+
+Setup
+
+You will want to do the I/O initialization before you get into libpng,
+so if it doesn't work, you don't have anything to undo. If you are not
+using the standard I/O functions, you will need to replace them with
+custom writing functions.  See the discussion under Customizing libpng.
+
+    FILE *fp = fopen(file_name, "wb");
+    if (!fp)
+    {
+       return (ERROR);
+    }
+
+Next, png_struct and png_info need to be allocated and initialized.
+As these can be both relatively large, you may not want to store these
+on the stack, unless you have stack space to spare.  Of course, you
+will want to check if they return NULL.  If you are also reading,
+you won't want to name your read structure and your write structure
+both "png_ptr"; you can call them anything you like, such as
+"read_ptr" and "write_ptr".  Look at pngtest.c, for example.
+
+    png_structp png_ptr = png_create_write_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+       return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+       png_destroy_write_struct(&png_ptr,
+         (png_infopp)NULL);
+       return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_write_struct_2() instead of png_create_write_struct():
+
+    png_structp png_ptr = png_create_write_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+After you have these structures, you will need to set up the
+error handling.  When libpng encounters an error, it expects to
+longjmp() back to your routine.  Therefore, you will need to call
+setjmp() and pass the png_jmpbuf(png_ptr).  If you
+write the file from different routines, you will need to update
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function.  See your documentation of setjmp/longjmp
+for your compiler for more information on setjmp/longjmp.  See
+the discussion on libpng error handling in the Customizing Libpng
+section below for more information on the libpng error handling.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+       png_destroy_write_struct(&png_ptr, &info_ptr);
+       fclose(fp);
+       return (ERROR);
+    }
+    ...
+    return;
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the output code.  The default for libpng is to
+use the C function fwrite().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  Again, if you wish to handle writing data in
+another way, see the discussion on libpng I/O handling in the Customizing
+Libpng section below.
+
+    png_init_io(png_ptr, fp);
+
+Write callbacks
+
+At this point, you can set up a callback function that will be
+called after each row has been written, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void write_row_callback(png_ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "write_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_write_status_fn(png_ptr, write_row_callback);
+
+You now have the option of modifying how the compression library will
+run.  The following functions are mainly for testing, but may be useful
+in some cases, like if you need to write PNG files extremely fast and
+are willing to give up some compression, or if you want to get the
+maximum possible compression at the expense of slower writing.  If you
+have no special needs in this area, let the library do what it wants by
+not calling this function at all, as it has been tuned to deliver a good
+speed/compression ratio. The second parameter to png_set_filter() is
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream).  The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline.  See the PNG specification for details on the specific filter
+types.
+
+
+    /* turn on or off filtering, and/or choose
+       specific filters.  You can use either a single
+       PNG_FILTER_VALUE_NAME or the logical OR of one
+       or more PNG_FILTER_NAME masks. */
+    png_set_filter(png_ptr, 0,
+       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
+       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
+       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
+       PNG_FILTER_AVE   | PNG_FILTER_VALUE_AVE  |
+       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+       PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
+
+The png_set_compression_*() functions interface to the zlib compression
+library, and should mostly be ignored unless you really know what you are
+doing.  The only generally useful call is png_set_compression_level()
+which changes how much time zlib spends on trying to compress the image
+data.  See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
+
+    /* set the zlib compression level */
+    png_set_compression_level(png_ptr,
+        Z_BEST_COMPRESSION);
+
+    /* set other zlib parameters */
+    png_set_compression_mem_level(png_ptr, 8);
+    png_set_compression_strategy(png_ptr,
+        Z_DEFAULT_STRATEGY);
+    png_set_compression_window_bits(png_ptr, 15);
+    png_set_compression_method(png_ptr, 8);
+    png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+Setting the contents of info for output
+
+You now need to fill in the png_info structure with all the data you
+wish to write before the actual image.  Note that the only thing you
+are allowed to write after the image is the text chunks and the time
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
+the latest PNG specification for more information on that.  If you
+wish to write them before the image, fill them in now, and flag that
+data as being valid.  If you want to wait until after the data, don't
+fill them until png_write_end().  For all the fields in png_info and
+their data types, see png.h.  For explanations of what the fields
+contain, see the PNG specification.
+
+Some of the more important parts of the png_info are:
+
+    png_set_IHDR(png_ptr, info_ptr, width, height,
+       bit_depth, color_type, interlace_type,
+       compression_type, filter_method)
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.
+                     (valid values are 1, 2, 4, 8, 16
+                     and depend also on the
+                     color_type.  See also significant
+                     bits (sBIT) below).
+    color_type     - describes which color/alpha
+                     channels are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    interlace_type - PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7
+    compression_type - (must be
+                     PNG_COMPRESSION_TYPE_DEFAULT)
+    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT
+                     or, if you are writing a PNG to
+                     be embedded in a MNG datastream,
+                     can also be
+                     PNG_INTRAPIXEL_DIFFERENCING)
+
+    png_set_PLTE(png_ptr, info_ptr, palette,
+       num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_set_gAMA(png_ptr, info_ptr, gamma);
+    gamma          - the gamma the image was created
+                     at (PNG_INFO_gAMA)
+
+    png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of
+                     the sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This chunk also implies specific
+                     values of gAMA and cHRM.  Rendering
+                     intent is the CSS-1 property that
+                     has been defined by the International
+                     Color Consortium
+                     (http://www.color.org).
+                     It can be one of
+                     PNG_sRGB_INTENT_SATURATION,
+                     PNG_sRGB_INTENT_PERCEPTUAL,
+                     PNG_sRGB_INTENT_ABSOLUTE, or
+                     PNG_sRGB_INTENT_RELATIVE.
+
+
+    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
+       srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of the
+                     sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This function also causes gAMA and
+                     cHRM chunks with the specific values
+                     that are consistent with sRGB to be
+                     written.
+
+    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+                      profile, proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_set_sBIT(png_ptr, info_ptr, sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray, red,
+                     green, and blue channels, whichever are
+                     appropriate for the given color type
+                     (png_color_16)
+
+    png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
+       trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_set_hIST(png_ptr, info_ptr, hist);
+                    (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_set_tIME(png_ptr, info_ptr, mod_time);
+    mod_time       - time image was last modified
+                     (PNG_VALID_tIME)
+
+    png_set_bKGD(png_ptr, info_ptr, background);
+    background     - background color (PNG_VALID_bKGD)
+
+    png_set_text(png_ptr, info_ptr, text_ptr, num_text);
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                 1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be NULL or empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (NULL or
+                         empty for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
+                         or empty for unknown).
+    num_text       - number of comments
+
+    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
+       num_spalettes);
+    palette_ptr    - array of png_sPLT_struct structures
+                     to be added to the list of palettes
+                     in the info structure.
+    num_spalettes  - number of palette structures to be
+                     added.
+
+    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
+        unit_type);
+    offset_x  - positive offset from the left
+                     edge of the screen
+    offset_y  - positive offset from the top
+                     edge of the screen
+    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
+        unit_type);
+    res_x       - pixels/unit physical resolution
+                  in x direction
+    res_y       - pixels/unit physical resolution
+                  in y direction
+    unit_type   - PNG_RESOLUTION_UNKNOWN,
+                  PNG_RESOLUTION_METER
+
+    png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                  (width and height are doubles)
+
+    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,
+       num_unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position to write chunk in file
+                           0: do not write chunk
+                           PNG_HAVE_IHDR: before PLTE
+                           PNG_HAVE_PLTE: before IDAT
+                           PNG_AFTER_IDAT: after IDAT
+
+The "location" member is set automatically according to
+what part of the output file has already been written.
+You can change its value after calling png_set_unknown_chunks()
+as demonstrated in pngtest.c.  Within each of the "locations",
+the chunks are sequenced according to their position in the
+structure (that is, the value of "i", which is the order in which
+the chunk was either read from the input file or defined with
+png_set_unknown_chunks).
+
+A quick word about text and num_text.  text is an array of png_text
+structures.  num_text is the number of valid structures in the array.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
+The compression types have the same valid numbers as the compression
+types of the image data.  Currently, the only valid number is zero.
+However, you can store text either compressed or uncompressed, unlike
+images, which always have to be compressed.  So if you don't want the
+text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
+Until text gets around 1000 bytes, it is not worth compressing it.
+After the text has been written out to the file, the compression type
+is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
+so that it isn't written out again at the end (in case you are calling
+png_write_end() with the same struct.
+
+The keywords that are given in the PNG Specification are:
+
+    Title            Short (one line) title or
+                     caption for image
+    Author           Name of image's creator
+    Description      Description of image (possibly long)
+    Copyright        Copyright notice
+    Creation Time    Time of original image creation
+                     (usually RFC 1123 format, see below)
+    Software         Software used to create the image
+    Disclaimer       Legal disclaimer
+    Warning          Warning of nature of content
+    Source           Device used to create the image
+    Comment          Miscellaneous comment; conversion
+                     from other image format
+
+The keyword-text pairs work like this.  Keywords should be short
+simple descriptions of what the comment is about.  Some typical
+keywords are found in the PNG specification, as is some recommendations
+on keywords.  You can repeat keywords in a file.  You can even write
+some text before the image and some after.  For example, you may want
+to put a description of the image before the image, but leave the
+disclaimer until after, so viewers working over modem connections
+don't have to wait for the disclaimer to go over the modem before
+they start seeing the image.  Finally, keywords should be full
+words, not abbreviations.  Keywords and text are in the ISO 8859-1
+(Latin-1) character set (a superset of regular ASCII) and can not
+contain NUL characters, and should not contain control or other
+unprintable characters.  To make the comments widely readable, stick
+with basic ASCII, and avoid machine specific character set extensions
+like the IBM-PC character set.  The keyword must be present, but
+you can leave off the text string on non-compressed pairs.
+Compressed pairs must have a text string, as only the text string
+is compressed anyway, so the compression would be meaningless.
+
+PNG supports modification time via the png_time structure.  Two
+conversion routines are provided, png_convert_from_time_t() for
+time_t and png_convert_from_struct_tm() for struct tm.  The
+time_t routine uses gmtime().  You don't have to use either of
+these, but if you wish to fill in the png_time structure directly,
+you should provide the time in universal time (GMT) if possible
+instead of your local time.  Note that the year number is the full
+year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
+that months start with 1.
+
+If you want to store the time of the original image creation, you should
+use a plain tEXt chunk with the "Creation Time" keyword.  This is
+necessary because the "creation time" of a PNG image is somewhat vague,
+depending on whether you mean the PNG file, the time the image was
+created in a non-PNG format, a still photo from which the image was
+scanned, or possibly the subject matter itself.  In order to facilitate
+machine-readable dates, it is recommended that the "Creation Time"
+tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
+although this isn't a requirement.  Unlike the tIME chunk, the
+"Creation Time" tEXt chunk is not expected to be automatically changed
+by the software.  To facilitate the use of RFC 1123 dates, a function
+png_convert_to_rfc1123(png_timep) is provided to convert from PNG
+time to an RFC 1123 format string.
+
+Writing unknown chunks
+
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing.  You give it a chunk name, raw data, and a size; that's
+all there is to it.  The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure.  All defined output
+transformations are permitted, enabled by the following masks.
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+    PNG_TRANSFORM_STRIP_FILLER  Strip out filler bytes.
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+    png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of some set of
+transformation flags.  This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform mask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future output transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_write_png().
+
+The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data.  You do
+this with a call to png_write_info().
+
+    png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info().  In PNG files, the alpha channel in an image is the
+level of opacity.  If your data is supplied as a level of
+transparency, you can invert the alpha channel before you write it, so
+that 0 is fully transparent and 255 (in 8-bit or paletted images) or
+65535 (in 16-bit images) is fully opaque, with
+
+    png_set_invert_alpha(png_ptr);
+
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written.  If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+    png_write_info_before_PLTE(png_ptr, info_ptr);
+    png_set_unknown_chunks(png_ptr, info_ptr, ...);
+    png_write_info(png_ptr, info_ptr);
+
+After you've written the file information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+PNG files store RGB pixels packed into 3 or 6 bytes.  This code tells
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
+
+    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit files.
+If the data is supplied at 1 pixel per byte, use this code, which will
+correctly pack the pixels into a single byte:
+
+    png_set_packing(png_ptr);
+
+PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
+data is of another bit depth, you can write an sBIT chunk into the
+file so that decoders can recover the original data if desired.
+
+    /* Set the true bit depth of the image data */
+    if (color_type & PNG_COLOR_MASK_COLOR)
+    {
+        sig_bit.red = true_bit_depth;
+        sig_bit.green = true_bit_depth;
+        sig_bit.blue = true_bit_depth;
+    }
+    else
+    {
+        sig_bit.gray = true_bit_depth;
+    }
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+    {
+        sig_bit.alpha = true_bit_depth;
+    }
+
+    png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+If the data is stored in the row buffer in a bit depth other than
+one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
+this will scale the values to appear to be the correct bit depth as
+is required by PNG.
+
+    png_set_shift(png_ptr, &sig_bit);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code would be used if they are
+supplied the other way (little-endian, i.e. least significant bits
+first, the way PCs store them):
+
+    if (bit_depth > 8)
+       png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+PNG files store 3 color pixels in red, green, blue order.  This code
+would be used if they are supplied as blue, green, red:
+
+    png_set_bgr(png_ptr);
+
+PNG files describe monochrome as black being zero and white being
+one. This code would be used if the pixels are supplied with this reversed
+(black being one and white being zero):
+
+    png_set_invert_mono(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_write_user_transform_fn(png_ptr,
+       write_transform_fn);
+
+You must supply the function
+
+    void write_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+It is possible to have libpng flush any pending output, either manually,
+or automatically after a certain number of lines have been written.  To
+flush the output stream a single time call:
+
+    png_write_flush(png_ptr);
+
+and to have libpng flush the output stream periodically after a certain
+number of scanlines have been written, call:
+
+    png_set_flush(png_ptr, nrows);
+
+Note that the distance between rows is from the last time png_write_flush()
+was called, or the first row of the image if it has never been called.
+So if you write 50 lines, and then png_set_flush 25, it will flush the
+output on the next scanline, and every 25 lines thereafter, unless
+png_write_flush() is called before 25 more lines have been written.
+If nrows is too small (less than about 10 lines for a 640 pixel wide
+RGB image) the image compression may decrease noticeably (although this
+may be acceptable for real-time applications).  Infrequent flushing will
+only degrade the compression performance by a few percent over images
+that do not use flushing.
+
+Writing the image data
+
+That's it for the transformations.  Now you can write the image data.
+The simplest way to do this is in one function call.  If you have the
+whole image in memory, you can just call png_write_image() and libpng
+will write the image.  You will need to pass in an array of pointers to
+each row.  This function automatically handles interlacing, so you don't
+need to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_write_rows().
+
+    png_write_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+    png_byte *row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to write the whole image at once, you can
+use png_write_rows() instead.  If the file is not interlaced,
+this is simple:
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+row_pointers is the same as in the png_write_image() call.
+
+If you are just writing one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+
+    png_write_row(png_ptr, row_pointer);
+
+When the file is interlaced, things can get a good deal more
+complicated.  The only currently (as of the PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
+is the "Adam7" interlace scheme, that breaks down an
+image into seven smaller images of varying size.  libpng will build
+these images for you, or you can do them yourself.  If you want to
+build them yourself, see the PNG specification for details of which
+pixels to write when.
+
+If you don't want libpng to handle the interlacing details, just
+use png_set_interlace_handling() and call png_write_rows() the
+correct number of times to write all seven sub-images.
+
+If you want libpng to build the sub-images, call this before you start
+writing any rows:
+
+    number_of_passes =
+       png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+
+Then write the complete image number_of_passes times.
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+As some of these rows are not used, and thus return immediately,
+you may want to read about interlacing in the PNG specification,
+and only update the rows that are actually used.
+
+Finishing a sequential write
+
+After you are finished writing the image, you should finish writing
+the file.  If you are interested in writing comments or time, you should
+pass an appropriately filled png_info pointer.  If you are not interested,
+you can pass NULL.
+
+    png_write_end(png_ptr, info_ptr);
+
+When you are done, you can free all memory used by libpng like this:
+
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask  - identifies data to be freed, a mask
+            containing the logical OR of one or
+            more of
+              PNG_FREE_PLTE, PNG_FREE_TRNS,
+              PNG_FREE_HIST, PNG_FREE_ICCP,
+              PNG_FREE_PCAL, PNG_FREE_ROWS,
+              PNG_FREE_SCAL, PNG_FREE_SPLT,
+              PNG_FREE_TEXT, PNG_FREE_UNKN,
+            or simply PNG_FREE_ALL
+    seq   - sequence number of item to be freed
+            (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user  and not by libpng,  and will in those
+cases do nothing.  The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+If you allocated data such as a palette that you passed
+in to libpng with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+    png_data_freer(read_ptr, read_info_ptr,
+       PNG_USER_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+    png_data_freer(write_ptr, write_info_ptr,
+       PNG_DESTROY_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function.  Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+For a more compact example of writing a PNG image, see the file example.c.
+
+V. Modifying/Customizing libpng:
+
+There are three issues here.  The first is changing how libpng does
+standard things like memory allocation, input/output, and error handling.
+The second deals with more complicated things like adding new chunks,
+adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them.  The third is a
+run-time issue:  choosing between and/or tuning one or more alternate
+versions of computationally intensive routines; specifically, optimized
+assembly-language (and therefore compiler- and platform-dependent)
+versions.
+
+Memory allocation, input/output, and error handling
+
+All of the memory allocation, input/output, and error handling in libpng
+goes through callbacks that are user-settable.  The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc()
+and png_free().  These currently just call the standard C functions.  If
+your pointers can't access more then 64K at a time, you will want to set
+MAXSEG_64K in zlib.h.  Since it is unlikely that the method of handling
+memory allocation on a platform will change between applications, these
+functions must be modified in the library at compile time.  If you prefer
+to use a different method of allocating and freeing data, you can use
+png_create_read_struct_2() or png_create_write_struct_2() to register
+your own functions as described above.
+These functions also provide a void pointer that can be retrieved via
+
+    mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your replacement memory functions must have prototypes as follows:
+
+    png_voidp malloc_fn(png_structp png_ptr,
+       png_size_t size);
+    void free_fn(png_structp png_ptr, png_voidp ptr);
+
+Your malloc_fn() must return NULL in case of failure.  The png_malloc()
+function will normally call png_error() if it receives a NULL from the
+system memory allocator or from your replacement malloc_fn().
+
+Input/Output in libpng is done through png_read() and png_write(),
+which currently just call fread() and fwrite().  The FILE * is stored in
+png_struct and is initialized via png_init_io().  If you wish to change
+the method of I/O, the library supplies callbacks that you can set
+through the function png_set_read_fn() and png_set_write_fn() at run
+time, instead of calling the png_init_io() function.  These functions
+also provide a void pointer that can be retrieved via the function
+png_get_io_ptr().  For example:
+
+    png_set_read_fn(png_structp read_ptr,
+        voidp read_io_ptr, png_rw_ptr read_data_fn)
+
+    png_set_write_fn(png_structp write_ptr,
+        voidp write_io_ptr, png_rw_ptr write_data_fn,
+        png_flush_ptr output_flush_fn);
+
+    voidp read_io_ptr = png_get_io_ptr(read_ptr);
+    voidp write_io_ptr = png_get_io_ptr(write_ptr);
+
+The replacement I/O functions must have prototypes as follows:
+
+    void user_read_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_write_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_flush_data(png_structp png_ptr);
+
+Supplying NULL for the read, write, or flush functions sets them back
+to using the default C stream functions.  It is an error to read from
+a write stream, and vice versa.
+
+Error handling in libpng is done through png_error() and png_warning().
+Errors handled through png_error() are fatal, meaning that png_error()
+should never return to its caller.  Currently, this is handled via
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
+to print a warning message, and then control returns to the calling code.
+By default png_error() and png_warning() print a message on stderr via
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available).  If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks.  These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own replacement
+functions after png_create_*_struct() has been called by calling:
+
+    png_set_error_fn(png_structp png_ptr,
+        png_voidp error_ptr, png_error_ptr error_fn,
+        png_error_ptr warning_fn);
+
+    png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
+If NULL is supplied for either error_fn or warning_fn, then the libpng
+default function will be used, calling fprintf() and/or longjmp() if a
+problem is encountered.  The replacement error functions should have
+parameters as follows:
+
+    void user_error_fn(png_structp png_ptr,
+        png_const_charp error_msg);
+    void user_warning_fn(png_structp png_ptr,
+        png_const_charp warning_msg);
+
+The motivation behind using setjmp() and longjmp() is the C++ throw and
+catch exception handling methods.  This makes the code much easier to write,
+as there is no need to check every return code of every function call.
+However, there are some uncertainties about the status of local variables
+after a longjmp, so the user may want to be careful about doing anything after
+setjmp returns non-zero besides returning itself.  Consult your compiler
+documentation for more details.  For an alternative approach, you may wish
+to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+Custom chunks
+
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code.  The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks.  Hoewver, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of
+understanding of how it works.  Pay particular attention to the
+sections that describe chunk names, and look at how other chunks were
+designed, so you can do things similarly.  Second, check out the
+sections of libpng that read and write chunks.  Try to find a chunk
+that is similar to yours and use it as a template.  More details can
+be found in the comments inside the code.  It is best to handle unknown
+chunks in a generic method, via callback functions, instead of by
+modifying libpng functions.
+
+If you wish to write your own transformation for the data, look through
+the part of the code that does the transformations, and check out some of
+the simpler ones to get an idea of how they work.  Try to find a similar
+transformation to the one you want to add and copy off of it.  More details
+can be found in the comments inside the code itself.
+
+Configuring for 16 bit platforms
+
+You will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time.  Even if you can, the memory
+won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+Configuring for DOS
+
+For DOS users who only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call.  See zlib.h or zconf.h in the zlib library for more information.
+
+Configuring for Medium Model
+
+Libpng's support for medium model has been tested on most of the popular
+compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set.  Everything in the library (except for zlib's structure) is
+expecting far data.  You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful).  Make
+note that the rows of data are defined as png_bytepp, which is an
+unsigned char far * far *.
+
+Configuring for gui/windowing platforms:
+
+You will need to write new error and warning functions that use the GUI
+interface, as described previously, and set them to be the error and
+warning functions at the time that png_create_*_struct() is called,
+in order to have them available during the structure initialization.
+They can be changed later via png_set_error_fn().  On some compilers,
+you may also have to change the memory allocators (png_malloc, etc.).
+
+Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h.  If you need to add/change/delete
+an include, this is the place to do it.  The includes that are not
+needed outside libpng are protected by the PNG_INTERNAL definition,
+which is only defined for those routines inside libpng itself.  The
+files in libpng proper only include png.h, which includes pngconf.h.
+
+Configuring zlib:
+
+There are special functions to configure the compression.  Perhaps the
+most useful one changes the compression level, which currently uses
+input compression values in the range 0 - 9.  The library normally
+uses the default compression level (Z_DEFAULT_COMPRESSION = 6).  Tests
+have shown that for a large majority of images, compression values in
+the range 3-6 compress nearly as well as higher levels, and do so much
+faster.  For online applications it may be desirable to have maximum speed
+(Z_BEST_SPEED = 1).  With versions of zlib after v0.99, you can also
+specify no compression (Z_NO_COMPRESSION = 0), but this would create
+files larger than just storing the raw bitmap.  You can specify the
+compression level by calling:
+
+    png_set_compression_level(png_ptr, level);
+
+Another useful one is to reduce the memory level used by the library.
+The memory level defaults to 8, but it can be lowered if you are
+short on memory (running DOS, for example, where you only have 640K).
+Note that the memory level does have an effect on compression; among
+other things, lower levels will result in sections of incompressible
+data being emitted in smaller stored blocks, with a correspondingly
+larger relative overhead of up to 15% in the worst case.
+
+    png_set_compression_mem_level(png_ptr, level);
+
+The other functions are for configuring zlib.  They are not recommended
+for normal use and may result in writing an invalid PNG file.  See
+zlib.h for more information on what these mean.
+
+    png_set_compression_strategy(png_ptr,
+        strategy);
+    png_set_compression_window_bits(png_ptr,
+        window_bits);
+    png_set_compression_method(png_ptr, method);
+    png_set_compression_buffer_size(png_ptr, size);
+
+Controlling row filtering
+
+If you want to control whether libpng uses filtering or not, which
+filters are used, and how it goes about picking row filters, you
+can call one of these functions.  The selection and configuration
+of row filters can have a significant impact on the size and
+encoding speed and a somewhat lesser impact on the decoding speed
+of an image.  Filtering is enabled by default for RGB and grayscale
+images (with and without alpha), but not for paletted images nor
+for any images with bit depths less than 8 bits/pixel.
+
+The 'method' parameter sets the main filtering method, which is
+currently only '0' in the PNG 1.2 specification.  The 'filters'
+parameter sets which filter(s), if any, should be used for each
+scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
+to turn filtering on and off, respectively.
+
+Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
+PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.
+If you intend to change the filter type during the course of writing
+the image, you should start with flags set for all of the filters
+you intend to use so that libpng can initialize its internal
+structures appropriately for all of the filter types.  (Note that this
+means the first row must always be adaptively filtered, because libpng
+currently does not allocate the filter buffers until png_write_row()
+is called for the first time.)
+
+    filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+              PNG_FILTER_UP | PNG_FILTER_AVE |
+              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+
+    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
+       filters);
+              The second parameter can also be
+              PNG_INTRAPIXEL_DIFFERENCING if you are
+              writing a PNG to be embedded in a MNG
+              datastream.  This parameter must be the
+              same as the value of filter_method used
+              in png_set_IHDR().
+
+It is also possible to influence how libpng chooses from among the
+available filters.  This is done in one or both of two ways - by
+telling it how important it is to keep the same filter for successive
+rows, and by telling it the relative computational costs of the filters.
+
+    double weights[3] = {1.5, 1.3, 1.1},
+       costs[PNG_FILTER_VALUE_LAST] =
+       {1.0, 1.3, 1.3, 1.5, 1.7};
+
+    png_set_filter_heuristics(png_ptr,
+       PNG_FILTER_HEURISTIC_WEIGHTED, 3,
+       weights, costs);
+
+The weights are multiplying factors that indicate to libpng that the
+row filter should be the same for successive rows unless another row filter
+is that many times better than the previous filter.  In the above example,
+if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
+"sum of absolute differences" 1.5 x 1.3 times higher than other filters
+and still be chosen, while the NONE filter could have a sum 1.1 times
+higher than other filters and still be chosen.  Unspecified weights are
+taken to be 1.0, and the specified weights should probably be declining
+like those above in order to emphasize recent filters over older filters.
+
+The filter costs specify for each filter type a relative decoding cost
+to be considered when selecting row filters.  This means that filters
+with higher costs are less likely to be chosen over filters with lower
+costs, unless their "sum of absolute differences" is that much smaller.
+The costs do not necessarily reflect the exact computational speeds of
+the various filters, since this would unduly influence the final image
+size.
+
+Note that the numbers above were invented purely for this example and
+are given only to help explain the function usage.  Little testing has
+been done to find optimum values for either the costs or the weights.
+
+Removing unwanted object code
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled.  All the defines end in _SUPPORTED.  If you are
+never going to use a capability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space, or
+you can turn off individual capabilities with defines that begin with
+PNG_NO_.
+
+You can also turn all of the transforms and ancillary chunk capabilities
+off en masse with compiler directives that define
+PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
+or all four,
+along with directives to turn on any of the capabilities that you do
+want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
+the extra transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks
+Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
+produces a library that is incapable of reading or writing ancillary chunks.
+If you are not using the progressive reading capability, you can
+turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse
+this with the INTERLACING capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs.  However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with pngr and all the writing files start with
+pngw.  The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections that are actually used will be loaded into memory.
+
+Requesting debug printout
+
+The macro definition PNG_DEBUG can be used to request debugging
+printout.  Set it to an integer value in the range 0 to 3.  Higher
+numbers result in increasing amounts of debugging information.  The
+information is printed to the "stderr" file, unless another file
+name is specified in the PNG_DEBUG_FILE macro definition.
+
+When PNG_DEBUG > 0, the following functions (macros) become available:
+
+   png_debug(level, message)
+   png_debug1(level, message, p1)
+   png_debug2(level, message, p1, p2)
+
+in which "level" is compared to PNG_DEBUG to decide whether to print
+the message, "message" is the formatted string to be printed,
+and p1 and p2 are parameters that are to be embedded in the string
+according to printf-style formatting directives.  For example,
+
+   png_debug1(2, "foo=%d\n", foo);
+
+is expanded to
+
+   if(PNG_DEBUG > 2)
+     fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
+
+When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
+can still use PNG_DEBUG to control your own debugging:
+
+   #ifdef PNG_DEBUG
+       fprintf(stderr, ...
+   #endif
+
+When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
+having level = 0 will be printed.  There aren't any such statements in
+this version of libpng, but if you insert some they will be printed.
+
+VI.  Runtime optimization
+
+A new feature in libpng 1.2.0 is the ability to dynamically switch between
+standard and optimized versions of some routines.  Currently these are
+limited to three computationally intensive tasks when reading PNG files:
+decoding row filters, expanding interlacing, and combining interlaced or
+transparent row data with previous row data.  Currently the optimized
+versions are available only for x86 (Intel, AMD, etc.) platforms with
+MMX support, though this may change in future versions.  (For example,
+the non-MMX assembler optimizations for zlib might become similarly
+runtime-selectable in future releases, in which case libpng could be
+extended to support them.  Alternatively, the compile-time choice of
+floating-point versus integer routines for gamma correction might become
+runtime-selectable.)
+
+Because such optimizations tend to be very platform- and compiler-dependent,
+both in how they are written and in how they perform, the new runtime code
+in libpng has been written to allow programs to query, enable, and disable
+either specific optimizations or all such optimizations.  For example, to
+enable all possible optimizations (bearing in mind that some "optimizations"
+may actually run more slowly in rare cases):
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       png_uint_32 mask, flags;
+
+       flags = png_get_asm_flags(png_ptr);
+       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+       png_set_asm_flags(png_ptr, flags | mask);
+    #endif
+
+To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ
+by itself when calling png_get_asm_flagmask(); similarly for optimizing
+only writing.  To disable all optimizations:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       flags = png_get_asm_flags(png_ptr);
+       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+       png_set_asm_flags(png_ptr, flags & ~mask);
+    #endif
+
+To enable or disable only MMX-related features, use png_get_mmx_flagmask()
+in place of png_get_asm_flagmask().  The mmx version takes one additional
+parameter:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
+       int compilerID;
+
+       mask = png_get_mmx_flagmask(selection, &compilerID);
+    #endif
+
+On return, compilerID will indicate which version of the MMX assembler
+optimizations was compiled.  Currently two flavors exist:  Microsoft
+Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2).
+On non-x86 platforms or on systems compiled without MMX optimizations, a
+value of -1 is used.
+
+Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return
+all valid, settable optimization bits for the version of the library that's
+currently in use.  In the case of shared (dynamically linked) libraries,
+this may include optimizations that did not exist at the time the code was
+written and compiled.  It is also possible, of course, to enable only known,
+specific optimizations; for example:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+             | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+       png_set_asm_flags(png_ptr, flags);
+    #endif
+
+This method would enable only the MMX read-optimizations available at the
+time of libpng 1.2.0's release, regardless of whether a later version of
+the DLL were actually being used.  (Also note that these functions did not
+exist in versions older than 1.2.0, so any attempt to run a dynamically
+linked app on such an older version would fail.)
+
+To determine whether the processor supports MMX instructions at all, use
+the png_mmx_support() function:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       mmxsupport = png_mmx_support();
+    #endif
+
+It returns -1 if MMX support is not compiled into libpng, 0 if MMX code
+is compiled but MMX is not supported by the processor, or 1 if MMX support
+is fully available.  Note that png_mmx_support(), png_get_mmx_flagmask(),
+and png_get_asm_flagmask() all may be called without allocating and ini-
+tializing any PNG structures (for example, as part of a usage screen or
+"about" box).
+
+The following code can be used to prevent an application from using the
+thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK
+defined:
+
+#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
+  && defined(PNG_THREAD_UNSAFE_OK)
+    /* Disable thread-unsafe features of pnggccrd */
+    if (png_access_version() >= 10200)
+    {
+      png_uint_32 mmx_disable_mask = 0;
+      png_uint_32 asm_flags;
+
+      mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
+      asm_flags = png_get_asm_flags(png_ptr);
+      png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
+    }
+#endif
+
+For more extensive examples of runtime querying, enabling and disabling
+of optimized features, see contrib/gregbook/readpng2.c in the libpng
+source-code distribution.
+
+VII.  MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions.  To enable them, use the
+png_permit_mng_features() function:
+
+   feature_set = png_permit_mng_features(png_ptr, mask)
+   mask is a png_uint_32 containing the logical OR of the
+        features you want to enable.  These include
+        PNG_FLAG_MNG_EMPTY_PLTE
+        PNG_FLAG_MNG_FILTER_64
+        PNG_ALL_MNG_FEATURES
+   feature_set is a png_uint_32 that is the logical AND of
+      your mask with the set of MNG features that is
+      supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped
+in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks.  Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them.  You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+VIII.  Changes to Libpng from version 0.88
+
+It should be noted that versions of libpng later than 0.96 are not
+distributed by the original libpng author, Guy Schalnat, nor by
+Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
+distributed versions 0.89 through 0.96, but rather by another member
+of the original PNG Group, Glenn Randers-Pehrson.  Guy and Andreas are
+still alive and well, but they have moved on to other things.
+
+The old libpng functions png_read_init(), png_write_init(),
+png_info_init(), png_read_destroy(), and png_write_destroy() have been
+moved to PNG_INTERNAL in version 0.95 to discourage their use.  These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
+via the png_create_read_struct(), png_create_write_struct(), and
+png_create_info_struct() because they isolate the size of the structures
+from the application, allow version error checking, and also allow the
+use of custom error handling routines during the initialization, which
+the old functions do not.  The functions png_read_destroy() and
+png_write_destroy() do not actually free the memory that libpng
+allocated for these structs, but just reset the data structures, so they
+can be used instead of png_destroy_read_struct() and
+png_destroy_write_struct() if you feel there is too much system overhead
+allocating and freeing the png_struct for each image read.
+
+Setting the error callbacks via png_set_message_fn() before
+png_read_init() as was suggested in libpng-0.88 is no longer supported
+because this caused applications that do not use custom error functions
+to fail if the png_ptr was not initialized to zero.  It is still possible
+to set the error callbacks AFTER png_read_init(), or to change them with
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can find out which version of the library
+you are using at run-time:
+
+   png_uint_32 libpng_vn = png_access_version_number();
+
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
+
+You can also check which version of png.h you used when compiling your
+application:
+
+   png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+IX. Y2K Compliance in libpng
+
+September 12, 2004
+
+Since the PNG Development group is an ad-hoc body, we can't make
+an official declaration.
+
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.2.7 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
+
+Libpng only has three year fields.  One is a 2-byte unsigned integer that
+will hold years up to 65535.  The other two hold the date in text
+format, and will hold years up to 9999.
+
+The integer is
+    "png_uint_16 year" in png_time_struct.
+
+The strings are
+    "png_charp time_buffer" in png_struct and
+    "near_time_buffer", which is a local character string in png.c.
+
+There are seven time-related functions:
+
+    png_convert_to_rfc_1123() in png.c
+      (formerly png_convert_to_rfc_1152() in error)
+    png_convert_from_struct_tm() in pngwrite.c, called
+      in pngwrite.c
+    png_convert_from_time_t() in pngwrite.c
+    png_get_tIME() in pngget.c
+    png_handle_tIME() in pngrutil.c, called in pngread.c
+    png_set_tIME() in pngset.c
+    png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+All appear to handle dates properly in a Y2K environment.  The
+png_convert_from_time_t() function calls gmtime() to convert from system
+clock time, which returns (year - 1900), which we properly convert to
+the full 4-digit year.  There is a possibility that applications using
+libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
+
+The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+integer to hold the year, and can hold years as large as 65535.
+
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
+
+   Glenn Randers-Pehrson
+   libpng maintainer
+   PNG Development Group
diff --git a/Utilities/FLTK/png/libpngpf.3 b/Utilities/FLTK/png/libpngpf.3
new file mode 100644
index 0000000000000000000000000000000000000000..9914fcfd40da6b429cf843fe8239b0d62a51fe65
--- /dev/null
+++ b/Utilities/FLTK/png/libpngpf.3
@@ -0,0 +1,1096 @@
+.TH LIBPNGPF 3 "September 12, 2004"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library 1.2.7
+(private functions)
+.SH SYNOPSIS
+\fB\fB#include <png.h>\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_build_gamma_table (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_build_grayscale_palette (int \fP\fI\fP\fIbit_depth\fP\fB\fP\fB, png_colorp \fI\fIpalette\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_calculate_crc (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIptr\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_check_chunk_name (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fI\fIchunk_name\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_size_t png_check_keyword (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charpp \fI\fInew_key\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_combine_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, int \fI\fImask\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_correct_palette (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_colorp \fP\fI\fP\fIpalette\fP\fB\fP\fB, int \fI\fInum_palette\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBint png_crc_error (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBint png_crc_finish (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIskip\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_crc_read (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_voidp png_create_struct (int \fI\fItype\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_voidp png_create_struct_2 (int \fP\fI\fP\fItype\fP\fB\fP\fB, png_malloc_ptr \fP\fI\fP\fImalloc_fn\fP\fB\fP\fB, png_voidp \fI\fImem_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_charp png_decompress_chunk (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, int \fP\fI\fP\fIcomp_type\fP\fB\fP\fB, png_charp \fP\fI\fP\fIchunkdata\fP\fB\fP\fB, png_size_t \fP\fI\fP\fIchunklength\fP\fB\fP\fB, png_size_t \fP\fI\fP\fIprefix_length\fP\fB\fP\fB, png_size_t \fI\fI*data_length\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_destroy_struct (png_voidp \fI\fIstruct_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_destroy_struct_2 (png_voidp \fP\fI\fP\fIstruct_ptr\fP\fB\fP\fB, png_free_ptr \fP\fI\fP\fIfree_fn\fP\fB\fP\fB, png_voidp \fI\fImem_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_background (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fItrans_values\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fIbackground\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fIbackground_1\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_table\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_from_1\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_to_1\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16_from_1\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16_to_1\fP\fB\fP\fB, int \fI\fIgamma_shift\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_bgr (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_chop (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_dither (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIpalette_lookup\fP\fB\fP\fB, png_bytep \fI\fIdither_lookup\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_expand (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_16p \fI\fItrans_value\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_expand_palette (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_colorp \fP\fI\fP\fIpalette\fP\fB\fP\fB, png_bytep \fP\fI\fP\fItrans\fP\fB\fP\fB, int \fI\fInum_trans\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_gamma (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_table\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16_table\fP\fB\fP\fB, int \fI\fIgamma_shift\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_invert (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_pack (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_uint_32 \fI\fIbit_depth\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_packswap (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_read_filler (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIfiller\fP\fB\fP\fB, png_uint_32 \fI\fIflags\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_read_interlace (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, int \fP\fI\fP\fIpass\fP\fB\fP\fB, png_uint_32 \fI\fItransformations\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_read_transformations (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBint png_do_rgb_to_gray (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_shift (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_8p \fI\fIbit_depth\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_strip_filler (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_uint_32 \fI\fIflags\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_swap (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_unpack (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_unshift (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_8p \fI\fIsig_bits\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_write_interlace (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, int \fI\fIpass\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_do_write_transformations (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fI\fP\fIptr\fP\fB\fP\fB, int \fI\fIcheck\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_flush (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_int_32 png_get_int_32 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_uint_16 png_get_uint_16 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_uint_32 png_get_uint_31 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBpng_uint_32 png_get_uint_32 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_bKGD (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_cHRM (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_gAMA (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_hIST (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_IEND (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_IHDR (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_iCCP (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_iTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_oFFs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_pCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_pHYs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_PLTE (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_sBIT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_sCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_sPLT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_sRGB (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_tIME (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_tRNS (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_unknown (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_handle_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_info_destroy (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_init_mmx_flags (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_init_read_transformations (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_process_IDAT_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuffer\fP\fB\fP\fB, png_size_t \fI\fIbuffer_length\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_process_some_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_check_crc (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_crc_finish (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_crc_skip (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_fill_buffer (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuffer\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_handle_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_handle_unknown (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_handle_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_have_end (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_have_info (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_have_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_process_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_read_chunk (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_read_end (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_read_IDAT (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_read_sig (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_read_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_read_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_restore_buffer (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuffer\fP\fB\fP\fB, png_size_t \fI\fIbuffer_length\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_push_save_buffer (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_read_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIdata\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_read_filter_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIprev_row\fP\fB\fP\fB, int \fI\fIfilter\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_read_finish_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_read_push_finish_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_read_start_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_read_transform_info (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_reset_crc (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_save_int_32 (png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, png_int_32 \fI\fIi\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_save_uint_16 (png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, unsigned int \fI\fIi\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_save_uint_32 (png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, png_uint_32 \fI\fIi\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBint png_set_text_2 (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_textp \fP\fI\fP\fItext_ptr\fP\fB\fP\fB, int \fI\fInum_text)\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_cHRM (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, double \fP\fI\fP\fIwhite_x\fP\fB\fP\fB, double \fP\fI\fP\fIwhite_y\fP\fB\fP\fB, double \fP\fI\fP\fIred_x\fP\fB\fP\fB, double \fP\fI\fP\fIred_y\fP\fB\fP\fB, double \fP\fI\fP\fIgreen_x\fP\fB\fP\fB, double \fP\fI\fP\fIgreen_y\fP\fB\fP\fB, double \fP\fI\fP\fIblue_x\fP\fB\fP\fB, double \fI\fIblue_y\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_cHRM_fixed (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIwhite_x\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIwhite_y\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIred_x\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIred_y\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIgreen_x\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIgreen_y\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIblue_x\fP\fB\fP\fB, png_uint_32 \fI\fIblue_y\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIdata\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_filtered_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fI\fIfiltered_row\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_find_filter (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_row_infop \fI\fIrow_info\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_finish_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_gAMA (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, double \fI\fIfile_gamma\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_gAMA_fixed (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIint_file_gamma\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_hIST (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_16p \fP\fI\fP\fIhist\fP\fB\fP\fB, int \fI\fInum_hist\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_iCCP (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIname\fP\fB\fP\fB, int \fP\fI\fP\fIcompression_type\fP\fB\fP\fB, png_charp \fP\fI\fP\fIprofile\fP\fB\fP\fB, int \fI\fIproflen\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_IDAT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIdata\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_IEND (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_IHDR (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIwidth\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIheight\fP\fB\fP\fB, int \fP\fI\fP\fIbit_depth\fP\fB\fP\fB, int \fP\fI\fP\fIcolor_type\fP\fB\fP\fB, int \fP\fI\fP\fIcompression_type\fP\fB\fP\fB, int \fP\fI\fP\fIfilter_type\fP\fB\fP\fB, int \fI\fIinterlace_type\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_iTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, int \fP\fI\fP\fIcompression\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charp \fP\fI\fP\fIlang\fP\fB\fP\fB, png_charp \fP\fI\fP\fItranslated_key\fP\fB\fP\fB, png_charp \fI\fItext)\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_oFFs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIx_offset\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIy_offset\fP\fB\fP\fB, int \fI\fIunit_type\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_pCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIpurpose\fP\fB\fP\fB, png_int_32 \fP\fI\fP\fIX0\fP\fB\fP\fB, png_int_32 \fP\fI\fP\fIX1\fP\fB\fP\fB, int \fP\fI\fP\fItype\fP\fB\fP\fB, int \fP\fI\fP\fInparams\fP\fB\fP\fB, png_charp \fP\fI\fP\fIunits\fP\fB\fP\fB, png_charpp \fI\fIparams\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_pHYs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIx_pixels_per_unit\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIy_pixels_per_unit\fP\fB\fP\fB, int \fI\fIunit_type\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_PLTE (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_colorp \fP\fI\fP\fIpalette\fP\fB\fP\fB, png_uint_32 \fI\fInum_pal\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_sBIT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_color_8p \fP\fI\fP\fIsbit\fP\fB\fP\fB, int \fI\fIcolor_type\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_sCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIunit\fP\fB\fP\fB, double \fP\fI\fP\fIwidth\fP\fB\fP\fB, double \fI\fIheight\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_sCAL_s (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIunit\fP\fB\fP\fB, png_charp \fP\fI\fP\fIwidth\fP\fB\fP\fB, png_charp \fI\fIheight\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_sig (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_sRGB (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, int \fI\fIintent\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_sPLT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_spalette_p \fI\fIpalette\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_start_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charp \fP\fI\fP\fItext\fP\fB\fP\fB, png_size_t \fI\fItext_len\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_tIME (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_timep \fI\fImod_time\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_tRNS (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fItrans\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fIvalues\fP\fB\fP\fB, int \fP\fI\fP\fInumber\fP\fB\fP\fB, int \fI\fIcolor_type\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_write_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charp \fP\fI\fP\fItext\fP\fB\fP\fB, png_size_t \fP\fI\fP\fItext_len\fP\fB\fP\fB, int \fI\fIcompression\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoidpf png_zalloc (voidpf \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, uInt \fP\fI\fP\fIitems\fP\fB\fP\fB, uInt \fI\fIsize\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+\fB\fBvoid png_zfree (voidpf \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, voidpf \fI\fIptr\fP\fB\fP\fB);\fP\fP
+
+\fI\fB
+
+\fI\fB\fI\fB
+
+\fI\fB
+
+.SH DESCRIPTION
+The functions listed above are used privately by libpng
+and are not recommended for use by applications.  They are
+not "exported" to applications using shared libraries.  They
+are listed alphabetically here as an aid to libpng maintainers.
+See png.h for more information on these functions.
+
+.SH SEE ALSO
+libpng(3), png(5)
+.SH AUTHOR
+Glenn Randers-Pehrson
diff --git a/Utilities/FLTK/png/makedepend b/Utilities/FLTK/png/makedepend
new file mode 100644
index 0000000000000000000000000000000000000000..bbb12e487c40ef7264e56c37df50e7d5bdf6c4e2
--- /dev/null
+++ b/Utilities/FLTK/png/makedepend
@@ -0,0 +1,17 @@
+# DO NOT DELETE
+
+png.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
diff --git a/Utilities/FLTK/png/makefile.wat b/Utilities/FLTK/png/makefile.wat
new file mode 100644
index 0000000000000000000000000000000000000000..b1b9e334e603ba0e386bb46e175650c4e691fb22
--- /dev/null
+++ b/Utilities/FLTK/png/makefile.wat
@@ -0,0 +1,64 @@
+#
+# "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $"
+#
+# PNG library makefile for the Fast Light Toolkit (FLTK).
+#
+# Copyright 1997-2004 by Easy Software Products.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+LIBNAMEROOT=ftlk_png
+# I ought to be able to do "EXTRA_INCLUDE_DIRS += ;../zlib" but it doesn't work for me (OW1.3)
+!undef EXTRA_INCLUDE_DIRS
+EXTRA_INCLUDE_DIRS=$(ROOT);../zlib
+
+!include ../watcom.mif
+
+
+#
+# Object files...
+#
+
+LIBOBJS = png.obj pngset.obj pngget.obj pngrutil.obj pngtrans.obj pngwutil.obj &
+          pngread.obj pngrio.obj pngwio.obj pngwrite.obj pngrtran.obj &
+          pngwtran.obj pngmem.obj pngerror.obj pngpread.obj
+
+
+#
+# Make all targets...
+#
+
+all: $(LIBNAME)
+
+$(LIBNAME): $(LIBOBJS)
+    $(LIB) $(LIBOPTS) $@ $<
+
+#
+# Clean all directories
+#
+clean : .SYMBOLIC
+    @echo Cleaning up.
+CLEANEXTS = obj
+    @for %a in ($(CLEANEXTS)) do -rm -f $(ODIR)\*.%a
+    -rm -f *.err
+    -rm -f $(LIBNAME)
+
+#
+# End of "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $".
+#
diff --git a/Utilities/FLTK/png/png.5 b/Utilities/FLTK/png/png.5
new file mode 100644
index 0000000000000000000000000000000000000000..1cc5ef4f99efb0daffb31e5ebc976e6a2f6cc719
--- /dev/null
+++ b/Utilities/FLTK/png/png.5
@@ -0,0 +1,74 @@
+.TH PNG 5 "September 12, 2004"
+.SH NAME
+png \- Portable Network Graphics (PNG) format
+.SH DESCRIPTION
+PNG (Portable Network Graphics) is an extensible file format for the
+lossless, portable, well-compressed storage of raster images. PNG provides
+a patent-free replacement for GIF and can also replace many
+common uses of TIFF. Indexed-color, grayscale, and truecolor images are
+supported, plus an optional alpha channel. Sample depths range from
+1 to 16 bits.
+.br
+
+PNG is designed to work well in online viewing applications, such as the
+World Wide Web, so it is fully streamable with a progressive display
+option. PNG is robust, providing both full file integrity checking and
+fast, simple detection of common transmission errors. Also, PNG can store
+gamma and chromaticity data for improved color matching on heterogeneous
+platforms.
+
+.SH "SEE ALSO"
+.IR libpng(3), zlib(3), deflate(5), and zlib(5)
+.LP
+PNG specification (second edition), November 2003:
+.IP
+.br
+  <http://www.w3.org/TR/2003/REC-PNG-20031110/
+PNG 1.2 specification, July 1999:
+.IP
+.br
+http://www.libpng.org/pub/png
+.LP
+PNG 1.0 specification, October 1996:
+.IP
+.br
+RFC 2083
+.IP
+.br
+ftp://ds.internic.net/rfc/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+.LP
+Portable Network Graphics (PNG) Specification (Second Edition)
+Information technology - Computer graphics and image processing -
+Portable Network Graphics (PNG): Functional specification.
+ISO/IEC 15948:2003 (E) (November 10, 2003): David Duce and others.
+.LP
+Portable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999):
+Glenn Randers-Pehrson and others (png-list).
+.LP
+Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
+Thomas Boutell and others (png-list).
+.LP
+
+
+.SH COPYRIGHT NOTICE
+.LP
+This man page is Copyright (c) 1998-2004 Glenn Randers-Pehrson.  See png.h
+for conditions of use and distribution.
+.LP
+The PNG Specification (Second Edition) is
+Copyright (c) 2003 W3C. (MIT, ERCIM, Keio), All Rights Reserved.
+.LP
+The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson.
+See the specification for conditions of use and distribution.
+.LP
+The PNG-1.0 specification is copyright (c) 1996 Massachusetts Institute of
+Technology.  See the specification for conditions of use and distribution.
+.LP
+.\" end of man page
+
diff --git a/Utilities/FLTK/png/png.c b/Utilities/FLTK/png/png.c
new file mode 100644
index 0000000000000000000000000000000000000000..75099d5ed21f90538dfdd282e57c205195fc1071
--- /dev/null
+++ b/Utilities/FLTK/png/png.c
@@ -0,0 +1,826 @@
+
+/* png.c - location for general purpose libpng functions
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_EXTERN
+#include "png.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_7 Your_png_h_is_not_version_1_2_7;
+
+/* Version information for C files.  This had better match the version
+ * string defined in png.h.  */
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* png_libpng_ver was changed to a function in version 1.0.5c */
+const char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
+
+/* png_sig was changed to a function in version 1.0.5c */
+/* Place to hold the signature string for a PNG file. */
+const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+/* Invoke global declarations for constant strings for known chunk types */
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_iCCP;
+PNG_iTXt;
+PNG_oFFs;
+PNG_pCAL;
+PNG_sCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sPLT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
+
+/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+/* start of interlace block */
+const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+/* offset to next interlace block */
+const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+/* start of interlace block in the y direction */
+const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+/* offset to next interlace block in the y direction */
+const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+/* width of interlace block (used in assembler routines only) */
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+#endif
+
+/* Height of interlace block.  This is not currently used - if you need
+ * it, uncomment it here and in png.h
+const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+*/
+
+/* Mask to determine which pixels are valid in a pass */
+const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+
+/* Mask to determine which pixels to overwrite while displaying */
+const int FARDATA png_pass_dsp_mask[]
+   = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+
+#endif
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature.  If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+void PNGAPI
+png_set_sig_bytes(png_structp png_ptr, int num_bytes)
+{
+   png_debug(1, "in png_set_sig_bytes\n");
+   if (num_bytes > 8)
+      png_error(png_ptr, "Too many bytes for PNG signature.");
+
+   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+}
+
+/* Checks whether the supplied bytes match the PNG signature.  We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance.  Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+   if (num_to_check > 8)
+      num_to_check = 8;
+   else if (num_to_check < 1)
+      return (0);
+
+   if (start > 7)
+      return (0);
+
+   if (start + num_to_check > 8)
+      num_to_check = 8 - start;
+
+   return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+/* (Obsolete) function to check signature bytes.  It does not allow one
+ * to check a partial signature.  This function might be removed in the
+ * future - use png_sig_cmp().  Returns true (nonzero) if the file is a PNG.
+ */
+int PNGAPI
+png_check_sig(png_bytep sig, int num)
+{
+  return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
+}
+
+/* Function to allocate memory for zlib and clear it to 0. */
+#ifdef PNG_1_0_X
+voidpf PNGAPI
+#else
+voidpf /* private */
+#endif
+png_zalloc(voidpf png_ptr, uInt items, uInt size)
+{
+   png_voidp ptr;
+   png_structp p=png_ptr;
+   png_uint_32 save_flags=p->flags;
+   png_uint_32 num_bytes;
+
+   if (items > PNG_UINT_32_MAX/size)
+   {
+     png_warning (png_ptr, "Potential overflow in png_zalloc()");
+     return (NULL);
+   }
+   num_bytes = (png_uint_32)items * size;
+
+   p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+   ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
+   p->flags=save_flags;
+
+#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
+   if (ptr == NULL)
+       return ((voidpf)ptr);
+
+   if (num_bytes > (png_uint_32)0x8000L)
+   {
+      png_memset(ptr, 0, (png_size_t)0x8000L);
+      png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
+         (png_size_t)(num_bytes - (png_uint_32)0x8000L));
+   }
+   else
+   {
+      png_memset(ptr, 0, (png_size_t)num_bytes);
+   }
+#endif
+   return ((voidpf)ptr);
+}
+
+/* function to free memory for zlib */
+#ifdef PNG_1_0_X
+void PNGAPI
+#else
+void /* private */
+#endif
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+   png_free((png_structp)png_ptr, (png_voidp)ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structp png_ptr)
+{
+   png_ptr->crc = crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data.  We can only pass as
+ * much data to this routine as the largest single buffer size.  We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
+{
+   int need_crc = 1;
+
+   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+   else                                                    /* critical */
+   {
+      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+         need_crc = 0;
+   }
+
+   if (need_crc)
+      png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
+}
+
+/* Allocate the memory for an info_struct for the application.  We don't
+ * really need the png_ptr, but it could potentially be useful in the
+ * future.  This should be used in favour of malloc(png_sizeof(png_info))
+ * and png_info_init() so that applications that want to use a shared
+ * libpng don't have to be recompiled if png_info changes size.
+ */
+png_infop PNGAPI
+png_create_info_struct(png_structp png_ptr)
+{
+   png_infop info_ptr;
+
+   png_debug(1, "in png_create_info_struct\n");
+   if(png_ptr == NULL) return (NULL);
+#ifdef PNG_USER_MEM_SUPPORTED
+   info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
+      png_ptr->malloc_fn, png_ptr->mem_ptr);
+#else
+   info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+#endif
+   if (info_ptr != NULL)
+      png_info_init_3(&info_ptr, png_sizeof(png_info));
+
+   return (info_ptr);
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications.
+ */
+void PNGAPI
+png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
+{
+   png_infop info_ptr = NULL;
+
+   png_debug(1, "in png_destroy_info_struct\n");
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (info_ptr != NULL)
+   {
+      png_info_destroy(png_ptr, info_ptr);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
+          png_ptr->mem_ptr);
+#else
+      png_destroy_struct((png_voidp)info_ptr);
+#endif
+      *info_ptr_ptr = NULL;
+   }
+}
+
+/* Initialize the info structure.  This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead.
+ */
+#undef png_info_init
+void PNGAPI
+png_info_init(png_infop info_ptr)
+{
+   /* We only come here via pre-1.0.12-compiled applications */
+   png_info_init_3(&info_ptr, 0);
+}
+
+void PNGAPI
+png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
+{
+   png_infop info_ptr = *ptr_ptr;
+
+   png_debug(1, "in png_info_init_3\n");
+
+   if(png_sizeof(png_info) > png_info_struct_size)
+     {
+       png_destroy_struct(info_ptr);
+       info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+       *ptr_ptr = info_ptr;
+     }
+
+   /* set everything to 0 */
+   png_memset(info_ptr, 0, png_sizeof (png_info));
+}
+
+#ifdef PNG_FREE_ME_SUPPORTED
+void PNGAPI
+png_data_freer(png_structp png_ptr, png_infop info_ptr,
+   int freer, png_uint_32 mask)
+{
+   png_debug(1, "in png_data_freer\n");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+   if(freer == PNG_DESTROY_WILL_FREE_DATA)
+      info_ptr->free_me |= mask;
+   else if(freer == PNG_USER_WILL_FREE_DATA)
+      info_ptr->free_me &= ~mask;
+   else
+      png_warning(png_ptr,
+         "Unknown freer parameter in png_data_freer.");
+}
+#endif
+
+void PNGAPI
+png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
+   int num)
+{
+   png_debug(1, "in png_free_data\n");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+#if defined(PNG_TEXT_SUPPORTED)
+/* free text item num or (if num == -1) all text items */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_TEXT)
+#endif
+{
+   if (num != -1)
+   {
+     if (info_ptr->text && info_ptr->text[num].key)
+     {
+         png_free(png_ptr, info_ptr->text[num].key);
+         info_ptr->text[num].key = NULL;
+     }
+   }
+   else
+   {
+       int i;
+       for (i = 0; i < info_ptr->num_text; i++)
+           png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
+       png_free(png_ptr, info_ptr->text);
+       info_ptr->text = NULL;
+       info_ptr->num_text=0;
+   }
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+/* free any tRNS entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
+#endif
+{
+    png_free(png_ptr, info_ptr->trans);
+    info_ptr->valid &= ~PNG_INFO_tRNS;
+#ifndef PNG_FREE_ME_SUPPORTED
+    png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+    info_ptr->trans = NULL;
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+/* free any sCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_SCAL)
+#endif
+{
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+    png_free(png_ptr, info_ptr->scal_s_width);
+    png_free(png_ptr, info_ptr->scal_s_height);
+    info_ptr->scal_s_width = NULL;
+    info_ptr->scal_s_height = NULL;
+#endif
+    info_ptr->valid &= ~PNG_INFO_sCAL;
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+/* free any pCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_PCAL)
+#endif
+{
+    png_free(png_ptr, info_ptr->pcal_purpose);
+    png_free(png_ptr, info_ptr->pcal_units);
+    info_ptr->pcal_purpose = NULL;
+    info_ptr->pcal_units = NULL;
+    if (info_ptr->pcal_params != NULL)
+    {
+        int i;
+        for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+        {
+          png_free(png_ptr, info_ptr->pcal_params[i]);
+          info_ptr->pcal_params[i]=NULL;
+        }
+        png_free(png_ptr, info_ptr->pcal_params);
+        info_ptr->pcal_params = NULL;
+    }
+    info_ptr->valid &= ~PNG_INFO_pCAL;
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+/* free any iCCP entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_ICCP)
+#endif
+{
+    png_free(png_ptr, info_ptr->iccp_name);
+    png_free(png_ptr, info_ptr->iccp_profile);
+    info_ptr->iccp_name = NULL;
+    info_ptr->iccp_profile = NULL;
+    info_ptr->valid &= ~PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+/* free a given sPLT entry, or (if num == -1) all sPLT entries */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_SPLT)
+#endif
+{
+   if (num != -1)
+   {
+      if(info_ptr->splt_palettes)
+      {
+          png_free(png_ptr, info_ptr->splt_palettes[num].name);
+          png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+          info_ptr->splt_palettes[num].name = NULL;
+          info_ptr->splt_palettes[num].entries = NULL;
+      }
+   }
+   else
+   {
+       if(info_ptr->splt_palettes_num)
+       {
+         int i;
+         for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+            png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
+
+         png_free(png_ptr, info_ptr->splt_palettes);
+         info_ptr->splt_palettes = NULL;
+         info_ptr->splt_palettes_num = 0;
+       }
+       info_ptr->valid &= ~PNG_INFO_sPLT;
+   }
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_UNKN)
+#endif
+{
+   if (num != -1)
+   {
+       if(info_ptr->unknown_chunks)
+       {
+          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+          info_ptr->unknown_chunks[num].data = NULL;
+       }
+   }
+   else
+   {
+       int i;
+
+       if(info_ptr->unknown_chunks_num)
+       {
+         for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
+            png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
+
+         png_free(png_ptr, info_ptr->unknown_chunks);
+         info_ptr->unknown_chunks = NULL;
+         info_ptr->unknown_chunks_num = 0;
+       }
+   }
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+/* free any hIST entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
+#endif
+{
+    png_free(png_ptr, info_ptr->hist);
+    info_ptr->hist = NULL;
+    info_ptr->valid &= ~PNG_INFO_hIST;
+#ifndef PNG_FREE_ME_SUPPORTED
+    png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+/* free any PLTE entry that was internally allocated */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
+#endif
+{
+    png_zfree(png_ptr, info_ptr->palette);
+    info_ptr->palette = NULL;
+    info_ptr->valid &= ~PNG_INFO_PLTE;
+#ifndef PNG_FREE_ME_SUPPORTED
+    png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+    info_ptr->num_palette = 0;
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* free any image bits attached to the info structure */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_ROWS)
+#endif
+{
+    if(info_ptr->row_pointers)
+    {
+       int row;
+       for (row = 0; row < (int)info_ptr->height; row++)
+       {
+          png_free(png_ptr, info_ptr->row_pointers[row]);
+          info_ptr->row_pointers[row]=NULL;
+       }
+       png_free(png_ptr, info_ptr->row_pointers);
+       info_ptr->row_pointers=NULL;
+    }
+    info_ptr->valid &= ~PNG_INFO_IDAT;
+}
+#endif
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   if(num == -1)
+     info_ptr->free_me &= ~mask;
+   else
+     info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
+#endif
+}
+
+/* This is an internal routine to free any memory that the info struct is
+ * pointing to before re-using it or freeing the struct itself.  Recall
+ * that png_free() checks for NULL pointers for us.
+ */
+void /* PRIVATE */
+png_info_destroy(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_info_destroy\n");
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+   if (png_ptr->num_chunk_list)
+   {
+       png_free(png_ptr, png_ptr->chunk_list);
+       png_ptr->chunk_list=NULL;
+       png_ptr->num_chunk_list=0;
+   }
+#endif
+
+   png_info_init_3(&info_ptr, png_sizeof(png_info));
+}
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_structp png_ptr)
+{
+   return (png_ptr->io_ptr);
+}
+
+#if !defined(PNG_NO_STDIO)
+/* Initialize the default input/output functions for the PNG file.  If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io().  If you have defined
+ * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
+ * necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structp png_ptr, png_FILE_p fp)
+{
+   png_debug(1, "in png_init_io\n");
+   png_ptr->io_ptr = (png_voidp)fp;
+}
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+png_charp PNGAPI
+png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
+{
+   static PNG_CONST char short_months[12][4] =
+        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+   if (png_ptr->time_buffer == NULL)
+   {
+      png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
+         png_sizeof(char)));
+   }
+
+#if defined(_WIN32_WCE)
+   {
+      wchar_t time_buf[29];
+      wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
+          ptime->day % 32, short_months[(ptime->month - 1) % 12],
+        ptime->year, ptime->hour % 24, ptime->minute % 60,
+          ptime->second % 61);
+      WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
+          NULL, NULL);
+   }
+#else
+#ifdef USE_FAR_KEYWORD
+   {
+      char near_time_buf[29];
+      sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
+          ptime->day % 32, short_months[(ptime->month - 1) % 12],
+          ptime->year, ptime->hour % 24, ptime->minute % 60,
+          ptime->second % 61);
+      png_memcpy(png_ptr->time_buffer, near_time_buf,
+          29*png_sizeof(char));
+   }
+#else
+   sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
+       ptime->day % 32, short_months[(ptime->month - 1) % 12],
+       ptime->year, ptime->hour % 24, ptime->minute % 60,
+       ptime->second % 61);
+#endif
+#endif /* _WIN32_WCE */
+   return ((png_charp)png_ptr->time_buffer);
+}
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#if 0
+/* Signature string for a PNG file. */
+png_bytep PNGAPI
+png_sig_bytes(void)
+{
+   return ((png_bytep)"\211\120\116\107\015\012\032\012");
+}
+#endif
+
+png_charp PNGAPI
+png_get_copyright(png_structp png_ptr)
+{
+   if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
+   return ((png_charp) "\n libpng version 1.2.7 - September 12, 2004\n\
+   Copyright (c) 1998-2005 Glenn Randers-Pehrson\n\
+   Copyright (c) 1996-1997 Andreas Dilger\n\
+   Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
+   return ((png_charp) "");
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
+ * used with your application, print out PNG_LIBPNG_VER_STRING, which
+ * is defined in png.h.
+ * Note: now there is no difference between png_get_libpng_ver() and
+ * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
+ * it is guaranteed that png.c uses the correct version of png.h.
+ */
+png_charp PNGAPI
+png_get_libpng_ver(png_structp png_ptr)
+{
+   /* Version of *.c files used when building libpng */
+   if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
+      return ((png_charp) PNG_LIBPNG_VER_STRING);
+   return ((png_charp) "");
+}
+
+png_charp PNGAPI
+png_get_header_ver(png_structp png_ptr)
+{
+   /* Version of *.h files used when building libpng */
+   if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
+      return ((png_charp) PNG_LIBPNG_VER_STRING);
+   return ((png_charp) "");
+}
+
+png_charp PNGAPI
+png_get_header_version(png_structp png_ptr)
+{
+   /* Returns longer string containing both version and date */
+   if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
+      return ((png_charp) PNG_HEADER_VERSION_STRING);
+   return ((png_charp) "");
+}
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
+{
+   /* check chunk_name and return "keep" value if it's on the list, else 0 */
+   int i;
+   png_bytep p;
+   if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0)
+      return 0;
+   p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
+   for (i = png_ptr->num_chunk_list; i; i--, p-=5)
+      if (!png_memcmp(chunk_name, p, 4))
+        return ((int)*(p+4));
+   return 0;
+}
+#endif
+
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structp png_ptr)
+{
+   return (inflateReset(&png_ptr->zstream));
+}
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+   /* Version of *.c files used when building libpng */
+   return((png_uint_32) PNG_LIBPNG_VER);
+}
+
+
+#if !defined(PNG_1_0_X)
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+    /* GRR:  could add this:   && defined(PNG_MMX_CODE_SUPPORTED) */
+/* this INTERNAL function was added to libpng 1.2.0 */
+void /* PRIVATE */
+png_init_mmx_flags (png_structp png_ptr)
+{
+    png_ptr->mmx_rowbytes_threshold = 0;
+    png_ptr->mmx_bitdepth_threshold = 0;
+
+#  if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD))
+
+    png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;
+
+    if (png_mmx_support() > 0) {
+        png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
+#    ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+                              | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
+#    endif
+#    ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
+                              | PNG_ASM_FLAG_MMX_READ_INTERLACE
+#    endif
+#    ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+                              ;
+#    else
+                              | PNG_ASM_FLAG_MMX_READ_FILTER_SUB
+                              | PNG_ASM_FLAG_MMX_READ_FILTER_UP
+                              | PNG_ASM_FLAG_MMX_READ_FILTER_AVG
+                              | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+
+        png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT;
+        png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT;
+#    endif
+    } else {
+        png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
+                               | PNG_MMX_READ_FLAGS
+                               | PNG_MMX_WRITE_FLAGS );
+    }
+
+#  else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */
+
+    /* clear all MMX flags; no support is compiled in */
+    png_ptr->asm_flags &= ~( PNG_MMX_FLAGS );
+
+#  endif /* ?(PNGVCRD || PNGGCCRD) */
+}
+
+#endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */
+
+/* this function was added to libpng 1.2.0 */
+#if !defined(PNG_USE_PNGGCCRD) && \
+    !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
+int PNGAPI
+png_mmx_support(void)
+{
+    return -1;
+}
+#endif
+#endif /* PNG_1_0_X */
+
+#ifdef PNG_SIZE_T
+/* Added at libpng version 1.2.6 */
+   PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
+png_size_t PNGAPI
+png_convert_size(size_t size)
+{
+  if (size > (png_size_t)-1)
+     PNG_ABORT();  /* We haven't got access to png_ptr, so no png_error() */
+  return ((png_size_t)size);
+}
+#endif /* PNG_SIZE_T */
diff --git a/Utilities/FLTK/png/png.h b/Utilities/FLTK/png/png.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5adadff5bca2aee115491136a92c3ec4887a8e5
--- /dev/null
+++ b/Utilities/FLTK/png/png.h
@@ -0,0 +1,3361 @@
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Authors and maintainers:
+ *  libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ *  libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ *  libpng versions 0.97, January 1998, through 1.2.7 - September 12, 2004: Glenn
+ *  See also "Contributing Authors", below.
+ *
+ * Note about libpng version numbers:
+ *
+ *    Due to various miscommunications, unforeseen code incompatibilities
+ *    and occasional factors outside the authors' control, version numbering
+ *    on the library has not always been consistent and straightforward.
+ *    The following table summarizes matters since version 0.89c, which was
+ *    the first widely used release:
+ *
+ *    source                 png.h  png.h  shared-lib
+ *    version                string   int  version
+ *    -------                ------ -----  ----------
+ *    0.89c "1.0 beta 3"     0.89      89  1.0.89
+ *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
+ *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
+ *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
+ *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
+ *    0.97c                  0.97      97  2.0.97
+ *    0.98                   0.98      98  2.0.98
+ *    0.99                   0.99      98  2.0.99
+ *    0.99a-m                0.99      99  2.0.99
+ *    1.00                   1.00     100  2.1.0 [100 should be 10000]
+ *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
+ *    1.0.1       png.h string is   10001  2.1.0
+ *    1.0.1a-e    identical to the  10002  from here on, the shared library
+ *    1.0.2       source version)   10002  is 2.V where V is the source code
+ *    1.0.2a-b                      10003  version, except as noted.
+ *    1.0.3                         10003
+ *    1.0.3a-d                      10004
+ *    1.0.4                         10004
+ *    1.0.4a-f                      10005
+ *    1.0.5 (+ 2 patches)           10005
+ *    1.0.5a-d                      10006
+ *    1.0.5e-r                      10100 (not source compatible)
+ *    1.0.5s-v                      10006 (not binary compatible)
+ *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
+ *    1.0.6d-f                      10007 (still binary incompatible)
+ *    1.0.6g                        10007
+ *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
+ *    1.0.6i                        10007  10.6i
+ *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
+ *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
+ *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
+ *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
+ *    1.0.7                    1    10007  (still compatible)
+ *    1.0.8beta1-4             1    10008  2.1.0.8beta1-4
+ *    1.0.8rc1                 1    10008  2.1.0.8rc1
+ *    1.0.8                    1    10008  2.1.0.8
+ *    1.0.9beta1-6             1    10009  2.1.0.9beta1-6
+ *    1.0.9rc1                 1    10009  2.1.0.9rc1
+ *    1.0.9beta7-10            1    10009  2.1.0.9beta7-10
+ *    1.0.9rc2                 1    10009  2.1.0.9rc2
+ *    1.0.9                    1    10009  2.1.0.9
+ *    1.0.10beta1              1    10010  2.1.0.10beta1
+ *    1.0.10rc1                1    10010  2.1.0.10rc1
+ *    1.0.10                   1    10010  2.1.0.10
+ *    1.0.11beta1-3            1    10011  2.1.0.11beta1-3
+ *    1.0.11rc1                1    10011  2.1.0.11rc1
+ *    1.0.11                   1    10011  2.1.0.11
+ *    1.0.12beta1-2            2    10012  2.1.0.12beta1-2
+ *    1.0.12rc1                2    10012  2.1.0.12rc1
+ *    1.0.12                   2    10012  2.1.0.12
+ *    1.1.0a-f                 -    10100  2.1.1.0a-f (branch abandoned)
+ *    1.2.0beta1-2             2    10200  2.1.2.0beta1-2
+ *    1.2.0beta3-5             3    10200  3.1.2.0beta3-5
+ *    1.2.0rc1                 3    10200  3.1.2.0rc1
+ *    1.2.0                    3    10200  3.1.2.0
+ *    1.2.1beta1-4             3    10201  3.1.2.1beta1-4
+ *    1.2.1rc1-2               3    10201  3.1.2.1rc1-2
+ *    1.2.1                    3    10201  3.1.2.1
+ *    1.2.2beta1-6            12    10202  12.so.0.1.2.2beta1-6
+ *    1.0.13beta1             10    10013  10.so.0.1.0.13beta1
+ *    1.0.13rc1               10    10013  10.so.0.1.0.13rc1
+ *    1.2.2rc1                12    10202  12.so.0.1.2.2rc1
+ *    1.0.13                  10    10013  10.so.0.1.0.13
+ *    1.2.2                   12    10202  12.so.0.1.2.2
+ *    1.2.3rc1-6              12    10203  12.so.0.1.2.3rc1-6
+ *    1.2.3                   12    10203  12.so.0.1.2.3
+ *    1.2.4beta1-3            13    10204  12.so.0.1.2.4beta1-3
+ *    1.0.14rc1               13    10014  10.so.0.1.0.14rc1
+ *    1.2.4rc1                13    10204  12.so.0.1.2.4rc1
+ *    1.0.14                  10    10014  10.so.0.1.0.14
+ *    1.2.4                   13    10204  12.so.0.1.2.4
+ *    1.2.5beta1-2            13    10205  12.so.0.1.2.5beta1-2
+ *    1.0.15rc1-3             10    10015  10.so.0.1.0.15rc1-3
+ *    1.2.5rc1-3              13    10205  12.so.0.1.2.5rc1-3
+ *    1.0.15                  10    10015  10.so.0.1.0.15
+ *    1.2.5                   13    10205  12.so.0.1.2.5
+ *    1.2.6beta1-4            13    10206  12.so.0.1.2.6beta1-4
+ *    1.0.16                  10    10016  10.so.0.1.0.16
+ *    1.2.6                   13    10206  12.so.0.1.2.6
+ *    1.2.7beta1-2            13    10207  12.so.0.1.2.7beta1-2
+ *    1.0.17rc1               10    10017  12.so.0.1.0.17rc1
+ *    1.2.7rc1                13    10207  12.so.0.1.2.7rc1
+ *    1.0.17                  10    10017  12.so.0.1.0.17
+ *    1.2.7                   13    10207  12.so.0.1.2.7
+ *
+ *    Henceforth the source version will match the shared-library major
+ *    and minor numbers; the shared-library major version number will be
+ *    used for changes in backward compatibility, as it is intended.  The
+ *    PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ *    for applications, is an unsigned integer of the form xyyzz corresponding
+ *    to the source version x.y.z (leading zeros in y and z).  Beta versions
+ *    were given the previous public release number plus a letter, until
+ *    version 1.0.6j; from then on they were given the upcoming public
+ *    release number plus "betaNN" or "rcN".
+ *
+ *    Binary incompatibility exists only when applications make direct access
+ *    to the info_ptr or png_ptr members through png.h, and the compiled
+ *    application is loaded with a different version of the library.
+ *
+ *    DLLNUM will change each time there are forward or backward changes
+ *    in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng.txt or libpng.3 for more information.  The PNG specification
+ * is available as a W3C Recommendation and as an ISO Specification,
+ * <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * libpng versions 1.2.6, August 15, 2004, through 1.2.7, September 12, 2004, are
+ * Copyright (c) 2004 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.2.5
+ * with the following individual added to the list of Contributing Authors:
+ *
+ *    Cosmin Truta
+ *
+ * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+ * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    Simon-Pierre Cadieux
+ *    Eric S. Raymond
+ *    Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ *    There is no warranty against interference with your enjoyment of the
+ *    library or against infringement.  There is no warranty that our
+ *    efforts or the library will fulfill any of your particular purposes
+ *    or needs.  This library is provided with all faults, and the entire
+ *    risk of satisfactory quality, performance, accuracy, and effort is with
+ *    the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    Tom Lane
+ *    Glenn Randers-Pehrson
+ *    Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    John Bowler
+ *    Kevin Bracey
+ *    Sam Bushell
+ *    Magnus Holmgren
+ *    Greg Roelofs
+ *    Tom Tanner
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ *    Andreas Dilger
+ *    Dave Martindale
+ *    Guy Eric Schalnat
+ *    Paul Schmidt
+ *    Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ * 1. The origin of this source code must not be misrepresented.
+ *
+ * 2. Altered versions must be plainly marked as such and
+ * must not be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from
+ *    any source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products.  If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s",png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * Libpng is OSI Certified Open Source Software.  OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience.  This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ *    September 12, 2004
+ *
+ *    Since the PNG Development group is an ad-hoc body, we can't make
+ *    an official declaration.
+ *
+ *    This is your unofficial assurance that libpng from version 0.71 and
+ *    upward through 1.2.7 are Y2K compliant.  It is my belief that earlier
+ *    versions were also Y2K compliant.
+ *
+ *    Libpng only has three year fields.  One is a 2-byte unsigned integer
+ *    that will hold years up to 65535.  The other two hold the date in text
+ *    format, and will hold years up to 9999.
+ *
+ *    The integer is
+ *        "png_uint_16 year" in png_time_struct.
+ *
+ *    The strings are
+ *        "png_charp time_buffer" in png_struct and
+ *        "near_time_buffer", which is a local character string in png.c.
+ *
+ *    There are seven time-related functions:
+ *        png.c: png_convert_to_rfc_1123() in png.c
+ *          (formerly png_convert_to_rfc_1152() in error)
+ *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ *        png_convert_from_time_t() in pngwrite.c
+ *        png_get_tIME() in pngget.c
+ *        png_handle_tIME() in pngrutil.c, called in pngread.c
+ *        png_set_tIME() in pngset.c
+ *        png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ *    All handle dates properly in a Y2K environment.  The
+ *    png_convert_from_time_t() function calls gmtime() to convert from system
+ *    clock time, which returns (year - 1900), which we properly convert to
+ *    the full 4-digit year.  There is a possibility that applications using
+ *    libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ *    function, or that they are incorrectly passing only a 2-digit year
+ *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ *    but this is not under our control.  The libpng documentation has always
+ *    stated that it works with 4-digit years, and the APIs have been
+ *    documented as such.
+ *
+ *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+ *    integer to hold the year, and can hold years as large as 65535.
+ *
+ *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
+ *    no date-related code.
+ *
+ *       Glenn Randers-Pehrson
+ *       libpng maintainer
+ *       PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+/* This is not the place to learn how to use libpng.  The file libpng.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build.  This file is useful for looking
+ * at the actual function definitions and structure components.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.2.7"
+#define PNG_HEADER_VERSION_STRING \
+   " libpng version 1.2.7 - September 12, 2004 (header)\n"
+
+#define PNG_LIBPNG_VER_SONUM   0
+#define PNG_LIBPNG_VER_DLLNUM  %DLLNUM%
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR   1
+#define PNG_LIBPNG_VER_MINOR   2
+#define PNG_LIBPNG_VER_RELEASE 7
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
+
+#define PNG_LIBPNG_VER_BUILD  0
+
+#define PNG_LIBPNG_BUILD_ALPHA    1
+#define PNG_LIBPNG_BUILD_BETA     2
+#define PNG_LIBPNG_BUILD_RC       3
+#define PNG_LIBPNG_BUILD_STABLE   4
+#define PNG_LIBPNG_BUILD_TYPEMASK 7
+#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with STABLE only */
+#define PNG_LIBPNG_BUILD_TYPE 4
+
+/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000).  From
+ * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release */
+#define PNG_LIBPNG_VER 10207 /* 1.2.7 */
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* include the compression library's header */
+#include "zlib.h"
+
+/* include all user configurable info, including optional assembler routines */
+#include "pngconf.h"
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This file is arranged in several sections.  The first section contains
+ * structure and type definitions.  The second section contains the external
+ * library functions, while the third has the internal library functions,
+ * which applications aren't expected to use directly.
+ */
+
+#ifndef PNG_NO_TYPECAST_NULL
+#define int_p_NULL                (int *)NULL
+#define png_bytep_NULL            (png_bytep)NULL
+#define png_bytepp_NULL           (png_bytepp)NULL
+#define png_doublep_NULL          (png_doublep)NULL
+#define png_error_ptr_NULL        (png_error_ptr)NULL
+#define png_flush_ptr_NULL        (png_flush_ptr)NULL
+#define png_free_ptr_NULL         (png_free_ptr)NULL
+#define png_infopp_NULL           (png_infopp)NULL
+#define png_malloc_ptr_NULL       (png_malloc_ptr)NULL
+#define png_read_status_ptr_NULL  (png_read_status_ptr)NULL
+#define png_rw_ptr_NULL           (png_rw_ptr)NULL
+#define png_structp_NULL          (png_structp)NULL
+#define png_uint_16p_NULL         (png_uint_16p)NULL
+#define png_voidp_NULL            (png_voidp)NULL
+#define png_write_status_ptr_NULL (png_write_status_ptr)NULL
+#else
+#define int_p_NULL                NULL
+#define png_bytep_NULL            NULL
+#define png_bytepp_NULL           NULL
+#define png_doublep_NULL          NULL
+#define png_error_ptr_NULL        NULL
+#define png_flush_ptr_NULL        NULL
+#define png_free_ptr_NULL         NULL
+#define png_infopp_NULL           NULL
+#define png_malloc_ptr_NULL       NULL
+#define png_read_status_ptr_NULL  NULL
+#define png_rw_ptr_NULL           NULL
+#define png_structp_NULL          NULL
+#define png_uint_16p_NULL         NULL
+#define png_voidp_NULL            NULL
+#define png_write_status_ptr_NULL NULL
+#endif
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Version information for C files, stored in png.c.  This had better match
+ * the version above.
+ */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (const char) png_libpng_ver[18];
+  /* need room for 99.99.99beta99z */
+#else
+#define png_libpng_ver png_get_header_ver(NULL)
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* This was removed in version 1.0.5c */
+/* Structures to facilitate easy interlacing.  See png.c for more details */
+PNG_EXPORT_VAR (const int FARDATA) png_pass_start[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_inc[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_ystart[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_yinc[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_mask[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_dsp_mask[7];
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+PNG_EXPORT_VAR (const int FARDATA) png_pass_width[7];
+#endif
+/* This isn't currently used.  If you need it, see png.c for more details.
+PNG_EXPORT_VAR (const int FARDATA) png_pass_height[7];
+*/
+#endif
+
+#endif /* PNG_NO_EXTERN */
+
+/* Three color definitions.  The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+   png_byte red;
+   png_byte green;
+   png_byte blue;
+} png_color;
+typedef png_color FAR * png_colorp;
+typedef png_color FAR * FAR * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+   png_byte index;    /* used for palette files */
+   png_uint_16 red;   /* for use in red green blue files */
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 gray;  /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 FAR * png_color_16p;
+typedef png_color_16 FAR * FAR * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+   png_byte red;   /* for use in red green blue files */
+   png_byte green;
+   png_byte blue;
+   png_byte gray;  /* for use in grayscale files */
+   png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 FAR * png_color_8p;
+typedef png_color_8 FAR * FAR * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+   png_uint_16 red;
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 alpha;
+   png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry FAR * png_sPLT_entryp;
+typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
+
+/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ *  occupy the LSB of their respective members, and the MSB of each member
+ *  is zero-filled.  The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+   png_charp name;           /* palette name */
+   png_byte depth;           /* depth of palette samples */
+   png_sPLT_entryp entries;  /* palette entries */
+   png_int_32 nentries;      /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t FAR * png_sPLT_tp;
+typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not.  The "key" field
+ * points to a regular zero-terminated C string.  The "text", "lang", and
+ * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
+ * However, the * structure returned by png_get_text() will always contain
+ * regular zero-terminated C strings (possibly empty), never NULL pointers,
+ * so they can be safely used in printf() and other string-handling functions.
+ */
+typedef struct png_text_struct
+{
+   int  compression;       /* compression value:
+                             -1: tEXt, none
+                              0: zTXt, deflate
+                              1: iTXt, none
+                              2: iTXt, deflate  */
+   png_charp key;          /* keyword, 1-79 character description of "text" */
+   png_charp text;         /* comment, may be an empty string (ie "")
+                              or a NULL pointer */
+   png_size_t text_length; /* length of the text string */
+#ifdef PNG_iTXt_SUPPORTED
+   png_size_t itxt_length; /* length of the itxt string */
+   png_charp lang;         /* language code, 0-79 characters
+                              or a NULL pointer */
+   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
+                              chars or a NULL pointer */
+#endif
+} png_text;
+typedef png_text FAR * png_textp;
+typedef png_text FAR * FAR * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE    -1
+#define PNG_TEXT_COMPRESSION_zTXt     0
+#define PNG_ITXT_COMPRESSION_NONE     1
+#define PNG_ITXT_COMPRESSION_zTXt     2
+#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm.  There
+ * is no portable way to convert to either of these structures, as far
+ * as I know.  If you know of a portable way, send it to me.  As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+   png_uint_16 year; /* full year, as in, 1995 */
+   png_byte month;   /* month of year, 1 - 12 */
+   png_byte day;     /* day of month, 1 - 31 */
+   png_byte hour;    /* hour of day, 0 - 23 */
+   png_byte minute;  /* minute of hour, 0 - 59 */
+   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time FAR * png_timep;
+typedef png_time FAR * FAR * png_timepp;
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support.  The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ */
+typedef struct png_unknown_chunk_t
+{
+    png_byte name[5];
+    png_byte *data;
+    png_size_t size;
+
+    /* libpng-using applications should NOT directly modify this byte. */
+    png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+typedef png_unknown_chunk FAR * png_unknown_chunkp;
+typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
+#endif
+
+/* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file.  If you are writing the file, fill in the information
+ * you want to put into the PNG file, then call png_write_info().
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed.  With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality.
+ *
+ * In any case, the order of the parameters in png_info_struct should NOT
+ * be changed for as long as possible to keep compatibility with applications
+ * that use the old direct-access method with png_info_struct.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng.  This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions.  A function to clear these members is available: see
+ * png_free_data().  The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+typedef struct png_info_struct
+{
+   /* the following are necessary for every PNG file */
+   png_uint_32 width;       /* width of image in pixels (from IHDR) */
+   png_uint_32 height;      /* height of image in pixels (from IHDR) */
+   png_uint_32 valid;       /* valid chunk data (see PNG_INFO_ below) */
+   png_uint_32 rowbytes;    /* bytes needed to hold an untransformed row */
+   png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */
+   png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
+   png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
+   png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+   png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
+   /* The following three should have been named *_method not *_type */
+   png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+   png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+   png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+   /* The following is informational only on read, and not used on writes. */
+   png_byte channels;       /* number of data channels per pixel (1, 2, 3, 4) */
+   png_byte pixel_depth;    /* number of bits per pixel */
+   png_byte spare_byte;     /* to align the data, and for future use */
+   png_byte signature[8];   /* magic bytes read by libpng from start of file */
+
+   /* The rest of the data is optional.  If you are reading, check the
+    * valid field to see if the information in these are valid.  If you
+    * are writing, set the valid field to those chunks you want written,
+    * and initialize the appropriate fields below.
+    */
+
+#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+   /* The gAMA chunk describes the gamma characteristics of the system
+    * on which the image was created, normally in the range [1.0, 2.5].
+    * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
+    */
+   float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+    /* GR-P, 0.96a */
+    /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
+   png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+   /* The tEXt, and zTXt chunks contain human-readable textual data in
+    * uncompressed, compressed, and optionally compressed forms, respectively.
+    * The data in "text" is an array of pointers to uncompressed,
+    * null-terminated C strings. Each chunk has a keyword that describes the
+    * textual data contained in that chunk.  Keywords are not required to be
+    * unique, and the text string may be empty.  Any number of text chunks may
+    * be in an image.
+    */
+   int num_text; /* number of comments read/to write */
+   int max_text; /* current size of text array */
+   png_textp text; /* array of comments read/to write */
+#endif /* PNG_TEXT_SUPPORTED */
+
+#if defined(PNG_tIME_SUPPORTED)
+   /* The tIME chunk holds the last time the displayed image data was
+    * modified.  See the png_time struct for the contents of this struct.
+    */
+   png_time mod_time;
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
+   /* The sBIT chunk specifies the number of significant high-order bits
+    * in the pixel data.  Values are in the range [1, bit_depth], and are
+    * only specified for the channels in the pixel data.  The contents of
+    * the low-order bits is not specified.  Data is valid if
+    * (valid & PNG_INFO_sBIT) is non-zero.
+    */
+   png_color_8 sig_bit; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* The tRNS chunk supplies transparency data for paletted images and
+    * other image types that don't need a full alpha channel.  There are
+    * "num_trans" transparency values for a paletted image, stored in the
+    * same order as the palette colors, starting from index 0.  Values
+    * for the data are in the range [0, 255], ranging from fully transparent
+    * to fully opaque, respectively.  For non-paletted images, there is a
+    * single color specified that should be treated as fully transparent.
+    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+    */
+   png_bytep trans; /* transparent values for paletted image */
+   png_color_16 trans_values; /* transparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* The bKGD chunk gives the suggested image background color if the
+    * display program does not have its own background color and the image
+    * is needs to composited onto a background before display.  The colors
+    * in "background" are normally in the same color space/depth as the
+    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+    */
+   png_color_16 background;
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
+   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+    * and downwards from the top-left corner of the display, page, or other
+    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
+    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
+    */
+   png_int_32 x_offset; /* x offset on page */
+   png_int_32 y_offset; /* y offset on page */
+   png_byte offset_unit_type; /* offset units type */
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+   /* The pHYs chunk gives the physical pixel density of the image for
+    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+    */
+   png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
+   png_uint_32 y_pixels_per_unit; /* vertical pixel density */
+   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+   /* The hIST chunk contains the relative frequency or importance of the
+    * various palette entries, so that a viewer can intelligently select a
+    * reduced-color palette, if required.  Data is an array of "num_palette"
+    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+    * is non-zero.
+    */
+   png_uint_16p hist;
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+   /* The cHRM chunk describes the CIE color characteristics of the monitor
+    * on which the PNG was created.  This data allows the viewer to do gamut
+    * mapping of the input image to ensure that the viewer sees the same
+    * colors in the image as the creator.  Values are in the range
+    * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
+    */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float x_white;
+   float y_white;
+   float x_red;
+   float y_red;
+   float x_green;
+   float y_green;
+   float x_blue;
+   float y_blue;
+#endif
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+   /* The pCAL chunk describes a transformation between the stored pixel
+    * values and original physical data values used to create the image.
+    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+    * range given by [pcal_X0, pcal_X1], and are further transformed by a
+    * (possibly non-linear) transformation function given by "pcal_type"
+    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
+    * defines below, and the PNG-Group's PNG extensions document for a
+    * complete description of the transformations and how they should be
+    * implemented, and for a description of the ASCII parameter strings.
+    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+    */
+   png_charp pcal_purpose;  /* pCAL chunk description string */
+   png_int_32 pcal_X0;      /* minimum value */
+   png_int_32 pcal_X1;      /* maximum value */
+   png_charp pcal_units;    /* Latin-1 string giving physical units */
+   png_charpp pcal_params;  /* ASCII strings containing parameter values */
+   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
+   png_byte pcal_nparams;   /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_uint_32 free_me;     /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+   /* storage for unknown chunks that the library doesn't recognize. */
+   png_unknown_chunkp unknown_chunks;
+   png_size_t unknown_chunks_num;
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+   /* iCCP chunk data. */
+   png_charp iccp_name;     /* profile name */
+   png_charp iccp_profile;  /* International Color Consortium profile data */
+                            /* Note to maintainer: should be png_bytep */
+   png_uint_32 iccp_proflen;  /* ICC profile data length */
+   png_byte iccp_compression; /* Always zero */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+   /* data on sPLT chunks (there may be more than one). */
+   png_sPLT_tp splt_palettes;
+   png_uint_32 splt_palettes_num;
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+   /* The sCAL chunk describes the actual physical dimensions of the
+    * subject matter of the graphic.  The chunk contains a unit specification
+    * a byte value, and two ASCII strings representing floating-point
+    * values.  The values are width and height corresponsing to one pixel
+    * in the image.  This external representation is converted to double
+    * here.  Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
+    */
+   png_byte scal_unit;         /* unit of physical scale */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   double scal_pixel_width;    /* width of one pixel */
+   double scal_pixel_height;   /* height of one pixel */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_charp scal_s_width;     /* string containing height */
+   png_charp scal_s_height;    /* string containing width */
+#endif
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
+   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+   png_bytepp row_pointers;        /* the image bits */
+#endif
+
+#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
+   png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
+   png_fixed_point int_x_white;
+   png_fixed_point int_y_white;
+   png_fixed_point int_x_red;
+   png_fixed_point int_y_red;
+   png_fixed_point int_x_green;
+   png_fixed_point int_y_green;
+   png_fixed_point int_x_blue;
+   png_fixed_point int_y_blue;
+#endif
+
+} png_info;
+
+typedef png_info FAR * png_infop;
+typedef png_info FAR * FAR * png_infopp;
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX (~((png_uint_32)0))
+#define PNG_SIZE_MAX (~((png_size_t)0))
+/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
+#define PNG_MAX_UINT PNG_UINT_31_MAX
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE    1
+#define PNG_COLOR_MASK_COLOR      2
+#define PNG_COLOR_MASK_ALPHA      4
+
+/* color types.  Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type.  These values should NOT be changed. */
+#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST        2 /* Not a valid value */
+
+/* These are for the oFFs chunk.  These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST           2 /* Not a valid value */
+
+/* These are for the pCAL chunk.  These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST         4 /* Not a valid value */
+
+/* These are for the sCAL chunk.  These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER           1 /* meters per pixel */
+#define PNG_SCALE_RADIAN          2 /* radians per pixel */
+#define PNG_SCALE_LAST            3 /* Not a valid value */
+
+/* These are for the pHYs chunk.  These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER      1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
+
+/* These are for the sRGB chunk.  These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE   1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE   3
+#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH     79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH    256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file.  The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000L  /* ESR, 1.0.6 */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row.  It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+   png_uint_32 width; /* width of row */
+   png_uint_32 rowbytes; /* number of bytes in row */
+   png_byte color_type; /* color type of row */
+   png_byte bit_depth; /* bit depth of row */
+   png_byte channels; /* number of channels (1, 2, 3, or 4) */
+   png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info FAR * png_row_infop;
+typedef png_row_info FAR * FAR * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own.  The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions.
+ */
+typedef struct png_struct_def png_struct;
+typedef png_struct FAR * png_structp;
+
+typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
+typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
+typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
+typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
+   int));
+typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
+   int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
+   png_uint_32, int));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
+    png_row_infop, png_bytep));
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
+#endif
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
+#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
+#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
+#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
+#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
+#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
+#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
+#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* WRITE only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
+#define PNG_FLAG_MNG_FILTER_64      0x04
+#define PNG_ALL_MNG_FEATURES        0x05
+
+typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
+typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application, except to store
+ * the jmp_buf.
+ */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf jmpbuf;            /* used in png_error */
+#endif
+   png_error_ptr error_fn;    /* function for printing errors and aborting */
+   png_error_ptr warning_fn;  /* function for printing warnings */
+   png_voidp error_ptr;       /* user supplied struct for error functions */
+   png_rw_ptr write_data_fn;  /* function for writing output data */
+   png_rw_ptr read_data_fn;   /* function for reading input data */
+   png_voidp io_ptr;          /* ptr to application struct for I/O functions */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_user_transform_ptr write_user_transform_fn; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_voidp user_transform_ptr; /* user supplied struct for user transform */
+   png_byte user_transform_depth;    /* bit depth of user transformed pixels */
+   png_byte user_transform_channels; /* channels in user transformed pixels */
+#endif
+#endif
+
+   png_uint_32 mode;          /* tells us where we are in the PNG file */
+   png_uint_32 flags;         /* flags indicating various things to libpng */
+   png_uint_32 transformations; /* which transformations to perform */
+
+   z_stream zstream;          /* pointer to decompression structure (below) */
+   png_bytep zbuf;            /* buffer for zlib */
+   png_size_t zbuf_size;      /* size of zbuf */
+   int zlib_level;            /* holds zlib compression level */
+   int zlib_method;           /* holds zlib compression method */
+   int zlib_window_bits;      /* holds zlib compression window bits */
+   int zlib_mem_level;        /* holds zlib compression memory level */
+   int zlib_strategy;         /* holds zlib compression strategy */
+
+   png_uint_32 width;         /* width of image in pixels */
+   png_uint_32 height;        /* height of image in pixels */
+   png_uint_32 num_rows;      /* number of rows in current pass */
+   png_uint_32 usr_width;     /* width of row at start of write */
+   png_uint_32 rowbytes;      /* size of row in bytes */
+   png_uint_32 irowbytes;     /* size of current interlaced row in bytes */
+   png_uint_32 iwidth;        /* width of current interlaced row in pixels */
+   png_uint_32 row_number;    /* current row in interlace pass */
+   png_bytep prev_row;        /* buffer to save previous (unfiltered) row */
+   png_bytep row_buf;         /* buffer to save current (unfiltered) row */
+   png_bytep sub_row;         /* buffer to save "sub" row when filtering */
+   png_bytep up_row;          /* buffer to save "up" row when filtering */
+   png_bytep avg_row;         /* buffer to save "avg" row when filtering */
+   png_bytep paeth_row;       /* buffer to save "Paeth" row when filtering */
+   png_row_info row_info;     /* used for transformation routines */
+
+   png_uint_32 idat_size;     /* current IDAT size for read */
+   png_uint_32 crc;           /* current chunk CRC value */
+   png_colorp palette;        /* palette from the input file */
+   png_uint_16 num_palette;   /* number of color entries in palette */
+   png_uint_16 num_trans;     /* number of transparency values */
+   png_byte chunk_name[5];    /* null-terminated name of current chunk */
+   png_byte compression;      /* file compression type (always 0) */
+   png_byte filter;           /* file filter type (always 0) */
+   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+   png_byte pass;             /* current interlace pass (0 - 6) */
+   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ below ) */
+   png_byte color_type;       /* color type of file */
+   png_byte bit_depth;        /* bit depth of file */
+   png_byte usr_bit_depth;    /* bit depth of users row */
+   png_byte pixel_depth;      /* number of bits per pixel */
+   png_byte channels;         /* number of channels in file */
+   png_byte usr_channels;     /* channels at start of write */
+   png_byte sig_bytes;        /* magic bytes read/written from start of file */
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+#ifdef PNG_LEGACY_SUPPORTED
+   png_byte filler;           /* filler byte for pixel expansion */
+#else
+   png_uint_16 filler;           /* filler bytes for pixel expansion */
+#endif
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED)
+   png_byte background_gamma_type;
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+   float background_gamma;
+#  endif
+   png_color_16 background;   /* background color in screen gamma space */
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   png_color_16 background_1; /* background normalized to gamma 1.0 */
+#endif
+#endif /* PNG_bKGD_SUPPORTED */
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+   png_flush_ptr output_flush_fn;/* Function for flushing output */
+   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
+   png_uint_32 flush_rows;    /* number of rows written since last flush */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   int gamma_shift;      /* number of "insignificant" bits 16-bit gamma */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float gamma;          /* file gamma value */
+   float screen_gamma;   /* screen gamma value (display_exponent) */
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_bytep gamma_table;     /* gamma table for 8-bit depth files */
+   png_bytep gamma_from_1;    /* converts from 1.0 to screen */
+   png_bytep gamma_to_1;      /* converts from file to 1.0 */
+   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
+   png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
+   png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+   png_color_8 sig_bit;       /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+   png_color_8 shift;         /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_bytep trans;           /* transparency values for paletted files */
+   png_color_16 trans_values; /* transparency values for non-paletted files */
+#endif
+
+   png_read_status_ptr read_row_fn;   /* called after each row is decoded */
+   png_write_status_ptr write_row_fn; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_progressive_info_ptr info_fn; /* called after header data fully read */
+   png_progressive_row_ptr row_fn;   /* called after each prog. row is decoded */
+   png_progressive_end_ptr end_fn;   /* called after image is complete */
+   png_bytep save_buffer_ptr;        /* current location in save_buffer */
+   png_bytep save_buffer;            /* buffer for previously read data */
+   png_bytep current_buffer_ptr;     /* current location in current_buffer */
+   png_bytep current_buffer;         /* buffer for recently used data */
+   png_uint_32 push_length;          /* size of current input chunk */
+   png_uint_32 skip_length;          /* bytes to skip in input data */
+   png_size_t save_buffer_size;      /* amount of data now in save_buffer */
+   png_size_t save_buffer_max;       /* total size of save_buffer */
+   png_size_t buffer_size;           /* total amount of available input data */
+   png_size_t current_buffer_size;   /* amount of data now in current_buffer */
+   int process_mode;                 /* what push library is currently doing */
+   int cur_palette;                  /* current push library palette index */
+
+#  if defined(PNG_TEXT_SUPPORTED)
+     png_size_t current_text_size;   /* current size of text input data */
+     png_size_t current_text_left;   /* how much text left to read in input */
+     png_charp current_text;         /* current text chunk buffer */
+     png_charp current_text_ptr;     /* current location in current_text */
+#  endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* for the Borland special 64K segment handler */
+   png_bytepp offset_table_ptr;
+   png_bytep offset_table;
+   png_uint_16 offset_table_number;
+   png_uint_16 offset_table_count;
+   png_uint_16 offset_table_count_free;
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   png_bytep palette_lookup;         /* lookup table for dithering */
+   png_bytep dither_index;           /* index translation for palette files */
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
+   png_uint_16p hist;                /* histogram */
+#endif
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_byte heuristic_method;        /* heuristic for row filter selection */
+   png_byte num_prev_filters;        /* number of weights for previous rows */
+   png_bytep prev_filters;           /* filter type(s) of previous row(s) */
+   png_uint_16p filter_weights;      /* weight(s) for previous line(s) */
+   png_uint_16p inv_filter_weights;  /* 1/weight(s) for previous line(s) */
+   png_uint_16p filter_costs;        /* relative filter calculation cost */
+   png_uint_16p inv_filter_costs;    /* 1/relative filter calculation cost */
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+   png_charp time_buffer;            /* String to hold RFC 1123 time text */
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_uint_32 free_me;       /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+   png_voidp user_chunk_ptr;
+   png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+   int num_chunk_list;
+   png_bytep chunk_list;
+#endif
+
+/* New members added in libpng-1.0.3 */
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+   png_byte rgb_to_gray_status;
+   /* These were changed from png_byte in libpng-1.0.6 */
+   png_uint_16 rgb_to_gray_red_coeff;
+   png_uint_16 rgb_to_gray_green_coeff;
+   png_uint_16 rgb_to_gray_blue_coeff;
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
+    defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* changed from png_byte to png_uint_32 at version 1.2.0 */
+#ifdef PNG_1_0_X
+   png_byte mng_features_permitted;
+#else
+   png_uint_32 mng_features_permitted;
+#endif /* PNG_1_0_X */
+#endif
+
+/* New member added in libpng-1.0.7 */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_fixed_point int_gamma;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   png_byte filter_type;
+#endif
+
+#if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD))
+/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
+   png_uint_32 row_buf_size;
+#endif
+
+/* New members added in libpng-1.2.0 */
+#if !defined(PNG_1_0_X) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+   png_byte     mmx_bitdepth_threshold;
+   png_uint_32  mmx_rowbytes_threshold;
+   png_uint_32  asm_flags;
+#endif
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_voidp mem_ptr;                /* user supplied struct for mem functions */
+   png_malloc_ptr malloc_fn;         /* function for allocating memory */
+   png_free_ptr free_fn;             /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+   png_bytep big_row_buf;         /* buffer to save current (unfiltered) row */
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+   png_bytep dither_sort;            /* working sort array */
+   png_bytep index_to_palette;       /* where the original index currently is */
+                                     /* in the palette */
+   png_bytep palette_to_index;       /* which original index points to this */
+                                     /* palette color */
+#endif
+
+/* New members added in libpng-1.0.16 and 1.2.6 */
+   png_byte compression_type;
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_uint_32 user_width_max;
+   png_uint_32 user_height_max;
+#endif
+
+};
+
+
+/* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+typedef png_structp version_1_2_7;
+
+typedef png_struct FAR * FAR * png_structpp;
+
+/* Here are the function definitions most commonly used.  This is not
+ * the place to find out how to use libpng.  See libpng.txt for the
+ * full explanation, see example.c for the summary.  This just provides
+ * a simple one line description of the use of each function.
+ */
+
+/* Returns the version number of the library */
+extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
+   int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise.  Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
+   png_size_t num_to_check));
+
+/* Simple signature checking function.  This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+extern PNG_EXPORT(png_structp,png_create_read_struct)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn));
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+extern PNG_EXPORT(png_structp,png_create_write_struct)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn));
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
+   PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(void,png_set_compression_buffer_size)
+   PNGARG((png_structp png_ptr, png_uint_32 size));
+#endif
+
+/* Reset the compression stream */
+extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_structp,png_create_read_struct_2)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+extern PNG_EXPORT(png_structp,png_create_write_struct_2)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+#endif
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
+   png_bytep chunk_name, png_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
+   png_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
+   png_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
+
+/* Allocate and initialize the info structure */
+extern PNG_EXPORT(png_infop,png_create_info_struct)
+   PNGARG((png_structp png_ptr));
+
+/* Initialize the info structure (old interface - DEPRECATED) */
+extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr));
+#undef png_info_init
+#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\
+    png_sizeof(png_info));
+extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
+    png_size_t png_info_struct_size));
+
+/* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read the information before the actual image data. */
+extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
+   PNGARG((png_structp png_ptr, png_timep ptime));
+#endif
+
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* convert from a struct tm to png_time */
+extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
+   struct tm FAR * ttime));
+
+/* convert from time_t to png_time.  Uses gmtime() */
+extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
+   time_t ttime));
+#endif /* PNG_WRITE_tIME_SUPPORTED */
+#endif /* _WIN32_WCE */
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* Expand the grayscale to 24-bit RGB if necessary. */
+extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* Reduce RGB to grayscale. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
+   int error_action, double red, double green ));
+#endif
+extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
+   int error_action, png_fixed_point red, png_fixed_point green ));
+extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
+   png_ptr));
+#endif
+
+extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
+   png_colorp palette));
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
+extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
+   png_uint_32 filler, int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+#define PNG_FILLER_BEFORE 0
+#define PNG_FILLER_AFTER 1
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+#if !defined(PNG_1_0_X)
+extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
+   png_uint_32 filler, int flags));
+#endif
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
+   png_color_8p true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing.  Returns the number of passes. */
+extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Handle alpha and tRNS by replacing with a background color. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
+   png_color_16p background_color, int background_gamma_code,
+   int need_expand, double background_gamma));
+#endif
+#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+#define PNG_BACKGROUND_GAMMA_SCREEN  1
+#define PNG_BACKGROUND_GAMMA_FILE    2
+#define PNG_BACKGROUND_GAMMA_UNIQUE  3
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip the second byte of information from a 16-bit depth file. */
+extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Turn on dithering, and reduce the palette to the number of colors available. */
+extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
+   png_colorp palette, int num_palette, int maximum_colors,
+   png_uint_16p histogram, int full_dither));
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Handle gamma correction. Screen_gamma=(display_exponent) */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
+   double screen_gamma, double default_file_gamma));
+#endif
+#endif
+
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
+/* Deprecated and will be removed.  Use png_permit_mng_features() instead. */
+extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
+   int empty_plte_permitted));
+#endif
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set how many lines between output flushes - 0 for no flushing */
+extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
+#endif
+
+/* optional update palette with requested transformations */
+extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
+
+/* optional call to update the users info structure */
+extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read one or more rows of image data. */
+extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
+   png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read a row of data. */
+extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
+   png_bytep row,
+   png_bytep display_row));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read the whole image into memory at once. */
+extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
+   png_bytepp image));
+#endif
+
+/* write a row of image data */
+extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
+   png_bytep row));
+
+/* write a few rows of image data */
+extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
+   png_bytepp row, png_uint_32 num_rows));
+
+/* write the image data */
+extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
+   png_bytepp image));
+
+/* writes the end of the PNG file. */
+extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* read the end of the PNG file. */
+extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+
+/* free any memory associated with the png_info_struct */
+extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
+   png_infopp info_ptr_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
+   png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* free all memory used by the read (old method - NOT DLL EXPORTED) */
+extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_infop end_info_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_write_struct)
+   PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+
+/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
+extern void png_write_destroy PNGARG((png_structp png_ptr));
+
+/* set the libpng method of handling chunk CRC errors */
+extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
+   int crit_action, int ancil_action));
+
+/* Values for png_set_crc_action() to say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein.  Note that it is impossible to "discard" data in a critical
+ * chunk.  For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard.  These values should NOT be changed.
+ *
+ *      value                       action:critical     action:ancillary
+ */
+#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
+#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
+#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
+#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
+#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
+#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib.  These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them.  See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* set the filtering method(s) used by libpng.  Currently, the only valid
+ * value for "method" is 0.
+ */
+extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
+   int filters));
+
+/* Flags for png_set_filter() to say which filters to use.  The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS     0x00
+#define PNG_FILTER_NONE    0x08
+#define PNG_FILTER_SUB     0x10
+#define PNG_FILTER_UP      0x20
+#define PNG_FILTER_AVG     0x40
+#define PNG_FILTER_PAETH   0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE  0
+#define PNG_FILTER_VALUE_SUB   1
+#define PNG_FILTER_VALUE_UP    2
+#define PNG_FILTER_VALUE_AVG   3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST  5
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows.  Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters.  This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified.  Weights have no influence on
+ * the selection of the first row filter.  Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type.  Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs.  There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs.  Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found.  If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
+   int heuristic_method, int num_weights, png_doublep filter_weights,
+   png_doublep filter_costs));
+#endif
+#endif /*  PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+/* Heuristic used for row filter selection.  These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
+
+/* Set the library compression level.  Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression).  Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations.  In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
+   int level));
+
+extern PNG_EXPORT(void,png_set_compression_mem_level)
+   PNGARG((png_structp png_ptr, int mem_level));
+
+extern PNG_EXPORT(void,png_set_compression_strategy)
+   PNGARG((png_structp png_ptr, int strategy));
+
+extern PNG_EXPORT(void,png_set_compression_window_bits)
+   PNGARG((png_structp png_ptr, int window_bits));
+
+extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
+   int method));
+
+/* These next functions are called for input/output, memory, and error
+ * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf().  These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn().  See libpng.txt for
+ * more information.
+ */
+
+#if !defined(PNG_NO_STDIO)
+/* Initialize the input/output for the PNG file to the default functions. */
+extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions.  If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling.  If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
+   png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ */
+extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
+   png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
+   png_voidp io_ptr, png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
+   png_read_status_ptr read_row_fn));
+
+extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
+   png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
+   png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
+   png_ptr, png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
+   png_ptr, png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+   png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
+   int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+   PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
+   png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
+   png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
+   png_voidp progressive_ptr,
+   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+   png_progressive_end_ptr end_fn));
+
+/* returns the user pointer associated with the push read functions */
+extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
+   PNGARG((png_structp png_ptr));
+
+/* function to be called when data becomes available */
+extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* function that combines rows.  Not very much different than the
+ * png_combine_row() call.  Is this even used?????
+ */
+extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
+   png_bytep old_row, png_bytep new_row));
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
+   png_uint_32 size));
+
+#if defined(PNG_1_0_X)
+#  define png_malloc_warn png_malloc
+#else
+/* Added at libpng version 1.2.4 */
+extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
+   png_uint_32 size));
+#endif
+
+/* frees a pointer allocated by png_malloc() */
+extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
+
+#if defined(PNG_1_0_X)
+/* Function to allocate memory for zlib. */
+extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
+   uInt size));
+
+/* Function to free memory for zlib */
+extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
+#endif
+
+/* Free data that was allocated internally */
+extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 free_me, int num));
+#ifdef PNG_FREE_ME_SUPPORTED
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application */
+extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int freer, png_uint_32 mask));
+#endif
+/* assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_UNKN 0x0200
+#define PNG_FREE_LIST 0x0400
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL  0x7fff
+#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
+   png_uint_32 size));
+extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
+   png_voidp ptr));
+#endif
+
+extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
+   png_voidp s1, png_voidp s2, png_uint_32 size));
+
+extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
+   png_voidp s1, int value, png_uint_32 size));
+
+#if defined(USE_FAR_KEYWORD)  /* memory model conversion function */
+extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
+   int check));
+#endif /* USE_FAR_KEYWORD */
+
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
+   png_const_charp error_message));
+
+/* The same, but the chunk name is prepended to the error string. */
+extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
+   png_const_charp error_message));
+
+/* Non-fatal error in libpng.  Can continue, but may have a problem. */
+extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
+   png_const_charp warning_message));
+
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
+   png_const_charp warning_message));
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored.  The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+returned from png_read_png(). */
+extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+/* Set row_pointers, which is an array of pointers to scanlines for use
+by png_write_png(). */
+extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image height in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image bit_depth. */
+extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image color_type. */
+extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image filter_type. */
+extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image interlace_type. */
+extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image compression_type. */
+extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data.  */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+#endif
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+/* Returns pointer to signature string read from PNG header */
+extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_bKGD_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_16p *background));
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED)
+extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_16p background));
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double *white_x, double *white_y, double *red_x,
+   double *red_y, double *green_x, double *green_y, double *blue_x,
+   double *blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
+   *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+   png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
+   *int_blue_x, png_fixed_point *int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double white_x, double white_y, double red_x,
+   double red_y, double green_x, double green_y, double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
+   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+   png_fixed_point int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double *file_gamma));
+#endif
+extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point *int_file_gamma));
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double file_gamma));
+#endif
+extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point int_file_gamma));
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_16p *hist));
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_16p hist));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
+   int *bit_depth, int *color_type, int *interlace_method,
+   int *compression_method, int *filter_method));
+
+extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_method, int compression_method,
+   int filter_method));
+
+#if defined(PNG_oFFs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+   int *unit_type));
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+   int unit_type));
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
+   int *type, int *nparams, png_charp *units, png_charpp *params));
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
+   int type, int nparams, png_charp units, png_charpp params));
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_colorp *palette, int *num_palette));
+
+extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_colorp palette, int num_palette));
+
+#if defined(PNG_sBIT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_8p *sig_bit));
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_8p sig_bit));
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *intent));
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int intent));
+extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int intent));
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charpp name, int *compression_type,
+   png_charpp profile, png_uint_32 *proflen));
+   /* Note to maintainer: profile should be png_bytepp */
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp name, int compression_type,
+   png_charp profile, png_uint_32 proflen));
+   /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_sPLT_tpp entries));
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_sPLT_tp entries, int nentries));
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+/* png_get_text also returns the number of text chunks in *num_text */
+extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/*
+ *  Note while png_set_text() will accept a structure whose text,
+ *  language, and  translated keywords are NULL pointers, the structure
+ *  returned by png_get_text will always contain regular
+ *  zero-terminated C strings.  They might be empty strings but
+ *  they will never be NULL pointers.
+ */
+
+#if defined(PNG_TEXT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_timep *mod_time));
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_timep mod_time));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep *trans, int *num_trans,
+   png_color_16p *trans_values));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep trans, int num_trans,
+   png_color_16p trans_values));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *unit, double *width, double *height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED */
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int unit, double width, double height));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
+#endif
+#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* provide a list of chunks and how they are to be handled, if the built-in
+   handling or default unknown chunk handling is not desired.  Any chunks not
+   listed will be handled in the default manner.  The IHDR and IEND chunks
+   must not be listed.
+      keep = 0: follow default behavour
+           = 1: do not keep
+           = 2: keep only if safe-to-copy
+           = 3: keep even if unsafe-to-copy
+*/
+extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
+   png_ptr, int keep, png_bytep chunk_list, int num_chunks));
+extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
+extern PNG_EXPORT(void, png_set_unknown_chunk_location)
+   PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
+extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
+   png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
+#endif
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
+   chunk_name));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+   If you need to turn it off for a chunk that your application has freed,
+   you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */
+extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int mask));
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* The "params" pointer is currently not used and is for future expansion. */
+extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
+                        png_infop info_ptr,
+                        int transforms,
+                        png_voidp params));
+extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
+                        png_infop info_ptr,
+                        int transforms,
+                        png_voidp params));
+#endif
+
+/* Define PNG_DEBUG at compile time for debugging information.  Higher
+ * numbers for PNG_DEBUG mean more debugging information.  This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ */
+#ifdef PNG_DEBUG
+#if (PNG_DEBUG > 0)
+#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+#include <crtdbg.h>
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m)  _RPT0(_CRT_WARN,m)
+#define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m,p1)
+#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2)
+#endif
+#else /* PNG_DEBUG_FILE || !_MSC_VER */
+#ifndef PNG_DEBUG_FILE
+#define PNG_DEBUG_FILE stderr
+#endif /* PNG_DEBUG_FILE */
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m) \
+{ \
+     int num_tabs=l; \
+     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+}
+#define png_debug1(l,m,p1) \
+{ \
+     int num_tabs=l; \
+     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+}
+#define png_debug2(l,m,p1,p2) \
+{ \
+     int num_tabs=l; \
+     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+}
+#endif /* (PNG_DEBUG > 1) */
+#endif /* _MSC_VER */
+#endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+#define png_debug(l, m)
+#endif
+#ifndef png_debug1
+#define png_debug1(l, m, p1)
+#endif
+#ifndef png_debug2
+#define png_debug2(l, m, p1, p2)
+#endif
+
+extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void));
+
+extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
+   png_ptr, png_uint_32 mng_features_permitted));
+#endif
+
+/* For use in png_set_keep_unknown, added to version 1.2.6 */
+#define PNG_HANDLE_CHUNK_AS_DEFAULT   0
+#define PNG_HANDLE_CHUNK_NEVER        1
+#define PNG_HANDLE_CHUNK_IF_SAFE      2
+#define PNG_HANDLE_CHUNK_ALWAYS       3
+
+/* Added to version 1.2.0 */
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED  0x01  /* not user-settable */
+#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU    0x02  /* not user-settable */
+#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  0x04
+#define PNG_ASM_FLAG_MMX_READ_INTERLACE    0x08
+#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB   0x10
+#define PNG_ASM_FLAG_MMX_READ_FILTER_UP    0x20
+#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG   0x40
+#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
+#define PNG_ASM_FLAGS_INITIALIZED          0x80000000  /* not user-settable */
+
+#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+                           | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
+#define PNG_MMX_WRITE_FLAGS ( 0 )
+
+#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
+                      | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU   \
+                      | PNG_MMX_READ_FLAGS                \
+                      | PNG_MMX_WRITE_FLAGS )
+
+#define PNG_SELECT_READ   1
+#define PNG_SELECT_WRITE  2
+
+#if !defined(PNG_1_0_X)
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
+   PNGARG((int flag_select, int *compilerID));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask)
+   PNGARG((int flag_select));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
+   PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
+   PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
+   PNGARG((png_structp png_ptr));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_asm_flags)
+   PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_mmx_thresholds)
+   PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
+   png_uint_32 mmx_rowbytes_threshold));
+
+#endif /* PNG_1_0_X */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#if !defined(PNG_1_0_X)
+/* png.c, pnggccrd.c, or pngvcrd.c */
+extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler. */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
+   png_ptr, png_uint_32 strip_mode));
+#endif
+
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
+   png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
+extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
+   png_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
+   png_ptr));
+#endif
+
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines.  However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems.  There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same!  128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity          */
+
+#  define png_composite(composite, fg, alpha, bg)                            \
+     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
+                        +        (png_uint_16)(bg)*(png_uint_16)(255 -       \
+                        (png_uint_16)(alpha)) + (png_uint_16)128);           \
+       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+
+#  define png_composite_16(composite, fg, alpha, bg)                         \
+     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
+                        + (png_uint_32)(bg)*(png_uint_32)(65535L -           \
+                        (png_uint_32)(alpha)) + (png_uint_32)32768L);        \
+       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else  /* standard method using integer division */
+
+#  define png_composite(composite, fg, alpha, bg)                            \
+     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) +    \
+       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) +       \
+       (png_uint_16)127) / 255)
+
+#  define png_composite_16(composite, fg, alpha, bg)                         \
+     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+       (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) +      \
+       (png_uint_32)32767) / (png_uint_32)65535L)
+
+#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
+
+/* These next functions are used internally in the code.  They generally
+ * shouldn't be used unless you are writing code to add or replace some
+ * functionality in libpng.  More information about most functions can
+ * be found in the files where the functions are located.
+ */
+
+#if defined(PNG_INTERNAL)
+
+/* Various modes of operation.  Note that after an init, mode is set to
+ * zero automatically when the structure is created.
+ */
+#define PNG_HAVE_IHDR               0x01
+#define PNG_HAVE_PLTE               0x02
+#define PNG_HAVE_IDAT               0x04
+#define PNG_AFTER_IDAT              0x08
+#define PNG_HAVE_IEND               0x10
+#define PNG_HAVE_gAMA               0x20
+#define PNG_HAVE_cHRM               0x40
+#define PNG_HAVE_sRGB               0x80
+#define PNG_HAVE_CHUNK_HEADER      0x100
+#define PNG_WROTE_tIME             0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY     0x800
+#define PNG_HAVE_PNG_SIGNATURE    0x1000
+
+/* flags for the transformations the PNG library does on the image data */
+#define PNG_BGR                0x0001
+#define PNG_INTERLACE          0x0002
+#define PNG_PACK               0x0004
+#define PNG_SHIFT              0x0008
+#define PNG_SWAP_BYTES         0x0010
+#define PNG_INVERT_MONO        0x0020
+#define PNG_DITHER             0x0040
+#define PNG_BACKGROUND         0x0080
+#define PNG_BACKGROUND_EXPAND  0x0100
+                          /*   0x0200 unused */
+#define PNG_16_TO_8            0x0400
+#define PNG_RGBA               0x0800
+#define PNG_EXPAND             0x1000
+#define PNG_GAMMA              0x2000
+#define PNG_GRAY_TO_RGB        0x4000
+#define PNG_FILLER             0x8000L
+#define PNG_PACKSWAP          0x10000L
+#define PNG_SWAP_ALPHA        0x20000L
+#define PNG_STRIP_ALPHA       0x40000L
+#define PNG_INVERT_ALPHA      0x80000L
+#define PNG_USER_TRANSFORM   0x100000L
+#define PNG_RGB_TO_GRAY_ERR  0x200000L
+#define PNG_RGB_TO_GRAY_WARN 0x400000L
+#define PNG_RGB_TO_GRAY      0x600000L  /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ADD_ALPHA       0x1000000L  /* Added to libpng-1.2.7 */
+
+/* flags for png_create_struct */
+#define PNG_STRUCT_PNG   0x0001
+#define PNG_STRUCT_INFO  0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_SHIFT 3
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
+#define PNG_FLAG_ZLIB_CUSTOM_LEVEL        0x0002
+#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL    0x0004
+#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS  0x0008
+#define PNG_FLAG_ZLIB_CUSTOM_METHOD       0x0010
+#define PNG_FLAG_ZLIB_FINISHED            0x0020
+#define PNG_FLAG_ROW_INIT                 0x0040
+#define PNG_FLAG_FILLER_AFTER             0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
+#define PNG_FLAG_FREE_PLTE                0x1000
+#define PNG_FLAG_FREE_TRNS                0x2000
+#define PNG_FLAG_FREE_HIST                0x4000
+#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000L
+#define PNG_FLAG_KEEP_UNSAFE_CHUNKS       0x10000L
+#define PNG_FLAG_LIBRARY_MISMATCH         0x20000L
+#define PNG_FLAG_STRIP_ERROR_NUMBERS      0x40000L
+#define PNG_FLAG_STRIP_ERROR_TEXT         0x80000L
+#define PNG_FLAG_MALLOC_NULL_MEM_OK       0x100000L
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
+                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
+                                     PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* save typing and make code easier to understand */
+
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+   abs((int)((c1).green) - (int)((c2).green)) + \
+   abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* Added to libpng-1.2.6 JB */
+#define PNG_ROWBYTES(pixel_bits, width) \
+    ((pixel_bits) >= 8 ? \
+    ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
+    (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
+
+/* PNG_OUT_OF_RANGE returns true if value is outside the range
+   ideal-delta..ideal+delta.  Each argument is evaluated twice.
+   "ideal" and "delta" should be constants, normally simple
+   integers, "value" a variable. Added to libpng-1.2.6 JB */
+#define PNG_OUT_OF_RANGE(value, ideal, delta) \
+        ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* place to hold the signature string for a PNG file. */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+   PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8];
+#else
+#define png_sig png_sig_bytes(NULL)
+#endif
+#endif /* PNG_NO_EXTERN */
+
+/* Constant strings for known chunk types.  If you need to add a chunk,
+ * define the name here, and add an invocation of the macro in png.c and
+ * wherever it's needed.
+ */
+#define PNG_IHDR const png_byte png_IHDR[5] = { 73,  72,  68,  82, '\0'}
+#define PNG_IDAT const png_byte png_IDAT[5] = { 73,  68,  65,  84, '\0'}
+#define PNG_IEND const png_byte png_IEND[5] = { 73,  69,  78,  68, '\0'}
+#define PNG_PLTE const png_byte png_PLTE[5] = { 80,  76,  84,  69, '\0'}
+#define PNG_bKGD const png_byte png_bKGD[5] = { 98,  75,  71,  68, '\0'}
+#define PNG_cHRM const png_byte png_cHRM[5] = { 99,  72,  82,  77, '\0'}
+#define PNG_gAMA const png_byte png_gAMA[5] = {103,  65,  77,  65, '\0'}
+#define PNG_hIST const png_byte png_hIST[5] = {104,  73,  83,  84, '\0'}
+#define PNG_iCCP const png_byte png_iCCP[5] = {105,  67,  67,  80, '\0'}
+#define PNG_iTXt const png_byte png_iTXt[5] = {105,  84,  88, 116, '\0'}
+#define PNG_oFFs const png_byte png_oFFs[5] = {111,  70,  70, 115, '\0'}
+#define PNG_pCAL const png_byte png_pCAL[5] = {112,  67,  65,  76, '\0'}
+#define PNG_sCAL const png_byte png_sCAL[5] = {115,  67,  65,  76, '\0'}
+#define PNG_pHYs const png_byte png_pHYs[5] = {112,  72,  89, 115, '\0'}
+#define PNG_sBIT const png_byte png_sBIT[5] = {115,  66,  73,  84, '\0'}
+#define PNG_sPLT const png_byte png_sPLT[5] = {115,  80,  76,  84, '\0'}
+#define PNG_sRGB const png_byte png_sRGB[5] = {115,  82,  71,  66, '\0'}
+#define PNG_tEXt const png_byte png_tEXt[5] = {116,  69,  88, 116, '\0'}
+#define PNG_tIME const png_byte png_tIME[5] = {116,  73,  77,  69, '\0'}
+#define PNG_tRNS const png_byte png_tRNS[5] = {116,  82,  78,  83, '\0'}
+#define PNG_zTXt const png_byte png_zTXt[5] = {122,  84,  88, 116, '\0'}
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5];
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+
+/* Inline macros to do direct reads of bytes from the input buffer.  These
+ * require that you are using an architecture that uses PNG byte ordering
+ * (MSB first) and supports unaligned data storage.  I think that PowerPC
+ * in big-endian mode and 680x0 are the only ones that will support this.
+ * The x86 line of processors definitely do not.  The png_get_int_32()
+ * routine also assumes we are using two's complement format for negative
+ * values, which is almost certainly true.
+ */
+#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
+#  if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED)
+#    define png_get_int_32(buf) ( *((png_int_32p) (buf)))
+#  endif
+#  define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
+#  define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
+#else
+#  if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED)
+PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf));
+#  endif
+PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf));
+PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf));
+#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
+PNG_EXTERN png_uint_32 png_get_uint_31 PNGARG((png_structp png_ptr,
+  png_bytep buf));
+
+/* Initialize png_ptr struct for reading, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_read_struct instead).
+ */
+extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr));
+#undef png_read_init
+#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
+    PNG_LIBPNG_VER_STRING,  png_sizeof(png_struct));
+extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size));
+extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+    png_info_size));
+
+/* Initialize png_ptr struct for writing, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_write_struct instead).
+ */
+extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr));
+#undef png_write_init
+#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
+    PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
+extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size));
+extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+    png_info_size));
+
+/* Allocate memory for an internal libpng struct */
+PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
+
+/* Free memory from internal libpng struct */
+PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
+
+PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
+  malloc_fn, png_voidp mem_ptr));
+PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
+   png_free_ptr free_fn, png_voidp mem_ptr));
+
+/* Free any memory that info_ptr points to and reset struct. */
+PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#ifndef PNG_1_0_X
+/* Function to allocate memory for zlib. */
+PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
+
+/* Function to free memory for zlib */
+PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
+
+#ifdef PNG_SIZE_T
+/* Function to convert a sizeof an item to png_sizeof item */
+   PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
+#endif
+
+/* Next four functions are used internally as callbacks.  PNGAPI is required
+ * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3. */
+
+PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
+   png_bytep data, png_size_t length));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t length));
+#endif
+
+PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
+   png_bytep data, png_size_t length));
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
+#endif
+#endif
+#else /* PNG_1_0_X */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t length));
+#endif
+#endif /* PNG_1_0_X */
+
+/* Reset the CRC variable */
+PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
+
+/* Write the "data" buffer to whatever output you are using. */
+PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length));
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length));
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
+   png_size_t length));
+
+/* Decompress data in a chunk that uses compression */
+#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
+    defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
+PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr,
+   int comp_type, png_charp chunkdata, png_size_t chunklength,
+   png_size_t prefix_length, png_size_t *data_length));
+#endif
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
+
+/* Calculate the CRC over a section of data.  Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
+   png_size_t length));
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
+#endif
+
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
+ * The only currently known PNG chunks that use signed numbers are
+ * the ancillary extension chunks, oFFs and pCAL.
+ */
+PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i));
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i));
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+PNG_EXTERN void png_save_uint_16 PNGARG((png_bytep buf, unsigned int i));
+
+/* simple function to write the signature */
+PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
+
+/* write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
+   png_uint_32 height,
+   int bit_depth, int color_type, int compression_method, int filter_method,
+   int interlace_method));
+
+PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
+   png_uint_32 num_pal));
+
+PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length));
+
+PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point
+    file_gamma));
+#endif
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
+   int color_type));
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
+   double white_x, double white_y,
+   double red_x, double red_y, double green_x, double green_y,
+   double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
+   png_fixed_point int_white_x, png_fixed_point int_white_y,
+   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+   png_fixed_point int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
+   int intent));
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
+   png_charp name, int compression_type,
+   png_charp profile, int proflen));
+   /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
+   png_sPLT_tp palette));
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
+   png_color_16p values, int number, int color_type));
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
+   png_color_16p values, int color_type));
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
+   int num_hist));
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
+   png_charp key, png_charpp new_key));
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
+   png_charp text, png_size_t text_len));
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
+   png_charp text, png_size_t text_len, int compression));
+#endif
+
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
+   int compression, png_charp key, png_charp lang, png_charp lang_key,
+   png_charp text));
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)  /* Added at version 1.0.14 and 1.2.4 */
+PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
+   png_int_32 x_offset, png_int_32 y_offset, int unit_type));
+#endif
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
+   png_int_32 X0, png_int_32 X1, int type, int nparams,
+   png_charp units, png_charpp params));
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
+   png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+   int unit_type));
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
+   png_timep mod_time));
+#endif
+
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
+   int unit, double width, double height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
+   int unit, png_charp width, png_charp height));
+#endif
+#endif
+#endif
+
+/* Called when finished processing a row of data */
+PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
+
+/* Internal use only.   Called before first row of data */
+PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
+#endif
+
+/* combine a row of data, dealing with alpha, etc. if requested */
+PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
+   int mask));
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+/* expand an interlaced row */
+/* OLD pre-1.0.9 interface:
+PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
+   png_bytep row, int pass, png_uint_32 transformations));
+ */
+PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
+#endif
+
+/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* grab pixels out of a row for an interlaced pass */
+PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
+   png_bytep row, int pass));
+#endif
+
+/* unfilter a row */
+PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
+   png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
+
+/* Choose the best filter to use and filter the row data */
+PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
+   png_row_infop row_info));
+
+/* Write out the filtered row. */
+PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
+   png_bytep filtered_row));
+/* finish a row while reading, dealing with interlacing passes, etc. */
+PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
+
+/* initialize the row buffers, etc. */
+PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
+/* optional call to update the users info structure */
+PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+/* these are the functions that do the transformations */
+#if defined(PNG_READ_FILLER_SUPPORTED)
+PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 filler, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
+   row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_8p sig_bits));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
+   png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
+
+#  if defined(PNG_CORRECT_PALETTE_SUPPORTED)
+PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
+   png_colorp palette, int num_palette));
+#  endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 bit_depth));
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_8p bit_depth));
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background,
+   png_color_16p background_1,
+   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+   png_uint_16pp gamma_16_to_1, int gamma_shift));
+#else
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background));
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
+   png_bytep gamma_table, png_uint_16pp gamma_16_table,
+   int gamma_shift));
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
+   png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
+PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
+   png_bytep row, png_color_16p trans_value));
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* decode the IHDR chunk */
+PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+
+PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
+   png_bytep chunk_name));
+
+/* handle the transformations for reading and writing */
+PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
+
+PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
+   png_uint_32 length));
+PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
+PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
+   png_bytep row));
+PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+/* png.c */ /* PRIVATE */
+PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr));
+#endif
+/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+
+#endif /* PNG_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* do not put anything past this line */
+#endif /* PNG_H */
diff --git a/Utilities/FLTK/png/pngconf.h b/Utilities/FLTK/png/pngconf.h
new file mode 100644
index 0000000000000000000000000000000000000000..1267e9c8db7da1e7ee9ad7efaa7a9a6c943c6efe
--- /dev/null
+++ b/Utilities/FLTK/png/pngconf.h
@@ -0,0 +1,1376 @@
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+#ifdef PNG_USER_CONFIG
+#include "pngusr.h"
+#endif
+
+/* This is the size of the compression buffer, and thus the size of
+ * an IDAT chunk.  Make this whatever size you feel is best for your
+ * machine.  One of these will be allocated per png_struct.  When this
+ * is full, it writes the data to the disk, and does some other
+ * calculations.  Making this an extremely small size will slow
+ * the library down, but you may want to experiment to determine
+ * where it becomes significant, if you are concerned with memory
+ * usage.  Note that zlib allocates at least 32Kb also.  For readers,
+ * this describes the size of the buffer available to read the data in.
+ * Unless this gets smaller than the size of a row (compressed),
+ * it should not make much difference how big this is.
+ */
+
+#ifndef PNG_ZBUF_SIZE
+#  define PNG_ZBUF_SIZE 8192
+#endif
+
+/* Enable if you want a write-only libpng */
+
+#ifndef PNG_NO_READ_SUPPORTED
+#  define PNG_READ_SUPPORTED
+#endif
+
+/* Enable if you want a read-only libpng */
+
+#ifndef PNG_NO_WRITE_SUPPORTED
+#  define PNG_WRITE_SUPPORTED
+#endif
+
+/* Enabled by default in 1.2.0.  You can disable this if you don't need to
+   support PNGs that are embedded in MNG datastreams */
+#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
+#  ifndef PNG_MNG_FEATURES_SUPPORTED
+#    define PNG_MNG_FEATURES_SUPPORTED
+#  endif
+#endif
+
+#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
+#  ifndef PNG_FLOATING_POINT_SUPPORTED
+#    define PNG_FLOATING_POINT_SUPPORTED
+#  endif
+#endif
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this.  While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+#define PNG_MAX_MALLOC_64K
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+#  define PNG_MAX_MALLOC_64K
+#endif
+
+/* Special munging to support doing things the 'cygwin' way:
+ * 'Normal' png-on-win32 defines/defaults:
+ *   PNG_BUILD_DLL -- building dll
+ *   PNG_USE_DLL   -- building an application, linking to dll
+ *   (no define)   -- building static library, or building an
+ *                    application and linking to the static lib
+ * 'Cygwin' defines/defaults:
+ *   PNG_BUILD_DLL -- (ignored) building the dll
+ *   (no define)   -- (ignored) building an application, linking to the dll
+ *   PNG_STATIC    -- (ignored) building the static lib, or building an 
+ *                    application that links to the static lib.
+ *   ALL_STATIC    -- (ignored) building various static libs, or building an 
+ *                    application that links to the static libs.
+ * Thus,
+ * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
+ * this bit of #ifdefs will define the 'correct' config variables based on
+ * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
+ * unnecessary.
+ *
+ * Also, the precedence order is:
+ *   ALL_STATIC (since we can't #undef something outside our namespace)
+ *   PNG_BUILD_DLL
+ *   PNG_STATIC
+ *   (nothing) == PNG_USE_DLL
+ * 
+ * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
+ *   of auto-import in binutils, we no longer need to worry about 
+ *   __declspec(dllexport) / __declspec(dllimport) and friends.  Therefore,
+ *   we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
+ *   to __declspec() stuff.  However, we DO need to worry about 
+ *   PNG_BUILD_DLL and PNG_STATIC because those change some defaults
+ *   such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
+ */
+#if defined(__CYGWIN__)
+#  if defined(ALL_STATIC)
+#    if defined(PNG_BUILD_DLL)
+#      undef PNG_BUILD_DLL
+#    endif
+#    if defined(PNG_USE_DLL)
+#      undef PNG_USE_DLL
+#    endif
+#    if defined(PNG_DLL)
+#      undef PNG_DLL
+#    endif
+#    if !defined(PNG_STATIC)
+#      define PNG_STATIC
+#    endif
+#  else
+#    if defined (PNG_BUILD_DLL)
+#      if defined(PNG_STATIC)
+#        undef PNG_STATIC
+#      endif
+#      if defined(PNG_USE_DLL)
+#        undef PNG_USE_DLL
+#      endif
+#      if !defined(PNG_DLL)
+#        define PNG_DLL
+#      endif
+#    else
+#      if defined(PNG_STATIC)
+#        if defined(PNG_USE_DLL)
+#          undef PNG_USE_DLL
+#        endif
+#        if defined(PNG_DLL)
+#          undef PNG_DLL
+#        endif
+#      else
+#        if !defined(PNG_USE_DLL)
+#          define PNG_USE_DLL
+#        endif
+#        if !defined(PNG_DLL)
+#          define PNG_DLL
+#        endif
+#      endif  
+#    endif  
+#  endif
+#endif
+
+/* This protects us against compilers that run on a windowing system
+ * and thus don't have or would rather us not use the stdio types:
+ * stdin, stdout, and stderr.  The only one currently used is stderr
+ * in png_error() and png_warning().  #defining PNG_NO_CONSOLE_IO will
+ * prevent these from being compiled and used. #defining PNG_NO_STDIO
+ * will also prevent these, plus will prevent the entire set of stdio
+ * macros and functions (FILE *, printf, etc.) from being compiled and used,
+ * unless (PNG_DEBUG > 0) has been #defined.
+ *
+ * #define PNG_NO_CONSOLE_IO
+ * #define PNG_NO_STDIO
+ */
+
+#if defined(_WIN32_WCE)
+#  include <windows.h>
+   /* Console I/O functions are not supported on WindowsCE */
+#  define PNG_NO_CONSOLE_IO
+#  ifdef PNG_DEBUG
+#    undef PNG_DEBUG
+#  endif
+#endif
+
+#ifdef PNG_BUILD_DLL
+#  ifndef PNG_CONSOLE_IO_SUPPORTED
+#    ifndef PNG_NO_CONSOLE_IO
+#      define PNG_NO_CONSOLE_IO
+#    endif
+#  endif
+#endif
+
+#  ifdef PNG_NO_STDIO
+#    ifndef PNG_NO_CONSOLE_IO
+#      define PNG_NO_CONSOLE_IO
+#    endif
+#    ifdef PNG_DEBUG
+#      if (PNG_DEBUG > 0)
+#        include <stdio.h>
+#      endif
+#    endif
+#  else
+#    if !defined(_WIN32_WCE)
+/* "stdio.h" functions are not supported on WindowsCE */
+#      include <stdio.h>
+#    endif
+#  endif
+
+/* This macro protects us against machines that don't have function
+ * prototypes (ie K&R style headers).  If your compiler does not handle
+ * function prototypes, define this macro and use the included ansi2knr.
+ * I've always been able to use _NO_PROTO as the indicator, but you may
+ * need to drag the empty declaration out in front of here, or change the
+ * ifdef to suit your own needs.
+ */
+#ifndef PNGARG
+
+#ifdef OF /* zlib prototype munger */
+#  define PNGARG(arglist) OF(arglist)
+#else
+
+#ifdef _NO_PROTO
+#  define PNGARG(arglist) ()
+#  ifndef PNG_TYPECAST_NULL
+#     define PNG_TYPECAST_NULL
+#  endif
+#else
+#  define PNGARG(arglist) arglist
+#endif /* _NO_PROTO */
+
+#endif /* OF */
+
+#endif /* PNGARG */
+
+/* Try to determine if we are compiling on a Mac.  Note that testing for
+ * just __MWERKS__ is not good enough, because the Codewarrior is now used
+ * on non-Mac platforms.
+ */
+#ifndef MACOS
+#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+      defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+#    define MACOS
+#  endif
+#endif
+
+/* enough people need this for various reasons to include it here */
+#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
+#  include <sys/types.h>
+#endif
+
+#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
+#  define PNG_SETJMP_SUPPORTED
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This is an attempt to force a single setjmp behaviour on Linux.  If
+ * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
+ */
+
+#  ifdef __linux__
+#    ifdef _BSD_SOURCE
+#      define PNG_SAVE_BSD_SOURCE
+#      undef _BSD_SOURCE
+#    endif
+#    ifdef _SETJMP_H
+     /* If you encounter a compiler error here, see the explanation
+      * near the end of INSTALL.
+      */
+         __png.h__ already includes setjmp.h;
+         __dont__ include it again.;
+#    endif
+#  endif /* __linux__ */
+
+   /* include setjmp.h for error handling */
+#  include <setjmp.h>
+
+#  ifdef __linux__
+#    ifdef PNG_SAVE_BSD_SOURCE
+#      define _BSD_SOURCE
+#      undef PNG_SAVE_BSD_SOURCE
+#    endif
+#  endif /* __linux__ */
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#ifdef BSD
+#  include <strings.h>
+#else
+#  include <string.h>
+#endif
+
+/* Other defines for things like memory and the like can go here.  */
+#ifdef PNG_INTERNAL
+
+#include <stdlib.h>
+
+/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
+ * aren't usually used outside the library (as far as I know), so it is
+ * debatable if they should be exported at all.  In the future, when it is
+ * possible to have run-time registry of chunk-handling functions, some of
+ * these will be made available again.
+#define PNG_EXTERN extern
+ */
+#define PNG_EXTERN
+
+/* Other defines specific to compilers can go here.  Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+#  if defined(MACOS)
+     /* We need to check that <math.h> hasn't already been included earlier
+      * as it seems it doesn't agree with <fp.h>, yet we should really use
+      * <fp.h> if possible.
+      */
+#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+#      include <fp.h>
+#    endif
+#  else
+#    include <math.h>
+#  endif
+#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+      * MATH=68881
+      */
+#    include <m68881.h>
+#  endif
+#endif
+
+/* Codewarrior on NT has linking problems without this. */
+#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
+#  define PNG_ALWAYS_EXTERN
+#endif
+
+/* This provides the non-ANSI (far) memory allocation routines. */
+#if defined(__TURBOC__) && defined(__MSDOS__)
+#  include <mem.h>
+#  include <alloc.h>
+#endif
+
+/* I have no idea why is this necessary... */
+#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
+    defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
+#  include <malloc.h>
+#endif
+
+/* This controls how fine the dithering gets.  As this allocates
+ * a largish chunk of memory (32K), those who are not as concerned
+ * with dithering quality can decrease some or all of these.
+ */
+#ifndef PNG_DITHER_RED_BITS
+#  define PNG_DITHER_RED_BITS 5
+#endif
+#ifndef PNG_DITHER_GREEN_BITS
+#  define PNG_DITHER_GREEN_BITS 5
+#endif
+#ifndef PNG_DITHER_BLUE_BITS
+#  define PNG_DITHER_BLUE_BITS 5
+#endif
+
+/* This controls how fine the gamma correction becomes when you
+ * are only interested in 8 bits anyway.  Increasing this value
+ * results in more memory being used, and more pow() functions
+ * being called to fill in the gamma tables.  Don't set this value
+ * less then 8, and even that may not work (I haven't tested it).
+ */
+
+#ifndef PNG_MAX_GAMMA_8
+#  define PNG_MAX_GAMMA_8 11
+#endif
+
+/* This controls how much a difference in gamma we can tolerate before
+ * we actually start doing gamma conversion.
+ */
+#ifndef PNG_GAMMA_THRESHOLD
+#  define PNG_GAMMA_THRESHOLD 0.05
+#endif
+
+#endif /* PNG_INTERNAL */
+
+/* The following uses const char * instead of char * for error
+ * and warning message functions, so some compilers won't complain.
+ * If you do not want to use const, define PNG_NO_CONST here.
+ */
+
+#ifndef PNG_NO_CONST
+#  define PNG_CONST const
+#else
+#  define PNG_CONST
+#endif
+
+/* The following defines give you the ability to remove code from the
+ * library that you will not be using.  I wish I could figure out how to
+ * automate this, but I can't do that without making it seriously hard
+ * on the users.  So if you are not using an ability, change the #define
+ * to and #undef, and that part of the library will not be compiled.  If
+ * your linker can't find a function, you may want to make sure the
+ * ability is defined here.  Some of these depend upon some others being
+ * defined.  I haven't figured out all the interactions here, so you may
+ * have to experiment awhile to get everything to compile.  If you are
+ * creating or using a shared library, you probably shouldn't touch this,
+ * as it will affect the size of the structures, and this will cause bad
+ * things to happen if the library and/or application ever change.
+ */
+
+/* Any features you will not be using can be undef'ed here */
+
+/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
+ * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
+ * on the compile line, then pick and choose which ones to define without
+ * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
+ * if you only want to have a png-compliant reader/writer but don't need
+ * any of the extra transformations.  This saves about 80 kbytes in a
+ * typical installation of the library. (PNG_NO_* form added in version
+ * 1.0.1c, for consistency)
+ */
+
+/* The size of the png_text structure changed in libpng-1.0.6 when
+ * iTXt is supported.  It is turned off by default, to support old apps
+ * that malloc the png_text structure instead of calling png_set_text()
+ * and letting libpng malloc it.  It will be turned on by default in
+ * libpng-1.3.0.
+ */
+
+#ifndef PNG_iTXt_SUPPORTED
+#  if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
+#    define PNG_NO_READ_iTXt
+#  endif
+#  if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
+#    define PNG_NO_WRITE_iTXt
+#  endif
+#endif
+
+/* The following support, added after version 1.0.0, can be turned off here en
+ * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
+ * with old applications that require the length of png_struct and png_info
+ * to remain unchanged.
+ */
+
+#ifdef PNG_LEGACY_SUPPORTED
+#  define PNG_NO_FREE_ME
+#  define PNG_NO_READ_UNKNOWN_CHUNKS
+#  define PNG_NO_WRITE_UNKNOWN_CHUNKS
+#  define PNG_NO_READ_USER_CHUNKS
+#  define PNG_NO_READ_iCCP
+#  define PNG_NO_WRITE_iCCP
+#  define PNG_NO_READ_iTXt
+#  define PNG_NO_WRITE_iTXt
+#  define PNG_NO_READ_sCAL
+#  define PNG_NO_WRITE_sCAL
+#  define PNG_NO_READ_sPLT
+#  define PNG_NO_WRITE_sPLT
+#  define PNG_NO_INFO_IMAGE
+#  define PNG_NO_READ_RGB_TO_GRAY
+#  define PNG_NO_READ_USER_TRANSFORM
+#  define PNG_NO_WRITE_USER_TRANSFORM
+#  define PNG_NO_USER_MEM
+#  define PNG_NO_READ_EMPTY_PLTE
+#  define PNG_NO_MNG_FEATURES
+#  define PNG_NO_FIXED_POINT_SUPPORTED
+#endif
+
+/* Ignore attempt to turn off both floating and fixed point support */
+#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
+    !defined(PNG_NO_FIXED_POINT_SUPPORTED)
+#  define PNG_FIXED_POINT_SUPPORTED
+#endif
+
+#ifndef PNG_NO_FREE_ME
+#  define PNG_FREE_ME_SUPPORTED
+#endif
+
+#if defined(PNG_READ_SUPPORTED)
+
+#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
+      !defined(PNG_NO_READ_TRANSFORMS)
+#  define PNG_READ_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+#  ifndef PNG_NO_READ_EXPAND
+#    define PNG_READ_EXPAND_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SHIFT
+#    define PNG_READ_SHIFT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_PACK
+#    define PNG_READ_PACK_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_BGR
+#    define PNG_READ_BGR_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SWAP
+#    define PNG_READ_SWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_PACKSWAP
+#    define PNG_READ_PACKSWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_INVERT
+#    define PNG_READ_INVERT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_DITHER
+#    define PNG_READ_DITHER_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_BACKGROUND
+#    define PNG_READ_BACKGROUND_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_16_TO_8
+#    define PNG_READ_16_TO_8_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_FILLER
+#    define PNG_READ_FILLER_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_GAMMA
+#    define PNG_READ_GAMMA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_GRAY_TO_RGB
+#    define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SWAP_ALPHA
+#    define PNG_READ_SWAP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_INVERT_ALPHA
+#    define PNG_READ_INVERT_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_STRIP_ALPHA
+#    define PNG_READ_STRIP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_USER_TRANSFORM
+#    define PNG_READ_USER_TRANSFORM_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_RGB_TO_GRAY
+#    define PNG_READ_RGB_TO_GRAY_SUPPORTED
+#  endif
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+#if !defined(PNG_NO_PROGRESSIVE_READ) && \
+ !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED)  /* if you don't do progressive */
+#  define PNG_PROGRESSIVE_READ_SUPPORTED     /* reading.  This is not talking */
+#endif                               /* about interlacing capability!  You'll */
+              /* still have interlacing unless you change the following line: */
+
+#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */
+
+#ifndef PNG_NO_READ_COMPOSITE_NODIV
+#  ifndef PNG_NO_READ_COMPOSITED_NODIV  /* libpng-1.0.x misspelling */
+#    define PNG_READ_COMPOSITE_NODIV_SUPPORTED   /* well tested on Intel, SGI */
+#  endif
+#endif
+
+/* Deprecated, will be removed from version 2.0.0.
+   Use PNG_MNG_FEATURES_SUPPORTED instead. */
+#ifndef PNG_NO_READ_EMPTY_PLTE
+#  define PNG_READ_EMPTY_PLTE_SUPPORTED
+#endif
+
+#endif /* PNG_READ_SUPPORTED */
+
+#if defined(PNG_WRITE_SUPPORTED)
+
+# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
+    !defined(PNG_NO_WRITE_TRANSFORMS)
+#  define PNG_WRITE_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+#  ifndef PNG_NO_WRITE_SHIFT
+#    define PNG_WRITE_SHIFT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_PACK
+#    define PNG_WRITE_PACK_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_BGR
+#    define PNG_WRITE_BGR_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_SWAP
+#    define PNG_WRITE_SWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_PACKSWAP
+#    define PNG_WRITE_PACKSWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_INVERT
+#    define PNG_WRITE_INVERT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_FILLER
+#    define PNG_WRITE_FILLER_SUPPORTED   /* same as WRITE_STRIP_ALPHA */
+#  endif
+#  ifndef PNG_NO_WRITE_SWAP_ALPHA
+#    define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_INVERT_ALPHA
+#    define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_USER_TRANSFORM
+#    define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#  endif
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
+
+#define PNG_WRITE_INTERLACING_SUPPORTED  /* not required for PNG-compliant
+                                            encoders, but can cause trouble
+                                            if left undefined */
+
+#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
+     defined(PNG_FLOATING_POINT_SUPPORTED)
+#  define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#endif
+
+#ifndef PNG_NO_WRITE_FLUSH
+#  define PNG_WRITE_FLUSH_SUPPORTED
+#endif
+
+/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
+#ifndef PNG_NO_WRITE_EMPTY_PLTE
+#  define PNG_WRITE_EMPTY_PLTE_SUPPORTED
+#endif
+
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef PNG_1_0_X
+#  ifndef PNG_NO_ERROR_NUMBERS
+#    define PNG_ERROR_NUMBERS_SUPPORTED
+#  endif
+#endif /* PNG_1_0_X */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+#  ifndef PNG_NO_USER_TRANSFORM_PTR
+#    define PNG_USER_TRANSFORM_PTR_SUPPORTED
+#  endif
+#endif
+
+#ifndef PNG_NO_STDIO
+#  define PNG_TIME_RFC1123_SUPPORTED
+#endif
+
+/* This adds extra functions in pngget.c for accessing data from the
+ * info pointer (added in version 0.99)
+ * png_get_image_width()
+ * png_get_image_height()
+ * png_get_bit_depth()
+ * png_get_color_type()
+ * png_get_compression_type()
+ * png_get_filter_type()
+ * png_get_interlace_type()
+ * png_get_pixel_aspect_ratio()
+ * png_get_pixels_per_meter()
+ * png_get_x_offset_pixels()
+ * png_get_y_offset_pixels()
+ * png_get_x_offset_microns()
+ * png_get_y_offset_microns()
+ */
+#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
+#  define PNG_EASY_ACCESS_SUPPORTED
+#endif
+
+/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 
+   even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
+#  ifndef PNG_ASSEMBLER_CODE_SUPPORTED
+#    define PNG_ASSEMBLER_CODE_SUPPORTED
+#  endif
+#  if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+#    define PNG_MMX_CODE_SUPPORTED
+#  endif
+#endif
+
+/* If you are sure that you don't need thread safety and you are compiling
+   with PNG_USE_PNGCCRD for an MMX application, you can define this for
+   faster execution.  See pnggccrd.c.
+#define PNG_THREAD_UNSAFE_OK
+*/
+
+#if !defined(PNG_1_0_X)
+#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
+#  define PNG_USER_MEM_SUPPORTED
+#endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.2.6 */
+#if !defined(PNG_1_0_X)
+#ifndef PNG_SET_USER_LIMITS_SUPPORTED
+#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED)
+#  define PNG_SET_USER_LIMITS_SUPPORTED
+#endif
+#endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.0.16 and 1.2.6.  To accept all valid PNGS no matter
+ * how large, set these limits to 0x7fffffffL
+ */
+#ifndef PNG_USER_WIDTH_MAX
+#  define PNG_USER_WIDTH_MAX 1000000L
+#endif
+#ifndef PNG_USER_HEIGHT_MAX
+#  define PNG_USER_HEIGHT_MAX 1000000L
+#endif
+
+/* These are currently experimental features, define them if you want */
+
+/* very little testing */
+/*
+#ifdef PNG_READ_SUPPORTED
+#  ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+#    define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+#  endif
+#endif
+*/
+
+/* This is only for PowerPC big-endian and 680x0 systems */
+/* some testing */
+/*
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+#  define PNG_READ_BIG_ENDIAN_SUPPORTED
+#endif
+*/
+
+/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
+/*
+#define PNG_NO_POINTER_INDEXING
+*/
+
+/* These functions are turned off by default, as they will be phased out. */
+/*
+#define  PNG_USELESS_TESTS_SUPPORTED
+#define  PNG_CORRECT_PALETTE_SUPPORTED
+*/
+
+/* Any chunks you are not interested in, you can undef here.  The
+ * ones that allocate memory may be expecially important (hIST,
+ * tEXt, zTXt, tRNS, pCAL).  Others will just save time and make png_info
+ * a bit smaller.
+ */
+
+#if defined(PNG_READ_SUPPORTED) && \
+    !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+    !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
+#  define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#if defined(PNG_WRITE_SUPPORTED) && \
+    !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+    !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
+#  define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_READ_TEXT
+#  define PNG_NO_READ_iTXt
+#  define PNG_NO_READ_tEXt
+#  define PNG_NO_READ_zTXt
+#endif
+#ifndef PNG_NO_READ_bKGD
+#  define PNG_READ_bKGD_SUPPORTED
+#  define PNG_bKGD_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_cHRM
+#  define PNG_READ_cHRM_SUPPORTED
+#  define PNG_cHRM_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_gAMA
+#  define PNG_READ_gAMA_SUPPORTED
+#  define PNG_gAMA_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_hIST
+#  define PNG_READ_hIST_SUPPORTED
+#  define PNG_hIST_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iCCP
+#  define PNG_READ_iCCP_SUPPORTED
+#  define PNG_iCCP_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iTXt
+#  ifndef PNG_READ_iTXt_SUPPORTED
+#    define PNG_READ_iTXt_SUPPORTED
+#  endif
+#  ifndef PNG_iTXt_SUPPORTED
+#    define PNG_iTXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_READ_oFFs
+#  define PNG_READ_oFFs_SUPPORTED
+#  define PNG_oFFs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pCAL
+#  define PNG_READ_pCAL_SUPPORTED
+#  define PNG_pCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sCAL
+#  define PNG_READ_sCAL_SUPPORTED
+#  define PNG_sCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pHYs
+#  define PNG_READ_pHYs_SUPPORTED
+#  define PNG_pHYs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sBIT
+#  define PNG_READ_sBIT_SUPPORTED
+#  define PNG_sBIT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sPLT
+#  define PNG_READ_sPLT_SUPPORTED
+#  define PNG_sPLT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sRGB
+#  define PNG_READ_sRGB_SUPPORTED
+#  define PNG_sRGB_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tEXt
+#  define PNG_READ_tEXt_SUPPORTED
+#  define PNG_tEXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tIME
+#  define PNG_READ_tIME_SUPPORTED
+#  define PNG_tIME_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tRNS
+#  define PNG_READ_tRNS_SUPPORTED
+#  define PNG_tRNS_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_zTXt
+#  define PNG_READ_zTXt_SUPPORTED
+#  define PNG_zTXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
+#  define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#  endif
+#  ifndef PNG_NO_HANDLE_AS_UNKNOWN
+#    define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#  endif
+#endif
+#if !defined(PNG_NO_READ_USER_CHUNKS) && \
+     defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+#  define PNG_READ_USER_CHUNKS_SUPPORTED
+#  define PNG_USER_CHUNKS_SUPPORTED
+#  ifdef PNG_NO_READ_UNKNOWN_CHUNKS
+#    undef PNG_NO_READ_UNKNOWN_CHUNKS
+#  endif
+#  ifdef PNG_NO_HANDLE_AS_UNKNOWN
+#    undef PNG_NO_HANDLE_AS_UNKNOWN
+#  endif
+#endif
+#ifndef PNG_NO_READ_OPT_PLTE
+#  define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
+#endif                      /* optional PLTE chunk in RGB and RGBA images */
+#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
+    defined(PNG_READ_zTXt_SUPPORTED)
+#  define PNG_READ_TEXT_SUPPORTED
+#  define PNG_TEXT_SUPPORTED
+#endif
+
+#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
+
+#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_WRITE_TEXT
+#  define PNG_NO_WRITE_iTXt
+#  define PNG_NO_WRITE_tEXt
+#  define PNG_NO_WRITE_zTXt
+#endif
+#ifndef PNG_NO_WRITE_bKGD
+#  define PNG_WRITE_bKGD_SUPPORTED
+#  ifndef PNG_bKGD_SUPPORTED
+#    define PNG_bKGD_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_cHRM
+#  define PNG_WRITE_cHRM_SUPPORTED
+#  ifndef PNG_cHRM_SUPPORTED
+#    define PNG_cHRM_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_gAMA
+#  define PNG_WRITE_gAMA_SUPPORTED
+#  ifndef PNG_gAMA_SUPPORTED
+#    define PNG_gAMA_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_hIST
+#  define PNG_WRITE_hIST_SUPPORTED
+#  ifndef PNG_hIST_SUPPORTED
+#    define PNG_hIST_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_iCCP
+#  define PNG_WRITE_iCCP_SUPPORTED
+#  ifndef PNG_iCCP_SUPPORTED
+#    define PNG_iCCP_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_iTXt
+#  ifndef PNG_WRITE_iTXt_SUPPORTED
+#    define PNG_WRITE_iTXt_SUPPORTED
+#  endif
+#  ifndef PNG_iTXt_SUPPORTED
+#    define PNG_iTXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_oFFs
+#  define PNG_WRITE_oFFs_SUPPORTED
+#  ifndef PNG_oFFs_SUPPORTED
+#    define PNG_oFFs_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_pCAL
+#  define PNG_WRITE_pCAL_SUPPORTED
+#  ifndef PNG_pCAL_SUPPORTED
+#    define PNG_pCAL_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sCAL
+#  define PNG_WRITE_sCAL_SUPPORTED
+#  ifndef PNG_sCAL_SUPPORTED
+#    define PNG_sCAL_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_pHYs
+#  define PNG_WRITE_pHYs_SUPPORTED
+#  ifndef PNG_pHYs_SUPPORTED
+#    define PNG_pHYs_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sBIT
+#  define PNG_WRITE_sBIT_SUPPORTED
+#  ifndef PNG_sBIT_SUPPORTED
+#    define PNG_sBIT_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sPLT
+#  define PNG_WRITE_sPLT_SUPPORTED
+#  ifndef PNG_sPLT_SUPPORTED
+#    define PNG_sPLT_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sRGB
+#  define PNG_WRITE_sRGB_SUPPORTED
+#  ifndef PNG_sRGB_SUPPORTED
+#    define PNG_sRGB_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_tEXt
+#  define PNG_WRITE_tEXt_SUPPORTED
+#  ifndef PNG_tEXt_SUPPORTED
+#    define PNG_tEXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_tIME
+#  define PNG_WRITE_tIME_SUPPORTED
+#  ifndef PNG_tIME_SUPPORTED
+#    define PNG_tIME_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_tRNS
+#  define PNG_WRITE_tRNS_SUPPORTED
+#  ifndef PNG_tRNS_SUPPORTED
+#    define PNG_tRNS_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_zTXt
+#  define PNG_WRITE_zTXt_SUPPORTED
+#  ifndef PNG_zTXt_SUPPORTED
+#    define PNG_zTXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
+#  define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#  endif
+#  ifndef PNG_NO_HANDLE_AS_UNKNOWN
+#     ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#       define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#     endif
+#  endif
+#endif
+#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+    defined(PNG_WRITE_zTXt_SUPPORTED)
+#  define PNG_WRITE_TEXT_SUPPORTED
+#  ifndef PNG_TEXT_SUPPORTED
+#    define PNG_TEXT_SUPPORTED
+#  endif
+#endif
+
+#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
+
+/* Turn this off to disable png_read_png() and
+ * png_write_png() and leave the row_pointers member
+ * out of the info structure.
+ */
+#ifndef PNG_NO_INFO_IMAGE
+#  define PNG_INFO_IMAGE_SUPPORTED
+#endif
+
+/* need the time information for reading tIME chunks */
+#if defined(PNG_tIME_SUPPORTED)
+#  if !defined(_WIN32_WCE)
+     /* "time.h" functions are not supported on WindowsCE */
+#    include <time.h>
+#  endif
+#endif
+
+/* Some typedefs to get us started.  These should be safe on most of the
+ * common platforms.  The typedefs should be at least as large as the
+ * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
+ * don't have to be exactly that size.  Some compilers dislike passing
+ * unsigned shorts as function parameters, so you may be better off using
+ * unsigned int for png_uint_16.  Likewise, for 64-bit systems, you may
+ * want to have unsigned int for png_uint_32 instead of unsigned long.
+ */
+
+typedef unsigned long png_uint_32;
+typedef long png_int_32;
+typedef unsigned short png_uint_16;
+typedef short png_int_16;
+typedef unsigned char png_byte;
+
+/* This is usually size_t.  It is typedef'ed just in case you need it to
+   change (I'm not sure if you will or not, so I thought I'd be safe) */
+#ifdef PNG_SIZE_T
+   typedef PNG_SIZE_T png_size_t;
+#  define png_sizeof(x) png_convert_size(sizeof (x))
+#else
+   typedef size_t png_size_t;
+#  define png_sizeof(x) sizeof (x)
+#endif
+
+/* The following is needed for medium model support.  It cannot be in the
+ * PNG_INTERNAL section.  Needs modification for other compilers besides
+ * MSC.  Model independent support declares all arrays and pointers to be
+ * large using the far keyword.  The zlib version used must also support
+ * model independent data.  As of version zlib 1.0.4, the necessary changes
+ * have been made in zlib.  The USE_FAR_KEYWORD define triggers other
+ * changes that are needed. (Tim Wegner)
+ */
+
+/* Separate compiler dependencies (problem here is that zlib.h always
+   defines FAR. (SJT) */
+#ifdef __BORLANDC__
+#  if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
+#    define LDATA 1
+#  else
+#    define LDATA 0
+#  endif
+   /* GRR:  why is Cygwin in here?  Cygwin is not Borland C... */
+#  if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
+#    define PNG_MAX_MALLOC_64K
+#    if (LDATA != 1)
+#      ifndef FAR
+#        define FAR __far
+#      endif
+#      define USE_FAR_KEYWORD
+#    endif   /* LDATA != 1 */
+     /* Possibly useful for moving data out of default segment.
+      * Uncomment it if you want. Could also define FARDATA as
+      * const if your compiler supports it. (SJT)
+#    define FARDATA FAR
+      */
+#  endif  /* __WIN32__, __FLAT__, __CYGWIN__ */
+#endif   /* __BORLANDC__ */
+
+
+/* Suggest testing for specific compiler first before testing for
+ * FAR.  The Watcom compiler defines both __MEDIUM__ and M_I86MM,
+ * making reliance oncertain keywords suspect. (SJT)
+ */
+
+/* MSC Medium model */
+#if defined(FAR)
+#  if defined(M_I86MM)
+#    define USE_FAR_KEYWORD
+#    define FARDATA FAR
+#    include <dos.h>
+#  endif
+#endif
+
+/* SJT: default case */
+#ifndef FAR
+#  define FAR
+#endif
+
+/* At this point FAR is always defined */
+#ifndef FARDATA
+#  define FARDATA
+#endif
+
+/* Typedef for floating-point numbers that are converted
+   to fixed-point with a multiple of 100,000, e.g., int_gamma */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void            FAR * png_voidp;
+typedef png_byte        FAR * png_bytep;
+typedef png_uint_32     FAR * png_uint_32p;
+typedef png_int_32      FAR * png_int_32p;
+typedef png_uint_16     FAR * png_uint_16p;
+typedef png_int_16      FAR * png_int_16p;
+typedef PNG_CONST char  FAR * png_const_charp;
+typedef char            FAR * png_charp;
+typedef png_fixed_point FAR * png_fixed_point_p;
+
+#ifndef PNG_NO_STDIO
+#if defined(_WIN32_WCE)
+typedef HANDLE                png_FILE_p;
+#else
+typedef FILE                * png_FILE_p;
+#endif
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double          FAR * png_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte        FAR * FAR * png_bytepp;
+typedef png_uint_32     FAR * FAR * png_uint_32pp;
+typedef png_int_32      FAR * FAR * png_int_32pp;
+typedef png_uint_16     FAR * FAR * png_uint_16pp;
+typedef png_int_16      FAR * FAR * png_int_16pp;
+typedef PNG_CONST char  FAR * FAR * png_const_charpp;
+typedef char            FAR * FAR * png_charpp;
+typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double          FAR * FAR * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char            FAR * FAR * FAR * png_charppp;
+
+/* libpng typedefs for types in zlib. If zlib changes
+ * or another compression library is used, then change these.
+ * Eliminates need to change all the source files.
+ */
+typedef charf *         png_zcharp;
+typedef charf * FAR *   png_zcharpp;
+typedef z_stream FAR *  png_zstreamp;
+
+/*
+ * Define PNG_BUILD_DLL if the module being built is a Windows
+ * LIBPNG DLL.
+ *
+ * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
+ * It is equivalent to Microsoft predefined macro _DLL that is
+ * automatically defined when you compile using the share
+ * version of the CRT (C Run-Time library)
+ *
+ * The cygwin mods make this behavior a little different:
+ * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
+ * Define PNG_STATIC if you are building a static library for use with cygwin,
+ *   -or- if you are building an application that you want to link to the
+ *   static library.
+ * PNG_USE_DLL is defined by default (no user action needed) unless one of
+ *   the other flags is defined.
+ */
+
+#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
+#  define PNG_DLL
+#endif
+/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
+ * When building a static lib, default to no GLOBAL ARRAYS, but allow
+ * command-line override
+ */
+#if defined(__CYGWIN__)
+#  if !defined(PNG_STATIC)
+#    if defined(PNG_USE_GLOBAL_ARRAYS)
+#      undef PNG_USE_GLOBAL_ARRAYS
+#    endif
+#    if !defined(PNG_USE_LOCAL_ARRAYS)
+#      define PNG_USE_LOCAL_ARRAYS
+#    endif
+#  else
+#    if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
+#      if defined(PNG_USE_GLOBAL_ARRAYS)
+#        undef PNG_USE_GLOBAL_ARRAYS
+#      endif
+#    endif
+#  endif
+#  if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+#    define PNG_USE_LOCAL_ARRAYS
+#  endif
+#endif
+
+/* Do not use global arrays (helps with building DLL's)
+ * They are no longer used in libpng itself, since version 1.0.5c,
+ * but might be required for some pre-1.0.5c applications.
+ */
+#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+#  if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL))
+#    define PNG_USE_LOCAL_ARRAYS
+#  else
+#    define PNG_USE_GLOBAL_ARRAYS
+#  endif
+#endif
+
+#if defined(__CYGWIN__)
+#  undef PNGAPI
+#  define PNGAPI __cdecl
+#  undef PNG_IMPEXP
+#  define PNG_IMPEXP
+#endif  
+
+/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
+ * you may get warnings regarding the linkage of png_zalloc and png_zfree.
+ * Don't ignore those warnings; you must also reset the default calling
+ * convention in your compiler to match your PNGAPI, and you must build
+ * zlib and your applications the same way you build libpng.
+ */
+
+#if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
+#  ifndef PNG_NO_MODULEDEF
+#    define PNG_NO_MODULEDEF
+#  endif
+#endif
+
+#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
+#  define PNG_IMPEXP
+#endif
+
+#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
+    (( defined(_Windows) || defined(_WINDOWS) || \
+       defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
+
+#  ifndef PNGAPI
+#     if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
+#        define PNGAPI __cdecl
+#     else
+#        define PNGAPI _cdecl
+#     endif
+#  endif
+
+#  if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
+       0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
+#     define PNG_IMPEXP
+#  endif
+
+#  if !defined(PNG_IMPEXP)
+
+#     define PNG_EXPORT_TYPE1(type,symbol)  PNG_IMPEXP type PNGAPI symbol
+#     define PNG_EXPORT_TYPE2(type,symbol)  type PNG_IMPEXP PNGAPI symbol
+
+      /* Borland/Microsoft */
+#     if defined(_MSC_VER) || defined(__BORLANDC__)
+#        if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
+#           define PNG_EXPORT PNG_EXPORT_TYPE1
+#        else
+#           define PNG_EXPORT PNG_EXPORT_TYPE2
+#           if defined(PNG_BUILD_DLL)
+#              define PNG_IMPEXP __export
+#           else
+#              define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
+                                                 VC++ */
+#           endif                             /* Exists in Borland C++ for
+                                                 C++ classes (== huge) */
+#        endif
+#     endif
+
+#     if !defined(PNG_IMPEXP)
+#        if defined(PNG_BUILD_DLL)
+#           define PNG_IMPEXP __declspec(dllexport)
+#        else
+#           define PNG_IMPEXP __declspec(dllimport)
+#        endif
+#     endif
+#  endif  /* PNG_IMPEXP */
+#else /* !(DLL || non-cygwin WINDOWS) */
+#   if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
+#      ifndef PNGAPI
+#         define PNGAPI _System
+#      endif
+#   else
+#      if 0 /* ... other platforms, with other meanings */
+#      endif
+#   endif
+#endif
+
+#ifndef PNGAPI
+#  define PNGAPI
+#endif
+#ifndef PNG_IMPEXP
+#  define PNG_IMPEXP
+#endif
+
+#ifndef PNG_EXPORT
+#  define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+#  ifndef PNG_EXPORT_VAR
+#    define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
+#  endif
+#endif
+
+/* User may want to use these so they are not in PNG_INTERNAL. Any library
+ * functions that are passed far data must be model independent.
+ */
+
+#ifndef PNG_ABORT
+#  define PNG_ABORT() abort()
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#else
+#  define png_jmpbuf(png_ptr) \
+   (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
+#endif
+
+#if defined(USE_FAR_KEYWORD)  /* memory model independent fns */
+/* use this to make far-to-near assignments */
+#  define CHECK   1
+#  define NOCHECK 0
+#  define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
+#  define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
+#  define png_strcpy  _fstrcpy
+#  define png_strncpy _fstrncpy   /* Added to v 1.2.6 */
+#  define png_strlen  _fstrlen
+#  define png_memcmp  _fmemcmp    /* SJT: added */
+#  define png_memcpy  _fmemcpy
+#  define png_memset  _fmemset
+#else /* use the usual functions */
+#  define CVT_PTR(ptr)         (ptr)
+#  define CVT_PTR_NOCHECK(ptr) (ptr)
+#  define png_strcpy  strcpy
+#  define png_strncpy strncpy     /* Added to v 1.2.6 */
+#  define png_strlen  strlen
+#  define png_memcmp  memcmp      /* SJT: added */
+#  define png_memcpy  memcpy
+#  define png_memset  memset
+#endif
+/* End of memory model independent support */
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
+#  undef PNG_ZBUF_SIZE
+#  define PNG_ZBUF_SIZE 65536L
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+/* Prior to libpng-1.0.9, this block was in pngasmrd.h */
+#if defined(PNG_INTERNAL)
+
+/* These are the default thresholds before the MMX code kicks in; if either
+ * rowbytes or bitdepth is below the threshold, plain C code is used.  These
+ * can be overridden at runtime via the png_set_mmx_thresholds() call in
+ * libpng 1.2.0 and later.  The values below were chosen by Intel.
+ */
+
+#ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT
+#  define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT  128  /*  >=  */
+#endif
+#ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT
+#  define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT  9    /*  >=  */   
+#endif
+
+/* Set this in the makefile for VC++ on Pentium, not here. */
+/* Platform must be Pentium.  Makefile must assemble and load pngvcrd.c .
+ * MMX will be detected at run time and used if present.
+ */
+#ifdef PNG_USE_PNGVCRD
+#  define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+#  define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+#  define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+
+/* Set this in the makefile for gcc/as on Pentium, not here. */
+/* Platform must be Pentium.  Makefile must assemble and load pnggccrd.c .
+ * MMX will be detected at run time and used if present.
+ */
+#ifdef PNG_USE_PNGGCCRD
+#  define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+#  define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+#  define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+/* - see pnggccrd.c for info about what is currently enabled */
+
+#endif /* PNG_INTERNAL */
+#endif /* PNG_READ_SUPPORTED */
+
+#endif /* PNGCONF_H */
+
diff --git a/Utilities/FLTK/png/pngerror.c b/Utilities/FLTK/png/pngerror.c
new file mode 100644
index 0000000000000000000000000000000000000000..c25157192680f5f1a0f5ecf850305c06eb78534f
--- /dev/null
+++ b/Utilities/FLTK/png/pngerror.c
@@ -0,0 +1,295 @@
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all error handling.  Users who
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions.  See the instructions
+ * at each function.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+static void /* PRIVATE */
+png_default_error PNGARG((png_structp png_ptr,
+  png_const_charp error_message));
+static void /* PRIVATE */
+png_default_warning PNGARG((png_structp png_ptr,
+  png_const_charp warning_message));
+
+/* This function is called whenever there is a fatal error.  This function
+ * should not be changed.  If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+void PNGAPI
+png_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   char msg[16];
+   if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+   {
+     if (*error_message == '#')
+     {
+         int offset;
+         for (offset=1; offset<15; offset++)
+            if (*(error_message+offset) == ' ')
+                break;
+         if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+         {
+            int i;
+            for (i=0; i<offset-1; i++)
+               msg[i]=error_message[i+1];
+            msg[i]='\0';
+            error_message=msg;
+         }
+         else
+            error_message+=offset;
+     }
+     else
+     {
+         if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+         {
+            msg[0]='0';        
+            msg[1]='\0';
+            error_message=msg;
+         }
+     }
+   }
+#endif
+   if (png_ptr != NULL && png_ptr->error_fn != NULL)
+      (*(png_ptr->error_fn))(png_ptr, error_message);
+
+   /* If the custom handler doesn't exist, or if it returns,
+      use the default handler, which will not return. */
+   png_default_error(png_ptr, error_message);
+}
+
+/* This function is called whenever there is a non-fatal error.  This function
+ * should not be changed.  If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+   int offset = 0;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+#endif
+   {
+     if (*warning_message == '#')
+     {
+         for (offset=1; offset<15; offset++)
+            if (*(warning_message+offset) == ' ')
+                break;
+     }
+   }
+   if (png_ptr != NULL && png_ptr->warning_fn != NULL)
+      (*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
+   else
+      png_default_warning(png_ptr, warning_message+offset);
+}
+
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
+ * this is used to prefix the message.  The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+   'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static void /* PRIVATE */
+png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
+   error_message)
+{
+   int iout = 0, iin = 0;
+
+   while (iin < 4)
+   {
+      int c = png_ptr->chunk_name[iin++];
+      if (isnonalpha(c))
+      {
+         buffer[iout++] = '[';
+         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+         buffer[iout++] = png_digit[c & 0x0f];
+         buffer[iout++] = ']';
+      }
+      else
+      {
+         buffer[iout++] = (png_byte)c;
+      }
+   }
+
+   if (error_message == NULL)
+      buffer[iout] = 0;
+   else
+   {
+      buffer[iout++] = ':';
+      buffer[iout++] = ' ';
+      png_strncpy(buffer+iout, error_message, 63);
+      buffer[iout+63] = 0;
+   }
+}
+
+void PNGAPI
+png_chunk_error(png_structp png_ptr, png_const_charp error_message)
+{
+   char msg[18+64];
+   png_format_buffer(png_ptr, msg, error_message);
+   png_error(png_ptr, msg);
+}
+
+void PNGAPI
+png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+   char msg[18+64];
+   png_format_buffer(png_ptr, msg, warning_message);
+   png_warning(png_ptr, msg);
+}
+
+/* This is the default error handling function.  Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash.  This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void /* PRIVATE */
+png_default_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if (*error_message == '#')
+   {
+     int offset;
+     char error_number[16];
+     for (offset=0; offset<15; offset++)
+     {
+         error_number[offset] = *(error_message+offset+1);
+         if (*(error_message+offset) == ' ')
+             break;
+     }
+     if((offset > 1) && (offset < 15))
+     {
+       error_number[offset-1]='\0';
+       fprintf(stderr, "libpng error no. %s: %s\n", error_number,
+          error_message+offset);
+     }
+     else
+       fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
+   }
+   else
+#endif
+   fprintf(stderr, "libpng error: %s\n", error_message);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#  ifdef USE_FAR_KEYWORD
+   {
+      jmp_buf jmpbuf;
+      png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf));
+      longjmp(jmpbuf, 1);
+   }
+#  else
+   longjmp(png_ptr->jmpbuf, 1);
+# endif
+#else
+   /* make compiler happy */ ;
+   if (png_ptr)
+   PNG_ABORT();
+#endif
+#ifdef PNG_NO_CONSOLE_IO
+   /* make compiler happy */ ;
+   if (&error_message != NULL)
+      return;
+#endif
+}
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway.  Replacement functions don't have to do anything
+ * here if you don't want them to.  In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+#ifndef PNG_NO_CONSOLE_IO
+#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if (*warning_message == '#')
+   {
+     int offset;
+     char warning_number[16];
+     for (offset=0; offset<15; offset++)
+     {
+        warning_number[offset]=*(warning_message+offset+1);
+        if (*(warning_message+offset) == ' ')
+            break;
+     }
+     if((offset > 1) && (offset < 15))
+     {
+       warning_number[offset-1]='\0';
+       fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
+          warning_message+offset);
+     }
+     else
+       fprintf(stderr, "libpng warning: %s\n", warning_message);
+   }
+   else
+#  endif
+     fprintf(stderr, "libpng warning: %s\n", warning_message);
+#else
+   /* make compiler happy */ ;
+   if (warning_message)
+     return;
+#endif
+   /* make compiler happy */ ;
+   if (png_ptr)
+      return;
+}
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings.  Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur.  The return
+ * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+   png_ptr->error_ptr = error_ptr;
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_structp png_ptr)
+{
+   return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
+{
+   if(png_ptr != NULL)
+   {
+     png_ptr->flags &=
+       ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+   }
+}
+#endif
diff --git a/Utilities/FLTK/png/pngget.c b/Utilities/FLTK/png/pngget.c
new file mode 100644
index 0000000000000000000000000000000000000000..eefd3319b4382684dda74388654543915ebab77f
--- /dev/null
+++ b/Utilities/FLTK/png/pngget.c
@@ -0,0 +1,934 @@
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * libpng 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+png_uint_32 PNGAPI
+png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->valid & flag);
+   else
+      return(0);
+}
+
+png_uint_32 PNGAPI
+png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->rowbytes);
+   else
+      return(0);
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+png_bytepp PNGAPI
+png_get_rows(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->row_pointers);
+   else
+      return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->width;
+   }
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->height;
+   }
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->bit_depth;
+   }
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->color_type;
+   }
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->filter_type;
+   }
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->interlace_type;
+   }
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->compression_type;
+   }
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
+      if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+          return (0);
+      else return (info_ptr->x_pixels_per_unit);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
+      if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+          return (0);
+      else return (info_ptr->y_pixels_per_unit);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
+      if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
+         info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
+          return (0);
+      else return (info_ptr->x_pixels_per_unit);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
+   {
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
+      if (info_ptr->x_pixels_per_unit == 0)
+         return ((float)0.0);
+      else
+         return ((float)((float)info_ptr->y_pixels_per_unit
+            /(float)info_ptr->x_pixels_per_unit));
+   }
+#else
+   return (0.0);
+#endif
+   return ((float)0.0);
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+          return (0);
+      else return (info_ptr->x_offset);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+          return (0);
+      else return (info_ptr->y_offset);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+          return (0);
+      else return (info_ptr->x_offset);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+          return (0);
+      else return (info_ptr->y_offset);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
+     *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
+     *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
+     *.0254 +.5));
+}
+
+float PNGAPI
+png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
+     *.00003937);
+}
+
+float PNGAPI
+png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
+     *.00003937);
+}
+
+#if defined(PNG_pHYs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "pHYs");
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+         if(*unit_type == 1)
+         {
+            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+         }
+      }
+   }
+   return (retval);
+}
+#endif /* PNG_pHYs_SUPPORTED */
+#endif  /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif  /* PNG_EASY_ACCESS_SUPPORTED */
+
+png_byte PNGAPI
+png_get_channels(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->channels);
+   else
+      return (0);
+}
+
+png_bytep PNGAPI
+png_get_signature(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->signature);
+   else
+      return (NULL);
+}
+
+#if defined(PNG_bKGD_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
+   png_color_16p *background)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+      && background != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "bKGD");
+      *background = &(info_ptr->background);
+      return (PNG_INFO_bKGD);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
+   double *white_x, double *white_y, double *red_x, double *red_y,
+   double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+   {
+      png_debug1(1, "in %s retrieval function\n", "cHRM");
+      if (white_x != NULL)
+         *white_x = (double)info_ptr->x_white;
+      if (white_y != NULL)
+         *white_y = (double)info_ptr->y_white;
+      if (red_x != NULL)
+         *red_x = (double)info_ptr->x_red;
+      if (red_y != NULL)
+         *red_y = (double)info_ptr->y_red;
+      if (green_x != NULL)
+         *green_x = (double)info_ptr->x_green;
+      if (green_y != NULL)
+         *green_y = (double)info_ptr->y_green;
+      if (blue_x != NULL)
+         *blue_x = (double)info_ptr->x_blue;
+      if (blue_y != NULL)
+         *blue_y = (double)info_ptr->y_blue;
+      return (PNG_INFO_cHRM);
+   }
+   return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+   png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+   png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+   png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+   {
+      png_debug1(1, "in %s retrieval function\n", "cHRM");
+      if (white_x != NULL)
+         *white_x = info_ptr->int_x_white;
+      if (white_y != NULL)
+         *white_y = info_ptr->int_y_white;
+      if (red_x != NULL)
+         *red_x = info_ptr->int_x_red;
+      if (red_y != NULL)
+         *red_y = info_ptr->int_y_red;
+      if (green_x != NULL)
+         *green_x = info_ptr->int_x_green;
+      if (green_y != NULL)
+         *green_y = info_ptr->int_y_green;
+      if (blue_x != NULL)
+         *blue_x = info_ptr->int_x_blue;
+      if (blue_y != NULL)
+         *blue_y = info_ptr->int_y_blue;
+      return (PNG_INFO_cHRM);
+   }
+   return (0);
+}
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+      && file_gamma != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "gAMA");
+      *file_gamma = (double)info_ptr->gamma;
+      return (PNG_INFO_gAMA);
+   }
+   return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
+    png_fixed_point *int_file_gamma)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+      && int_file_gamma != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "gAMA");
+      *int_file_gamma = info_ptr->int_gamma;
+      return (PNG_INFO_gAMA);
+   }
+   return (0);
+}
+#endif
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+      && file_srgb_intent != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "sRGB");
+      *file_srgb_intent = (int)info_ptr->srgb_intent;
+      return (PNG_INFO_sRGB);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charpp name, int *compression_type,
+             png_charpp profile, png_uint_32 *proflen)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+      && name != NULL && profile != NULL && proflen != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "iCCP");
+      *name = info_ptr->iccp_name;
+      *profile = info_ptr->iccp_profile;
+      /* compression_type is a dummy so the API won't have to change
+         if we introduce multiple compression types later. */
+      *proflen = (int)info_ptr->iccp_proflen;
+      *compression_type = (int)info_ptr->iccp_compression;
+      return (PNG_INFO_iCCP);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
+             png_sPLT_tpp spalettes)
+{
+   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+     *spalettes = info_ptr->splt_palettes;
+   return ((png_uint_32)info_ptr->splt_palettes_num);
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+      && hist != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "hIST");
+      *hist = info_ptr->hist;
+      return (PNG_INFO_hIST);
+   }
+   return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+   int *color_type, int *interlace_type, int *compression_type,
+   int *filter_type)
+
+{
+   if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
+      bit_depth != NULL && color_type != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "IHDR");
+      *width = info_ptr->width;
+      *height = info_ptr->height;
+      *bit_depth = info_ptr->bit_depth;
+      if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16)
+        png_error(png_ptr, "Invalid bit depth");
+      *color_type = info_ptr->color_type;
+      if (info_ptr->color_type > 6)
+        png_error(png_ptr, "Invalid color type");
+      if (compression_type != NULL)
+         *compression_type = info_ptr->compression_type;
+      if (filter_type != NULL)
+         *filter_type = info_ptr->filter_type;
+      if (interlace_type != NULL)
+         *interlace_type = info_ptr->interlace_type;
+
+      /* check for potential overflow of rowbytes */
+      if (width == 0 || *width > PNG_UINT_31_MAX)
+        png_error(png_ptr, "Invalid image width");
+      if (height == 0 || *height > PNG_UINT_31_MAX)
+        png_error(png_ptr, "Invalid image height");
+      if (info_ptr->width > (PNG_UINT_32_MAX
+                 >> 3)      /* 8-byte RGBA pixels */
+                 - 64       /* bigrowbuf hack */
+                 - 1        /* filter byte */
+                 - 7*8      /* rounding of width to multiple of 8 pixels */
+                 - 8)       /* extra max_pixel_depth pad */
+      {
+         png_warning(png_ptr,
+            "Width too large for libpng to process image data.");
+      }
+      return (1);
+   }
+   return (0);
+}
+
+#if defined(PNG_oFFs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
+   png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+      && offset_x != NULL && offset_y != NULL && unit_type != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "oFFs");
+      *offset_x = info_ptr->x_offset;
+      *offset_y = info_ptr->y_offset;
+      *unit_type = (int)info_ptr->offset_unit_type;
+      return (PNG_INFO_oFFs);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
+   png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+   png_charp *units, png_charpp *params)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+      && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+      nparams != NULL && units != NULL && params != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "pCAL");
+      *purpose = info_ptr->pcal_purpose;
+      *X0 = info_ptr->pcal_X0;
+      *X1 = info_ptr->pcal_X1;
+      *type = (int)info_ptr->pcal_type;
+      *nparams = (int)info_ptr->pcal_nparams;
+      *units = info_ptr->pcal_units;
+      *params = info_ptr->pcal_params;
+      return (PNG_INFO_pCAL);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+             int *unit, double *width, double *height)
+{
+    if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sCAL))
+    {
+        *unit = info_ptr->scal_unit;
+        *width = info_ptr->scal_pixel_width;
+        *height = info_ptr->scal_pixel_height;
+        return (PNG_INFO_sCAL);
+    }
+    return(0);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+             int *unit, png_charpp width, png_charpp height)
+{
+    if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sCAL))
+    {
+        *unit = info_ptr->scal_unit;
+        *width = info_ptr->scal_s_width;
+        *height = info_ptr->scal_s_height;
+        return (PNG_INFO_sCAL);
+    }
+    return(0);
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "pHYs");
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+      }
+   }
+   return (retval);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
+   int *num_palette)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+       && palette != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "PLTE");
+      *palette = info_ptr->palette;
+      *num_palette = info_ptr->num_palette;
+      png_debug1(3, "num_palette = %d\n", *num_palette);
+      return (PNG_INFO_PLTE);
+   }
+   return (0);
+}
+
+#if defined(PNG_sBIT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+      && sig_bit != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "sBIT");
+      *sig_bit = &(info_ptr->sig_bit);
+      return (PNG_INFO_sBIT);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
+   int *num_text)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+   {
+      png_debug1(1, "in %s retrieval function\n",
+         (png_ptr->chunk_name[0] == '\0' ? "text"
+             : (png_const_charp)png_ptr->chunk_name));
+      if (text_ptr != NULL)
+         *text_ptr = info_ptr->text;
+      if (num_text != NULL)
+         *num_text = info_ptr->num_text;
+      return ((png_uint_32)info_ptr->num_text);
+   }
+   if (num_text != NULL)
+     *num_text = 0;
+   return(0);
+}
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+       && mod_time != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "tIME");
+      *mod_time = &(info_ptr->mod_time);
+      return (PNG_INFO_tIME);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
+   png_bytep *trans, int *num_trans, png_color_16p *trans_values)
+{
+   png_uint_32 retval = 0;
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+   {
+      png_debug1(1, "in %s retrieval function\n", "tRNS");
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+          if (trans != NULL)
+          {
+             *trans = info_ptr->trans;
+             retval |= PNG_INFO_tRNS;
+          }
+          if (trans_values != NULL)
+             *trans_values = &(info_ptr->trans_values);
+      }
+      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+      {
+          if (trans_values != NULL)
+          {
+             *trans_values = &(info_ptr->trans_values);
+             retval |= PNG_INFO_tRNS;
+          }
+          if(trans != NULL)
+             *trans = NULL;
+      }
+      if(num_trans != NULL)
+      {
+         *num_trans = info_ptr->num_trans;
+         retval |= PNG_INFO_tRNS;
+      }
+   }
+   return (retval);
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
+             png_unknown_chunkpp unknowns)
+{
+   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+     *unknowns = info_ptr->unknown_chunks;
+   return ((png_uint_32)info_ptr->unknown_chunks_num);
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_structp png_ptr)
+{
+   return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_structp png_ptr)
+{
+   return (png_ptr? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+png_uint_32 PNGAPI
+png_get_compression_buffer_size(png_structp png_ptr)
+{
+   return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
+}
+#endif
+
+#ifndef PNG_1_0_X
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* this function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flags (png_structp png_ptr)
+{
+    return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L);
+}
+
+/* this function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flagmask (int flag_select)
+{
+    png_uint_32 settable_asm_flags = 0;
+
+    if (flag_select & PNG_SELECT_READ)
+        settable_asm_flags |=
+          PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  |
+          PNG_ASM_FLAG_MMX_READ_INTERLACE    |
+          PNG_ASM_FLAG_MMX_READ_FILTER_SUB   |
+          PNG_ASM_FLAG_MMX_READ_FILTER_UP    |
+          PNG_ASM_FLAG_MMX_READ_FILTER_AVG   |
+          PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+          /* no non-MMX flags yet */
+
+#if 0
+    /* GRR:  no write-flags yet, either, but someday... */
+    if (flag_select & PNG_SELECT_WRITE)
+        settable_asm_flags |=
+          PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
+#endif /* 0 */
+
+    return settable_asm_flags;  /* _theoretically_ settable capabilities only */
+}
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+    /* GRR:  could add this:   && defined(PNG_MMX_CODE_SUPPORTED) */
+/* this function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_flagmask (int flag_select, int *compilerID)
+{
+    png_uint_32 settable_mmx_flags = 0;
+
+    if (flag_select & PNG_SELECT_READ)
+        settable_mmx_flags |=
+          PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  |
+          PNG_ASM_FLAG_MMX_READ_INTERLACE    |
+          PNG_ASM_FLAG_MMX_READ_FILTER_SUB   |
+          PNG_ASM_FLAG_MMX_READ_FILTER_UP    |
+          PNG_ASM_FLAG_MMX_READ_FILTER_AVG   |
+          PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+#if 0
+    /* GRR:  no MMX write support yet, but someday... */
+    if (flag_select & PNG_SELECT_WRITE)
+        settable_mmx_flags |=
+          PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
+#endif /* 0 */
+
+    if (compilerID != NULL) {
+#ifdef PNG_USE_PNGVCRD
+        *compilerID = 1;    /* MSVC */
+#else
+#ifdef PNG_USE_PNGGCCRD
+        *compilerID = 2;    /* gcc/gas */
+#else
+        *compilerID = -1;   /* unknown (i.e., no asm/MMX code compiled) */
+#endif
+#endif
+    }
+
+    return settable_mmx_flags;  /* _theoretically_ settable capabilities only */
+}
+
+/* this function was added to libpng 1.2.0 */
+png_byte PNGAPI
+png_get_mmx_bitdepth_threshold (png_structp png_ptr)
+{
+    return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0);
+}
+
+/* this function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_rowbytes_threshold (png_structp png_ptr)
+{
+    return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L);
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* these functions were added to libpng 1.2.6 */
+png_uint_32 PNGAPI
+png_get_user_width_max (png_structp png_ptr)
+{
+    return (png_ptr? png_ptr->user_width_max : 0);
+}
+png_uint_32 PNGAPI
+png_get_user_height_max (png_structp png_ptr)
+{
+    return (png_ptr? png_ptr->user_height_max : 0);
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+#endif /* ?PNG_1_0_X */
diff --git a/Utilities/FLTK/png/pngmem.c b/Utilities/FLTK/png/pngmem.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d0c2b9d29a7a87fbaed1770ed7d2ea607e40994
--- /dev/null
+++ b/Utilities/FLTK/png/pngmem.c
@@ -0,0 +1,595 @@
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all memory allocation.  Users who
+ * need special memory handling are expected to supply replacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the replacement functions.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Borland DOS special memory handler */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* if you change this, be sure to change the one in png.h also */
+
+/* Allocate memory for a png_struct.  The malloc and memset can be replaced
+   by a single call to calloc() if this is thought to improve performance. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Alternate version of png_create_struct, for use with user-defined malloc. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+   png_size_t size;
+   png_voidp struct_ptr;
+
+   if (type == PNG_STRUCT_INFO)
+     size = png_sizeof(png_info);
+   else if (type == PNG_STRUCT_PNG)
+     size = png_sizeof(png_struct);
+   else
+     return (png_get_copyright(NULL));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if(malloc_fn != NULL)
+   {
+      png_struct dummy_struct;
+      png_structp png_ptr = &dummy_struct;
+      png_ptr->mem_ptr=mem_ptr;
+      struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
+   }
+   else
+#endif /* PNG_USER_MEM_SUPPORTED */
+      struct_ptr = (png_voidp)farmalloc(size);
+   if (struct_ptr != NULL)
+      png_memset(struct_ptr, 0, size);
+   return (struct_ptr);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+    png_voidp mem_ptr)
+{
+#endif
+   if (struct_ptr != NULL)
+   {
+#ifdef PNG_USER_MEM_SUPPORTED
+      if(free_fn != NULL)
+      {
+         png_struct dummy_struct;
+         png_structp png_ptr = &dummy_struct;
+         png_ptr->mem_ptr=mem_ptr;
+         (*(free_fn))(png_ptr, struct_ptr);
+         return;
+      }
+#endif /* PNG_USER_MEM_SUPPORTED */
+      farfree (struct_ptr);
+   }
+}
+
+/* Allocate memory.  For reasonable files, size should never exceed
+ * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * it not to.  See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * Borland seems to have a problem in DOS mode for exactly 64K.
+ * It gives you a segment with an offset of 8 (perhaps to store its
+ * memory stuff).  zlib doesn't like this at all, so we have to
+ * detect and deal with it.  This code should not be needed in
+ * Windows or OS/2 modes, and only in 16 bit mode.  This code has
+ * been updated by Alexander Lehmann for version 0.89 to waste less
+ * memory.
+ *
+ * Note that we can't use png_size_t for the "size" declaration,
+ * since on some systems a png_size_t is a 16-bit quantity, and as a
+ * result, we would be truncating potentially larger memory requests
+ * (which should cause a fatal error) and introducing major problems.
+ */
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+
+   if (png_ptr == NULL || size == 0)
+      return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if(png_ptr->malloc_fn != NULL)
+       ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+   else
+       ret = (png_malloc_default(png_ptr, size));
+   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+       png_error(png_ptr, "Out of memory!");
+   return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (size > (png_uint_32)65536L)
+   {
+      png_warning(png_ptr, "Cannot Allocate > 64K");
+      ret = NULL;
+   }
+   else
+#endif
+
+   if (size != (size_t)size)
+     ret = NULL;
+   else if (size == (png_uint_32)65536L)
+   {
+      if (png_ptr->offset_table == NULL)
+      {
+         /* try to see if we need to do any of this fancy stuff */
+         ret = farmalloc(size);
+         if (ret == NULL || ((png_size_t)ret & 0xffff))
+         {
+            int num_blocks;
+            png_uint_32 total_size;
+            png_bytep table;
+            int i;
+            png_byte huge * hptr;
+
+            if (ret != NULL)
+            {
+               farfree(ret);
+               ret = NULL;
+            }
+
+            if(png_ptr->zlib_window_bits > 14)
+               num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+            else
+               num_blocks = 1;
+            if (png_ptr->zlib_mem_level >= 7)
+               num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
+            else
+               num_blocks++;
+
+            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
+
+            table = farmalloc(total_size);
+
+            if (table == NULL)
+            {
+#ifndef PNG_USER_MEM_SUPPORTED
+               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+                  png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
+               else
+                  png_warning(png_ptr, "Out Of Memory.");
+#endif
+               return (NULL);
+            }
+
+            if ((png_size_t)table & 0xfff0)
+            {
+#ifndef PNG_USER_MEM_SUPPORTED
+               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+                  png_error(png_ptr,
+                    "Farmalloc didn't return normalized pointer");
+               else
+                  png_warning(png_ptr,
+                    "Farmalloc didn't return normalized pointer");
+#endif
+               return (NULL);
+            }
+
+            png_ptr->offset_table = table;
+            png_ptr->offset_table_ptr = farmalloc(num_blocks *
+               png_sizeof (png_bytep));
+
+            if (png_ptr->offset_table_ptr == NULL)
+            {
+#ifndef PNG_USER_MEM_SUPPORTED
+               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+                  png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
+               else
+                  png_warning(png_ptr, "Out Of memory.");
+#endif
+               return (NULL);
+            }
+
+            hptr = (png_byte huge *)table;
+            if ((png_size_t)hptr & 0xf)
+            {
+               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
+               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
+            }
+            for (i = 0; i < num_blocks; i++)
+            {
+               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
+               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
+            }
+
+            png_ptr->offset_table_number = num_blocks;
+            png_ptr->offset_table_count = 0;
+            png_ptr->offset_table_count_free = 0;
+         }
+      }
+
+      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
+      {
+#ifndef PNG_USER_MEM_SUPPORTED
+         if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+            png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
+         else
+            png_warning(png_ptr, "Out of Memory.");
+#endif
+         return (NULL);
+      }
+
+      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
+   }
+   else
+      ret = farmalloc(size);
+
+#ifndef PNG_USER_MEM_SUPPORTED
+   if (ret == NULL)
+   {
+      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+         png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
+      else
+         png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
+   }
+#endif
+
+   return (ret);
+}
+
+/* free a pointer allocated by png_malloc().  In the default
+   configuration, png_ptr is not used, but is passed in case it
+   is needed.  If ptr is NULL, return without taking any action. */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr->free_fn != NULL)
+   {
+      (*(png_ptr->free_fn))(png_ptr, ptr);
+      return;
+   }
+   else png_free_default(png_ptr, ptr);
+}
+
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+   if (png_ptr->offset_table != NULL)
+   {
+      int i;
+
+      for (i = 0; i < png_ptr->offset_table_count; i++)
+      {
+         if (ptr == png_ptr->offset_table_ptr[i])
+         {
+            ptr = NULL;
+            png_ptr->offset_table_count_free++;
+            break;
+         }
+      }
+      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
+      {
+         farfree(png_ptr->offset_table);
+         farfree(png_ptr->offset_table_ptr);
+         png_ptr->offset_table = NULL;
+         png_ptr->offset_table_ptr = NULL;
+      }
+   }
+
+   if (ptr != NULL)
+   {
+      farfree(ptr);
+   }
+}
+
+#else /* Not the Borland DOS special memory handler */
+
+/* Allocate memory for a png_struct or a png_info.  The malloc and
+   memset can be replaced by a single call to calloc() if this is thought
+   to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Allocate memory for a png_struct or a png_info.  The malloc and
+   memset can be replaced by a single call to calloc() if this is thought
+   to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+   png_size_t size;
+   png_voidp struct_ptr;
+
+   if (type == PNG_STRUCT_INFO)
+      size = png_sizeof(png_info);
+   else if (type == PNG_STRUCT_PNG)
+      size = png_sizeof(png_struct);
+   else
+      return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if(malloc_fn != NULL)
+   {
+      png_struct dummy_struct;
+      png_structp png_ptr = &dummy_struct;
+      png_ptr->mem_ptr=mem_ptr;
+      struct_ptr = (*(malloc_fn))(png_ptr, size);
+      if (struct_ptr != NULL)
+         png_memset(struct_ptr, 0, size);
+      return (struct_ptr);
+   }
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   struct_ptr = (png_voidp)farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   struct_ptr = (png_voidp)halloc(size,1);
+# else
+   struct_ptr = (png_voidp)malloc(size);
+# endif
+#endif
+   if (struct_ptr != NULL)
+      png_memset(struct_ptr, 0, size);
+
+   return (struct_ptr);
+}
+
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+    png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+   if (struct_ptr != NULL)
+   {
+#ifdef PNG_USER_MEM_SUPPORTED
+      if(free_fn != NULL)
+      {
+         png_struct dummy_struct;
+         png_structp png_ptr = &dummy_struct;
+         png_ptr->mem_ptr=mem_ptr;
+         (*(free_fn))(png_ptr, struct_ptr);
+         return;
+      }
+#endif /* PNG_USER_MEM_SUPPORTED */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+      farfree(struct_ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+      hfree(struct_ptr);
+# else
+      free(struct_ptr);
+# endif
+#endif
+   }
+}
+
+/* Allocate memory.  For reasonable files, size should never exceed
+   64K.  However, zlib may allocate more then 64K if you don't tell
+   it not to.  See zconf.h and png.h for more information.  zlib does
+   need to allocate exactly 64K, so whatever you call here must
+   have the ability to do that. */
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr == NULL || size == 0)
+      return (NULL);
+
+   if(png_ptr->malloc_fn != NULL)
+       ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+   else
+       ret = (png_malloc_default(png_ptr, size));
+   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+       png_error(png_ptr, "Out of Memory!");
+   return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+   if (png_ptr == NULL || size == 0)
+      return (NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (size > (png_uint_32)65536L)
+   {
+#ifndef PNG_USER_MEM_SUPPORTED
+      if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+         png_error(png_ptr, "Cannot Allocate > 64K");
+      else
+#endif
+         return NULL;
+   }
+#endif
+
+ /* Check for overflow */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ if (size != (unsigned long)size)
+   ret = NULL;
+ else
+   ret = farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ if (size != (unsigned long)size)
+   ret = NULL;
+ else
+   ret = halloc(size, 1);
+# else
+ if (size != (size_t)size)
+   ret = NULL;
+ else
+   ret = malloc((size_t)size);
+# endif
+#endif
+
+#ifndef PNG_USER_MEM_SUPPORTED
+   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+      png_error(png_ptr, "Out of Memory");
+#endif
+
+   return (ret);
+}
+
+/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
+   without taking any action. */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr->free_fn != NULL)
+   {
+      (*(png_ptr->free_fn))(png_ptr, ptr);
+      return;
+   }
+   else png_free_default(png_ptr, ptr);
+}
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   farfree(ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   hfree(ptr);
+# else
+   free(ptr);
+# endif
+#endif
+}
+
+#endif /* Not Borland DOS special memory handler */
+
+#if defined(PNG_1_0_X)
+#  define png_malloc_warn png_malloc
+#else
+/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
+ * function will set up png_malloc() to issue a png_warning and return NULL
+ * instead of issuing a png_error, if it fails to allocate the requested
+ * memory.
+ */
+png_voidp PNGAPI
+png_malloc_warn(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ptr;
+   png_uint_32 save_flags=png_ptr->flags;
+
+   png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+   ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
+   png_ptr->flags=save_flags;
+   return(ptr);
+}
+#endif
+
+png_voidp PNGAPI
+png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
+   png_uint_32 length)
+{
+   png_size_t size;
+
+   size = (png_size_t)length;
+   if ((png_uint_32)size != length)
+      png_error(png_ptr,"Overflow in png_memcpy_check.");
+
+   return(png_memcpy (s1, s2, size));
+}
+
+png_voidp PNGAPI
+png_memset_check (png_structp png_ptr, png_voidp s1, int value,
+   png_uint_32 length)
+{
+   png_size_t size;
+
+   size = (png_size_t)length;
+   if ((png_uint_32)size != length)
+      png_error(png_ptr,"Overflow in png_memset_check.");
+
+   return (png_memset (s1, value, size));
+
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+  malloc_fn, png_free_ptr free_fn)
+{
+   png_ptr->mem_ptr = mem_ptr;
+   png_ptr->malloc_fn = malloc_fn;
+   png_ptr->free_fn = free_fn;
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_structp png_ptr)
+{
+   return ((png_voidp)png_ptr->mem_ptr);
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
diff --git a/Utilities/FLTK/png/pngpread.c b/Utilities/FLTK/png/pngpread.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba45d138eeef6f341de109ae720f25d302f10534
--- /dev/null
+++ b/Utilities/FLTK/png/pngpread.c
@@ -0,0 +1,1573 @@
+
+/* pngpread.c - read a png file in push mode
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* push model modes */
+#define PNG_READ_SIG_MODE   0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE  2
+#define PNG_SKIP_MODE       3
+#define PNG_READ_tEXt_MODE  4
+#define PNG_READ_zTXt_MODE  5
+#define PNG_READ_DONE_MODE  6
+#define PNG_READ_iTXt_MODE  7
+#define PNG_ERROR_MODE      8
+
+void PNGAPI
+png_process_data(png_structp png_ptr, png_infop info_ptr,
+   png_bytep buffer, png_size_t buffer_size)
+{
+   png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+   while (png_ptr->buffer_size)
+   {
+      png_process_some_data(png_ptr, info_ptr);
+   }
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structp png_ptr, png_infop info_ptr)
+{
+   switch (png_ptr->process_mode)
+   {
+      case PNG_READ_SIG_MODE:
+      {
+         png_push_read_sig(png_ptr, info_ptr);
+         break;
+      }
+      case PNG_READ_CHUNK_MODE:
+      {
+         png_push_read_chunk(png_ptr, info_ptr);
+         break;
+      }
+      case PNG_READ_IDAT_MODE:
+      {
+         png_push_read_IDAT(png_ptr);
+         break;
+      }
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      case PNG_READ_tEXt_MODE:
+      {
+         png_push_read_tEXt(png_ptr, info_ptr);
+         break;
+      }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      case PNG_READ_zTXt_MODE:
+      {
+         png_push_read_zTXt(png_ptr, info_ptr);
+         break;
+      }
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      case PNG_READ_iTXt_MODE:
+      {
+         png_push_read_iTXt(png_ptr, info_ptr);
+         break;
+      }
+#endif
+      case PNG_SKIP_MODE:
+      {
+         png_push_crc_finish(png_ptr);
+         break;
+      }
+      default:
+      {
+         png_ptr->buffer_size = 0;
+         break;
+      }
+   }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature.  It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
+{
+   png_size_t num_checked = png_ptr->sig_bytes,
+             num_to_check = 8 - num_checked;
+
+   if (png_ptr->buffer_size < num_to_check)
+   {
+      num_to_check = png_ptr->buffer_size;
+   }
+
+   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+      num_to_check);
+   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
+
+   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+   {
+      if (num_checked < 4 &&
+          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+         png_error(png_ptr, "Not a PNG file");
+      else
+         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+   }
+   else
+   {
+      if (png_ptr->sig_bytes >= 8)
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+      }
+   }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+   /* First we make sure we have enough data for the 4 byte chunk name
+    * and the 4 byte chunk length before proceeding with decoding the
+    * chunk data.  To fully decode each of these chunks, we also make
+    * sure we have enough data in the buffer for the 4 byte CRC at the
+    * end of every chunk (except IDAT, which is handled separately).
+    */
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+   {
+      png_byte chunk_length[4];
+
+      if (png_ptr->buffer_size < 8)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+   }
+
+   if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+   }
+   else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+      png_ptr->process_mode = PNG_READ_DONE_MODE;
+      png_push_have_end(png_ptr, info_ptr);
+   }
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+         png_ptr->mode |= PNG_HAVE_IDAT;
+      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+      if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+         png_ptr->mode |= PNG_HAVE_PLTE;
+      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         if (!(png_ptr->mode & PNG_HAVE_IHDR))
+            png_error(png_ptr, "Missing IHDR before IDAT");
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                  !(png_ptr->mode & PNG_HAVE_PLTE))
+            png_error(png_ptr, "Missing PLTE before IDAT");
+      }
+   }
+#endif
+   else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+   }
+   else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+   {
+      /* If we reach an IDAT chunk, this means we have read all of the
+       * header chunks, and we can start reading the image (or if this
+       * is called after the image has been read - we have an error).
+       */
+     if (!(png_ptr->mode & PNG_HAVE_IHDR))
+       png_error(png_ptr, "Missing IHDR before IDAT");
+     else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+         !(png_ptr->mode & PNG_HAVE_PLTE))
+       png_error(png_ptr, "Missing PLTE before IDAT");
+
+      if (png_ptr->mode & PNG_HAVE_IDAT)
+      {
+         if (png_ptr->push_length == 0)
+            return;
+
+         if (png_ptr->mode & PNG_AFTER_IDAT)
+            png_error(png_ptr, "Too many IDAT's found");
+      }
+
+      png_ptr->idat_size = png_ptr->push_length;
+      png_ptr->mode |= PNG_HAVE_IDAT;
+      png_ptr->process_mode = PNG_READ_IDAT_MODE;
+      png_push_have_info(png_ptr, info_ptr);
+      png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+      png_ptr->zstream.next_out = png_ptr->row_buf;
+      return;
+   }
+#if defined(PNG_READ_gAMA_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_bKGD_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+   else
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void /* PRIVATE */
+png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
+{
+   png_ptr->process_mode = PNG_SKIP_MODE;
+   png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structp png_ptr)
+{
+   if (png_ptr->skip_length && png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
+         save_size = (png_size_t)png_ptr->skip_length;
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (png_ptr->skip_length && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
+         save_size = (png_size_t)png_ptr->skip_length;
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (!png_ptr->skip_length)
+   {
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_crc_finish(png_ptr, 0);
+      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+   }
+}
+
+void PNGAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+   png_bytep ptr;
+
+   ptr = buffer;
+   if (png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->save_buffer_size)
+         save_size = length;
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+      length -= save_size;
+      ptr += save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (length && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->current_buffer_size)
+         save_size = length;
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structp png_ptr)
+{
+   if (png_ptr->save_buffer_size)
+   {
+      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+      {
+         png_size_t i,istop;
+         png_bytep sp;
+         png_bytep dp;
+
+         istop = png_ptr->save_buffer_size;
+         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+            i < istop; i++, sp++, dp++)
+         {
+            *dp = *sp;
+         }
+      }
+   }
+   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+      png_ptr->save_buffer_max)
+   {
+      png_size_t new_max;
+      png_bytep old_buffer;
+
+      if (png_ptr->save_buffer_size > PNG_SIZE_MAX - 
+         (png_ptr->current_buffer_size + 256))
+      {
+        png_error(png_ptr, "Potential overflow of save_buffer");
+      }
+      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+      old_buffer = png_ptr->save_buffer;
+      png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
+         (png_uint_32)new_max);
+      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      png_free(png_ptr, old_buffer);
+      png_ptr->save_buffer_max = new_max;
+   }
+   if (png_ptr->current_buffer_size)
+   {
+      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+      png_ptr->current_buffer_size = 0;
+   }
+   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+   png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   png_ptr->current_buffer = buffer;
+   png_ptr->current_buffer_size = buffer_length;
+   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+#endif
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+   {
+      png_byte chunk_length[4];
+
+      if (png_ptr->buffer_size < 8)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+      if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+            png_error(png_ptr, "Not enough compressed data");
+         return;
+      }
+
+      png_ptr->idat_size = png_ptr->push_length;
+   }
+   if (png_ptr->idat_size && png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
+      {
+         save_size = (png_size_t)png_ptr->idat_size;
+         /* check for overflow */
+         if((png_uint_32)save_size != png_ptr->idat_size)
+            png_error(png_ptr, "save_size overflowed in pngpread");
+      }
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+         png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+      png_ptr->idat_size -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (png_ptr->idat_size && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
+      {
+         save_size = (png_size_t)png_ptr->idat_size;
+         /* check for overflow */
+         if((png_uint_32)save_size != png_ptr->idat_size)
+            png_error(png_ptr, "save_size overflowed in pngpread");
+      }
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+        png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->idat_size -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (!png_ptr->idat_size)
+   {
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_crc_finish(png_ptr, 0);
+      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+      png_ptr->mode |= PNG_AFTER_IDAT;
+   }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   int ret;
+
+   if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
+      png_error(png_ptr, "Extra compression data");
+
+   png_ptr->zstream.next_in = buffer;
+   png_ptr->zstream.avail_in = (uInt)buffer_length;
+   for(;;)
+   {
+      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+      if (ret != Z_OK)
+      {
+         if (ret == Z_STREAM_END)
+         {
+            if (png_ptr->zstream.avail_in)
+               png_error(png_ptr, "Extra compressed data");
+            if (!(png_ptr->zstream.avail_out))
+            {
+               png_push_process_row(png_ptr);
+            }
+
+            png_ptr->mode |= PNG_AFTER_IDAT;
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            break;
+         }
+         else if (ret == Z_BUF_ERROR)
+            break;
+         else
+            png_error(png_ptr, "Decompression Error");
+      }
+      if (!(png_ptr->zstream.avail_out))
+      {
+         if ((
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+             png_ptr->interlaced && png_ptr->pass > 6) ||
+             (!png_ptr->interlaced &&
+#endif
+             png_ptr->row_number == png_ptr->num_rows))
+         {
+           if (png_ptr->zstream.avail_in)
+             png_warning(png_ptr, "Too much data in IDAT chunks");
+           png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+           break;
+         }
+         png_push_process_row(png_ptr);
+         png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+         png_ptr->zstream.next_out = png_ptr->row_buf;
+      }
+      else
+         break;
+   }
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structp png_ptr)
+{
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->iwidth;
+   png_ptr->row_info.channels = png_ptr->channels;
+   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+
+   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+       png_ptr->row_info.width);
+
+   png_read_filter_row(png_ptr, &(png_ptr->row_info),
+      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+      (int)(png_ptr->row_buf[0]));
+
+   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+      png_ptr->rowbytes + 1);
+
+   if (png_ptr->transformations)
+      png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+   /* blow up interlaced rows to full size */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      if (png_ptr->pass < 6)
+/*       old interface (pre-1.0.9):
+         png_do_read_interlace(&(png_ptr->row_info),
+            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+         png_do_read_interlace(png_ptr);
+
+    switch (png_ptr->pass)
+    {
+         case 0:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
+            }
+            if (png_ptr->pass == 2) /* pass 1 might be empty */
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+            if (png_ptr->pass == 4 && png_ptr->height <= 4)
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+            if (png_ptr->pass == 6 && png_ptr->height <= 4)
+            {
+                png_push_have_row(png_ptr, png_bytep_NULL);
+                png_read_push_finish_row(png_ptr);
+            }
+            break;
+         }
+         case 1:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 2) /* skip top 4 generated rows */
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+            break;
+         }
+         case 2:
+         {
+            int i;
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+               png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 4) /* pass 3 might be empty */
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+            break;
+         }
+         case 3:
+         {
+            int i;
+            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 4) /* skip top two generated rows */
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+            break;
+         }
+         case 4:
+         {
+            int i;
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+               png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 6) /* pass 5 might be empty */
+            {
+               png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+            break;
+         }
+         case 5:
+         {
+            int i;
+            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 6) /* skip top generated row */
+            {
+               png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+            break;
+         }
+         case 6:
+         {
+            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+            png_read_push_finish_row(png_ptr);
+            if (png_ptr->pass != 6)
+               break;
+            png_push_have_row(png_ptr, png_bytep_NULL);
+            png_read_push_finish_row(png_ptr);
+         }
+      }
+   }
+   else
+#endif
+   {
+      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+      png_read_push_finish_row(png_ptr);
+   }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+   /* Width of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+   */
+
+   /* Height of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+   */
+#endif
+
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      png_memset_check(png_ptr, png_ptr->prev_row, 0,
+         png_ptr->rowbytes + 1);
+      do
+      {
+         png_ptr->pass++;
+         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+             (png_ptr->pass == 3 && png_ptr->width < 3) ||
+             (png_ptr->pass == 5 && png_ptr->width < 2))
+           png_ptr->pass++;
+
+         if (png_ptr->pass > 7)
+            png_ptr->pass--;
+         if (png_ptr->pass >= 7)
+            break;
+
+         png_ptr->iwidth = (png_ptr->width +
+            png_pass_inc[png_ptr->pass] - 1 -
+            png_pass_start[png_ptr->pass]) /
+            png_pass_inc[png_ptr->pass];
+
+         png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
+            png_ptr->iwidth) + 1;
+
+         if (png_ptr->transformations & PNG_INTERLACE)
+            break;
+
+         png_ptr->num_rows = (png_ptr->height +
+            png_pass_yinc[png_ptr->pass] - 1 -
+            png_pass_ystart[png_ptr->pass]) /
+            png_pass_yinc[png_ptr->pass];
+
+      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+   }
+}
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+      {
+         png_error(png_ptr, "Out of place tEXt");
+         /* to quiet some compiler warnings */
+         if(info_ptr == NULL) return;
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   png_ptr->skip_length = 0;  /* This may not be necessary */
+
+   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+   {
+      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+      png_ptr->skip_length = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+         (png_uint_32)(length+1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_tEXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+      else
+         text_size = png_ptr->current_text_left;
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp text;
+      png_charp key;
+      int ret;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+      if (png_ptr->skip_length)
+         return;
+#endif
+
+      key = png_ptr->current_text;
+
+      for (text = key; *text; text++)
+         /* empty loop */ ;
+
+      if (text != key + png_ptr->current_text_size)
+         text++;
+
+      text_ptr = (png_textp)png_malloc(png_ptr,
+         (png_uint_32)png_sizeof(png_text));
+      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+      text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+      text_ptr->lang = NULL;
+      text_ptr->lang_key = NULL;
+#endif
+      text_ptr->text = text;
+
+      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, key);
+      png_free(png_ptr, text_ptr);
+      png_ptr->current_text = NULL;
+
+      if (ret)
+        png_warning(png_ptr, "Insufficient memory to store text chunk.");
+   }
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+      {
+         png_error(png_ptr, "Out of place zTXt");
+         /* to quiet some compiler warnings */
+         if(info_ptr == NULL) return;
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We can't handle zTXt chunks > 64K, since we don't have enough space
+    * to be able to store the uncompressed data.  Actually, the threshold
+    * is probably around 32K, but it isn't as definite as 64K is.
+    */
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+      png_push_crc_skip(png_ptr, length);
+      return;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+       (png_uint_32)(length+1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_zTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+      else
+         text_size = png_ptr->current_text_left;
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp text;
+      png_charp key;
+      int ret;
+      png_size_t text_size, key_size;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+      key = png_ptr->current_text;
+
+      for (text = key; *text; text++)
+         /* empty loop */ ;
+
+      /* zTXt can't have zero text */
+      if (text == key + png_ptr->current_text_size)
+      {
+         png_ptr->current_text = NULL;
+         png_free(png_ptr, key);
+         return;
+      }
+
+      text++;
+
+      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
+      {
+         png_ptr->current_text = NULL;
+         png_free(png_ptr, key);
+         return;
+      }
+
+      text++;
+
+      png_ptr->zstream.next_in = (png_bytep )text;
+      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
+         (text - key));
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+      key_size = text - key;
+      text_size = 0;
+      text = NULL;
+      ret = Z_STREAM_END;
+
+      while (png_ptr->zstream.avail_in)
+      {
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret != Z_OK && ret != Z_STREAM_END)
+         {
+            inflateReset(&png_ptr->zstream);
+            png_ptr->zstream.avail_in = 0;
+            png_ptr->current_text = NULL;
+            png_free(png_ptr, key);
+            png_free(png_ptr, text);
+            return;
+         }
+         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
+         {
+            if (text == NULL)
+            {
+               text = (png_charp)png_malloc(png_ptr,
+                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+                     + key_size + 1));
+               png_memcpy(text + key_size, png_ptr->zbuf,
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+               png_memcpy(text, key, key_size);
+               text_size = key_size + png_ptr->zbuf_size -
+                  png_ptr->zstream.avail_out;
+               *(text + text_size) = '\0';
+            }
+            else
+            {
+               png_charp tmp;
+
+               tmp = text;
+               text = (png_charp)png_malloc(png_ptr, text_size +
+                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+                   + 1));
+               png_memcpy(text, tmp, text_size);
+               png_free(png_ptr, tmp);
+               png_memcpy(text + text_size, png_ptr->zbuf,
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               *(text + text_size) = '\0';
+            }
+            if (ret != Z_STREAM_END)
+            {
+               png_ptr->zstream.next_out = png_ptr->zbuf;
+               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            }
+         }
+         else
+         {
+            break;
+         }
+
+         if (ret == Z_STREAM_END)
+            break;
+      }
+
+      inflateReset(&png_ptr->zstream);
+      png_ptr->zstream.avail_in = 0;
+
+      if (ret != Z_STREAM_END)
+      {
+         png_ptr->current_text = NULL;
+         png_free(png_ptr, key);
+         png_free(png_ptr, text);
+         return;
+      }
+
+      png_ptr->current_text = NULL;
+      png_free(png_ptr, key);
+      key = text;
+      text += key_size;
+
+      text_ptr = (png_textp)png_malloc(png_ptr,
+          (png_uint_32)png_sizeof(png_text));
+      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
+      text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+      text_ptr->lang = NULL;
+      text_ptr->lang_key = NULL;
+#endif
+      text_ptr->text = text;
+
+      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, key);
+      png_free(png_ptr, text_ptr);
+
+      if (ret)
+        png_warning(png_ptr, "Insufficient memory to store text chunk.");
+   }
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+      {
+         png_error(png_ptr, "Out of place iTXt");
+         /* to quiet some compiler warnings */
+         if(info_ptr == NULL) return;
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   png_ptr->skip_length = 0;  /* This may not be necessary */
+
+   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+   {
+      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+      png_ptr->skip_length = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+         (png_uint_32)(length+1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_iTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
+{
+
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+      else
+         text_size = png_ptr->current_text_left;
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp key;
+      int comp_flag;
+      png_charp lang;
+      png_charp lang_key;
+      png_charp text;
+      int ret;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+      if (png_ptr->skip_length)
+         return;
+#endif
+
+      key = png_ptr->current_text;
+
+      for (lang = key; *lang; lang++)
+         /* empty loop */ ;
+
+      if (lang != key + png_ptr->current_text_size)
+         lang++;
+
+      comp_flag = *lang++;
+      lang++;     /* skip comp_type, always zero */
+
+      for (lang_key = lang; *lang_key; lang_key++)
+         /* empty loop */ ;
+      lang_key++;        /* skip NUL separator */
+
+      for (text = lang_key; *text; text++)
+         /* empty loop */ ;
+
+      if (text != key + png_ptr->current_text_size)
+         text++;
+
+      text_ptr = (png_textp)png_malloc(png_ptr,
+         (png_uint_32)png_sizeof(png_text));
+      text_ptr->compression = comp_flag + 2;
+      text_ptr->key = key;
+      text_ptr->lang = lang;
+      text_ptr->lang_key = lang_key;
+      text_ptr->text = text;
+      text_ptr->text_length = 0;
+      text_ptr->itxt_length = png_strlen(text);
+
+      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+      png_ptr->current_text = NULL;
+
+      png_free(png_ptr, text_ptr);
+      if (ret)
+        png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
+   }
+}
+#endif
+
+/* This function is called when we haven't found a handler for this
+ * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
+ * name or a critical chunk), the chunk is (currently) silently ignored.
+ */
+void /* PRIVATE */
+png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   png_uint_32 skip=0;
+   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+   if (!(png_ptr->chunk_name[0] & 0x20))
+   {
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+      if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+           PNG_HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+           && png_ptr->read_user_chunk_fn == NULL
+#endif
+         )
+#endif
+         png_chunk_error(png_ptr, "unknown critical chunk");
+
+      /* to quiet compiler warnings about unused info_ptr */
+      if (info_ptr == NULL)
+         return;
+   }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+   {
+       png_unknown_chunk chunk;
+
+#ifdef PNG_MAX_MALLOC_64K
+       if (length > (png_uint_32)65535L)
+       {
+           png_warning(png_ptr, "unknown chunk too large to fit in memory");
+           skip = length - (png_uint_32)65535L;
+           length = (png_uint_32)65535L;
+       }
+#endif
+
+       png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
+       chunk.data = (png_bytep)png_malloc(png_ptr, length);
+       png_crc_read(png_ptr, chunk.data, length);
+       chunk.size = length;
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+       if(png_ptr->read_user_chunk_fn != NULL)
+       {
+          /* callback to user unknown chunk handler */
+          if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
+          {
+             if (!(png_ptr->chunk_name[0] & 0x20))
+                if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+                     PNG_HANDLE_CHUNK_ALWAYS)
+                   png_chunk_error(png_ptr, "unknown critical chunk");
+          }
+             png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+       }
+       else
+#endif
+          png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+       png_free(png_ptr, chunk.data);
+   }
+   else
+#endif
+      skip=length;
+   png_push_crc_skip(png_ptr, skip);
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->info_fn != NULL)
+      (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->end_fn != NULL)
+      (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structp png_ptr, png_bytep row)
+{
+   if (png_ptr->row_fn != NULL)
+      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+         (int)png_ptr->pass);
+}
+
+void PNGAPI
+png_progressive_combine_row (png_structp png_ptr,
+   png_bytep old_row, png_bytep new_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   const int FARDATA png_pass_dsp_mask[7] =
+      {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+#endif
+   if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
+      png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
+}
+
+void PNGAPI
+png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
+   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+   png_progressive_end_ptr end_fn)
+{
+   png_ptr->info_fn = info_fn;
+   png_ptr->row_fn = row_fn;
+   png_ptr->end_fn = end_fn;
+
+   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_structp png_ptr)
+{
+   return png_ptr->io_ptr;
+}
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
diff --git a/Utilities/FLTK/png/pngread.c b/Utilities/FLTK/png/pngread.c
new file mode 100644
index 0000000000000000000000000000000000000000..168e28013d03da9e62b4f9be0b7902c86f941add
--- /dev/null
+++ b/Utilities/FLTK/png/pngread.c
@@ -0,0 +1,1453 @@
+
+/* pngread.c - read a PNG file
+ *
+ * libpng 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+   png_structp png_ptr;
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif
+#endif
+
+   int i;
+
+   png_debug(1, "in png_create_read_struct\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif
+   if (png_ptr == NULL)
+      return (NULL);
+
+#if !defined(PNG_1_0_X)
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
+#endif
+#endif /* PNG_1_0_X */
+
+   /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_ptr->jmpbuf))
+#endif
+   {
+      png_free(png_ptr, png_ptr->zbuf);
+      png_ptr->zbuf=NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr, 
+         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)png_ptr);
+#endif
+      return (NULL);
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif
+
+   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+   i=0;
+   do
+   {
+     if(user_png_ver[i] != png_libpng_ver[i])
+        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+   } while (png_libpng_ver[i++]);
+
+   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+   {
+     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+      * we must recompile any applications that use any older library version.
+      * For versions after libpng 1.0, we will be compatible, so we need
+      * only check the first digit.
+      */
+     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+     {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+        char msg[80];
+        if (user_png_ver)
+        {
+          sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+             user_png_ver);
+          png_warning(png_ptr, msg);
+        }
+        sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
+           png_libpng_ver);
+        png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+        png_ptr->flags=0;
+#endif
+        png_error(png_ptr,
+           "Incompatible libpng version in application and library");
+     }
+   }
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+   switch (inflateInit(&png_ptr->zstream))
+   {
+     case Z_OK: /* Do nothing */ break;
+     case Z_MEM_ERROR:
+     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
+     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
+     default: png_error(png_ptr, "Unknown zlib error");
+   }
+
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then encounter
+   a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
+   abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+      PNG_ABORT();
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#else
+   if (setjmp(png_ptr->jmpbuf))
+      PNG_ABORT();
+#endif
+#endif
+   return (png_ptr);
+}
+
+/* Initialize PNG structure for reading, and allocate any memory needed.
+   This interface is deprecated in favour of the png_create_read_struct(),
+   and it will eventually disappear. */
+#undef png_read_init
+void PNGAPI
+png_read_init(png_structp png_ptr)
+{
+   /* We only come here via pre-1.0.7-compiled applications */
+   png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size, png_size_t png_info_size)
+{
+   /* We only come here via pre-1.0.12-compiled applications */
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+   if(png_sizeof(png_struct) > png_struct_size || 
+      png_sizeof(png_info) > png_info_size)
+   {
+      char msg[80];
+      png_ptr->warning_fn=NULL;
+      if (user_png_ver)
+      {
+        sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+           user_png_ver);
+        png_warning(png_ptr, msg);
+      }
+      sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
+         png_libpng_ver);
+      png_warning(png_ptr, msg);
+   }
+#endif
+   if(png_sizeof(png_struct) > png_struct_size)
+     {
+       png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+       png_ptr->flags=0;
+#endif
+       png_error(png_ptr,
+       "The png struct allocated by the application for reading is too small.");
+     }
+   if(png_sizeof(png_info) > png_info_size)
+     {
+       png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+       png_ptr->flags=0;
+#endif
+       png_error(png_ptr,
+         "The info struct allocated by application for reading is too small.");
+     }
+   png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+
+void PNGAPI
+png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp;  /* to save current jump buffer */
+#endif
+
+   int i=0;
+
+   png_structp png_ptr=*ptr_ptr;
+
+   do
+   {
+     if(user_png_ver[i] != png_libpng_ver[i])
+     {
+#ifdef PNG_LEGACY_SUPPORTED
+       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+       png_ptr->warning_fn=NULL;
+       png_warning(png_ptr,
+        "Application uses deprecated png_read_init() and should be recompiled.");
+       break;
+#endif
+     }
+   } while (png_libpng_ver[i++]);
+
+   png_debug(1, "in png_read_init_3\n");
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* save jump buffer and error functions */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+   if(png_sizeof(png_struct) > png_struct_size)
+     {
+       png_destroy_struct(png_ptr);
+       *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+       png_ptr = *ptr_ptr;
+     }
+
+   /* reset all variables to 0 */
+   png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* restore jump buffer */
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+
+   /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+   switch (inflateInit(&png_ptr->zstream))
+   {
+     case Z_OK: /* Do nothing */ break;
+     case Z_MEM_ERROR:
+     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
+     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
+     default: png_error(png_ptr, "Unknown zlib error");
+   }
+
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+}
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data.  This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream.  You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here.  The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_info\n");
+   /* If we haven't checked all of the PNG signature bytes, do so now. */
+   if (png_ptr->sig_bytes < 8)
+   {
+      png_size_t num_checked = png_ptr->sig_bytes,
+                 num_to_check = 8 - num_checked;
+
+      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+      png_ptr->sig_bytes = 8;
+
+      if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+      {
+         if (num_checked < 4 &&
+             png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+            png_error(png_ptr, "Not a PNG file");
+         else
+            png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+      }
+      if (num_checked < 3)
+         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+   }
+
+   for(;;)
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
+      png_byte chunk_length[4];
+      png_uint_32 length;
+
+      png_read_data(png_ptr, chunk_length, 4);
+      length = png_get_uint_31(png_ptr,chunk_length);
+
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
+         length);
+
+      /* This should be a binary subdivision search or a hash for
+       * matching the chunk name rather than a linear search.
+       */
+      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+         png_handle_IHDR(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+         png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+      {
+         if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+            png_ptr->mode |= PNG_HAVE_IDAT;
+         png_handle_unknown(png_ptr, info_ptr, length);
+         if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+            png_ptr->mode |= PNG_HAVE_PLTE;
+         else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+         {
+            if (!(png_ptr->mode & PNG_HAVE_IHDR))
+               png_error(png_ptr, "Missing IHDR before IDAT");
+            else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                     !(png_ptr->mode & PNG_HAVE_PLTE))
+               png_error(png_ptr, "Missing PLTE before IDAT");
+            break;
+         }
+      }
+#endif
+      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+         png_handle_PLTE(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         if (!(png_ptr->mode & PNG_HAVE_IHDR))
+            png_error(png_ptr, "Missing IHDR before IDAT");
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                  !(png_ptr->mode & PNG_HAVE_PLTE))
+            png_error(png_ptr, "Missing PLTE before IDAT");
+
+         png_ptr->idat_size = length;
+         png_ptr->mode |= PNG_HAVE_IDAT;
+         break;
+      }
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+      else
+         png_handle_unknown(png_ptr, info_ptr, length);
+   }
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+/* optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_update_info\n");
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+   else
+      png_warning(png_ptr,
+      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
+   png_read_transform_info(png_ptr, info_ptr);
+}
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place.  This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structp png_ptr)
+{
+   png_debug(1, "in png_start_read_image\n");
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+void PNGAPI
+png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+   const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+   const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+#endif
+   int ret;
+   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
+      png_ptr->row_number, png_ptr->pass);
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+   /* check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
+#endif
+   }
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+   /* if interlaced and we do not need a new row, combine row and return */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if (png_ptr->row_number & 0x07)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 1:
+            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 2:
+            if ((png_ptr->row_number & 0x07) != 4)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 4))
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 3:
+            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 4:
+            if ((png_ptr->row_number & 3) != 2)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 2))
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 5:
+            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 6:
+            if (!(png_ptr->row_number & 1))
+            {
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+      }
+   }
+#endif
+
+   if (!(png_ptr->mode & PNG_HAVE_IDAT))
+      png_error(png_ptr, "Invalid attempt to read row data");
+
+   png_ptr->zstream.next_out = png_ptr->row_buf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+   do
+   {
+      if (!(png_ptr->zstream.avail_in))
+      {
+         while (!png_ptr->idat_size)
+         {
+            png_byte chunk_length[4];
+
+            png_crc_finish(png_ptr, 0);
+
+            png_read_data(png_ptr, chunk_length, 4);
+            png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
+
+            png_reset_crc(png_ptr);
+            png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+               png_error(png_ptr, "Not enough image data");
+         }
+         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_in = png_ptr->zbuf;
+         if (png_ptr->zbuf_size > png_ptr->idat_size)
+            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+         png_crc_read(png_ptr, png_ptr->zbuf,
+            (png_size_t)png_ptr->zstream.avail_in);
+         png_ptr->idat_size -= png_ptr->zstream.avail_in;
+      }
+      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+      if (ret == Z_STREAM_END)
+      {
+         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
+            png_ptr->idat_size)
+            png_error(png_ptr, "Extra compressed data");
+         png_ptr->mode |= PNG_AFTER_IDAT;
+         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         break;
+      }
+      if (ret != Z_OK)
+         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+                   "Decompression error");
+
+   } while (png_ptr->zstream.avail_out);
+
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->iwidth;
+   png_ptr->row_info.channels = png_ptr->channels;
+   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+       png_ptr->row_info.width);
+
+   if(png_ptr->row_buf[0])
+   png_read_filter_row(png_ptr, &(png_ptr->row_info),
+      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+      (int)(png_ptr->row_buf[0]));
+
+   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+      png_ptr->rowbytes + 1);
+   
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+   }
+#endif
+
+   if (png_ptr->transformations)
+      png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+   /* blow up interlaced rows to full size */
+   if (png_ptr->interlaced &&
+      (png_ptr->transformations & PNG_INTERLACE))
+   {
+      if (png_ptr->pass < 6)
+/*       old interface (pre-1.0.9):
+         png_do_read_interlace(&(png_ptr->row_info),
+            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+         png_do_read_interlace(png_ptr);
+
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row,
+            png_pass_dsp_mask[png_ptr->pass]);
+      if (row != NULL)
+         png_combine_row(png_ptr, row,
+            png_pass_mask[png_ptr->pass]);
+   }
+   else
+#endif
+   {
+      if (row != NULL)
+         png_combine_row(png_ptr, row, 0xff);
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row, 0xff);
+   }
+   png_read_finish_row(png_ptr);
+
+   if (png_ptr->read_row_fn != NULL)
+      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data.  If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass.  If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive.  If the image is displayed after each pass, it will
+ * appear to "sparkle" in.  "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available.  If you do not want this "chunky" display, you may pass
+ * NULL for display_row.  If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows.  In this case, you do not have to provide a display_row buffer
+ * also, but you may.  If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.7
+ */
+
+void PNGAPI
+png_read_rows(png_structp png_ptr, png_bytepp row,
+   png_bytepp display_row, png_uint_32 num_rows)
+{
+   png_uint_32 i;
+   png_bytepp rp;
+   png_bytepp dp;
+
+   png_debug(1, "in png_read_rows\n");
+   rp = row;
+   dp = display_row;
+   if (rp != NULL && dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp++;
+         png_bytep dptr = *dp++;
+
+         png_read_row(png_ptr, rptr, dptr);
+      }
+   else if(rp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp;
+         png_read_row(png_ptr, rptr, png_bytep_NULL);
+         rp++;
+      }
+   else if(dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep dptr = *dp;
+         png_read_row(png_ptr, png_bytep_NULL, dptr);
+         dp++;
+      }
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the entire image.  If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been.  You can
+ * only call this function once.  If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.7
+ */
+void PNGAPI
+png_read_image(png_structp png_ptr, png_bytepp image)
+{
+   png_uint_32 i,image_height;
+   int pass, j;
+   png_bytepp rp;
+
+   png_debug(1, "in png_read_image\n");
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   pass = png_set_interlace_handling(png_ptr);
+#else
+   if (png_ptr->interlaced)
+      png_error(png_ptr,
+        "Cannot read interlaced image -- interlace handler disabled.");
+   pass = 1;
+#endif
+
+
+   image_height=png_ptr->height;
+   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
+
+   for (j = 0; j < pass; j++)
+   {
+      rp = image;
+      for (i = 0; i < image_height; i++)
+      {
+         png_read_row(png_ptr, *rp, png_bytep_NULL);
+         rp++;
+      }
+   }
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file.  Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structp png_ptr, png_infop info_ptr)
+{
+   png_byte chunk_length[4];
+   png_uint_32 length;
+
+   png_debug(1, "in png_read_end\n");
+   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
+
+   do
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
+
+      png_read_data(png_ptr, chunk_length, 4);
+      length = png_get_uint_31(png_ptr,chunk_length);
+
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+      png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
+
+      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+         png_handle_IHDR(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+         png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+      {
+         if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+         {
+            if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
+               png_error(png_ptr, "Too many IDAT's found");
+         }
+         else
+            png_ptr->mode |= PNG_AFTER_IDAT;
+         png_handle_unknown(png_ptr, info_ptr, length);
+         if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+            png_ptr->mode |= PNG_HAVE_PLTE;
+      }
+#endif
+      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         /* Zero length IDATs are legal after the last IDAT has been
+          * read, but not after other chunks have been read.
+          */
+         if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
+            png_error(png_ptr, "Too many IDAT's found");
+         png_crc_finish(png_ptr, length);
+      }
+      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+         png_handle_PLTE(png_ptr, info_ptr, length);
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+      else
+         png_handle_unknown(png_ptr, info_ptr, length);
+   } while (!(png_ptr->mode & PNG_HAVE_IEND));
+}
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+
+/* free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+   png_infopp end_info_ptr_ptr)
+{
+   png_structp png_ptr = NULL;
+   png_infop info_ptr = NULL, end_info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn;
+   png_voidp mem_ptr;
+#endif
+
+   png_debug(1, "in png_destroy_read_struct\n");
+   if (png_ptr_ptr != NULL)
+      png_ptr = *png_ptr_ptr;
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (end_info_ptr_ptr != NULL)
+      end_info_ptr = *end_info_ptr_ptr;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+   mem_ptr = png_ptr->mem_ptr;
+#endif
+
+   png_read_destroy(png_ptr, info_ptr, end_info_ptr);
+
+   if (info_ptr != NULL)
+   {
+#if defined(PNG_TEXT_SUPPORTED)
+      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+          (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)info_ptr);
+#endif
+      *info_ptr_ptr = NULL;
+   }
+
+   if (end_info_ptr != NULL)
+   {
+#if defined(PNG_READ_TEXT_SUPPORTED)
+      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
+#endif
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
+         (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)end_info_ptr);
+#endif
+      *end_info_ptr_ptr = NULL;
+   }
+
+   if (png_ptr != NULL)
+   {
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+          (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)png_ptr);
+#endif
+      *png_ptr_ptr = NULL;
+   }
+}
+
+/* free all memory used by the read (old method) */
+void /* PRIVATE */
+png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp;
+#endif
+   png_error_ptr error_fn;
+   png_error_ptr warning_fn;
+   png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn;
+#endif
+
+   png_debug(1, "in png_read_destroy\n");
+   if (info_ptr != NULL)
+      png_info_destroy(png_ptr, info_ptr);
+
+   if (end_info_ptr != NULL)
+      png_info_destroy(png_ptr, end_info_ptr);
+
+   png_free(png_ptr, png_ptr->zbuf);
+   png_free(png_ptr, png_ptr->big_row_buf);
+   png_free(png_ptr, png_ptr->prev_row);
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   png_free(png_ptr, png_ptr->palette_lookup);
+   png_free(png_ptr, png_ptr->dither_index);
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   png_free(png_ptr, png_ptr->gamma_table);
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_free(png_ptr, png_ptr->gamma_from_1);
+   png_free(png_ptr, png_ptr->gamma_to_1);
+#endif
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_PLTE)
+      png_zfree(png_ptr, png_ptr->palette);
+   png_ptr->free_me &= ~PNG_FREE_PLTE;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
+      png_zfree(png_ptr, png_ptr->palette);
+   png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+#if defined(PNG_tRNS_SUPPORTED) || \
+    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_TRNS)
+      png_free(png_ptr, png_ptr->trans);
+   png_ptr->free_me &= ~PNG_FREE_TRNS;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
+      png_free(png_ptr, png_ptr->trans);
+   png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_HIST)
+      png_free(png_ptr, png_ptr->hist);
+   png_ptr->free_me &= ~PNG_FREE_HIST;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_HIST)
+      png_free(png_ptr, png_ptr->hist);
+   png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if (png_ptr->gamma_16_table != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_table[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_table);
+   }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if (png_ptr->gamma_16_from_1 != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_from_1);
+   }
+   if (png_ptr->gamma_16_to_1 != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_to_1);
+   }
+#endif
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+   png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+   inflateEnd(&png_ptr->zstream);
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_free(png_ptr, png_ptr->save_buffer);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+#ifdef PNG_TEXT_SUPPORTED
+   png_free(png_ptr, png_ptr->current_text);
+#endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+   /* Save the important info out of the png_struct, in case it is
+    * being used again.
+    */
+#ifdef PNG_SETJMP_SUPPORTED
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+   error_fn = png_ptr->error_fn;
+   warning_fn = png_ptr->warning_fn;
+   error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+#endif
+
+   png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+   png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
+{
+   png_ptr->read_row_fn = read_row_fn;
+}
+
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_read_png(png_structp png_ptr, png_infop info_ptr,
+                           int transforms,
+                           voidp params)
+{
+   int row;
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+   /* invert the alpha channel from opacity to transparency
+    */
+   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+       png_set_invert_alpha(png_ptr);
+#endif
+
+   /* png_read_info() gives us all of the information from the
+    * PNG file before the first IDAT (image data chunk).
+    */
+   png_read_info(png_ptr, info_ptr);
+   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
+      png_error(png_ptr,"Image is too high to process with png_read_png()");
+
+   /* -------------- image transformations start here ------------------- */
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+   /* tell libpng to strip 16 bit/color files down to 8 bits per color
+    */
+   if (transforms & PNG_TRANSFORM_STRIP_16)
+       png_set_strip_16(png_ptr);
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+   /* Strip alpha bytes from the input data without combining with
+    * the background (not recommended).
+    */
+   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+       png_set_strip_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
+   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
+    * byte into separate bytes (useful for paletted and grayscale images).
+    */
+   if (transforms & PNG_TRANSFORM_PACKING)
+       png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+   /* Change the order of packed pixels to least significant bit first
+    * (not useful if you are using png_set_packing).
+    */
+   if (transforms & PNG_TRANSFORM_PACKSWAP)
+       png_set_packswap(png_ptr);
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   /* Expand paletted colors into true RGB triplets
+    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+    * Expand paletted or RGB images with transparency to full alpha
+    * channels so the data will be available as RGBA quartets.
+    */
+   if (transforms & PNG_TRANSFORM_EXPAND)
+       if ((png_ptr->bit_depth < 8) ||
+           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+           (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+         png_set_expand(png_ptr);
+#endif
+
+   /* We don't handle background color or gamma transformation or dithering.
+    */
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+   /* invert monochrome files to have 0 as white and 1 as black
+    */
+   if (transforms & PNG_TRANSFORM_INVERT_MONO)
+       png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+   /* If you want to shift the pixel values from the range [0,255] or
+    * [0,65535] to the original [0,7] or [0,31], or whatever range the
+    * colors were originally in:
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT)
+       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+   {
+      png_color_8p sig_bit;
+
+      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+      png_set_shift(png_ptr, sig_bit);
+   }
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+   /* flip the RGB pixels to BGR (or RGBA to BGRA)
+    */
+   if (transforms & PNG_TRANSFORM_BGR)
+       png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
+    */
+   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+       png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+   /* swap bytes of 16 bit files to least significant byte first
+    */
+   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+       png_set_swap(png_ptr);
+#endif
+
+   /* We don't handle adding filler bytes */
+
+   /* Optional call to gamma correct and add the background to the palette
+    * and update info structure.  REQUIRED if you are expecting libpng to
+    * update the palette for you (i.e., you selected such a transform above).
+    */
+   png_read_update_info(png_ptr, info_ptr);
+
+   /* -------------- image transformations end here ------------------- */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+#endif
+   if(info_ptr->row_pointers == NULL)
+   {
+      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+         info_ptr->height * png_sizeof(png_bytep));
+#ifdef PNG_FREE_ME_SUPPORTED
+      info_ptr->free_me |= PNG_FREE_ROWS;
+#endif
+      for (row = 0; row < (int)info_ptr->height; row++)
+      {
+         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
+            png_get_rowbytes(png_ptr, info_ptr));
+      }
+   }
+
+   png_read_image(png_ptr, info_ptr->row_pointers);
+   info_ptr->valid |= PNG_INFO_IDAT;
+
+   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
+   png_read_end(png_ptr, info_ptr);
+
+   if(transforms == 0 || params == NULL)
+      /* quiet compiler warnings */ return;
+
+}
+#endif
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
diff --git a/Utilities/FLTK/png/pngrio.c b/Utilities/FLTK/png/pngrio.c
new file mode 100644
index 0000000000000000000000000000000000000000..d7675eb623ea127cf1891b645a88509ad7924b11
--- /dev/null
+++ b/Utilities/FLTK/png/pngrio.c
@@ -0,0 +1,161 @@
+
+/* pngrio.c - functions for data input
+ *
+ * libpng 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all input.  Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method.  Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Read the data from whatever input you are using.  The default routine
+   reads from a file pointer.  Note that this routine sometimes gets called
+   with very small lengths, so you should implement some kind of simple
+   buffering if you are using unbuffered reads.  This should never be asked
+   to read more then 64K on a 16 bit machine. */
+void /* PRIVATE */
+png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_debug1(4,"reading %d bytes\n", (int)length);
+   if (png_ptr->read_data_fn != NULL)
+      (*(png_ptr->read_data_fn))(png_ptr, data, length);
+   else
+      png_error(png_ptr, "Call to NULL read function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function that does the actual reading of data.  If you are
+   not reading from a standard C stream, you should create a replacement
+   read_data function and use it at run time with png_set_read_fn(), rather
+   than changing the library. */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_size_t check;
+
+   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+    * instead of an int, which is what fread() actually returns.
+    */
+#if defined(_WIN32_WCE)
+   if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+      check = 0;
+#else
+   check = (png_size_t)fread(data, (png_size_t)1, length,
+      (png_FILE_p)png_ptr->io_ptr);
+#endif
+
+   if (check != length)
+      png_error(png_ptr, "Read Error");
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void /* PRIVATE */
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   int check;
+   png_byte *n_data;
+   png_FILE_p io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)n_data == data)
+   {
+#if defined(_WIN32_WCE)
+      if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+         check = 0;
+#else
+      check = fread(n_data, 1, length, io_ptr);
+#endif
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t read, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         read = MIN(NEAR_BUF_SIZE, remaining);
+#if defined(_WIN32_WCE)
+         if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
+            err = 0;
+#else
+         err = fread(buf, (png_size_t)1, read, io_ptr);
+#endif
+         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+         if(err != read)
+            break;
+         else
+            check += err;
+         data += read;
+         remaining -= read;
+      }
+      while (remaining != 0);
+   }
+   if ((png_uint_32)check != (png_uint_32)length)
+      png_error(png_ptr, "read Error");
+}
+#endif
+#endif
+
+/* This function allows the application to supply a new input function
+   for libpng if standard C streams aren't being used.
+
+   This function takes as its arguments:
+   png_ptr      - pointer to a png input data structure
+   io_ptr       - pointer to user supplied structure containing info about
+                  the input functions.  May be NULL.
+   read_data_fn - pointer to a new input function that takes as its
+                  arguments a pointer to a png_struct, a pointer to
+                  a location where input data can be stored, and a 32-bit
+                  unsigned int that is the number of bytes to be read.
+                  To exit and output any fatal error messages the new write
+                  function should call png_error(png_ptr, "Error msg"). */
+void PNGAPI
+png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
+   png_rw_ptr read_data_fn)
+{
+   png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+   if (read_data_fn != NULL)
+      png_ptr->read_data_fn = read_data_fn;
+   else
+      png_ptr->read_data_fn = png_default_read_data;
+#else
+   png_ptr->read_data_fn = read_data_fn;
+#endif
+
+   /* It is an error to write to a read device */
+   if (png_ptr->write_data_fn != NULL)
+   {
+      png_ptr->write_data_fn = NULL;
+      png_warning(png_ptr,
+         "It's an error to set both read_data_fn and write_data_fn in the ");
+      png_warning(png_ptr,
+         "same structure.  Resetting write_data_fn to NULL.");
+   }
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+   png_ptr->output_flush_fn = NULL;
+#endif
+}
diff --git a/Utilities/FLTK/png/pngrtran.c b/Utilities/FLTK/png/pngrtran.c
new file mode 100644
index 0000000000000000000000000000000000000000..cc7d4ff5c58924b1041efbfbffdf3bf815c5247f
--- /dev/null
+++ b/Utilities/FLTK/png/pngrtran.c
@@ -0,0 +1,4177 @@
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * libpng version  1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file contains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
+{
+   png_debug(1, "in png_set_crc_action\n");
+   /* Tell libpng how we react to CRC errors in critical chunks */
+   switch (crit_action)
+   {
+      case PNG_CRC_NO_CHANGE:                        /* leave setting as is */
+         break;
+      case PNG_CRC_WARN_USE:                               /* warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+         break;
+      case PNG_CRC_QUIET_USE:                             /* quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+                           PNG_FLAG_CRC_CRITICAL_IGNORE;
+         break;
+      case PNG_CRC_WARN_DISCARD:    /* not a valid action for critical data */
+         png_warning(png_ptr, "Can't discard critical data on CRC error.");
+      case PNG_CRC_ERROR_QUIT:                                /* error/quit */
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         break;
+   }
+
+   switch (ancil_action)
+   {
+      case PNG_CRC_NO_CHANGE:                       /* leave setting as is */
+         break;
+      case PNG_CRC_WARN_USE:                              /* warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+         break;
+      case PNG_CRC_QUIET_USE:                            /* quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+      case PNG_CRC_ERROR_QUIT:                               /* error/quit */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+      case PNG_CRC_WARN_DISCARD:                      /* warn/discard data */
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         break;
+   }
+}
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+    defined(PNG_FLOATING_POINT_SUPPORTED)
+/* handle alpha and tRNS via a background color */
+void PNGAPI
+png_set_background(png_structp png_ptr,
+   png_color_16p background_color, int background_gamma_code,
+   int need_expand, double background_gamma)
+{
+   png_debug(1, "in png_set_background\n");
+   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+   {
+      png_warning(png_ptr, "Application must supply a known background gamma");
+      return;
+   }
+
+   png_ptr->transformations |= PNG_BACKGROUND;
+   png_memcpy(&(png_ptr->background), background_color,
+      png_sizeof(png_color_16));
+   png_ptr->background_gamma = (float)background_gamma;
+   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+   png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
+
+   /* Note:  if need_expand is set and color_type is either RGB or RGB_ALPHA
+    * (in which case need_expand is superfluous anyway), the background color
+    * might actually be gray yet not be flagged as such. This is not a problem
+    * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
+    * decide when to do the png_do_gray_to_rgb() transformation.
+    */
+   if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ||
+       (!need_expand && background_color->red == background_color->green &&
+        background_color->red == background_color->blue))
+      png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip 16 bit depth files to 8 bit depth */
+void PNGAPI
+png_set_strip_16(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_strip_16\n");
+   png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_strip_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_strip_alpha\n");
+   png_ptr->transformations |= PNG_STRIP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Dither file to 8 bit.  Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible.  If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number.  "full_dither" indicates
+ * whether we need a dithering cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+   struct png_dsort_struct FAR * next;
+   png_byte left;
+   png_byte right;
+} png_dsort;
+typedef png_dsort FAR *       png_dsortp;
+typedef png_dsort FAR * FAR * png_dsortpp;
+
+void PNGAPI
+png_set_dither(png_structp png_ptr, png_colorp palette,
+   int num_palette, int maximum_colors, png_uint_16p histogram,
+   int full_dither)
+{
+   png_debug(1, "in png_set_dither\n");
+   png_ptr->transformations |= PNG_DITHER;
+
+   if (!full_dither)
+   {
+      int i;
+
+      png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
+         (png_uint_32)(num_palette * png_sizeof (png_byte)));
+      for (i = 0; i < num_palette; i++)
+         png_ptr->dither_index[i] = (png_byte)i;
+   }
+
+   if (num_palette > maximum_colors)
+   {
+      if (histogram != NULL)
+      {
+         /* This is easy enough, just throw out the least used colors.
+            Perhaps not the best solution, but good enough. */
+
+         int i;
+
+         /* initialize an array to sort colors */
+         png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * png_sizeof (png_byte)));
+
+         /* initialize the dither_sort array */
+         for (i = 0; i < num_palette; i++)
+            png_ptr->dither_sort[i] = (png_byte)i;
+
+         /* Find the least used palette entries by starting a
+            bubble sort, and running it until we have sorted
+            out enough colors.  Note that we don't care about
+            sorting all the colors, just finding which are
+            least used. */
+
+         for (i = num_palette - 1; i >= maximum_colors; i--)
+         {
+            int done; /* to stop early if the list is pre-sorted */
+            int j;
+
+            done = 1;
+            for (j = 0; j < i; j++)
+            {
+               if (histogram[png_ptr->dither_sort[j]]
+                   < histogram[png_ptr->dither_sort[j + 1]])
+               {
+                  png_byte t;
+
+                  t = png_ptr->dither_sort[j];
+                  png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
+                  png_ptr->dither_sort[j + 1] = t;
+                  done = 0;
+               }
+            }
+            if (done)
+               break;
+         }
+
+         /* swap the palette around, and set up a table, if necessary */
+         if (full_dither)
+         {
+            int j = num_palette;
+
+            /* put all the useful colors within the max, but don't
+               move the others */
+            for (i = 0; i < maximum_colors; i++)
+            {
+               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+               {
+                  do
+                     j--;
+                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+                  palette[i] = palette[j];
+               }
+            }
+         }
+         else
+         {
+            int j = num_palette;
+
+            /* move all the used colors inside the max limit, and
+               develop a translation table */
+            for (i = 0; i < maximum_colors; i++)
+            {
+               /* only move the colors we need to */
+               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+               {
+                  png_color tmp_color;
+
+                  do
+                     j--;
+                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+
+                  tmp_color = palette[j];
+                  palette[j] = palette[i];
+                  palette[i] = tmp_color;
+                  /* indicate where the color went */
+                  png_ptr->dither_index[j] = (png_byte)i;
+                  png_ptr->dither_index[i] = (png_byte)j;
+               }
+            }
+
+            /* find closest color for those colors we are not using */
+            for (i = 0; i < num_palette; i++)
+            {
+               if ((int)png_ptr->dither_index[i] >= maximum_colors)
+               {
+                  int min_d, k, min_k, d_index;
+
+                  /* find the closest color to one we threw out */
+                  d_index = png_ptr->dither_index[i];
+                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+                  for (k = 1, min_k = 0; k < maximum_colors; k++)
+                  {
+                     int d;
+
+                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+                     if (d < min_d)
+                     {
+                        min_d = d;
+                        min_k = k;
+                     }
+                  }
+                  /* point to closest color */
+                  png_ptr->dither_index[i] = (png_byte)min_k;
+               }
+            }
+         }
+         png_free(png_ptr, png_ptr->dither_sort);
+         png_ptr->dither_sort=NULL;
+      }
+      else
+      {
+         /* This is much harder to do simply (and quickly).  Perhaps
+            we need to go through a median cut routine, but those
+            don't always behave themselves with only a few colors
+            as input.  So we will just find the closest two colors,
+            and throw out one of them (chosen somewhat randomly).
+            [We don't understand this at all, so if someone wants to
+             work on improving it, be our guest - AED, GRP]
+            */
+         int i;
+         int max_d;
+         int num_new_palette;
+         png_dsortp t;
+         png_dsortpp hash;
+
+         t=NULL;
+
+         /* initialize palette index arrays */
+         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * png_sizeof (png_byte)));
+         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * png_sizeof (png_byte)));
+
+         /* initialize the sort array */
+         for (i = 0; i < num_palette; i++)
+         {
+            png_ptr->index_to_palette[i] = (png_byte)i;
+            png_ptr->palette_to_index[i] = (png_byte)i;
+         }
+
+         hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
+            png_sizeof (png_dsortp)));
+         for (i = 0; i < 769; i++)
+            hash[i] = NULL;
+/*         png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
+
+         num_new_palette = num_palette;
+
+         /* initial wild guess at how far apart the farthest pixel
+            pair we will be eliminating will be.  Larger
+            numbers mean more areas will be allocated, Smaller
+            numbers run the risk of not saving enough data, and
+            having to do this all over again.
+
+            I have not done extensive checking on this number.
+            */
+         max_d = 96;
+
+         while (num_new_palette > maximum_colors)
+         {
+            for (i = 0; i < num_new_palette - 1; i++)
+            {
+               int j;
+
+               for (j = i + 1; j < num_new_palette; j++)
+               {
+                  int d;
+
+                  d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+                  if (d <= max_d)
+                  {
+
+                     t = (png_dsortp)png_malloc_warn(png_ptr,
+                         (png_uint_32)(png_sizeof(png_dsort)));
+                     if (t == NULL)
+                         break;
+                     t->next = hash[d];
+                     t->left = (png_byte)i;
+                     t->right = (png_byte)j;
+                     hash[d] = t;
+                  }
+               }
+               if (t == NULL)
+                  break;
+            }
+
+            if (t != NULL)
+            for (i = 0; i <= max_d; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p;
+
+                  for (p = hash[i]; p; p = p->next)
+                  {
+                     if ((int)png_ptr->index_to_palette[p->left]
+                        < num_new_palette &&
+                        (int)png_ptr->index_to_palette[p->right]
+                        < num_new_palette)
+                     {
+                        int j, next_j;
+
+                        if (num_new_palette & 0x01)
+                        {
+                           j = p->left;
+                           next_j = p->right;
+                        }
+                        else
+                        {
+                           j = p->right;
+                           next_j = p->left;
+                        }
+
+                        num_new_palette--;
+                        palette[png_ptr->index_to_palette[j]]
+                          = palette[num_new_palette];
+                        if (!full_dither)
+                        {
+                           int k;
+
+                           for (k = 0; k < num_palette; k++)
+                           {
+                              if (png_ptr->dither_index[k] ==
+                                 png_ptr->index_to_palette[j])
+                                 png_ptr->dither_index[k] =
+                                    png_ptr->index_to_palette[next_j];
+                              if ((int)png_ptr->dither_index[k] ==
+                                 num_new_palette)
+                                 png_ptr->dither_index[k] =
+                                    png_ptr->index_to_palette[j];
+                           }
+                        }
+
+                        png_ptr->index_to_palette[png_ptr->palette_to_index
+                           [num_new_palette]] = png_ptr->index_to_palette[j];
+                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+                           = png_ptr->palette_to_index[num_new_palette];
+
+                        png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
+                        png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
+                     }
+                     if (num_new_palette <= maximum_colors)
+                        break;
+                  }
+                  if (num_new_palette <= maximum_colors)
+                     break;
+               }
+            }
+
+            for (i = 0; i < 769; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p = hash[i];
+                  while (p)
+                  {
+                     t = p->next;
+                     png_free(png_ptr, p);
+                     p = t;
+                  }
+               }
+               hash[i] = 0;
+            }
+            max_d += 96;
+         }
+         png_free(png_ptr, hash);
+         png_free(png_ptr, png_ptr->palette_to_index);
+         png_free(png_ptr, png_ptr->index_to_palette);
+         png_ptr->palette_to_index=NULL;
+         png_ptr->index_to_palette=NULL;
+      }
+      num_palette = maximum_colors;
+   }
+   if (png_ptr->palette == NULL)
+   {
+      png_ptr->palette = palette;
+   }
+   png_ptr->num_palette = (png_uint_16)num_palette;
+
+   if (full_dither)
+   {
+      int i;
+      png_bytep distance;
+      int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
+         PNG_DITHER_BLUE_BITS;
+      int num_red = (1 << PNG_DITHER_RED_BITS);
+      int num_green = (1 << PNG_DITHER_GREEN_BITS);
+      int num_blue = (1 << PNG_DITHER_BLUE_BITS);
+      png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+      png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
+         (png_uint_32)(num_entries * png_sizeof (png_byte)));
+
+      png_memset(png_ptr->palette_lookup, 0, num_entries *
+         png_sizeof (png_byte));
+
+      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+         png_sizeof(png_byte)));
+
+      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
+
+      for (i = 0; i < num_palette; i++)
+      {
+         int ir, ig, ib;
+         int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
+         int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
+         int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
+
+         for (ir = 0; ir < num_red; ir++)
+         {
+            /* int dr = abs(ir - r); */
+            int dr = ((ir > r) ? ir - r : r - ir);
+            int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
+
+            for (ig = 0; ig < num_green; ig++)
+            {
+               /* int dg = abs(ig - g); */
+               int dg = ((ig > g) ? ig - g : g - ig);
+               int dt = dr + dg;
+               int dm = ((dr > dg) ? dr : dg);
+               int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
+
+               for (ib = 0; ib < num_blue; ib++)
+               {
+                  int d_index = index_g | ib;
+                  /* int db = abs(ib - b); */
+                  int db = ((ib > b) ? ib - b : b - ib);
+                  int dmax = ((dm > db) ? dm : db);
+                  int d = dmax + dt + db;
+
+                  if (d < (int)distance[d_index])
+                  {
+                     distance[d_index] = (png_byte)d;
+                     png_ptr->palette_lookup[d_index] = (png_byte)i;
+                  }
+               }
+            }
+         }
+      }
+
+      png_free(png_ptr, distance);
+   }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Transform the image from the file_gamma to the screen_gamma.  We
+ * only do transformations on images where the file_gamma and screen_gamma
+ * are not close reciprocals, otherwise it slows things down slightly, and
+ * also needlessly introduces small errors.
+ *
+ * We will turn off gamma transformation later if no semitransparent entries
+ * are present in the tRNS array for palette images.  We can't do it here
+ * because we don't necessarily have the tRNS chunk yet.
+ */
+void PNGAPI
+png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
+{
+   png_debug(1, "in png_set_gamma\n");
+   if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
+       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
+       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+     png_ptr->transformations |= PNG_GAMMA;
+   png_ptr->gamma = (float)file_gamma;
+   png_ptr->screen_gamma = (float)scrn_gamma;
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* GRR 19990627:  the following three functions currently are identical
+ *  to png_set_expand().  However, it is entirely reasonable that someone
+ *  might wish to expand an indexed image to RGB but *not* expand a single,
+ *  fully transparent palette entry to a full alpha channel--perhaps instead
+ *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ *  the transparent color with a particular RGB value, or drop tRNS entirely.
+ *  IOW, a future version of the library may make the transformations flag
+ *  a bit more fine-grained, with separate bits for each of these three
+ *  functions.
+ *
+ *  More to the point, these functions make it obvious what libpng will be
+ *  doing, whereas "expand" can (and does) mean any number of things.
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_gray_1_2_4_to_8(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+void PNGAPI
+png_set_gray_to_rgb(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_gray_to_rgb\n");
+   png_ptr->transformations |= PNG_GRAY_TO_RGB;
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Convert a RGB image to a grayscale of the same width.  This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
+   double green)
+{
+      int red_fixed = (int)((float)red*100000.0 + 0.5);
+      int green_fixed = (int)((float)green*100000.0 + 0.5);
+      png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
+}
+#endif
+
+void PNGAPI
+png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
+   png_fixed_point red, png_fixed_point green)
+{
+   png_debug(1, "in png_set_rgb_to_gray\n");
+   switch(error_action)
+   {
+      case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
+              break;
+      case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+              break;
+      case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+   }
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+      png_ptr->transformations |= PNG_EXPAND;
+#else
+   {
+      png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
+      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
+   }
+#endif
+   {
+      png_uint_16 red_int, green_int;
+      if(red < 0 || green < 0)
+      {
+         red_int   =  6968; /* .212671 * 32768 + .5 */
+         green_int = 23434; /* .715160 * 32768 + .5 */
+      }
+      else if(red + green < 100000L)
+      {
+        red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
+        green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
+      }
+      else
+      {
+         png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
+         red_int   =  6968;
+         green_int = 23434;
+      }
+      png_ptr->rgb_to_gray_red_coeff   = red_int;
+      png_ptr->rgb_to_gray_green_coeff = green_int;
+      png_ptr->rgb_to_gray_blue_coeff  = (png_uint_16)(32768-red_int-green_int);
+   }
+}
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+   read_user_transform_fn)
+{
+   png_debug(1, "in png_set_read_user_transform_fn\n");
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+#ifdef PNG_LEGACY_SUPPORTED
+   if(read_user_transform_fn)
+      png_warning(png_ptr,
+        "This version of libpng does not support user transforms");
+#endif
+}
+#endif
+
+/* Initialize everything needed for the read.  This includes modifying
+ * the palette.
+ */
+void /* PRIVATE */
+png_init_read_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_init_read_transformations\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if(png_ptr != NULL)
+#endif
+  {
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
+ || defined(PNG_READ_GAMMA_SUPPORTED)
+   int color_type = png_ptr->color_type;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+       (png_ptr->transformations & PNG_EXPAND))
+   {
+      if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
+      {
+         /* expand background chunk. */
+         switch (png_ptr->bit_depth)
+         {
+            case 1:
+               png_ptr->background.gray *= (png_uint_16)0xff;
+               png_ptr->background.red = png_ptr->background.green
+                 =  png_ptr->background.blue = png_ptr->background.gray;
+               break;
+            case 2:
+               png_ptr->background.gray *= (png_uint_16)0x55;
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+               break;
+            case 4:
+               png_ptr->background.gray *= (png_uint_16)0x11;
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+               break;
+            case 8:
+            case 16:
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+               break;
+         }
+      }
+      else if (color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_ptr->background.red   =
+            png_ptr->palette[png_ptr->background.index].red;
+         png_ptr->background.green =
+            png_ptr->palette[png_ptr->background.index].green;
+         png_ptr->background.blue  =
+            png_ptr->palette[png_ptr->background.index].blue;
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+        if (png_ptr->transformations & PNG_INVERT_ALPHA)
+        {
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+           if (!(png_ptr->transformations & PNG_EXPAND))
+#endif
+           {
+           /* invert the alpha channel (in tRNS) unless the pixels are
+              going to be expanded, in which case leave it for later */
+              int i,istop;
+              istop=(int)png_ptr->num_trans;
+              for (i=0; i<istop; i++)
+                 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
+           }
+        }
+#endif
+
+      }
+   }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+   png_ptr->background_1 = png_ptr->background;
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+
+   if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
+       && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
+         < PNG_GAMMA_THRESHOLD))
+   {
+    int i,k;
+    k=0;
+    for (i=0; i<png_ptr->num_trans; i++)
+    {
+      if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
+        k=1; /* partial transparency is present */
+    }
+    if (k == 0)
+      png_ptr->transformations &= (~PNG_GAMMA);
+   }
+
+   if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY))
+   {
+      png_build_gamma_table(png_ptr);
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+      if (png_ptr->transformations & PNG_BACKGROUND)
+      {
+         if (color_type == PNG_COLOR_TYPE_PALETTE)
+         {
+           /* could skip if no transparency and 
+           */
+            png_color back, back_1;
+            png_colorp palette = png_ptr->palette;
+            int num_palette = png_ptr->num_palette;
+            int i;
+            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+            {
+               back.red = png_ptr->gamma_table[png_ptr->background.red];
+               back.green = png_ptr->gamma_table[png_ptr->background.green];
+               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+            }
+            else
+            {
+               double g, gs;
+
+               switch (png_ptr->background_gamma_type)
+               {
+                  case PNG_BACKGROUND_GAMMA_SCREEN:
+                     g = (png_ptr->screen_gamma);
+                     gs = 1.0;
+                     break;
+                  case PNG_BACKGROUND_GAMMA_FILE:
+                     g = 1.0 / (png_ptr->gamma);
+                     gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+                     break;
+                  case PNG_BACKGROUND_GAMMA_UNIQUE:
+                     g = 1.0 / (png_ptr->background_gamma);
+                     gs = 1.0 / (png_ptr->background_gamma *
+                                 png_ptr->screen_gamma);
+                     break;
+                  default:
+                     g = 1.0;    /* back_1 */
+                     gs = 1.0;   /* back */
+               }
+
+               if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
+               {
+                  back.red   = (png_byte)png_ptr->background.red;
+                  back.green = (png_byte)png_ptr->background.green;
+                  back.blue  = (png_byte)png_ptr->background.blue;
+               }
+               else
+               {
+                  back.red = (png_byte)(pow(
+                     (double)png_ptr->background.red/255, gs) * 255.0 + .5);
+                  back.green = (png_byte)(pow(
+                     (double)png_ptr->background.green/255, gs) * 255.0 + .5);
+                  back.blue = (png_byte)(pow(
+                     (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
+               }
+
+               back_1.red = (png_byte)(pow(
+                  (double)png_ptr->background.red/255, g) * 255.0 + .5);
+               back_1.green = (png_byte)(pow(
+                  (double)png_ptr->background.green/255, g) * 255.0 + .5);
+               back_1.blue = (png_byte)(pow(
+                  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
+            }
+            for (i = 0; i < num_palette; i++)
+            {
+               if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+               {
+                  if (png_ptr->trans[i] == 0)
+                  {
+                     palette[i] = back;
+                  }
+                  else /* if (png_ptr->trans[i] != 0xff) */
+                  {
+                     png_byte v, w;
+
+                     v = png_ptr->gamma_to_1[palette[i].red];
+                     png_composite(w, v, png_ptr->trans[i], back_1.red);
+                     palette[i].red = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].green];
+                     png_composite(w, v, png_ptr->trans[i], back_1.green);
+                     palette[i].green = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].blue];
+                     png_composite(w, v, png_ptr->trans[i], back_1.blue);
+                     palette[i].blue = png_ptr->gamma_from_1[w];
+                  }
+               }
+               else
+               {
+                  palette[i].red = png_ptr->gamma_table[palette[i].red];
+                  palette[i].green = png_ptr->gamma_table[palette[i].green];
+                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+               }
+            }
+         }
+         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+         else
+         /* color_type != PNG_COLOR_TYPE_PALETTE */
+         {
+            double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
+            double g = 1.0;
+            double gs = 1.0;
+
+            switch (png_ptr->background_gamma_type)
+            {
+               case PNG_BACKGROUND_GAMMA_SCREEN:
+                  g = (png_ptr->screen_gamma);
+                  gs = 1.0;
+                  break;
+               case PNG_BACKGROUND_GAMMA_FILE:
+                  g = 1.0 / (png_ptr->gamma);
+                  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+                  break;
+               case PNG_BACKGROUND_GAMMA_UNIQUE:
+                  g = 1.0 / (png_ptr->background_gamma);
+                  gs = 1.0 / (png_ptr->background_gamma *
+                     png_ptr->screen_gamma);
+                  break;
+            }
+
+            png_ptr->background_1.gray = (png_uint_16)(pow(
+               (double)png_ptr->background.gray / m, g) * m + .5);
+            png_ptr->background.gray = (png_uint_16)(pow(
+               (double)png_ptr->background.gray / m, gs) * m + .5);
+
+            if ((png_ptr->background.red != png_ptr->background.green) ||
+                (png_ptr->background.red != png_ptr->background.blue) ||
+                (png_ptr->background.red != png_ptr->background.gray))
+            {
+               /* RGB or RGBA with color background */
+               png_ptr->background_1.red = (png_uint_16)(pow(
+                  (double)png_ptr->background.red / m, g) * m + .5);
+               png_ptr->background_1.green = (png_uint_16)(pow(
+                  (double)png_ptr->background.green / m, g) * m + .5);
+               png_ptr->background_1.blue = (png_uint_16)(pow(
+                  (double)png_ptr->background.blue / m, g) * m + .5);
+               png_ptr->background.red = (png_uint_16)(pow(
+                  (double)png_ptr->background.red / m, gs) * m + .5);
+               png_ptr->background.green = (png_uint_16)(pow(
+                  (double)png_ptr->background.green / m, gs) * m + .5);
+               png_ptr->background.blue = (png_uint_16)(pow(
+                  (double)png_ptr->background.blue / m, gs) * m + .5);
+            }
+            else
+            {
+               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+               png_ptr->background_1.red = png_ptr->background_1.green
+                 = png_ptr->background_1.blue = png_ptr->background_1.gray;
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+            }
+         }
+      }
+      else
+      /* transformation does not include PNG_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+      if (color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_colorp palette = png_ptr->palette;
+         int num_palette = png_ptr->num_palette;
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            palette[i].red = png_ptr->gamma_table[palette[i].red];
+            palette[i].green = png_ptr->gamma_table[palette[i].green];
+            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+         }
+      }
+   }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   else
+#endif
+#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* No GAMMA transformation */
+   if ((png_ptr->transformations & PNG_BACKGROUND) &&
+       (color_type == PNG_COLOR_TYPE_PALETTE))
+   {
+      int i;
+      int istop = (int)png_ptr->num_trans;
+      png_color back;
+      png_colorp palette = png_ptr->palette;
+
+      back.red   = (png_byte)png_ptr->background.red;
+      back.green = (png_byte)png_ptr->background.green;
+      back.blue  = (png_byte)png_ptr->background.blue;
+
+      for (i = 0; i < istop; i++)
+      {
+         if (png_ptr->trans[i] == 0)
+         {
+            palette[i] = back;
+         }
+         else if (png_ptr->trans[i] != 0xff)
+         {
+            /* The png_composite() macro is defined in png.h */
+            png_composite(palette[i].red, palette[i].red,
+               png_ptr->trans[i], back.red);
+            png_composite(palette[i].green, palette[i].green,
+               png_ptr->trans[i], back.green);
+            png_composite(palette[i].blue, palette[i].blue,
+               png_ptr->trans[i], back.blue);
+         }
+      }
+   }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+   if ((png_ptr->transformations & PNG_SHIFT) &&
+      (color_type == PNG_COLOR_TYPE_PALETTE))
+   {
+      png_uint_16 i;
+      png_uint_16 istop = png_ptr->num_palette;
+      int sr = 8 - png_ptr->sig_bit.red;
+      int sg = 8 - png_ptr->sig_bit.green;
+      int sb = 8 - png_ptr->sig_bit.blue;
+
+      if (sr < 0 || sr > 8)
+         sr = 0;
+      if (sg < 0 || sg > 8)
+         sg = 0;
+      if (sb < 0 || sb > 8)
+         sb = 0;
+      for (i = 0; i < istop; i++)
+      {
+         png_ptr->palette[i].red >>= sr;
+         png_ptr->palette[i].green >>= sg;
+         png_ptr->palette[i].blue >>= sb;
+      }
+   }
+#endif  /* PNG_READ_SHIFT_SUPPORTED */
+ }
+#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
+ && !defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if(png_ptr)
+      return;
+#endif
+}
+
+/* Modify the info structure to reflect the transformations.  The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_transform_info\n");
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (png_ptr->num_trans)
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+         else
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+         info_ptr->bit_depth = 8;
+         info_ptr->num_trans = 0;
+      }
+      else
+      {
+         if (png_ptr->num_trans)
+            info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+         if (info_ptr->bit_depth < 8)
+            info_ptr->bit_depth = 8;
+         info_ptr->num_trans = 0;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if (png_ptr->transformations & PNG_BACKGROUND)
+   {
+      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+      info_ptr->num_trans = 0;
+      info_ptr->background = png_ptr->background;
+   }
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if (png_ptr->transformations & PNG_GAMMA)
+   {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+      info_ptr->gamma = png_ptr->gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      info_ptr->int_gamma = png_ptr->int_gamma;
+#endif
+   }
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+   if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
+      info_ptr->bit_depth = 8;
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   if (png_ptr->transformations & PNG_DITHER)
+   {
+      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+         (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+         png_ptr->palette_lookup && info_ptr->bit_depth == 8)
+      {
+         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
+      info_ptr->bit_depth = 8;
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+      info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+      info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
+#endif
+
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      info_ptr->channels = 3;
+   else
+      info_ptr->channels = 1;
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_STRIP_ALPHA)
+      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+#endif
+
+   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+      info_ptr->channels++;
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
+   if ((png_ptr->transformations & PNG_FILLER) &&
+       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
+   {
+      info_ptr->channels++;
+      /* if adding a true alpha channel not just filler */
+#if !defined(PNG_1_0_X)
+      if (png_ptr->transformations & PNG_ADD_ALPHA)
+        info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+#endif
+   }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   if(png_ptr->transformations & PNG_USER_TRANSFORM)
+     {
+       if(info_ptr->bit_depth < png_ptr->user_transform_depth)
+         info_ptr->bit_depth = png_ptr->user_transform_depth;
+       if(info_ptr->channels < png_ptr->user_transform_channels)
+         info_ptr->channels = png_ptr->user_transform_channels;
+     }
+#endif
+
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+      info_ptr->bit_depth);
+
+   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
+
+#if !defined(PNG_READ_EXPAND_SUPPORTED)
+   if(png_ptr)
+      return;
+#endif
+}
+
+/* Transform the row.  The order of transformations is significant,
+ * and is very touchy.  If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_do_read_transformations\n");
+#if !defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (png_ptr->row_buf == NULL)
+   {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+      char msg[50];
+
+      sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
+         png_ptr->pass);
+      png_error(png_ptr, msg);
+#else
+      png_error(png_ptr, "NULL row buffer");
+#endif
+   }
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
+            png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
+      }
+      else
+      {
+         if (png_ptr->num_trans)
+            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+               &(png_ptr->trans_values));
+         else
+            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+               NULL);
+      }
+   }
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_STRIP_ALPHA)
+      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         PNG_FLAG_FILLER_AFTER);
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+   {
+      int rgb_error =
+         png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
+      if(rgb_error)
+      {
+         png_ptr->rgb_to_gray_status=1;
+         if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN)
+            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+         if(png_ptr->transformations == PNG_RGB_TO_GRAY_ERR)
+            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+      }
+   }
+#endif
+
+/*
+From Andreas Dilger e-mail to png-implement, 26 March 1998:
+
+  In most cases, the "simple transparency" should be done prior to doing
+  gray-to-RGB, or you will have to test 3x as many bytes to check if a
+  pixel is transparent.  You would also need to make sure that the
+  transparency information is upgraded to RGB.
+
+  To summarize, the current flow is:
+  - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+                                  with background "in place" if transparent,
+                                  convert to RGB if necessary
+  - Gray + alpha -> composite with gray background and remove alpha bytes,
+                                  convert to RGB if necessary
+
+  To support RGB backgrounds for gray images we need:
+  - Gray + simple transparency -> convert to RGB + simple transparency, compare
+                                  3 or 6 bytes and composite with background
+                                  "in place" if transparent (3x compare/pixel
+                                  compared to doing composite with gray bkgrnd)
+  - Gray + alpha -> convert to RGB + alpha, composite with background and
+                                  remove alpha bytes (3x float operations/pixel
+                                  compared with composite on gray background)
+
+  Greg's change will do this.  The reason it wasn't done before is for
+  performance, as this increases the per-pixel operations.  If we would check
+  in advance if the background was gray or RGB, and position the gray-to-RGB
+  transform appropriately, then it would save a lot of work/time.
+ */
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+   /* if gray -> RGB, do so now only if background is non-gray; else do later
+    * for performance reasons */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if ((png_ptr->transformations & PNG_BACKGROUND) &&
+      ((png_ptr->num_trans != 0 ) ||
+      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
+      png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->trans_values), &(png_ptr->background)
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+         , &(png_ptr->background_1),
+         png_ptr->gamma_table, png_ptr->gamma_from_1,
+         png_ptr->gamma_to_1, png_ptr->gamma_16_table,
+         png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
+         png_ptr->gamma_shift
+#endif
+);
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if ((png_ptr->transformations & PNG_GAMMA) &&
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+      !((png_ptr->transformations & PNG_BACKGROUND) &&
+      ((png_ptr->num_trans != 0) ||
+      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+      (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+      png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->gamma_table, png_ptr->gamma_16_table,
+         png_ptr->gamma_shift);
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+   if (png_ptr->transformations & PNG_16_TO_8)
+      png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   if (png_ptr->transformations & PNG_DITHER)
+   {
+      png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->palette_lookup, png_ptr->dither_index);
+      if(png_ptr->row_info.rowbytes == (png_uint_32)0)
+         png_error(png_ptr, "png_do_dither returned rowbytes=0");
+   }
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->shift));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+   /* if gray -> RGB, do so now only if we did not do so above */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+    {
+      if(png_ptr->read_user_transform_fn != NULL)
+        (*(png_ptr->read_user_transform_fn)) /* user read transform function */
+          (png_ptr,                    /* png_ptr */
+           &(png_ptr->row_info),       /* row_info:     */
+             /*  png_uint_32 width;          width of row */
+             /*  png_uint_32 rowbytes;       number of bytes in row */
+             /*  png_byte color_type;        color type of pixels */
+             /*  png_byte bit_depth;         bit depth of samples */
+             /*  png_byte channels;          number of channels (1-4) */
+             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
+           png_ptr->row_buf + 1);      /* start of pixel data for row */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+      if(png_ptr->user_transform_depth)
+         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
+      if(png_ptr->user_transform_channels)
+         png_ptr->row_info.channels = png_ptr->user_transform_channels;
+#endif
+      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+         png_ptr->row_info.channels);
+      png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+         png_ptr->row_info.width);
+   }
+#endif
+
+}
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values.  Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+void /* PRIVATE */
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_unpack\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
+#else
+   if (row_info->bit_depth < 8)
+#endif
+   {
+      png_uint_32 i;
+      png_uint_32 row_width=row_info->width;
+
+      switch (row_info->bit_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x01);
+               if (shift == 7)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift++;
+
+               dp--;
+            }
+            break;
+         }
+         case 2:
+         {
+
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x03);
+               if (shift == 6)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift += 2;
+
+               dp--;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x0f);
+               if (shift == 4)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift = 4;
+
+               dp--;
+            }
+            break;
+         }
+      }
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_width * row_info->channels;
+   }
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+/* Reverse the effects of png_do_shift.  This routine merely shifts the
+ * pixels back to their significant bits values.  Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+void /* PRIVATE */
+png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
+{
+   png_debug(1, "in png_do_unshift\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL && sig_bits != NULL &&
+#endif
+       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift[4];
+      int channels = 0;
+      int c;
+      png_uint_16 value = 0;
+      png_uint_32 row_width = row_info->width;
+
+      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->red;
+         shift[channels++] = row_info->bit_depth - sig_bits->green;
+         shift[channels++] = row_info->bit_depth - sig_bits->blue;
+      }
+      else
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->gray;
+      }
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
+      }
+
+      for (c = 0; c < channels; c++)
+      {
+         if (shift[c] <= 0)
+            shift[c] = 0;
+         else
+            value = 1;
+      }
+
+      if (!value)
+         return;
+
+      switch (row_info->bit_depth)
+      {
+         case 2:
+         {
+            png_bytep bp;
+            png_uint_32 i;
+            png_uint_32 istop = row_info->rowbytes;
+
+            for (bp = row, i = 0; i < istop; i++)
+            {
+               *bp >>= 1;
+               *bp++ &= 0x55;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep bp = row;
+            png_uint_32 i;
+            png_uint_32 istop = row_info->rowbytes;
+            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
+               (png_byte)((int)0xf >> shift[0]));
+
+            for (i = 0; i < istop; i++)
+            {
+               *bp >>= shift[0];
+               *bp++ &= mask;
+            }
+            break;
+         }
+         case 8:
+         {
+            png_bytep bp = row;
+            png_uint_32 i;
+            png_uint_32 istop = row_width * channels;
+
+            for (i = 0; i < istop; i++)
+            {
+               *bp++ >>= shift[i%channels];
+            }
+            break;
+         }
+         case 16:
+         {
+            png_bytep bp = row;
+            png_uint_32 i;
+            png_uint_32 istop = channels * row_width;
+
+            for (i = 0; i < istop; i++)
+            {
+               value = (png_uint_16)((*bp << 8) + *(bp + 1));
+               value >>= shift[i%channels];
+               *bp++ = (png_byte)(value >> 8);
+               *bp++ = (png_byte)(value & 0xff);
+            }
+            break;
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* chop rows of bit depth 16 down to 8 */
+void /* PRIVATE */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_chop\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
+#else
+   if (row_info->bit_depth == 16)
+#endif
+   {
+      png_bytep sp = row;
+      png_bytep dp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->width * row_info->channels;
+
+      for (i = 0; i<istop; i++, sp += 2, dp++)
+      {
+#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
+      /* This does a more accurate scaling of the 16-bit color
+       * value, rather than a simple low-byte truncation.
+       *
+       * What the ideal calculation should be:
+       *   *dp = (((((png_uint_32)(*sp) << 8) |
+       *          (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
+       *
+       * GRR: no, I think this is what it really should be:
+       *   *dp = (((((png_uint_32)(*sp) << 8) |
+       *           (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
+       *
+       * GRR: here's the exact calculation with shifts:
+       *   temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
+       *   *dp = (temp - (temp >> 8)) >> 8;
+       *
+       * Approximate calculation with shift/add instead of multiply/divide:
+       *   *dp = ((((png_uint_32)(*sp) << 8) |
+       *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
+       *
+       * What we actually do to avoid extra shifting and conversion:
+       */
+
+         *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
+#else
+       /* Simply discard the low order byte */
+         *dp = *sp;
+#endif
+      }
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_info->width * row_info->channels;
+   }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This converts from RGBA to ARGB */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+         /* This converts from RRGGBBAA to AARRGGBB */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This converts from GA to AG */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+         /* This converts from GGAA to AAGG */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This inverts the alpha channel in RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+
+/*             This does nothing:
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               We can replace it with:
+*/
+               sp-=3;
+               dp=sp;
+            }
+         }
+         /* This inverts the alpha channel in RRGGBBAA */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = (png_byte)(255 - *(--sp));
+
+/*             This does nothing:
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               We can replace it with:
+*/
+               sp-=6;
+               dp=sp;
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This inverts the alpha channel in GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = *(--sp);
+            }
+         }
+         /* This inverts the alpha channel in GGAA */
+         else
+         {
+            png_bytep sp  = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = (png_byte)(255 - *(--sp));
+/*
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+*/
+               sp-=2;
+               dp=sp;
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+/* Add filler channel if we have RGB color */
+void /* PRIVATE */
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+   png_uint_32 filler, png_uint_32 flags)
+{
+   png_uint_32 i;
+   png_uint_32 row_width = row_info->width;
+
+   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+   png_byte lo_filler = (png_byte)(filler & 0xff);
+
+   png_debug(1, "in png_do_read_filler\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL  && row_info != NULL &&
+#endif
+       row_info->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      if(row_info->bit_depth == 8)
+      {
+         /* This changes the data from G to GX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width;
+            png_bytep dp =  sp + (png_size_t)row_width;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = lo_filler;
+            row_info->channels = 2;
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+      /* This changes the data from G to XG */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width;
+            png_bytep dp = sp  + (png_size_t)row_width;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 2;
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+      }
+      else if(row_info->bit_depth == 16)
+      {
+         /* This changes the data from GG to GGXX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = hi_filler;
+            *(--dp) = lo_filler;
+            row_info->channels = 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+         /* This changes the data from GG to XXGG */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      }
+   } /* COLOR_TYPE == GRAY */
+   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      if(row_info->bit_depth == 8)
+      {
+         /* This changes the data from RGB to RGBX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 3;
+            png_bytep dp = sp  + (png_size_t)row_width;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = lo_filler;
+            row_info->channels = 4;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      /* This changes the data from RGB to XRGB */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 3;
+            png_bytep dp = sp + (png_size_t)row_width;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 4;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      }
+      else if(row_info->bit_depth == 16)
+      {
+         /* This changes the data from RRGGBB to RRGGBBXX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 6;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = hi_filler;
+            *(--dp) = lo_filler;
+            row_info->channels = 4;
+            row_info->pixel_depth = 64;
+            row_info->rowbytes = row_width * 8;
+         }
+         /* This changes the data from RRGGBB to XXRRGGBB */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 6;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 4;
+            row_info->pixel_depth = 64;
+            row_info->rowbytes = row_width * 8;
+         }
+      }
+   } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* expand grayscale files to RGB, with or without alpha */
+void /* PRIVATE */
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+   png_uint_32 i;
+   png_uint_32 row_width = row_info->width;
+
+   png_debug(1, "in png_do_gray_to_rgb\n");
+   if (row_info->bit_depth >= 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+      !(row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + (png_size_t)row_width - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *(sp--);
+            }
+         }
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *(sp--);
+            }
+         }
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+            }
+         }
+      }
+      row_info->channels += (png_byte)2;
+      row_info->color_type |= PNG_COLOR_MASK_COLOR;
+      row_info->pixel_depth = (png_byte)(row_info->channels *
+         row_info->bit_depth);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+   }
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ at
+ * <http://www.inforamp.net/~poynton/>
+ * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
+ *
+ *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ *  We approximate this with
+ *
+ *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
+ *
+ *  which can be expressed with integers as
+ *
+ *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ *  The calculation is to be done in a linear colorspace.
+ *
+ *  Other integer coefficents can be used via png_set_rgb_to_gray().
+ */
+int /* PRIVATE */
+png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+   png_uint_32 i;
+
+   png_uint_32 row_width = row_info->width;
+   int rgb_error = 0;
+
+   png_debug(1, "in png_do_rgb_to_gray\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+      (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+      png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
+
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (row_info->bit_depth == 8)
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
+                  if(red != green || red != blue)
+                  {
+                     rgb_error |= 1;
+                     *(dp++) = png_ptr->gamma_from_1[
+                       (rc*red+gc*green+bc*blue)>>15];
+                  }
+                  else
+                     *(dp++) = *(sp-1);
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = *(sp++);
+                  png_byte green = *(sp++);
+                  png_byte blue  = *(sp++);
+                  if(red != green || red != blue)
+                  {
+                     rgb_error |= 1;
+                     *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
+                  }
+                  else
+                     *(dp++) = *(sp-1);
+               }
+            }
+         }
+
+         else /* RGB bit_depth == 16 */
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_16_to_1 != NULL &&
+                png_ptr->gamma_16_from_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, w;
+
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+                  if(red == green && red == blue)
+                     w = red;
+                  else
+                  {
+                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
+                                  png_ptr->gamma_shift][red>>8];
+                     png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
+                                  png_ptr->gamma_shift][green>>8];
+                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
+                                  png_ptr->gamma_shift][blue>>8];
+                     png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
+                                  + bc*blue_1)>>15);
+                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+                         png_ptr->gamma_shift][gray16 >> 8];
+                     rgb_error |= 1;
+                  }
+
+                  *(dp++) = (png_byte)((w>>8) & 0xff);
+                  *(dp++) = (png_byte)(w & 0xff);
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, gray16;
+
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+                  if(red != green || red != blue)
+                     rgb_error |= 1;
+                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
+                  *(dp++) = (png_byte)(gray16 & 0xff);
+               }
+            }
+         }
+      }
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
+                  if(red != green || red != blue)
+                     rgb_error |= 1;
+                  *(dp++) =  png_ptr->gamma_from_1
+                             [(rc*red + gc*green + bc*blue)>>15];
+                  *(dp++) = *(sp++);  /* alpha */
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = *(sp++);
+                  png_byte green = *(sp++);
+                  png_byte blue  = *(sp++);
+                  if(red != green || red != blue)
+                     rgb_error |= 1;
+                  *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = *(sp++);  /* alpha */
+               }
+            }
+         }
+         else /* RGBA bit_depth == 16 */
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_16_to_1 != NULL &&
+                png_ptr->gamma_16_from_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, w;
+
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+                  if(red == green && red == blue)
+                     w = red;
+                  else
+                  {
+                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
+                                  png_ptr->gamma_shift][red>>8];
+                     png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
+                                  png_ptr->gamma_shift][green>>8];
+                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
+                                  png_ptr->gamma_shift][blue>>8];
+                     png_uint_16 gray16  = (png_uint_16)((rc * red_1
+                                  + gc * green_1 + bc * blue_1)>>15);
+                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+                         png_ptr->gamma_shift][gray16 >> 8];
+                     rgb_error |= 1;
+                  }
+
+                  *(dp++) = (png_byte)((w>>8) & 0xff);
+                  *(dp++) = (png_byte)(w & 0xff);
+                  *(dp++) = *(sp++);  /* alpha */
+                  *(dp++) = *(sp++);
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, gray16;
+                  red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  if(red != green || red != blue)
+                     rgb_error |= 1;
+                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
+                  *(dp++) = (png_byte)(gray16 & 0xff);
+                  *(dp++) = *(sp++);  /* alpha */
+                  *(dp++) = *(sp++);
+               }
+            }
+         }
+      }
+   row_info->channels -= (png_byte)2;
+      row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
+      row_info->pixel_depth = (png_byte)(row_info->channels *
+         row_info->bit_depth);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+   }
+   return rgb_error;
+}
+#endif
+
+/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
+ * large of png_color.  This lets grayscale images be treated as
+ * paletted.  Most useful for gamma correction and simplification
+ * of code.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+   int num_palette;
+   int color_inc;
+   int i;
+   int v;
+
+   png_debug(1, "in png_do_build_grayscale_palette\n");
+   if (palette == NULL)
+      return;
+
+   switch (bit_depth)
+   {
+      case 1:
+         num_palette = 2;
+         color_inc = 0xff;
+         break;
+      case 2:
+         num_palette = 4;
+         color_inc = 0x55;
+         break;
+      case 4:
+         num_palette = 16;
+         color_inc = 0x11;
+         break;
+      case 8:
+         num_palette = 256;
+         color_inc = 1;
+         break;
+      default:
+         num_palette = 0;
+         color_inc = 0;
+         break;
+   }
+
+   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+   {
+      palette[i].red = (png_byte)v;
+      palette[i].green = (png_byte)v;
+      palette[i].blue = (png_byte)v;
+   }
+}
+
+/* This function is currently unused.  Do we really need it? */
+#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
+void /* PRIVATE */
+png_correct_palette(png_structp png_ptr, png_colorp palette,
+   int num_palette)
+{
+   png_debug(1, "in png_correct_palette\n");
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+    defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+   if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
+   {
+      png_color back, back_1;
+
+      if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+      {
+         back.red = png_ptr->gamma_table[png_ptr->background.red];
+         back.green = png_ptr->gamma_table[png_ptr->background.green];
+         back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+         back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+         back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+         back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+      }
+      else
+      {
+         double g;
+
+         g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
+
+         if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
+             fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
+         {
+            back.red = png_ptr->background.red;
+            back.green = png_ptr->background.green;
+            back.blue = png_ptr->background.blue;
+         }
+         else
+         {
+            back.red =
+               (png_byte)(pow((double)png_ptr->background.red/255, g) *
+                255.0 + 0.5);
+            back.green =
+               (png_byte)(pow((double)png_ptr->background.green/255, g) *
+                255.0 + 0.5);
+            back.blue =
+               (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+                255.0 + 0.5);
+         }
+
+         g = 1.0 / png_ptr->background_gamma;
+
+         back_1.red =
+            (png_byte)(pow((double)png_ptr->background.red/255, g) *
+             255.0 + 0.5);
+         back_1.green =
+            (png_byte)(pow((double)png_ptr->background.green/255, g) *
+             255.0 + 0.5);
+         back_1.blue =
+            (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+             255.0 + 0.5);
+      }
+
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_uint_32 i;
+
+         for (i = 0; i < (png_uint_32)num_palette; i++)
+         {
+            if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
+            {
+               palette[i] = back;
+            }
+            else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+            {
+               png_byte v, w;
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
+               png_composite(w, v, png_ptr->trans[i], back_1.red);
+               palette[i].red = png_ptr->gamma_from_1[w];
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
+               png_composite(w, v, png_ptr->trans[i], back_1.green);
+               palette[i].green = png_ptr->gamma_from_1[w];
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
+               png_composite(w, v, png_ptr->trans[i], back_1.blue);
+               palette[i].blue = png_ptr->gamma_from_1[w];
+            }
+            else
+            {
+               palette[i].red = png_ptr->gamma_table[palette[i].red];
+               palette[i].green = png_ptr->gamma_table[palette[i].green];
+               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+            }
+         }
+      }
+      else
+      {
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
+            {
+               palette[i] = back;
+            }
+            else
+            {
+               palette[i].red = png_ptr->gamma_table[palette[i].red];
+               palette[i].green = png_ptr->gamma_table[palette[i].green];
+               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+            }
+         }
+      }
+   }
+   else
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if (png_ptr->transformations & PNG_GAMMA)
+   {
+      int i;
+
+      for (i = 0; i < num_palette; i++)
+      {
+         palette[i].red = png_ptr->gamma_table[palette[i].red];
+         palette[i].green = png_ptr->gamma_table[palette[i].green];
+         palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+      }
+   }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   else
+#endif
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if (png_ptr->transformations & PNG_BACKGROUND)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_color back;
+
+         back.red   = (png_byte)png_ptr->background.red;
+         back.green = (png_byte)png_ptr->background.green;
+         back.blue  = (png_byte)png_ptr->background.blue;
+
+         for (i = 0; i < (int)png_ptr->num_trans; i++)
+         {
+            if (png_ptr->trans[i] == 0)
+            {
+               palette[i].red = back.red;
+               palette[i].green = back.green;
+               palette[i].blue = back.blue;
+            }
+            else if (png_ptr->trans[i] != 0xff)
+            {
+               png_composite(palette[i].red, png_ptr->palette[i].red,
+                  png_ptr->trans[i], back.red);
+               png_composite(palette[i].green, png_ptr->palette[i].green,
+                  png_ptr->trans[i], back.green);
+               png_composite(palette[i].blue, png_ptr->palette[i].blue,
+                  png_ptr->trans[i], back.blue);
+            }
+         }
+      }
+      else /* assume grayscale palette (what else could it be?) */
+      {
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            if (i == (png_byte)png_ptr->trans_values.gray)
+            {
+               palette[i].red = (png_byte)png_ptr->background.red;
+               palette[i].green = (png_byte)png_ptr->background.green;
+               palette[i].blue = (png_byte)png_ptr->background.blue;
+            }
+         }
+      }
+   }
+#endif
+}
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0.  Paletted files have already been taken care of.
+ */
+void /* PRIVATE */
+png_do_background(png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   , png_color_16p background_1,
+   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+   png_uint_16pp gamma_16_to_1, int gamma_shift
+#endif
+   )
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+   int shift;
+
+   png_debug(1, "in png_do_background\n");
+   if (background != NULL &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+      (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
+      (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  sp = row;
+                  shift = 7;
+                  for (i = 0; i < row_width; i++)
+                  {
+                     if ((png_uint_16)((*sp >> shift) & 0x01)
+                        == trans_values->gray)
+                     {
+                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+                        *sp |= (png_byte)(background->gray << shift);
+                     }
+                     if (!shift)
+                     {
+                        shift = 7;
+                        sp++;
+                     }
+                     else
+                        shift--;
+                  }
+                  break;
+               }
+               case 2:
+               {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     shift = 6;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        else
+                        {
+                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
+                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
+                               (p << 4) | (p << 6)] >> 6) & 0x03);
+                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                           *sp |= (png_byte)(g << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 6;
+                           sp++;
+                        }
+                        else
+                           shift -= 2;
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     shift = 6;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 6;
+                           sp++;
+                        }
+                        else
+                           shift -= 2;
+                     }
+                  }
+                  break;
+               }
+               case 4:
+               {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     shift = 4;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        else
+                        {
+                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
+                           png_byte g = (png_byte)((gamma_table[p |
+                             (p << 4)] >> 4) & 0x0f);
+                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                           *sp |= (png_byte)(g << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 4;
+                           sp++;
+                        }
+                        else
+                           shift -= 4;
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     shift = 4;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 4;
+                           sp++;
+                        }
+                        else
+                           shift -= 4;
+                     }
+                  }
+                  break;
+               }
+               case 8:
+               {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp++)
+                     {
+                        if (*sp == trans_values->gray)
+                        {
+                           *sp = (png_byte)background->gray;
+                        }
+                        else
+                        {
+                           *sp = gamma_table[*sp];
+                        }
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp++)
+                     {
+                        if (*sp == trans_values->gray)
+                        {
+                           *sp = (png_byte)background->gray;
+                        }
+                     }
+                  }
+                  break;
+               }
+               case 16:
+               {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                  if (gamma_16 != NULL)
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        if (v == trans_values->gray)
+                        {
+                           /* background is already in screen gamma */
+                           *sp = (png_byte)((background->gray >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(background->gray & 0xff);
+                        }
+                        else
+                        {
+                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                           *sp = (png_byte)((v >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(v & 0xff);
+                        }
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        if (v == trans_values->gray)
+                        {
+                           *sp = (png_byte)((background->gray >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(background->gray & 0xff);
+                        }
+                     }
+                  }
+                  break;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_table != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 3)
+                  {
+                     if (*sp == trans_values->red &&
+                        *(sp + 1) == trans_values->green &&
+                        *(sp + 2) == trans_values->blue)
+                     {
+                        *sp = (png_byte)background->red;
+                        *(sp + 1) = (png_byte)background->green;
+                        *(sp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        *sp = gamma_table[*sp];
+                        *(sp + 1) = gamma_table[*(sp + 1)];
+                        *(sp + 2) = gamma_table[*(sp + 2)];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 3)
+                  {
+                     if (*sp == trans_values->red &&
+                        *(sp + 1) == trans_values->green &&
+                        *(sp + 2) == trans_values->blue)
+                     {
+                        *sp = (png_byte)background->red;
+                        *(sp + 1) = (png_byte)background->green;
+                        *(sp + 2) = (png_byte)background->blue;
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_16 != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 6)
+                  {
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+                     if (r == trans_values->red && g == trans_values->green &&
+                        b == trans_values->blue)
+                     {
+                        /* background is already in screen gamma */
+                        *sp = (png_byte)((background->red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(background->red & 0xff);
+                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(background->green & 0xff);
+                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 6)
+                  {
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
+                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+
+                     if (r == trans_values->red && g == trans_values->green &&
+                        b == trans_values->blue)
+                     {
+                        *sp = (png_byte)((background->red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(background->red & 0xff);
+                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(background->green & 0xff);
+                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 2, dp++)
+                  {
+                     png_uint_16 a = *(sp + 1);
+
+                     if (a == 0xff)
+                     {
+                        *dp = gamma_table[*sp];
+                     }
+                     else if (a == 0)
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)background->gray;
+                     }
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, background_1->gray);
+                        *dp = gamma_from_1[w];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 2, dp++)
+                  {
+                     png_byte a = *(sp + 1);
+
+                     if (a == 0xff)
+                     {
+                        *dp = *sp;
+                     }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)background->gray;
+                     }
+                     else
+                     {
+                        png_composite(*dp, *sp, a, background_1->gray);
+                     }
+#else
+                     *dp = (png_byte)background->gray;
+#endif
+                  }
+               }
+            }
+            else /* if (png_ptr->bit_depth == 16) */
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+                  {
+                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                     }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                     else if (a == 0)
+#else
+                     else
+#endif
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)((background->gray >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->gray & 0xff);
+                     }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                     else
+                     {
+                        png_uint_16 g, v, w;
+
+                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(v, g, a, background_1->gray);
+                        w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+                        *dp = (png_byte)((w >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(w & 0xff);
+                     }
+#endif
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+                  {
+                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_memcpy(dp, sp, 2);
+                     }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                     else if (a == 0)
+#else
+                     else
+#endif
+                     {
+                        *dp = (png_byte)((background->gray >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->gray & 0xff);
+                     }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                     else
+                     {
+                        png_uint_16 g, v;
+
+                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        png_composite_16(v, g, a, background_1->gray);
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                     }
+#endif
+                  }
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+                  {
+                     png_byte a = *(sp + 3);
+
+                     if (a == 0xff)
+                     {
+                        *dp = gamma_table[*sp];
+                        *(dp + 1) = gamma_table[*(sp + 1)];
+                        *(dp + 2) = gamma_table[*(sp + 2)];
+                     }
+                     else if (a == 0)
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)background->red;
+                        *(dp + 1) = (png_byte)background->green;
+                        *(dp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, background_1->red);
+                        *dp = gamma_from_1[w];
+                        v = gamma_to_1[*(sp + 1)];
+                        png_composite(w, v, a, background_1->green);
+                        *(dp + 1) = gamma_from_1[w];
+                        v = gamma_to_1[*(sp + 2)];
+                        png_composite(w, v, a, background_1->blue);
+                        *(dp + 2) = gamma_from_1[w];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+                  {
+                     png_byte a = *(sp + 3);
+
+                     if (a == 0xff)
+                     {
+                        *dp = *sp;
+                        *(dp + 1) = *(sp + 1);
+                        *(dp + 2) = *(sp + 2);
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)background->red;
+                        *(dp + 1) = (png_byte)background->green;
+                        *(dp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        png_composite(*dp, *sp, a, background->red);
+                        png_composite(*(dp + 1), *(sp + 1), a,
+                           background->green);
+                        png_composite(*(dp + 2), *(sp + 2), a,
+                           background->blue);
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+                  {
+                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                         << 8) + (png_uint_16)(*(sp + 7)));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(v & 0xff);
+                     }
+                     else if (a == 0)
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)((background->red >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->red & 0xff);
+                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(background->green & 0xff);
+                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v, w, x;
+
+                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(w, v, a, background_1->red);
+                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+                        *dp = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(x & 0xff);
+                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        png_composite_16(w, v, a, background_1->green);
+                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+                        *(dp + 2) = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(x & 0xff);
+                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        png_composite_16(w, v, a, background_1->blue);
+                        x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
+                        *(dp + 4) = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(x & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+                  {
+                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                        << 8) + (png_uint_16)(*(sp + 7)));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_memcpy(dp, sp, 6);
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)((background->red >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->red & 0xff);
+                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(background->green & 0xff);
+                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v;
+
+                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                            + *(sp + 3));
+                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                            + *(sp + 5));
+
+                        png_composite_16(v, r, a, background->red);
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                        png_composite_16(v, g, a, background->green);
+                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(v & 0xff);
+                        png_composite_16(v, b, a, background->blue);
+                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+      }
+
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+         row_info->channels--;
+         row_info->pixel_depth = (png_byte)(row_info->channels *
+            row_info->bit_depth);
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Gamma correct the image, avoiding the alpha channel.  Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift.  Build these with
+ * build_gamma_table().
+ */
+void /* PRIVATE */
+png_do_gamma(png_row_infop row_info, png_bytep row,
+   png_bytep gamma_table, png_uint_16pp gamma_16_table,
+   int gamma_shift)
+{
+   png_bytep sp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_gamma\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  sp++;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp += 2;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            if (row_info->bit_depth == 2)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i += 4)
+               {
+                  int a = *sp & 0xc0;
+                  int b = *sp & 0x30;
+                  int c = *sp & 0x0c;
+                  int d = *sp & 0x03;
+
+                  *sp = (png_byte)(
+                        ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
+                        ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+                        ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+                        ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+                  sp++;
+               }
+            }
+            if (row_info->bit_depth == 4)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i += 2)
+               {
+                  int msb = *sp & 0xf0;
+                  int lsb = *sp & 0x0f;
+
+                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+                          | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+                  sp++;
+               }
+            }
+            else if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+            else if (row_info->bit_depth == 16)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+void /* PRIVATE */
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+   png_colorp palette, png_bytep trans, int num_trans)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_expand_palette\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (row_info->bit_depth < 8)
+      {
+         switch (row_info->bit_depth)
+         {
+            case 1:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 3);
+               dp = row + (png_size_t)row_width - 1;
+               shift = 7 - (int)((row_width + 7) & 0x07);
+               for (i = 0; i < row_width; i++)
+               {
+                  if ((*sp >> shift) & 0x01)
+                     *dp = 1;
+                  else
+                     *dp = 0;
+                  if (shift == 7)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift++;
+
+                  dp--;
+               }
+               break;
+            }
+            case 2:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 2);
+               dp = row + (png_size_t)row_width - 1;
+               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+               for (i = 0; i < row_width; i++)
+               {
+                  value = (*sp >> shift) & 0x03;
+                  *dp = (png_byte)value;
+                  if (shift == 6)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift += 2;
+
+                  dp--;
+               }
+               break;
+            }
+            case 4:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 1);
+               dp = row + (png_size_t)row_width - 1;
+               shift = (int)((row_width & 0x01) << 2);
+               for (i = 0; i < row_width; i++)
+               {
+                  value = (*sp >> shift) & 0x0f;
+                  *dp = (png_byte)value;
+                  if (shift == 4)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift += 4;
+
+                  dp--;
+               }
+               break;
+            }
+         }
+         row_info->bit_depth = 8;
+         row_info->pixel_depth = 8;
+         row_info->rowbytes = row_width;
+      }
+      switch (row_info->bit_depth)
+      {
+         case 8:
+         {
+            if (trans != NULL)
+            {
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width << 2) - 1;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  if ((int)(*sp) >= num_trans)
+                     *dp-- = 0xff;
+                  else
+                     *dp-- = trans[*sp];
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 32;
+               row_info->rowbytes = row_width * 4;
+               row_info->color_type = 6;
+               row_info->channels = 4;
+            }
+            else
+            {
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width * 3) - 1;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 24;
+               row_info->rowbytes = row_width * 3;
+               row_info->color_type = 2;
+               row_info->channels = 3;
+            }
+            break;
+         }
+      }
+   }
+}
+
+/* If the bit depth < 8, it is expanded to 8.  Also, if the
+ * transparency value is supplied, an alpha channel is built.
+ */
+void /* PRIVATE */
+png_do_expand(png_row_infop row_info, png_bytep row,
+   png_color_16p trans_value)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_expand\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
+
+         if (row_info->bit_depth < 8)
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  gray = (png_uint_16)(gray*0xff);
+                  sp = row + (png_size_t)((row_width - 1) >> 3);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = 7 - (int)((row_width + 7) & 0x07);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     if ((*sp >> shift) & 0x01)
+                        *dp = 0xff;
+                     else
+                        *dp = 0;
+                     if (shift == 7)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift++;
+
+                     dp--;
+                  }
+                  break;
+               }
+               case 2:
+               {
+                  gray = (png_uint_16)(gray*0x55);
+                  sp = row + (png_size_t)((row_width - 1) >> 2);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     value = (*sp >> shift) & 0x03;
+                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
+                        (value << 6));
+                     if (shift == 6)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift += 2;
+
+                     dp--;
+                  }
+                  break;
+               }
+               case 4:
+               {
+                  gray = (png_uint_16)(gray*0x11);
+                  sp = row + (png_size_t)((row_width - 1) >> 1);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     value = (*sp >> shift) & 0x0f;
+                     *dp = (png_byte)(value | (value << 4));
+                     if (shift == 4)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift = 4;
+
+                     dp--;
+                  }
+                  break;
+               }
+            }
+            row_info->bit_depth = 8;
+            row_info->pixel_depth = 8;
+            row_info->rowbytes = row_width;
+         }
+
+         if (trans_value != NULL)
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width << 1) - 1;
+               for (i = 0; i < row_width; i++)
+               {
+                  if (*sp == gray)
+                     *dp-- = 0;
+                  else
+                     *dp-- = 0xff;
+                  *dp-- = *sp--;
+               }
+            }
+            else if (row_info->bit_depth == 16)
+            {
+               sp = row + row_info->rowbytes - 1;
+               dp = row + (row_info->rowbytes << 1) - 1;
+               for (i = 0; i < row_width; i++)
+               {
+                  if (((png_uint_16)*(sp) |
+                     ((png_uint_16)*(sp - 1) << 8)) == gray)
+                  {
+                     *dp-- = 0;
+                     *dp-- = 0;
+                  }
+                  else
+                  {
+                     *dp-- = 0xff;
+                     *dp-- = 0xff;
+                  }
+                  *dp-- = *sp--;
+                  *dp-- = *sp--;
+               }
+            }
+            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+            row_info->channels = 2;
+            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+               row_width);
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            sp = row + (png_size_t)row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_width << 2) - 1;
+            for (i = 0; i < row_width; i++)
+            {
+               if (*(sp - 2) == trans_value->red &&
+                  *(sp - 1) == trans_value->green &&
+                  *(sp - 0) == trans_value->blue)
+                  *dp-- = 0;
+               else
+                  *dp-- = 0xff;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         else if (row_info->bit_depth == 16)
+         {
+            sp = row + row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_width << 3) - 1;
+            for (i = 0; i < row_width; i++)
+            {
+               if ((((png_uint_16)*(sp - 4) |
+                  ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
+                  (((png_uint_16)*(sp - 2) |
+                  ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
+                  (((png_uint_16)*(sp - 0) |
+                  ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
+               {
+                  *dp-- = 0;
+                  *dp-- = 0;
+               }
+               else
+               {
+                  *dp-- = 0xff;
+                  *dp-- = 0xff;
+               }
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+         row_info->channels = 4;
+         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+void /* PRIVATE */
+png_do_dither(png_row_infop row_info, png_bytep row,
+    png_bytep palette_lookup, png_bytep dither_lookup)
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_dither\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+         palette_lookup && row_info->bit_depth == 8)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+
+            /* this looks real messy, but the compiler will reduce
+               it down to a reasonable formula.  For example, with
+               5 bits per color, we get:
+               p = (((r >> 3) & 0x1f) << 10) |
+                  (((g >> 3) & 0x1f) << 5) |
+                  ((b >> 3) & 0x1f);
+               */
+            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+               (PNG_DITHER_BLUE_BITS)) |
+               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+               ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+         palette_lookup != NULL && row_info->bit_depth == 8)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+            sp++;
+
+            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+               (PNG_DITHER_BLUE_BITS)) |
+               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+               ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+         dither_lookup && row_info->bit_depth == 8)
+      {
+         sp = row;
+         for (i = 0; i < row_width; i++, sp++)
+         {
+            *sp = dither_lookup[*sp];
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+static int png_gamma_shift[] =
+   {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
+
+/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future.  Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ */
+void /* PRIVATE */
+png_build_gamma_table(png_structp png_ptr)
+{
+  png_debug(1, "in png_build_gamma_table\n");
+  if(png_ptr->gamma != 0.0)
+  {
+   if (png_ptr->bit_depth <= 8)
+   {
+      int i;
+      double g;
+
+      if (png_ptr->screen_gamma > .000001)
+         g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+      else
+         g = 1.0;
+
+      png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
+         (png_uint_32)256);
+
+      for (i = 0; i < 256; i++)
+      {
+         png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
+            g) * 255.0 + .5);
+      }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+      if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
+      {
+
+         g = 1.0 / (png_ptr->gamma);
+
+         png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)256);
+
+         for (i = 0; i < 256; i++)
+         {
+            png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
+               g) * 255.0 + .5);
+         }
+
+
+         png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)256);
+
+         if(png_ptr->screen_gamma > 0.000001)
+            g = 1.0 / png_ptr->screen_gamma;
+         else
+            g = png_ptr->gamma;   /* probably doing rgb_to_gray */
+
+         for (i = 0; i < 256; i++)
+         {
+            png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
+               g) * 255.0 + .5);
+
+         }
+      }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+   }
+   else
+   {
+      double g;
+      int i, j, shift, num;
+      int sig_bit;
+      png_uint_32 ig;
+
+      if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         sig_bit = (int)png_ptr->sig_bit.red;
+         if ((int)png_ptr->sig_bit.green > sig_bit)
+            sig_bit = png_ptr->sig_bit.green;
+         if ((int)png_ptr->sig_bit.blue > sig_bit)
+            sig_bit = png_ptr->sig_bit.blue;
+      }
+      else
+      {
+         sig_bit = (int)png_ptr->sig_bit.gray;
+      }
+
+      if (sig_bit > 0)
+         shift = 16 - sig_bit;
+      else
+         shift = 0;
+
+      if (png_ptr->transformations & PNG_16_TO_8)
+      {
+         if (shift < (16 - PNG_MAX_GAMMA_8))
+            shift = (16 - PNG_MAX_GAMMA_8);
+      }
+
+      if (shift > 8)
+         shift = 8;
+      if (shift < 0)
+         shift = 0;
+
+      png_ptr->gamma_shift = (png_byte)shift;
+
+      num = (1 << (8 - shift));
+
+      if (png_ptr->screen_gamma > .000001)
+         g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+      else
+         g = 1.0;
+
+      png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
+         (png_uint_32)(num * png_sizeof (png_uint_16p)));
+
+      if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
+      {
+         double fin, fout;
+         png_uint_32 last, max;
+
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * png_sizeof (png_uint_16)));
+         }
+
+         g = 1.0 / g;
+         last = 0;
+         for (i = 0; i < 256; i++)
+         {
+            fout = ((double)i + 0.5) / 256.0;
+            fin = pow(fout, g);
+            max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
+            while (last <= max)
+            {
+               png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+                  [(int)(last >> (8 - shift))] = (png_uint_16)(
+                  (png_uint_16)i | ((png_uint_16)i << 8));
+               last++;
+            }
+         }
+         while (last < ((png_uint_32)num << 8))
+         {
+            png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+               [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
+            last++;
+         }
+      }
+      else
+      {
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * png_sizeof (png_uint_16)));
+
+            ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
+            for (j = 0; j < 256; j++)
+            {
+               png_ptr->gamma_16_table[i][j] =
+                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                     65535.0, g) * 65535.0 + .5);
+            }
+         }
+      }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+      if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
+      {
+
+         g = 1.0 / (png_ptr->gamma);
+
+         png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
+            (png_uint_32)(num * png_sizeof (png_uint_16p )));
+
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * png_sizeof (png_uint_16)));
+
+            ig = (((png_uint_32)i *
+               (png_uint_32)png_gamma_shift[shift]) >> 4);
+            for (j = 0; j < 256; j++)
+            {
+               png_ptr->gamma_16_to_1[i][j] =
+                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                     65535.0, g) * 65535.0 + .5);
+            }
+         }
+
+         if(png_ptr->screen_gamma > 0.000001)
+            g = 1.0 / png_ptr->screen_gamma;
+         else
+            g = png_ptr->gamma;   /* probably doing rgb_to_gray */
+
+         png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
+            (png_uint_32)(num * png_sizeof (png_uint_16p)));
+
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * png_sizeof (png_uint_16)));
+
+            ig = (((png_uint_32)i *
+               (png_uint_32)png_gamma_shift[shift]) >> 4);
+            for (j = 0; j < 256; j++)
+            {
+               png_ptr->gamma_16_from_1[i][j] =
+                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                     65535.0, g) * 65535.0 + .5);
+            }
+         }
+      }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+   }
+ }
+}
+#endif
+/* To do: install integer version of png_build_gamma_table here */
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing  */
+void /* PRIVATE */
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_intrapixel\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
+            *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp  ) << 8) | *(rp+1);
+            png_uint_32 s1   = (*(rp+2) << 8) | *(rp+3);
+            png_uint_32 s2   = (*(rp+4) << 8) | *(rp+5);
+            png_uint_32 red  = (png_uint_32)((s0+s1+65536L) & 0xffffL);
+            png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
+            *(rp  ) = (png_byte)((red >> 8) & 0xff);
+            *(rp+1) = (png_byte)(red & 0xff);
+            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp+5) = (png_byte)(blue & 0xff);
+         }
+      }
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
diff --git a/Utilities/FLTK/png/pngrutil.c b/Utilities/FLTK/png/pngrutil.c
new file mode 100644
index 0000000000000000000000000000000000000000..4197bc77667c5eb520a8a56711580fe334464bfe
--- /dev/null
+++ b/Utilities/FLTK/png/pngrutil.c
@@ -0,0 +1,3124 @@
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file contains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(_WIN32_WCE)
+/* strtod() function is not supported on WindowsCE */
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+__inline double strtod(const char *nptr, char **endptr)
+{
+   double result = 0;
+   int len;
+   wchar_t *str, *end;
+
+   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
+   str = (wchar_t *)malloc(len * sizeof(wchar_t));
+   if ( NULL != str )
+   {
+      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
+      result = wcstod(str, &end);
+      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
+      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
+      free(str);
+   }
+   return result;
+}
+#  endif
+#endif
+
+png_uint_32 /* PRIVATE */
+png_get_uint_31(png_structp png_ptr, png_bytep buf)
+{
+   png_uint_32 i = png_get_uint_32(buf);
+   if (i > PNG_UINT_31_MAX)
+     png_error(png_ptr, "PNG unsigned integer out of range.\n");
+   return (i);
+}
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 /* PRIVATE */
+png_get_uint_32(png_bytep buf)
+{
+   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+      ((png_uint_32)(*(buf + 1)) << 16) +
+      ((png_uint_32)(*(buf + 2)) << 8) +
+      (png_uint_32)(*(buf + 3));
+
+   return (i);
+}
+
+#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
+/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
+ * data is stored in the PNG file in two's complement format, and it is
+ * assumed that the machine format for signed integers is the same. */
+png_int_32 /* PRIVATE */
+png_get_int_32(png_bytep buf)
+{
+   png_int_32 i = ((png_int_32)(*buf) << 24) +
+      ((png_int_32)(*(buf + 1)) << 16) +
+      ((png_int_32)(*(buf + 2)) << 8) +
+      (png_int_32)(*(buf + 3));
+
+   return (i);
+}
+#endif /* PNG_READ_pCAL_SUPPORTED */
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 /* PRIVATE */
+png_get_uint_16(png_bytep buf)
+{
+   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
+      (png_uint_16)(*(buf + 1)));
+
+   return (i);
+}
+#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
+{
+   png_read_data(png_ptr, buf, length);
+   png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC.  Depending on whether we
+   are reading a ancillary or critical chunk, and how the program has set
+   things up, we may calculate the CRC on the data and print a message.
+   Returns '1' if there was a CRC error, '0' otherwise. */
+int /* PRIVATE */
+png_crc_finish(png_structp png_ptr, png_uint_32 skip)
+{
+   png_size_t i;
+   png_size_t istop = png_ptr->zbuf_size;
+
+   for (i = (png_size_t)skip; i > istop; i -= istop)
+   {
+      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+   }
+   if (i)
+   {
+      png_crc_read(png_ptr, png_ptr->zbuf, i);
+   }
+
+   if (png_crc_error(png_ptr))
+   {
+      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
+           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
+          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
+          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
+      {
+         png_chunk_warning(png_ptr, "CRC error");
+      }
+      else
+      {
+         png_chunk_error(png_ptr, "CRC error");
+      }
+      return (1);
+   }
+
+   return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+   the data it has read thus far. */
+int /* PRIVATE */
+png_crc_error(png_structp png_ptr)
+{
+   png_byte crc_bytes[4];
+   png_uint_32 crc;
+   int need_crc = 1;
+
+   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+   else                                                    /* critical */
+   {
+      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+         need_crc = 0;
+   }
+
+   png_read_data(png_ptr, crc_bytes, 4);
+
+   if (need_crc)
+   {
+      crc = png_get_uint_32(crc_bytes);
+      return ((int)(crc != png_ptr->crc));
+   }
+   else
+      return (0);
+}
+
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+    defined(PNG_READ_iCCP_SUPPORTED)
+/*
+ * Decompress trailing data in a chunk.  The assumption is that chunkdata
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part.  What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+png_charp /* PRIVATE */
+png_decompress_chunk(png_structp png_ptr, int comp_type,
+                              png_charp chunkdata, png_size_t chunklength,
+                              png_size_t prefix_size, png_size_t *newlength)
+{
+   static char msg[] = "Error decoding compressed text";
+   png_charp text;
+   png_size_t text_size;
+
+   if (comp_type == PNG_COMPRESSION_TYPE_BASE)
+   {
+      int ret = Z_OK;
+      png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
+      png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+      text_size = 0;
+      text = NULL;
+
+      while (png_ptr->zstream.avail_in)
+      {
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret != Z_OK && ret != Z_STREAM_END)
+         {
+            if (png_ptr->zstream.msg != NULL)
+               png_warning(png_ptr, png_ptr->zstream.msg);
+            else
+               png_warning(png_ptr, msg);
+            inflateReset(&png_ptr->zstream);
+            png_ptr->zstream.avail_in = 0;
+
+            if (text ==  NULL)
+            {
+               text_size = prefix_size + png_sizeof(msg) + 1;
+               text = (png_charp)png_malloc_warn(png_ptr, text_size);
+               if (text ==  NULL)
+                 {
+                    png_free(png_ptr,chunkdata);
+                    png_error(png_ptr,"Not enough memory to decompress chunk");
+                 }
+               png_memcpy(text, chunkdata, prefix_size);
+            }
+
+            text[text_size - 1] = 0x00;
+
+            /* Copy what we can of the error message into the text chunk */
+            text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
+            text_size = png_sizeof(msg) > text_size ? text_size :
+               png_sizeof(msg);
+            png_memcpy(text + prefix_size, msg, text_size + 1);
+            break;
+         }
+         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
+         {
+            if (text == NULL)
+            {
+               text_size = prefix_size +
+                   png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
+               if (text ==  NULL)
+                 {
+                    png_free(png_ptr,chunkdata);
+                    png_error(png_ptr,"Not enough memory to decompress chunk.");
+                 }
+               png_memcpy(text + prefix_size, png_ptr->zbuf,
+                    text_size - prefix_size);
+               png_memcpy(text, chunkdata, prefix_size);
+               *(text + text_size) = 0x00;
+            }
+            else
+            {
+               png_charp tmp;
+
+               tmp = text;
+               text = (png_charp)png_malloc_warn(png_ptr,
+                  (png_uint_32)(text_size +
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+               if (text == NULL)
+               {
+                  png_free(png_ptr, tmp);
+                  png_free(png_ptr, chunkdata);
+                  png_error(png_ptr,"Not enough memory to decompress chunk..");
+               }
+               png_memcpy(text, tmp, text_size);
+               png_free(png_ptr, tmp);
+               png_memcpy(text + text_size, png_ptr->zbuf,
+                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               *(text + text_size) = 0x00;
+            }
+            if (ret == Z_STREAM_END)
+               break;
+            else
+            {
+               png_ptr->zstream.next_out = png_ptr->zbuf;
+               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            }
+         }
+      }
+      if (ret != Z_STREAM_END)
+      {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+         char umsg[50];
+
+         if (ret == Z_BUF_ERROR)
+            sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
+                png_ptr->chunk_name);
+         else if (ret == Z_DATA_ERROR)
+            sprintf(umsg,"Data error in compressed datastream in %s chunk",
+                png_ptr->chunk_name);
+         else
+            sprintf(umsg,"Incomplete compressed datastream in %s chunk",
+                png_ptr->chunk_name);
+         png_warning(png_ptr, umsg);
+#else
+         png_warning(png_ptr,
+            "Incomplete compressed datastream in chunk other than IDAT");
+#endif
+         text_size=prefix_size;
+         if (text ==  NULL)
+         {
+            text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
+            if (text == NULL)
+              {
+                png_free(png_ptr, chunkdata);
+                png_error(png_ptr,"Not enough memory for text.");
+              }
+            png_memcpy(text, chunkdata, prefix_size);
+         }
+         *(text + text_size) = 0x00;
+      }
+
+      inflateReset(&png_ptr->zstream);
+      png_ptr->zstream.avail_in = 0;
+
+      png_free(png_ptr, chunkdata);
+      chunkdata = text;
+      *newlength=text_size;
+   }
+   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
+   {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+      char umsg[50];
+
+      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
+      png_warning(png_ptr, umsg);
+#else
+      png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+      *(chunkdata + prefix_size) = 0x00;
+      *newlength=prefix_size;
+   }
+
+   return chunkdata;
+}
+#endif
+
+/* read and check the IDHR chunk */
+void /* PRIVATE */
+png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[13];
+   png_uint_32 width, height;
+   int bit_depth, color_type, compression_type, filter_type;
+   int interlace_type;
+
+   png_debug(1, "in png_handle_IHDR\n");
+
+   if (png_ptr->mode & PNG_HAVE_IHDR)
+      png_error(png_ptr, "Out of place IHDR");
+
+   /* check the length */
+   if (length != 13)
+      png_error(png_ptr, "Invalid IHDR chunk");
+
+   png_ptr->mode |= PNG_HAVE_IHDR;
+
+   png_crc_read(png_ptr, buf, 13);
+   png_crc_finish(png_ptr, 0);
+
+   width = png_get_uint_31(png_ptr, buf);
+   height = png_get_uint_31(png_ptr, buf + 4);
+   bit_depth = buf[8];
+   color_type = buf[9];
+   compression_type = buf[10];
+   filter_type = buf[11];
+   interlace_type = buf[12];
+
+   /* set internal variables */
+   png_ptr->width = width;
+   png_ptr->height = height;
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->interlaced = (png_byte)interlace_type;
+   png_ptr->color_type = (png_byte)color_type;
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   png_ptr->filter_type = (png_byte)filter_type;
+#endif
+   png_ptr->compression_type = (png_byte)compression_type;
+
+   /* find number of channels */
+   switch (png_ptr->color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+      case PNG_COLOR_TYPE_PALETTE:
+         png_ptr->channels = 1;
+         break;
+      case PNG_COLOR_TYPE_RGB:
+         png_ptr->channels = 3;
+         break;
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         png_ptr->channels = 2;
+         break;
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         png_ptr->channels = 4;
+         break;
+   }
+
+   /* set up other useful info */
+   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+   png_ptr->channels);
+   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
+   png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
+   png_debug1(3,"channels = %d\n", png_ptr->channels);
+   png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
+   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+      color_type, interlace_type, compression_type, filter_type);
+}
+
+/* read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_color palette[PNG_MAX_PALETTE_LENGTH];
+   int num, i;
+#ifndef PNG_NO_POINTER_INDEXING
+   png_colorp pal_ptr;
+#endif
+
+   png_debug(1, "in png_handle_PLTE\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before PLTE");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid PLTE after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      png_error(png_ptr, "Duplicate PLTE chunk");
+
+   png_ptr->mode |= PNG_HAVE_PLTE;
+
+   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+   {
+      png_warning(png_ptr,
+        "Ignoring PLTE chunk in grayscale PNG");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+#endif
+
+   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+   {
+      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+      {
+         png_warning(png_ptr, "Invalid palette chunk");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      else
+      {
+         png_error(png_ptr, "Invalid palette chunk");
+      }
+   }
+
+   num = (int)length / 3;
+
+#ifndef PNG_NO_POINTER_INDEXING
+   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      pal_ptr->red = buf[0];
+      pal_ptr->green = buf[1];
+      pal_ptr->blue = buf[2];
+   }
+#else
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      /* don't depend upon png_color being any order */
+      palette[i].red = buf[0];
+      palette[i].green = buf[1];
+      palette[i].blue = buf[2];
+   }
+#endif
+
+   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
+      whatever the normal CRC configuration tells us.  However, if we
+      have an RGB image, the PLTE can be considered ancillary, so
+      we will act as though it is. */
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+   {
+      png_crc_finish(png_ptr, 0);
+   }
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
+   {
+      /* If we don't want to use the data from an ancillary chunk,
+         we have two options: an error abort, or a warning and we
+         ignore the data in this chunk (which should be OK, since
+         it's considered ancillary for a RGB or RGBA image). */
+      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+      {
+         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+         {
+            png_chunk_error(png_ptr, "CRC error");
+         }
+         else
+         {
+            png_chunk_warning(png_ptr, "CRC error");
+            return;
+         }
+      }
+      /* Otherwise, we (optionally) emit a warning and use the chunk. */
+      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+      {
+         png_chunk_warning(png_ptr, "CRC error");
+      }
+   }
+#endif
+
+   png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+      {
+         if (png_ptr->num_trans > (png_uint_16)num)
+         {
+            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
+            png_ptr->num_trans = (png_uint_16)num;
+         }
+         if (info_ptr->num_trans > (png_uint_16)num)
+         {
+            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
+            info_ptr->num_trans = (png_uint_16)num;
+         }
+      }
+   }
+#endif
+
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_debug(1, "in png_handle_IEND\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+   {
+      png_error(png_ptr, "No image in file");
+   }
+
+   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+   if (length != 0)
+   {
+      png_warning(png_ptr, "Incorrect IEND chunk length");
+   }
+   png_crc_finish(png_ptr, length);
+
+   if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
+      return;
+}
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+void /* PRIVATE */
+png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_fixed_point igamma;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float file_gamma;
+#endif
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_gAMA\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before gAMA");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid gAMA after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place gAMA chunk");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+      )
+   {
+      png_warning(png_ptr, "Duplicate gAMA chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 4)
+   {
+      png_warning(png_ptr, "Incorrect gAMA chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   igamma = (png_fixed_point)png_get_uint_32(buf);
+   /* check for zero gamma */
+   if (igamma == 0)
+      {
+         png_warning(png_ptr,
+           "Ignoring gAMA chunk with gamma=0");
+         return;
+      }
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sRGB)
+      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+      {
+         png_warning(png_ptr,
+           "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+         fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
+#endif
+         return;
+      }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   file_gamma = (float)igamma / (float)100000.0;
+#  ifdef PNG_READ_GAMMA_SUPPORTED
+     png_ptr->gamma = file_gamma;
+#  endif
+     png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+void /* PRIVATE */
+png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_size_t truelen;
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_sBIT\n");
+
+   buf[0] = buf[1] = buf[2] = buf[3] = 0;
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sBIT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sBIT after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+   {
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place sBIT chunk");
+   }
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
+   {
+      png_warning(png_ptr, "Duplicate sBIT chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      truelen = 3;
+   else
+      truelen = (png_size_t)png_ptr->channels;
+
+   if (length != truelen || length > 4)
+   {
+      png_warning(png_ptr, "Incorrect sBIT chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, truelen);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_ptr->sig_bit.red = buf[0];
+      png_ptr->sig_bit.green = buf[1];
+      png_ptr->sig_bit.blue = buf[2];
+      png_ptr->sig_bit.alpha = buf[3];
+   }
+   else
+   {
+      png_ptr->sig_bit.gray = buf[0];
+      png_ptr->sig_bit.red = buf[0];
+      png_ptr->sig_bit.green = buf[0];
+      png_ptr->sig_bit.blue = buf[0];
+      png_ptr->sig_bit.alpha = buf[1];
+   }
+   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+void /* PRIVATE */
+png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[4];
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+      int_y_green, int_x_blue, int_y_blue;
+
+   png_uint_32 uint_x, uint_y;
+
+   png_debug(1, "in png_handle_cHRM\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before cHRM");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid cHRM after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Missing PLTE before cHRM");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+      )
+   {
+      png_warning(png_ptr, "Duplicate cHRM chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 32)
+   {
+      png_warning(png_ptr, "Incorrect cHRM chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_x = png_get_uint_32(buf);
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_y = png_get_uint_32(buf);
+
+   if (uint_x > 80000L || uint_y > 80000L ||
+      uint_x + uint_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid cHRM white point");
+      png_crc_finish(png_ptr, 24);
+      return;
+   }
+   int_x_white = (png_fixed_point)uint_x;
+   int_y_white = (png_fixed_point)uint_y;
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_x = png_get_uint_32(buf);
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_y = png_get_uint_32(buf);
+
+   if (uint_x > 80000L || uint_y > 80000L ||
+      uint_x + uint_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid cHRM red point");
+      png_crc_finish(png_ptr, 16);
+      return;
+   }
+   int_x_red = (png_fixed_point)uint_x;
+   int_y_red = (png_fixed_point)uint_y;
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_x = png_get_uint_32(buf);
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_y = png_get_uint_32(buf);
+
+   if (uint_x > 80000L || uint_y > 80000L ||
+      uint_x + uint_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid cHRM green point");
+      png_crc_finish(png_ptr, 8);
+      return;
+   }
+   int_x_green = (png_fixed_point)uint_x;
+   int_y_green = (png_fixed_point)uint_y;
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_x = png_get_uint_32(buf);
+
+   png_crc_read(png_ptr, buf, 4);
+   uint_y = png_get_uint_32(buf);
+
+   if (uint_x > 80000L || uint_y > 80000L ||
+      uint_x + uint_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid cHRM blue point");
+      png_crc_finish(png_ptr, 0);
+      return;
+   }
+   int_x_blue = (png_fixed_point)uint_x;
+   int_y_blue = (png_fixed_point)uint_y;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   white_x = (float)int_x_white / (float)100000.0;
+   white_y = (float)int_y_white / (float)100000.0;
+   red_x   = (float)int_x_red   / (float)100000.0;
+   red_y   = (float)int_y_red   / (float)100000.0;
+   green_x = (float)int_x_green / (float)100000.0;
+   green_y = (float)int_y_green / (float)100000.0;
+   blue_x  = (float)int_x_blue  / (float)100000.0;
+   blue_y  = (float)int_y_blue  / (float)100000.0;
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sRGB)
+      {
+      if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
+          PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
+          PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
+          PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
+          PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
+          PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
+          PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
+          PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
+         {
+
+            png_warning(png_ptr,
+              "Ignoring incorrect cHRM value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+            fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
+               white_x, white_y, red_x, red_y);
+            fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
+               green_x, green_y, blue_x, blue_y);
+#else
+            fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
+               int_x_white, int_y_white, int_x_red, int_y_red);
+            fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
+               int_x_green, int_y_green, int_x_blue, int_y_blue);
+#endif
+#endif /* PNG_NO_CONSOLE_IO */
+         }
+         png_crc_finish(png_ptr, 0);
+         return;
+      }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   png_set_cHRM(png_ptr, info_ptr,
+      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_cHRM_fixed(png_ptr, info_ptr,
+      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+      int_y_green, int_x_blue, int_y_blue);
+#endif
+   if (png_crc_finish(png_ptr, 0))
+      return;
+}
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+void /* PRIVATE */
+png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   int intent;
+   png_byte buf[1];
+
+   png_debug(1, "in png_handle_sRGB\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sRGB");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sRGB after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place sRGB chunk");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+   {
+      png_warning(png_ptr, "Duplicate sRGB chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 1)
+   {
+      png_warning(png_ptr, "Incorrect sRGB chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 1);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   intent = buf[0];
+   /* check for bad intent */
+   if (intent >= PNG_sRGB_INTENT_LAST)
+   {
+      png_warning(png_ptr, "Unknown sRGB intent");
+      return;
+   }
+
+#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+   if ((info_ptr->valid & PNG_INFO_gAMA))
+   {
+   png_fixed_point igamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      igamma=info_ptr->int_gamma;
+#else
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+      igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
+#  endif
+#endif
+      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+      {
+         png_warning(png_ptr,
+           "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+         fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
+#  else
+#    ifdef PNG_FLOATING_POINT_SUPPORTED
+         fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
+#    endif
+#  endif
+#endif
+      }
+   }
+#endif /* PNG_READ_gAMA_SUPPORTED */
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_cHRM)
+      if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
+         {
+            png_warning(png_ptr,
+              "Ignoring incorrect cHRM value when sRGB is also present");
+         }
+#endif /* PNG_FIXED_POINT_SUPPORTED */
+#endif /* PNG_READ_cHRM_SUPPORTED */
+
+   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+void /* PRIVATE */
+png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_charp chunkdata;
+   png_byte compression_type;
+   png_bytep pC;
+   png_charp profile;
+   png_uint_32 skip = 0;
+   png_uint_32 profile_size, profile_length;
+   png_size_t slength, prefix_length, data_length;
+
+   png_debug(1, "in png_handle_iCCP\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iCCP");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid iCCP after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place iCCP chunk");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
+   {
+      png_warning(png_ptr, "Duplicate iCCP chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (profile = chunkdata; *profile; profile++)
+      /* empty loop to find end of name */ ;
+
+   ++profile;
+
+   /* there should be at least one zero (the compression type byte)
+      following the separator, and we should be on it  */
+   if ( profile >= chunkdata + slength)
+   {
+      png_free(png_ptr, chunkdata);
+      png_warning(png_ptr, "Malformed iCCP chunk");
+      return;
+   }
+
+   /* compression_type should always be zero */
+   compression_type = *profile++;
+   if (compression_type)
+   {
+      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
+      compression_type=0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
+                                 wrote nonzero) */
+   }
+
+   prefix_length = profile - chunkdata;
+   chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
+                                    slength, prefix_length, &data_length);
+
+   profile_length = data_length - prefix_length;
+
+   if ( prefix_length > data_length || profile_length < 4)
+   {
+      png_free(png_ptr, chunkdata);
+      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
+      return;
+   }
+
+   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
+   pC = (png_bytep)(chunkdata+prefix_length);
+   profile_size = ((*(pC  ))<<24) |
+                  ((*(pC+1))<<16) |
+                  ((*(pC+2))<< 8) |
+                  ((*(pC+3))    );
+
+   if(profile_size < profile_length)
+      profile_length = profile_size;
+
+   if(profile_size > profile_length)
+   {
+      png_free(png_ptr, chunkdata);
+      png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
+      return;
+   }
+
+   png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
+                chunkdata + prefix_length, profile_length);
+   png_free(png_ptr, chunkdata);
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+void /* PRIVATE */
+png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_bytep chunkdata;
+   png_bytep entry_start;
+   png_sPLT_t new_palette;
+#ifdef PNG_NO_POINTER_INDEXING
+   png_sPLT_entryp pp;
+#endif
+   int data_length, entry_size, i;
+   png_uint_32 skip = 0;
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sPLT\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sPLT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sPLT after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (entry_start = chunkdata; *entry_start; entry_start++)
+      /* empty loop to find end of name */ ;
+   ++entry_start;
+
+   /* a sample depth should follow the separator, and we should be on it  */
+   if (entry_start > chunkdata + slength)
+   {
+      png_free(png_ptr, chunkdata);
+      png_warning(png_ptr, "malformed sPLT chunk");
+      return;
+   }
+
+   new_palette.depth = *entry_start++;
+   entry_size = (new_palette.depth == 8 ? 6 : 10);
+   data_length = (slength - (entry_start - chunkdata));
+
+   /* integrity-check the data length */
+   if (data_length % entry_size)
+   {
+      png_free(png_ptr, chunkdata);
+      png_warning(png_ptr, "sPLT chunk has bad length");
+      return;
+   }
+
+   new_palette.nentries = (png_uint_32) (data_length / entry_size);
+   if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
+       png_sizeof(png_sPLT_entry)))
+   {
+       png_warning(png_ptr, "sPLT chunk too long");
+       return;
+   }
+   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
+   if (new_palette.entries == NULL)
+   {
+       png_warning(png_ptr, "sPLT chunk requires too much memory");
+       return;
+   }
+
+#ifndef PNG_NO_POINTER_INDEXING
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+      png_sPLT_entryp pp = new_palette.entries + i;
+
+      if (new_palette.depth == 8)
+      {
+          pp->red = *entry_start++;
+          pp->green = *entry_start++;
+          pp->blue = *entry_start++;
+          pp->alpha = *entry_start++;
+      }
+      else
+      {
+          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
+          pp->green = png_get_uint_16(entry_start); entry_start += 2;
+          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
+          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#else
+   pp = new_palette.entries;
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+
+      if (new_palette.depth == 8)
+      {
+          pp[i].red   = *entry_start++;
+          pp[i].green = *entry_start++;
+          pp[i].blue  = *entry_start++;
+          pp[i].alpha = *entry_start++;
+      }
+      else
+      {
+          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#endif
+
+   /* discard all chunk data except the name and stash that */
+   new_palette.name = (png_charp)chunkdata;
+
+   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+   png_free(png_ptr, chunkdata);
+   png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+void /* PRIVATE */
+png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+
+   png_debug(1, "in png_handle_tRNS\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before tRNS");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid tRNS after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+   {
+      png_warning(png_ptr, "Duplicate tRNS chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_byte buf[2];
+
+      if (length != 2)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      png_crc_read(png_ptr, buf, 2);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_values.gray = png_get_uint_16(buf);
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      png_byte buf[6];
+
+      if (length != 6)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      png_crc_read(png_ptr, buf, (png_size_t)length);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_values.red = png_get_uint_16(buf);
+      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
+      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (!(png_ptr->mode & PNG_HAVE_PLTE))
+      {
+         /* Should be an error, but we can cope with it. */
+         png_warning(png_ptr, "Missing PLTE before tRNS");
+      }
+      if (length > (png_uint_32)png_ptr->num_palette ||
+          length > PNG_MAX_PALETTE_LENGTH)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (length == 0)
+      {
+         png_warning(png_ptr, "Zero length tRNS chunk");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      png_crc_read(png_ptr, readbuf, (png_size_t)length);
+      png_ptr->num_trans = (png_uint_16)length;
+   }
+   else
+   {
+      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+      &(png_ptr->trans_values));
+}
+#endif
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+void /* PRIVATE */
+png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_size_t truelen;
+   png_byte buf[6];
+
+   png_debug(1, "in png_handle_bKGD\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before bKGD");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid bKGD after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+            !(png_ptr->mode & PNG_HAVE_PLTE))
+   {
+      png_warning(png_ptr, "Missing PLTE before bKGD");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
+   {
+      png_warning(png_ptr, "Duplicate bKGD chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      truelen = 1;
+   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      truelen = 6;
+   else
+      truelen = 2;
+
+   if (length != truelen)
+   {
+      png_warning(png_ptr, "Incorrect bKGD chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, truelen);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   /* We convert the index value into RGB components so that we can allow
+    * arbitrary RGB values for background when we have transparency, and
+    * so it is easy to determine the RGB values of the background color
+    * from the info_ptr struct. */
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      png_ptr->background.index = buf[0];
+      if(info_ptr->num_palette)
+      {
+          if(buf[0] > info_ptr->num_palette)
+          {
+             png_warning(png_ptr, "Incorrect bKGD chunk index value");
+             return;
+          }
+          png_ptr->background.red =
+             (png_uint_16)png_ptr->palette[buf[0]].red;
+          png_ptr->background.green =
+             (png_uint_16)png_ptr->palette[buf[0]].green;
+          png_ptr->background.blue =
+             (png_uint_16)png_ptr->palette[buf[0]].blue;
+      }
+   }
+   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
+   {
+      png_ptr->background.red =
+      png_ptr->background.green =
+      png_ptr->background.blue =
+      png_ptr->background.gray = png_get_uint_16(buf);
+   }
+   else
+   {
+      png_ptr->background.red = png_get_uint_16(buf);
+      png_ptr->background.green = png_get_uint_16(buf + 2);
+      png_ptr->background.blue = png_get_uint_16(buf + 4);
+   }
+
+   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
+}
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+void /* PRIVATE */
+png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   unsigned int num, i;
+   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+   png_debug(1, "in png_handle_hIST\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before hIST");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid hIST after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
+   {
+      png_warning(png_ptr, "Missing PLTE before hIST");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
+   {
+      png_warning(png_ptr, "Duplicate hIST chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   num = length / 2 ;
+   if (num != (unsigned int) png_ptr->num_palette || num >
+      (unsigned int) PNG_MAX_PALETTE_LENGTH)
+   {
+      png_warning(png_ptr, "Incorrect hIST chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[2];
+
+      png_crc_read(png_ptr, buf, 2);
+      readbuf[i] = png_get_uint_16(buf);
+   }
+
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+void /* PRIVATE */
+png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_uint_32 res_x, res_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_pHYs\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before pHYs");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid pHYs after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_warning(png_ptr, "Duplicate pHYs chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_warning(png_ptr, "Incorrect pHYs chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   res_x = png_get_uint_32(buf);
+   res_y = png_get_uint_32(buf + 4);
+   unit_type = buf[8];
+   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+void /* PRIVATE */
+png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_int_32 offset_x, offset_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_oFFs\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before oFFs");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid oFFs after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   {
+      png_warning(png_ptr, "Duplicate oFFs chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_warning(png_ptr, "Incorrect oFFs chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   offset_x = png_get_int_32(buf);
+   offset_y = png_get_int_32(buf + 4);
+   unit_type = buf[8];
+   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+/* read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_charp purpose;
+   png_int_32 X0, X1;
+   png_byte type, nparams;
+   png_charp buf, units, endptr;
+   png_charpp params;
+   png_size_t slength;
+   int i;
+
+   png_debug(1, "in png_handle_pCAL\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before pCAL");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid pCAL after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
+   {
+      png_warning(png_ptr, "Duplicate pCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
+      length + 1);
+   purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (purpose == NULL)
+     {
+       png_warning(png_ptr, "No memory for pCAL purpose.");
+       return;
+     }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)purpose, slength);
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, purpose);
+      return;
+   }
+
+   purpose[slength] = 0x00; /* null terminate the last string */
+
+   png_debug(3, "Finding end of pCAL purpose string\n");
+   for (buf = purpose; *buf; buf++)
+      /* empty loop */ ;
+
+   endptr = purpose + slength;
+
+   /* We need to have at least 12 bytes after the purpose string
+      in order to get the parameter information. */
+   if (endptr <= buf + 12)
+   {
+      png_warning(png_ptr, "Invalid pCAL data");
+      png_free(png_ptr, purpose);
+      return;
+   }
+
+   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
+   X0 = png_get_int_32((png_bytep)buf+1);
+   X1 = png_get_int_32((png_bytep)buf+5);
+   type = buf[9];
+   nparams = buf[10];
+   units = buf + 11;
+
+   png_debug(3, "Checking pCAL equation type and number of parameters\n");
+   /* Check that we have the right number of parameters for known
+      equation types. */
+   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+   {
+      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
+      png_free(png_ptr, purpose);
+      return;
+   }
+   else if (type >= PNG_EQUATION_LAST)
+   {
+      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+   }
+
+   for (buf = units; *buf; buf++)
+      /* Empty loop to move past the units string. */ ;
+
+   png_debug(3, "Allocating pCAL parameters array\n");
+   params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
+      *png_sizeof(png_charp))) ;
+   if (params == NULL)
+     {
+       png_free(png_ptr, purpose);
+       png_warning(png_ptr, "No memory for pCAL params.");
+       return;
+     }
+
+   /* Get pointers to the start of each parameter string. */
+   for (i = 0; i < (int)nparams; i++)
+   {
+      buf++; /* Skip the null string terminator from previous parameter. */
+
+      png_debug1(3, "Reading pCAL parameter %d\n", i);
+      for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
+         /* Empty loop to move past each parameter string */ ;
+
+      /* Make sure we haven't run out of data yet */
+      if (buf > endptr)
+      {
+         png_warning(png_ptr, "Invalid pCAL data");
+         png_free(png_ptr, purpose);
+         png_free(png_ptr, params);
+         return;
+      }
+   }
+
+   png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
+      units, params);
+
+   png_free(png_ptr, purpose);
+   png_free(png_ptr, params);
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+/* read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_charp buffer, ep;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   double width, height;
+   png_charp vp;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_charp swidth, sheight;
+#endif
+#endif
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sCAL\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sCAL");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sCAL after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+   {
+      png_warning(png_ptr, "Duplicate sCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
+      length + 1);
+   buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (buffer == NULL)
+     {
+       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
+       return;
+     }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)buffer, slength);
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, buffer);
+      return;
+   }
+
+   buffer[slength] = 0x00; /* null terminate the last string */
+
+   ep = buffer + 1;        /* skip unit byte */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   width = strtod(ep, &vp);
+   if (*vp)
+   {
+       png_warning(png_ptr, "malformed width string in sCAL chunk");
+       return;
+   }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+   if (swidth == NULL)
+     {
+       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
+       return;
+     }
+   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+   for (ep = buffer; *ep; ep++)
+      /* empty loop */ ;
+   ep++;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   height = strtod(ep, &vp);
+   if (*vp)
+   {
+       png_warning(png_ptr, "malformed height string in sCAL chunk");
+       return;
+   }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+   if (swidth == NULL)
+     {
+       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
+       return;
+     }
+   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+   if (buffer + slength < ep
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+      || width <= 0. || height <= 0.
+#endif
+      )
+   {
+      png_warning(png_ptr, "Invalid sCAL data");
+      png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+      png_free(png_ptr, swidth);
+      png_free(png_ptr, sheight);
+#endif
+      return;
+   }
+
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
+#endif
+#endif
+
+   png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+   png_free(png_ptr, swidth);
+   png_free(png_ptr, sheight);
+#endif
+}
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+void /* PRIVATE */
+png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[7];
+   png_time mod_time;
+
+   png_debug(1, "in png_handle_tIME\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Out of place tIME chunk");
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
+   {
+      png_warning(png_ptr, "Duplicate tIME chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+   if (length != 7)
+   {
+      png_warning(png_ptr, "Incorrect tIME chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 7);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   mod_time.second = buf[6];
+   mod_time.minute = buf[5];
+   mod_time.hour = buf[4];
+   mod_time.day = buf[3];
+   mod_time.month = buf[2];
+   mod_time.year = png_get_uint_16(buf);
+
+   png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp key;
+   png_charp text;
+   png_uint_32 skip = 0;
+   png_size_t slength;
+   int ret;
+
+   png_debug(1, "in png_handle_tEXt\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before tEXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   key = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (key == NULL)
+   {
+     png_warning(png_ptr, "No memory to process text chunk.");
+     return;
+   }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)key, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, key);
+      return;
+   }
+
+   key[slength] = 0x00;
+
+   for (text = key; *text; text++)
+      /* empty loop to find end of key */ ;
+
+   if (text != key + slength)
+      text++;
+
+   text_ptr = (png_textp)png_malloc_warn(png_ptr,
+      (png_uint_32)png_sizeof(png_text));
+   if (text_ptr == NULL)
+   {
+     png_warning(png_ptr, "Not enough memory to process text chunk.");
+     png_free(png_ptr, key);
+     return;
+   }
+   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr->lang = NULL;
+   text_ptr->lang_key = NULL;
+   text_ptr->itxt_length = 0;
+#endif
+   text_ptr->text = text;
+   text_ptr->text_length = png_strlen(text);
+
+   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, key);
+   png_free(png_ptr, text_ptr);
+   if (ret)
+     png_warning(png_ptr, "Insufficient memory to process text chunk.");
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp chunkdata;
+   png_charp text;
+   int comp_type;
+   int ret;
+   png_size_t slength, prefix_len, data_len;
+
+   png_debug(1, "in png_handle_zTXt\n");
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before zTXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We will no doubt have problems with chunks even half this size, but
+      there is no hard and fast rule to tell us where to stop. */
+   if (length > (png_uint_32)65535L)
+   {
+     png_warning(png_ptr,"zTXt chunk too large to fit in memory");
+     png_crc_finish(png_ptr, length);
+     return;
+   }
+#endif
+
+   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (chunkdata == NULL)
+   {
+     png_warning(png_ptr,"Out of memory processing zTXt chunk.");
+     return;
+   }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (text = chunkdata; *text; text++)
+      /* empty loop */ ;
+
+   /* zTXt must have some text after the chunkdataword */
+   if (text == chunkdata + slength)
+   {
+      comp_type = PNG_TEXT_COMPRESSION_NONE;
+      png_warning(png_ptr, "Zero length zTXt chunk");
+   }
+   else
+   {
+       comp_type = *(++text);
+       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
+       {
+          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
+          comp_type = PNG_TEXT_COMPRESSION_zTXt;
+       }
+       text++;        /* skip the compression_method byte */
+   }
+   prefix_len = text - chunkdata;
+
+   chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
+                                    (png_size_t)length, prefix_len, &data_len);
+
+   text_ptr = (png_textp)png_malloc_warn(png_ptr,
+     (png_uint_32)png_sizeof(png_text));
+   if (text_ptr == NULL)
+   {
+     png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
+     png_free(png_ptr, chunkdata);
+     return;
+   }
+   text_ptr->compression = comp_type;
+   text_ptr->key = chunkdata;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr->lang = NULL;
+   text_ptr->lang_key = NULL;
+   text_ptr->itxt_length = 0;
+#endif
+   text_ptr->text = chunkdata + prefix_len;
+   text_ptr->text_length = data_len;
+
+   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, text_ptr);
+   png_free(png_ptr, chunkdata);
+   if (ret)
+     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp chunkdata;
+   png_charp key, lang, text, lang_key;
+   int comp_flag;
+   int comp_type = 0;
+   int ret;
+   png_size_t slength, prefix_len, data_len;
+
+   png_debug(1, "in png_handle_iTXt\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iTXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We will no doubt have problems with chunks even half this size, but
+      there is no hard and fast rule to tell us where to stop. */
+   if (length > (png_uint_32)65535L)
+   {
+     png_warning(png_ptr,"iTXt chunk too large to fit in memory");
+     png_crc_finish(png_ptr, length);
+     return;
+   }
+#endif
+
+   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (chunkdata == NULL)
+   {
+     png_warning(png_ptr, "No memory to process iTXt chunk.");
+     return;
+   }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (lang = chunkdata; *lang; lang++)
+      /* empty loop */ ;
+   lang++;        /* skip NUL separator */
+
+   /* iTXt must have a language tag (possibly empty), two compression bytes,
+      translated keyword (possibly empty), and possibly some text after the
+      keyword */
+
+   if (lang >= chunkdata + slength)
+   {
+      comp_flag = PNG_TEXT_COMPRESSION_NONE;
+      png_warning(png_ptr, "Zero length iTXt chunk");
+   }
+   else
+   {
+       comp_flag = *lang++;
+       comp_type = *lang++;
+   }
+
+   for (lang_key = lang; *lang_key; lang_key++)
+      /* empty loop */ ;
+   lang_key++;        /* skip NUL separator */
+
+   for (text = lang_key; *text; text++)
+      /* empty loop */ ;
+   text++;        /* skip NUL separator */
+
+   prefix_len = text - chunkdata;
+
+   key=chunkdata;
+   if (comp_flag)
+       chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
+          (size_t)length, prefix_len, &data_len);
+   else
+       data_len=png_strlen(chunkdata + prefix_len);
+   text_ptr = (png_textp)png_malloc_warn(png_ptr,
+      (png_uint_32)png_sizeof(png_text));
+   if (text_ptr == NULL)
+   {
+     png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
+     png_free(png_ptr, chunkdata);
+     return;
+   }
+   text_ptr->compression = (int)comp_flag + 1;
+   text_ptr->lang_key = chunkdata+(lang_key-key);
+   text_ptr->lang = chunkdata+(lang-key);
+   text_ptr->itxt_length = data_len;
+   text_ptr->text_length = 0;
+   text_ptr->key = chunkdata;
+   text_ptr->text = chunkdata + prefix_len;
+
+   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, text_ptr);
+   png_free(png_ptr, chunkdata);
+   if (ret)
+     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
+}
+#endif
+
+/* This function is called when we haven't found a handler for a
+   chunk.  If there isn't a problem with the chunk itself (ie bad
+   chunk name, CRC, or a critical chunk), the chunk is silently ignored
+   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
+   case it will be saved away to be written out later. */
+void /* PRIVATE */
+png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_uint_32 skip = 0;
+
+   png_debug(1, "in png_handle_unknown\n");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IDAT;
+#endif
+      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* not an IDAT */
+         png_ptr->mode |= PNG_AFTER_IDAT;
+   }
+
+   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+   if (!(png_ptr->chunk_name[0] & 0x20))
+   {
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+      if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+           PNG_HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+           && png_ptr->read_user_chunk_fn == NULL
+#endif
+        )
+#endif
+          png_chunk_error(png_ptr, "unknown critical chunk");
+   }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+   {
+       png_unknown_chunk chunk;
+
+#ifdef PNG_MAX_MALLOC_64K
+       if (length > (png_uint_32)65535L)
+       {
+           png_warning(png_ptr, "unknown chunk too large to fit in memory");
+           skip = length - (png_uint_32)65535L;
+           length = (png_uint_32)65535L;
+       }
+#endif
+       png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
+       chunk.data = (png_bytep)png_malloc(png_ptr, length);
+       chunk.size = (png_size_t)length;
+       png_crc_read(png_ptr, (png_bytep)chunk.data, length);
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+       if(png_ptr->read_user_chunk_fn != NULL)
+       {
+          /* callback to user unknown chunk handler */
+          if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
+          {
+             if (!(png_ptr->chunk_name[0] & 0x20))
+                if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+                     PNG_HANDLE_CHUNK_ALWAYS)
+                 {
+                   png_free(png_ptr, chunk.data);
+                   png_chunk_error(png_ptr, "unknown critical chunk");
+                 }
+             png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+          }
+       }
+       else
+#endif
+          png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+       png_free(png_ptr, chunk.data);
+   }
+   else
+#endif
+      skip = length;
+
+   png_crc_finish(png_ptr, skip);
+
+#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+   if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
+      return;
+#endif
+}
+
+/* This function is called to verify that a chunk name is valid.
+   This function can't have the "critical chunk check" incorporated
+   into it, since in the future we will need to be able to call user
+   functions to handle unknown critical chunks after we check that
+   the chunk name itself is valid. */
+
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+
+void /* PRIVATE */
+png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
+{
+   png_debug(1, "in png_check_chunk_name\n");
+   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
+       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
+   {
+      png_chunk_error(png_ptr, "invalid chunk type");
+   }
+}
+
+/* Combines the row recently read in with the existing pixels in the
+   row.  This routine takes care of alpha and transparency if requested.
+   This routine also handles the two methods of progressive display
+   of interlaced images, depending on the mask value.
+   The mask value describes which pixels are to be combined with
+   the row.  The pattern always repeats every 8 pixels, so just 8
+   bits are needed.  A one indicates the pixel is to be combined,
+   a zero indicates the pixel is to be skipped.  This is in addition
+   to any alpha or transparency value associated with the pixel.  If
+   you want all pixels to be combined, pass 0xff (255) in mask.  */
+#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int mask)
+{
+   png_debug(1,"in png_combine_row\n");
+   if (mask == 0xff)
+   {
+      png_memcpy(row, png_ptr->row_buf + 1,
+         PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
+   }
+   else
+   {
+      switch (png_ptr->row_info.pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            int s_inc, s_start, s_end;
+            int m = 0x80;
+            int shift;
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+                s_start = 0;
+                s_end = 7;
+                s_inc = 1;
+            }
+            else
+#endif
+            {
+                s_start = 7;
+                s_end = 0;
+                s_inc = -1;
+            }
+
+            shift = s_start;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  int value;
+
+                  value = (*sp >> shift) & 0x01;
+                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            int s_start, s_end, s_inc;
+            int m = 0x80;
+            int shift;
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+            int value;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+               s_start = 0;
+               s_end = 6;
+               s_inc = 2;
+            }
+            else
+#endif
+            {
+               s_start = 6;
+               s_end = 0;
+               s_inc = -2;
+            }
+
+            shift = s_start;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  value = (*sp >> shift) & 0x03;
+                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            int s_start, s_end, s_inc;
+            int m = 0x80;
+            int shift;
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+            int value;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+               s_start = 0;
+               s_end = 4;
+               s_inc = 4;
+            }
+            else
+#endif
+            {
+               s_start = 4;
+               s_end = 0;
+               s_inc = -4;
+            }
+            shift = s_start;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  value = (*sp >> shift) & 0xf;
+                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         default:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+            png_byte m = 0x80;
+
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  png_memcpy(dp, sp, pixel_bytes);
+               }
+
+               sp += pixel_bytes;
+               dp += pixel_bytes;
+
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+      }
+   }
+}
+#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE   /* else in pngvcrd.c, pnggccrd.c */
+/* OLD pre-1.0.9 interface:
+void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+   png_uint_32 transformations)
+ */
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+   png_row_infop row_info = &(png_ptr->row_info);
+   png_bytep row = png_ptr->row_buf + 1;
+   int pass = png_ptr->pass;
+   png_uint_32 transformations = png_ptr->transformations;
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+   png_debug(1,"in png_do_read_interlace (stock C version)\n");
+   if (row != NULL && row_info != NULL)
+   {
+      png_uint_32 final_width;
+
+      final_width = row_info->width * png_pass_inc[pass];
+
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            int jstop = png_pass_inc[pass];
+            png_byte v;
+            png_uint_32 i;
+            int j;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (transformations & PNG_PACKSWAP)
+            {
+                sshift = (int)((row_info->width + 7) & 0x07);
+                dshift = (int)((final_width + 7) & 0x07);
+                s_start = 7;
+                s_end = 0;
+                s_inc = -1;
+            }
+            else
+#endif
+            {
+                sshift = 7 - (int)((row_info->width + 7) & 0x07);
+                dshift = 7 - (int)((final_width + 7) & 0x07);
+                s_start = 0;
+                s_end = 7;
+                s_inc = 1;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               v = (png_byte)((*sp >> sshift) & 0x01);
+               for (j = 0; j < jstop; j++)
+               {
+                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            int jstop = png_pass_inc[pass];
+            png_uint_32 i;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (transformations & PNG_PACKSWAP)
+            {
+               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+               dshift = (int)(((final_width + 3) & 0x03) << 1);
+               s_start = 6;
+               s_end = 0;
+               s_inc = -2;
+            }
+            else
+#endif
+            {
+               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+               s_start = 0;
+               s_end = 6;
+               s_inc = 2;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v;
+               int j;
+
+               v = (png_byte)((*sp >> sshift) & 0x03);
+               for (j = 0; j < jstop; j++)
+               {
+                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            png_uint_32 i;
+            int jstop = png_pass_inc[pass];
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (transformations & PNG_PACKSWAP)
+            {
+               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+               dshift = (int)(((final_width + 1) & 0x01) << 2);
+               s_start = 4;
+               s_end = 0;
+               s_inc = -4;
+            }
+            else
+#endif
+            {
+               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+               s_start = 0;
+               s_end = 4;
+               s_inc = 4;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
+               int j;
+
+               for (j = 0; j < jstop; j++)
+               {
+                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         default:
+         {
+            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+            png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
+            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+            int jstop = png_pass_inc[pass];
+            png_uint_32 i;
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v[8];
+               int j;
+
+               png_memcpy(v, sp, pixel_bytes);
+               for (j = 0; j < jstop; j++)
+               {
+                  png_memcpy(dp, v, pixel_bytes);
+                  dp -= pixel_bytes;
+               }
+               sp -= pixel_bytes;
+            }
+            break;
+         }
+      }
+      row_info->width = final_width;
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
+   }
+#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if (&transformations == NULL) /* silence compiler warning */
+      return;
+#endif
+}
+#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+void /* PRIVATE */
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
+   png_bytep prev_row, int filter)
+{
+   png_debug(1, "in png_read_filter_row\n");
+   png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
+   switch (filter)
+   {
+      case PNG_FILTER_VALUE_NONE:
+         break;
+      case PNG_FILTER_VALUE_SUB:
+      {
+         png_uint_32 i;
+         png_uint_32 istop = row_info->rowbytes;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+         png_bytep rp = row + bpp;
+         png_bytep lp = row;
+
+         for (i = bpp; i < istop; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_UP:
+      {
+         png_uint_32 i;
+         png_uint_32 istop = row_info->rowbytes;
+         png_bytep rp = row;
+         png_bytep pp = prev_row;
+
+         for (i = 0; i < istop; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_AVG:
+      {
+         png_uint_32 i;
+         png_bytep rp = row;
+         png_bytep pp = prev_row;
+         png_bytep lp = row;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+         png_uint_32 istop = row_info->rowbytes - bpp;
+
+         for (i = 0; i < bpp; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) +
+               ((int)(*pp++) / 2 )) & 0xff);
+            rp++;
+         }
+
+         for (i = 0; i < istop; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) +
+               (int)(*pp++ + *lp++) / 2 ) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_PAETH:
+      {
+         png_uint_32 i;
+         png_bytep rp = row;
+         png_bytep pp = prev_row;
+         png_bytep lp = row;
+         png_bytep cp = prev_row;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+         png_uint_32 istop=row_info->rowbytes - bpp;
+
+         for (i = 0; i < bpp; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+            rp++;
+         }
+
+         for (i = 0; i < istop; i++)   /* use leftover rp,pp */
+         {
+            int a, b, c, pa, pb, pc, p;
+
+            a = *lp++;
+            b = *pp++;
+            c = *cp++;
+
+            p = b - c;
+            pc = a - c;
+
+#ifdef PNG_USE_ABS
+            pa = abs(p);
+            pb = abs(pc);
+            pc = abs(p + pc);
+#else
+            pa = p < 0 ? -p : p;
+            pb = pc < 0 ? -pc : pc;
+            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+            /*
+               if (pa <= pb && pa <= pc)
+                  p = a;
+               else if (pb <= pc)
+                  p = b;
+               else
+                  p = c;
+             */
+
+            p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      default:
+         png_warning(png_ptr, "Ignoring bad adaptive filter type");
+         *row=0;
+         break;
+   }
+}
+#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
+
+void /* PRIVATE */
+png_read_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   png_debug(1, "in png_read_finish_row\n");
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+      do
+      {
+         png_ptr->pass++;
+         if (png_ptr->pass >= 7)
+            break;
+         png_ptr->iwidth = (png_ptr->width +
+            png_pass_inc[png_ptr->pass] - 1 -
+            png_pass_start[png_ptr->pass]) /
+            png_pass_inc[png_ptr->pass];
+
+         png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
+            png_ptr->iwidth) + 1;
+
+         if (!(png_ptr->transformations & PNG_INTERLACE))
+         {
+            png_ptr->num_rows = (png_ptr->height +
+               png_pass_yinc[png_ptr->pass] - 1 -
+               png_pass_ystart[png_ptr->pass]) /
+               png_pass_yinc[png_ptr->pass];
+            if (!(png_ptr->num_rows))
+               continue;
+         }
+         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
+            break;
+      } while (png_ptr->iwidth == 0);
+
+      if (png_ptr->pass < 7)
+         return;
+   }
+
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IDAT;
+#endif
+      char extra;
+      int ret;
+
+      png_ptr->zstream.next_out = (Byte *)&extra;
+      png_ptr->zstream.avail_out = (uInt)1;
+      for(;;)
+      {
+         if (!(png_ptr->zstream.avail_in))
+         {
+            while (!png_ptr->idat_size)
+            {
+               png_byte chunk_length[4];
+
+               png_crc_finish(png_ptr, 0);
+
+               png_read_data(png_ptr, chunk_length, 4);
+               png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
+               png_reset_crc(png_ptr);
+               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+               if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+                  png_error(png_ptr, "Not enough image data");
+
+            }
+            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+            png_ptr->zstream.next_in = png_ptr->zbuf;
+            if (png_ptr->zbuf_size > png_ptr->idat_size)
+               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
+            png_ptr->idat_size -= png_ptr->zstream.avail_in;
+         }
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret == Z_STREAM_END)
+         {
+            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
+               png_ptr->idat_size)
+               png_warning(png_ptr, "Extra compressed data");
+            png_ptr->mode |= PNG_AFTER_IDAT;
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            break;
+         }
+         if (ret != Z_OK)
+            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+                      "Decompression Error");
+
+         if (!(png_ptr->zstream.avail_out))
+         {
+            png_warning(png_ptr, "Extra compressed data.");
+            png_ptr->mode |= PNG_AFTER_IDAT;
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            break;
+         }
+
+      }
+      png_ptr->zstream.avail_out = 0;
+   }
+
+   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
+      png_warning(png_ptr, "Extra compression data");
+
+   inflateReset(&png_ptr->zstream);
+
+   png_ptr->mode |= PNG_AFTER_IDAT;
+}
+
+void /* PRIVATE */
+png_read_start_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   int max_pixel_depth;
+   png_uint_32 row_bytes;
+
+   png_debug(1, "in png_read_start_row\n");
+   png_ptr->zstream.avail_in = 0;
+   png_init_read_transformations(png_ptr);
+   if (png_ptr->interlaced)
+   {
+      if (!(png_ptr->transformations & PNG_INTERLACE))
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+            png_pass_ystart[0]) / png_pass_yinc[0];
+      else
+         png_ptr->num_rows = png_ptr->height;
+
+      png_ptr->iwidth = (png_ptr->width +
+         png_pass_inc[png_ptr->pass] - 1 -
+         png_pass_start[png_ptr->pass]) /
+         png_pass_inc[png_ptr->pass];
+
+         row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
+
+         png_ptr->irowbytes = (png_size_t)row_bytes;
+         if((png_uint_32)png_ptr->irowbytes != row_bytes)
+            png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
+   }
+   else
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->iwidth = png_ptr->width;
+      png_ptr->irowbytes = png_ptr->rowbytes + 1;
+   }
+   max_pixel_depth = png_ptr->pixel_depth;
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
+      max_pixel_depth = 8;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (png_ptr->num_trans)
+            max_pixel_depth = 32;
+         else
+            max_pixel_depth = 24;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (max_pixel_depth < 8)
+            max_pixel_depth = 8;
+         if (png_ptr->num_trans)
+            max_pixel_depth *= 2;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (png_ptr->num_trans)
+         {
+            max_pixel_depth *= 4;
+            max_pixel_depth /= 3;
+         }
+      }
+   }
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & (PNG_FILLER))
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         max_pixel_depth = 32;
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (max_pixel_depth <= 8)
+            max_pixel_depth = 16;
+         else
+            max_pixel_depth = 32;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (max_pixel_depth <= 32)
+            max_pixel_depth = 32;
+         else
+            max_pixel_depth = 64;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+   {
+      if (
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
+#endif
+#if defined(PNG_READ_FILLER_SUPPORTED)
+        (png_ptr->transformations & (PNG_FILLER)) ||
+#endif
+        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (max_pixel_depth <= 16)
+            max_pixel_depth = 32;
+         else
+            max_pixel_depth = 64;
+      }
+      else
+      {
+         if (max_pixel_depth <= 8)
+           {
+             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+               max_pixel_depth = 32;
+             else
+               max_pixel_depth = 24;
+           }
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            max_pixel_depth = 64;
+         else
+            max_pixel_depth = 48;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   if(png_ptr->transformations & PNG_USER_TRANSFORM)
+     {
+       int user_pixel_depth=png_ptr->user_transform_depth*
+         png_ptr->user_transform_channels;
+       if(user_pixel_depth > max_pixel_depth)
+         max_pixel_depth=user_pixel_depth;
+     }
+#endif
+
+   /* align the width on the next larger 8 pixels.  Mainly used
+      for interlacing */
+   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+   /* calculate the maximum bytes needed, adding a byte and a pixel
+      for safety's sake */
+   row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
+      1 + ((max_pixel_depth + 7) >> 3);
+#ifdef PNG_MAX_MALLOC_64K
+   if (row_bytes > (png_uint_32)65536L)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+   png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
+   png_ptr->row_buf = png_ptr->big_row_buf+32;
+#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
+   png_ptr->row_buf_size = row_bytes;
+#endif
+
+#ifdef PNG_MAX_MALLOC_64K
+   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+   if ((png_uint_32)png_ptr->rowbytes + 1 > PNG_SIZE_MAX)
+      png_error(png_ptr, "Row has too many bytes to allocate in memory.");
+   png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
+      png_ptr->rowbytes + 1));
+
+   png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+   png_debug1(3, "width = %lu,\n", png_ptr->width);
+   png_debug1(3, "height = %lu,\n", png_ptr->height);
+   png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
+   png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
+   png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
+   png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
+
+   png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
diff --git a/Utilities/FLTK/png/pngset.c b/Utilities/FLTK/png/pngset.c
new file mode 100644
index 0000000000000000000000000000000000000000..39c5bfa7009df4e3fba8eb6ff8e5e9cdb147e28b
--- /dev/null
+++ b/Utilities/FLTK/png/pngset.c
@@ -0,0 +1,1219 @@
+
+/* pngset.c - storage of image information into info struct
+ *
+ * libpng 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file.  This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_bKGD_SUPPORTED)
+void PNGAPI
+png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
+{
+   png_debug1(1, "in %s storage function\n", "bKGD");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
+   info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
+   double white_x, double white_y, double red_x, double red_y,
+   double green_x, double green_y, double blue_x, double blue_y)
+{
+   png_debug1(1, "in %s storage function\n", "cHRM");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (white_x < 0.0 || white_y < 0.0 ||
+         red_x < 0.0 ||   red_y < 0.0 ||
+       green_x < 0.0 || green_y < 0.0 ||
+        blue_x < 0.0 ||  blue_y < 0.0)
+   {
+      png_warning(png_ptr,
+        "Ignoring attempt to set negative chromaticity value");
+      return;
+   }
+   if (white_x > 21474.83 || white_y > 21474.83 ||
+         red_x > 21474.83 ||   red_y > 21474.83 ||
+       green_x > 21474.83 || green_y > 21474.83 ||
+        blue_x > 21474.83 ||  blue_y > 21474.83)
+   {
+      png_warning(png_ptr,
+        "Ignoring attempt to set chromaticity value exceeding 21474.83");
+      return;
+   }
+
+   info_ptr->x_white = (float)white_x;
+   info_ptr->y_white = (float)white_y;
+   info_ptr->x_red   = (float)red_x;
+   info_ptr->y_red   = (float)red_y;
+   info_ptr->x_green = (float)green_x;
+   info_ptr->y_green = (float)green_y;
+   info_ptr->x_blue  = (float)blue_x;
+   info_ptr->y_blue  = (float)blue_y;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
+   info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
+   info_ptr->int_x_red   = (png_fixed_point)(  red_x*100000.+0.5);
+   info_ptr->int_y_red   = (png_fixed_point)(  red_y*100000.+0.5);
+   info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
+   info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
+   info_ptr->int_x_blue  = (png_fixed_point)( blue_x*100000.+0.5);
+   info_ptr->int_y_blue  = (png_fixed_point)( blue_y*100000.+0.5);
+#endif
+   info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+   png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+   png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+   png_fixed_point blue_x, png_fixed_point blue_y)
+{
+   png_debug1(1, "in %s storage function\n", "cHRM");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (white_x < 0 || white_y < 0 ||
+         red_x < 0 ||   red_y < 0 ||
+       green_x < 0 || green_y < 0 ||
+        blue_x < 0 ||  blue_y < 0)
+   {
+      png_warning(png_ptr,
+        "Ignoring attempt to set negative chromaticity value");
+      return;
+   }
+   if (white_x > (double) PNG_UINT_31_MAX ||
+       white_y > (double) PNG_UINT_31_MAX ||
+         red_x > (double) PNG_UINT_31_MAX ||
+         red_y > (double) PNG_UINT_31_MAX ||
+       green_x > (double) PNG_UINT_31_MAX ||
+       green_y > (double) PNG_UINT_31_MAX ||
+        blue_x > (double) PNG_UINT_31_MAX ||
+        blue_y > (double) PNG_UINT_31_MAX)
+   {
+      png_warning(png_ptr,
+        "Ignoring attempt to set chromaticity value exceeding 21474.83");
+      return;
+   }
+   info_ptr->int_x_white = white_x;
+   info_ptr->int_y_white = white_y;
+   info_ptr->int_x_red   = red_x;
+   info_ptr->int_y_red   = red_y;
+   info_ptr->int_x_green = green_x;
+   info_ptr->int_y_green = green_y;
+   info_ptr->int_x_blue  = blue_x;
+   info_ptr->int_y_blue  = blue_y;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   info_ptr->x_white = (float)(white_x/100000.);
+   info_ptr->y_white = (float)(white_y/100000.);
+   info_ptr->x_red   = (float)(  red_x/100000.);
+   info_ptr->y_red   = (float)(  red_y/100000.);
+   info_ptr->x_green = (float)(green_x/100000.);
+   info_ptr->y_green = (float)(green_y/100000.);
+   info_ptr->x_blue  = (float)( blue_x/100000.);
+   info_ptr->y_blue  = (float)( blue_y/100000.);
+#endif
+   info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
+{
+   double gamma;
+   png_debug1(1, "in %s storage function\n", "gAMA");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* Check for overflow */
+   if (file_gamma > 21474.83)
+   {
+      png_warning(png_ptr, "Limiting gamma to 21474.83");
+      gamma=21474.83;
+   }
+   else
+      gamma=file_gamma;
+   info_ptr->gamma = (float)gamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_gamma = (int)(gamma*100000.+.5);
+#endif
+   info_ptr->valid |= PNG_INFO_gAMA;
+   if(gamma == 0.0)
+      png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+void PNGAPI
+png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
+   int_gamma)
+{
+   png_fixed_point gamma;
+
+   png_debug1(1, "in %s storage function\n", "gAMA");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
+   {
+     png_warning(png_ptr, "Limiting gamma to 21474.83");
+     gamma=PNG_UINT_31_MAX;
+   }
+   else
+   {
+     if (int_gamma < 0)
+     {
+       png_warning(png_ptr, "Setting negative gamma to zero");
+       gamma=0;
+     }
+     else
+       gamma=int_gamma;
+   }
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   info_ptr->gamma = (float)(gamma/100000.);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_gamma = gamma;
+#endif
+   info_ptr->valid |= PNG_INFO_gAMA;
+   if(gamma == 0)
+      png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+void PNGAPI
+png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function\n", "hIST");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+   if (info_ptr->num_palette == 0)
+   {
+       png_warning(png_ptr,
+          "Palette size 0, hIST allocation skipped.");
+       return;
+   }
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+#endif
+   /* Changed from info->num_palette to 256 in version 1.2.1 */
+   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
+      (png_uint_32)(256 * png_sizeof (png_uint_16)));
+   if (png_ptr->hist == NULL)
+     {
+       png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
+       return;
+     }
+
+   for (i = 0; i < info_ptr->num_palette; i++)
+       png_ptr->hist[i] = hist[i];
+   info_ptr->hist = png_ptr->hist;
+   info_ptr->valid |= PNG_INFO_hIST;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_HIST;
+#else
+   png_ptr->flags |= PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_type, int compression_type,
+   int filter_type)
+{
+   png_debug1(1, "in %s storage function\n", "IHDR");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* check for width and height valid values */
+   if (width == 0 || height == 0)
+      png_error(png_ptr, "Image width or height is zero in IHDR");
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
+      png_error(png_ptr, "image size exceeds user limits in IHDR");
+#else
+   if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
+      png_error(png_ptr, "image size exceeds user limits in IHDR");
+#endif
+   if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
+      png_error(png_ptr, "Invalid image size in IHDR");
+   if ( width > (PNG_UINT_32_MAX
+                 >> 3)      /* 8-byte RGBA pixels */
+                 - 64       /* bigrowbuf hack */
+                 - 1        /* filter byte */
+                 - 7*8      /* rounding of width to multiple of 8 pixels */
+                 - 8)       /* extra max_pixel_depth pad */
+      png_warning(png_ptr, "Width is too large for libpng to process pixels");
+
+   /* check other values */
+   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+      bit_depth != 8 && bit_depth != 16)
+      png_error(png_ptr, "Invalid bit depth in IHDR");
+
+   if (color_type < 0 || color_type == 1 ||
+      color_type == 5 || color_type > 6)
+      png_error(png_ptr, "Invalid color type in IHDR");
+
+   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+       ((color_type == PNG_COLOR_TYPE_RGB ||
+         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+      png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
+
+   if (interlace_type >= PNG_INTERLACE_LAST)
+      png_error(png_ptr, "Unknown interlace method in IHDR");
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+      png_error(png_ptr, "Unknown compression method in IHDR");
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   /* Accept filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not read a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
+      png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
+   if(filter_type != PNG_FILTER_TYPE_BASE)
+   {
+     if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+        (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+        ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+        (color_type == PNG_COLOR_TYPE_RGB || 
+         color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+        png_error(png_ptr, "Unknown filter method in IHDR");
+     if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
+        png_warning(png_ptr, "Invalid filter method in IHDR");
+   }
+#else
+   if(filter_type != PNG_FILTER_TYPE_BASE)
+      png_error(png_ptr, "Unknown filter method in IHDR");
+#endif
+
+   info_ptr->width = width;
+   info_ptr->height = height;
+   info_ptr->bit_depth = (png_byte)bit_depth;
+   info_ptr->color_type =(png_byte) color_type;
+   info_ptr->compression_type = (png_byte)compression_type;
+   info_ptr->filter_type = (png_byte)filter_type;
+   info_ptr->interlace_type = (png_byte)interlace_type;
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      info_ptr->channels = 3;
+   else
+      info_ptr->channels = 1;
+   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+      info_ptr->channels++;
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+   /* check for potential overflow */
+   if ( width > (PNG_UINT_32_MAX
+                 >> 3)      /* 8-byte RGBA pixels */
+                 - 64       /* bigrowbuf hack */
+                 - 1        /* filter byte */
+                 - 7*8      /* rounding of width to multiple of 8 pixels */
+                 - 8)       /* extra max_pixel_depth pad */
+      info_ptr->rowbytes = (png_size_t)0;
+   else
+      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width);
+}
+
+#if defined(PNG_oFFs_SUPPORTED)
+void PNGAPI
+png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
+   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function\n", "oFFs");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_offset = offset_x;
+   info_ptr->y_offset = offset_y;
+   info_ptr->offset_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+void PNGAPI
+png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
+   png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+   png_charp units, png_charpp params)
+{
+   png_uint_32 length;
+   int i;
+
+   png_debug1(1, "in %s storage function\n", "pCAL");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   length = png_strlen(purpose) + 1;
+   png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
+   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->pcal_purpose == NULL)
+     {
+       png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
+       return;
+     }
+   png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
+
+   png_debug(3, "storing X0, X1, type, and nparams in info\n");
+   info_ptr->pcal_X0 = X0;
+   info_ptr->pcal_X1 = X1;
+   info_ptr->pcal_type = (png_byte)type;
+   info_ptr->pcal_nparams = (png_byte)nparams;
+
+   length = png_strlen(units) + 1;
+   png_debug1(3, "allocating units for info (%lu bytes)\n", length);
+   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->pcal_units == NULL)
+     {
+       png_warning(png_ptr, "Insufficient memory for pCAL units.");
+       return;
+     }
+   png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
+
+   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
+      (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
+   if (info_ptr->pcal_params == NULL)
+     {
+       png_warning(png_ptr, "Insufficient memory for pCAL params.");
+       return;
+     }
+
+   info_ptr->pcal_params[nparams] = NULL;
+
+   for (i = 0; i < nparams; i++)
+   {
+      length = png_strlen(params[i]) + 1;
+      png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
+      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+      if (info_ptr->pcal_params[i] == NULL)
+        {
+          png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
+          return;
+        }
+      png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
+   }
+
+   info_ptr->valid |= PNG_INFO_pCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_PCAL;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
+             int unit, double width, double height)
+{
+   png_debug1(1, "in %s storage function\n", "sCAL");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->scal_unit = (png_byte)unit;
+   info_ptr->scal_pixel_width = width;
+   info_ptr->scal_pixel_height = height;
+
+   info_ptr->valid |= PNG_INFO_sCAL;
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+             int unit, png_charp swidth, png_charp sheight)
+{
+   png_uint_32 length;
+
+   png_debug1(1, "in %s storage function\n", "sCAL");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->scal_unit = (png_byte)unit;
+
+   length = png_strlen(swidth) + 1;
+   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->scal_s_width == NULL)
+   {
+      png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
+   }
+   png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
+
+   length = png_strlen(sheight) + 1;
+   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->scal_s_height == NULL)
+   {
+      png_free (png_ptr, info_ptr->scal_s_width);
+      png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
+   }
+   png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
+
+   info_ptr->valid |= PNG_INFO_sCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_SCAL;
+#endif
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+void PNGAPI
+png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function\n", "pHYs");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_pixels_per_unit = res_x;
+   info_ptr->y_pixels_per_unit = res_y;
+   info_ptr->phys_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
+   png_colorp palette, int num_palette)
+{
+
+   png_debug1(1, "in %s storage function\n", "PLTE");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /*
+    * It may not actually be necessary to set png_ptr->palette here;
+    * we do it for backward compatibility with the way the png_handle_tRNS
+    * function used to do the allocation.
+    */
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+#endif
+
+   /* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries,
+      in case of an invalid PNG file that has too-large sample values. */
+   png_ptr->palette = (png_colorp)png_malloc(png_ptr,
+      256 * png_sizeof(png_color));
+   png_memset(png_ptr->palette, 0, 256 * png_sizeof(png_color));
+   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color));
+   info_ptr->palette = png_ptr->palette;
+   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_PLTE;
+#else
+   png_ptr->flags |= PNG_FLAG_FREE_PLTE;
+#endif
+
+   info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#if defined(PNG_sBIT_SUPPORTED)
+void PNGAPI
+png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
+   png_color_8p sig_bit)
+{
+   png_debug1(1, "in %s storage function\n", "sBIT");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8));
+   info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+void PNGAPI
+png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
+{
+   png_debug1(1, "in %s storage function\n", "sRGB");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->srgb_intent = (png_byte)intent;
+   info_ptr->valid |= PNG_INFO_sRGB;
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
+   int intent)
+{
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float file_gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_fixed_point int_file_gamma;
+#endif
+#endif
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+      int_green_y, int_blue_x, int_blue_y;
+#endif
+#endif
+   png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_set_sRGB(png_ptr, info_ptr, intent);
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   file_gamma = (float).45455;
+   png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   int_file_gamma = 45455L;
+   png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
+#endif
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   int_white_x = 31270L;
+   int_white_y = 32900L;
+   int_red_x   = 64000L;
+   int_red_y   = 33000L;
+   int_green_x = 30000L;
+   int_green_y = 60000L;
+   int_blue_x  = 15000L;
+   int_blue_y  =  6000L;
+
+   png_set_cHRM_fixed(png_ptr, info_ptr,
+      int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
+      int_blue_x, int_blue_y);
+#endif
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   white_x = (float).3127;
+   white_y = (float).3290;
+   red_x   = (float).64;
+   red_y   = (float).33;
+   green_x = (float).30;
+   green_y = (float).60;
+   blue_x  = (float).15;
+   blue_y  = (float).06;
+
+   png_set_cHRM(png_ptr, info_ptr,
+      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#endif
+}
+#endif
+
+
+#if defined(PNG_iCCP_SUPPORTED)
+void PNGAPI
+png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charp name, int compression_type,
+             png_charp profile, png_uint_32 proflen)
+{
+   png_charp new_iccp_name;
+   png_charp new_iccp_profile;
+
+   png_debug1(1, "in %s storage function\n", "iCCP");
+   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+      return;
+
+   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1);
+   if (new_iccp_name == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
+      return;
+   }
+   png_strcpy(new_iccp_name, name);
+   new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
+   if (new_iccp_profile == NULL)
+   {
+      png_free (png_ptr, new_iccp_name);
+      png_warning(png_ptr, "Insufficient memory to process iCCP profile.");
+      return;
+   }
+   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+   info_ptr->iccp_proflen = proflen;
+   info_ptr->iccp_name = new_iccp_name;
+   info_ptr->iccp_profile = new_iccp_profile;
+   /* Compression is always zero but is here so the API and info structure
+    * does not have to change if we introduce multiple compression types */
+   info_ptr->iccp_compression = (png_byte)compression_type;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_ICCP;
+#endif
+   info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+void PNGAPI
+png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+   int num_text)
+{
+   int ret;
+   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+   if (ret)
+     png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+   int num_text)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
+      "text" : (png_const_charp)png_ptr->chunk_name));
+
+   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
+      return(0);
+
+   /* Make sure we have enough space in the "text" array in info_struct
+    * to hold all of the incoming text_ptr objects.
+    */
+   if (info_ptr->num_text + num_text > info_ptr->max_text)
+   {
+      if (info_ptr->text != NULL)
+      {
+         png_textp old_text;
+         int old_max;
+
+         old_max = info_ptr->max_text;
+         info_ptr->max_text = info_ptr->num_text + num_text + 8;
+         old_text = info_ptr->text;
+         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+            (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
+         if (info_ptr->text == NULL)
+           {
+             png_free(png_ptr, old_text);
+             return(1);
+           }
+         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
+            png_sizeof(png_text)));
+         png_free(png_ptr, old_text);
+      }
+      else
+      {
+         info_ptr->max_text = num_text + 8;
+         info_ptr->num_text = 0;
+         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+            (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
+         if (info_ptr->text == NULL)
+           return(1);
+#ifdef PNG_FREE_ME_SUPPORTED
+         info_ptr->free_me |= PNG_FREE_TEXT;
+#endif
+      }
+      png_debug1(3, "allocated %d entries for info_ptr->text\n",
+         info_ptr->max_text);
+   }
+   for (i = 0; i < num_text; i++)
+   {
+      png_size_t text_length,key_len;
+      png_size_t lang_len,lang_key_len;
+      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+      if (text_ptr[i].key == NULL)
+          continue;
+
+      key_len = png_strlen(text_ptr[i].key);
+
+      if(text_ptr[i].compression <= 0)
+      {
+        lang_len = 0;
+        lang_key_len = 0;
+      }
+      else
+#ifdef PNG_iTXt_SUPPORTED
+      {
+        /* set iTXt data */
+        if (text_ptr[i].lang != NULL)
+          lang_len = png_strlen(text_ptr[i].lang);
+        else
+          lang_len = 0;
+        if (text_ptr[i].lang_key != NULL)
+          lang_key_len = png_strlen(text_ptr[i].lang_key);
+        else
+          lang_key_len = 0;
+      }
+#else
+      {
+        png_warning(png_ptr, "iTXt chunk not supported.");
+        continue;
+      }
+#endif
+
+      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+      {
+         text_length = 0;
+#ifdef PNG_iTXt_SUPPORTED
+         if(text_ptr[i].compression > 0)
+            textp->compression = PNG_ITXT_COMPRESSION_NONE;
+         else
+#endif
+            textp->compression = PNG_TEXT_COMPRESSION_NONE;
+      }
+      else
+      {
+         text_length = png_strlen(text_ptr[i].text);
+         textp->compression = text_ptr[i].compression;
+      }
+
+      textp->key = (png_charp)png_malloc_warn(png_ptr,
+         (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
+      if (textp->key == NULL)
+        return(1);
+      png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
+         (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4),
+         (int)textp->key);
+
+      png_memcpy(textp->key, text_ptr[i].key,
+         (png_size_t)(key_len));
+      *(textp->key+key_len) = '\0';
+#ifdef PNG_iTXt_SUPPORTED
+      if (text_ptr[i].compression > 0)
+      {
+         textp->lang=textp->key + key_len + 1;
+         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
+         *(textp->lang+lang_len) = '\0';
+         textp->lang_key=textp->lang + lang_len + 1;
+         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+         *(textp->lang_key+lang_key_len) = '\0';
+         textp->text=textp->lang_key + lang_key_len + 1;
+      }
+      else
+#endif
+      {
+#ifdef PNG_iTXt_SUPPORTED
+         textp->lang=NULL;
+         textp->lang_key=NULL;
+#endif
+         textp->text=textp->key + key_len + 1;
+      }
+      if(text_length)
+         png_memcpy(textp->text, text_ptr[i].text,
+            (png_size_t)(text_length));
+      *(textp->text+text_length) = '\0';
+
+#ifdef PNG_iTXt_SUPPORTED
+      if(textp->compression > 0)
+      {
+         textp->text_length = 0;
+         textp->itxt_length = text_length;
+      }
+      else
+#endif
+      {
+         textp->text_length = text_length;
+#ifdef PNG_iTXt_SUPPORTED
+         textp->itxt_length = 0;
+#endif
+      }
+      info_ptr->text[info_ptr->num_text]= *textp;
+      info_ptr->num_text++;
+      png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
+   }
+   return(0);
+}
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+void PNGAPI
+png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
+{
+   png_debug1(1, "in %s storage function\n", "tIME");
+   if (png_ptr == NULL || info_ptr == NULL ||
+       (png_ptr->mode & PNG_WROTE_tIME))
+      return;
+
+   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time));
+   info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+void PNGAPI
+png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
+   png_bytep trans, int num_trans, png_color_16p trans_values)
+{
+   png_debug1(1, "in %s storage function\n", "tRNS");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (trans != NULL)
+   {
+       /*
+        * It may not actually be necessary to set png_ptr->trans here;
+        * we do it for backward compatibility with the way the png_handle_tRNS
+        * function used to do the allocation.
+        */
+#ifdef PNG_FREE_ME_SUPPORTED
+       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+#endif
+       /* Changed from num_trans to 256 in version 1.2.1 */
+       png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
+           (png_uint_32)256);
+       png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
+#ifdef PNG_FREE_ME_SUPPORTED
+       info_ptr->free_me |= PNG_FREE_TRNS;
+#else
+       png_ptr->flags |= PNG_FLAG_FREE_TRNS;
+#endif
+   }
+
+   if (trans_values != NULL)
+   {
+      png_memcpy(&(info_ptr->trans_values), trans_values,
+         png_sizeof(png_color_16));
+      if (num_trans == 0)
+        num_trans = 1;
+   }
+   info_ptr->num_trans = (png_uint_16)num_trans;
+   info_ptr->valid |= PNG_INFO_tRNS;
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+void PNGAPI
+png_set_sPLT(png_structp png_ptr,
+             png_infop info_ptr, png_sPLT_tp entries, int nentries)
+{
+    png_sPLT_tp np;
+    int i;
+
+    np = (png_sPLT_tp)png_malloc_warn(png_ptr,
+        (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t));
+    if (np == NULL)
+    {
+      png_warning(png_ptr, "No memory for sPLT palettes.");
+      return;
+    }
+
+    png_memcpy(np, info_ptr->splt_palettes,
+           info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
+    png_free(png_ptr, info_ptr->splt_palettes);
+    info_ptr->splt_palettes=NULL;
+
+    for (i = 0; i < nentries; i++)
+    {
+        png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
+        png_sPLT_tp from = entries + i;
+
+        to->name = (png_charp)png_malloc(png_ptr,
+            png_strlen(from->name) + 1);
+        /* TODO: use png_malloc_warn */
+        png_strcpy(to->name, from->name);
+        to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
+            from->nentries * png_sizeof(png_sPLT_t));
+        /* TODO: use png_malloc_warn */
+        png_memcpy(to->entries, from->entries,
+            from->nentries * png_sizeof(png_sPLT_t));
+        to->nentries = from->nentries;
+        to->depth = from->depth;
+    }
+
+    info_ptr->splt_palettes = np;
+    info_ptr->splt_palettes_num += nentries;
+    info_ptr->valid |= PNG_INFO_sPLT;
+#ifdef PNG_FREE_ME_SUPPORTED
+    info_ptr->free_me |= PNG_FREE_SPLT;
+#endif
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_unknown_chunks(png_structp png_ptr,
+   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
+{
+    png_unknown_chunkp np;
+    int i;
+
+    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
+        return;
+
+    np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
+        (info_ptr->unknown_chunks_num + num_unknowns) *
+        png_sizeof(png_unknown_chunk));
+    if (np == NULL)
+    {
+       png_warning(png_ptr, "Out of memory while processing unknown chunk.");
+       return;
+    }
+
+    png_memcpy(np, info_ptr->unknown_chunks,
+           info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
+    png_free(png_ptr, info_ptr->unknown_chunks);
+    info_ptr->unknown_chunks=NULL;
+
+    for (i = 0; i < num_unknowns; i++)
+    {
+        png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
+        png_unknown_chunkp from = unknowns + i;
+
+        png_strncpy((png_charp)to->name, (png_charp)from->name, 5);
+        to->data = (png_bytep)png_malloc_warn(png_ptr, from->size);
+        if (to->data == NULL)
+        {
+           png_warning(png_ptr, "Out of memory processing unknown chunk.");
+        }
+        else
+        {
+           png_memcpy(to->data, from->data, from->size);
+           to->size = from->size;
+
+           /* note our location in the read or write sequence */
+           to->location = (png_byte)(png_ptr->mode & 0xff);
+        }
+    }
+
+    info_ptr->unknown_chunks = np;
+    info_ptr->unknown_chunks_num += num_unknowns;
+#ifdef PNG_FREE_ME_SUPPORTED
+    info_ptr->free_me |= PNG_FREE_UNKN;
+#endif
+}
+void PNGAPI
+png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
+   int chunk, int location)
+{
+   if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
+         (int)info_ptr->unknown_chunks_num)
+      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
+}
+#endif
+
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+void PNGAPI
+png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
+{
+   /* This function is deprecated in favor of png_permit_mng_features()
+      and will be removed from libpng-2.0.0 */
+   png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
+   if (png_ptr == NULL)
+      return;
+   png_ptr->mng_features_permitted = (png_byte)
+     ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
+     ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
+}
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
+{
+   png_debug(1, "in png_permit_mng_features\n");
+   if (png_ptr == NULL)
+      return (png_uint_32)0;
+   png_ptr->mng_features_permitted =
+     (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
+   return (png_uint_32)png_ptr->mng_features_permitted;
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
+   chunk_list, int num_chunks)
+{
+    png_bytep new_list, p;
+    int i, old_num_chunks;
+    if (num_chunks == 0)
+    {
+      if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
+        png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+      else
+        png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+
+      if(keep == PNG_HANDLE_CHUNK_ALWAYS)
+        png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+      else
+        png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+      return;
+    }
+    if (chunk_list == NULL)
+      return;
+    old_num_chunks=png_ptr->num_chunk_list;
+    new_list=(png_bytep)png_malloc(png_ptr,
+       (png_uint_32)(5*(num_chunks+old_num_chunks)));
+    if(png_ptr->chunk_list != NULL)
+    {
+       png_memcpy(new_list, png_ptr->chunk_list,
+          (png_size_t)(5*old_num_chunks));
+       png_free(png_ptr, png_ptr->chunk_list);
+       png_ptr->chunk_list=NULL;
+    }
+    png_memcpy(new_list+5*old_num_chunks, chunk_list,
+       (png_size_t)(5*num_chunks));
+    for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
+       *p=(png_byte)keep;
+    png_ptr->num_chunk_list=old_num_chunks+num_chunks;
+    png_ptr->chunk_list=new_list;
+#ifdef PNG_FREE_ME_SUPPORTED
+    png_ptr->free_me |= PNG_FREE_LIST;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
+   png_user_chunk_ptr read_user_chunk_fn)
+{
+   png_debug(1, "in png_set_read_user_chunk_fn\n");
+   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+   png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
+{
+   png_debug1(1, "in %s storage function\n", "rows");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
+      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+   info_ptr->row_pointers = row_pointers;
+   if(row_pointers)
+      info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+void PNGAPI
+png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
+{
+    if(png_ptr->zbuf)
+       png_free(png_ptr, png_ptr->zbuf);
+    png_ptr->zbuf_size = (png_size_t)size;
+    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
+    png_ptr->zstream.next_out = png_ptr->zbuf;
+    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+}
+#endif
+
+void PNGAPI
+png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
+{
+   if (png_ptr && info_ptr)
+      info_ptr->valid &= ~(mask);
+}
+
+
+#ifndef PNG_1_0_X
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* this function was added to libpng 1.2.0 and should always exist by default */
+void PNGAPI
+png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
+{
+    png_uint_32 settable_asm_flags;
+    png_uint_32 settable_mmx_flags;
+
+    settable_mmx_flags =
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+                         PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  |
+#endif
+#ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
+                         PNG_ASM_FLAG_MMX_READ_INTERLACE    |
+#endif
+#ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+                         PNG_ASM_FLAG_MMX_READ_FILTER_SUB   |
+                         PNG_ASM_FLAG_MMX_READ_FILTER_UP    |
+                         PNG_ASM_FLAG_MMX_READ_FILTER_AVG   |
+                         PNG_ASM_FLAG_MMX_READ_FILTER_PAETH |
+#endif
+                         0;
+
+    /* could be some non-MMX ones in the future, but not currently: */
+    settable_asm_flags = settable_mmx_flags;
+
+    if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) ||
+        !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU))
+    {
+        /* clear all MMX flags if MMX isn't supported */
+        settable_asm_flags &= ~settable_mmx_flags;
+        png_ptr->asm_flags &= ~settable_mmx_flags;
+    }
+
+    /* we're replacing the settable bits with those passed in by the user,
+     * so first zero them out of the master copy, then logical-OR in the
+     * allowed subset that was requested */
+
+    png_ptr->asm_flags &= ~settable_asm_flags;               /* zero them */
+    png_ptr->asm_flags |= (asm_flags & settable_asm_flags);  /* set them */
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* this function was added to libpng 1.2.0 */
+void PNGAPI
+png_set_mmx_thresholds (png_structp png_ptr,
+                        png_byte mmx_bitdepth_threshold,
+                        png_uint_32 mmx_rowbytes_threshold)
+{
+    png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold;
+    png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold;
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* this function was added to libpng 1.2.6 */
+void PNGAPI
+png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
+    png_uint_32 user_height_max)
+{
+    /* Images with dimensions larger than these limits will be
+     * rejected by png_set_IHDR().  To accept any PNG datastream
+     * regardless of dimensions, set both limits to 0x7ffffffL.
+     */
+    png_ptr->user_width_max = user_width_max;
+    png_ptr->user_height_max = user_height_max;
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+#endif /* ?PNG_1_0_X */
diff --git a/Utilities/FLTK/png/pngtrans.c b/Utilities/FLTK/png/pngtrans.c
new file mode 100644
index 0000000000000000000000000000000000000000..f3e5766289a69672ff90cb9e6118146d336887e0
--- /dev/null
+++ b/Utilities/FLTK/png/pngtrans.c
@@ -0,0 +1,644 @@
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * libpng  1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_bgr\n");
+   png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* turn on 16 bit byte swapping */
+void PNGAPI
+png_set_swap(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_swap\n");
+   if (png_ptr->bit_depth == 16)
+      png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_packing\n");
+   if (png_ptr->bit_depth < 8)
+   {
+      png_ptr->transformations |= PNG_PACK;
+      png_ptr->usr_bit_depth = 8;
+   }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_packswap\n");
+   if (png_ptr->bit_depth < 8)
+      png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structp png_ptr, png_color_8p true_bits)
+{
+   png_debug(1, "in png_set_shift\n");
+   png_ptr->transformations |= PNG_SHIFT;
+   png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_interlace handling\n");
+   if (png_ptr->interlaced)
+   {
+      png_ptr->transformations |= PNG_INTERLACE;
+      return (7);
+   }
+
+   return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+   png_debug(1, "in png_set_filler\n");
+   png_ptr->transformations |= PNG_FILLER;
+   png_ptr->filler = (png_byte)filler;
+   if (filler_loc == PNG_FILLER_AFTER)
+      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+   else
+      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+
+   /* This should probably go in the "do_read_filler" routine.
+    * I attempted to do that in libpng-1.0.1a but that caused problems
+    * so I restored it in libpng-1.0.2a
+   */
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      png_ptr->usr_channels = 4;
+   }
+
+   /* Also I added this in libpng-1.0.2a (what happens when we expand
+    * a less-than-8-bit grayscale to GA? */
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
+   {
+      png_ptr->usr_channels = 2;
+   }
+}
+
+#if !defined(PNG_1_0_X)
+/* Added to libpng-1.2.7 */
+void PNGAPI
+png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+   png_debug(1, "in png_set_add_alpha\n");
+   png_set_filler(png_ptr, filler, filler_loc);
+   png_ptr->transformations |= PNG_ADD_ALPHA;
+}
+#endif
+
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_swap_alpha\n");
+   png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_invert_alpha\n");
+   png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_invert_mono\n");
+   png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_invert\n");
+  /* This test removed from libpng version 1.0.13 and 1.2.0:
+   *   if (row_info->bit_depth == 1 &&
+   */
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row == NULL || row_info == NULL)
+     return;
+#endif
+   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i++)
+      {
+         *rp = (png_byte)(~(*rp));
+         rp++;
+      }
+   }
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+      row_info->bit_depth == 8)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i+=2)
+      {
+         *rp = (png_byte)(~(*rp));
+         rp+=2;
+      }
+   }
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+      row_info->bit_depth == 16)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i+=4)
+      {
+         *rp = (png_byte)(~(*rp));
+         *(rp+1) = (png_byte)(~(*(rp+1)));
+         rp+=4;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* swaps byte order on 16 bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_swap\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->bit_depth == 16)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop= row_info->width * row_info->channels;
+
+      for (i = 0; i < istop; i++, rp += 2)
+      {
+         png_byte t = *rp;
+         *rp = *(rp + 1);
+         *(rp + 1) = t;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static png_byte onebppswaptable[256] = {
+   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static png_byte twobppswaptable[256] = {
+   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static png_byte fourbppswaptable[256] = {
+   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_packswap\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->bit_depth < 8)
+   {
+      png_bytep rp, end, table;
+
+      end = row + row_info->rowbytes;
+
+      if (row_info->bit_depth == 1)
+         table = onebppswaptable;
+      else if (row_info->bit_depth == 2)
+         table = twobppswaptable;
+      else if (row_info->bit_depth == 4)
+         table = fourbppswaptable;
+      else
+         return;
+
+      for (rp = row; rp < end; rp++)
+         *rp = table[*rp];
+   }
+}
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* remove filler or alpha byte(s) */
+void /* PRIVATE */
+png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
+{
+   png_debug(1, "in png_do_strip_filler\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      png_bytep sp=row;
+      png_bytep dp=row;
+      png_uint_32 row_width=row_info->width;
+      png_uint_32 i;
+
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+         row_info->channels == 4)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from RGBX or RGBA to RGB */
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               dp+=3; sp+=4;
+               for (i = 1; i < row_width; i++)
+               {
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp++;
+               }
+            }
+            /* This converts from XRGB or ARGB to RGB */
+            else
+            {
+               for (i = 0; i < row_width; i++)
+               {
+                  sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 24;
+            row_info->rowbytes = row_width * 3;
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
+               sp += 8; dp += 6;
+               for (i = 1; i < row_width; i++)
+               {
+                  /* This could be (although png_memcpy is probably slower):
+                  png_memcpy(dp, sp, 6);
+                  sp += 8;
+                  dp += 6;
+                  */
+
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp += 2;
+               }
+            }
+            else
+            {
+               /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
+               for (i = 0; i < row_width; i++)
+               {
+                  /* This could be (although png_memcpy is probably slower):
+                  png_memcpy(dp, sp, 6);
+                  sp += 8;
+                  dp += 6;
+                  */
+
+                  sp+=2;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 48;
+            row_info->rowbytes = row_width * 6;
+         }
+         row_info->channels = 3;
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY &&
+          row_info->channels == 2)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from GX or GA to G */
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               for (i = 0; i < row_width; i++)
+               {
+                  *dp++ = *sp++;
+                  sp++;
+               }
+            }
+            /* This converts from XG or AG to G */
+            else
+            {
+               for (i = 0; i < row_width; i++)
+               {
+                  sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 8;
+            row_info->rowbytes = row_width;
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               /* This converts from GGXX or GGAA to GG */
+               sp += 4; dp += 2;
+               for (i = 1; i < row_width; i++)
+               {
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp += 2;
+               }
+            }
+            else
+            {
+               /* This converts from XXGG or AAGG to GG */
+               for (i = 0; i < row_width; i++)
+               {
+                  sp += 2;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+         row_info->channels = 1;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_bgr\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 3)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 4)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 6)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 4);
+               *(rp + 4) = save;
+               save = *(rp + 1);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 5) = save;
+            }
+         }
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 8)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 4);
+               *(rp + 4) = save;
+               save = *(rp + 1);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 5) = save;
+            }
+         }
+      }
+   }
+}
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
+png_set_user_transform_info(png_structp png_ptr, png_voidp
+   user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+   png_debug(1, "in png_set_user_transform_info\n");
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   png_ptr->user_transform_ptr = user_transform_ptr;
+   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+#else
+   if(user_transform_ptr || user_transform_depth || user_transform_channels)
+      png_warning(png_ptr,
+        "This version of libpng does not support user transform info");
+#endif
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions.  The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_structp png_ptr)
+{
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   return ((png_voidp)png_ptr->user_transform_ptr);
+#else
+   if(png_ptr)
+     return (NULL);
+   return (NULL);
+#endif
+}
diff --git a/Utilities/FLTK/png/pngwio.c b/Utilities/FLTK/png/pngwio.c
new file mode 100644
index 0000000000000000000000000000000000000000..d569b6851f0708b9425fb022ff21ed17049d1a6a
--- /dev/null
+++ b/Utilities/FLTK/png/pngwio.c
@@ -0,0 +1,228 @@
+
+/* pngwio.c - functions for data output
+ *
+ * libpng 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all output.  Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods.  Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using.  The default routine
+   writes to a file pointer.  Note that this routine sometimes gets called
+   with very small lengths, so you should implement some kind of simple
+   buffering if you are using unbuffered writes.  This should never be asked
+   to write more than 64K on a 16 bit machine.  */
+
+void /* PRIVATE */
+png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   if (png_ptr->write_data_fn != NULL )
+      (*(png_ptr->write_data_fn))(png_ptr, data, length);
+   else
+      png_error(png_ptr, "Call to NULL write function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function that does the actual writing of data.  If you are
+   not writing to a standard C stream, you should create a replacement
+   write_data function and use it at run time with png_set_write_fn(), rather
+   than changing the library. */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+
+#if defined(_WIN32_WCE)
+   if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+      check = 0;
+#else
+   check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+#endif
+   if (check != length)
+      png_error(png_ptr, "Write Error");
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
+   png_FILE_p io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)near_data == data)
+   {
+#if defined(_WIN32_WCE)
+      if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
+         check = 0;
+#else
+      check = fwrite(near_data, 1, length, io_ptr);
+#endif
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t written, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         written = MIN(NEAR_BUF_SIZE, remaining);
+         png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+#if defined(_WIN32_WCE)
+         if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
+            err = 0;
+#else
+         err = fwrite(buf, 1, written, io_ptr);
+#endif
+         if (err != written)
+            break;
+         else
+            check += err;
+         data += written;
+         remaining -= written;
+      }
+      while (remaining != 0);
+   }
+   if (check != length)
+      png_error(png_ptr, "Write Error");
+}
+
+#endif
+#endif
+
+/* This function is called to output any data pending writing (normally
+   to disk).  After png_flush is called, there should be no data pending
+   writing in any buffers. */
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+void /* PRIVATE */
+png_flush(png_structp png_ptr)
+{
+   if (png_ptr->output_flush_fn != NULL)
+      (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+#if !defined(PNG_NO_STDIO)
+void PNGAPI
+png_default_flush(png_structp png_ptr)
+{
+#if !defined(_WIN32_WCE)
+   png_FILE_p io_ptr;
+   io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+   if (io_ptr != NULL)
+      fflush(io_ptr);
+#endif
+}
+#endif
+#endif
+
+/* This function allows the application to supply new output functions for
+   libpng if standard C streams aren't being used.
+
+   This function takes as its arguments:
+   png_ptr       - pointer to a png output data structure
+   io_ptr        - pointer to user supplied structure containing info about
+                   the output functions.  May be NULL.
+   write_data_fn - pointer to a new output function that takes as its
+                   arguments a pointer to a png_struct, a pointer to
+                   data to be written, and a 32-bit unsigned int that is
+                   the number of bytes to be written.  The new write
+                   function should call png_error(png_ptr, "Error msg")
+                   to exit and output any fatal error messages.
+   flush_data_fn - pointer to a new flush function that takes as its
+                   arguments a pointer to a png_struct.  After a call to
+                   the flush function, there should be no data in any buffers
+                   or pending transmission.  If the output method doesn't do
+                   any buffering of ouput, a function prototype must still be
+                   supplied although it doesn't have to do anything.  If
+                   PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+                   time, output_flush_fn will be ignored, although it must be
+                   supplied for compatibility. */
+void PNGAPI
+png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
+   png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+   png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+   if (write_data_fn != NULL)
+      png_ptr->write_data_fn = write_data_fn;
+   else
+      png_ptr->write_data_fn = png_default_write_data;
+#else
+   png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+   if (output_flush_fn != NULL)
+      png_ptr->output_flush_fn = output_flush_fn;
+   else
+      png_ptr->output_flush_fn = png_default_flush;
+#else
+   png_ptr->output_flush_fn = output_flush_fn;
+#endif
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+   /* It is an error to read while writing a png file */
+   if (png_ptr->read_data_fn != NULL)
+   {
+      png_ptr->read_data_fn = NULL;
+      png_warning(png_ptr,
+         "Attempted to set both read_data_fn and write_data_fn in");
+      png_warning(png_ptr,
+         "the same structure.  Resetting read_data_fn to NULL.");
+   }
+}
+
+#if defined(USE_FAR_KEYWORD)
+#if defined(_MSC_VER)
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+   void *near_ptr;
+   void FAR *far_ptr;
+   FP_OFF(near_ptr) = FP_OFF(ptr);
+   far_ptr = (void FAR *)near_ptr;
+   if(check != 0)
+      if(FP_SEG(ptr) != FP_SEG(far_ptr))
+         png_error(png_ptr,"segment lost in conversion");
+   return(near_ptr);
+}
+#  else
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+   void *near_ptr;
+   void FAR *far_ptr;
+   near_ptr = (void FAR *)ptr;
+   far_ptr = (void FAR *)near_ptr;
+   if(check != 0)
+      if(far_ptr != ptr)
+         png_error(png_ptr,"segment lost in conversion");
+   return(near_ptr);
+}
+#   endif
+#   endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Utilities/FLTK/png/pngwrite.c b/Utilities/FLTK/png/pngwrite.c
new file mode 100644
index 0000000000000000000000000000000000000000..6cb539b46b3b3da359094683d5e5d812b593645a
--- /dev/null
+++ b/Utilities/FLTK/png/pngwrite.c
@@ -0,0 +1,1464 @@
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * libpng 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+/* get internal access to png.h */
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Writes all the PNG information.  This is the suggested way to use the
+ * library.  If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here.  If you want the chunk written
+ * after the image data, put it in png_write_end().  I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file.  If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_write_info_before_PLTE\n");
+   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+   {
+   png_write_sig(png_ptr); /* write PNG signature */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
+   {
+      png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
+      png_ptr->mng_features_permitted=0;
+   }
+#endif
+   /* write IHDR information. */
+   png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+      info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+      info_ptr->filter_type,
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+      info_ptr->interlace_type);
+#else
+      0);
+#endif
+   /* the rest of these check to see if the valid field has the appropriate
+      flag set, and if it does, writes the chunk. */
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_gAMA)
+   {
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+      png_write_gAMA(png_ptr, info_ptr->gamma);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
+#  endif
+#endif
+   }
+#endif
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sRGB)
+      png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
+#endif
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_iCCP)
+      png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
+                     info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
+#endif
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sBIT)
+      png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_cHRM)
+   {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+      png_write_cHRM(png_ptr,
+         info_ptr->x_white, info_ptr->y_white,
+         info_ptr->x_red, info_ptr->y_red,
+         info_ptr->x_green, info_ptr->y_green,
+         info_ptr->x_blue, info_ptr->y_blue);
+#else
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_cHRM_fixed(png_ptr,
+         info_ptr->int_x_white, info_ptr->int_y_white,
+         info_ptr->int_x_red, info_ptr->int_y_red,
+         info_ptr->int_x_green, info_ptr->int_y_green,
+         info_ptr->int_x_blue, info_ptr->int_y_blue);
+#  endif
+#endif
+   }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+   if (info_ptr->unknown_chunks_num)
+   {
+       png_unknown_chunk *up;
+
+       png_debug(5, "writing extra chunks\n");
+
+       for (up = info_ptr->unknown_chunks;
+            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+            up++)
+       {
+         int keep=png_handle_as_unknown(png_ptr, up->name);
+         if (keep != PNG_HANDLE_CHUNK_NEVER &&
+            up->location && !(up->location & PNG_HAVE_PLTE) &&
+            !(up->location & PNG_HAVE_IDAT) &&
+            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+       }
+   }
+#endif
+      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+   }
+}
+
+void PNGAPI
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+   int i;
+#endif
+
+   png_debug(1, "in png_write_info\n");
+
+   png_write_info_before_PLTE(png_ptr, info_ptr);
+
+   if (info_ptr->valid & PNG_INFO_PLTE)
+      png_write_PLTE(png_ptr, info_ptr->palette,
+         (png_uint_32)info_ptr->num_palette);
+   else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      png_error(png_ptr, "Valid palette required for paletted images\n");
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_tRNS)
+      {
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+         /* invert the alpha channel (in tRNS) */
+         if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
+            info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         {
+            int j;
+            for (j=0; j<(int)info_ptr->num_trans; j++)
+               info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
+         }
+#endif
+      png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
+         info_ptr->num_trans, info_ptr->color_type);
+      }
+#endif
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_bKGD)
+      png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_hIST)
+      png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
+      png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+         info_ptr->offset_unit_type);
+#endif
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pCAL)
+      png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+         info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+         info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sCAL)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+      png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
+          info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+          info_ptr->scal_s_width, info_ptr->scal_s_height);
+#else
+      png_warning(png_ptr,
+          "png_write_sCAL not supported; sCAL chunk not written.\n");
+#endif
+#endif
+#endif
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
+      png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+         info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_tIME)
+   {
+      png_write_tIME(png_ptr, &(info_ptr->mod_time));
+      png_ptr->mode |= PNG_WROTE_tIME;
+   }
+#endif
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sPLT)
+     for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+       png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+   /* Check to see if we need to write text chunks */
+   for (i = 0; i < info_ptr->num_text; i++)
+   {
+      png_debug2(2, "Writing header text chunk %d, type %d\n", i,
+         info_ptr->text[i].compression);
+      /* an internationalized chunk? */
+      if (info_ptr->text[i].compression > 0)
+      {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+          /* write international chunk */
+          png_write_iTXt(png_ptr,
+                         info_ptr->text[i].compression,
+                         info_ptr->text[i].key,
+                         info_ptr->text[i].lang,
+                         info_ptr->text[i].lang_key,
+                         info_ptr->text[i].text);
+#else
+          png_warning(png_ptr, "Unable to write international text\n");
+#endif
+          /* Mark this chunk as written */
+          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+      }
+      /* If we want a compressed text chunk */
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+      {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+         /* write compressed chunk */
+         png_write_zTXt(png_ptr, info_ptr->text[i].key,
+            info_ptr->text[i].text, 0,
+            info_ptr->text[i].compression);
+#else
+         png_warning(png_ptr, "Unable to write compressed text\n");
+#endif
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+      }
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+      {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+         /* write uncompressed chunk */
+         png_write_tEXt(png_ptr, info_ptr->text[i].key,
+                         info_ptr->text[i].text,
+                         0);
+#else
+         png_warning(png_ptr, "Unable to write uncompressed text\n");
+#endif
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+      }
+   }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+   if (info_ptr->unknown_chunks_num)
+   {
+       png_unknown_chunk *up;
+
+       png_debug(5, "writing extra chunks\n");
+
+       for (up = info_ptr->unknown_chunks;
+            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+            up++)
+       {
+         int keep=png_handle_as_unknown(png_ptr, up->name);
+         if (keep != PNG_HANDLE_CHUNK_NEVER &&
+            up->location && (up->location & PNG_HAVE_PLTE) &&
+            !(up->location & PNG_HAVE_IDAT) &&
+            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+       }
+   }
+#endif
+}
+
+/* Writes the end of the PNG file.  If you don't want to write comments or
+ * time information, you can pass NULL for info.  If you already wrote these
+ * in png_write_info(), do not write them again here.  If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_write_end\n");
+   if (!(png_ptr->mode & PNG_HAVE_IDAT))
+      png_error(png_ptr, "No IDATs written into file");
+
+   /* see if user wants us to write information chunks */
+   if (info_ptr != NULL)
+   {
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+      int i; /* local index variable */
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+      /* check to see if user has supplied a time chunk */
+      if ((info_ptr->valid & PNG_INFO_tIME) &&
+         !(png_ptr->mode & PNG_WROTE_tIME))
+         png_write_tIME(png_ptr, &(info_ptr->mod_time));
+#endif
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+      /* loop through comment chunks */
+      for (i = 0; i < info_ptr->num_text; i++)
+      {
+         png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
+            info_ptr->text[i].compression);
+         /* an internationalized chunk? */
+         if (info_ptr->text[i].compression > 0)
+         {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+             /* write international chunk */
+             png_write_iTXt(png_ptr,
+                         info_ptr->text[i].compression,
+                         info_ptr->text[i].key,
+                         info_ptr->text[i].lang,
+                         info_ptr->text[i].lang_key,
+                         info_ptr->text[i].text);
+#else
+             png_warning(png_ptr, "Unable to write international text\n");
+#endif
+             /* Mark this chunk as written */
+             info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         }
+         else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+         {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+            /* write compressed chunk */
+            png_write_zTXt(png_ptr, info_ptr->text[i].key,
+               info_ptr->text[i].text, 0,
+               info_ptr->text[i].compression);
+#else
+            png_warning(png_ptr, "Unable to write compressed text\n");
+#endif
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+         }
+         else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+         {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+            /* write uncompressed chunk */
+            png_write_tEXt(png_ptr, info_ptr->text[i].key,
+               info_ptr->text[i].text, 0);
+#else
+            png_warning(png_ptr, "Unable to write uncompressed text\n");
+#endif
+
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         }
+      }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+   if (info_ptr->unknown_chunks_num)
+   {
+       png_unknown_chunk *up;
+
+       png_debug(5, "writing extra chunks\n");
+
+       for (up = info_ptr->unknown_chunks;
+            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+            up++)
+       {
+         int keep=png_handle_as_unknown(png_ptr, up->name);
+         if (keep != PNG_HANDLE_CHUNK_NEVER &&
+            up->location && (up->location & PNG_AFTER_IDAT) &&
+            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+       }
+   }
+#endif
+   }
+
+   png_ptr->mode |= PNG_AFTER_IDAT;
+
+   /* write end of PNG file */
+   png_write_IEND(png_ptr);
+#if 0
+/* This flush, added in libpng-1.0.8,  causes some applications to crash
+   because they do not set png_ptr->output_flush_fn */
+   png_flush(png_ptr);
+#endif
+}
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
+{
+   png_debug(1, "in png_convert_from_struct_tm\n");
+   ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+   ptime->month = (png_byte)(ttime->tm_mon + 1);
+   ptime->day = (png_byte)ttime->tm_mday;
+   ptime->hour = (png_byte)ttime->tm_hour;
+   ptime->minute = (png_byte)ttime->tm_min;
+   ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+   struct tm *tbuf;
+
+   png_debug(1, "in png_convert_from_time_t\n");
+   tbuf = gmtime(&ttime);
+   png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+   png_structp png_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif
+#endif
+   int i;
+   png_debug(1, "in png_create_write_struct\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif /* PNG_USER_MEM_SUPPORTED */
+   if (png_ptr == NULL)
+      return (NULL);
+
+#if !defined(PNG_1_0_X)
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
+#endif
+#endif /* PNG_1_0_X */
+
+   /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_ptr->jmpbuf))
+#endif
+   {
+      png_free(png_ptr, png_ptr->zbuf);
+      png_ptr->zbuf=NULL;
+      png_destroy_struct(png_ptr);
+      return (NULL);
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+   i=0;
+   do
+   {
+     if(user_png_ver[i] != png_libpng_ver[i])
+        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+   } while (png_libpng_ver[i++]);
+
+   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+   {
+     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+      * we must recompile any applications that use any older library version.
+      * For versions after libpng 1.0, we will be compatible, so we need
+      * only check the first digit.
+      */
+     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+     {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+        char msg[80];
+        if (user_png_ver)
+        {
+          sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+             user_png_ver);
+          png_warning(png_ptr, msg);
+        }
+        sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
+           png_libpng_ver);
+        png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+        png_ptr->flags=0;
+#endif
+        png_error(png_ptr,
+           "Incompatible libpng version in application and library");
+     }
+   }
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+      (png_uint_32)png_ptr->zbuf_size);
+
+   png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+      png_flush_ptr_NULL);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+      1, png_doublep_NULL, png_doublep_NULL);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then encounter
+   a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
+   abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+      PNG_ABORT();
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
+#else
+   if (setjmp(png_ptr->jmpbuf))
+      PNG_ABORT();
+#endif
+#endif
+   return (png_ptr);
+}
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+#undef png_write_init
+void PNGAPI
+png_write_init(png_structp png_ptr)
+{
+   /* We only come here via pre-1.0.7-compiled applications */
+   png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size, png_size_t png_info_size)
+{
+   /* We only come here via pre-1.0.12-compiled applications */
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+   if(png_sizeof(png_struct) > png_struct_size ||
+      png_sizeof(png_info) > png_info_size)
+   {
+      char msg[80];
+      png_ptr->warning_fn=NULL;
+      if (user_png_ver)
+      {
+        sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+           user_png_ver);
+        png_warning(png_ptr, msg);
+      }
+      sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
+         png_libpng_ver);
+      png_warning(png_ptr, msg);
+   }
+#endif
+   if(png_sizeof(png_struct) > png_struct_size)
+     {
+       png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+       png_ptr->flags=0;
+#endif
+       png_error(png_ptr,
+       "The png struct allocated by the application for writing is too small.");
+     }
+   if(png_sizeof(png_info) > png_info_size)
+     {
+       png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+       png_ptr->flags=0;
+#endif
+       png_error(png_ptr,
+       "The info struct allocated by the application for writing is too small.");
+     }
+   png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+
+
+void PNGAPI
+png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size)
+{
+   png_structp png_ptr=*ptr_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+   int i = 0;
+   do
+   {
+     if (user_png_ver[i] != png_libpng_ver[i])
+     {
+#ifdef PNG_LEGACY_SUPPORTED
+       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+       png_ptr->warning_fn=NULL;
+       png_warning(png_ptr,
+     "Application uses deprecated png_write_init() and should be recompiled.");
+       break;
+#endif
+     }
+   } while (png_libpng_ver[i++]);
+
+   png_debug(1, "in png_write_init_3\n");
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* save jump buffer and error functions */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+   if (png_sizeof(png_struct) > png_struct_size)
+     {
+       png_destroy_struct(png_ptr);
+       png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+       *ptr_ptr = png_ptr;
+     }
+
+   /* reset all variables to 0 */
+   png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+   /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
+#if !defined(PNG_1_0_X)
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
+#endif
+#endif /* PNG_1_0_X */
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* restore jump buffer */
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+
+   png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+      png_flush_ptr_NULL);
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+      (png_uint_32)png_ptr->zbuf_size);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+      1, png_doublep_NULL, png_doublep_NULL);
+#endif
+}
+
+/* Write a few rows of image data.  If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structp png_ptr, png_bytepp row,
+   png_uint_32 num_rows)
+{
+   png_uint_32 i; /* row counter */
+   png_bytepp rp; /* row pointer */
+
+   png_debug(1, "in png_write_rows\n");
+   /* loop through the rows */
+   for (i = 0, rp = row; i < num_rows; i++, rp++)
+   {
+      png_write_row(png_ptr, *rp);
+   }
+}
+
+/* Write the image.  You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structp png_ptr, png_bytepp image)
+{
+   png_uint_32 i; /* row index */
+   int pass, num_pass; /* pass variables */
+   png_bytepp rp; /* points to current row */
+
+   png_debug(1, "in png_write_image\n");
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+   /* intialize interlace handling.  If image is not interlaced,
+      this will set pass to 1 */
+   num_pass = png_set_interlace_handling(png_ptr);
+#else
+   num_pass = 1;
+#endif
+   /* loop through passes */
+   for (pass = 0; pass < num_pass; pass++)
+   {
+      /* loop through image */
+      for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+      {
+         png_write_row(png_ptr, *rp);
+      }
+   }
+}
+
+/* called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structp png_ptr, png_bytep row)
+{
+   png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
+      png_ptr->row_number, png_ptr->pass);
+   /* initialize transformations and other stuff if first time */
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+   /* make sure we wrote the header info */
+   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+      png_error(png_ptr,
+         "png_write_info was never called before png_write_row.");
+
+   /* check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
+#endif
+
+      png_write_start_row(png_ptr);
+   }
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+   /* if interlaced and not interested in row, return */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if (png_ptr->row_number & 0x07)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 1:
+            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 2:
+            if ((png_ptr->row_number & 0x07) != 4)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 3:
+            if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 4:
+            if ((png_ptr->row_number & 0x03) != 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 5:
+            if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 6:
+            if (!(png_ptr->row_number & 0x01))
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+      }
+   }
+#endif
+
+   /* set up row info for transformations */
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->usr_width;
+   png_ptr->row_info.channels = png_ptr->usr_channels;
+   png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
+   png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+      png_ptr->row_info.channels);
+
+   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+      png_ptr->row_info.width);
+
+   png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
+   png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
+   png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
+   png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
+   png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
+   png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
+
+   /* Copy user's row into buffer, leaving room for filter byte. */
+   png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
+      png_ptr->row_info.rowbytes);
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+   /* handle interlacing */
+   if (png_ptr->interlaced && png_ptr->pass < 6 &&
+      (png_ptr->transformations & PNG_INTERLACE))
+   {
+      png_do_write_interlace(&(png_ptr->row_info),
+         png_ptr->row_buf + 1, png_ptr->pass);
+      /* this should always get caught above, but still ... */
+      if (!(png_ptr->row_info.width))
+      {
+         png_write_finish_row(png_ptr);
+         return;
+      }
+   }
+#endif
+
+   /* handle other transformations */
+   if (png_ptr->transformations)
+      png_do_write_transformations(png_ptr);
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+   }
+#endif
+
+   /* Find a filter if necessary, filter the row and write it out. */
+   png_write_find_filter(png_ptr, &(png_ptr->row_info));
+
+   if (png_ptr->write_row_fn != NULL)
+      (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structp png_ptr, int nrows)
+{
+   png_debug(1, "in png_set_flush\n");
+   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structp png_ptr)
+{
+   int wrote_IDAT;
+
+   png_debug(1, "in png_write_flush\n");
+   /* We have already written out all of the data */
+   if (png_ptr->row_number >= png_ptr->num_rows)
+     return;
+
+   do
+   {
+      int ret;
+
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+      wrote_IDAT = 0;
+
+      /* check for compression errors */
+      if (ret != Z_OK)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      if (!(png_ptr->zstream.avail_out))
+      {
+         /* write the IDAT and reset the zlib output buffer */
+         png_write_IDAT(png_ptr, png_ptr->zbuf,
+                        png_ptr->zbuf_size);
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         wrote_IDAT = 1;
+      }
+   } while(wrote_IDAT == 1);
+
+   /* If there is any data left to be output, write it into a new IDAT */
+   if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
+   {
+      /* write the IDAT and reset the zlib output buffer */
+      png_write_IDAT(png_ptr, png_ptr->zbuf,
+                     png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   }
+   png_ptr->flush_rows = 0;
+   png_flush(png_ptr);
+}
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+/* free all memory used by the write */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+   png_structp png_ptr = NULL;
+   png_infop info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn = NULL;
+   png_voidp mem_ptr = NULL;
+#endif
+
+   png_debug(1, "in png_destroy_write_struct\n");
+   if (png_ptr_ptr != NULL)
+   {
+      png_ptr = *png_ptr_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+      free_fn = png_ptr->free_fn;
+      mem_ptr = png_ptr->mem_ptr;
+#endif
+   }
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (info_ptr != NULL)
+   {
+      png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+      if (png_ptr->num_chunk_list)
+      {
+         png_free(png_ptr, png_ptr->chunk_list);
+         png_ptr->chunk_list=NULL;
+         png_ptr->num_chunk_list=0;
+      }
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+         (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)info_ptr);
+#endif
+      *info_ptr_ptr = NULL;
+   }
+
+   if (png_ptr != NULL)
+   {
+      png_write_destroy(png_ptr);
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+         (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)png_ptr);
+#endif
+      *png_ptr_ptr = NULL;
+   }
+}
+
+
+/* Free any memory used in png_ptr struct (old method) */
+void /* PRIVATE */
+png_write_destroy(png_structp png_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp; /* save jump buffer */
+#endif
+   png_error_ptr error_fn;
+   png_error_ptr warning_fn;
+   png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn;
+#endif
+
+   png_debug(1, "in png_write_destroy\n");
+   /* free any memory zlib uses */
+   deflateEnd(&png_ptr->zstream);
+
+   /* free our memory.  png_free checks NULL for us. */
+   png_free(png_ptr, png_ptr->zbuf);
+   png_free(png_ptr, png_ptr->row_buf);
+   png_free(png_ptr, png_ptr->prev_row);
+   png_free(png_ptr, png_ptr->sub_row);
+   png_free(png_ptr, png_ptr->up_row);
+   png_free(png_ptr, png_ptr->avg_row);
+   png_free(png_ptr, png_ptr->paeth_row);
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+   png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_free(png_ptr, png_ptr->prev_filters);
+   png_free(png_ptr, png_ptr->filter_weights);
+   png_free(png_ptr, png_ptr->inv_filter_weights);
+   png_free(png_ptr, png_ptr->filter_costs);
+   png_free(png_ptr, png_ptr->inv_filter_costs);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* reset structure */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
+#endif
+
+   error_fn = png_ptr->error_fn;
+   warning_fn = png_ptr->warning_fn;
+   error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+#endif
+
+   png_memset(png_ptr, 0, png_sizeof (png_struct));
+
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+   png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structp png_ptr, int method, int filters)
+{
+   png_debug(1, "in png_set_filter\n");
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (method == PNG_INTRAPIXEL_DIFFERENCING))
+         method = PNG_FILTER_TYPE_BASE;
+#endif
+   if (method == PNG_FILTER_TYPE_BASE)
+   {
+      switch (filters & (PNG_ALL_FILTERS | 0x07))
+      {
+         case 5:
+         case 6:
+         case 7: png_warning(png_ptr, "Unknown row filter for method 0");
+         case PNG_FILTER_VALUE_NONE:  png_ptr->do_filter=PNG_FILTER_NONE; break;
+         case PNG_FILTER_VALUE_SUB:   png_ptr->do_filter=PNG_FILTER_SUB;  break;
+         case PNG_FILTER_VALUE_UP:    png_ptr->do_filter=PNG_FILTER_UP;   break;
+         case PNG_FILTER_VALUE_AVG:   png_ptr->do_filter=PNG_FILTER_AVG;  break;
+         case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break;
+         default: png_ptr->do_filter = (png_byte)filters; break;
+      }
+
+      /* If we have allocated the row_buf, this means we have already started
+       * with the image and we should have allocated all of the filter buffers
+       * that have been selected.  If prev_row isn't already allocated, then
+       * it is too late to start using the filters that need it, since we
+       * will be missing the data in the previous row.  If an application
+       * wants to start and stop using particular filters during compression,
+       * it should start out with all of the filters, and then add and
+       * remove them after the start of compression.
+       */
+      if (png_ptr->row_buf != NULL)
+      {
+         if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
+         {
+            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+              (png_ptr->rowbytes + 1));
+            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Up filter after starting");
+               png_ptr->do_filter &= ~PNG_FILTER_UP;
+            }
+            else
+            {
+               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+            }
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Average filter after starting");
+               png_ptr->do_filter &= ~PNG_FILTER_AVG;
+            }
+            else
+            {
+               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+            }
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
+             png_ptr->paeth_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Paeth filter after starting");
+               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+            }
+            else
+            {
+               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+            }
+         }
+
+         if (png_ptr->do_filter == PNG_NO_FILTERS)
+            png_ptr->do_filter = PNG_FILTER_NONE;
+      }
+   }
+   else
+      png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline.  While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)      /* GRR 970116 */
+void PNGAPI
+png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
+   int num_weights, png_doublep filter_weights,
+   png_doublep filter_costs)
+{
+   int i;
+
+   png_debug(1, "in png_set_filter_heuristics\n");
+   if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
+   {
+      png_warning(png_ptr, "Unknown filter heuristic method");
+      return;
+   }
+
+   if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
+   {
+      heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+   }
+
+   if (num_weights < 0 || filter_weights == NULL ||
+      heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+   {
+      num_weights = 0;
+   }
+
+   png_ptr->num_prev_filters = (png_byte)num_weights;
+   png_ptr->heuristic_method = (png_byte)heuristic_method;
+
+   if (num_weights > 0)
+   {
+      if (png_ptr->prev_filters == NULL)
+      {
+         png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(png_sizeof(png_byte) * num_weights));
+
+         /* To make sure that the weighting starts out fairly */
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->prev_filters[i] = 255;
+         }
+      }
+
+      if (png_ptr->filter_weights == NULL)
+      {
+         png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+            (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+
+         png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+            (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+      }
+
+      for (i = 0; i < num_weights; i++)
+      {
+         if (filter_weights[i] < 0.0)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+         else
+         {
+            png_ptr->inv_filter_weights[i] =
+               (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
+            png_ptr->filter_weights[i] =
+               (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
+         }
+      }
+   }
+
+   /* If, in the future, there are other filter methods, this would
+    * need to be based on png_ptr->filter.
+    */
+   if (png_ptr->filter_costs == NULL)
+   {
+      png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+         (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+      png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+         (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+      {
+         png_ptr->inv_filter_costs[i] =
+         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+      }
+   }
+
+   /* Here is where we set the relative costs of the different filters.  We
+    * should take the desired compression level into account when setting
+    * the costs, so that Paeth, for instance, has a high relative cost at low
+    * compression levels, while it has a lower relative cost at higher
+    * compression settings.  The filter types are in order of increasing
+    * relative cost, so it would be possible to do this with an algorithm.
+    */
+   for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+   {
+      if (filter_costs == NULL || filter_costs[i] < 0.0)
+      {
+         png_ptr->inv_filter_costs[i] =
+         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+      }
+      else if (filter_costs[i] >= 1.0)
+      {
+         png_ptr->inv_filter_costs[i] =
+            (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
+         png_ptr->filter_costs[i] =
+            (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
+      }
+   }
+}
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+void PNGAPI
+png_set_compression_level(png_structp png_ptr, int level)
+{
+   png_debug(1, "in png_set_compression_level\n");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
+   png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structp png_ptr, int mem_level)
+{
+   png_debug(1, "in png_set_compression_mem_level\n");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
+   png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structp png_ptr, int strategy)
+{
+   png_debug(1, "in png_set_compression_strategy\n");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+   png_ptr->zlib_strategy = strategy;
+}
+
+void PNGAPI
+png_set_compression_window_bits(png_structp png_ptr, int window_bits)
+{
+   if (window_bits > 15)
+      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+   else if (window_bits < 8)
+      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+#ifndef WBITS_8_OK
+   /* avoid libpng bug with 256-byte windows */
+   if (window_bits == 8)
+     {
+       png_warning(png_ptr, "Compression window is being reset to 512");
+       window_bits=9;
+     }
+#endif
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
+   png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structp png_ptr, int method)
+{
+   png_debug(1, "in png_set_compression_method\n");
+   if (method != 8)
+      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
+   png_ptr->zlib_method = method;
+}
+
+void PNGAPI
+png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
+{
+   png_ptr->write_row_fn = write_row_fn;
+}
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+   write_user_transform_fn)
+{
+   png_debug(1, "in png_set_write_user_transform_fn\n");
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_write_png(png_structp png_ptr, png_infop info_ptr,
+              int transforms, voidp params)
+{
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+   /* invert the alpha channel from opacity to transparency */
+   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+       png_set_invert_alpha(png_ptr);
+#endif
+
+   /* Write the file header information. */
+   png_write_info(png_ptr, info_ptr);
+
+   /* ------ these transformations don't touch the info structure ------- */
+
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+   /* invert monochrome pixels */
+   if (transforms & PNG_TRANSFORM_INVERT_MONO)
+       png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+   /* Shift the pixels up to a legal bit depth and fill in
+    * as appropriate to correctly scale the image.
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT)
+               && (info_ptr->valid & PNG_INFO_sBIT))
+       png_set_shift(png_ptr, &info_ptr->sig_bit);
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+   /* pack pixels into bytes */
+   if (transforms & PNG_TRANSFORM_PACKING)
+       png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+   /* swap location of alpha bytes from ARGB to RGBA */
+   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+       png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+   /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
+    * RGB (4 channels -> 3 channels). The second parameter is not used.
+    */
+   if (transforms & PNG_TRANSFORM_STRIP_FILLER)
+       png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#endif
+
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+   /* flip BGR pixels to RGB */
+   if (transforms & PNG_TRANSFORM_BGR)
+       png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+   /* swap bytes of 16-bit files to most significant byte first */
+   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+       png_set_swap(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+   /* swap bits of 1, 2, 4 bit packed pixel formats */
+   if (transforms & PNG_TRANSFORM_PACKSWAP)
+       png_set_packswap(png_ptr);
+#endif
+
+   /* ----------------------- end of transformations ------------------- */
+
+   /* write the bits */
+   if (info_ptr->valid & PNG_INFO_IDAT)
+       png_write_image(png_ptr, info_ptr->row_pointers);
+
+   /* It is REQUIRED to call this to finish writing the rest of the file */
+   png_write_end(png_ptr, info_ptr);
+
+   if(transforms == 0 || params == NULL)
+      /* quiet compiler warnings */ return;
+}
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Utilities/FLTK/png/pngwtran.c b/Utilities/FLTK/png/pngwtran.c
new file mode 100644
index 0000000000000000000000000000000000000000..d2bf5bc7849c4f54b744ed64df11d7117dacac22
--- /dev/null
+++ b/Utilities/FLTK/png/pngwtran.c
@@ -0,0 +1,563 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Transform the data according to the user's wishes.  The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_do_write_transformations\n");
+
+   if (png_ptr == NULL)
+      return;
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+      if(png_ptr->write_user_transform_fn != NULL)
+        (*(png_ptr->write_user_transform_fn)) /* user write transform function */
+          (png_ptr,                    /* png_ptr */
+           &(png_ptr->row_info),       /* row_info:     */
+             /*  png_uint_32 width;          width of row */
+             /*  png_uint_32 rowbytes;       number of bytes in row */
+             /*  png_byte color_type;        color type of pixels */
+             /*  png_byte bit_depth;         bit depth of samples */
+             /*  png_byte channels;          number of channels (1-4) */
+             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
+           png_ptr->row_buf + 1);      /* start of pixel data for row */
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->flags);
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         (png_uint_32)png_ptr->bit_depth);
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->shift));
+#endif
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+}
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
+ * row_info bit depth should be 8 (one pixel per byte).  The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+void /* PRIVATE */
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+   png_debug(1, "in png_do_pack\n");
+   if (row_info->bit_depth == 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+      row_info->channels == 1)
+   {
+      switch ((int)bit_depth)
+      {
+         case 1:
+         {
+            png_bytep sp, dp;
+            int mask, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            mask = 0x80;
+            v = 0;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (*sp != 0)
+                  v |= mask;
+               sp++;
+               if (mask > 1)
+                  mask >>= 1;
+               else
+               {
+                  mask = 0x80;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+            }
+            if (mask != 0x80)
+               *dp = (png_byte)v;
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            shift = 6;
+            v = 0;
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0x03);
+               v |= (value << shift);
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+               else
+                  shift -= 2;
+               sp++;
+            }
+            if (shift != 6)
+               *dp = (png_byte)v;
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            shift = 4;
+            v = 0;
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0x0f);
+               v |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+               else
+                  shift -= 4;
+
+               sp++;
+            }
+            if (shift != 4)
+               *dp = (png_byte)v;
+            break;
+         }
+      }
+      row_info->bit_depth = (png_byte)bit_depth;
+      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+         row_info->width);
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Shift pixel values to take advantage of whole range.  Pass the
+ * true number of bits in bit_depth.  The row should be packed
+ * according to row_info->bit_depth.  Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+void /* PRIVATE */
+png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
+{
+   png_debug(1, "in png_do_shift\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL &&
+#else
+   if (
+#endif
+      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift_start[4], shift_dec[4];
+      int channels = 0;
+
+      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->red;
+         shift_dec[channels] = bit_depth->red;
+         channels++;
+         shift_start[channels] = row_info->bit_depth - bit_depth->green;
+         shift_dec[channels] = bit_depth->green;
+         channels++;
+         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+         shift_dec[channels] = bit_depth->blue;
+         channels++;
+      }
+      else
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+         shift_dec[channels] = bit_depth->gray;
+         channels++;
+      }
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+         shift_dec[channels] = bit_depth->alpha;
+         channels++;
+      }
+
+      /* with low row depths, could only be grayscale, so one channel */
+      if (row_info->bit_depth < 8)
+      {
+         png_bytep bp = row;
+         png_uint_32 i;
+         png_byte mask;
+         png_uint_32 row_bytes = row_info->rowbytes;
+
+         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+            mask = 0x55;
+         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+            mask = 0x11;
+         else
+            mask = 0xff;
+
+         for (i = 0; i < row_bytes; i++, bp++)
+         {
+            png_uint_16 v;
+            int j;
+
+            v = *bp;
+            *bp = 0;
+            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+            {
+               if (j > 0)
+                  *bp |= (png_byte)((v << j) & 0xff);
+               else
+                  *bp |= (png_byte)((v >> (-j)) & mask);
+            }
+         }
+      }
+      else if (row_info->bit_depth == 8)
+      {
+         png_bytep bp = row;
+         png_uint_32 i;
+         png_uint_32 istop = channels * row_info->width;
+
+         for (i = 0; i < istop; i++, bp++)
+         {
+
+            png_uint_16 v;
+            int j;
+            int c = (int)(i%channels);
+
+            v = *bp;
+            *bp = 0;
+            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+            {
+               if (j > 0)
+                  *bp |= (png_byte)((v << j) & 0xff);
+               else
+                  *bp |= (png_byte)((v >> (-j)) & 0xff);
+            }
+         }
+      }
+      else
+      {
+         png_bytep bp;
+         png_uint_32 i;
+         png_uint_32 istop = channels * row_info->width;
+
+         for (bp = row, i = 0; i < istop; i++)
+         {
+            int c = (int)(i%channels);
+            png_uint_16 value, v;
+            int j;
+
+            v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
+            value = 0;
+            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+            {
+               if (j > 0)
+                  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
+               else
+                  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
+            }
+            *bp++ = (png_byte)(value >> 8);
+            *bp++ = (png_byte)(value & 0xff);
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This converts from ARGB to RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+         /* This converts from AARRGGBB to RRGGBBAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save[2];
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This converts from AG to GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+         /* This converts from AAGG to GGAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save[2];
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This inverts the alpha channel in RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+         /* This inverts the alpha channel in RRGGBBAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This inverts the alpha channel in GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+         /* This inverts the alpha channel in GGAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing  */
+void /* PRIVATE */
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_intrapixel\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp)   = (png_byte)((*rp     - *(rp+1))&0xff);
+            *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp  ) << 8) | *(rp+1);
+            png_uint_32 s1   = (*(rp+2) << 8) | *(rp+3);
+            png_uint_32 s2   = (*(rp+4) << 8) | *(rp+5);
+            png_uint_32 red  = (png_uint_32)((s0-s1) & 0xffffL);
+            png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
+            *(rp  ) = (png_byte)((red >> 8) & 0xff);
+            *(rp+1) = (png_byte)(red & 0xff);
+            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp+5) = (png_byte)(blue & 0xff);
+         }
+      }
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Utilities/FLTK/png/pngwutil.c b/Utilities/FLTK/png/pngwutil.c
new file mode 100644
index 0000000000000000000000000000000000000000..87f028f9a880d42419c0f631886ea4788ab005da
--- /dev/null
+++ b/Utilities/FLTK/png/pngwutil.c
@@ -0,0 +1,2726 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * libpng version 1.2.7 - September 12, 2004
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2005 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Place a 32-bit number into a buffer in PNG byte order.  We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void /* PRIVATE */
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format.  If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format.
+ */
+void /* PRIVATE */
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void /* PRIVATE */
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+   buf[0] = (png_byte)((i >> 8) & 0xff);
+   buf[1] = (png_byte)(i & 0xff);
+}
+
+/* Write a PNG chunk all at once.  The type is an array of ASCII characters
+ * representing the chunk name.  The array must be at least 4 bytes in
+ * length, and does not need to be null terminated.  To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined.  The length is the length of the data.
+ * All the data must be present.  If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+void PNGAPI
+png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
+   png_bytep data, png_size_t length)
+{
+   png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
+   png_write_chunk_data(png_ptr, data, length);
+   png_write_chunk_end(png_ptr);
+}
+
+/* Write the start of a PNG chunk.  The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+void PNGAPI
+png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
+   png_uint_32 length)
+{
+   png_byte buf[4];
+   png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);
+
+   /* write the length */
+   png_save_uint_32(buf, length);
+   png_write_data(png_ptr, buf, (png_size_t)4);
+
+   /* write the chunk name */
+   png_write_data(png_ptr, chunk_name, (png_size_t)4);
+   /* reset the crc and run it over the chunk name */
+   png_reset_crc(png_ptr);
+   png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_start().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_start().
+ */
+void PNGAPI
+png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   /* write the data, and run the CRC over it */
+   if (data != NULL && length > 0)
+   {
+      png_calculate_crc(png_ptr, data, length);
+      png_write_data(png_ptr, data, length);
+   }
+}
+
+/* Finish a chunk started with png_write_chunk_start(). */
+void PNGAPI
+png_write_chunk_end(png_structp png_ptr)
+{
+   png_byte buf[4];
+
+   /* write the crc */
+   png_save_uint_32(buf, png_ptr->crc);
+
+   png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+/* Simple function to write the signature.  If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void /* PRIVATE */
+png_write_sig(png_structp png_ptr)
+{
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+   /* write the rest of the 8 byte signature */
+   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+      (png_size_t)8 - png_ptr->sig_bytes);
+   if(png_ptr->sig_bytes < 3)
+      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
+/*
+ * This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller in order to make the whole mess thread-safe.
+ */
+
+typedef struct
+{
+    char *input;   /* the uncompressed input data */
+    int input_len;   /* its length */
+    int num_output_ptr; /* number of output pointers used */
+    int max_output_ptr; /* size of output_ptr */
+    png_charpp output_ptr; /* array of pointers to output */
+} compression_state;
+
+/* compress given text into storage in the png_ptr structure */
+static int /* PRIVATE */
+png_text_compress(png_structp png_ptr,
+        png_charp text, png_size_t text_len, int compression,
+        compression_state *comp)
+{
+   int ret;
+
+   comp->num_output_ptr = comp->max_output_ptr = 0;
+   comp->output_ptr = NULL;
+   comp->input = NULL;
+
+   /* we may just want to pass the text right through */
+   if (compression == PNG_TEXT_COMPRESSION_NONE)
+   {
+       comp->input = text;
+       comp->input_len = text_len;
+       return((int)text_len);
+   }
+
+   if (compression >= PNG_TEXT_COMPRESSION_LAST)
+   {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+      char msg[50];
+      sprintf(msg, "Unknown compression type %d", compression);
+      png_warning(png_ptr, msg);
+#else
+      png_warning(png_ptr, "Unknown compression type");
+#endif
+   }
+
+   /* We can't write the chunk until we find out how much data we have,
+    * which means we need to run the compressor first and save the
+    * output.  This shouldn't be a problem, as the vast majority of
+    * comments should be reasonable, but we will set up an array of
+    * malloc'd pointers to be sure.
+    *
+    * If we knew the application was well behaved, we could simplify this
+    * greatly by assuming we can always malloc an output buffer large
+    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+    * and malloc this directly.  The only time this would be a bad idea is
+    * if we can't malloc more than 64K and we have 64K of random input
+    * data, or if the input string is incredibly large (although this
+    * wouldn't cause a failure, just a slowdown due to swapping).
+    */
+
+   /* set up the compression buffers */
+   png_ptr->zstream.avail_in = (uInt)text_len;
+   png_ptr->zstream.next_in = (Bytef *)text;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+   /* this is the same compression loop as in png_write_row() */
+   do
+   {
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      if (ret != Z_OK)
+      {
+         /* error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+      /* check to see if we need more room */
+      if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
+      {
+         /* make sure the output array has room */
+         if (comp->num_output_ptr >= comp->max_output_ptr)
+         {
+            int old_max;
+
+            old_max = comp->max_output_ptr;
+            comp->max_output_ptr = comp->num_output_ptr + 4;
+            if (comp->output_ptr != NULL)
+            {
+               png_charpp old_ptr;
+
+               old_ptr = comp->output_ptr;
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr *
+                  png_sizeof (png_charpp)));
+               png_memcpy(comp->output_ptr, old_ptr, old_max
+                  * png_sizeof (png_charp));
+               png_free(png_ptr, old_ptr);
+            }
+            else
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr *
+                  png_sizeof (png_charp)));
+         }
+
+         /* save the data */
+         comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
+            (png_uint_32)png_ptr->zbuf_size);
+         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+            png_ptr->zbuf_size);
+         comp->num_output_ptr++;
+
+         /* and reset the buffer */
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+      }
+   /* continue until we don't have any more to compress */
+   } while (png_ptr->zstream.avail_in);
+
+   /* finish the compression */
+   do
+   {
+      /* tell zlib we are finished */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+
+      if (ret == Z_OK)
+      {
+         /* check to see if we need more room */
+         if (!(png_ptr->zstream.avail_out))
+         {
+            /* check to make sure our output array has room */
+            if (comp->num_output_ptr >= comp->max_output_ptr)
+            {
+               int old_max;
+
+               old_max = comp->max_output_ptr;
+               comp->max_output_ptr = comp->num_output_ptr + 4;
+               if (comp->output_ptr != NULL)
+               {
+                  png_charpp old_ptr;
+
+                  old_ptr = comp->output_ptr;
+                  /* This could be optimized to realloc() */
+                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                     (png_uint_32)(comp->max_output_ptr *
+                     png_sizeof (png_charpp)));
+                  png_memcpy(comp->output_ptr, old_ptr,
+                     old_max * png_sizeof (png_charp));
+                  png_free(png_ptr, old_ptr);
+               }
+               else
+                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                     (png_uint_32)(comp->max_output_ptr *
+                     png_sizeof (png_charp)));
+            }
+
+            /* save off the data */
+            comp->output_ptr[comp->num_output_ptr] =
+               (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);
+            png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+               png_ptr->zbuf_size);
+            comp->num_output_ptr++;
+
+            /* and reset the buffer pointers */
+            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            png_ptr->zstream.next_out = png_ptr->zbuf;
+         }
+      }
+      else if (ret != Z_STREAM_END)
+      {
+         /* we got an error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* text length is number of buffers plus last buffer */
+   text_len = png_ptr->zbuf_size * comp->num_output_ptr;
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+   return((int)text_len);
+}
+
+/* ship the compressed text out via chunk writes */
+static void /* PRIVATE */
+png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
+{
+   int i;
+
+   /* handle the no-compression case */
+   if (comp->input)
+   {
+       png_write_chunk_data(png_ptr, (png_bytep)comp->input,
+                            (png_size_t)comp->input_len);
+       return;
+   }
+
+   /* write saved output buffers, if any */
+   for (i = 0; i < comp->num_output_ptr; i++)
+   {
+      png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],
+         png_ptr->zbuf_size);
+      png_free(png_ptr, comp->output_ptr[i]);
+      comp->output_ptr[i]=NULL;
+   }
+   if (comp->max_output_ptr != 0)
+      png_free(png_ptr, comp->output_ptr);
+      comp->output_ptr=NULL;
+   /* write anything left in zbuf */
+   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+      png_write_chunk_data(png_ptr, png_ptr->zbuf,
+         png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+   /* reset zlib for another zTXt/iTXt or the image data */
+   deflateReset(&png_ptr->zstream);
+
+}
+#endif
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.  Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
+   int bit_depth, int color_type, int compression_type, int filter_type,
+   int interlace_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IHDR;
+#endif
+   png_byte buf[13]; /* buffer to store the IHDR info */
+
+   png_debug(1, "in png_write_IHDR\n");
+   /* Check that we have valid input data from the application info */
+   switch (color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8:
+            case 16: png_ptr->channels = 1; break;
+            default: png_error(png_ptr,"Invalid bit depth for grayscale image");
+         }
+         break;
+      case PNG_COLOR_TYPE_RGB:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for RGB image");
+         png_ptr->channels = 3;
+         break;
+      case PNG_COLOR_TYPE_PALETTE:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8: png_ptr->channels = 1; break;
+            default: png_error(png_ptr, "Invalid bit depth for paletted image");
+         }
+         break;
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+         png_ptr->channels = 2;
+         break;
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for RGBA image");
+         png_ptr->channels = 4;
+         break;
+      default:
+         png_error(png_ptr, "Invalid image color type specified");
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid compression type specified");
+      compression_type = PNG_COMPRESSION_TYPE_BASE;
+   }
+
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+      !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+      (color_type == PNG_COLOR_TYPE_RGB ||
+       color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+      (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+      filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid filter type specified");
+      filter_type = PNG_FILTER_TYPE_BASE;
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   if (interlace_type != PNG_INTERLACE_NONE &&
+      interlace_type != PNG_INTERLACE_ADAM7)
+   {
+      png_warning(png_ptr, "Invalid interlace type specified");
+      interlace_type = PNG_INTERLACE_ADAM7;
+   }
+#else
+   interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+   /* save off the relevent information */
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->color_type = (png_byte)color_type;
+   png_ptr->interlaced = (png_byte)interlace_type;
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   png_ptr->filter_type = (png_byte)filter_type;
+#endif
+   png_ptr->compression_type = (png_byte)compression_type;
+   png_ptr->width = width;
+   png_ptr->height = height;
+
+   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+   /* set the usr info, so any transformations can modify it */
+   png_ptr->usr_width = png_ptr->width;
+   png_ptr->usr_bit_depth = png_ptr->bit_depth;
+   png_ptr->usr_channels = png_ptr->channels;
+
+   /* pack the header information into the buffer */
+   png_save_uint_32(buf, width);
+   png_save_uint_32(buf + 4, height);
+   buf[8] = (png_byte)bit_depth;
+   buf[9] = (png_byte)color_type;
+   buf[10] = (png_byte)compression_type;
+   buf[11] = (png_byte)filter_type;
+   buf[12] = (png_byte)interlace_type;
+
+   /* write the chunk */
+   png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
+
+   /* initialize zlib with PNG info */
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+   if (!(png_ptr->do_filter))
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+         png_ptr->bit_depth < 8)
+         png_ptr->do_filter = PNG_FILTER_NONE;
+      else
+         png_ptr->do_filter = PNG_ALL_FILTERS;
+   }
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
+   {
+      if (png_ptr->do_filter != PNG_FILTER_NONE)
+         png_ptr->zlib_strategy = Z_FILTERED;
+      else
+         png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
+   }
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
+      png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
+      png_ptr->zlib_mem_level = 8;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
+      png_ptr->zlib_window_bits = 15;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
+      png_ptr->zlib_method = 8;
+   deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
+      png_ptr->zlib_method, png_ptr->zlib_window_bits,
+      png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_ptr->mode = PNG_HAVE_IHDR;
+}
+
+/* write the palette.  We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_PLTE;
+#endif
+   png_uint_32 i;
+   png_colorp pal_ptr;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_PLTE\n");
+   if ((
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+        !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
+#endif
+        num_pal == 0) || num_pal > 256)
+   {
+     if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+     {
+        png_error(png_ptr, "Invalid number of colors in palette");
+     }
+     else
+     {
+        png_warning(png_ptr, "Invalid number of colors in palette");
+        return;
+     }
+   }
+
+   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+   {
+      png_warning(png_ptr,
+        "Ignoring request to write a PLTE chunk in grayscale PNG");
+      return;
+   }
+
+   png_ptr->num_palette = (png_uint_16)num_pal;
+   png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
+
+   png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3);
+#ifndef PNG_NO_POINTER_INDEXING
+   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+   {
+      buf[0] = pal_ptr->red;
+      buf[1] = pal_ptr->green;
+      buf[2] = pal_ptr->blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+#else
+   /* This is a little slower but some buggy compilers need to do this instead */
+   pal_ptr=palette;
+   for (i = 0; i < num_pal; i++)
+   {
+      buf[0] = pal_ptr[i].red;
+      buf[1] = pal_ptr[i].green;
+      buf[2] = pal_ptr[i].blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+#endif
+   png_write_chunk_end(png_ptr);
+   png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* write an IDAT chunk */
+void /* PRIVATE */
+png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+#endif
+   png_debug(1, "in png_write_IDAT\n");
+
+   /* Optimize the CMF field in the zlib stream. */
+   /* This hack of the zlib stream is compliant to the stream specification. */
+   if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+       png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+   {
+      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
+      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
+      {
+         /* Avoid memory underflows and multiplication overflows. */
+         /* The conditions below are practically always satisfied;
+            however, they still must be checked. */
+         if (length >= 2 &&
+             png_ptr->height < 16384 && png_ptr->width < 16384)
+         {
+            png_uint_32 uncompressed_idat_size = png_ptr->height *
+               ((png_ptr->width *
+               png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
+            unsigned int z_cinfo = z_cmf >> 4;
+            unsigned int half_z_window_size = 1 << (z_cinfo + 7);
+            while (uncompressed_idat_size <= half_z_window_size &&
+                   half_z_window_size >= 256)
+            {
+               z_cinfo--;
+               half_z_window_size >>= 1;
+            }
+            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
+            if (data[0] != (png_byte)z_cmf)
+            {
+               data[0] = (png_byte)z_cmf;
+               data[1] &= 0xe0;
+               data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
+            }
+         }
+      }
+      else
+         png_error(png_ptr,
+            "Invalid zlib compression method or flags in IDAT");
+   }
+
+   png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
+   png_ptr->mode |= PNG_HAVE_IDAT;
+}
+
+/* write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IEND;
+#endif
+   png_debug(1, "in png_write_IEND\n");
+   png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
+     (png_size_t)0);
+   png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+/* write a gAMA chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA(png_structp png_ptr, double file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_gAMA;
+#endif
+   png_uint_32 igamma;
+   png_byte buf[4];
+
+   png_debug(1, "in png_write_gAMA\n");
+   /* file_gamma is saved in 1/100,000ths */
+   igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
+   png_save_uint_32(buf, igamma);
+   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_gAMA;
+#endif
+   png_byte buf[4];
+
+   png_debug(1, "in png_write_gAMA\n");
+   /* file_gamma is saved in 1/100,000ths */
+   png_save_uint_32(buf, (png_uint_32)file_gamma);
+   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+/* write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structp png_ptr, int srgb_intent)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sRGB;
+#endif
+   png_byte buf[1];
+
+   png_debug(1, "in png_write_sRGB\n");
+   if(srgb_intent >= PNG_sRGB_INTENT_LAST)
+         png_warning(png_ptr,
+            "Invalid sRGB rendering intent specified");
+   buf[0]=(png_byte)srgb_intent;
+   png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+/* write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
+   png_charp profile, int profile_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iCCP;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   compression_state comp;
+
+   png_debug(1, "in png_write_iCCP\n");
+   if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
+      &new_name)) == 0)
+   {
+      png_warning(png_ptr, "Empty keyword in iCCP chunk");
+      return;
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+      png_warning(png_ptr, "Unknown compression type in iCCP chunk");
+
+   if (profile == NULL)
+      profile_len = 0;
+
+   if (profile_len)
+       profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
+          PNG_COMPRESSION_TYPE_BASE, &comp);
+
+   /* make sure we include the NULL after the name and the compression type */
+   png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
+          (png_uint_32)name_len+profile_len+2);
+   new_name[name_len+1]=0x00;
+   png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
+
+   if (profile_len)
+      png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+/* write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sPLT;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   png_byte entrybuf[10];
+   int entry_size = (spalette->depth == 8 ? 6 : 10);
+   int palette_size = entry_size * spalette->nentries;
+   png_sPLT_entryp ep;
+#ifdef PNG_NO_POINTER_INDEXING
+   int i;
+#endif
+
+   png_debug(1, "in png_write_sPLT\n");
+   if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
+      spalette->name, &new_name))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in sPLT chunk");
+      return;
+   }
+
+   /* make sure we include the NULL after the name */
+   png_write_chunk_start(png_ptr, (png_bytep)png_sPLT,
+          (png_uint_32)(name_len + 2 + palette_size));
+   png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
+   png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
+
+   /* loop through each palette entry, writing appropriately */
+#ifndef PNG_NO_POINTER_INDEXING
+   for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
+   {
+       if (spalette->depth == 8)
+       {
+           entrybuf[0] = (png_byte)ep->red;
+           entrybuf[1] = (png_byte)ep->green;
+           entrybuf[2] = (png_byte)ep->blue;
+           entrybuf[3] = (png_byte)ep->alpha;
+           png_save_uint_16(entrybuf + 4, ep->frequency);
+       }
+       else
+       {
+           png_save_uint_16(entrybuf + 0, ep->red);
+           png_save_uint_16(entrybuf + 2, ep->green);
+           png_save_uint_16(entrybuf + 4, ep->blue);
+           png_save_uint_16(entrybuf + 6, ep->alpha);
+           png_save_uint_16(entrybuf + 8, ep->frequency);
+       }
+       png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
+   }
+#else
+   ep=spalette->entries;
+   for (i=0; i>spalette->nentries; i++)
+   {
+       if (spalette->depth == 8)
+       {
+           entrybuf[0] = (png_byte)ep[i].red;
+           entrybuf[1] = (png_byte)ep[i].green;
+           entrybuf[2] = (png_byte)ep[i].blue;
+           entrybuf[3] = (png_byte)ep[i].alpha;
+           png_save_uint_16(entrybuf + 4, ep[i].frequency);
+       }
+       else
+       {
+           png_save_uint_16(entrybuf + 0, ep[i].red);
+           png_save_uint_16(entrybuf + 2, ep[i].green);
+           png_save_uint_16(entrybuf + 4, ep[i].blue);
+           png_save_uint_16(entrybuf + 6, ep[i].alpha);
+           png_save_uint_16(entrybuf + 8, ep[i].frequency);
+       }
+       png_write_chunk_data(png_ptr, entrybuf, entry_size);
+   }
+#endif
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+/* write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sBIT;
+#endif
+   png_byte buf[4];
+   png_size_t size;
+
+   png_debug(1, "in png_write_sBIT\n");
+   /* make sure we don't depend upon the order of PNG_COLOR_8 */
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_byte maxbits;
+
+      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+                png_ptr->usr_bit_depth);
+      if (sbit->red == 0 || sbit->red > maxbits ||
+          sbit->green == 0 || sbit->green > maxbits ||
+          sbit->blue == 0 || sbit->blue > maxbits)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[0] = sbit->red;
+      buf[1] = sbit->green;
+      buf[2] = sbit->blue;
+      size = 3;
+   }
+   else
+   {
+      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[0] = sbit->gray;
+      size = 1;
+   }
+
+   if (color_type & PNG_COLOR_MASK_ALPHA)
+   {
+      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[size++] = sbit->alpha;
+   }
+
+   png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
+}
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+/* write the cHRM chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
+   double red_x, double red_y, double green_x, double green_y,
+   double blue_x, double blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_cHRM;
+#endif
+   png_byte buf[32];
+   png_uint_32 itemp;
+
+   png_debug(1, "in png_write_cHRM\n");
+   /* each value is saved in 1/100,000ths */
+   if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
+       white_x + white_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+      fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y);
+#endif
+      return;
+   }
+   itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
+   png_save_uint_32(buf, itemp);
+   itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 4, itemp);
+
+   if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
+       red_x + red_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM red point specified");
+      return;
+   }
+   itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
+   png_save_uint_32(buf + 8, itemp);
+   itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 12, itemp);
+
+   if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
+       green_x + green_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM green point specified");
+      return;
+   }
+   itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
+   png_save_uint_32(buf + 16, itemp);
+   itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 20, itemp);
+
+   if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 ||
+       blue_x + blue_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM blue point specified");
+      return;
+   }
+   itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
+   png_save_uint_32(buf + 24, itemp);
+   itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 28, itemp);
+
+   png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
+   png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
+   png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
+   png_fixed_point blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_cHRM;
+#endif
+   png_byte buf[32];
+
+   png_debug(1, "in png_write_cHRM\n");
+   /* each value is saved in 1/100,000ths */
+   if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid fixed cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+      fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y);
+#endif
+      return;
+   }
+   png_save_uint_32(buf, (png_uint_32)white_x);
+   png_save_uint_32(buf + 4, (png_uint_32)white_y);
+
+   if (red_x > 80000L || red_y > 80000L || red_x + red_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid cHRM fixed red point specified");
+      return;
+   }
+   png_save_uint_32(buf + 8, (png_uint_32)red_x);
+   png_save_uint_32(buf + 12, (png_uint_32)red_y);
+
+   if (green_x > 80000L || green_y > 80000L || green_x + green_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid fixed cHRM green point specified");
+      return;
+   }
+   png_save_uint_32(buf + 16, (png_uint_32)green_x);
+   png_save_uint_32(buf + 20, (png_uint_32)green_y);
+
+   if (blue_x > 80000L || blue_y > 80000L || blue_x + blue_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
+      return;
+   }
+   png_save_uint_32(buf + 24, (png_uint_32)blue_x);
+   png_save_uint_32(buf + 28, (png_uint_32)blue_y);
+
+   png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+}
+#endif
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+/* write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
+   int num_trans, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tRNS;
+#endif
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_tRNS\n");
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+      {
+         png_warning(png_ptr,"Invalid number of transparent colors specified");
+         return;
+      }
+      /* write the chunk out as it is */
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans);
+   }
+   else if (color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      /* one 16 bit value */
+      if(tran->gray >= (1 << png_ptr->bit_depth))
+      {
+         png_warning(png_ptr,
+           "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+         return;
+      }
+      png_save_uint_16(buf, tran->gray);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
+   }
+   else if (color_type == PNG_COLOR_TYPE_RGB)
+   {
+      /* three 16 bit values */
+      png_save_uint_16(buf, tran->red);
+      png_save_uint_16(buf + 2, tran->green);
+      png_save_uint_16(buf + 4, tran->blue);
+      if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+         {
+            png_warning(png_ptr,
+              "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+            return;
+         }
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
+   }
+   else
+   {
+      png_warning(png_ptr, "Can't write tRNS with an alpha channel");
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+/* write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_bKGD;
+#endif
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_bKGD\n");
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+          (png_ptr->num_palette ||
+          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
+#endif
+         back->index > png_ptr->num_palette)
+      {
+         png_warning(png_ptr, "Invalid background palette index");
+         return;
+      }
+      buf[0] = back->index;
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
+   }
+   else if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_save_uint_16(buf, back->red);
+      png_save_uint_16(buf + 2, back->green);
+      png_save_uint_16(buf + 4, back->blue);
+      if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+         {
+            png_warning(png_ptr,
+              "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+            return;
+         }
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
+   }
+   else
+   {
+      if(back->gray >= (1 << png_ptr->bit_depth))
+      {
+         png_warning(png_ptr,
+           "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+         return;
+      }
+      png_save_uint_16(buf, back->gray);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+/* write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_hIST;
+#endif
+   int i;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_hIST\n");
+   if (num_hist > (int)png_ptr->num_palette)
+   {
+      png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
+         png_ptr->num_palette);
+      png_warning(png_ptr, "Invalid number of histogram entries specified");
+      return;
+   }
+
+   png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2));
+   for (i = 0; i < num_hist; i++)
+   {
+      png_save_uint_16(buf, hist[i]);
+      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+   }
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
+ *
+ * The new_key is allocated to hold the corrected keyword and must be freed
+ * by the calling routine.  This avoids problems with trying to write to
+ * static keywords without having to have duplicate copies of the strings.
+ */
+png_size_t /* PRIVATE */
+png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
+{
+   png_size_t key_len;
+   png_charp kp, dp;
+   int kflag;
+   int kwarn=0;
+
+   png_debug(1, "in png_check_keyword\n");
+   *new_key = NULL;
+
+   if (key == NULL || (key_len = png_strlen(key)) == 0)
+   {
+      png_warning(png_ptr, "zero length keyword");
+      return ((png_size_t)0);
+   }
+
+   png_debug1(2, "Keyword to be checked is '%s'\n", key);
+
+   *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
+   if (*new_key == NULL)
+   {
+      png_warning(png_ptr, "Out of memory while procesing keyword");
+      return ((png_size_t)0);
+   }
+
+   /* Replace non-printing characters with a blank and print a warning */
+   for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
+   {
+      if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1))
+      {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+         char msg[40];
+
+         sprintf(msg, "invalid keyword character 0x%02X", *kp);
+         png_warning(png_ptr, msg);
+#else
+         png_warning(png_ptr, "invalid character in keyword");
+#endif
+         *dp = ' ';
+      }
+      else
+      {
+         *dp = *kp;
+      }
+   }
+   *dp = '\0';
+
+   /* Remove any trailing white space. */
+   kp = *new_key + key_len - 1;
+   if (*kp == ' ')
+   {
+      png_warning(png_ptr, "trailing spaces removed from keyword");
+
+      while (*kp == ' ')
+      {
+        *(kp--) = '\0';
+        key_len--;
+      }
+   }
+
+   /* Remove any leading white space. */
+   kp = *new_key;
+   if (*kp == ' ')
+   {
+      png_warning(png_ptr, "leading spaces removed from keyword");
+
+      while (*kp == ' ')
+      {
+        kp++;
+        key_len--;
+      }
+   }
+
+   png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
+
+   /* Remove multiple internal spaces. */
+   for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
+   {
+      if (*kp == ' ' && kflag == 0)
+      {
+         *(dp++) = *kp;
+         kflag = 1;
+      }
+      else if (*kp == ' ')
+      {
+         key_len--;
+         kwarn=1;
+      }
+      else
+      {
+         *(dp++) = *kp;
+         kflag = 0;
+      }
+   }
+   *dp = '\0';
+   if(kwarn)
+      png_warning(png_ptr, "extra interior spaces removed from keyword");
+
+   if (key_len == 0)
+   {
+      png_free(png_ptr, *new_key);
+      *new_key=NULL;
+      png_warning(png_ptr, "Zero length keyword");
+   }
+
+   if (key_len > 79)
+   {
+      png_warning(png_ptr, "keyword length must be 1 - 79 characters");
+      new_key[79] = '\0';
+      key_len = 79;
+   }
+
+   return (key_len);
+}
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+/* write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
+   png_size_t text_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tEXt;
+#endif
+   png_size_t key_len;
+   png_charp new_key;
+
+   png_debug(1, "in png_write_tEXt\n");
+   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in tEXt chunk");
+      return;
+   }
+
+   if (text == NULL || *text == '\0')
+      text_len = 0;
+   else
+      text_len = png_strlen(text);
+
+   /* make sure we include the 0 after the key */
+   png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1);
+   /*
+    * We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
+   png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+   if (text_len)
+      png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_key);
+}
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+/* write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
+   png_size_t text_len, int compression)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_zTXt;
+#endif
+   png_size_t key_len;
+   char buf[1];
+   png_charp new_key;
+   compression_state comp;
+
+   png_debug(1, "in png_write_zTXt\n");
+
+   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in zTXt chunk");
+      return;
+   }
+
+   if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
+   {
+      png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
+      png_free(png_ptr, new_key);
+      return;
+   }
+
+   text_len = png_strlen(text);
+
+   png_free(png_ptr, new_key);
+
+   /* compute the compressed data; do it now for the length */
+   text_len = png_text_compress(png_ptr, text, text_len, compression,
+       &comp);
+
+   /* write start of chunk */
+   png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32)
+      (key_len+text_len+2));
+   /* write key */
+   png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1);
+   buf[0] = (png_byte)compression;
+   /* write compression */
+   png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+   /* write the compressed data */
+   png_write_compressed_data_out(png_ptr, &comp);
+
+   /* close the chunk */
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+/* write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
+    png_charp lang, png_charp lang_key, png_charp text)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iTXt;
+#endif
+   png_size_t lang_len, key_len, lang_key_len, text_len;
+   png_charp new_lang, new_key;
+   png_byte cbuf[2];
+   compression_state comp;
+
+   png_debug(1, "in png_write_iTXt\n");
+
+   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in iTXt chunk");
+      return;
+   }
+   if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
+   {
+      png_warning(png_ptr, "Empty language field in iTXt chunk");
+      new_lang = NULL;
+      lang_len = 0;
+   }
+
+   if (lang_key == NULL)
+     lang_key_len = 0;
+   else
+     lang_key_len = png_strlen(lang_key);
+
+   if (text == NULL)
+      text_len = 0;
+   else
+     text_len = png_strlen(text);
+
+   /* compute the compressed data; do it now for the length */
+   text_len = png_text_compress(png_ptr, text, text_len, compression-2,
+      &comp);
+
+
+   /* make sure we include the compression flag, the compression byte,
+    * and the NULs after the key, lang, and lang_key parts */
+
+   png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
+          (png_uint_32)(
+        5 /* comp byte, comp flag, terminators for key, lang and lang_key */
+        + key_len
+        + lang_len
+        + lang_key_len
+        + text_len));
+
+   /*
+    * We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
+   png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+
+   /* set the compression flag */
+   if (compression == PNG_ITXT_COMPRESSION_NONE || \
+       compression == PNG_TEXT_COMPRESSION_NONE)
+       cbuf[0] = 0;
+   else /* compression == PNG_ITXT_COMPRESSION_zTXt */
+       cbuf[0] = 1;
+   /* set the compression method */
+   cbuf[1] = 0;
+   png_write_chunk_data(png_ptr, cbuf, 2);
+
+   cbuf[0] = 0;
+   png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1);
+   png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1);
+   png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_key);
+   if (new_lang)
+     png_free(png_ptr, new_lang);
+}
+#endif
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+/* write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+   int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_oFFs;
+#endif
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_oFFs\n");
+   if (unit_type >= PNG_OFFSET_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+   png_save_int_32(buf, x_offset);
+   png_save_int_32(buf + 4, y_offset);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
+}
+#endif
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+/* write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
+   png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pCAL;
+#endif
+   png_size_t purpose_len, units_len, total_len;
+   png_uint_32p params_len;
+   png_byte buf[10];
+   png_charp new_purpose;
+   int i;
+
+   png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
+   if (type >= PNG_EQUATION_LAST)
+      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+   purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
+   png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len);
+   units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
+   png_debug1(3, "pCAL units length = %d\n", (int)units_len);
+   total_len = purpose_len + units_len + 10;
+
+   params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
+      *png_sizeof(png_uint_32)));
+
+   /* Find the length of each parameter, making sure we don't count the
+      null terminator for the last parameter. */
+   for (i = 0; i < nparams; i++)
+   {
+      params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+      png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]);
+      total_len += (png_size_t)params_len[i];
+   }
+
+   png_debug1(3, "pCAL total length = %d\n", (int)total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
+   png_save_int_32(buf, X0);
+   png_save_int_32(buf + 4, X1);
+   buf[8] = (png_byte)type;
+   buf[9] = (png_byte)nparams;
+   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+   png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
+
+   png_free(png_ptr, new_purpose);
+
+   for (i = 0; i < nparams; i++)
+   {
+      png_write_chunk_data(png_ptr, (png_bytep)params[i],
+         (png_size_t)params_len[i]);
+   }
+
+   png_free(png_ptr, params_len);
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+/* write the sCAL chunk */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+void /* PRIVATE */
+png_write_sCAL(png_structp png_ptr, int unit, double width,double height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sCAL;
+#endif
+   png_size_t total_len;
+   char wbuf[32], hbuf[32];
+   png_byte bunit = unit;
+
+   png_debug(1, "in png_write_sCAL\n");
+
+#if defined(_WIN32_WCE)
+/* sprintf() function is not supported on WindowsCE */
+   {
+      wchar_t wc_buf[32];
+      swprintf(wc_buf, TEXT("%12.12e"), width);
+      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, wbuf, 32, NULL, NULL);
+      swprintf(wc_buf, TEXT("%12.12e"), height);
+      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, hbuf, 32, NULL, NULL);
+   }
+#else
+   sprintf(wbuf, "%12.12e", width);
+   sprintf(hbuf, "%12.12e", height);
+#endif
+   total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf);
+
+   png_debug1(3, "sCAL total length = %d\n", (int)total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1);
+   png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1);
+   png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf));
+
+   png_write_chunk_end(png_ptr);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
+   png_charp height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sCAL;
+#endif
+   png_size_t total_len;
+   char wbuf[32], hbuf[32];
+   png_byte bunit = unit;
+
+   png_debug(1, "in png_write_sCAL_s\n");
+
+   png_strcpy(wbuf,(const char *)width);
+   png_strcpy(hbuf,(const char *)height);
+   total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf);
+
+   png_debug1(3, "sCAL total length = %d\n", total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1);
+   png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1);
+   png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf));
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+/* write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
+   png_uint_32 y_pixels_per_unit,
+   int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pHYs;
+#endif
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_pHYs\n");
+   if (unit_type >= PNG_RESOLUTION_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+   png_save_uint_32(buf, x_pixels_per_unit);
+   png_save_uint_32(buf + 4, y_pixels_per_unit);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structp png_ptr, png_timep mod_time)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tIME;
+#endif
+   png_byte buf[7];
+
+   png_debug(1, "in png_write_tIME\n");
+   if (mod_time->month  > 12 || mod_time->month  < 1 ||
+       mod_time->day    > 31 || mod_time->day    < 1 ||
+       mod_time->hour   > 23 || mod_time->second > 60)
+   {
+      png_warning(png_ptr, "Invalid time specified for tIME chunk");
+      return;
+   }
+
+   png_save_uint_16(buf, mod_time->year);
+   buf[2] = mod_time->month;
+   buf[3] = mod_time->day;
+   buf[4] = mod_time->hour;
+   buf[5] = mod_time->minute;
+   buf[6] = mod_time->second;
+
+   png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   png_size_t buf_size;
+
+   png_debug(1, "in png_write_start_row\n");
+   buf_size = (png_size_t)(PNG_ROWBYTES(
+      png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1);
+
+   /* set up row buffer */
+   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+   /* set up filtering buffer, if using this filter */
+   if (png_ptr->do_filter & PNG_FILTER_SUB)
+   {
+      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+         (png_ptr->rowbytes + 1));
+      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+   }
+
+   /* We only need to keep the previous row if we are using one of these. */
+   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+   {
+     /* set up previous row buffer */
+      png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+      png_memset(png_ptr->prev_row, 0, buf_size);
+
+      if (png_ptr->do_filter & PNG_FILTER_UP)
+      {
+         png_ptr->up_row = (png_bytep )png_malloc(png_ptr,
+            (png_ptr->rowbytes + 1));
+         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+      }
+
+      if (png_ptr->do_filter & PNG_FILTER_AVG)
+      {
+         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+            (png_ptr->rowbytes + 1));
+         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+      }
+
+      if (png_ptr->do_filter & PNG_FILTER_PAETH)
+      {
+         png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr,
+            (png_ptr->rowbytes + 1));
+         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+      }
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* if interlaced, we need to set up width and height of pass */
+   if (png_ptr->interlaced)
+   {
+      if (!(png_ptr->transformations & PNG_INTERLACE))
+      {
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+            png_pass_ystart[0]) / png_pass_yinc[0];
+         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+            png_pass_start[0]) / png_pass_inc[0];
+      }
+      else
+      {
+         png_ptr->num_rows = png_ptr->height;
+         png_ptr->usr_width = png_ptr->width;
+      }
+   }
+   else
+#endif
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->usr_width = png_ptr->width;
+   }
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+}
+
+/* Internal use only.  Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   int ret;
+
+   png_debug(1, "in png_write_finish_row\n");
+   /* next row */
+   png_ptr->row_number++;
+
+   /* see if we are done */
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* if interlaced, go to next pass */
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      if (png_ptr->transformations & PNG_INTERLACE)
+      {
+         png_ptr->pass++;
+      }
+      else
+      {
+         /* loop until we find a non-zero width or height pass */
+         do
+         {
+            png_ptr->pass++;
+            if (png_ptr->pass >= 7)
+               break;
+            png_ptr->usr_width = (png_ptr->width +
+               png_pass_inc[png_ptr->pass] - 1 -
+               png_pass_start[png_ptr->pass]) /
+               png_pass_inc[png_ptr->pass];
+            png_ptr->num_rows = (png_ptr->height +
+               png_pass_yinc[png_ptr->pass] - 1 -
+               png_pass_ystart[png_ptr->pass]) /
+               png_pass_yinc[png_ptr->pass];
+            if (png_ptr->transformations & PNG_INTERLACE)
+               break;
+         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+      }
+
+      /* reset the row above the image for the next pass */
+      if (png_ptr->pass < 7)
+      {
+         if (png_ptr->prev_row != NULL)
+            png_memset(png_ptr->prev_row, 0,
+               (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+               png_ptr->usr_bit_depth,png_ptr->width))+1);
+         return;
+      }
+   }
+#endif
+
+   /* if we get here, we've just written the last row, so we need
+      to flush the compressor */
+   do
+   {
+      /* tell the compressor we are done */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+      /* check for an error */
+      if (ret == Z_OK)
+      {
+         /* check to see if we need more room */
+         if (!(png_ptr->zstream.avail_out))
+         {
+            png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+            png_ptr->zstream.next_out = png_ptr->zbuf;
+            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         }
+      }
+      else if (ret != Z_STREAM_END)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* write any extra space */
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+   {
+      png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
+         png_ptr->zstream.avail_out);
+   }
+
+   deflateReset(&png_ptr->zstream);
+}
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass.  As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+   png_debug(1, "in png_do_write_interlace\n");
+   /* we don't have to do anything on the last pass (6) */
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL && pass < 6)
+#else
+   if (pass < 6)
+#endif
+   {
+      /* each pixel depth is handled separately */
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            d = 0;
+            shift = 7;
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 3);
+               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 7;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift--;
+
+            }
+            if (shift != 7)
+               *dp = (png_byte)d;
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            shift = 6;
+            d = 0;
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 2);
+               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift -= 2;
+            }
+            if (shift != 6)
+                   *dp = (png_byte)d;
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            shift = 4;
+            d = 0;
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 1);
+               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift -= 4;
+            }
+            if (shift != 4)
+               *dp = (png_byte)d;
+            break;
+         }
+         default:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+            png_size_t pixel_bytes;
+
+            /* start at the beginning */
+            dp = row;
+            /* find out how many bytes each pixel takes up */
+            pixel_bytes = (row_info->pixel_depth >> 3);
+            /* loop through the row, only looking at the pixels that
+               matter */
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               /* find out where the original pixel is */
+               sp = row + (png_size_t)i * pixel_bytes;
+               /* move the pixel */
+               if (dp != sp)
+                  png_memcpy(dp, sp, pixel_bytes);
+               /* next pixel */
+               dp += pixel_bytes;
+            }
+            break;
+         }
+      }
+      /* set new row width */
+      row_info->width = (row_info->width +
+         png_pass_inc[pass] - 1 -
+         png_pass_start[pass]) /
+         png_pass_inc[pass];
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+            row_info->width);
+   }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+#define PNG_MAXSUM (~((png_uint_32)0) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void /* PRIVATE */
+png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
+{
+   png_bytep prev_row, best_row, row_buf;
+   png_uint_32 mins, bpp;
+   png_byte filter_to_do = png_ptr->do_filter;
+   png_uint_32 row_bytes = row_info->rowbytes;
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   int num_p_filters = (int)png_ptr->num_prev_filters;
+#endif
+
+   png_debug(1, "in png_write_find_filter\n");
+   /* find out how many bytes offset each pixel is */
+   bpp = (row_info->pixel_depth + 7) >> 3;
+
+   prev_row = png_ptr->prev_row;
+   best_row = row_buf = png_ptr->row_buf;
+   mins = PNG_MAXSUM;
+
+   /* The prediction method we use is to find which method provides the
+    * smallest value when summing the absolute values of the distances
+    * from zero, using anything >= 128 as negative numbers.  This is known
+    * as the "minimum sum of absolute differences" heuristic.  Other
+    * heuristics are the "weighted minimum sum of absolute differences"
+    * (experimental and can in theory improve compression), and the "zlib
+    * predictive" method (not implemented yet), which does test compressions
+    * of lines using different filter methods, and then chooses the
+    * (series of) filter(s) that give minimum compressed data size (VERY
+    * computationally expensive).
+    *
+    * GRR 980525:  consider also
+    *   (1) minimum sum of absolute differences from running average (i.e.,
+    *       keep running sum of non-absolute differences & count of bytes)
+    *       [track dispersion, too?  restart average if dispersion too large?]
+    *  (1b) minimum sum of absolute differences from sliding average, probably
+    *       with window size <= deflate window (usually 32K)
+    *   (2) minimum sum of squared differences from zero or running average
+    *       (i.e., ~ root-mean-square approach)
+    */
+
+
+   /* We don't need to test the 'no filter' case if this is the only filter
+    * that has been chosen, as it doesn't actually do anything to the data.
+    */
+   if ((filter_to_do & PNG_FILTER_NONE) &&
+       filter_to_do != PNG_FILTER_NONE)
+   {
+      png_bytep rp;
+      png_uint_32 sum = 0;
+      png_uint_32 i;
+      int v;
+
+      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+      {
+         v = *rp;
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         int j;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+         /* Reduce the sum if we match any of the previous rows */
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         /* Factor in the cost of this filter (this is here for completeness,
+          * but it makes no sense to have a "cost" for the NONE filter, as
+          * it has the minimum possible computational cost - none).
+          */
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+      mins = sum;
+   }
+
+   /* sub filter */
+   if (filter_to_do == PNG_FILTER_SUB)
+   /* it's the only filter so no testing is needed */
+   {
+      png_bytep rp, lp, dp;
+      png_uint_32 i;
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+           i++, rp++, dp++)
+      {
+         *dp = *rp;
+      }
+      for (lp = row_buf + 1; i < row_bytes;
+         i++, rp++, lp++, dp++)
+      {
+         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+      }
+      best_row = png_ptr->sub_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_SUB)
+   {
+      png_bytep rp, dp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      /* We temporarily increase the "minimum sum" by the factor we
+       * would reduce the sum of this filter, so that we can do the
+       * early exit comparison without scaling the sum each time.
+       */
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+           i++, rp++, dp++)
+      {
+         v = *dp = *rp;
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+      for (lp = row_buf + 1; i < row_bytes;
+         i++, rp++, lp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+            {
+               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->sub_row;
+      }
+   }
+
+   /* up filter */
+   if (filter_to_do == PNG_FILTER_UP)
+   {
+      png_bytep rp, dp, pp;
+      png_uint_32 i;
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+           pp = prev_row + 1; i < row_bytes;
+           i++, rp++, pp++, dp++)
+      {
+         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+      }
+      best_row = png_ptr->up_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_UP)
+   {
+      png_bytep rp, dp, pp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+           pp = prev_row + 1; i < row_bytes; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->up_row;
+      }
+   }
+
+   /* avg filter */
+   if (filter_to_do == PNG_FILTER_AVG)
+   {
+      png_bytep rp, dp, pp, lp;
+      png_uint_32 i;
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+      }
+      for (lp = row_buf + 1; i < row_bytes; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+                 & 0xff);
+      }
+      best_row = png_ptr->avg_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_AVG)
+   {
+      png_bytep rp, dp, pp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+      for (lp = row_buf + 1; i < row_bytes; i++)
+      {
+         v = *dp++ =
+          (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->avg_row;
+      }
+   }
+
+   /* Paeth filter */
+   if (filter_to_do == PNG_FILTER_PAETH)
+   {
+      png_bytep rp, dp, pp, cp, lp;
+      png_uint_32 i;
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+      }
+
+      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+      {
+         int a, b, c, pa, pb, pc, p;
+
+         b = *pp++;
+         c = *cp++;
+         a = *lp++;
+
+         p = b - c;
+         pc = a - c;
+
+#ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+      }
+      best_row = png_ptr->paeth_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_PAETH)
+   {
+      png_bytep rp, dp, pp, cp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+      {
+         int a, b, c, pa, pb, pc, p;
+
+         b = *pp++;
+         c = *cp++;
+         a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+         p = b - c;
+         pc = a - c;
+#ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* PNG_SLOW_PAETH */
+         p = a + b - c;
+         pa = abs(p - a);
+         pb = abs(p - b);
+         pc = abs(p - c);
+         if (pa <= pb && pa <= pc)
+            p = a;
+         else if (pb <= pc)
+            p = b;
+         else
+            p = c;
+#endif /* PNG_SLOW_PAETH */
+
+         v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         best_row = png_ptr->paeth_row;
+      }
+   }
+
+   /* Do the actual writing of the filtered row data from the chosen filter. */
+
+   png_write_filtered_row(png_ptr, best_row);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   /* Save the type of filter we picked this time for future calculations */
+   if (png_ptr->num_prev_filters > 0)
+   {
+      int j;
+      for (j = 1; j < num_p_filters; j++)
+      {
+         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+      }
+      png_ptr->prev_filters[j] = best_row[0];
+   }
+#endif
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+void /* PRIVATE */
+png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
+{
+   png_debug(1, "in png_write_filtered_row\n");
+   png_debug1(2, "filter = %d\n", filtered_row[0]);
+   /* set up the zlib input buffer */
+
+   png_ptr->zstream.next_in = filtered_row;
+   png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
+   /* repeat until we have compressed all the data */
+   do
+   {
+      int ret; /* return of zlib */
+
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      /* check for compression errors */
+      if (ret != Z_OK)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      /* see if it is time to write another IDAT */
+      if (!(png_ptr->zstream.avail_out))
+      {
+         /* write the IDAT and reset the zlib output buffer */
+         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+      }
+   /* repeat until all data has been compressed */
+   } while (png_ptr->zstream.avail_in);
+
+   /* swap the current and previous rows */
+   if (png_ptr->prev_row != NULL)
+   {
+      png_bytep tptr;
+
+      tptr = png_ptr->prev_row;
+      png_ptr->prev_row = png_ptr->row_buf;
+      png_ptr->row_buf = tptr;
+   }
+
+   /* finish row - updates counters and flushes zlib if last row */
+   png_write_finish_row(png_ptr);
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+   png_ptr->flush_rows++;
+
+   if (png_ptr->flush_dist > 0 &&
+       png_ptr->flush_rows >= png_ptr->flush_dist)
+   {
+      png_write_flush(png_ptr);
+   }
+#endif
+}
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Utilities/FLTK/src/CMakeLists.txt b/Utilities/FLTK/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..addde02f44fe24112dc4be09f8b0b6886c46aec8
--- /dev/null
+++ b/Utilities/FLTK/src/CMakeLists.txt
@@ -0,0 +1,217 @@
+SET(CPPFILES
+  Fl.cxx
+  Fl_Adjuster.cxx
+  Fl_Bitmap.cxx
+  Fl_Browser.cxx
+  Fl_Browser_.cxx
+  Fl_Browser_load.cxx
+  Fl_Box.cxx
+  Fl_Button.cxx
+  Fl_Chart.cxx
+  Fl_Check_Browser.cxx
+  Fl_Check_Button.cxx
+  Fl_Choice.cxx
+  Fl_Clock.cxx
+  Fl_Color_Chooser.cxx
+  Fl_Counter.cxx
+  Fl_Dial.cxx
+  Fl_Double_Window.cxx
+  Fl_File_Browser.cxx
+  Fl_File_Chooser.cxx
+  Fl_File_Chooser2.cxx
+  Fl_File_Icon.cxx
+  Fl_File_Input.cxx
+  Fl_Group.cxx
+  Fl_Help_View.cxx
+  Fl_Image.cxx
+  Fl_Input.cxx
+  Fl_Input_.cxx
+  Fl_Light_Button.cxx
+  Fl_Menu.cxx
+  Fl_Menu_.cxx
+  Fl_Menu_Bar.cxx
+  Fl_Sys_Menu_Bar.cxx
+  Fl_Menu_Button.cxx
+  Fl_Menu_Window.cxx
+  Fl_Menu_add.cxx
+  Fl_Menu_global.cxx
+  Fl_Multi_Label.cxx
+  Fl_Overlay_Window.cxx
+  Fl_Pack.cxx
+  Fl_Pixmap.cxx
+  Fl_Positioner.cxx
+  Fl_Preferences.cxx
+  Fl_Progress.cxx
+  Fl_Repeat_Button.cxx
+  Fl_Return_Button.cxx
+  Fl_Roller.cxx
+  Fl_Round_Button.cxx
+  Fl_Scroll.cxx
+  Fl_Scrollbar.cxx
+  Fl_Shared_Image.cxx
+  Fl_Single_Window.cxx
+  Fl_Slider.cxx
+  Fl_Tabs.cxx
+  Fl_Text_Buffer.cxx
+  Fl_Text_Display.cxx
+  Fl_Text_Editor.cxx
+  Fl_Tile.cxx
+  Fl_Tiled_Image.cxx
+  Fl_Tooltip.cxx
+  Fl_Valuator.cxx
+  Fl_Value_Input.cxx
+  Fl_Value_Output.cxx
+  Fl_Value_Slider.cxx
+  Fl_Widget.cxx
+  Fl_Window.cxx
+  Fl_Window_fullscreen.cxx
+  Fl_Window_hotspot.cxx
+  Fl_Window_iconize.cxx
+  Fl_Wizard.cxx
+  Fl_XBM_Image.cxx
+  Fl_XPM_Image.cxx
+  Fl_abort.cxx
+  Fl_add_idle.cxx
+  Fl_arg.cxx
+  Fl_compose.cxx
+  Fl_display.cxx
+  Fl_get_key.cxx
+  Fl_get_system_colors.cxx
+  Fl_grab.cxx
+  Fl_lock.cxx
+  Fl_own_colormap.cxx
+  Fl_visual.cxx
+  Fl_x.cxx
+  filename_absolute.cxx
+  filename_expand.cxx
+  filename_ext.cxx
+  filename_isdir.cxx
+  filename_list.cxx
+  filename_match.cxx
+  filename_setext.cxx
+  fl_arc.cxx
+  fl_arci.cxx
+  fl_ask.cxx
+  fl_boxtype.cxx
+  fl_color.cxx
+  fl_cursor.cxx
+  fl_curve.cxx
+  fl_diamond_box.cxx
+  fl_dnd.cxx
+  fl_draw.cxx
+  fl_draw_image.cxx
+  fl_draw_pixmap.cxx
+  fl_engraved_label.cxx
+  fl_file_dir.cxx
+  fl_font.cxx
+  fl_labeltype.cxx
+  fl_line_style.cxx
+  fl_oval_box.cxx
+  fl_overlay.cxx
+  fl_overlay_visual.cxx
+  fl_plastic.cxx
+  fl_read_image.cxx
+  fl_rect.cxx
+  fl_round_box.cxx
+  fl_rounded_box.cxx
+  fl_set_font.cxx
+  fl_set_fonts.cxx
+  fl_scroll_area.cxx
+  fl_shadow_box.cxx
+  fl_shortcut.cxx
+  fl_show_colormap.cxx
+  fl_symbols.cxx
+  fl_vertex.cxx
+	screen_xywh.cxx
+  )
+SET(FLCPPFILES
+  forms_compatability.cxx
+  forms_bitmap.cxx
+  forms_free.cxx
+  forms_fselect.cxx
+  forms_pixmap.cxx
+  forms_timer.cxx
+  )
+SET(GLCPPFILES
+  Fl_Gl_Choice.cxx
+  Fl_Gl_Overlay.cxx
+  Fl_Gl_Window.cxx
+  gl_draw.cxx
+  gl_start.cxx
+  glut_compatability.cxx
+  glut_font.cxx
+  )
+SET(IMGCPPFILES
+  fl_images_core.cxx
+  Fl_BMP_Image.cxx
+  Fl_File_Icon2.cxx
+  Fl_GIF_Image.cxx
+  Fl_Help_Dialog.cxx
+  Fl_JPEG_Image.cxx
+  Fl_PNG_Image.cxx
+  Fl_PNM_Image.cxx
+  )
+
+SET(CFILES 
+  fl_call_main.c
+  flstring.c
+  scandir.c
+  numericsort.c
+  vsnprintf.c
+  )
+
+ADD_LIBRARY(fltk ${CPPFILES} ${CFILES})
+#INSTALL_TARGETS(/lib fltk)
+INSTALL(TARGETS fltk
+        RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries
+        LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
+        ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT Development)
+SET_TARGET_PROPERTIES(fltk
+  PROPERTIES
+  VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
+  SOVERSION ${FLTK_VERSION_PATCH})
+
+TARGET_LINK_LIBRARIES(fltk ${FLTK_PLATFORM_DEPENDENT_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+
+IF(X11_FOUND)
+  TARGET_LINK_LIBRARIES(fltk ${X11_LIBRARIES})
+ENDIF(X11_FOUND)
+
+IF(OPENGL_FOUND)
+  ADD_LIBRARY(fltk_gl ${GLCPPFILES})
+#  INSTALL_TARGETS(/lib fltk_gl)
+  INSTALL(TARGETS fltk_gl
+        RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries
+        LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
+        ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT Development)
+  TARGET_LINK_LIBRARIES(fltk_gl fltk ${OPENGL_LIBRARIES})
+  SET_TARGET_PROPERTIES(fltk_gl
+    PROPERTIES
+    VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
+    SOVERSION ${FLTK_VERSION_PATCH})
+ENDIF(OPENGL_FOUND)
+
+ADD_LIBRARY(fltk_forms ${FLCPPFILES})
+#INSTALL_TARGETS(/lib fltk_forms)
+INSTALL(TARGETS fltk_forms
+        RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries
+        LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
+        ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT Development)
+TARGET_LINK_LIBRARIES(fltk_forms fltk)
+SET_TARGET_PROPERTIES(fltk_forms
+  PROPERTIES
+  VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
+  SOVERSION ${FLTK_VERSION_PATCH})
+
+ADD_LIBRARY(fltk_images ${IMGCPPFILES})
+#INSTALL_TARGETS(/lib fltk_images)
+INSTALL(TARGETS fltk_images
+        RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries
+        LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
+        ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT Development)
+TARGET_LINK_LIBRARIES(fltk_images fltk ${FLTK_PNG_LIBRARIES}
+     ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES})
+SET_TARGET_PROPERTIES(fltk_images
+  PROPERTIES
+  VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
+  SOVERSION ${FLTK_VERSION_PATCH})
diff --git a/Utilities/FLTK/src/Fl.cxx b/Utilities/FLTK/src/Fl.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..17967a783130dca7507ce85eb4dc1850137d8d33
--- /dev/null
+++ b/Utilities/FLTK/src/Fl.cxx
@@ -0,0 +1,1203 @@
+//
+// "$Id$"
+//
+// Main event handling code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// warning: the Apple Quartz version still uses some Quickdraw calls,
+//          mostly to get around the single active context in QD and 
+//          to implement clipping. This should be changed into pure
+//          Quartz calls in the near future.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#include <FL/Fl_Tooltip.H>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+#ifdef DEBUG
+#  include <stdio.h>
+#endif // DEBUG
+
+#ifdef WIN32
+#  include <ole2.h>
+void fl_free_fonts(void);
+HBRUSH fl_brush_action(int action);
+void fl_cleanup_pens(void);
+void fl_release_dc(HWND,HDC);
+void fl_cleanup_dc_list(void);
+#endif // WIN32
+
+//
+// Globals...
+//
+
+Fl_Widget	*Fl::belowmouse_,
+		*Fl::pushed_,
+		*Fl::focus_,
+		*Fl::selection_owner_;
+int		Fl::damage_,
+		Fl::e_number,
+		Fl::e_x,
+		Fl::e_y,
+		Fl::e_x_root,
+		Fl::e_y_root,
+		Fl::e_dx,
+		Fl::e_dy,
+		Fl::e_state,
+		Fl::e_clicks,
+		Fl::e_is_click,
+		Fl::e_keysym;
+char		*Fl::e_text = (char *)"";
+int		Fl::e_length;
+int		Fl::visible_focus_ = 1,
+		Fl::dnd_text_ops_ = 1;
+
+
+//
+// 'Fl::version()' - Return the API version number...
+//
+
+double
+Fl::version() {
+  return FL_VERSION;
+}
+
+
+//
+// 'Fl:event_inside()' - Return whether or not the mouse event is inside
+//                       the given rectangle.
+//
+
+int Fl::event_inside(int xx,int yy,int ww,int hh) /*const*/ {
+  int mx = e_x - xx;
+  int my = e_y - yy;
+  return (mx >= 0 && mx < ww && my >= 0 && my < hh);
+}
+
+int Fl::event_inside(const Fl_Widget *o) /*const*/ {
+  int mx = e_x - o->x();
+  int my = e_y - o->y();
+  return (mx >= 0 && mx < o->w() && my >= 0 && my < o->h());
+}
+
+//
+//
+// timer support
+//
+
+#ifdef WIN32
+
+/// implementation in Fl_win32.cxx
+
+#elif defined(__APPLE__)
+
+/// implementation in Fl_mac.cxx
+
+#else
+
+//
+// X11 timers
+//
+
+
+////////////////////////////////////////////////////////////////
+// Timeouts are stored in a sorted list, so only the first one needs
+// to be checked to see if any should be called.
+  
+struct Timeout {
+  double time;
+  void (*cb)(void*);
+  void* arg;
+  Timeout* next;
+};
+static Timeout* first_timeout, *free_timeout;
+static int first_timeout_count, free_timeout_count;
+
+#include <sys/time.h>
+
+// I avoid the overhead of getting the current time when we have no
+// timeouts by setting this flag instead of getting the time.
+// In this case calling elapse_timeouts() does nothing, but records
+// the current time, and the next call will actualy elapse time.
+static char reset_clock = 1;
+
+static void elapse_timeouts() {
+  static struct timeval prevclock;
+  struct timeval newclock;
+  gettimeofday(&newclock, NULL);
+  double elapsed = newclock.tv_sec - prevclock.tv_sec +
+    (newclock.tv_usec - prevclock.tv_usec)/1000000.0;
+  prevclock.tv_sec = newclock.tv_sec;
+  prevclock.tv_usec = newclock.tv_usec;
+  if (reset_clock) {
+    reset_clock = 0;
+  } else if (elapsed > 0) {
+    for (Timeout* t = first_timeout; t; t = t->next) t->time -= elapsed;
+  }
+}
+
+// Continuously-adjusted error value, this is a number <= 0 for how late
+// we were at calling the last timeout. This appears to make repeat_timeout
+// very accurate even when processing takes a significant portion of the
+// time interval:
+static double missed_timeout_by;
+
+void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
+  elapse_timeouts();
+  repeat_timeout(time, cb, argp);
+}
+
+void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
+  time += missed_timeout_by; if (time < -.05) time = 0;
+  Timeout* t = free_timeout;
+  if (t) {
+      free_timeout = t->next;
+      --free_timeout_count;
+  } else {
+      t = new Timeout;
+  }
+  t->time = time;
+  t->cb = cb;
+  t->arg = argp;
+  // insert-sort the new timeout:
+  Timeout** p = &first_timeout; 
+  while (*p && (*p)->time <= time) p = &((*p)->next);
+  t->next = *p;
+  *p = t;
+}
+
+int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) {
+  for (Timeout* t = first_timeout; t; t = t->next)
+    if (t->cb == cb && t->arg == argp) return 1;
+  return 0;
+}
+
+void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) {
+  // This version removes all matching timeouts, not just the first one.
+  // This may change in the future.
+  for (Timeout** p = &first_timeout; *p;) {
+    Timeout* t = *p;
+    if (t->cb == cb && (t->arg == argp || !argp)) {
+      *p = t->next;
+      t->next = free_timeout;
+      free_timeout = t;
+    } else {
+      p = &(t->next);
+    }
+  }
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////
+// Checks are just stored in a list. They are called in the reverse
+// order that they were added (this may change in the future).
+// This is a bit messy because I want to allow checks to be added,
+// removed, and have wait() called from inside them, to do this
+// next_check points at the next unprocessed one for the outermost
+// call to Fl::wait().
+
+struct Check {
+  void (*cb)(void*);
+  void* arg;
+  Check* next;
+};
+static Check *first_check, *next_check, *free_check;
+
+void Fl::add_check(Fl_Timeout_Handler cb, void *argp) {
+  Check* t = free_check;
+  if (t) free_check = t->next;
+  else t = new Check;
+  t->cb = cb;
+  t->arg = argp;
+  t->next = first_check;
+  if (next_check == first_check) next_check = t;
+  first_check = t;
+}
+
+void Fl::remove_check(Fl_Timeout_Handler cb, void *argp) {
+  for (Check** p = &first_check; *p;) {
+    Check* t = *p;
+    if (t->cb == cb && t->arg == argp) {
+      if (next_check == t) next_check = t->next;
+      *p = t->next;
+      t->next = free_check;
+      free_check = t;
+    } else {
+      p = &(t->next);
+    }
+  }
+}
+
+#if !defined(__APPLE__)
+static void run_checks()
+{
+  // checks are a bit messy so that add/remove and wait may be called
+  // from inside them without causing an infinite loop:
+  if (next_check == first_check) {
+    while (next_check) {
+      Check* checkp = next_check;
+      next_check = checkp->next;
+      (checkp->cb)(checkp->arg);
+    }
+    next_check = first_check;
+  }
+}
+#endif // !__APPLE__
+
+static char in_idle;
+
+////////////////////////////////////////////////////////////////
+// wait/run/check/ready:
+
+void (*Fl::idle)(); // see Fl_add_idle.cxx for the add/remove functions
+
+extern int fl_ready(); // in Fl_<platform>.cxx
+extern int fl_wait(double time); // in Fl_<platform>.cxx
+
+double Fl::wait(double time_to_wait) {
+  // delete all widgets that were listed during callbacks
+  do_widget_deletion();
+
+#ifdef WIN32
+
+  return fl_wait(time_to_wait);
+
+#elif defined(__APPLE__)
+
+  flush();
+  if (idle) {
+    if (!in_idle) {
+      in_idle = 1;
+      idle();
+      in_idle = 0;
+    }
+    // the idle function may turn off idle, we can then wait:
+    if (idle) time_to_wait = 0.0;
+  }
+  return fl_wait(time_to_wait);
+
+#else
+
+  if (first_timeout) {
+    elapse_timeouts();
+    Timeout *t;
+    while ((t = first_timeout)) {
+      if (t->time > 0) break;
+      // The first timeout in the array has expired.
+      missed_timeout_by = t->time;
+      // We must remove timeout from array before doing the callback:
+      void (*cb)(void*) = t->cb;
+      void *argp = t->arg;
+      first_timeout = t->next;
+      t->next = free_timeout;
+      free_timeout = t;
+      ++free_timeout_count;
+      --first_timeout_count;
+      // Now it is safe for the callback to do add_timeout:
+      cb(argp);
+    }
+  } else {
+    reset_clock = 1; // we are not going to check the clock
+  }
+  run_checks();
+//  if (idle && !fl_ready()) {
+  if (idle) {
+    if (!in_idle) {
+      in_idle = 1;
+      idle();
+      in_idle = 0;
+    }
+    // the idle function may turn off idle, we can then wait:
+    if (idle) time_to_wait = 0.0;
+  }
+  if (first_timeout && first_timeout->time < time_to_wait)
+    time_to_wait = first_timeout->time;
+  if (time_to_wait <= 0.0) {
+    // do flush second so that the results of events are visible:
+    int ret = fl_wait(0.0);
+    flush();
+    return ret;
+  } else {
+    // do flush first so that user sees the display:
+    flush();
+    return fl_wait(time_to_wait);
+  }
+#endif
+}
+
+#define FOREVER 1e20
+
+int Fl::run() {
+  while (Fl_X::first) wait(FOREVER);
+#ifdef WIN32
+  fl_free_fonts();        // do some WIN32 cleanup
+  fl_cleanup_pens();
+  OleUninitialize();
+  fl_brush_action(1);
+  fl_cleanup_dc_list();
+#endif
+  return 0;
+}
+
+int Fl::wait() {
+  if (!Fl_X::first) return 0;
+  wait(FOREVER);
+  return Fl_X::first != 0; // return true if there is a window
+}
+
+int Fl::check() {
+  wait(0.0);
+  return Fl_X::first != 0; // return true if there is a window
+}
+
+int Fl::ready() {
+#if ! defined( WIN32 )  &&  ! defined(__APPLE__)
+  if (first_timeout) {
+    elapse_timeouts();
+    if (first_timeout->time <= 0) return 1;
+  } else {
+    reset_clock = 1;
+  }
+#endif
+  return fl_ready();
+}
+
+////////////////////////////////////////////////////////////////
+// Window list management:
+
+Fl_X* Fl_X::first;
+
+Fl_Window* fl_find(Window xid) {
+  Fl_X *window;
+  for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next)
+#ifdef __APPLE_QD__
+    if (window->xid == xid && !window->w->window()) {
+#elif defined(__APPLE_QUARTZ__)
+    if (window->xid == xid && !window->w->window()) {
+#else
+    if (window->xid == xid) {
+#endif // __APPLE__
+      if (window != Fl_X::first && !Fl::modal()) {
+	// make this window be first to speed up searches
+	// this is not done if modal is true to avoid messing up modal stack
+	*pp = window->next;
+	window->next = Fl_X::first;
+	Fl_X::first = window;
+      }
+      return window->w;
+    }
+  return 0;
+}
+
+Fl_Window* Fl::first_window() {
+  Fl_X* i = Fl_X::first;
+  return i ? i->w : 0;
+}
+
+Fl_Window* Fl::next_window(const Fl_Window* window) {
+  Fl_X* i = Fl_X::i(window)->next;
+  return i ? i->w : 0;
+}
+
+void Fl::first_window(Fl_Window* window) {
+  if (!window || !window->shown()) return;
+  fl_find(fl_xid(window));
+}
+
+void Fl::redraw() {
+  for (Fl_X* i = Fl_X::first; i; i = i->next) i->w->redraw();
+}
+
+void Fl::flush() {
+  if (damage()) {
+    damage_ = 0;
+    for (Fl_X* i = Fl_X::first; i; i = i->next) {
+      if (i->wait_for_expose) {damage_ = 1; continue;}
+      Fl_Window* wi = i->w;
+      if (!wi->visible_r()) continue;
+      if (wi->damage()) {i->flush(); wi->clear_damage();}
+      // destroy damage regions for windows that don't use them:
+      if (i->region) {XDestroyRegion(i->region); i->region = 0;}
+    }
+  }
+
+#ifdef WIN32
+  GdiFlush();
+#elif defined(__APPLE_QD__)
+  GrafPtr port;
+  GetPort( &port );
+  if ( port )
+    QDFlushPortBuffer( port, 0 );
+#elif defined (__APPLE_QUARTZ__)
+  if (fl_gc)
+    CGContextFlush(fl_gc);
+#else
+  if (fl_display) XFlush(fl_display);
+#endif
+}
+
+////////////////////////////////////////////////////////////////
+// Event handlers:
+
+struct handler_link {
+  int (*handle)(int);
+  handler_link *next;
+};
+
+static handler_link *handlers = 0;
+
+void Fl::add_handler(int (*ha)(int)) {
+  handler_link *l = new handler_link;
+  l->handle = ha;
+  l->next = handlers;
+  handlers = l;
+}
+
+void Fl::remove_handler(int (*ha)(int)) {
+  handler_link *l, *p;
+
+  // Search for the handler in the list...
+  for (l = handlers, p = 0; l && l->handle != ha; p = l, l = l->next);
+
+  if (l) {
+    // Found it, so remove it from the list...
+    if (p) p->next = l->next;
+    else handlers = l->next;
+
+    // And free the record...
+    delete l;
+  }
+}
+
+int (*fl_local_grab)(int); // used by fl_dnd.cxx
+
+static int send_handlers(int e) {
+  for (const handler_link *hl = handlers; hl; hl = hl->next)
+    if (hl->handle(e)) return 1;
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Widget* fl_oldfocus; // kludge for Fl_Group...
+
+void Fl::focus(Fl_Widget *o) {
+  if (o && !o->visible_focus()) return;
+  if (grab()) return; // don't do anything while grab is on
+  Fl_Widget *p = focus_;
+  if (o != p) {
+    Fl::compose_reset();
+    focus_ = o;
+    fl_oldfocus = 0;
+    int old_event = e_number;
+    e_number = FL_UNFOCUS;
+    for (; p; p = p->parent()) {
+      p->handle(FL_UNFOCUS);
+      fl_oldfocus = p;
+    }
+    e_number = old_event;
+  }
+}
+
+static char dnd_flag = 0; // make 'belowmouse' send DND_LEAVE instead of LEAVE
+
+void Fl::belowmouse(Fl_Widget *o) {
+  if (grab()) return; // don't do anything while grab is on
+  Fl_Widget *p = belowmouse_;
+  if (o != p) {
+    belowmouse_ = o;
+    int old_event = e_number;
+    e_number = dnd_flag ? FL_DND_LEAVE : FL_LEAVE;
+    for (; p && !p->contains(o); p = p->parent()) {
+      p->handle(e_number);
+    }
+    e_number = old_event;
+  }
+}
+
+void Fl::pushed(Fl_Widget *o) {
+  pushed_ = o;
+}
+
+Fl_Window *fl_xfocus;	// which window X thinks has focus
+Fl_Window *fl_xmousewin;// which window X thinks has FL_ENTER
+Fl_Window *Fl::grab_;	// most recent Fl::grab()
+Fl_Window *Fl::modal_;	// topmost modal() window
+
+static void nothing(Fl_Widget *) {}
+void (*Fl_Tooltip::enter)(Fl_Widget *) = nothing;
+void (*Fl_Tooltip::exit)(Fl_Widget *) = nothing;
+
+// Update modal(), focus() and other state according to system state,
+// and send FL_ENTER, FL_LEAVE, FL_FOCUS, and/or FL_UNFOCUS events.
+// This is the only function that produces these events in response
+// to system activity.
+// This is called whenever a window is added or hidden, and whenever
+// X says the focus or mouse window have changed.
+
+void fl_fix_focus() {
+#ifdef DEBUG
+  puts("fl_fix_focus();");
+#endif // DEBUG
+
+  if (Fl::grab()) return; // don't do anything while grab is on.
+
+  // set focus based on Fl::modal() and fl_xfocus
+  Fl_Widget* w = fl_xfocus;
+  if (w) {
+    int saved = Fl::e_keysym;
+    if (Fl::e_keysym < (FL_Button + FL_LEFT_MOUSE) ||
+        Fl::e_keysym > (FL_Button + FL_RIGHT_MOUSE))
+      Fl::e_keysym = 0; // make sure widgets don't think a keystroke moved focus
+    while (w->parent()) w = w->parent();
+    if (Fl::modal()) w = Fl::modal();
+    if (!w->contains(Fl::focus()))
+      if (!w->take_focus()) Fl::focus(w);
+    Fl::e_keysym = saved;
+  } else
+    Fl::focus(0);
+
+// MRS: Originally we checked the button state, but a user reported that it
+//      broke click-to-focus in FLWM?!?
+//  if (!(Fl::event_state() & 0x7f00000 /*FL_BUTTONS*/)) {
+  if (!Fl::pushed()) {
+    // set belowmouse based on Fl::modal() and fl_xmousewin:
+    w = fl_xmousewin;
+    if (w) {
+      if (Fl::modal()) w = Fl::modal();
+      if (!w->contains(Fl::belowmouse())) {
+        int old_event = Fl::e_number;
+	w->handle(Fl::e_number = FL_ENTER);
+	Fl::e_number = old_event;
+	if (!w->contains(Fl::belowmouse())) Fl::belowmouse(w);
+      } else {
+	// send a FL_MOVE event so the enter/leave state is up to date
+	Fl::e_x = Fl::e_x_root-fl_xmousewin->x();
+	Fl::e_y = Fl::e_y_root-fl_xmousewin->y();
+        int old_event = Fl::e_number;
+	w->handle(Fl::e_number = FL_MOVE);
+	Fl::e_number = old_event;
+      }
+    } else {
+      Fl::belowmouse(0);
+      Fl_Tooltip::enter(0);
+    }
+  }
+}
+
+#ifndef WIN32
+extern Fl_Widget *fl_selection_requestor; // from Fl_x.cxx
+#endif
+
+// This function is called by ~Fl_Widget() and by Fl_Widget::deactivate
+// and by Fl_Widget::hide().  It indicates that the widget does not want
+// to receive any more events, and also removes all global variables that
+// point at the widget.
+// I changed this from the 1.0.1 behavior, the older version could send
+// FL_LEAVE or FL_UNFOCUS events to the widget.  This appears to not be
+// desirable behavior and caused flwm to crash.
+
+void fl_throw_focus(Fl_Widget *o) {
+#ifdef DEBUG
+  printf("fl_throw_focus(o=%p)\n", o);
+#endif // DEBUG
+
+  if (o->contains(Fl::pushed())) Fl::pushed_ = 0;
+#ifndef WIN32
+  if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0;
+#endif
+  if (o->contains(Fl::belowmouse())) Fl::belowmouse_ = 0;
+  if (o->contains(Fl::focus())) Fl::focus_ = 0;
+  if (o == fl_xfocus) fl_xfocus = 0;
+  if (o == Fl_Tooltip::current()) Fl_Tooltip::current(0);
+  if (o == fl_xmousewin) fl_xmousewin = 0;
+  Fl_Tooltip::exit(o);
+  fl_fix_focus();
+}
+
+////////////////////////////////////////////////////////////////
+
+// Call to->handle but first replace the mouse x/y with the correct
+// values to account for nested X windows. 'window' is the outermost
+// window the event was posted to by X:
+static int send(int event, Fl_Widget* to, Fl_Window* window) {
+  int dx, dy;
+  int old_event = Fl::e_number;
+  if (window) {
+    dx = window->x();
+    dy = window->y();
+  } else {
+    dx = dy = 0;
+  }
+  for (const Fl_Widget* w = to; w; w = w->parent())
+    if (w->type()>=FL_WINDOW) {dx -= w->x(); dy -= w->y();}
+  int save_x = Fl::e_x; Fl::e_x += dx;
+  int save_y = Fl::e_y; Fl::e_y += dy;
+  int ret = to->handle(Fl::e_number = event);
+  Fl::e_number = old_event;
+  Fl::e_y = save_y;
+  Fl::e_x = save_x;
+  return ret;
+}
+
+int Fl::handle(int e, Fl_Window* window)
+{
+  e_number = e;
+  if (fl_local_grab) return fl_local_grab(e);
+
+  Fl_Widget* wi = window;
+
+  switch (e) {
+
+  case FL_CLOSE:
+    if (grab() || modal() && window != modal()) return 0;
+    wi->do_callback();
+    return 1;
+
+  case FL_SHOW:
+    wi->show(); // this calls Fl_Widget::show(), not Fl_Window::show()
+    return 1;
+
+  case FL_HIDE:
+    wi->hide(); // this calls Fl_Widget::hide(), not Fl_Window::hide()
+    return 1;
+
+  case FL_PUSH:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    if (grab()) wi = grab();
+    else if (modal() && wi != modal()) return 0;
+    pushed_ = wi;
+    Fl_Tooltip::current(wi);
+    if (send(e, wi, window)) return 1;
+    // raise windows that are clicked on:
+    window->show();
+    return 1;
+
+  case FL_DND_ENTER:
+  case FL_DND_DRAG:
+    dnd_flag = 1;
+    break;
+
+  case FL_DND_LEAVE:
+    dnd_flag = 1;
+    belowmouse(0);
+    dnd_flag = 0;
+    return 1;
+
+  case FL_DND_RELEASE:
+    wi = belowmouse();
+    break;
+
+  case FL_MOVE:
+  case FL_DRAG:
+    fl_xmousewin = window; // this should already be set, but just in case.
+    if (pushed()) {
+      wi = pushed();
+      if (grab()) wi = grab();
+      e_number = e = FL_DRAG;
+      break;
+    }
+    if (modal() && wi != modal()) wi = 0;
+    if (grab()) wi = grab();
+    {Fl_Widget* pbm = belowmouse();
+    int ret = (wi && send(e, wi, window));
+    if (pbm != belowmouse()) {
+#ifdef DEBUG
+      printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+      Fl_Tooltip::enter(belowmouse());
+    }
+    return ret;}
+
+  case FL_RELEASE: {
+//    printf("FL_RELEASE: window=%p, pushed() = %p, grab() = %p, modal() = %p\n",
+//           window, pushed(), grab(), modal());
+
+    if (grab()) {
+      wi = grab();
+      pushed_ = 0; // must be zero before callback is done!
+    } else if (pushed()) {
+      wi = pushed();
+      pushed_ = 0; // must be zero before callback is done!
+    } else if (modal() && wi != modal()) return 0;
+    int r = send(e, wi, window);
+    fl_fix_focus();
+    return r;}
+
+  case FL_UNFOCUS:
+    window = 0;
+  case FL_FOCUS:
+    fl_xfocus = window;
+    fl_fix_focus();
+    return 1;
+
+  case FL_KEYBOARD:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    Fl_Tooltip::enter((Fl_Widget*)0);
+
+    fl_xfocus = window; // this should not happen!  But maybe it does:
+
+    // Try it as keystroke, sending it to focus and all parents:
+    for (wi = grab() ? grab() : focus(); wi; wi = wi->parent())
+      if (send(FL_KEYBOARD, wi, window)) return 1;
+
+    // recursive call to try shortcut:
+    if (handle(FL_SHORTCUT, window)) return 1;
+
+    // and then try a shortcut with the case of the text swapped, by
+    // changing the text and falling through to FL_SHORTCUT case:
+    {unsigned char* c = (unsigned char*)event_text(); // cast away const
+    if (!isalpha(*c)) return 0;
+    *c = isupper(*c) ? tolower(*c) : toupper(*c);}
+    e_number = e = FL_SHORTCUT;
+
+  case FL_SHORTCUT:
+    if (grab()) {wi = grab(); break;} // send it to grab window
+
+    // Try it as shortcut, sending to mouse widget and all parents:
+    wi = belowmouse(); if (!wi) {wi = modal(); if (!wi) wi = window;}
+    for (; wi; wi = wi->parent()) if (send(FL_SHORTCUT, wi, window)) return 1;
+
+    // try using add_handle() functions:
+    if (send_handlers(FL_SHORTCUT)) return 1;
+
+    // make Escape key close windows:
+    if (event_key()==FL_Escape) {
+      wi = modal(); if (!wi) wi = window;
+      wi->do_callback();
+      return 1;
+    }
+
+    return 0;
+
+  case FL_ENTER:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    fl_xmousewin = window;
+    fl_fix_focus();
+    Fl_Tooltip::enter(belowmouse());
+    return 1;
+
+  case FL_LEAVE:
+#ifdef DEBUG
+    printf("Fl::handle(e=%d, window=%p);\n", e, window);
+#endif // DEBUG
+
+    if (!pushed_) {
+      belowmouse(0);
+      Fl_Tooltip::enter(0);
+    }
+    if (window == fl_xmousewin) {fl_xmousewin = 0; fl_fix_focus();}
+    return 1;
+
+  case FL_MOUSEWHEEL:
+    fl_xfocus = window; // this should not happen!  But maybe it does:
+
+    // Try sending it to the grab and then the window:
+    if (grab()) {
+      if (send(FL_MOUSEWHEEL, grab(), window)) return 1;
+    }
+    if (send(FL_MOUSEWHEEL, window, window)) return 1;
+  default:
+    break;
+  }
+  if (wi && send(e, wi, window)) {
+    dnd_flag = 0;
+    return 1;
+  }
+  dnd_flag = 0;
+  return send_handlers(e);
+}
+
+////////////////////////////////////////////////////////////////
+// hide() destroys the X window, it does not do unmap!
+
+#if !defined(WIN32) && USE_XFT
+extern void fl_destroy_xft_draw(Window);
+#endif
+
+void Fl_Window::hide() {
+  clear_visible();
+
+  if (!shown()) return;
+
+  // remove from the list of windows:
+  Fl_X* ip = i;
+  Fl_X** pp = &Fl_X::first;
+  for (; *pp != ip; pp = &(*pp)->next) if (!*pp) return;
+  *pp = ip->next;
+
+#ifdef __APPLE_QD__
+  // remove all childwindow links
+  for ( Fl_X *pc = Fl_X::first; pc; pc = pc->next )
+  { 
+    if ( pc->xidNext == ip ) pc->xidNext = ip->xidNext;
+    if ( pc->xidChildren == ip ) pc->xidChildren = ip->xidNext;   
+  }
+#elif defined(__APPLE_QUARTZ__)
+  // remove all childwindow links
+  for ( Fl_X *pc = Fl_X::first; pc; pc = pc->next )
+  {
+    if ( pc->xidNext == ip ) pc->xidNext = ip->xidNext;
+    if ( pc->xidChildren == ip ) pc->xidChildren = ip->xidNext;
+  }
+#endif // __APPLE__
+
+  i = 0;
+
+  // recursively remove any subwindows:
+  for (Fl_X *wi = Fl_X::first; wi;) {
+    Fl_Window* W = wi->w;
+    if (W->window() == this) {
+      W->hide();
+      W->set_visible();
+      wi = Fl_X::first;
+    } else wi = wi->next;
+  }
+
+  if (this == Fl::modal_) { // we are closing the modal window, find next one:
+    Fl_Window* W;
+    for (W = Fl::first_window(); W; W = Fl::next_window(W))
+      if (W->modal()) break;
+    Fl::modal_ = W;
+  }
+
+  // Make sure no events are sent to this window:
+  fl_throw_focus(this);
+  handle(FL_HIDE);
+
+#ifdef WIN32
+  // this little trick keeps the current clipboard alive, even if we are about
+  // to destroy the window that owns the selection.
+  if (GetClipboardOwner()==ip->xid) {
+    Fl_Window *w1 = Fl::first_window();
+    if (w1 && OpenClipboard(fl_xid(w1))) {
+      EmptyClipboard();
+      SetClipboardData(CF_TEXT, NULL);
+      CloseClipboard();
+    }
+  }
+  // Send a message to myself so that I'll get out of the event loop...
+  PostMessage(ip->xid, WM_APP, 0, 0);
+  if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
+    if (ip->xid == fl_window && fl_gc) {
+      fl_release_dc(fl_window, fl_gc);
+      fl_window = (HWND)-1;
+      fl_gc = 0;
+    }
+#elif defined(__APPLE_QD__)
+  if ( ip->xid == fl_window )
+    fl_window = 0;
+#elif defined(__APPLE_QUARTZ__)
+  Fl_X::q_release_context(ip);
+  if ( ip->xid == fl_window )
+    fl_window = 0;
+#endif
+
+  if (ip->region) XDestroyRegion(ip->region);
+
+#ifdef WIN32
+  XDestroyWindow(fl_display, ip->xid);
+#elif defined(__APPLE_QD__)
+  if ( !parent() ) // don't destroy shared windows!
+  {
+    //+ RemoveTrackingHandler( dndTrackingHandler, ip->xid );
+    //+ RemoveReceiveHandler( dndReceiveHandler, ip->xid );
+    XDestroyWindow(fl_display, ip->xid);
+  }
+#elif defined(__APPLE_QUARTZ__)
+  if ( !parent() ) // don't destroy shared windows!
+  {
+    //+ RemoveTrackingHandler( dndTrackingHandler, ip->xid );
+    //+ RemoveReceiveHandler( dndReceiveHandler, ip->xid );
+    XDestroyWindow(fl_display, ip->xid);
+  }
+#else
+# if USE_XFT
+  fl_destroy_xft_draw(ip->xid);
+# endif
+  XDestroyWindow(fl_display, ip->xid);
+#endif
+  
+#ifdef WIN32
+  // Try to stop the annoying "raise another program" behavior
+  if (non_modal() && Fl::first_window() && Fl::first_window()->shown())
+    Fl::first_window()->show();
+#endif
+  delete ip;
+}
+
+Fl_Window::~Fl_Window() {
+  hide();
+}
+
+// FL_SHOW and FL_HIDE are called whenever the visibility of this widget
+// or any parent changes.  We must correctly map/unmap the system's window.
+
+// For top-level windows it is assummed the window has already been
+// mapped or unmapped!!!  This is because this should only happen when
+// Fl_Window::show() or Fl_Window::hide() is called, or in response to
+// iconize/deiconize events from the system.
+
+int Fl_Window::handle(int ev)
+{
+  if (parent()) {
+    switch (ev) {
+    case FL_SHOW:
+      if (!shown()) show();
+      else XMapWindow(fl_display, fl_xid(this)); // extra map calls are harmless
+      break;
+    case FL_HIDE:
+      if (shown()) {
+	// Find what really turned invisible, if is was a parent window
+	// we do nothing.  We need to avoid unnecessary unmap calls
+	// because they cause the display to blink when the parent is
+	// remapped.  However if this or any intermediate non-window
+	// widget has really had hide() called directly on it, we must
+	// unmap because when the parent window is remapped we don't
+	// want to reappear.
+	if (visible()) {
+	 Fl_Widget* p = parent(); for (;p->visible();p = p->parent()) {}
+	 if (p->type() >= FL_WINDOW) break; // don't do the unmap
+	}
+#ifdef __APPLE_QD__
+        hide();
+	set_visible();
+#elif defined(__APPLE_QUARTZ__)
+        hide();
+        set_visible();
+#else
+	XUnmapWindow(fl_display, fl_xid(this));
+#endif // __APPLE__
+      }
+      break;
+    }
+//  } else if (ev == FL_FOCUS || ev == FL_UNFOCUS) {
+//    Fl_Tooltip::exit(Fl_Tooltip::current());
+  }
+
+  return Fl_Group::handle(ev);
+}
+
+////////////////////////////////////////////////////////////////
+// Back compatability cut & paste functions for fltk 1.1 only:
+
+void Fl::selection_owner(Fl_Widget *owner) {selection_owner_ = owner;}
+
+void Fl::selection(Fl_Widget &owner, const char* text, int len) {
+  selection_owner_ = &owner;
+  Fl::copy(text, len, 0);
+}
+
+void Fl::paste(Fl_Widget &receiver) {
+  Fl::paste(receiver, 0);
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/fl_draw.H>
+
+void Fl_Widget::redraw() {
+  damage(FL_DAMAGE_ALL);
+}
+
+void Fl_Widget::redraw_label() {
+  if (window()) {
+    if (box() == FL_NO_BOX) {
+      // Widgets with the FL_NO_BOX boxtype need a parent to
+      // redraw, since it is responsible for redrawing the
+      // background...
+      int X = x() > 0 ? x() - 1 : 0;
+      int Y = y() > 0 ? y() - 1 : 0;
+      window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
+    }
+
+    if (align() && !(align() & FL_ALIGN_INSIDE) && window()->shown()) {
+      // If the label is not inside the widget, compute the location of
+      // the label and redraw the window within that bounding box...
+      int W = 0, H = 0;
+      label_.measure(W, H);
+      W += 5; // Add a little to the size of the label to cover overflow
+      H += 5;
+
+      if (align() & FL_ALIGN_BOTTOM) {
+	window()->damage(FL_DAMAGE_EXPOSE, x(), y() + h(), w(), H);
+      } else if (align() & FL_ALIGN_TOP) {
+	window()->damage(FL_DAMAGE_EXPOSE, x(), y() - H, w(), H);
+      } else if (align() & FL_ALIGN_LEFT) {
+	window()->damage(FL_DAMAGE_EXPOSE, x() - W, y(), W, h());
+      } else if (align() & FL_ALIGN_RIGHT) {
+	window()->damage(FL_DAMAGE_EXPOSE, x() + w(), y(), W, h());
+      } else {
+        window()->damage(FL_DAMAGE_ALL);
+      }
+    } else {
+      // The label is inside the widget, so just redraw the widget itself...
+      damage(FL_DAMAGE_ALL);
+    }
+  }
+}
+
+void Fl_Widget::damage(uchar fl) {
+  if (type() < FL_WINDOW) {
+    // damage only the rectangle covered by a child widget:
+    damage(fl, x(), y(), w(), h());
+  } else {
+    // damage entire window by deleting the region:
+    Fl_X* i = Fl_X::i((Fl_Window*)this);
+    if (!i) return; // window not mapped, so ignore it
+    if (i->region) {XDestroyRegion(i->region); i->region = 0;}
+    damage_ |= fl;
+    Fl::damage(FL_DAMAGE_CHILD);
+  }
+}
+
+void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) {
+  Fl_Widget* wi = this;
+  // mark all parent widgets between this and window with FL_DAMAGE_CHILD:
+  while (wi->type() < FL_WINDOW) {
+    wi->damage_ |= fl;
+    wi = wi->parent();
+    if (!wi) return;
+    fl = FL_DAMAGE_CHILD;
+  }
+  Fl_X* i = Fl_X::i((Fl_Window*)wi);
+  if (!i) return; // window not mapped, so ignore it
+
+  // clip the damage to the window and quit if none:
+  if (X < 0) {W += X; X = 0;}
+  if (Y < 0) {H += Y; Y = 0;}
+  if (W > wi->w()-X) W = wi->w()-X;
+  if (H > wi->h()-Y) H = wi->h()-Y;
+  if (W <= 0 || H <= 0) return;
+
+  if (!X && !Y && W==wi->w() && H==wi->h()) {
+    // if damage covers entire window delete region:
+    wi->damage(fl);
+    return;
+  }
+
+  if (wi->damage()) {
+    // if we already have damage we must merge with existing region:
+    if (i->region) {
+#ifdef WIN32
+      Fl_Region R = XRectangleRegion(X, Y, W, H);
+      CombineRgn(i->region, i->region, R, RGN_OR);
+      XDestroyRegion(R);
+#elif defined(__APPLE_QD__)
+      Fl_Region R = NewRgn(); 
+      SetRectRgn(R, X, Y, X+W, Y+H);
+      UnionRgn(R, i->region, i->region);
+      DisposeRgn(R);
+#elif defined(__APPLE_QUARTZ__)
+      Fl_Region R = NewRgn();
+      SetRectRgn(R, X, Y, X+W, Y+H);
+      UnionRgn(R, i->region, i->region);
+      DisposeRgn(R);
+#else
+      XRectangle R;
+      R.x = X; R.y = Y; R.width = W; R.height = H;
+      XUnionRectWithRegion(&R, i->region, i->region);
+#endif
+    }
+    wi->damage_ |= fl;
+  } else {
+    // create a new region:
+    if (i->region) XDestroyRegion(i->region);
+    i->region = XRectangleRegion(X,Y,W,H);
+    wi->damage_ = fl;
+  }
+  Fl::damage(FL_DAMAGE_CHILD);
+}
+
+void Fl_Window::flush() {
+  make_current();
+//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this;
+  fl_clip_region(i->region); i->region = 0;
+  draw();
+}
+
+#ifdef WIN32
+#  include "Fl_win32.cxx"
+#elif defined(__APPLE__)
+#  include "Fl_mac.cxx"
+#endif
+
+//
+// The following methods allow callbacks to schedule the deletion of
+// widgets at "safe" times.
+//
+
+static int		num_dwidgets = 0, alloc_dwidgets = 0;
+static Fl_Widget	**dwidgets = 0;
+
+void
+Fl::delete_widget(Fl_Widget *wi) {
+  if (!wi) return;
+
+  if (num_dwidgets >= alloc_dwidgets) {
+    Fl_Widget	**temp;
+
+    temp = new Fl_Widget *[alloc_dwidgets + 10];
+    if (alloc_dwidgets) {
+      memcpy(temp, dwidgets, alloc_dwidgets * sizeof(Fl_Widget *));
+      delete[] dwidgets;
+    }
+
+    dwidgets = temp;
+    alloc_dwidgets += 10;
+  }
+
+  dwidgets[num_dwidgets] = wi;
+  num_dwidgets ++;
+}
+
+
+void
+Fl::do_widget_deletion() {
+  if (!num_dwidgets) return;
+
+  for (int i = 0; i < num_dwidgets; i ++)
+    delete dwidgets[i];
+
+  num_dwidgets = 0;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Adjuster.cxx b/Utilities/FLTK/src/Fl_Adjuster.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5c5e46f3a2602bdcf2dee36c25c0482b3b8e62ee
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Adjuster.cxx
@@ -0,0 +1,171 @@
+//
+// "$Id$"
+//
+// Adjuster widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+
+#include <FL/Fl.H>
+#include <FL/Fl_Adjuster.H>
+#include <FL/Fl_Bitmap.H>
+#include <FL/fl_draw.H>
+
+#include "fastarrow.h"
+static Fl_Bitmap fastarrow(fastarrow_bits, fastarrow_width, fastarrow_height);
+#include "mediumarrow.h"
+static Fl_Bitmap mediumarrow(mediumarrow_bits, mediumarrow_width, mediumarrow_height);
+#include "slowarrow.h"
+static Fl_Bitmap slowarrow(slowarrow_bits, slowarrow_width, slowarrow_height);
+
+// changing the value does not change the appearance:
+void Fl_Adjuster::value_damage() {}
+
+void Fl_Adjuster::draw() {
+  int dx, dy, W, H;
+  if (w()>=h()) {
+    dx = W = w()/3;
+    dy = 0; H = h();
+  } else {
+    dx = 0; W = w();
+    dy = H = h()/3;
+  }
+  draw_box(drag==1?FL_DOWN_BOX:box(), x(),  y()+2*dy, W, H, color());
+  draw_box(drag==2?FL_DOWN_BOX:box(), x()+dx, y()+dy, W, H, color());
+  draw_box(drag==3?FL_DOWN_BOX:box(), x()+2*dx,  y(), W, H, color());
+  if (active_r())
+    fl_color(selection_color());
+  else
+    fl_color(fl_inactive(selection_color()));
+  fastarrow.draw(x()+(W-fastarrow_width)/2,
+		 y()+2*dy+(H-fastarrow_height)/2, W, H);
+  mediumarrow.draw(x()+dx+(W-mediumarrow_width)/2,
+		   y()+dy+(H-mediumarrow_height)/2, W, H);
+  slowarrow.draw(x()+2*dx+(W-slowarrow_width)/2,
+		 y()+(H-slowarrow_width)/2, W, H);
+  if (Fl::focus() == this) draw_focus();
+}
+
+int Fl_Adjuster::handle(int event) {
+  double v;
+  int delta;
+  int mx = Fl::event_x();
+  switch (event) {
+    case FL_PUSH:
+      if (Fl::visible_focus()) Fl::focus(this);
+      ix = mx;
+      if (w()>=h())
+	drag = 3*(mx-x())/w() + 1;
+      else
+	drag = 3-3*(Fl::event_y()-y()-1)/h();
+      handle_push();
+      redraw();
+      return 1;
+    case FL_DRAG:
+      if (w() >= h()) {
+	delta = x()+(drag-1)*w()/3;	// left edge of button
+	if (mx < delta)
+	  delta = mx-delta;
+	else if (mx > (delta+w()/3)) // right edge of button
+	  delta = mx-delta-w()/3;
+	else
+	  delta = 0;
+      } else {
+	if (mx < x())
+	  delta = mx-x();
+	else if (mx > (x()+w()))
+	  delta = mx-x()-w();
+	else
+	  delta = 0;
+      }
+      switch (drag) {
+      case 3: v = increment(previous_value(), delta); break;
+      case 2: v = increment(previous_value(), delta*10); break;
+      default:v = increment(previous_value(), delta*100); break;
+      }
+      handle_drag(soft() ? softclamp(v) : clamp(v));
+      return 1;
+    case FL_RELEASE:
+      if (Fl::event_is_click()) { // detect click but no drag
+	if (Fl::event_state()&0xF0000) delta = -10;
+	else delta = 10;
+	switch (drag) {
+	case 3: v = increment(previous_value(), delta); break;
+	case 2: v = increment(previous_value(), delta*10); break;
+	default:v = increment(previous_value(), delta*100); break;
+	}
+	handle_drag(soft() ? softclamp(v) : clamp(v));
+      }
+      drag = 0;
+      redraw();
+      handle_release();
+      return 1;
+    case FL_KEYBOARD :
+      switch (Fl::event_key()) {
+	case FL_Up:
+          if (w() > h()) return 0;
+	  handle_drag(clamp(increment(value(),-1)));
+	  return 1;
+	case FL_Down:
+          if (w() > h()) return 0;
+	  handle_drag(clamp(increment(value(),1)));
+	  return 1;
+	case FL_Left:
+          if (w() < h()) return 0;
+	  handle_drag(clamp(increment(value(),-1)));
+	  return 1;
+	case FL_Right:
+          if (w() < h()) return 0;
+	  handle_drag(clamp(increment(value(),1)));
+	  return 1;
+	default:
+          return 0;
+      }
+      // break not required because of switch...
+
+    case FL_FOCUS:
+    case FL_UNFOCUS:
+      if (Fl::visible_focus()) {
+        redraw();
+        return 1;
+      } else return 0;
+
+    case FL_ENTER :
+    case FL_LEAVE :
+      return 1;
+  }
+  return 0;
+}
+
+Fl_Adjuster::Fl_Adjuster(int X, int Y, int W, int H, const char* l)
+  : Fl_Valuator(X, Y, W, H, l) {
+  box(FL_UP_BOX);
+  step(1, 10000);
+  selection_color(FL_SELECTION_COLOR);
+  drag = 0;
+  soft_ = 1;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_BMP_Image.cxx b/Utilities/FLTK/src/Fl_BMP_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2af7f0c95e2addfd28029f10c263dbbcb285d56c
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_BMP_Image.cxx
@@ -0,0 +1,496 @@
+//
+// "$Id$"
+//
+// Fl_BMP_Image routines.
+//
+// Copyright 1997-2005 by Easy Software Products.
+// Image support donated by Matthias Melcher, Copyright 2000.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_BMP_Image::Fl_BMP_Image() - Load a BMP image file.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl_BMP_Image.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+//
+// BMP definitions...
+//
+
+#ifndef BI_RGB
+#  define BI_RGB       0             // No compression - straight BGR data
+#  define BI_RLE8      1             // 8-bit run-length compression
+#  define BI_RLE4      2             // 4-bit run-length compression
+#  define BI_BITFIELDS 3             // RGB bitmap with RGB masks
+#endif // !BI_RGB
+
+
+//
+// Local functions...
+//
+
+static int		read_long(FILE *fp);
+static unsigned short	read_word(FILE *fp);
+static unsigned int	read_dword(FILE *fp);
+
+
+//
+// 'Fl_BMP_Image::Fl_BMP_Image()' - Load a BMP image file.
+//
+
+Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
+  : Fl_RGB_Image(0,0,0) {
+  FILE		*fp;		// File pointer
+  int		info_size,	// Size of info header
+		depth,		// Depth of image (bits)
+		bDepth = 3,	// Depth of image (bytes)
+		compression,	// Type of compression
+		colors_used,	// Number of colors used
+		x, y,		// Looping vars
+		color,		// Color of RLE pixel
+		repcount,	// Number of times to repeat
+		temp,		// Temporary color
+		align,		// Alignment bytes
+		dataSize,	// number of bytes in image data set
+		row_order,	// 1 = normal;  -1 = flipped row order
+		start_y,	// Beginning Y
+		end_y;		// Ending Y
+  long		offbits;	// Offset to image data
+  uchar		bit,		// Bit in image
+		byte;		// Byte in image
+  uchar		*ptr;		// Pointer into pixels
+  uchar		colormap[256][3];// Colormap
+  uchar		havemask;	// Single bit mask follows image data
+  int		use_5_6_5;	// Use 5:6:5 for R:G:B channels in 16 bit images
+
+
+  // Open the file...
+  if ((fp = fopen(bmp, "rb")) == NULL) return;
+
+  // Get the header...
+  byte = (uchar)getc(fp);	// Check "BM" sync chars
+  bit  = (uchar)getc(fp);
+  if (byte != 'B' || bit != 'M') {
+    fclose(fp);
+    return;
+  }
+
+  read_dword(fp);		// Skip size
+  read_word(fp);		// Skip reserved stuff
+  read_word(fp);
+  offbits = (long)read_dword(fp);// Read offset to image data
+
+  // Then the bitmap information...
+  info_size = read_dword(fp);
+
+//  printf("offbits = %ld, info_size = %d\n", offbits, info_size);
+
+  havemask  = 0;
+  row_order = -1;
+  use_5_6_5 = 0;
+
+  if (info_size < 40) {
+    // Old Windows/OS2 BMP header...
+    w(read_word(fp));
+    h(read_word(fp));
+    read_word(fp);
+    depth = read_word(fp);
+    compression = BI_RGB;
+    colors_used = 0;
+
+    repcount = info_size - 12;
+  } else {
+    // New BMP header...
+    w(read_long(fp));
+    // If the height is negative, the row order is flipped
+    temp = read_long(fp);
+    if (temp < 0) row_order = 1;
+    h(abs(temp));
+    read_word(fp);
+    depth = read_word(fp);
+    compression = read_dword(fp);
+    dataSize = read_dword(fp);
+    read_long(fp);
+    read_long(fp);
+    colors_used = read_dword(fp);
+    read_dword(fp);
+
+    repcount = info_size - 40;
+
+    if (!compression && depth>=8 && w()>32/depth) {
+      int Bpp = depth/8;
+      int maskSize = (((w()*Bpp+3)&~3)*h()) + (((((w()+7)/8)+3)&~3)*h());
+      if (maskSize==2*dataSize) {
+        havemask = 1;
+	h(h()/2);
+	bDepth = 4;
+      }
+    }
+  }
+
+//  printf("w() = %d, h() = %d, depth = %d, compression = %d, colors_used = %d, repcount = %d\n",
+//         w(), h(), depth, compression, colors_used, repcount);
+
+  // Skip remaining header bytes...
+  while (repcount > 0) {
+    getc(fp);
+    repcount --;
+  }
+
+  // Check header data...
+  if (!w() || !h() || !depth) {
+    fclose(fp);
+    return;
+  }
+
+  // Get colormap...
+  if (colors_used == 0 && depth <= 8)
+    colors_used = 1 << depth;
+
+  for (repcount = 0; repcount < colors_used; repcount ++) {
+    // Read BGR color...
+    fread(colormap[repcount], 1, 3, fp);
+
+    // Skip pad byte for new BMP files...
+    if (info_size > 12) getc(fp);
+  }
+
+  // Read first dword of colormap. It tells us if 5:5:5 or 5:6:5 for 16 bit
+  if (depth == 16)
+    use_5_6_5 = (read_dword(fp) == 0xf800);
+
+  // Set byte depth for RGBA images
+  if (depth == 32)
+    bDepth=4;
+
+  // Setup image and buffers...
+  d(bDepth);
+  if (offbits) fseek(fp, offbits, SEEK_SET);
+
+  array = new uchar[w() * h() * d()];
+  alloc_array = 1;
+
+  // Read the image data...
+  color = 0;
+  repcount = 0;
+  align = 0;
+  byte  = 0;
+  temp  = 0;
+
+  if (row_order < 0) {
+    start_y = h() - 1;
+    end_y   = -1;
+  } else {
+    start_y = 0;
+    end_y   = h();
+  }
+
+  for (y = start_y; y != end_y; y += row_order) {
+    ptr = (uchar *)array + y * w() * d();
+
+    switch (depth)
+    {
+      case 1 : // Bitmap
+          for (x = w(), bit = 128; x > 0; x --) {
+	    if (bit == 128) byte = (uchar)getc(fp);
+
+	    if (byte & bit) {
+	      *ptr++ = colormap[1][2];
+	      *ptr++ = colormap[1][1];
+	      *ptr++ = colormap[1][0];
+	    } else {
+	      *ptr++ = colormap[0][2];
+	      *ptr++ = colormap[0][1];
+	      *ptr++ = colormap[0][0];
+	    }
+
+	    if (bit > 1)
+	      bit >>= 1;
+	    else
+	      bit = 128;
+	  }
+
+          // Read remaining bytes to align to 32 bits...
+	  for (temp = (w() + 7) / 8; temp & 3; temp ++) {
+	    getc(fp);
+	  }
+          break;
+
+      case 4 : // 16-color
+          for (x = w(), bit = 0xf0; x > 0; x --) {
+	    // Get a new repcount as needed...
+	    if (repcount == 0) {
+              if (compression != BI_RLE4) {
+		repcount = 2;
+		color = -1;
+              } else {
+		while (align > 0) {
+	          align --;
+		  getc(fp);
+        	}
+
+		if ((repcount = getc(fp)) == 0) {
+		  if ((repcount = getc(fp)) == 0) {
+		    // End of line...
+                    x ++;
+		    continue;
+		  } else if (repcount == 1) {
+                    // End of image...
+		    break;
+		  } else if (repcount == 2) {
+		    // Delta...
+		    repcount = getc(fp) * getc(fp) * w();
+		    color = 0;
+		  } else {
+		    // Absolute...
+		    color = -1;
+		    align = ((4 - (repcount & 3)) / 2) & 1;
+		  }
+		} else {
+	          color = getc(fp);
+		}
+	      }
+	    }
+
+            // Get a new color as needed...
+	    repcount --;
+
+	    // Extract the next pixel...
+            if (bit == 0xf0) {
+	      // Get the next color byte as needed...
+              if (color < 0) temp = getc(fp);
+	      else temp = color;
+
+              // Copy the color value...
+	      *ptr++ = colormap[(temp >> 4) & 15][2];
+	      *ptr++ = colormap[(temp >> 4) & 15][1];
+	      *ptr++ = colormap[(temp >> 4) & 15][0];
+
+	      bit  = 0x0f;
+	    } else {
+	      bit  = 0xf0;
+
+              // Copy the color value...
+	      *ptr++ = colormap[temp & 15][2];
+	      *ptr++ = colormap[temp & 15][1];
+	      *ptr++ = colormap[temp & 15][0];
+	    }
+
+	  }
+
+	  if (!compression) {
+            // Read remaining bytes to align to 32 bits...
+	    for (temp = (w() + 1) / 2; temp & 3; temp ++) {
+	      getc(fp);
+	    }
+	  }
+          break;
+
+      case 8 : // 256-color
+          for (x = w(); x > 0; x --) {
+	    // Get a new repcount as needed...
+            if (compression != BI_RLE8) {
+	      repcount = 1;
+	      color = -1;
+            }
+
+	    if (repcount == 0) {
+	      while (align > 0) {
+	        align --;
+		getc(fp);
+              }
+
+	      if ((repcount = getc(fp)) == 0) {
+		if ((repcount = getc(fp)) == 0) {
+		  // End of line...
+                  x ++;
+		  continue;
+		} else if (repcount == 1) {
+		  // End of image...
+		  break;
+		} else if (repcount == 2) {
+		  // Delta...
+		  repcount = getc(fp) * getc(fp) * w();
+		  color = 0;
+		} else {
+		  // Absolute...
+		  color = -1;
+		  align = (2 - (repcount & 1)) & 1;
+		}
+	      } else {
+	        color = getc(fp);
+              }
+            }
+
+            // Get a new color as needed...
+            if (color < 0) temp = getc(fp);
+	    else temp = color;
+
+            repcount --;
+
+            // Copy the color value...
+	    *ptr++ = colormap[temp][2];
+	    *ptr++ = colormap[temp][1];
+	    *ptr++ = colormap[temp][0];
+	    if (havemask) ptr++;
+	  }
+
+	  if (!compression) {
+            // Read remaining bytes to align to 32 bits...
+	    for (temp = w(); temp & 3; temp ++) {
+	      getc(fp);
+	    }
+	  }
+          break;
+
+      case 16 : // 16-bit 5:5:5 or 5:6:5 RGB
+          for (x = w(); x > 0; x --, ptr += bDepth) {
+	    uchar b = getc(fp), a = getc(fp) ;
+	    if (use_5_6_5) {
+		ptr[2] = (uchar)(( b << 3 ) & 0xf8);
+		ptr[1] = (uchar)(((a << 5) & 0xe0) | ((b >> 3) & 0x1c));
+		ptr[0] = (uchar)(a & 0xf8);
+	    } else {
+		ptr[2] = (uchar)((b << 3) & 0xf8);
+		ptr[1] = (uchar)(((a << 6) & 0xc0) | ((b >> 2) & 0x38));
+		ptr[0] = (uchar)((a<<1) & 0xf8);
+	    }
+	  }
+
+          // Read remaining bytes to align to 32 bits...
+	  for (temp = w() * 2; temp & 3; temp ++) {
+	    getc(fp);
+	  }
+          break;
+
+      case 24 : // 24-bit RGB
+          for (x = w(); x > 0; x --, ptr += bDepth) {
+	    ptr[2] = (uchar)getc(fp);
+	    ptr[1] = (uchar)getc(fp);
+	    ptr[0] = (uchar)getc(fp);
+	  }
+
+          // Read remaining bytes to align to 32 bits...
+	  for (temp = w() * 3; temp & 3; temp ++) {
+	    getc(fp);
+	  }
+          break;
+		  
+      case 32 : // 32-bit RGBA
+         for (x = w(); x > 0; x --, ptr += bDepth) {
+            ptr[2] = (uchar)getc(fp);
+            ptr[1] = (uchar)getc(fp);
+            ptr[0] = (uchar)getc(fp);
+            ptr[3] = (uchar)getc(fp);
+          }
+          break;
+    }
+  }
+  
+  if (havemask) {
+    for (y = h() - 1; y >= 0; y --) {
+      ptr = (uchar *)array + y * w() * d() + 3;
+      for (x = w(), bit = 128; x > 0; x --, ptr+=bDepth) {
+	if (bit == 128) byte = (uchar)getc(fp);
+	if (byte & bit)
+	  *ptr = 0;
+	else
+	  *ptr = 255;
+	if (bit > 1)
+	  bit >>= 1;
+	else
+	  bit = 128;
+      }
+      // Read remaining bytes to align to 32 bits...
+      for (temp = (w() + 7) / 8; temp & 3; temp ++)
+	getc(fp);
+    }
+  }
+
+  // Close the file and return...
+  fclose(fp);
+}
+
+
+//
+// 'read_word()' - Read a 16-bit unsigned integer.
+//
+
+static unsigned short	// O - 16-bit unsigned integer
+read_word(FILE *fp) {	// I - File to read from
+  unsigned char b0, b1;	// Bytes from file
+
+  b0 = (uchar)getc(fp);
+  b1 = (uchar)getc(fp);
+
+  return ((b1 << 8) | b0);
+}
+
+
+//
+// 'read_dword()' - Read a 32-bit unsigned integer.
+//
+
+static unsigned int		// O - 32-bit unsigned integer
+read_dword(FILE *fp) {		// I - File to read from
+  unsigned char b0, b1, b2, b3;	// Bytes from file
+
+  b0 = (uchar)getc(fp);
+  b1 = (uchar)getc(fp);
+  b2 = (uchar)getc(fp);
+  b3 = (uchar)getc(fp);
+
+  return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+}
+
+
+//
+// 'read_long()' - Read a 32-bit signed integer.
+//
+
+static int			// O - 32-bit signed integer
+read_long(FILE *fp) {		// I - File to read from
+  unsigned char b0, b1, b2, b3;	// Bytes from file
+
+  b0 = (uchar)getc(fp);
+  b1 = (uchar)getc(fp);
+  b2 = (uchar)getc(fp);
+  b3 = (uchar)getc(fp);
+
+  return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Bitmap.cxx b/Utilities/FLTK/src/Fl_Bitmap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..46425e98d6ffe16291d5caefd1da0dd01366421b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Bitmap.cxx
@@ -0,0 +1,518 @@
+//
+// "$Id$"
+//
+// Bitmap drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Bitmap.H>
+#include "flstring.h"
+
+#ifdef __APPLE_QD__ // MacOS bitmask functions
+Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) {
+  Rect srcRect;
+  srcRect.left = 0; srcRect.right = w;
+  srcRect.top = 0; srcRect.bottom = h;
+  GrafPtr savePort;
+
+  GetPort(&savePort); // remember the current port
+
+  Fl_Bitmask gw;
+  NewGWorld( &gw, 1, &srcRect, 0L, 0L, 0 );
+  PixMapHandle pm = GetGWorldPixMap( gw );
+  if ( pm ) 
+  {
+    LockPixels( pm );
+    if ( *pm ) 
+    {
+      uchar *base = (uchar*)GetPixBaseAddr( pm );
+      if ( base ) 
+      {
+        PixMapPtr pmp = *pm;
+        // verify the parameters for direct memory write
+        if ( pmp->pixelType == 0 || pmp->pixelSize == 1 || pmp->cmpCount == 1 || pmp->cmpSize == 1 ) 
+        {
+          static uchar reverse[16] =	/* Bit reversal lookup table */
+          { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff };
+          uchar *dst = base;
+          const uchar *src = array;
+          int rowBytesSrc = (w+7)>>3 ;
+          int rowPatch = (pmp->rowBytes&0x3fff) - rowBytesSrc;
+          for ( int j=0; j<h; j++,dst+=rowPatch )
+            for ( int i=0; i<rowBytesSrc; i++,src++ )
+              *dst++ = (reverse[*src & 0x0f] & 0xf0) | (reverse[(*src >> 4) & 0x0f] & 0x0f);
+        }
+      }
+      UnlockPixels( pm );
+    }
+  }
+
+  SetPort(savePort);
+  return gw;               /* tell caller we succeeded! */
+}
+
+void fl_delete_bitmask(Fl_Bitmask id) {
+  if (id) DisposeGWorld(id);
+}
+#elif defined(__APPLE_QUARTZ__)
+Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) {
+  static uchar reverse[16] =    /* Bit reversal lookup table */
+    { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, 
+      0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff };
+  int rowBytes = (w+7)>>3 ;
+  uchar *bmask = (uchar*)malloc(rowBytes*h), *dst = bmask;
+  const uchar *src = array;
+  for ( int i=rowBytes*h; i>0; i--,src++ ) {
+    *dst++ = ((reverse[*src & 0x0f] & 0xf0) | (reverse[(*src >> 4) & 0x0f] & 0x0f))^0xff;
+  }
+  CGDataProviderRef srcp = CGDataProviderCreateWithData( 0L, bmask, rowBytes*h, 0L);
+  CGImageRef id = CGImageMaskCreate( w, h, 1, 1, rowBytes, srcp, 0L, false);
+  CGDataProviderRelease(srcp);
+  return (Fl_Bitmask)id;
+}
+void fl_delete_bitmask(Fl_Bitmask id) {
+  if (id) CGImageRelease((CGImageRef)id);
+}
+#elif defined(WIN32) // Windows bitmask functions...
+// 'fl_create_bitmap()' - Create a 1-bit bitmap for drawing...
+static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) {
+  // we need to pad the lines out to words & swap the bits
+  // in each byte.
+  int w1 = (w+7)/8;
+  int w2 = ((w+15)/16)*2;
+  uchar* newarray = new uchar[w2*h];
+  const uchar* src = data;
+  uchar* dest = newarray;
+  Fl_Bitmask id;
+  static uchar reverse[16] =	/* Bit reversal lookup table */
+  	      { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee,
+		0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff };
+
+  for (int y=0; y < h; y++) {
+    for (int n = 0; n < w1; n++, src++)
+      *dest++ = (uchar)((reverse[*src & 0x0f] & 0xf0) |
+	                (reverse[(*src >> 4) & 0x0f] & 0x0f));
+    dest += w2-w1;
+  }
+
+  id = CreateBitmap(w, h, 1, 1, newarray);
+
+  delete[] newarray;
+
+  return id;
+}
+
+// 'fl_create_bitmask()' - Create an N-bit bitmap for masking...
+Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) {
+  // this won't work when the user changes display mode during run or
+  // has two screens with differnet depths
+  Fl_Bitmask id;
+  static uchar hiNibble[16] =
+  { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 };
+  static uchar loNibble[16] =
+  { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
+    0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f };
+  int np  = GetDeviceCaps(fl_gc, PLANES);	//: was always one on sample machines
+  int bpp = GetDeviceCaps(fl_gc, BITSPIXEL);//: 1,4,8,16,24,32 and more odd stuff?
+  int Bpr = (bpp*w+7)/8;			//: bytes per row
+  int pad = Bpr&1, w1 = (w+7)/8, shr = ((w-1)&7)+1;
+  if (bpp==4) shr = (shr+1)/2;
+  uchar *newarray = new uchar[(Bpr+pad)*h];
+  uchar *dst = newarray;
+  const uchar *src = data;
+
+  for (int i=0; i<h; i++) {
+    // This is slooow, but we do it only once per pixmap
+    for (int j=w1; j>0; j--) {
+      uchar b = *src++;
+      if (bpp==1) {
+        *dst++ = (uchar)( hiNibble[b&15] ) | ( loNibble[(b>>4)&15] );
+      } else if (bpp==4) {
+        for (int k=(j==1)?shr:4; k>0; k--) {
+          *dst++ = (uchar)("\377\360\017\000"[b&3]);
+          b = b >> 2;
+        }
+      } else {
+        for (int k=(j==1)?shr:8; k>0; k--) {
+          if (b&1) {
+            *dst++=0;
+	    if (bpp>8) *dst++=0;
+            if (bpp>16) *dst++=0;
+	    if (bpp>24) *dst++=0;
+	  } else {
+	    *dst++=0xff;
+	    if (bpp>8) *dst++=0xff;
+	    if (bpp>16) *dst++=0xff;
+	    if (bpp>24) *dst++=0xff;
+	  }
+
+	  b = b >> 1;
+        }
+      }
+    }
+
+    dst += pad;
+  }
+
+  id = CreateBitmap(w, h, np, bpp, newarray);
+  delete[] newarray;
+
+  return id;
+}
+
+#if 0 // This doesn't appear to be used anywhere...
+Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data, int for_mask) {
+  // we need to pad the lines out to words & swap the bits
+  // in each byte.
+  int w1 = (w+7)/8;
+  int w2 = ((w+15)/16)*2;
+  uchar* newarray = new uchar[w2*h];
+  const uchar* src = data;
+  uchar* dest = newarray;
+  Fl_Bitmask id;
+  static uchar reverse[16] =	/* Bit reversal lookup table */
+  	      { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee,
+		0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff };
+
+  for (int y=0; y < h; y++) {
+    for (int n = 0; n < w1; n++, src++)
+      *dest++ = (reverse[*src & 0x0f] & 0xf0) |
+	        (reverse[(*src >> 4) & 0x0f] & 0x0f);
+    dest += w2-w1;
+  }
+
+  id = CreateBitmap(w, h, 1, 1, newarray);
+
+  delete[] newarray;
+
+  return (id);
+}
+#  endif // 0
+
+void fl_delete_bitmask(Fl_Bitmask bm) {
+  DeleteObject((HGDIOBJ)bm);
+}
+#else // X11 bitmask functions
+Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) {
+  return XCreateBitmapFromData(fl_display, fl_window, (const char *)data,
+                               (w+7)&-8, h);
+}
+
+void fl_delete_bitmask(Fl_Bitmask bm) {
+  fl_delete_offscreen((Fl_Offscreen)bm);
+}
+#endif // __APPLE__
+
+
+// MRS: Currently it appears that CopyDeepMask() does not work with an 8-bit alpha mask.
+//      If you want to test/fix this, uncomment the "#ifdef __APPLE__" and comment out
+//      the "#if 0" here.  Also see Fl_Image.cxx for a similar check...
+
+//#ifdef __APPLE_QD__
+#if 0
+// Create an 8-bit mask used for alpha blending
+Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array) {
+  Rect srcRect;
+  srcRect.left = 0; srcRect.right = w;
+  srcRect.top = 0; srcRect.bottom = h;
+  GrafPtr savePort;
+
+  GetPort(&savePort); // remember the current port
+
+  Fl_Bitmask gw;
+  NewGWorld( &gw, 8, &srcRect, 0L, 0L, 0 );
+  PixMapHandle pm = GetGWorldPixMap( gw );
+  if ( pm ) 
+  {
+    LockPixels( pm );
+    if ( *pm ) 
+    {
+      uchar *base = (uchar*)GetPixBaseAddr( pm );
+      if ( base ) 
+      {
+        PixMapPtr pmp = *pm;
+        // verify the parameters for direct memory write
+        if ( pmp->pixelType == 0 || pmp->pixelSize == 8 || pmp->cmpCount == 1 || pmp->cmpSize == 8 ) 
+        {
+	  // Copy alpha values from the source array to the pixmap...
+	  array += d - 1;
+          int rowoffset = (pmp->rowBytes & 0x3fff) - w;
+	  for (int y = h; y > 0; y --, array += ld, base += rowoffset) {
+	    for (int x = w; x > 0; x --, array += d) {
+	      *base++ = 255 /*255 - *array*/;
+	    }
+	  }
+        }
+      }
+      UnlockPixels( pm );
+    }
+  }
+
+  SetPort(savePort);
+  return gw;               /* tell caller we succeeded! */
+}
+#else
+// Create a 1-bit mask used for alpha blending
+Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array) {
+  Fl_Bitmask mask;
+  int bmw = (w + 7) / 8;
+  uchar *bitmap = new uchar[bmw * h];
+  uchar *bitptr, bit;
+  const uchar *dataptr;
+  int x, y;
+  static uchar dither[16][16] = { // Simple 16x16 Floyd dither
+    { 0,   128, 32,  160, 8,   136, 40,  168,
+      2,   130, 34,  162, 10,  138, 42,  170 },
+    { 192, 64,  224, 96,  200, 72,  232, 104,
+      194, 66,  226, 98,  202, 74,  234, 106 },
+    { 48,  176, 16,  144, 56,  184, 24,  152,
+      50,  178, 18,  146, 58,  186, 26,  154 },
+    { 240, 112, 208, 80,  248, 120, 216, 88,
+      242, 114, 210, 82,  250, 122, 218, 90 },
+    { 12,  140, 44,  172, 4,   132, 36,  164,
+      14,  142, 46,  174, 6,   134, 38,  166 },
+    { 204, 76,  236, 108, 196, 68,  228, 100,
+      206, 78,  238, 110, 198, 70,  230, 102 },
+    { 60,  188, 28,  156, 52,  180, 20,  148,
+      62,  190, 30,  158, 54,  182, 22,  150 },
+    { 252, 124, 220, 92,  244, 116, 212, 84,
+      254, 126, 222, 94,  246, 118, 214, 86 },
+    { 3,   131, 35,  163, 11,  139, 43,  171,
+      1,   129, 33,  161, 9,   137, 41,  169 },
+    { 195, 67,  227, 99,  203, 75,  235, 107,
+      193, 65,  225, 97,  201, 73,  233, 105 },
+    { 51,  179, 19,  147, 59,  187, 27,  155,
+      49,  177, 17,  145, 57,  185, 25,  153 },
+    { 243, 115, 211, 83,  251, 123, 219, 91,
+      241, 113, 209, 81,  249, 121, 217, 89 },
+    { 15,  143, 47,  175, 7,   135, 39,  167,
+      13,  141, 45,  173, 5,   133, 37,  165 },
+    { 207, 79,  239, 111, 199, 71,  231, 103,
+      205, 77,  237, 109, 197, 69,  229, 101 },
+    { 63,  191, 31,  159, 55,  183, 23,  151,
+      61,  189, 29,  157, 53,  181, 21,  149 },
+    { 254, 127, 223, 95,  247, 119, 215, 87,
+      253, 125, 221, 93,  245, 117, 213, 85 }
+  };
+
+  // Generate a 1-bit "screen door" alpha mask; not always pretty, but
+  // definitely fast...  In the future we may be able to support things
+  // like the RENDER extension in XFree86, when available, to provide
+  // true RGBA-blended rendering.  See:
+  //
+  //     http://www.xfree86.org/~keithp/render/protocol.html
+  //
+  // for more info on XRender...
+  //
+  // MacOS already provides alpha blending support and has its own
+  // fl_create_alphamask() function...
+  memset(bitmap, 0, bmw * h);
+
+  for (dataptr = array + d - 1, y = 0; y < h; y ++, dataptr += ld)
+    for (bitptr = bitmap + y * bmw, bit = 1, x = 0; x < w; x ++, dataptr += d) {
+      if (*dataptr > dither[x & 15][y & 15])
+	*bitptr |= bit;
+      if (bit < 128) bit <<= 1;
+      else {
+	bit = 1;
+	bitptr ++;
+      }
+    }
+
+  mask = fl_create_bitmask(w, h, bitmap);
+  delete[] bitmap;
+
+  return (mask);
+}
+#endif // __APPLE__
+
+void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+  if (!array) {
+    draw_empty(XP, YP);
+    return;
+  }
+
+  // account for current clip region (faster on Irix):
+  int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
+  cx += X-XP; cy += Y-YP;
+  // clip the box down to the size of image, quit if empty:
+  if (cx < 0) {W += cx; X -= cx; cx = 0;}
+  if ((cx+W) > w()) W = w()-cx;
+  if (W <= 0) return;
+  if (cy < 0) {H += cy; Y -= cy; cy = 0;}
+  if ((cy+H) > h()) H = h()-cy;
+  if (H <= 0) return;
+#ifdef WIN32
+  if (!id) id = fl_create_bitmap(w(), h(), array);
+
+  HDC tempdc = CreateCompatibleDC(fl_gc);
+  int save = SaveDC(tempdc);
+  SelectObject(tempdc, (HGDIOBJ)id);
+  SelectObject(fl_gc, fl_brush());
+  // secret bitblt code found in old MSWindows reference manual:
+  BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
+  RestoreDC(tempdc, save);
+  DeleteDC(tempdc);
+#elif defined(__APPLE_QD__)
+  if (!id) id = fl_create_bitmask(w(), h(), array);
+  GrafPtr dstPort;
+  GetPort( &dstPort );
+  Rect src, dst;
+  GetPortBounds( (Fl_Offscreen)id, &src );
+  SetRect( &src, cx, cy, cx+W, cy+H );
+  SetRect( &dst, X, Y, X+W, Y+H );
+  CopyBits(GetPortBitMapForCopyBits((Fl_Offscreen)id),	// srcBits
+	   GetPortBitMapForCopyBits(dstPort),	// dstBits
+	   &src,		 		// src bounds
+	   &dst, 				// dst bounds
+	   srcOr, 				// mode
+	   0L);					// mask region
+#elif defined(__APPLE_QUARTZ__)
+  if (!id) id = fl_create_bitmask(w(), h(), array);
+  if (id && fl_gc) {
+    CGRect rect = { X, Y, W, H };
+    Fl_X::q_begin_image(rect, cx, cy, w(), h());
+    CGContextDrawImage(fl_gc, rect, (CGImageRef)id);
+    Fl_X::q_end_image();
+  }
+#else
+  if (!id) id = fl_create_bitmask(w(), h(), array);
+
+  XSetStipple(fl_display, fl_gc, id);
+  int ox = X-cx; if (ox < 0) ox += w();
+  int oy = Y-cy; if (oy < 0) oy += h();
+  XSetTSOrigin(fl_display, fl_gc, ox, oy);
+  XSetFillStyle(fl_display, fl_gc, FillStippled);
+  XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H);
+  XSetFillStyle(fl_display, fl_gc, FillSolid);
+#endif
+}
+
+Fl_Bitmap::~Fl_Bitmap() {
+  uncache();
+  if (alloc_array) delete[] (uchar *)array;
+}
+
+void Fl_Bitmap::uncache() {
+  if (id) {
+    fl_delete_bitmask((Fl_Offscreen)id);
+    id = 0;
+  }
+}
+
+void Fl_Bitmap::label(Fl_Widget* widget) {
+  widget->image(this);
+}
+
+void Fl_Bitmap::label(Fl_Menu_Item* m) {
+  Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure);
+  m->label(_FL_IMAGE_LABEL, (const char*)this);
+}
+
+Fl_Image *Fl_Bitmap::copy(int W, int H) {
+  Fl_Bitmap	*new_image;	// New RGB image
+  uchar		*new_array;	// New array for image data
+
+  // Optimize the simple copy where the width and height are the same...
+  if (W == w() && H == h()) {
+    new_array = new uchar [H * ((W + 7) / 8)];
+    memcpy(new_array, array, H * ((W + 7) / 8));
+
+    new_image = new Fl_Bitmap(new_array, W, H);
+    new_image->alloc_array = 1;
+
+    return new_image;
+  }
+  if (W <= 0 || H <= 0) return 0;
+
+  // OK, need to resize the image data; allocate memory and 
+  uchar		*new_ptr,	// Pointer into new array
+		new_bit,	// Bit for new array
+		old_bit;	// Bit for old array
+  const uchar	*old_ptr;	// Pointer into old array
+  int		sx, sy,		// Source coordinates
+		dx, dy,		// Destination coordinates
+		xerr, yerr,	// X & Y errors
+		xmod, ymod,	// X & Y moduli
+		xstep, ystep;	// X & Y step increments
+
+
+  // Figure out Bresenheim step/modulus values...
+  xmod   = w() % W;
+  xstep  = w() / W;
+  ymod   = h() % H;
+  ystep  = h() / H;
+
+  // Allocate memory for the new image...
+  new_array = new uchar [H * ((W + 7) / 8)];
+  new_image = new Fl_Bitmap(new_array, W, H);
+  new_image->alloc_array = 1;
+
+  memset(new_array, 0, H * ((W + 7) / 8));
+
+  // Scale the image using a nearest-neighbor algorithm...
+  for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) {
+    for (dx = W, xerr = W, old_ptr = array + sy * ((w() + 7) / 8), sx = 0, new_bit = 1;
+	 dx > 0;
+	 dx --) {
+      old_bit = (uchar)(1 << (sx & 7));
+      if (old_ptr[sx / 8] & old_bit) *new_ptr |= new_bit;
+
+      if (new_bit < 128) new_bit <<= 1;
+      else {
+        new_bit = 1;
+	new_ptr ++;
+      }
+
+      sx   += xstep;
+      xerr -= xmod;
+
+      if (xerr <= 0) {
+	xerr += W;
+	sx ++;
+      }
+    }
+
+    if (new_bit > 1) new_ptr ++;
+
+    sy   += ystep;
+    yerr -= ymod;
+    if (yerr <= 0) {
+      yerr += H;
+      sy ++;
+    }
+  }
+
+  return new_image;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Box.cxx b/Utilities/FLTK/src/Fl_Box.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b8107e9f83c186b0f9ff7585d252a6609c1b8714
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Box.cxx
@@ -0,0 +1,44 @@
+//
+// "$Id$"
+//
+// Box widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Box.H>
+
+void Fl_Box::draw() {
+  draw_box();
+  draw_label();
+}
+
+int Fl_Box::handle(int event) {
+  if (event == FL_ENTER || event == FL_LEAVE) return 1;
+  else return 0;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Browser.cxx b/Utilities/FLTK/src/Fl_Browser.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..96f2dfe05de6df780ac8cfa7a60b8f27bb723f9c
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Browser.cxx
@@ -0,0 +1,551 @@
+//
+// "$Id$"
+//
+// Browser widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Browser.H>
+#include <FL/fl_draw.H>
+#include "flstring.h"
+#include <stdlib.h>
+#include <math.h>
+
+// I modified this from the original Forms data to use a linked list
+// so that the number of items in the browser and size of those items
+// is unlimited.  The only problem is that the old browser used an
+// index number to identify a line, and it is slow to convert from/to
+// a pointer.  I use a cache of the last match to try to speed this
+// up.
+
+// Also added the ability to "hide" a line.  This set's it's height to
+// zero, so the Fl_Browser_ cannot pick it.
+
+#define SELECTED 1
+#define NOTDISPLAYED 2
+
+struct FL_BLINE {	// data is in a linked list of these
+  FL_BLINE* prev;
+  FL_BLINE* next;
+  void* data;
+  short length;		// sizeof(txt)-1, may be longer than string
+  char flags;		// selected, displayed
+  char txt[1];		// start of allocated array
+};
+
+void* Fl_Browser::item_first() const {return first;}
+
+void* Fl_Browser::item_next(void* l) const {return ((FL_BLINE*)l)->next;}
+
+void* Fl_Browser::item_prev(void* l) const {return ((FL_BLINE*)l)->prev;}
+
+int Fl_Browser::item_selected(void* l) const {
+  return ((FL_BLINE*)l)->flags&SELECTED;}
+
+void Fl_Browser::item_select(void* l, int v) {
+  if (v) ((FL_BLINE*)l)->flags |= SELECTED;
+  else ((FL_BLINE*)l)->flags &= ~SELECTED;
+}
+
+FL_BLINE* Fl_Browser::find_line(int line) const {
+  int n; FL_BLINE* l;
+  if (line == cacheline) return cache;
+  if (cacheline && line > (cacheline/2) && line < ((cacheline+lines)/2)) {
+    n = cacheline; l = cache;
+  } else if (line <= (lines/2)) {
+    n = 1; l = first;
+  } else {
+    n = lines; l = last;
+  }
+  for (; n < line && l; n++) l = l->next;
+  for (; n > line && l; n--) l = l->prev;
+  ((Fl_Browser*)this)->cacheline = line;
+  ((Fl_Browser*)this)->cache = l;
+  return l;
+}
+
+int Fl_Browser::lineno(void* v) const {
+  FL_BLINE* l = (FL_BLINE*)v;
+  if (!l) return 0;
+  if (l == cache) return cacheline;
+  if (l == first) return 1;
+  if (l == last) return lines;
+  if (!cache) {
+    ((Fl_Browser*)this)->cache = first;
+    ((Fl_Browser*)this)->cacheline = 1;
+  }
+  // assumme it is near cache, search both directions:
+  FL_BLINE* b = cache->prev;
+  int bnum = cacheline-1;
+  FL_BLINE* f = cache->next;
+  int fnum = cacheline+1;
+  int n = 0;
+  for (;;) {
+    if (b == l) {n = bnum; break;}
+    if (f == l) {n = fnum; break;}
+    if (b) {b = b->prev; bnum--;}
+    if (f) {f = f->next; fnum++;}
+  }
+  ((Fl_Browser*)this)->cache = l;
+  ((Fl_Browser*)this)->cacheline = n;
+  return n;
+}
+
+FL_BLINE* Fl_Browser::_remove(int line) {
+  FL_BLINE* ttt = find_line(line);
+  deleting(ttt);
+
+  cacheline = line-1;
+  cache = ttt->prev;
+  lines--;
+  full_height_ -= item_height(ttt);
+  if (ttt->prev) ttt->prev->next = ttt->next;
+  else first = ttt->next;
+  if (ttt->next) ttt->next->prev = ttt->prev;
+  else last = ttt->prev;
+
+  return(ttt);
+}
+
+void Fl_Browser::remove(int line) {
+  if (line < 1 || line > lines) return;
+  free(_remove(line));
+}
+
+void Fl_Browser::insert(int line, FL_BLINE* t) {
+  if (!first) {
+    t->prev = t->next = 0;
+    first = last = t;
+  } else if (line <= 1) {
+    inserting(first, t);
+    t->prev = 0;
+    t->next = first;
+    t->next->prev = t;
+    first = t;
+  } else if (line > lines) {
+    t->prev = last;
+    t->prev->next = t;
+    t->next = 0;
+    last = t;
+  } else {
+    FL_BLINE* n = find_line(line);
+    inserting(n, t);
+    t->next = n;
+    t->prev = n->prev;
+    t->prev->next = t;
+    n->prev = t;
+  }
+  cacheline = line;
+  cache = t;
+  lines++;
+  full_height_ += item_height(t);
+  redraw_line(t);
+}
+
+void Fl_Browser::insert(int line, const char* newtext, void* d) {
+  int l = strlen(newtext);
+  FL_BLINE* t = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);
+  t->length = (short)l;
+  t->flags = 0;
+  strcpy(t->txt, newtext);
+  t->data = d;
+  insert(line, t);
+}
+
+void Fl_Browser::move(int to, int from) {
+  if (from < 1 || from > lines) return;
+  insert(to, _remove(from));
+}
+
+void Fl_Browser::text(int line, const char* newtext) {
+  if (line < 1 || line > lines) return;
+  FL_BLINE* t = find_line(line);
+  int l = strlen(newtext);
+  if (l > t->length) {
+    FL_BLINE* n = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);
+    replacing(t, n);
+    cache = n;
+    n->data = t->data;
+    n->length = (short)l;
+    n->flags = t->flags;
+    n->prev = t->prev;
+    if (n->prev) n->prev->next = n; else first = n;
+    n->next = t->next;
+    if (n->next) n->next->prev = n; else last = n;
+    free(t);
+    t = n;
+  }
+  strcpy(t->txt, newtext);
+  redraw_line(t);
+}
+
+void Fl_Browser::data(int line, void* d) {
+  if (line < 1 || line > lines) return;
+  find_line(line)->data = d;
+}
+
+int Fl_Browser::item_height(void* lv) const {
+  FL_BLINE* l = (FL_BLINE*)lv;
+  if (l->flags & NOTDISPLAYED) return 0;
+
+  int hmax = 2; // use 2 to insure we don't return a zero!
+
+  if (!l->txt[0]) {
+    // For blank lines set the height to exactly 1 line!
+    fl_font(textfont(), textsize());
+    int hh = fl_height();
+    if (hh > hmax) hmax = hh;
+  }
+  else {
+    const int* i = column_widths();
+    // do each column separately as they may all set different fonts:
+    for (char* str = l->txt; str && *str; str++) {
+      Fl_Font font = textfont(); // default font
+      int tsize = textsize(); // default size
+      while (*str==format_char()) {
+	str++;
+	switch (*str++) {
+	case 'l': case 'L': tsize = 24; break;
+	case 'm': case 'M': tsize = 18; break;
+	case 's': tsize = 11; break;
+	case 'b': font = (Fl_Font)(font|FL_BOLD); break;
+	case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
+	case 'f': case 't': font = FL_COURIER; break;
+	case 'B':
+	case 'C': strtol(str, &str, 10); break;// skip a color number
+	case 'F': font = (Fl_Font)strtol(str,&str,10); break;
+	case 'S': tsize = strtol(str,&str,10); break;
+	case 0: case '@': str--;
+	case '.': goto END_FORMAT;
+	}
+      }
+      END_FORMAT:
+      char* ptr = str;
+      if (ptr && *i++) str = strchr(str, column_char());
+      else str = NULL;
+      if((!str && *ptr) || (str && ptr < str)) {
+	fl_font(font, tsize); int hh = fl_height();
+	if (hh > hmax) hmax = hh;
+      }
+      if (!str || !*str) break;
+    }
+  }
+
+  return hmax; // previous version returned hmax+2!
+}
+
+int Fl_Browser::item_width(void* v) const {
+  char* str = ((FL_BLINE*)v)->txt;
+  const int* i = column_widths();
+  int ww = 0;
+
+  while (*i) { // add up all tab-seperated fields
+    char* e;
+    e = strchr(str, column_char());
+    if (!e) break; // last one occupied by text
+    str = e+1;
+    ww += *i++;
+  }
+
+  // OK, we gotta parse the string and find the string width...
+  int tsize = textsize();
+  Fl_Font font = textfont();
+  int done = 0;
+
+  while (*str == format_char_ && str[1] && str[1] != format_char_) {
+    str ++;
+    switch (*str++) {
+    case 'l': case 'L': tsize = 24; break;
+    case 'm': case 'M': tsize = 18; break;
+    case 's': tsize = 11; break;
+    case 'b': font = (Fl_Font)(font|FL_BOLD); break;
+    case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
+    case 'f': case 't': font = FL_COURIER; break;
+    case 'B':
+    case 'C': strtol(str, &str, 10); break;// skip a color number
+    case 'F': font = (Fl_Font)strtol(str, &str, 10); break;
+    case 'S': tsize = strtol(str, &str, 10); break;
+    case '.':
+      done = 1;
+      break;
+    case '@':
+      str--;
+      done = 1;
+    }
+
+    if (done)
+      break;
+  }
+
+  if (*str == format_char_ && str[1])
+    str ++;
+
+  fl_font(font, tsize);
+  return ww + int(fl_width(str)) + 6;
+}
+
+int Fl_Browser::full_height() const {
+  return full_height_;
+}
+
+int Fl_Browser::incr_height() const {
+  return textsize()+2;
+}
+
+void Fl_Browser::item_draw(void* v, int X, int Y, int W, int H) const {
+  char* str = ((FL_BLINE*)v)->txt;
+  const int* i = column_widths();
+
+  while (W > 6) {	// do each tab-seperated field
+    int w1 = W;	// width for this field
+    char* e = 0; // pointer to end of field or null if none
+    if (*i) { // find end of field and temporarily replace with 0
+      e = strchr(str, column_char());
+      if (e) {*e = 0; w1 = *i++;}
+    }
+    int tsize = textsize();
+    Fl_Font font = textfont();
+    Fl_Color lcol = textcolor();
+    Fl_Align talign = FL_ALIGN_LEFT;
+    // check for all the @-lines recognized by XForms:
+    while (*str == format_char() && *++str && *str != format_char()) {
+      switch (*str++) {
+      case 'l': case 'L': tsize = 24; break;
+      case 'm': case 'M': tsize = 18; break;
+      case 's': tsize = 11; break;
+      case 'b': font = (Fl_Font)(font|FL_BOLD); break;
+      case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
+      case 'f': case 't': font = FL_COURIER; break;
+      case 'c': talign = FL_ALIGN_CENTER; break;
+      case 'r': talign = FL_ALIGN_RIGHT; break;
+      case 'B': 
+	if (!(((FL_BLINE*)v)->flags & SELECTED)) {
+	  fl_color((Fl_Color)strtol(str, &str, 10));
+	  fl_rectf(X, Y, w1, H);
+	} else strtol(str, &str, 10);
+        break;
+      case 'C':
+	lcol = (Fl_Color)strtol(str, &str, 10);
+	break;
+      case 'F':
+	font = (Fl_Font)strtol(str, &str, 10);
+	break;
+      case 'N':
+	lcol = FL_INACTIVE_COLOR;
+	break;
+      case 'S':
+	tsize = strtol(str, &str, 10);
+	break;
+      case '-':
+	fl_color(FL_DARK3);
+	fl_line(X+3, Y+H/2, X+w1-3, Y+H/2);
+	fl_color(FL_LIGHT3);
+	fl_line(X+3, Y+H/2+1, X+w1-3, Y+H/2+1);
+	break;
+      case 'u':
+      case '_':
+	fl_color(lcol);
+	fl_line(X+3, Y+H-1, X+w1-3, Y+H-1);
+	break;
+      case '.':
+	goto BREAK;
+      case '@':
+	str--; goto BREAK;
+      }
+    }
+  BREAK:
+    fl_font(font, tsize);
+    if (((FL_BLINE*)v)->flags & SELECTED)
+      lcol = fl_contrast(lcol, selection_color());
+    if (!active_r()) lcol = fl_inactive(lcol);
+    fl_color(lcol);
+    fl_draw(str, X+3, Y, w1-6, H, e ? Fl_Align(talign|FL_ALIGN_CLIP) : talign, 0, 0);
+    if (!e) break; // no more fields...
+    *e = column_char(); // put the seperator back
+    X += w1;
+    W -= w1;
+    str = e+1;
+  }
+}
+
+static const int no_columns[1] = {0};
+
+Fl_Browser::Fl_Browser(int X, int Y, int W, int H, const char*l)
+  : Fl_Browser_(X, Y, W, H, l) {
+  column_widths_ = no_columns;
+  lines = 0;
+  full_height_ = 0;
+  cacheline = 0;
+  format_char_ = '@';
+  column_char_ = '\t';
+  first = last = cache = 0;
+}
+
+void Fl_Browser::lineposition(int line, Fl_Line_Position pos) {
+  if (line<1) line = 1;
+  if (line>lines) line = lines;
+  int p = 0;
+
+  FL_BLINE* l;
+  for (l=first; l && line>1; l = l->next) {
+    line--; p += item_height(l);
+  }
+  if (l && (pos == BOTTOM)) p += item_height (l);
+
+  int final = p, X, Y, W, H;
+  bbox(X, Y, W, H);
+
+  switch(pos) {
+    case TOP: break;
+    case BOTTOM: final -= H; break;
+    case MIDDLE: final -= H/2; break;
+  }
+  
+  if (final > (full_height() - H)) final = full_height() -H;
+  position(final);
+}
+
+int Fl_Browser::topline() const {
+  return lineno(top());
+}
+
+void Fl_Browser::clear() {
+  for (FL_BLINE* l = first; l;) {
+    FL_BLINE* n = l->next;
+    free(l);
+    l = n;
+  }
+  full_height_ = 0;
+  first = 0;
+  lines = 0;
+  new_list();
+}
+
+void Fl_Browser::add(const char* newtext, void* d) {
+  insert(lines+1, newtext, d);
+  //Fl_Browser_::display(last);
+}
+
+const char* Fl_Browser::text(int line) const {
+  if (line < 1 || line > lines) return 0;
+  return find_line(line)->txt;
+}
+
+void* Fl_Browser::data(int line) const {
+  if (line < 1 || line > lines) return 0;
+  return find_line(line)->data;
+}
+
+int Fl_Browser::select(int line, int v) {
+  if (line < 1 || line > lines) return 0;
+  return Fl_Browser_::select(find_line(line), v);
+}
+
+int Fl_Browser::selected(int line) const {
+  if (line < 1 || line > lines) return 0;
+  return find_line(line)->flags & SELECTED;
+}
+
+void Fl_Browser::show(int line) {
+  FL_BLINE* t = find_line(line);
+  if (t->flags & NOTDISPLAYED) {
+    t->flags &= ~NOTDISPLAYED;
+    full_height_ += item_height(t);
+    if (Fl_Browser_::displayed(t)) redraw_lines();
+  }
+}
+
+void Fl_Browser::hide(int line) {
+  FL_BLINE* t = find_line(line);
+  if (!(t->flags & NOTDISPLAYED)) {
+    full_height_ -= item_height(t);
+    t->flags |= NOTDISPLAYED;
+    if (Fl_Browser_::displayed(t)) redraw_lines();
+  }
+}
+
+void Fl_Browser::display(int line, int v) {
+  if (line < 1 || line > lines) return;
+  if (v) show(line); else hide(line);
+}
+
+int Fl_Browser::visible(int line) const {
+  if (line < 1 || line > lines) return 0;
+  return !(find_line(line)->flags&NOTDISPLAYED);
+}
+
+int Fl_Browser::value() const {
+  return lineno(selection());
+}
+
+// SWAP TWO LINES
+void Fl_Browser::swap(FL_BLINE *a, FL_BLINE *b) {
+
+  if ( a == b || !a || !b) return;          // nothing to do
+  FL_BLINE *aprev  = a->prev;
+  FL_BLINE *anext  = a->next;
+  FL_BLINE *bprev  = b->prev;
+  FL_BLINE *bnext  = b->next;
+  if ( b->prev == a ) { 		// A ADJACENT TO B
+     if ( aprev ) aprev->next = b; else first = b;
+     b->next = a;
+     a->next = bnext;
+     b->prev = aprev;
+     a->prev = b;
+     if ( bnext ) bnext->prev = a; else last = a;
+  } else if ( a->prev == b ) {		// B ADJACENT TO A
+     if ( bprev ) bprev->next = a; else first = a;
+     a->next = b;
+     b->next = anext;
+     a->prev = bprev;
+     b->prev = a;
+     if ( anext ) anext->prev = b; else last = b;
+  } else {				// A AND B NOT ADJACENT
+     // handle prev's
+     b->prev = aprev;
+     if ( anext ) anext->prev = b; else last = b;
+     a->prev = bprev;
+     if ( bnext ) bnext->prev = a; else last = a;
+     // handle next's
+     if ( aprev ) aprev->next = b; else first = b;
+     b->next = anext;
+     if ( bprev ) bprev->next = a; else first = a;
+     a->next = bnext;
+  }
+  // Disable cache -- we played around with positions
+  cacheline = 0;
+  // Redraw modified lines
+  redraw_lines();
+}
+
+void Fl_Browser::swap(int ai, int bi) {
+  if (ai < 1 || ai > lines || bi < 1 || bi > lines) return;
+  FL_BLINE* a = find_line(ai);
+  FL_BLINE* b = find_line(bi);
+  swap(a,b);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Browser_.cxx b/Utilities/FLTK/src/Fl_Browser_.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8f51318fe3fd6c188b191156e8bcd0e6108d71b5
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Browser_.cxx
@@ -0,0 +1,807 @@
+//
+// "$Id$"
+//
+// Base Browser widget class for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#define DISPLAY_SEARCH_BOTH_WAYS_AT_ONCE
+
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Browser_.H>
+#include <FL/fl_draw.H>
+
+
+// This is the base class for browsers.  To be useful it must be
+// subclassed and several virtual functions defined.  The
+// Forms-compatable browser and the file chooser's browser are
+// subclassed off of this.
+
+// Yes, I know this should be a template...
+
+// This has been designed so that the subclass has complete control
+// over the storage of the data, although because next() and prev()
+// functions are used to index, it works best as a linked list or as a
+// large block of characters in which the line breaks must be searched
+// for.
+
+// A great deal of work has been done so that the "height" of a data
+// object does not need to be determined until it is drawn.  This was
+// done for the file chooser, because the height requires doing stat()
+// to see if the file is a directory, which can be annoyingly slow
+// over the network.
+
+/* redraw bits:
+   1 = redraw children (the scrollbar)
+   2 = redraw one or two items
+   4 = redraw all items
+*/
+
+static void scrollbar_callback(Fl_Widget* s, void*) {
+  ((Fl_Browser_*)(s->parent()))->position(int(((Fl_Scrollbar*)s)->value()));
+}
+
+static void hscrollbar_callback(Fl_Widget* s, void*) {
+  ((Fl_Browser_*)(s->parent()))->hposition(int(((Fl_Scrollbar*)s)->value()));
+}
+
+int Fl_Browser_::scrollbar_width_ = 16;
+
+// return where to draw the actual box:
+void Fl_Browser_::bbox(int& X, int& Y, int& W, int& H) const {
+  Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
+  X = x()+Fl::box_dx(b);
+  Y = y()+Fl::box_dy(b);
+  W = w()-Fl::box_dw(b);
+  H = h()-Fl::box_dh(b);
+  if (scrollbar.visible()) {
+    W -= scrollbar_width_;
+    if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar_width_;
+  }
+  if (W < 0) W = 0;
+  if (hscrollbar.visible()) {
+    H -= scrollbar_width_;
+    if (scrollbar.align() & FL_ALIGN_TOP) Y += scrollbar_width_;
+  }
+  if (H < 0) H = 0;
+}
+
+int Fl_Browser_::leftedge() const {
+  int X, Y, W, H; bbox(X, Y, W, H);
+  return X;
+}
+
+// The scrollbars may be moved again by draw(), since each one's size
+// depends on whether the other is visible or not.  This skips over
+// Fl_Group::resize since it moves the scrollbars uselessly.
+void Fl_Browser_::resize(int X, int Y, int W, int H) {
+  Fl_Widget::resize(X, Y, W, H);
+  // move the scrollbars so they can respond to events:
+  bbox(X,Y,W,H);
+  scrollbar.resize(
+	scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar_width_ : X+W,
+	Y, scrollbar_width_, H);
+  hscrollbar.resize(
+	X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollbar_width_ : Y+H,
+	W, scrollbar_width_);
+}
+
+// Cause minimal update to redraw the given item:
+void Fl_Browser_::redraw_line(void* l) {
+  if (!redraw1 || redraw1 == l) {redraw1 = l; damage(FL_DAMAGE_EXPOSE);}
+  else if (!redraw2 || redraw2 == l) {redraw2 = l; damage(FL_DAMAGE_EXPOSE);}
+  else damage(FL_DAMAGE_SCROLL);
+}
+
+// Figure out top() based on position():
+void Fl_Browser_::update_top() {
+  if (!top_) top_ = item_first();
+  if (position_ != real_position_) {
+    void* l;
+    int ly;
+    int yy = position_;
+    // start from either head or current position, whichever is closer:
+    if (!top_ || yy <= (real_position_/2)) {
+      l = item_first();
+      ly = 0;
+    } else {
+      l = top_;
+      ly = real_position_-offset_;
+    }
+    if (!l) {
+      top_ = 0;
+      offset_ = 0;
+      real_position_ = 0;
+    } else {
+      int hh = item_quick_height(l);
+      // step through list until we find line containing this point:
+      while (ly > yy) {
+	void* l1 = item_prev(l);
+	if (!l1) {ly = 0; break;} // hit the top
+	l  = l1;
+	hh = item_quick_height(l);
+	ly -= hh;
+      }
+      while ((ly+hh) <= yy) {
+	void* l1 = item_next(l);
+	if (!l1) {yy = ly+hh-1; break;}
+	l = l1;
+	ly += hh;
+	hh = item_quick_height(l);
+      }
+      // top item must *really* be visible, use slow height:
+      for (;;) {
+	hh = item_height(l);
+	if ((ly+hh) > yy) break; // it is big enough to see
+	// go up to top of previous item:
+	void* l1 = item_prev(l);
+	if (!l1) {ly = yy = 0; break;} // hit the top
+	l = l1; yy = position_ = ly = ly-item_quick_height(l);
+      }
+      // use it:
+      top_ = l;
+      offset_ = yy-ly;
+      real_position_ = yy;
+    }
+    damage(FL_DAMAGE_SCROLL);
+  }
+}
+
+// Change position(), top() will update when update_top() is called
+// (probably by draw() or handle()):
+void Fl_Browser_::position(int yy) {
+  if (yy < 0) yy = 0;
+  if (yy == position_) return;
+  position_ = yy;
+  if (yy != real_position_) redraw_lines();
+}
+
+void Fl_Browser_::hposition(int xx) {
+  if (xx < 0) xx = 0;
+  if (xx == hposition_) return;
+  hposition_ = xx;
+  if (xx != real_hposition_) redraw_lines();
+}
+
+// Tell whether item is currently displayed:
+int Fl_Browser_::displayed(void* p) const {
+  int X, Y, W, H; bbox(X, Y, W, H);
+  int yy = H+offset_;
+  for (void* l = top_; l && yy > 0; l = item_next(l)) {
+    if (l == p) return 1;
+    yy -= item_height(l);
+  }
+  return 0;
+}
+
+// Ensure this item is displayed:
+// Messy because we have no idea if it is before top or after bottom:
+void Fl_Browser_::display(void* p) {
+
+  // First special case - want to display first item in the list?
+  update_top();
+  if (p == item_first()) {position(0); return;}
+
+  int X, Y, W, H, Yp; bbox(X, Y, W, H);
+  void* l = top_;
+  Y = Yp = -offset_;
+  int h1;
+
+  // 2nd special case - want to display item already displayed at top of browser?
+  if (l == p) {position(real_position_+Y); return;} // scroll up a bit
+
+  // 3rd special case - want to display item just above top of browser?
+  void* lp = item_prev(l);
+  if (lp == p) {position(real_position_+Y-item_quick_height(lp)); return;}
+
+#ifdef DISPLAY_SEARCH_BOTH_WAYS_AT_ONCE
+  // search for item.  We search both up and down the list at the same time,
+  // this evens up the execution time for the two cases - the old way was
+  // much slower for going up than for going down.
+  while (l || lp) {
+    if (l) {
+      h1 = item_quick_height(l);
+      if (l == p) {
+	if (Y <= H) { // it is visible or right at bottom
+	  Y = Y+h1-H; // find where bottom edge is
+	  if (Y > 0) position(real_position_+Y); // scroll down a bit
+	} else {
+	  position(real_position_+Y-(H-h1)/2); // center it
+	}
+	return;
+      }
+      Y += h1;
+      l = item_next(l);
+    }
+    if (lp) {
+      h1 = item_quick_height(lp);
+      Yp -= h1;
+      if (lp == p) {
+	if ((Yp + h1) >= 0) position(real_position_+Yp);
+	else position(real_position_+Yp-(H-h1)/2);
+	return;
+      }
+      lp = item_prev(lp);
+    }
+  }
+#else
+  // Old version went forwards and then backwards:
+  // search forward for it:
+  l = top_;
+  for (; l; l = item_next(l)) {
+    h1 = item_quick_height(l);
+    if (l == p) {
+      if (Y <= H) { // it is visible or right at bottom
+	Y = Y+h1-H; // find where bottom edge is
+	if (Y > 0) position(real_position_+Y); // scroll down a bit
+      } else {
+	position(real_position_+Y-(H-h1)/2); // center it
+      }
+      return;
+    }
+    Y += h1;
+  }
+  // search backward for it, if found center it:
+  l = lp;
+  Y = -offset_;
+  for (; l; l = item_prev(l)) {
+    h1 = item_quick_height(l);
+    Y -= h1;
+    if (l == p) {
+      if ((Y + h1) >= 0) position(real_position_+Y);
+      else position(real_position_+Y-(H-h1)/2);
+      return;
+    }
+  }
+#endif
+}
+
+// redraw, has side effect of updating top and setting scrollbar:
+
+void Fl_Browser_::draw() {
+  int drawsquare = 0;
+  update_top();
+  int full_width_ = full_width();
+  int full_height_ = full_height();
+  int X, Y, W, H; bbox(X, Y, W, H);
+  int dont_repeat = 0;
+J1:
+  if (damage() & FL_DAMAGE_ALL) { // redraw the box if full redraw
+    Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
+    draw_box(b, x(), y(), w(), h(), color());
+    drawsquare = 1;
+  }
+  // see if scrollbar needs to be switched on/off:
+  if ((has_scrollbar_ & VERTICAL) && (
+	(has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) {
+    if (!scrollbar.visible()) {
+      scrollbar.set_visible();
+      drawsquare = 1;
+      bbox(X, Y, W, H);
+    }
+  } else {
+    top_ = item_first(); real_position_ = offset_ = 0;
+    if (scrollbar.visible()) {
+      scrollbar.clear_visible();
+      clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL));
+    }
+  }
+
+  if ((has_scrollbar_ & HORIZONTAL) && (
+	(has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_ > W)) {
+    if (!hscrollbar.visible()) {
+      hscrollbar.set_visible();
+      drawsquare = 1;
+      bbox(X, Y, W, H);
+    }
+  } else {
+    real_hposition_ = 0;
+    if (hscrollbar.visible()) {
+      hscrollbar.clear_visible();
+      clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL));
+    }
+  }
+
+  // Check the vertical scrollbar again, just in case it needs to be drawn
+  // because the horizontal one is drawn.  There should be a cleaner way
+  // to do this besides copying the same code...
+  if ((has_scrollbar_ & VERTICAL) && (
+	(has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) {
+    if (!scrollbar.visible()) {
+      scrollbar.set_visible();
+      drawsquare = 1;
+      bbox(X, Y, W, H);
+    }
+  } else {
+    top_ = item_first(); real_position_ = offset_ = 0;
+    if (scrollbar.visible()) {
+      scrollbar.clear_visible();
+      clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL));
+    }
+  }
+
+  bbox(X, Y, W, H);
+
+  fl_clip(X, Y, W, H);
+  // for each line, draw it if full redraw or scrolled.  Erase background
+  // if not a full redraw or if it is selected:
+  void* l = top();
+  int yy = -offset_;
+  for (; l && yy < H; l = item_next(l)) {
+    int hh = item_height(l);
+    if (hh <= 0) continue;
+    if ((damage()&(FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) || l == redraw1 || l == redraw2) {
+      if (item_selected(l)) {
+	fl_color(active_r() ? selection_color() : fl_inactive(selection_color()));
+	fl_rectf(X, yy+Y, W, hh);
+      } else if (!(damage()&FL_DAMAGE_ALL)) {
+	fl_push_clip(X, yy+Y, W, hh);
+	draw_box(box() ? box() : FL_DOWN_BOX, x(), y(), w(), h(), color());
+	fl_pop_clip();
+      }
+      item_draw(l, X-hposition_, yy+Y, W+hposition_, hh);
+      if (l == selection_ && Fl::focus() == this) {
+	draw_box(FL_BORDER_FRAME, X, yy+Y, W, hh, color());
+	draw_focus(FL_NO_BOX, X, yy+Y, W+1, hh+1);
+      }
+      int ww = item_width(l);
+      if (ww > max_width) {max_width = ww; max_width_item = l;}
+    }
+    yy += hh;
+  }
+  // erase the area below last line:
+  if (!(damage()&FL_DAMAGE_ALL) && yy < H) {
+    fl_push_clip(X, yy+Y, W, H-yy);
+    draw_box(box() ? box() : FL_DOWN_BOX, x(), y(), w(), h(), color());
+    fl_pop_clip();
+  }
+  fl_pop_clip();
+  redraw1 = redraw2 = 0;
+
+  if (!dont_repeat) {
+    dont_repeat = 1;
+    // see if changes to full_height caused by calls to slow_height
+    // caused scrollbar state to change, in which case we have to redraw:
+    full_height_ = full_height();
+    full_width_ = full_width();
+    if ((has_scrollbar_ & VERTICAL) &&
+	((has_scrollbar_ & ALWAYS_ON) || position_ || full_height_>H)) {
+      if (!scrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; }
+    } else {
+      if (scrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; }
+    }
+    if ((has_scrollbar_ & HORIZONTAL) &&
+	((has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_>W)) {
+      if (!hscrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; }
+    } else {
+      if (hscrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; }
+    }
+  }
+
+  // update the scrollbars and redraw them:
+  int dy = top_ ? item_quick_height(top_) : 0; if (dy < 10) dy = 10;
+  if (scrollbar.visible()) {
+    scrollbar.damage_resize(
+	scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar_width_ : X+W,
+	Y, scrollbar_width_, H);
+    scrollbar.value(position_, H, 0, full_height_);
+    scrollbar.linesize(dy);
+    if (drawsquare) draw_child(scrollbar);
+    else update_child(scrollbar);
+  }
+  if (hscrollbar.visible()) {
+    hscrollbar.damage_resize(
+	X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollbar_width_ : Y+H,
+	W, scrollbar_width_);
+    hscrollbar.value(hposition_, W, 0, full_width_);
+    hscrollbar.linesize(dy);
+    if (drawsquare) draw_child(hscrollbar);
+    else update_child(hscrollbar);
+  }
+
+  // draw that little square between the scrollbars:
+  if (drawsquare && scrollbar.visible() && hscrollbar.visible()) {
+    fl_color(parent()->color());
+    fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar_width_,scrollbar_width_);
+  }
+
+  real_hposition_ = hposition_;
+}
+
+// Quick way to delete and reset everything:
+void Fl_Browser_::new_list() {
+  top_ = 0;
+  position_ = real_position_ = 0;
+  hposition_ = real_hposition_ = 0;
+  selection_ = 0;
+  offset_ = 0;
+  max_width = 0;
+  max_width_item = 0;
+  redraw_lines();
+}
+
+// Tell it that this item is going away, and that this must remove
+// all pointers to it:
+void Fl_Browser_::deleting(void* l) {
+  if (displayed(l)) {
+    redraw_lines();
+    if (l == top_) {
+      real_position_ -= offset_;
+      offset_ = 0;
+      top_ = item_next(l);
+      if (!top_) top_ = item_prev(l);
+    }
+  } else {
+    // we don't know where this item is, recalculate top...
+    real_position_ = 0;
+    offset_ = 0;
+    top_ = 0;
+  }
+  if (l == selection_) selection_ = 0;
+  if (l == max_width_item) {max_width_item = 0; max_width = 0;}
+}
+
+void Fl_Browser_::replacing(void* a, void* b) {
+  redraw_line(a);
+  if (a == selection_) selection_ = b;
+  if (a == top_) top_ = b;
+  if (a == max_width_item) {max_width_item = 0; max_width = 0;}
+}
+
+void Fl_Browser_::inserting(void* a, void* b) {
+  if (displayed(a)) redraw_lines();
+  if (a == top_) top_ = b;
+}
+
+void* Fl_Browser_::find_item(int my) {
+  update_top();
+  int X, Y, W, H; bbox(X, Y, W, H);
+  void* l;
+  int yy = Y-offset_;
+  for (l = top_; l; l = item_next(l)) {
+    int hh = item_height(l); if (hh <= 0) continue;
+    yy += hh;
+    if (my <= yy || yy>=(Y+H)) return l;
+  }
+  return 0;
+}
+
+int Fl_Browser_::select(void* l, int i, int docallbacks) {
+  if (type() == FL_MULTI_BROWSER) {
+    if (selection_ != l) {
+      if (selection_) redraw_line(selection_);
+      selection_ = l;
+      redraw_line(l);
+    }
+    if ((!i)==(!item_selected(l))) return 0;
+    item_select(l, i);
+    redraw_line(l);
+  } else {
+    if (i && selection_ == l) return 0;
+    if (!i && selection_ != l) return 0;
+    if (selection_) {
+      item_select(selection_, 0);
+      redraw_line(selection_);
+      selection_ = 0;
+    }
+    if (i) {
+      item_select(l, 1);
+      selection_ = l;
+      redraw_line(l);
+      display(l);
+    }
+  }	    
+  if (docallbacks) {
+    set_changed();
+    do_callback();
+  }
+  return 1;
+}
+
+int Fl_Browser_::deselect(int docallbacks) {
+  if (type() == FL_MULTI_BROWSER) {
+    int change = 0;
+    for (void* p = item_first(); p; p = item_next(p))
+      change |= select(p, 0, docallbacks);
+    return change;
+  } else {
+    if (!selection_) return 0;
+    item_select(selection_, 0);
+    redraw_line(selection_);
+    selection_ = 0;
+    return 1;
+  }
+}
+
+int Fl_Browser_::select_only(void* l, int docallbacks) {
+  if (!l) return deselect(docallbacks);
+  int change = 0;
+  if (type() == FL_MULTI_BROWSER) {
+    for (void* p = item_first(); p; p = item_next(p))
+      if (p != l) change |= select(p, 0, docallbacks);
+  }
+  change |= select(l, 1, docallbacks);
+  display(l);
+  return change;
+}
+
+int Fl_Browser_::handle(int event) {
+  // must do shortcuts first or the scrollbar will get them...
+  if (event == FL_ENTER || event == FL_LEAVE) return 1;
+  if (event == FL_KEYBOARD && type() >= FL_HOLD_BROWSER) {
+    void* l1 = selection_;
+    void* l = l1; if (!l) l = top_; if (!l) l = item_first();
+    if (l) {
+      if (type()==FL_HOLD_BROWSER) switch (Fl::event_key()) {
+      case FL_Down:
+	while ((l = item_next(l)))
+	  if (item_height(l)>0) {select_only(l, 1); break;}
+	return 1;
+      case FL_Up:
+	while ((l = item_prev(l))) if (item_height(l)>0) {
+	  select_only(l, 1); break;}
+	return 1;
+      } else switch (Fl::event_key()) {
+      case FL_Enter:
+      case FL_KP_Enter:
+	select_only(l, 1);
+	return 1;
+      case ' ':
+	selection_ = l;
+	select(l, !item_selected(l), 1);
+	return 1;
+      case FL_Down:
+	while ((l = item_next(l))) {
+	  if (Fl::event_state(FL_SHIFT|FL_CTRL))
+	    select(l, l1 ? item_selected(l1) : 1, 1);
+	  if (item_height(l)>0) goto J1;
+	}
+	return 1;
+      case FL_Up:
+	while ((l = item_prev(l))) {
+	  if (Fl::event_state(FL_SHIFT|FL_CTRL))
+	    select(l, l1 ? item_selected(l1) : 1, 1);
+	  if (item_height(l)>0) goto J1;
+	}
+	return 1;
+      J1:
+	if (selection_) redraw_line(selection_);
+	selection_ = l; redraw_line(l);
+	display(l);
+	return 1;
+      }
+    }
+  }
+
+  if (Fl_Group::handle(event)) return 1;
+  int X, Y, W, H; bbox(X, Y, W, H);
+  int my;
+// NOTE:
+// instead of:
+//     change = select_only(find_item(my), when() & FL_WHEN_CHANGED)
+// we use the construct:
+//     change = select_only(find_item(my), 0);
+//     if (change && (when() & FL_WHEN_CHANGED)) {
+//	 set_changed();
+//       do_callback();
+//     }
+// See str #834
+// The first form calls the callback *before* setting change.
+// The callback may execute an Fl::wait(), resulting in another
+// call of Fl_Browser_::handle() for the same widget. The sequence
+// of events can be an FL_PUSH followed by an FL_RELEASE.
+// This second call of Fl_Browser_::handle() may result in a -
+// somewhat unexpected - second concurrent invocation of the callback.
+
+  static char change;
+  static char whichway;
+  static int py;
+  switch (event) {
+  case FL_PUSH:
+    if (!Fl::event_inside(X, Y, W, H)) return 0;
+    if (Fl::visible_focus()) {
+      Fl::focus(this);
+      redraw();
+    }
+    my = py = Fl::event_y();
+    change = 0;
+    if (type() == FL_NORMAL_BROWSER || !top_)
+      ;
+    else if (type() != FL_MULTI_BROWSER) {
+      change = select_only(find_item(my), 0);
+      if (change && (when() & FL_WHEN_CHANGED)) {
+	set_changed();
+	do_callback();
+      }
+    } else {
+      void* l = find_item(my);
+      whichway = 1;
+      if (Fl::event_state(FL_CTRL)) { // toggle selection:
+      TOGGLE:
+	if (l) {
+	  whichway = !item_selected(l);
+	  change = select(l, whichway, 0);
+	  if (change && (when() & FL_WHEN_CHANGED)) {
+	    set_changed();
+	    do_callback();
+	  }
+	}
+      } else if (Fl::event_state(FL_SHIFT)) { // extend selection:
+	if (l == selection_) goto TOGGLE;
+	// state of previous selection determines new value:
+	whichway = l ? !item_selected(l) : 1;
+	// see which of the new item or previous selection is earlier,
+	// by searching from the previous forward for this one:
+	int down;
+	if (!l) down = 1;
+	else {for (void* m = selection_; ; m = item_next(m)) {
+	  if (m == l) {down = 1; break;}
+	  if (!m) {down = 0; break;}
+	}}
+	if (down) {
+	  for (void* m = selection_; m != l; m = item_next(m))
+	    select(m, whichway, when() & FL_WHEN_CHANGED);
+	} else {
+	  void* e = selection_;
+	  for (void* m = item_next(l); m; m = item_next(m)) {
+	    select(m, whichway, when() & FL_WHEN_CHANGED);
+	    if (m == e) break;
+	  }
+	}
+	// do the clicked item last so the select box is around it:
+	change = 1;
+	if (l) select(l, whichway, when() & FL_WHEN_CHANGED);
+      } else { // select only this item
+	change = select_only(l, 0);
+	if (change && (when() & FL_WHEN_CHANGED)) {
+	  set_changed();
+	  do_callback();
+	}
+      }
+    }
+    return 1;
+  case FL_DRAG:
+    // do the scrolling first:
+    my = Fl::event_y();
+    if (my < Y && my < py) {
+      int p = real_position_+my-Y;
+      if (p<0) p = 0;
+      position(p);
+    } else if (my > (Y+H) && my > py) {
+      int p = real_position_+my-(Y+H);
+      int hh = full_height()-H; if (p > hh) p = hh;
+      if (p<0) p = 0;
+      position(p);
+    }
+    if (type() == FL_NORMAL_BROWSER || !top_)
+      ;
+    else if (type() == FL_MULTI_BROWSER) {
+      void* l = find_item(my);
+      void* t; void* b; // this will be the range to change
+      if (my > py) { // go down
+	t = selection_ ? item_next(selection_) : 0;
+	b = l ? item_next(l) : 0;
+      } else {	// go up
+	t = l;
+	b = selection_;
+      }
+      for (; t && t != b; t = item_next(t)) {
+	char change_t;
+	change_t = select(t, whichway, 0);
+	change |= change_t;
+	if (change_t && (when() & FL_WHEN_CHANGED)) {
+	  set_changed();
+	  do_callback();
+	}
+      }
+      if (l) selection_ = l;
+    } else {
+      void* l1 = selection_;
+      void* l =
+	(Fl::event_x()<x() || Fl::event_x()>x()+w()) ? selection_ :
+	find_item(my);
+      change = (l != l1);
+      select_only(l, when() & FL_WHEN_CHANGED);
+    }
+    py = my;
+    return 1;
+  case FL_RELEASE:
+    if (type() == FL_SELECT_BROWSER) {
+      void* t = selection_; deselect(); selection_ = t;
+    }
+    if (change) {
+      set_changed();
+      if (when() & FL_WHEN_RELEASE) do_callback();
+    } else {
+      if (when() & FL_WHEN_NOT_CHANGED) do_callback();
+    }
+    return 1;
+  case FL_FOCUS:
+  case FL_UNFOCUS:
+    if (type() >= FL_HOLD_BROWSER && Fl::visible_focus()) {
+      redraw();
+      return 1;
+    } else return 0;
+  }
+
+  return 0;
+}
+
+Fl_Browser_::Fl_Browser_(int X, int Y, int W, int H, const char* l)
+  : Fl_Group(X, Y, W, H, l),
+    scrollbar(0, 0, 0, 0, 0), // they will be resized by draw()
+    hscrollbar(0, 0, 0, 0, 0)
+{
+  box(FL_NO_BOX);
+  align(FL_ALIGN_BOTTOM);
+  position_ = real_position_ = 0;
+  hposition_ = real_hposition_ = 0;
+  offset_ = 0;
+  top_ = 0;
+  when(FL_WHEN_RELEASE_ALWAYS);
+  selection_ = 0;
+  color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
+  scrollbar.callback(scrollbar_callback);
+//scrollbar.align(FL_ALIGN_LEFT|FL_ALIGN_BOTTOM); // back compatability?
+  hscrollbar.callback(hscrollbar_callback);
+  hscrollbar.type(FL_HORIZONTAL);
+  textfont_ = FL_HELVETICA;
+  textsize_ = (uchar)FL_NORMAL_SIZE;
+  textcolor_ = FL_FOREGROUND_COLOR;
+  has_scrollbar_ = BOTH;
+  max_width = 0;
+  max_width_item = 0;
+  redraw1 = redraw2 = 0;
+  end();
+}
+
+// Default versions of some of the virtual functions:
+
+int Fl_Browser_::item_quick_height(void* l) const {
+  return item_height(l);
+}
+
+int Fl_Browser_::incr_height() const {
+  return item_quick_height(item_first());
+}
+
+int Fl_Browser_::full_height() const {
+  int t = 0;
+  for (void* p = item_first(); p; p = item_next(p))
+    t += item_quick_height(p);
+  return t;
+}
+
+int Fl_Browser_::full_width() const {
+  return max_width;
+}
+
+void Fl_Browser_::item_select(void*, int) {}
+
+int Fl_Browser_::item_selected(void* l) const {return l==selection_;}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Browser_load.cxx b/Utilities/FLTK/src/Fl_Browser_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1e12a7872853956e9c22427d1b513659c237c0c6
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Browser_load.cxx
@@ -0,0 +1,57 @@
+//
+// "$Id$"
+//
+// File loading routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Browser.H>
+#include <stdio.h>
+
+int Fl_Browser::load(const char *filename) {
+#define MAXFL_BLINE 1024
+    char newtext[MAXFL_BLINE];
+    int c;
+    int i;
+    clear();
+    if (!filename || !(filename[0])) return 1;
+    FILE *fl = fopen(filename,"r");
+    if (!fl) return 0;
+    i = 0;
+    do {
+	c = getc(fl);
+	if (c == '\n' || c <= 0 || i>=(MAXFL_BLINE-1)) {
+	    newtext[i] = 0;
+	    add(newtext);
+	    i = 0;
+	} else
+	    newtext[i++] = c;
+    } while (c >= 0);
+    fclose(fl);
+    return 1;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Button.cxx b/Utilities/FLTK/src/Fl_Button.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8a4536de0a09c4e3da764060b37815ad7352dc9a
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Button.cxx
@@ -0,0 +1,164 @@
+//
+// "$Id$"
+//
+// Button widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Window.H>
+
+// There are a lot of subclasses, named Fl_*_Button.  Some of
+// them are implemented by setting the type() value and testing it
+// here.  This includes Fl_Radio_Button and Fl_Toggle_Button
+
+int Fl_Button::value(int v) {
+  v = v ? 1 : 0;
+  oldval = v;
+  clear_changed();
+  if (value_ != v) {
+    value_ = v;
+    redraw();
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+void Fl_Button::setonly() { // set this radio button on, turn others off
+  value(1);
+  Fl_Group* g = (Fl_Group*)parent();
+  Fl_Widget*const* a = g->array();
+  for (int i = g->children(); i--;) {
+    Fl_Widget* o = *a++;
+    if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0);
+  }
+}
+
+void Fl_Button::draw() {
+  if (type() == FL_HIDDEN_BUTTON) return;
+  Fl_Color col = value() ? selection_color() : color();
+//if (col == FL_GRAY && Fl::belowmouse()==this) col = FL_LIGHT1;
+  draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
+  draw_label();
+  if (Fl::focus() == this) draw_focus();
+}
+
+int Fl_Button::handle(int event) {
+  int newval;
+  switch (event) {
+  case FL_ENTER:
+  case FL_LEAVE:
+//  if ((value_?selection_color():color())==FL_GRAY) redraw();
+    return 1;
+  case FL_PUSH:
+    if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
+  case FL_DRAG:
+    if (Fl::event_inside(this)) {
+      if (type() == FL_RADIO_BUTTON) newval = 1;
+      else newval = !oldval;
+    } else
+      newval = oldval;
+    if (newval != value_) {
+      value_ = newval;
+      set_changed();
+      redraw();
+      if (when() & FL_WHEN_CHANGED) do_callback();
+    }
+    return 1;
+  case FL_RELEASE:
+    if (value_ == oldval) {
+      if (when() & FL_WHEN_NOT_CHANGED) do_callback();
+      return 1;
+    }
+    set_changed();
+    if (type() == FL_RADIO_BUTTON) setonly();
+    else if (type() == FL_TOGGLE_BUTTON) oldval = value_;
+    else {
+      value(oldval);
+      if (when() & FL_WHEN_CHANGED) do_callback();
+    }
+    if (when() & FL_WHEN_RELEASE) do_callback();
+    return 1;
+  case FL_SHORTCUT:
+    if (!(shortcut() ?
+	  Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
+    
+    if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
+
+    if (type() == FL_RADIO_BUTTON && !value_) {
+      setonly();
+      set_changed();
+      if (when() & FL_WHEN_CHANGED) do_callback();
+    } else if (type() == FL_TOGGLE_BUTTON) {
+      value(!value());
+      set_changed();
+      if (when() & FL_WHEN_CHANGED) do_callback();
+    } else if (when() & FL_WHEN_RELEASE) do_callback();
+    return 1;
+  case FL_FOCUS :
+  case FL_UNFOCUS :
+    if (Fl::visible_focus()) {
+      if (box() == FL_NO_BOX) {
+	// Widgets with the FL_NO_BOX boxtype need a parent to
+	// redraw, since it is responsible for redrawing the
+	// background...
+	int X = x() > 0 ? x() - 1 : 0;
+	int Y = y() > 0 ? y() - 1 : 0;
+	if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
+      } else redraw();
+      return 1;
+    } else return 0;
+  case FL_KEYBOARD :
+    if (Fl::focus() == this && Fl::event_key() == ' ' &&
+        !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
+      set_changed();
+      if (type() == FL_RADIO_BUTTON && !value_) {
+	setonly();
+	if (when() & FL_WHEN_CHANGED) do_callback();
+      } else if (type() == FL_TOGGLE_BUTTON) {
+	value(!value());
+	if (when() & FL_WHEN_CHANGED) do_callback();
+      }
+      if (when() & FL_WHEN_RELEASE) do_callback();
+      return 1;
+    }
+  default:
+    return 0;
+  }
+}
+
+Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *l)
+: Fl_Widget(X,Y,W,H,l) {
+  box(FL_UP_BOX);
+  down_box(FL_NO_BOX);
+  value_ = oldval = 0;
+  shortcut_ = 0;
+  set_flag(SHORTCUT_LABEL);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Chart.cxx b/Utilities/FLTK/src/Fl_Chart.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fce4bf045fe193513e26301fee1b1a37895d4dee
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Chart.cxx
@@ -0,0 +1,390 @@
+//
+// "$Id$"
+//
+// Forms-compatible chart widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/math.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Chart.H>
+#include <FL/fl_draw.H>
+#include "flstring.h"
+#include <stdlib.h>
+
+#define ARCINC	(2.0*M_PI/360.0)
+
+// this function is in fl_boxtype.cxx:
+void fl_rectbound(int x,int y,int w,int h, Fl_Color color);
+
+/* Widget specific information */
+
+static void draw_barchart(int x,int y,int w,int h,
+			  int numb, FL_CHART_ENTRY entries[],
+			  double min, double max, int autosize, int maxnumb,
+			  Fl_Color textcolor)
+/* Draws a bar chart. x,y,w,h is the bounding box, entries the array of
+   numb entries and min and max the boundaries. */
+{
+  double incr;
+  int zeroh;
+  double lh = fl_height();
+  if (max == min) incr = h;
+  else incr = h/(max-min);
+  if ( (-min*incr) < lh) {
+      incr = (h - lh + min*incr)/(max-min);
+      zeroh = int(y+h-lh);
+  } else {
+      zeroh = (int)rint(y+h+min * incr);
+  }
+  int bwidth = (int)rint(w/double(autosize?numb:maxnumb));
+  /* Draw base line */
+  fl_color(textcolor);
+  fl_line(x, zeroh, x+w, zeroh);
+  if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */
+  int i;
+  /* Draw the bars */
+  for (i=0; i<numb; i++) {
+      int hh = (int)rint(entries[i].val*incr);
+      if (hh < 0)
+	fl_rectbound(x+i*bwidth,zeroh,bwidth+1,-hh+1, (Fl_Color)entries[i].col);
+      else if (hh > 0)
+	fl_rectbound(x+i*bwidth,zeroh-hh,bwidth+1,hh+1,(Fl_Color)entries[i].col);
+  }
+  /* Draw the labels */
+  fl_color(textcolor);
+  for (i=0; i<numb; i++)
+      fl_draw(entries[i].str,
+	      x+i*bwidth+bwidth/2,zeroh,0,0,
+	      FL_ALIGN_TOP);
+}
+
+static void draw_horbarchart(int x,int y,int w,int h,
+			     int numb, FL_CHART_ENTRY entries[],
+			     double min, double max, int autosize, int maxnumb,
+			     Fl_Color textcolor)
+/* Draws a horizontal bar chart. x,y,w,h is the bounding box, entries the
+   array of numb entries and min and max the boundaries. */
+{
+  int i;
+  double lw = 0.0;		/* Maximal label width */
+  /* Compute maximal label width */
+  for (i=0; i<numb; i++) {
+      double w1 = fl_width(entries[i].str);
+      if (w1 > lw) lw = w1;
+  }
+  if (lw > 0.0) lw += 4.0;
+  double incr;
+  int zeroh;
+  if (max == min) incr = w;
+  else incr = w/(max-min);
+  if ( (-min*incr) < lw) {
+      incr = (w - lw + min*incr)/(max-min);
+      zeroh = x+(int)rint(lw);
+  } else {
+      zeroh = (int)rint(x-min * incr);
+  }
+  int bwidth = (int)rint(h/double(autosize?numb:maxnumb));
+  /* Draw base line */
+  fl_color(textcolor);
+  fl_line(zeroh, y, zeroh, y+h);
+  if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */
+  /* Draw the bars */
+  for (i=0; i<numb; i++) {
+      int ww = (int)rint(entries[i].val*incr);
+      if (ww > 0)
+	fl_rectbound(zeroh,y+i*bwidth,ww+1,bwidth+1, (Fl_Color)entries[i].col);
+      else if (ww < 0)
+	fl_rectbound(zeroh+w,y+i*bwidth,-ww+1,bwidth+1,(Fl_Color)entries[i].col);
+  }
+  /* Draw the labels */
+  fl_color(textcolor);
+  for (i=0; i<numb; i++)
+      fl_draw(entries[i].str,
+	      zeroh-2,y+i*bwidth+bwidth/2,0,0,
+	      FL_ALIGN_RIGHT);
+}
+
+static void draw_linechart(int type, int x,int y,int w,int h,
+			   int numb, FL_CHART_ENTRY entries[],
+			   double min, double max, int autosize, int maxnumb,
+			   Fl_Color textcolor)
+/* Draws a line chart. x,y,w,h is the bounding box, entries the array of
+   numb entries and min and max the boundaries. */
+{
+  int i;
+  double lh = fl_height();
+  double incr;
+  if (max == min) incr = h-2.0*lh;
+  else incr = (h-2.0*lh)/ (max-min);
+  int zeroh = (int)rint(y+h-lh+min * incr);
+  double bwidth = w/double(autosize?numb:maxnumb);
+  /* Draw the values */
+  for (i=0; i<numb; i++) {
+      int x0 = x + (int)rint((i-.5)*bwidth);
+      int x1 = x + (int)rint((i+.5)*bwidth);
+      int yy0 = i ? zeroh - (int)rint(entries[i-1].val*incr) : 0;
+      int yy1 = zeroh - (int)rint(entries[i].val*incr);
+      if (type == FL_SPIKE_CHART) {
+	  fl_color((Fl_Color)entries[i].col);
+	  fl_line(x1, zeroh, x1, yy1);
+      } else if (type == FL_LINE_CHART && i != 0) {
+	  fl_color((Fl_Color)entries[i-1].col);
+	  fl_line(x0,yy0,x1,yy1);
+      } else if (type == FL_FILLED_CHART && i != 0) {
+	  fl_color((Fl_Color)entries[i-1].col);
+	  if ((entries[i-1].val>0.0)!=(entries[i].val>0.0)) {
+	      double ttt = entries[i-1].val/(entries[i-1].val-entries[i].val);
+	      int xt = x + (int)rint((i-.5+ttt)*bwidth);
+	      fl_polygon(x0,zeroh, x0,yy0, xt,zeroh);
+	      fl_polygon(xt,zeroh, x1,yy1, x1,zeroh);
+	  } else {
+	      fl_polygon(x0,zeroh, x0,yy0, x1,yy1, x1,zeroh);
+	  }
+	  fl_color(textcolor);
+	  fl_line(x0,yy0,x1,yy1);
+      }
+  }
+  /* Draw base line */
+  fl_color(textcolor);
+  fl_line(x,zeroh,x+w,zeroh);
+  /* Draw the labels */
+  for (i=0; i<numb; i++)
+      fl_draw(entries[i].str,
+	      x+(int)rint((i+.5)*bwidth), zeroh - (int)rint(entries[i].val*incr),0,0,
+	      entries[i].val>=0 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP);
+}
+
+static void draw_piechart(int x,int y,int w,int h,
+			  int numb, FL_CHART_ENTRY entries[], int special,
+			  Fl_Color textcolor)
+/* Draws a pie chart. x,y,w,h is the bounding box, entries the array of
+   numb entries */
+{
+  int i;
+  double xc,yc,rad;	/* center and radius */
+  double tot;		/* sum of values */
+  double incr;		/* increment in angle */
+  double curang;		/* current angle we are drawing */
+  double txc,tyc;	/* temporary center */
+  double lh = fl_height();
+  /* compute center and radius */
+  double h_denom = (special ? 2.3 : 2.0);
+  rad = (h - 2*lh)/h_denom/1.1;
+  xc = x+w/2.0; yc = y+h-1.1*rad-lh;
+  /* compute sum of values */
+  tot = 0.0;
+  for (i=0; i<numb; i++)
+    if (entries[i].val > 0.0) tot += entries[i].val;
+  if (tot == 0.0) return;
+  incr = 360.0/tot;
+  /* Draw the pie */
+  curang = 0.0;
+  for (i=0; i<numb; i++)
+    if (entries[i].val > 0.0)
+    {
+      txc = xc; tyc = yc;
+      /* Correct for special pies */
+      if (special && i==0)
+      {
+        txc += 0.3*rad*cos(ARCINC*(curang+0.5*incr*entries[i].val));
+        tyc -= 0.3*rad*sin(ARCINC*(curang+0.5*incr*entries[i].val));
+      }
+      fl_color((Fl_Color)entries[i].col);
+      fl_begin_polygon(); fl_vertex(txc,tyc);
+      fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val);
+      fl_end_polygon();
+      fl_color(textcolor);
+      fl_begin_loop(); fl_vertex(txc,tyc);
+      fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val);
+      fl_end_loop();
+      curang += 0.5 * incr * entries[i].val;
+      /* draw the label */
+      double xl = txc + 1.1*rad*cos(ARCINC*curang);
+      fl_draw(entries[i].str,
+	      (int)rint(xl),
+	      (int)rint(tyc - 1.1*rad*sin(ARCINC*curang)),
+	      0, 0,
+	      xl<txc ? FL_ALIGN_RIGHT : FL_ALIGN_LEFT);
+      curang += 0.5 * incr * entries[i].val;
+    }
+}
+
+void Fl_Chart::draw() {
+
+    draw_box();
+    Fl_Boxtype b = box();
+    int xx = x()+Fl::box_dx(b); // was 9 instead of dx...
+    int yy = y()+Fl::box_dy(b);
+    int ww = w()-Fl::box_dw(b);
+    int hh = h()-Fl::box_dh(b);
+    fl_push_clip(xx, yy, ww, hh);
+
+    ww--; hh--; // adjust for line thickness
+
+    if (min >= max) {
+	min = max = 0.0;
+	for (int i=0; i<numb; i++) {
+	    if (entries[i].val < min) min = entries[i].val;
+	    if (entries[i].val > max) max = entries[i].val;
+	}
+    }
+
+    fl_font(textfont(),textsize());
+
+    switch (type()) {
+    case FL_BAR_CHART:
+	ww++; // makes the bars fill box correctly
+	draw_barchart(xx,yy,ww,hh, numb, entries, min, max,
+			autosize(), maxnumb, textcolor());
+	break;
+    case FL_HORBAR_CHART:
+	hh++; // makes the bars fill box correctly
+	draw_horbarchart(xx,yy,ww,hh, numb, entries, min, max,
+			autosize(), maxnumb, textcolor());
+	break;
+    case FL_PIE_CHART:
+	draw_piechart(xx,yy,ww,hh,numb,entries,0, textcolor());
+	break;
+    case FL_SPECIALPIE_CHART:
+	draw_piechart(xx,yy,ww,hh,numb,entries,1,textcolor());
+	break;
+    default:
+	draw_linechart(type(),xx,yy,ww,hh, numb, entries, min, max,
+			autosize(), maxnumb, textcolor());
+	break;
+    }
+    draw_label();
+    fl_pop_clip();
+}
+
+/*------------------------------*/
+
+#define FL_CHART_BOXTYPE	FL_BORDER_BOX
+#define FL_CHART_COL1		FL_COL1
+#define FL_CHART_LCOL		FL_LCOL
+#define FL_CHART_ALIGN		FL_ALIGN_BOTTOM
+
+Fl_Chart::Fl_Chart(int X, int Y, int W, int H,const char *l) :
+Fl_Widget(X,Y,W,H,l) {
+  box(FL_BORDER_BOX);
+  align(FL_ALIGN_BOTTOM);
+  numb       = 0;
+  maxnumb    = 0;
+  sizenumb   = FL_CHART_MAX;
+  autosize_  = 1;
+  min = max  = 0;
+  textfont_  = FL_HELVETICA;
+  textsize_  = 10;
+  textcolor_ = FL_FOREGROUND_COLOR;
+  entries    = (FL_CHART_ENTRY *)calloc(sizeof(FL_CHART_ENTRY), FL_CHART_MAX + 1);
+}
+
+Fl_Chart::~Fl_Chart() {
+  free(entries);
+}
+
+void Fl_Chart::clear() {
+  numb = 0;
+  redraw();
+}
+
+void Fl_Chart::add(double val, const char *str, unsigned col) {
+  /* Allocate more entries if required */
+  if (numb >= sizenumb) {
+    sizenumb += FL_CHART_MAX;
+    entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1));
+  }
+  // Shift entries as needed
+  if (numb >= maxnumb && maxnumb > 0) {
+    memmove(entries, entries + 1, sizeof(FL_CHART_ENTRY) * (numb - 1));
+    numb --;
+  }
+  entries[numb].val = float(val);
+  entries[numb].col = col;
+    if (str) {
+	strlcpy(entries[numb].str,str,FL_CHART_LABEL_MAX + 1);
+    } else {
+	entries[numb].str[0] = 0;
+    }
+  numb++;
+  redraw();
+}
+
+void Fl_Chart::insert(int ind, double val, const char *str, unsigned col) {
+  int i;
+  if (ind < 1 || ind > numb+1) return;
+  /* Allocate more entries if required */
+  if (numb >= sizenumb) {
+    sizenumb += FL_CHART_MAX;
+    entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1));
+  }
+  // Shift entries as needed
+  for (i=numb; i >= ind; i--) entries[i] = entries[i-1];
+  if (numb < maxnumb || maxnumb == 0) numb++;
+  /* Fill in the new entry */
+  entries[ind-1].val = float(val);
+  entries[ind-1].col = col;
+  if (str) {
+      strlcpy(entries[ind-1].str,str,FL_CHART_LABEL_MAX+1);
+  } else {
+      entries[ind-1].str[0] = 0;
+  }
+  redraw();
+}
+
+void Fl_Chart::replace(int ind,double val, const char *str, unsigned col) {
+  if (ind < 1 || ind > numb) return;
+  entries[ind-1].val = float(val);
+  entries[ind-1].col = col;
+  if (str) {
+      strlcpy(entries[ind-1].str,str,FL_CHART_LABEL_MAX+1);
+  } else {
+      entries[ind-1].str[0] = 0;
+  }
+  redraw();
+}
+
+void Fl_Chart::bounds(double mymin, double mymax) {
+  this->min = mymin;
+  this->max = mymax;
+  redraw();
+}
+
+void Fl_Chart::maxsize(int m) {
+  int i;
+  /* Fill in the new number */
+  if (m < 0) return;
+  maxnumb = m;
+  /* Shift entries if required */
+  if (numb > maxnumb) {
+      for (i = 0; i<maxnumb; i++)
+	  entries[i] = entries[i+numb-maxnumb];
+      numb = maxnumb;
+      redraw();
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Check_Browser.cxx b/Utilities/FLTK/src/Fl_Check_Browser.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..05c7b1c329c9142c2975f7b2cc029cf461915508
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Check_Browser.cxx
@@ -0,0 +1,272 @@
+//
+// "$Id$"
+//
+// Fl_Check_Browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <FL/fl_draw.H>
+#include <FL/Fl_Check_Browser.H>
+
+/* This uses a cache for faster access when you're scanning the list
+either forwards or backwards. */
+
+Fl_Check_Browser::cb_item *Fl_Check_Browser::find_item(int n) const {
+	int i = n;
+	cb_item *p = first;
+
+	if (n <= 0 || n > nitems_ || p == 0) {
+		return 0;
+	}
+
+	if (n == cached_item) {
+		p = cache;
+		n = 1;
+	} else if (n == cached_item + 1) {
+		p = cache->next;
+		n = 1;
+	} else if (n == cached_item - 1) {
+		p = cache->prev;
+		n = 1;
+	}
+
+	while (--n) {
+		p = p->next;
+	}
+
+	/* Cast to not const and cache it. */
+
+	((Fl_Check_Browser *)this)->cache = p;
+	((Fl_Check_Browser *)this)->cached_item = i;
+
+	return p;
+}
+
+int Fl_Check_Browser::lineno(cb_item *p0) const {
+	cb_item *p = first;
+
+	if (p == 0) {
+		return 0;
+	}
+
+	int i = 1;
+	while (p) {
+		if (p == p0) {
+			return i;
+		}
+		i++;
+		p = p->next;
+	}
+
+	return 0;
+}
+
+Fl_Check_Browser::Fl_Check_Browser(int X, int Y, int W, int H, const char *l)
+	: Fl_Browser_(X, Y, W, H, l) {
+	type(FL_SELECT_BROWSER);
+	when(FL_WHEN_NEVER);
+	first = last = 0;
+	nitems_ = nchecked_ = 0;
+	cached_item = -1;
+}
+
+void *Fl_Check_Browser::item_first() const {
+	return first;
+}
+
+void *Fl_Check_Browser::item_next(void *l) const {
+	return ((cb_item *)l)->next;
+}
+
+void *Fl_Check_Browser::item_prev(void *l) const {
+	return ((cb_item *)l)->prev;
+}
+
+int Fl_Check_Browser::item_height(void *) const {
+	return textsize() + 2;
+}
+
+#define CHECK_SIZE (textsize()-2)
+
+int Fl_Check_Browser::item_width(void *v) const {
+	fl_font(textfont(), textsize());
+	return int(fl_width(((cb_item *)v)->text)) + CHECK_SIZE + 8;
+}
+
+void Fl_Check_Browser::item_draw(void *v, int X, int Y, int, int) const {
+	cb_item *i = (cb_item *)v;
+	char *s = i->text;
+	int tsize = textsize();
+	Fl_Color col = active_r() ? textcolor() : fl_inactive(textcolor());
+	int cy = Y + (tsize + 1 - CHECK_SIZE) / 2;
+	X += 2;
+
+	fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR));
+	fl_loop(X, cy, X, cy + CHECK_SIZE,
+	        X + CHECK_SIZE, cy + CHECK_SIZE, X + CHECK_SIZE, cy);
+	if (i->checked) {
+	  int tx = X + 3;
+	  int tw = CHECK_SIZE - 4;
+	  int d1 = tw/3;
+	  int d2 = tw-d1;
+	  int ty = cy + (CHECK_SIZE+d2)/2-d1-2;
+	  for (int n = 0; n < 3; n++, ty++) {
+	    fl_line(tx, ty, tx+d1, ty+d1);
+	    fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1);
+	  }
+	}
+	fl_font(textfont(), tsize);
+	if (i->selected) {
+		col = fl_contrast(col, selection_color());
+	}
+	fl_color(col);
+	fl_draw(s, X + CHECK_SIZE + 8, Y + tsize - 1);
+}
+
+void Fl_Check_Browser::item_select(void *v, int state) {
+	cb_item *i = (cb_item *)v;
+
+	if (state) {
+		if (i->checked) {
+			i->checked = 0;
+			nchecked_--;
+		} else {
+			i->checked = 1;
+			nchecked_++;
+		}
+	}
+}
+
+int Fl_Check_Browser::item_selected(void *v) const {
+	cb_item *i = (cb_item *)v;
+	return i->selected;
+}
+
+int Fl_Check_Browser::add(char *s) {
+	return (add(s, 0));
+}
+
+int Fl_Check_Browser::add(char *s, int b) {
+	cb_item *p = (cb_item *)malloc(sizeof(cb_item));
+	p->next = 0;
+	p->prev = 0;
+	p->checked = b;
+	p->selected = 0;
+	p->text = strdup(s);
+
+	if (b) {
+		nchecked_++;
+	}
+
+	if (last == 0) {
+		first = last = p;
+	} else {
+		last->next = p;
+		p->prev = last;
+		last = p;
+	}
+	nitems_++;
+
+	return (nitems_);
+}
+
+void Fl_Check_Browser::clear() {
+	cb_item *p = first;
+	cb_item *next;
+
+	if (p == 0) {
+		return;
+	}
+
+	new_list();
+	do {
+		next = p->next;
+		free(p->text);
+		free(p);
+		p = next;
+	} while (p);
+
+	first = last = 0;
+	nitems_ = nchecked_ = 0;
+	cached_item = -1;
+}
+
+int Fl_Check_Browser::checked(int i) const {
+	cb_item *p = find_item(i);
+
+	if (p) return p->checked;
+	return 0;
+}
+
+void Fl_Check_Browser::checked(int i, int b) {
+	cb_item *p = find_item(i);
+
+	if (p && (p->checked ^ b)) {
+		p->checked = b;
+		if (b) {
+			nchecked_++;
+		} else {
+			nchecked_--;
+		}
+		redraw();
+	}
+}
+
+int Fl_Check_Browser::value() const {
+	return lineno((cb_item *)selection());
+}
+
+char *Fl_Check_Browser::text(int i) const {
+	cb_item *p = find_item(i);
+
+	if (p) return p->text;
+	return 0;
+}
+
+void Fl_Check_Browser::check_all() {
+	cb_item *p;
+
+	nchecked_ = nitems_;
+	for (p = first; p; p = p->next) {
+		p->checked = 1;
+	}
+	redraw();
+}
+
+void Fl_Check_Browser::check_none() {
+	cb_item *p;
+
+	nchecked_ = 0;
+	for (p = first; p; p = p->next) {
+		p->checked = 0;
+	}
+	redraw();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Check_Button.cxx b/Utilities/FLTK/src/Fl_Check_Button.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..54fb028501dc26e2a82bf5d9d557fcda0057dfa2
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Check_Button.cxx
@@ -0,0 +1,40 @@
+//
+// "$Id$"
+//
+// Check button widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Check_Button.H>
+
+// A subclass of Fl_Button that always draws as a diamond box.  This
+// diamond is smaller than the widget size and can be surchecked by
+// another box type, for compatability with Forms.
+
+Fl_Check_Button::Fl_Check_Button(int X, int Y, int W, int H, const char *l)
+: Fl_Light_Button(X, Y, W, H, l) {
+  box(FL_NO_BOX);
+  down_box(FL_DOWN_BOX);
+  selection_color(FL_FOREGROUND_COLOR);
+}
diff --git a/Utilities/FLTK/src/Fl_Choice.cxx b/Utilities/FLTK/src/Fl_Choice.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6361e03a452089cc8e43a6fc20864723ddee2ea6
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Choice.cxx
@@ -0,0 +1,162 @@
+//
+// "$Id$"
+//
+// Choice widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Choice.H>
+#include <FL/fl_draw.H>
+
+// Emulates the Forms choice widget.  This is almost exactly the same
+// as an Fl_Menu_Button.  The only difference is the appearance of the
+// button: it draws the text of the current pick and a down-arrow.
+
+void Fl_Choice::draw() {
+  int dx = Fl::box_dx(FL_DOWN_BOX);
+  int dy = Fl::box_dy(FL_DOWN_BOX);
+  int H = h() - 2 * dy;
+  int W = (H > 20) ? 20 : H;
+  int X = x() + w() - W - dx;
+  int Y = y() + dy;
+  int w1 = (W - 4) / 3; if (w1 < 1) w1 = 1;
+  int x1 = X + (W - 2 * w1 - 1) / 2;
+  int y1 = Y + (H - w1 - 1) / 2;
+
+  if (Fl::scheme()) {
+    draw_box(FL_UP_BOX, color());
+
+    fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor()));
+    fl_polygon(x1, y1 + 3, x1 + w1, y1 + w1 + 3, x1 + 2 * w1, y1 + 3);
+    fl_polygon(x1, y1 + 1, x1 + w1, y1 - w1 + 1, x1 + 2 * w1, y1 + 1);
+  } else {
+    draw_box(FL_DOWN_BOX, color());
+    draw_box(FL_UP_BOX,X,Y,W,H,FL_GRAY);
+
+    fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor()));
+    fl_polygon(x1, y1, x1 + w1, y1 + w1, x1 + 2 * w1, y1);
+  }
+
+  W += 2 * dx;
+
+  if (mvalue()) {
+    Fl_Menu_Item m = *mvalue();
+    if (active_r()) m.activate(); else m.deactivate();
+
+    // ERCO
+    int xx = x() + dx, yy = y() + dy + 1, ww = w() - W, hh = H - 2;
+
+    fl_clip(xx, yy, ww, hh);
+
+    if ( Fl::scheme()) {
+      Fl_Label l;
+      l.value = m.text;
+      l.image = 0;
+      l.deimage = 0;
+      l.type = m.labeltype_;
+      l.font = m.labelsize_ || m.labelfont_ ? m.labelfont_ : uchar(textfont());
+      l.size = m.labelsize_ ? m.labelsize_ : textsize();
+      l.color= m.labelcolor_ ? m.labelcolor_ : textcolor();
+      if (!m.active()) l.color = fl_inactive((Fl_Color)l.color);
+      fl_draw_shortcut = 2; // hack value to make '&' disappear
+      l.draw(xx+3, yy, ww>6 ? ww-6 : 0, hh, FL_ALIGN_LEFT);
+      fl_draw_shortcut = 0;
+      if ( Fl::focus() == this ) draw_focus(box(), xx, yy, ww, hh);
+    }
+    else {
+      fl_draw_shortcut = 2; // hack value to make '&' disappear
+      m.draw(xx, yy, ww, hh, this, Fl::focus() == this);
+      fl_draw_shortcut = 0;
+    }
+
+    fl_pop_clip();
+  }
+
+  draw_label();
+}
+
+Fl_Choice::Fl_Choice(int X, int Y, int W, int H, const char *l)
+: Fl_Menu_(X,Y,W,H,l) {
+  align(FL_ALIGN_LEFT);
+  when(FL_WHEN_RELEASE);
+  textfont(FL_HELVETICA);
+  box(FL_FLAT_BOX);
+  down_box(FL_BORDER_BOX);
+  color(FL_BACKGROUND2_COLOR);
+}
+
+int Fl_Choice::value(const Fl_Menu_Item *v) {
+  if (!Fl_Menu_::value(v)) return 0;
+  redraw();
+  return 1;
+}
+
+int Fl_Choice::value(int v) {
+  if (v == -1) return value((const Fl_Menu_Item *)0);
+  if (v < 0 || v >= (size() - 1)) return 0;
+  if (!Fl_Menu_::value(v)) return 0;
+  redraw();
+  return 1;
+}
+
+int Fl_Choice::handle(int e) {
+  if (!menu() || !menu()->text) return 0;
+  const Fl_Menu_Item* v;
+  switch (e) {
+  case FL_ENTER:
+  case FL_LEAVE:
+    return 1;
+
+  case FL_KEYBOARD:
+    if (Fl::event_key() != ' ' ||
+        (Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) return 0;
+  case FL_PUSH:
+    if (Fl::visible_focus()) Fl::focus(this);
+  J1:
+    v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this);
+    if (!v || v->submenu()) return 1;
+    if (v != mvalue()) redraw();
+    picked(v);
+    return 1;
+  case FL_SHORTCUT:
+    if (Fl_Widget::test_shortcut()) goto J1;
+    v = menu()->test_shortcut();
+    if (!v) return 0;
+    if (v != mvalue()) redraw();
+    picked(v);
+    return 1;
+  case FL_FOCUS:
+  case FL_UNFOCUS:
+    if (Fl::visible_focus()) {
+      redraw();
+      return 1;
+    } else return 0;
+  default:
+    return 0;
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Clock.cxx b/Utilities/FLTK/src/Fl_Clock.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..edb6749c4c26b091435f4c67d6f24ad3ad084d48
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Clock.cxx
@@ -0,0 +1,173 @@
+//
+// "$Id$"
+//
+// Clock widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Clock.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+#include <time.h>
+#ifndef WIN32
+#  include <sys/time.h>
+#endif /* !WIN32 */
+
+// Original clock display written by Paul Haeberli at SGI.
+// Modifications by Mark Overmars for Forms
+// Further changes by Bill Spitzak for fltk
+
+const float hourhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -7.0f}};
+const float  minhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -11.5f}};
+const float  sechand[4][2] = {{-0.1f, 0}, {0, 2.0f}, {0.1f, 0}, {0, -11.5f}};
+
+static void drawhand(double ang,const float v[][2],Fl_Color fill,Fl_Color line)
+{
+  fl_push_matrix();
+  fl_rotate(ang);
+  fl_color(fill); fl_begin_polygon();
+  int i; for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_polygon();
+  fl_color(line); fl_begin_loop();
+  for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_loop();
+  fl_pop_matrix();
+}
+
+void Fl_Clock_Output::drawhands(Fl_Color fill, Fl_Color line) {
+  drawhand(-360*(hour()+minute()/60.0)/12, hourhand, fill, line);
+  drawhand(-360*(minute()+second()/60.0)/60, minhand, fill, line);
+  drawhand(-360*(second()/60.0), sechand, fill, line);
+}
+
+static void rect(double x, double y, double w, double h) {
+  double r = x+w;
+  double t = y+h;
+  fl_begin_polygon();
+  fl_vertex(x, y);
+  fl_vertex(r, y);
+  fl_vertex(r, t);
+  fl_vertex(x, t);
+  fl_end_polygon();
+}
+
+void Fl_Clock_Output::draw(int X, int Y, int W, int H) {
+  Fl_Color box_color = type()==FL_ROUND_CLOCK ? FL_GRAY : color();
+  Fl_Color shadow_color = fl_color_average(box_color, FL_BLACK, 0.5);
+  draw_box(box(), X, Y, W, H, box_color);
+  fl_push_matrix();
+  fl_translate(X+W/2.0-.5, Y+H/2.0-.5);
+  fl_scale((W-1)/28.0, (H-1)/28.0);
+  if (type() == FL_ROUND_CLOCK) {
+    fl_color(color());
+    fl_begin_polygon(); fl_circle(0,0,14); fl_end_polygon();
+    fl_color(FL_FOREGROUND_COLOR);
+    fl_begin_loop(); fl_circle(0,0,14); fl_end_loop();
+  }
+  // draw the shadows:
+  fl_push_matrix();
+  fl_translate(0.60, 0.60);
+  drawhands(shadow_color, shadow_color);
+  fl_pop_matrix();
+  // draw the tick marks:
+  fl_push_matrix();
+  fl_color(FL_FOREGROUND_COLOR); // color was 52
+  for (int i=0; i<12; i++) {
+    if (i==6) rect(-0.5, 9, 1, 2);
+    else if (i==3 || i==0 || i== 9) rect(-0.5, 9.5, 1, 1);
+    else rect(-0.25, 9.5, .5, 1);
+    fl_rotate(-30);
+  }
+  fl_pop_matrix();
+  // draw the hands:
+  drawhands(selection_color(), FL_FOREGROUND_COLOR); // color was 54
+  fl_pop_matrix();
+}
+
+void Fl_Clock_Output::draw() {
+  draw(x(), y(), w(), h());
+  draw_label();
+}
+
+void Fl_Clock_Output::value(int H, int m, int s) {
+  if (H!=hour_ || m!=minute_ || s!=second_) {
+    hour_ = H; minute_ = m; second_ = s;
+    value_ = (H * 60 + m) * 60 + s;
+    damage(FL_DAMAGE_CHILD);
+  }
+}
+
+void Fl_Clock_Output::value(ulong v) {
+  value_ = v;
+  struct tm *timeofday;
+  // Some platforms, notably Windows, now use a 64-bit time_t value...
+  time_t vv = (time_t)v;
+  timeofday = localtime(&vv);
+  value(timeofday->tm_hour, timeofday->tm_min, timeofday->tm_sec);
+}
+
+Fl_Clock_Output::Fl_Clock_Output(int X, int Y, int W, int H, const char *l)
+: Fl_Widget(X, Y, W, H, l) {
+  box(FL_UP_BOX);
+  selection_color(fl_gray_ramp(5));
+  align(FL_ALIGN_BOTTOM);
+  hour_ = 0;
+  minute_ = 0;
+  second_ = 0;
+  value_ = 0;
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Clock::Fl_Clock(int X, int Y, int W, int H, const char *l)
+  : Fl_Clock_Output(X, Y, W, H, l) {}
+
+Fl_Clock::Fl_Clock(uchar t, int X, int Y, int W, int H, const char *l)
+  : Fl_Clock_Output(X, Y, W, H, l) {
+  type(t);
+  box(t==FL_ROUND_CLOCK ? FL_NO_BOX : FL_UP_BOX);
+}
+
+static void tick(void *v) {
+  ((Fl_Clock*)v)->value(time(0));
+  Fl::add_timeout(1.0, tick, v);
+}
+
+int Fl_Clock::handle(int event) {
+  switch (event) {
+  case FL_SHOW:
+    tick(this);
+    break;
+  case FL_HIDE:
+    Fl::remove_timeout(tick, this);
+    break;
+  }
+  return Fl_Clock_Output::handle(event);
+}
+  
+Fl_Clock::~Fl_Clock() {
+  Fl::remove_timeout(tick, this);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Color_Chooser.cxx b/Utilities/FLTK/src/Fl_Color_Chooser.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d97b2b577f8377ae58df02f3938631b8b489b0b7
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Color_Chooser.cxx
@@ -0,0 +1,529 @@
+//
+// "$Id$"
+//
+// Color chooser for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Color_Chooser.H>
+#include <FL/fl_draw.H>
+#include <FL/math.h>
+#include <stdio.h>
+
+// Besides being a useful object on it's own, the Fl_Color_Chooser was
+// an attempt to make a complex composite object that could be easily
+// imbedded into a user interface.  If you wish to make complex objects
+// of your own, be sure to read this code.
+
+// The function fl_color_chooser() creates a window containing a color
+// chooser and a few buttons and current-color indicators.  It is an
+// easier interface for simple programs that just need a color.
+
+// The "hue box" can be a circle or rectilinear.
+// You get a circle by defining this:
+#define CIRCLE 1
+// And the "hue box" can auto-update when the value changes
+// you get this by defining this:
+#define UPDATE_HUE_BOX 1
+
+void Fl_Color_Chooser::hsv2rgb(
+	double H, double S, double V, double& R, double& G, double& B) {
+  if (S < 5.0e-6) {
+    R = G = B = V;
+  } else {
+    int i = (int)H;  
+    double f = H - (float)i;
+    double p1 = V*(1.0-S);
+    double p2 = V*(1.0-S*f);
+    double p3 = V*(1.0-S*(1.0-f));
+    switch (i) {
+    case 0: R = V;   G = p3;  B = p1;  break;
+    case 1: R = p2;  G = V;   B = p1;  break;
+    case 2: R = p1;  G = V;   B = p3;  break;
+    case 3: R = p1;  G = p2;  B = V;   break;
+    case 4: R = p3;  G = p1;  B = V;   break;
+    case 5: R = V;   G = p1;  B = p2;  break;
+    }
+  }
+}
+
+void Fl_Color_Chooser::rgb2hsv(
+	double R, double G, double B, double& H, double& S, double& V) {
+  double maxv = R > G ? R : G; if (B > maxv) maxv = B;
+  V = maxv;
+  if (maxv>0) {
+    double minv = R < G ? R : G; if (B < minv) minv = B;
+    S = 1.0 - double(minv)/maxv;
+    if (maxv > minv) {
+      if (maxv == R) {H = (G-B)/double(maxv-minv); if (H<0) H += 6.0;}
+      else if (maxv == G) H = 2.0+(B-R)/double(maxv-minv);
+      else H = 4.0+(R-G)/double(maxv-minv);
+    }
+  }
+}
+
+enum {M_RGB, M_BYTE, M_HEX, M_HSV}; // modes
+static Fl_Menu_Item mode_menu[] = {
+  {"rgb"},
+  {"byte"},
+  {"hex"},
+  {"hsv"},
+  {0}
+};
+
+int Flcc_Value_Input::format(char* buf) {
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+  if (c->mode() == M_HEX) return sprintf(buf,"0x%02X", int(value()));
+  else return Fl_Valuator::format(buf);
+}
+
+void Fl_Color_Chooser::set_valuators() {
+  switch (mode()) {
+  case M_RGB:
+    rvalue.range(0,1); rvalue.step(1,1000); rvalue.value(r_);
+    gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_);
+    bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_);
+    break;
+  case M_BYTE:
+  case M_HEX:
+    rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5));
+    gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5));
+    bvalue.range(0,255); bvalue.step(1); bvalue.value(int(255*b_+.5));
+    break;
+  case M_HSV:
+    rvalue.range(0,6); rvalue.step(1,1000); rvalue.value(hue_);
+    gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(saturation_);
+    bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(value_);
+    break;
+  }
+}
+
+int Fl_Color_Chooser::rgb(double R, double G, double B) {
+  if (R == r_ && G == g_ && B == b_) return 0;
+  r_ = R; g_ = G; b_ = B;
+  double ph = hue_;
+  double ps = saturation_;
+  double pv = value_;
+  rgb2hsv(R,G,B,hue_,saturation_,value_);
+  set_valuators();
+  set_changed();
+  if (value_ != pv) {
+#ifdef UPDATE_HUE_BOX
+    huebox.damage(FL_DAMAGE_SCROLL);
+#endif
+    valuebox.damage(FL_DAMAGE_EXPOSE);}
+  if (hue_ != ph || saturation_ != ps) {
+    huebox.damage(FL_DAMAGE_EXPOSE); 
+    valuebox.damage(FL_DAMAGE_SCROLL);
+  }
+  return 1;
+}
+
+int Fl_Color_Chooser::hsv(double H, double S, double V) {
+  H = fmod(H,6.0); if (H < 0.0) H += 6.0;
+  if (S < 0.0) S = 0.0; else if (S > 1.0) S = 1.0;
+  if (V < 0.0) V = 0.0; else if (V > 1.0) V = 1.0;
+  if (H == hue_ && S == saturation_ && V == value_) return 0;
+  double ph = hue_;
+  double ps = saturation_;
+  double pv = value_;
+  hue_ = H; saturation_ = S; value_ = V;
+  if (value_ != pv) {
+#ifdef UPDATE_HUE_BOX
+    huebox.damage(FL_DAMAGE_SCROLL);
+#endif
+    valuebox.damage(FL_DAMAGE_EXPOSE);}
+  if (hue_ != ph || saturation_ != ps) {
+    huebox.damage(FL_DAMAGE_EXPOSE); 
+    valuebox.damage(FL_DAMAGE_SCROLL);
+  }
+  hsv2rgb(H,S,V,r_,g_,b_);
+  set_valuators();
+  set_changed();
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+static void tohs(double x, double y, double& h, double& s) {
+#ifdef CIRCLE
+  x = 2*x-1;
+  y = 1-2*y;
+  s = sqrt(x*x+y*y); if (s > 1.0) s = 1.0;
+  h = (3.0/M_PI)*atan2(y,x);
+  if (h<0) h += 6.0;
+#else
+  h = fmod(6.0*x,6.0); if (h < 0.0) h += 6.0;
+  s = 1.0-y; if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0;
+#endif
+}
+
+int Flcc_HueBox::handle(int e) {
+  static double ih, is;
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+  switch (e) {
+  case FL_PUSH:
+    if (Fl::visible_focus()) {
+      Fl::focus(this);
+      redraw();
+    }
+    ih = c->hue();
+    is = c->saturation();
+  case FL_DRAG: {
+    double Xf, Yf, H, S;
+    Xf = (Fl::event_x()-x()-Fl::box_dx(box()))/double(w()-Fl::box_dw(box()));
+    Yf = (Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
+    tohs(Xf, Yf, H, S);
+    if (fabs(H-ih) < 3*6.0/w()) H = ih;
+    if (fabs(S-is) < 3*1.0/h()) S = is;
+    if (Fl::event_state(FL_CTRL)) H = ih;
+    if (c->hsv(H, S, c->value())) c->do_callback();
+    } return 1;
+  case FL_FOCUS :
+  case FL_UNFOCUS :
+    if (Fl::visible_focus()) {
+      redraw();
+      return 1;
+    }
+    else return 1;
+  case FL_KEYBOARD :
+    return handle_key(Fl::event_key());
+  default:
+    return 0;
+  }
+}
+
+static void generate_image(void* vv, int X, int Y, int W, uchar* buf) {
+  Flcc_HueBox* v = (Flcc_HueBox*)vv;
+  int iw = v->w()-Fl::box_dw(v->box());
+  double Yf = double(Y)/(v->h()-Fl::box_dh(v->box()));
+#ifdef UPDATE_HUE_BOX
+  const double V = ((Fl_Color_Chooser*)(v->parent()))->value();
+#else
+  const double V = 1.0;
+#endif
+  for (int x = X; x < X+W; x++) {
+    double Xf = double(x)/iw;
+    double H,S; tohs(Xf,Yf,H,S);
+    double r,g,b;
+    Fl_Color_Chooser::hsv2rgb(H,S,V,r,g,b);
+    *buf++ = uchar(255*r+.5);
+    *buf++ = uchar(255*g+.5);
+    *buf++ = uchar(255*b+.5);
+  }
+}
+
+int Flcc_HueBox::handle_key(int key) {
+  int w1 = w()-Fl::box_dw(box())-6;
+  int h1 = h()-Fl::box_dh(box())-6;
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+
+#ifdef CIRCLE
+  int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * w1);
+  int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * h1);
+#else
+  int X = int(c->hue()/6.0*w1);
+  int Y = int((1-c->saturation())*h1);
+#endif
+
+  switch (key) {
+    case FL_Up :
+      Y -= 3;
+      break;
+    case FL_Down :
+      Y += 3;
+      break;
+    case FL_Left :
+      X -= 3;
+      break;
+    case FL_Right :
+      X += 3;
+      break;
+    default :
+      return 0;
+  }
+
+  double Xf, Yf, H, S;
+  Xf = (double)X/(double)w1;
+  Yf = (double)Y/(double)h1;
+  tohs(Xf, Yf, H, S);
+  if (c->hsv(H, S, c->value())) c->do_callback();
+
+  return 1;
+}
+
+void Flcc_HueBox::draw() {
+  if (damage()&FL_DAMAGE_ALL) draw_box();
+  int x1 = x()+Fl::box_dx(box());
+  int yy1 = y()+Fl::box_dy(box());
+  int w1 = w()-Fl::box_dw(box());
+  int h1 = h()-Fl::box_dh(box());
+  if (damage() == FL_DAMAGE_EXPOSE) fl_clip(x1+px,yy1+py,6,6);
+  fl_draw_image(generate_image, this, x1, yy1, w1, h1);
+  if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip();
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+#ifdef CIRCLE
+  int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * (w1-6));
+  int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * (h1-6));
+#else
+  int X = int(c->hue()/6.0*(w1-6));
+  int Y = int((1-c->saturation())*(h1-6));
+#endif
+  if (X < 0) X = 0; else if (X > w1-6) X = w1-6;
+  if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
+  //  fl_color(c->value()>.75 ? FL_BLACK : FL_WHITE);
+  draw_box(FL_UP_BOX,x1+X,yy1+Y,6,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY);
+  px = X; py = Y;
+}
+
+////////////////////////////////////////////////////////////////
+
+int Flcc_ValueBox::handle(int e) {
+  static double iv;
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+  switch (e) {
+  case FL_PUSH:
+    if (Fl::visible_focus()) {
+      Fl::focus(this);
+      redraw();
+    }
+    iv = c->value();
+  case FL_DRAG: {
+    double Yf;
+    Yf = 1-(Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
+    if (fabs(Yf-iv)<(3*1.0/h())) Yf = iv;
+    if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback();
+    } return 1;
+  case FL_FOCUS :
+  case FL_UNFOCUS :
+    if (Fl::visible_focus()) {
+      redraw();
+      return 1;
+    }
+    else return 1;
+  case FL_KEYBOARD :
+    return handle_key(Fl::event_key());
+  default:
+    return 0;
+  }
+}
+
+static double tr, tg, tb;
+static void generate_vimage(void* vv, int X, int Y, int W, uchar* buf) {
+  Flcc_ValueBox* v = (Flcc_ValueBox*)vv;
+  double Yf = 255*(1.0-double(Y)/(v->h()-Fl::box_dh(v->box())));
+  uchar r = uchar(tr*Yf+.5);
+  uchar g = uchar(tg*Yf+.5);
+  uchar b = uchar(tb*Yf+.5);
+  for (int x = X; x < X+W; x++) {
+    *buf++ = r; *buf++ = g; *buf++ = b;
+  }
+}
+
+void Flcc_ValueBox::draw() {
+  if (damage()&FL_DAMAGE_ALL) draw_box();
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+  c->hsv2rgb(c->hue(),c->saturation(),1.0,tr,tg,tb);
+  int x1 = x()+Fl::box_dx(box());
+  int yy1 = y()+Fl::box_dy(box());
+  int w1 = w()-Fl::box_dw(box());
+  int h1 = h()-Fl::box_dh(box());
+  if (damage() == FL_DAMAGE_EXPOSE) fl_clip(x1,yy1+py,w1,6);
+  fl_draw_image(generate_vimage, this, x1, yy1, w1, h1);
+  if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip();
+  int Y = int((1-c->value()) * (h1-6));
+  if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
+  draw_box(FL_UP_BOX,x1,yy1+Y,w1,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY);
+  py = Y;
+}
+
+int Flcc_ValueBox::handle_key(int key) {
+  int h1 = h()-Fl::box_dh(box())-6;
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+
+  int Y = int((1-c->value()) * h1);
+  if (Y < 0) Y = 0; else if (Y > h1) Y = h1;
+
+  switch (key) {
+    case FL_Up :
+      Y -= 3;
+      break;
+    case FL_Down :
+      Y += 3;
+      break;
+    default :
+      return 0;
+  }
+
+  double Yf;
+  Yf = 1-((double)Y/(double)h1);
+  if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback();
+
+  return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Color_Chooser::rgb_cb(Fl_Widget* o, void*) {
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
+  double R = c->rvalue.value();
+  double G = c->gvalue.value();
+  double B = c->bvalue.value();
+  if (c->mode() == M_HSV) {
+    if (c->hsv(R,G,B)) c->do_callback();
+    return;
+  }
+  if (c->mode() != M_RGB) {
+    R = R/255;
+    G = G/255;
+    B = B/255;
+  }
+  if (c->rgb(R,G,B)) c->do_callback();
+}
+
+void Fl_Color_Chooser::mode_cb(Fl_Widget* o, void*) {
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
+  // force them to redraw even if value is the same:
+  c->rvalue.value(-1);
+  c->gvalue.value(-1);
+  c->bvalue.value(-1);
+  c->set_valuators();
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Color_Chooser::Fl_Color_Chooser(int X, int Y, int W, int H, const char* L)
+  : Fl_Group(0,0,195,115,L),
+    huebox(0,0,115,115),
+    valuebox(115,0,20,115),
+    choice(140,0,55,25),
+    rvalue(140,30,55,25),
+    gvalue(140,60,55,25),
+    bvalue(140,90,55,25),
+    resize_box(0,0,115,115)
+{
+  end();
+  resizable(resize_box);
+  resize(X,Y,W,H);
+  r_ = g_ = b_ = 0;
+  hue_ = 0.0;
+  saturation_ = 0.0;
+  value_ = 0.0;
+  huebox.box(FL_DOWN_FRAME);
+  valuebox.box(FL_DOWN_FRAME);
+  choice.menu(mode_menu);
+  set_valuators();
+  rvalue.callback(rgb_cb);
+  gvalue.callback(rgb_cb);
+  bvalue.callback(rgb_cb);
+  choice.callback(mode_cb);
+  choice.box(FL_THIN_UP_BOX);
+  choice.textfont(FL_HELVETICA_BOLD_ITALIC);
+}
+
+////////////////////////////////////////////////////////////////
+// fl_color_chooser():
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Return_Button.H>
+
+class ColorChip : public Fl_Widget {
+  void draw();
+public:
+  uchar r,g,b;
+  ColorChip(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
+    box(FL_ENGRAVED_FRAME);}
+};
+
+void ColorChip::draw() {
+  if (damage()&FL_DAMAGE_ALL) draw_box();
+  fl_rectf(x()+Fl::box_dx(box()),
+	   y()+Fl::box_dy(box()),
+	   w()-Fl::box_dw(box()),
+	   h()-Fl::box_dh(box()),r,g,b);
+}
+
+static void chooser_cb(Fl_Object* o, void* vv) {
+  Fl_Color_Chooser* c = (Fl_Color_Chooser*)o;
+  ColorChip* v = (ColorChip*)vv;
+  v->r = uchar(255*c->r()+.5);
+  v->g = uchar(255*c->g()+.5);
+  v->b = uchar(255*c->b()+.5);
+  v->damage(FL_DAMAGE_EXPOSE);
+}
+
+extern const char* fl_ok;
+extern const char* fl_cancel;
+
+int fl_color_chooser(const char* name, double& r, double& g, double& b) {
+  Fl_Window window(215,200,name);
+  Fl_Color_Chooser chooser(10, 10, 195, 115);
+  ColorChip ok_color(10, 130, 95, 25);
+  Fl_Return_Button ok_button(10, 165, 95, 25, fl_ok);
+  ColorChip cancel_color(110, 130, 95, 25);
+  cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r;
+  ok_color.g = cancel_color.g = uchar(255*g+.5);
+  ok_color.b = cancel_color.b = uchar(255*b+.5);
+  Fl_Button cancel_button(110, 165, 95, 25, fl_cancel);
+  window.resizable(chooser);
+  chooser.rgb(r,g,b);
+  chooser.callback(chooser_cb, &ok_color);
+  window.end();
+  window.set_modal();
+  window.hotspot(window);
+  window.show();
+  while (window.shown()) {
+    Fl::wait();
+    for (;;) {
+      Fl_Widget* o = Fl::readqueue();
+      if (!o) break;
+      if (o == &ok_button) {
+	r = chooser.r();
+	g = chooser.g();
+	b = chooser.b();
+	return 1;
+      }
+      if (o == &window || o == &cancel_button) return 0;
+    }
+  }
+  return 0;
+}
+
+int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b) {
+  double dr = r/255.0;
+  double dg = g/255.0;
+  double db = b/255.0;
+  if (fl_color_chooser(name,dr,dg,db)) {
+    r = uchar(255*dr+.5);
+    g = uchar(255*dg+.5);
+    b = uchar(255*db+.5);
+    return 1;
+  }
+  return 0;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Counter.cxx b/Utilities/FLTK/src/Fl_Counter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..875171541a9e38182f4e43b55fae481a33b85286
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Counter.cxx
@@ -0,0 +1,197 @@
+//
+// "$Id$"
+//
+// Counter widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Counter.H>
+#include <FL/fl_draw.H>
+
+void Fl_Counter::draw() {
+  int i; Fl_Boxtype boxtype[5];
+  Fl_Color selcolor;
+
+  boxtype[0] = box();
+  if (boxtype[0] == FL_UP_BOX) boxtype[0] = FL_DOWN_BOX;
+  if (boxtype[0] == FL_THIN_UP_BOX) boxtype[0] = FL_THIN_DOWN_BOX;
+  for (i=1; i<5; i++)
+    if (mouseobj == i)
+      boxtype[i] = fl_down(box());
+    else
+      boxtype[i] = box();
+
+  int xx[5], ww[5];
+  if (type() == FL_NORMAL_COUNTER) {
+    int W = w()*15/100;
+    xx[1] = x();	 ww[1] = W;
+    xx[2] = x()+1*W;     ww[2] = W;
+    xx[0] = x()+2*W;     ww[0] = w()-4*W;
+    xx[3] = x()+w()-2*W; ww[3] = W;
+    xx[4] = x()+w()-1*W; ww[4] = W;
+  } else {
+    int W = w()*20/100;
+    xx[1] = 0;	         ww[1] = 0;
+    xx[2] = x();	 ww[2] = W;
+    xx[0] = x()+W;	 ww[0] = w()-2*W;
+    xx[3] = x()+w()-1*W; ww[3] = W;
+    xx[4] = 0;	         ww[4] = 0;
+  }
+
+  draw_box(boxtype[0], xx[0], y(), ww[0], h(), FL_BACKGROUND2_COLOR);
+  fl_font(textfont(), textsize());
+  fl_color(active_r() ? textcolor() : fl_inactive(textcolor()));
+  char str[128]; format(str);
+  fl_draw(str, xx[0], y(), ww[0], h(), FL_ALIGN_CENTER);
+  if (Fl::focus() == this) draw_focus(boxtype[0], xx[0], y(), ww[0], h());
+  if (!(damage()&FL_DAMAGE_ALL)) return; // only need to redraw text
+
+  if (active_r())
+    selcolor = labelcolor();
+  else
+    selcolor = fl_inactive(labelcolor());
+
+  if (type() == FL_NORMAL_COUNTER) {
+    draw_box(boxtype[1], xx[1], y(), ww[1], h(), color());
+    fl_draw_symbol("@-4<<", xx[1], y(), ww[1], h(), selcolor);
+  }
+  draw_box(boxtype[2], xx[2], y(), ww[2], h(), color());
+  fl_draw_symbol("@-4<",  xx[2], y(), ww[2], h(), selcolor);
+  draw_box(boxtype[3], xx[3], y(), ww[3], h(), color());
+  fl_draw_symbol("@-4>",  xx[3], y(), ww[3], h(), selcolor);
+  if (type() == FL_NORMAL_COUNTER) {
+    draw_box(boxtype[4], xx[4], y(), ww[4], h(), color());
+    fl_draw_symbol("@-4>>", xx[4], y(), ww[4], h(), selcolor);
+  }
+}
+
+void Fl_Counter::increment_cb() {
+  if (!mouseobj) return;
+  double v = value();
+  switch (mouseobj) {
+  case 1: v -= lstep_; break;
+  case 2: v = increment(v, -1); break;
+  case 3: v = increment(v, 1); break;
+  case 4: v += lstep_; break;
+  }
+  handle_drag(clamp(round(v)));
+}
+
+#define INITIALREPEAT .5
+#define REPEAT .1
+
+void Fl_Counter::repeat_callback(void* v) {
+  Fl_Counter* b = (Fl_Counter*)v;
+  if (b->mouseobj) {
+    Fl::add_timeout(REPEAT, repeat_callback, b);
+    b->increment_cb();
+  }
+}
+
+int Fl_Counter::calc_mouseobj() {
+  if (type() == FL_NORMAL_COUNTER) {
+    int W = w()*15/100;
+    if (Fl::event_inside(x(), y(), W, h())) return 1;
+    if (Fl::event_inside(x()+W, y(), W, h())) return 2;
+    if (Fl::event_inside(x()+w()-2*W, y(), W, h())) return 3;
+    if (Fl::event_inside(x()+w()-W, y(), W, h())) return 4;
+  } else {
+    int W = w()*20/100;
+    if (Fl::event_inside(x(), y(), W, h())) return 2;
+    if (Fl::event_inside(x()+w()-W, y(), W, h())) return 3;
+  }
+  return -1;
+}
+
+int Fl_Counter::handle(int event) {
+  int i;
+  switch (event) {
+  case FL_RELEASE:
+    if (mouseobj) {
+      Fl::remove_timeout(repeat_callback, this);
+      mouseobj = 0;
+      redraw();
+    }
+    handle_release();
+    return 1;
+  case FL_PUSH:
+    if (Fl::visible_focus()) Fl::focus(this);
+    handle_push();
+  case FL_DRAG:
+    i = calc_mouseobj();
+    if (i != mouseobj) {
+      Fl::remove_timeout(repeat_callback, this);
+      mouseobj = (uchar)i;
+      if (i) Fl::add_timeout(INITIALREPEAT, repeat_callback, this);
+      increment_cb();
+      redraw();
+    }
+    return 1;
+  case FL_KEYBOARD :
+    switch (Fl::event_key()) {
+      case FL_Left:
+	handle_drag(clamp(increment(value(),-1)));
+	return 1;
+      case FL_Right:
+	handle_drag(clamp(increment(value(),1)));
+	return 1;
+      default:
+        return 0;
+    }
+    // break not required because of switch...
+  case FL_FOCUS :
+  case FL_UNFOCUS :
+    if (Fl::visible_focus()) {
+      redraw();
+      return 1;
+    } else return 0;
+  case FL_ENTER :
+  case FL_LEAVE :
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+Fl_Counter::~Fl_Counter() {
+  Fl::remove_timeout(repeat_callback, this);
+}
+
+Fl_Counter::Fl_Counter(int X, int Y, int W, int H, const char* l)
+  : Fl_Valuator(X, Y, W, H, l) {
+  box(FL_UP_BOX);
+  selection_color(FL_INACTIVE_COLOR); // was FL_BLUE
+  align(FL_ALIGN_BOTTOM);
+  bounds(-1000000.0, 1000000.0);
+  Fl_Valuator::step(1, 10);
+  lstep_ = 1.0;
+  mouseobj = 0;
+  textfont_ = FL_HELVETICA;
+  textsize_ = (uchar)FL_NORMAL_SIZE;
+  textcolor_ = FL_FOREGROUND_COLOR;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Dial.cxx b/Utilities/FLTK/src/Fl_Dial.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..de77cb26825d326548314f3a6f8f41704848a7cf
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Dial.cxx
@@ -0,0 +1,140 @@
+//
+// "$Id$"
+//
+// Circular dial widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Dial.H>
+#include <FL/fl_draw.H>
+#include <stdlib.h>
+#include <FL/math.h>
+
+// All angles are measured with 0 to the right and counter-clockwise
+
+void Fl_Dial::draw(int X, int Y, int W, int H) {
+  if (damage()&FL_DAMAGE_ALL) draw_box(box(), X, Y, W, H, color());
+  X += Fl::box_dx(box());
+  Y += Fl::box_dy(box());
+  W -= Fl::box_dw(box());
+  H -= Fl::box_dh(box());
+  double angle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
+  if (type() == FL_FILL_DIAL) {
+    // foo: draw this nicely in certain round box types
+    int foo = (box() > _FL_ROUND_UP_BOX && Fl::box_dx(box()));
+    if (foo) {X--; Y--; W+=2; H+=2;}
+    fl_color(color());
+    fl_pie(X, Y, W, H, 270-a1, angle > a1 ? 360+270-angle : 270-360-angle);
+    fl_color(selection_color());
+    fl_pie(X, Y, W, H, 270-angle, 270-a1);
+    if (foo) {
+      fl_color(FL_FOREGROUND_COLOR);
+      fl_arc(X, Y, W, H, 0, 360);
+    }
+    return;
+  }
+  if (!(damage()&FL_DAMAGE_ALL)) {
+    fl_color(color());
+    fl_pie(X+1, Y+1, W-2, H-2, 0, 360);
+  }
+  fl_push_matrix();
+  fl_translate(X+W/2-.5, Y+H/2-.5);
+  fl_scale(W-1, H-1);
+  fl_rotate(45-angle);
+  fl_color(selection_color());
+  if (type()) { // FL_LINE_DIAL
+    fl_begin_polygon();
+    fl_vertex(0.0,   0.0);
+    fl_vertex(-0.04, 0.0);
+    fl_vertex(-0.25, 0.25);
+    fl_vertex(0.0,   0.04);
+    fl_end_polygon();
+    fl_color(FL_FOREGROUND_COLOR);
+    fl_begin_loop();
+    fl_vertex(0.0,   0.0);
+    fl_vertex(-0.04, 0.0);
+    fl_vertex(-0.25, 0.25);
+    fl_vertex(0.0,   0.04);
+    fl_end_loop();
+  } else {
+    fl_begin_polygon(); fl_circle(-0.20, 0.20, 0.07); fl_end_polygon();
+    fl_color(FL_FOREGROUND_COLOR);
+    fl_begin_loop(); fl_circle(-0.20, 0.20, 0.07); fl_end_loop();
+  }
+  fl_pop_matrix();
+}
+
+void Fl_Dial::draw() {
+  draw(x(), y(), w(), h());
+  draw_label();
+}
+
+int Fl_Dial::handle(int event, int X, int Y, int W, int H) {
+  switch (event) {
+  case FL_PUSH:
+    handle_push();
+  case FL_DRAG: {
+    int mx = (Fl::event_x()-X-W/2)*H;
+    int my = (Fl::event_y()-Y-H/2)*W;
+    if (!mx && !my) return 1;
+    double angle = 270-atan2((float)-my, (float)mx)*180/M_PI;
+    double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
+    while (angle < oldangle-180) angle += 360;
+    while (angle > oldangle+180) angle -= 360;
+    double val;
+    if ((a1<a2) ? (angle <= a1) : (angle >= a1)) {
+      val = minimum();
+    } else if ((a1<a2) ? (angle >= a2) : (angle <= a2)) {
+      val = maximum();
+    } else {
+      val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1);
+    }
+    handle_drag(clamp(round(val)));
+  } return 1;
+  case FL_RELEASE:
+    handle_release();
+    return 1;
+  case FL_ENTER :
+  case FL_LEAVE :
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+int Fl_Dial::handle(int e) {
+  return handle(e, x(), y(), w(), h());
+}
+
+Fl_Dial::Fl_Dial(int X, int Y, int W, int H, const char* l)
+  : Fl_Valuator(X, Y, W, H, l) {
+  box(FL_OVAL_BOX);
+  selection_color(FL_INACTIVE_COLOR); // was 37
+  a1 = 45;
+  a2 = 315;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Double_Window.cxx b/Utilities/FLTK/src/Fl_Double_Window.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fdeffe99de4f635aac9b901a93cae2a97e01868b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Double_Window.cxx
@@ -0,0 +1,368 @@
+//
+// "$Id$"
+//
+// Double-buffered window code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/Fl_Double_Window.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+// On systems that support double buffering "naturally" the base
+// Fl_Window class will probably do double-buffer and this subclass
+// does nothing.
+
+#if USE_XDBE
+
+#include <X11/extensions/Xdbe.h>
+
+static int use_xdbe;
+
+static int can_xdbe() {
+  static int tried;
+  if (!tried) {
+    tried = 1;
+    int event_base, error_base;
+    if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
+    Drawable root = RootWindow(fl_display,fl_screen);
+    int numscreens = 1;
+    XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens);
+    if (!a) return 0;
+    for (int j = 0; j < a->count; j++)
+      if (a->visinfo[j].visual == fl_visual->visualid
+	  /*&& a->visinfo[j].perflevel > 0*/) {use_xdbe = 1; break;}
+    XdbeFreeVisualInfo(a);
+  }
+  return use_xdbe;
+}
+#endif
+
+void Fl_Double_Window::show() {
+#if !defined(WIN32) && !defined(__APPLE__)
+  if (!shown()) { // don't set the background pixel
+    fl_open_display();
+    Fl_X::make_xid(this);
+    return;
+  }
+#endif
+  Fl_Window::show();
+}
+
+#ifdef WIN32
+
+// Code used to switch output to an off-screen window.  See macros in
+// win32.H which save the old state in local variables.
+
+HDC fl_makeDC(HBITMAP bitmap) {
+  HDC new_gc = CreateCompatibleDC(fl_gc);
+  SetTextAlign(new_gc, TA_BASELINE|TA_LEFT);
+  SetBkMode(new_gc, TRANSPARENT);
+#if USE_COLORMAP
+  if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE);
+#endif
+  SelectObject(new_gc, bitmap);
+  return new_gc;
+}
+
+void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
+  HDC new_gc = CreateCompatibleDC(fl_gc);
+  int save = SaveDC(new_gc);
+  SelectObject(new_gc, bitmap);
+  BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
+  RestoreDC(new_gc, save);
+  DeleteDC(new_gc);
+}
+
+extern void fl_restore_clip();
+
+#elif defined(__APPLE_QD__)
+
+GWorldPtr fl_create_offscreen(int w, int h) {
+  GWorldPtr gw;
+  Rect bounds;
+  bounds.left=0; bounds.right=w; bounds.top=0; bounds.bottom=h;
+  QDErr err = NewGWorld(&gw, 0, &bounds, 0L, 0L, 0); // 'useTempMem' should not be used (says the Carbon port manual)
+  if ( err == -108 )
+    { }
+//    fl_message( "The application memory is low. Please increase the initial memory assignment.\n" ); 
+  if (err!=noErr || gw==0L) return 0L;
+  return gw;
+}
+
+void fl_copy_offscreen(int x,int y,int w,int h,GWorldPtr gWorld,int srcx,int srcy) {
+  Rect src;
+  if ( !gWorld ) return;
+  src.top = srcy; src.left = srcx; src.bottom = srcy+h; src.right = srcx+w;
+  Rect dst;
+  GrafPtr dstPort; GetPort(&dstPort);
+  dst.top = y; dst.left = x; dst.bottom = y+h; dst.right = x+w;
+  RGBColor rgb, oldbg, oldfg;
+  GetForeColor(&oldfg);
+  GetBackColor(&oldbg);
+  rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff;
+  RGBBackColor( &rgb );
+  rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000;
+  RGBForeColor( &rgb );
+  CopyBits(GetPortBitMapForCopyBits(gWorld), GetPortBitMapForCopyBits(dstPort), &src, &dst, srcCopy, 0L);
+  RGBBackColor(&oldbg);
+  RGBForeColor(&oldfg);
+}
+
+void fl_delete_offscreen(GWorldPtr gWorld) {
+  DisposeGWorld(gWorld);
+}
+
+static GrafPtr prevPort;
+static GDHandle prevGD;
+
+void fl_begin_offscreen(GWorldPtr gWorld) {
+  GetGWorld( &prevPort, &prevGD );
+  if ( gWorld )
+  {
+    SetGWorld( gWorld, 0 ); // sets the correct port
+    PixMapHandle pm = GetGWorldPixMap(gWorld);
+    Boolean ret = LockPixels(pm);
+    if ( ret == false )
+    {
+      Rect rect;
+      GetPortBounds( gWorld, &rect );
+      UpdateGWorld( &gWorld, 0, &rect, 0, 0, 0 );
+      pm = GetGWorldPixMap( gWorld );
+      LockPixels( pm );
+    }
+    fl_window = 0;
+  }
+  fl_push_no_clip();
+}
+
+void fl_end_offscreen() {
+  GWorldPtr currPort;
+  GDHandle currGD;
+  GetGWorld( &currPort, &currGD );
+  fl_pop_clip();
+  PixMapHandle pm = GetGWorldPixMap(currPort);
+  UnlockPixels(pm);
+  SetGWorld( prevPort, prevGD );
+  fl_window = GetWindowFromPort( prevPort );
+}
+
+extern void fl_restore_clip();
+
+#elif defined(__APPLE_QUARTZ__)
+
+Fl_Offscreen fl_create_offscreen(int w, int h) {
+  void *data = calloc(w*h,4);
+  CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+  CGContextRef ctx = CGBitmapContextCreate(
+    data, w, h, 8, w*4, lut, kCGImageAlphaNoneSkipLast);
+  CGColorSpaceRelease(lut);
+  return (Fl_Offscreen)ctx;
+}
+
+Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h) {
+  void *data = calloc(w*h,4);
+  CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+  CGContextRef ctx = CGBitmapContextCreate(
+    data, w, h, 8, w*4, lut, kCGImageAlphaPremultipliedLast);
+  CGColorSpaceRelease(lut);
+  return (Fl_Offscreen)ctx;
+}
+
+void fl_copy_offscreen(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) {
+  CGContextRef src = (CGContextRef)osrc;
+  void *data = CGBitmapContextGetData(src);
+  int sw = CGBitmapContextGetWidth(src);
+  int sh = CGBitmapContextGetHeight(src);
+  CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(src);
+  CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+  CGDataProviderRef src_bytes = CGDataProviderCreateWithData( 0L, data, sw*sh*4, 0L);
+  CGImageRef img = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, alpha,
+    src_bytes, 0L, false, kCGRenderingIntentDefault);
+  // fl_push_clip();
+  CGRect rect = { x, y, w, h };
+  Fl_X::q_begin_image(rect, srcx, srcy, sw, sh);
+  CGContextDrawImage(fl_gc, rect, img);
+  Fl_X::q_end_image();
+  CGImageRelease(img);
+  CGColorSpaceRelease(lut);
+  CGDataProviderRelease(src_bytes);
+}
+
+void fl_delete_offscreen(Fl_Offscreen ctx) {
+  if (!ctx) return;
+  void *data = CGBitmapContextGetData((CGContextRef)ctx);
+  CGContextRelease((CGContextRef)ctx);
+  if (!data) return;
+  free(data);
+}
+
+static CGContextRef prev_gc = 0;
+static Window prev_window = 0;
+
+void fl_begin_offscreen(Fl_Offscreen ctx) {
+  prev_gc = fl_gc;
+  prev_window = fl_window;
+  fl_gc = (CGContextRef)ctx;
+  fl_window = 0;
+  //fl_push_no_clip();
+  CGContextSaveGState(fl_gc);
+  Fl_X::q_fill_context();
+}
+
+void fl_end_offscreen() {
+  Fl_X::q_release_context();
+  //fl_pop_clip();
+  fl_gc = prev_gc;
+  fl_window = prev_window;
+}
+
+extern void fl_restore_clip();
+
+#endif
+
+// Fl_Overlay_Window relies on flush(1) copying the back buffer to the
+// front everywhere, even if damage() == 0, thus erasing the overlay,
+// and leaving the clip region set to the entire window.
+
+void Fl_Double_Window::flush() {flush(0);}
+
+void Fl_Double_Window::flush(int eraseoverlay) {
+  make_current(); // make sure fl_gc is non-zero
+  Fl_X *myi = Fl_X::i(this);
+  if (!myi->other_xid) {
+#if USE_XDBE
+    if (can_xdbe()) myi->other_xid =
+      XdbeAllocateBackBufferName(fl_display, fl_xid(this), XdbeUndefined);
+    else
+#endif
+#ifdef __APPLE_QD__
+    if ( ( !QDIsPortBuffered( GetWindowPort(myi->xid) ) ) 
+        || force_doublebuffering_ ) {
+      myi->other_xid = fl_create_offscreen(w(), h());
+      clear_damage(FL_DAMAGE_ALL);
+    }
+#elif defined(__APPLE_QUARTZ__)
+    if (force_doublebuffering_) {
+      myi->other_xid = fl_create_offscreen(w(), h());
+      clear_damage(FL_DAMAGE_ALL);
+    }
+#else
+    myi->other_xid = fl_create_offscreen(w(), h());
+    clear_damage(FL_DAMAGE_ALL);
+#endif
+  }
+#if USE_XDBE
+  if (use_xdbe) {
+    // if this is true, copy rather than swap so back buffer is preserved:
+    int copy = (myi->region || eraseoverlay);
+    if (myi->backbuffer_bad) { // make sure we do a complete redraw...
+      if (myi->region) {XDestroyRegion(myi->region); myi->region = 0;}
+      clear_damage(FL_DAMAGE_ALL);
+    }
+    if (damage()) {
+      fl_clip_region(myi->region); myi->region = 0;
+      fl_window = myi->other_xid;
+      draw();
+      fl_window = myi->xid;
+    }
+    if (!copy) {
+      XdbeSwapInfo s;
+      s.swap_window = fl_xid(this);
+      s.swap_action = XdbeUndefined;
+      XdbeSwapBuffers(fl_display, &s, 1);
+      myi->backbuffer_bad = 1;
+      return;
+    }
+    // otherwise just use normal copy from back to front:
+    myi->backbuffer_bad = 0; // which won't destroy the back buffer...
+  } else
+#endif
+  if (damage() & ~FL_DAMAGE_EXPOSE) {
+    fl_clip_region(myi->region); myi->region = 0;
+#ifdef WIN32
+    HDC _sgc = fl_gc;
+    fl_gc = fl_makeDC(myi->other_xid);
+    int save = SaveDC(fl_gc);
+    fl_restore_clip(); // duplicate region into new gc
+    draw();
+    RestoreDC(fl_gc, save);
+    DeleteDC(fl_gc);
+    fl_gc = _sgc;
+#elif defined(__APPLE__)
+    if ( myi->other_xid ) {
+      fl_begin_offscreen( myi->other_xid );
+      fl_clip_region( 0 );   
+      draw();
+      fl_end_offscreen();
+    } else {
+      draw();
+    }
+#else // X:
+    fl_window = myi->other_xid;
+    draw();
+    fl_window = myi->xid;
+#endif
+  }
+  if (eraseoverlay) fl_clip_region(0);
+  // on Irix (at least) it is faster to reduce the area copied to
+  // the current clip region:
+  int X,Y,W,H; fl_clip_box(0,0,w(),h(),X,Y,W,H);
+  if (myi->other_xid) fl_copy_offscreen(X, Y, W, H, myi->other_xid, X, Y);
+}
+
+void Fl_Double_Window::resize(int X,int Y,int W,int H) {
+  int ow = w();
+  int oh = h();
+  Fl_Window::resize(X,Y,W,H);
+#if USE_XDBE
+  if (use_xdbe) return;
+#endif
+  Fl_X* myi = Fl_X::i(this);
+  if (myi && myi->other_xid && (ow != w() || oh != h())) {
+    fl_delete_offscreen(myi->other_xid);
+    myi->other_xid = 0;
+  }
+}
+
+void Fl_Double_Window::hide() {
+  Fl_X* myi = Fl_X::i(this);
+  if (myi && myi->other_xid) {
+#if USE_XDBE
+    if (!use_xdbe)
+#endif
+      fl_delete_offscreen(myi->other_xid);
+  }
+  Fl_Window::hide();
+}
+
+Fl_Double_Window::~Fl_Double_Window() {
+  hide();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_File_Browser.cxx b/Utilities/FLTK/src/Fl_File_Browser.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7698a8083b8389d15b59acde71bfe3a7b7307bfd
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_File_Browser.cxx
@@ -0,0 +1,636 @@
+//
+// "$Id$"
+//
+// Fl_File_Browser routines.
+//
+// Copyright 1999-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_File_Browser::full_height()     - Return the height of the list.
+//   Fl_File_Browser::item_height()     - Return the height of a list item.
+//   Fl_File_Browser::item_width()      - Return the width of a list item.
+//   Fl_File_Browser::item_draw()       - Draw a list item.
+//   Fl_File_Browser::Fl_File_Browser() - Create a Fl_File_Browser widget.
+//   Fl_File_Browser::load()            - Load a directory into the browser.
+//   Fl_File_Browser::filter()          - Set the filename filter.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl_File_Browser.H>
+#include <FL/fl_draw.H>
+#include <FL/filename.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+#ifdef __CYGWIN__
+#  include <mntent.h>
+#elif defined(WIN32)
+#  include <windows.h>
+#  include <direct.h>
+// Apparently Borland C++ defines DIRECTORY in <direct.h>, which
+// interfers with the Fl_File_Icon enumeration of the same name.
+#  ifdef DIRECTORY
+#    undef DIRECTORY
+#  endif // DIRECTORY
+#endif // __CYGWIN__
+
+#ifdef __EMX__
+#  define  INCL_DOS
+#  define  INCL_DOSMISC
+#  include <os2.h>
+#endif // __EMX__
+
+// CodeWarrior (__MWERKS__) gets its include paths confused, so we
+// temporarily disable this...
+#if defined(__APPLE__) && !defined(__MWERKS__)
+#  include <sys/param.h>
+#  include <sys/ucred.h>
+#  include <sys/mount.h>
+#endif // __APPLE__ && !__MWERKS__
+
+
+//
+// FL_BLINE definition from "Fl_Browser.cxx"...
+//
+
+#define SELECTED 1
+#define NOTDISPLAYED 2
+
+struct FL_BLINE			// data is in a linked list of these
+{
+  FL_BLINE	*prev;		// Previous item in list
+  FL_BLINE	*next;		// Next item in list
+  void		*data;		// Pointer to data (function)
+  short		length;		// sizeof(txt)-1, may be longer than string
+  char		flags;		// selected, displayed
+  char		txt[1];		// start of allocated array
+};
+
+
+//
+// 'Fl_File_Browser::full_height()' - Return the height of the list.
+//
+
+int					// O - Height in pixels
+Fl_File_Browser::full_height() const
+{
+  int	i,				// Looping var
+	th;				// Total height of list.
+
+
+  for (i = 0, th = 0; i < size(); i ++)
+    th += item_height(find_line(i));
+
+  return (th);
+}
+
+
+//
+// 'Fl_File_Browser::item_height()' - Return the height of a list item.
+//
+
+int					// O - Height in pixels
+Fl_File_Browser::item_height(void *p) const	// I - List item data
+{
+  FL_BLINE	*line;			// Pointer to line
+  char		*t;			// Pointer into text
+  int		height;			// Width of line
+  int		textheight;		// Height of text
+
+
+  // Figure out the standard text height...
+  fl_font(textfont(), textsize());
+  textheight = fl_height();
+
+  // We always have at least 1 line...
+  height = textheight;
+
+  // Scan for newlines...
+  line = (FL_BLINE *)p;
+
+  if (line != NULL)
+    for (t = line->txt; *t != '\0'; t ++)
+      if (*t == '\n')
+	height += textheight;
+
+  // If we have enabled icons then add space for them...
+  if (Fl_File_Icon::first() != NULL && height < iconsize_)
+    height = iconsize_;
+
+  // Add space for the selection border..
+  height += 2;
+
+  // Return the height
+  return (height);
+}
+
+
+//
+// 'Fl_File_Browser::item_width()' - Return the width of a list item.
+//
+
+int					// O - Width in pixels
+Fl_File_Browser::item_width(void *p) const	// I - List item data
+{
+  int		i;			// Looping var
+  FL_BLINE	*line;			// Pointer to line
+  char		*t,			// Pointer into text
+		*ptr,			// Pointer into fragment
+		fragment[10240];	// Fragment of text
+  int		width,			// Width of line
+		tempwidth;		// Width of fragment
+  int		column;			// Current column
+  const int	*columns;		// Columns
+
+
+  // Set the font and size...
+  fl_font(textfont(), textsize());
+
+  // Scan for newlines...
+  line    = (FL_BLINE *)p;
+  columns = column_widths();
+
+  if (strchr(line->txt, '\n') == NULL &&
+      strchr(line->txt, column_char()) == NULL)
+  {
+    // Do a fast width calculation...
+    width = (int)fl_width(line->txt);
+  }
+  else
+  {
+    // More than 1 line or have columns; find the maximum width...
+    width     = 0;
+    tempwidth = 0;
+    column    = 0;
+
+    for (t = line->txt, ptr = fragment; *t != '\0'; t ++)
+      if (*t == '\n')
+      {
+        // Newline - nul terminate this fragment and get the width...
+        *ptr = '\0';
+
+	tempwidth += (int)fl_width(fragment);
+
+        // Update the max width as needed...
+	if (tempwidth > width)
+	  width = tempwidth;
+
+        // Point back to the start of the fragment...
+	ptr       = fragment;
+	tempwidth = 0;
+	column    = 0;
+      }
+      else if (*t == column_char())
+      {
+        // Advance to the next column...
+        column ++;
+	if (columns)
+	{
+	  for (i = 0, tempwidth = 0; i < column && columns[i]; i ++)
+	    tempwidth += columns[i];
+	}
+	else
+          tempwidth = column * (int)(fl_height() * 0.6 * 8.0);
+
+        if (tempwidth > width)
+	  width = tempwidth;
+
+	ptr = fragment;
+      }
+      else
+        *ptr++ = *t;
+
+    if (ptr > fragment)
+    {
+      // Nul terminate this fragment and get the width...
+      *ptr = '\0';
+
+      tempwidth += (int)fl_width(fragment);
+
+      // Update the max width as needed...
+      if (tempwidth > width)
+	width = tempwidth;
+    }
+  }
+
+  // If we have enabled icons then add space for them...
+  if (Fl_File_Icon::first() != NULL)
+    width += iconsize_ + 8;
+
+  // Add space for the selection border..
+  width += 2;
+
+  // Return the width
+  return (width);
+}
+
+
+//
+// 'Fl_File_Browser::item_draw()' - Draw a list item.
+//
+
+void
+Fl_File_Browser::item_draw(void *p,	// I - List item data
+                 	   int  X,	// I - Upper-lefthand X coordinate
+		 	   int  Y,	// I - Upper-lefthand Y coordinate
+		 	   int  W,	// I - Width of item
+			   int) const	// I - Height of item
+{
+  int		i;			// Looping var
+  FL_BLINE	*line;			// Pointer to line
+  Fl_Color	c;			// Text color
+  char		*t,			// Pointer into text
+		*ptr,			// Pointer into fragment
+		fragment[10240];	// Fragment of text
+  int		width,			// Width of line
+		height;			// Height of line
+  int		column;			// Current column
+  const int	*columns;		// Columns
+
+
+  // Draw the list item text...
+  line = (FL_BLINE *)p;
+
+  if (line->txt[strlen(line->txt) - 1] == '/')
+    fl_font(textfont() | FL_BOLD, textsize());
+  else
+    fl_font(textfont(), textsize());
+
+  if (line->flags & SELECTED)
+    c = fl_contrast(textcolor(), selection_color());
+  else
+    c = textcolor();
+
+  if (Fl_File_Icon::first() == NULL)
+  {
+    // No icons, just draw the text...
+    X ++;
+    W -= 2;
+  }
+  else
+  {
+    // Draw the icon if it is set...
+    if (line->data)
+      ((Fl_File_Icon *)line->data)->draw(X, Y, iconsize_, iconsize_,
+                                	(line->flags & SELECTED) ? FL_YELLOW :
+				                                   FL_LIGHT2,
+					active_r());
+
+    // Draw the text offset to the right...
+    X += iconsize_ + 9;
+    W -= iconsize_ - 10;
+
+    // Center the text vertically...
+    height = fl_height();
+
+    for (t = line->txt; *t != '\0'; t ++)
+      if (*t == '\n')
+	height += fl_height();
+
+    if (height < iconsize_)
+      Y += (iconsize_ - height) / 2;
+  }
+
+  // Draw the text...
+  line    = (FL_BLINE *)p;
+  columns = column_widths();
+  width   = 0;
+  column  = 0;
+
+  if (active_r())
+    fl_color(c);
+  else
+    fl_color(fl_inactive(c));
+
+  for (t = line->txt, ptr = fragment; *t != '\0'; t ++)
+    if (*t == '\n')
+    {
+      // Newline - nul terminate this fragment and draw it...
+      *ptr = '\0';
+
+      fl_draw(fragment, X + width, Y, W - width, fl_height(),
+              (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0);
+
+      // Point back to the start of the fragment...
+      ptr    = fragment;
+      width  = 0;
+      Y      += fl_height();
+      column = 0;
+    }
+    else if (*t == column_char())
+    {
+      // Tab - nul terminate this fragment and draw it...
+      *ptr = '\0';
+
+      int cW = W - width; // Clip width...
+
+      if (columns)
+      {
+        // Try clipping inside this column...
+	for (i = 0; i < column && columns[i]; i ++);
+
+        if (columns[i])
+          cW = columns[i];
+      }
+
+      fl_draw(fragment, X + width, Y, cW, fl_height(),
+              (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0);
+
+      // Advance to the next column...
+      column ++;
+      if (columns)
+      {
+	for (i = 0, width = 0; i < column && columns[i]; i ++)
+	  width += columns[i];
+      }
+      else
+        width = column * (int)(fl_height() * 0.6 * 8.0);
+
+      ptr = fragment;
+    }
+    else
+      *ptr++ = *t;
+
+  if (ptr > fragment)
+  {
+    // Nul terminate this fragment and draw it...
+    *ptr = '\0';
+
+    fl_draw(fragment, X + width, Y, W - width, fl_height(),
+            (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0);
+  }
+}
+
+
+//
+// 'Fl_File_Browser::Fl_File_Browser()' - Create a Fl_File_Browser widget.
+//
+
+Fl_File_Browser::Fl_File_Browser(int        X,  // I - Upper-lefthand X coordinate
+                        	 int        Y,  // I - Upper-lefthand Y coordinate
+				 int        W,  // I - Width in pixels
+				 int        H,  // I - Height in pixels
+				 const char *l)	// I - Label text
+    : Fl_Browser(X, Y, W, H, l)
+{
+  // Initialize the filter pattern, current directory, and icon size...
+  pattern_   = "*";
+  directory_ = "";
+  iconsize_  = (uchar)(3 * textsize() / 2);
+  filetype_  = FILES;
+}
+
+
+//
+// 'Fl_File_Browser::load()' - Load a directory into the browser.
+//
+
+int						// O - Number of files loaded
+Fl_File_Browser::load(const char     *directory,// I - Directory to load
+                      Fl_File_Sort_F *sort)	// I - Sort function to use
+{
+  int		i;				// Looping var
+  int		num_files;			// Number of files in directory
+  int		num_dirs;			// Number of directories in list
+  char		filename[4096];			// Current file
+  Fl_File_Icon	*icon;				// Icon to use
+
+
+//  printf("Fl_File_Browser::load(\"%s\")\n", directory);
+
+  clear();
+
+  directory_ = directory;
+
+  if (!directory)
+    return (0);
+
+  if (directory_[0] == '\0')
+  {
+    //
+    // No directory specified; for UNIX list all mount points.  For DOS
+    // list all valid drive letters...
+    //
+
+    num_files = 0;
+    if ((icon = Fl_File_Icon::find("any", Fl_File_Icon::DEVICE)) == NULL)
+      icon = Fl_File_Icon::find("any", Fl_File_Icon::DIRECTORY);
+
+#ifdef WIN32
+#  ifdef __CYGWIN__
+    //
+    // Cygwin provides an implementation of setmntent() to get the list
+    // of available drives...
+    //
+    FILE          *m = setmntent("/-not-used-", "r");
+    struct mntent *p;
+
+    while ((p = getmntent (m)) != NULL) {
+      add(p->mnt_dir, icon);
+      num_files ++;
+    }
+
+    endmntent(m);
+#  else
+    //
+    // Normal WIN32 code uses drive bits...
+    //
+    DWORD	drives;		// Drive available bits
+
+    drives = GetLogicalDrives();
+    for (i = 'A'; i <= 'Z'; i ++, drives >>= 1)
+      if (drives & 1)
+      {
+        sprintf(filename, "%c:/", i);
+
+	if (i < 'C')
+	  add(filename, icon);
+	else
+	  add(filename, icon);
+
+	num_files ++;
+      }
+#  endif // __CYGWIN__
+#elif defined(__EMX__)
+    //
+    // OS/2 code uses drive bits...
+    //
+    ULONG	curdrive;	// Current drive
+    ULONG	drives;		// Drive available bits
+    int		start = 3;      // 'C' (MRS - dunno if this is correct!)
+
+
+    DosQueryCurrentDisk(&curdrive, &drives);
+    drives >>= start - 1;
+    for (i = 'A'; i <= 'Z'; i ++, drives >>= 1)
+      if (drives & 1)
+      {
+        sprintf(filename, "%c:/", i);
+        add(filename, icon);
+
+	num_files ++;
+      }
+#elif defined(__APPLE__) && !defined(__MWERKS__)
+    // MacOS X and Darwin use getfsstat() system call...
+    int			numfs;	// Number of file systems
+    struct statfs	*fs;	// Buffer for file system info
+
+
+    // We always have the root filesystem.
+    add("/", icon);
+
+    // Get the mounted filesystems...
+    numfs = getfsstat(NULL, 0, MNT_NOWAIT);
+    if (numfs > 0) {
+      // We have file systems, get them...
+      fs = new struct statfs[numfs];
+      getfsstat(fs, sizeof(struct statfs) * numfs, MNT_NOWAIT);
+
+      // Add filesystems to the list...
+      for (i = 0; i < numfs; i ++) {
+	// Ignore "/", "/dev", and "/.vol"...
+        if (fs[i].f_mntonname[1] && strcmp(fs[i].f_mntonname, "/dev") &&
+	    strcmp(fs[i].f_mntonname, "/.vol")) {
+          snprintf(filename, sizeof(filename), "%s/", fs[i].f_mntonname);
+          add(filename, icon);
+        }
+        num_files ++;
+      }
+
+      // Free the memory used for the file system info array...
+      delete[] fs;
+    }
+#else
+    //
+    // UNIX code uses /etc/fstab or similar...
+    //
+    FILE	*mtab;		// /etc/mtab or /etc/mnttab file
+    char	line[1024];	// Input line
+
+    //
+    // Open the file that contains a list of mounted filesystems...
+    //
+
+    mtab = fopen("/etc/mnttab", "r");	// Fairly standard
+    if (mtab == NULL)
+      mtab = fopen("/etc/mtab", "r");	// More standard
+    if (mtab == NULL)
+      mtab = fopen("/etc/fstab", "r");	// Otherwise fallback to full list
+    if (mtab == NULL)
+      mtab = fopen("/etc/vfstab", "r");	// Alternate full list file
+
+    if (mtab != NULL)
+    {
+      while (fgets(line, sizeof(line), mtab) != NULL)
+      {
+        if (line[0] == '#' || line[0] == '\n')
+	  continue;
+        if (sscanf(line, "%*s%4095s", filename) != 1)
+	  continue;
+
+        strlcat(filename, "/", sizeof(filename));
+
+//        printf("Fl_File_Browser::load() - adding \"%s\" to list...\n", filename);
+        add(filename, icon);
+	num_files ++;
+      }
+
+      fclose(mtab);
+    }
+#endif // WIN32 || __EMX__
+  }
+  else
+  {
+    dirent	**files;	// Files in in directory
+
+
+    //
+    // Build the file list...
+    //
+
+#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__)
+    strlcpy(filename, directory_, sizeof(filename));
+    i = strlen(filename) - 1;
+
+    if (i == 2 && filename[1] == ':' &&
+        (filename[2] == '/' || filename[2] == '\\'))
+      filename[2] = '/';
+    else if (filename[i] != '/' && filename[i] != '\\')
+      strlcat(filename, "/", sizeof(filename));
+
+    num_files = fl_filename_list(filename, &files, sort);
+#else
+    num_files = fl_filename_list(directory_, &files, sort);
+#endif /* WIN32 || __EMX__ */
+
+    if (num_files <= 0)
+      return (0);
+
+    for (i = 0, num_dirs = 0; i < num_files; i ++) {
+      if (strcmp(files[i]->d_name, "./")) {
+	snprintf(filename, sizeof(filename), "%s/%s", directory_,
+	         files[i]->d_name);
+
+        icon = Fl_File_Icon::find(filename);
+	if ((icon && icon->type() == Fl_File_Icon::DIRECTORY) ||
+	     fl_filename_isdir(filename)) {
+          num_dirs ++;
+          insert(num_dirs, files[i]->d_name, icon);
+	} else if (filetype_ == FILES &&
+	           fl_filename_match(files[i]->d_name, pattern_)) {
+          add(files[i]->d_name, icon);
+	}
+      }
+
+      free(files[i]);
+    }
+
+    free(files);
+  }
+
+  return (num_files);
+}
+
+
+//
+// 'Fl_File_Browser::filter()' - Set the filename filter.
+//
+
+void
+Fl_File_Browser::filter(const char *pattern)	// I - Pattern string
+{
+  // If pattern is NULL set the pattern to "*"...
+  if (pattern)
+    pattern_ = pattern;
+  else
+    pattern_ = "*";
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_File_Chooser.cxx b/Utilities/FLTK/src/Fl_File_Chooser.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..356e97ddeea699f6284a09b0519941c52cb3bc7d
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_File_Chooser.cxx
@@ -0,0 +1,445 @@
+//
+// "$Id$"
+//
+// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "../FL/Fl_File_Chooser.H"
+#include <FL/fl_draw.H>
+
+void Fl_File_Chooser::cb_window_i(Fl_Double_Window*, void*) {
+  fileName->value("");
+fileList->deselect();
+Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+window->hide();
+}
+void Fl_File_Chooser::cb_window(Fl_Double_Window* o, void* v) {
+  ((Fl_File_Chooser*)(o->user_data()))->cb_window_i(o,v);
+}
+
+void Fl_File_Chooser::cb_showChoice_i(Fl_Choice*, void*) {
+  showChoiceCB();
+}
+void Fl_File_Chooser::cb_showChoice(Fl_Choice* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_showChoice_i(o,v);
+}
+
+void Fl_File_Chooser::cb_favoritesButton_i(Fl_Menu_Button*, void*) {
+  favoritesButtonCB();
+}
+void Fl_File_Chooser::cb_favoritesButton(Fl_Menu_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favoritesButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_newButton_i(Fl_Button*, void*) {
+  newdir();
+}
+void Fl_File_Chooser::cb_newButton(Fl_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_newButton_i(o,v);
+}
+
+#include <FL/Fl_Bitmap.H>
+static unsigned char idata_new[] =
+{0,0,120,0,132,0,2,1,1,254,1,128,49,128,49,128,253,128,253,128,49,128,49,
+128,1,128,1,128,255,255,0,0};
+static Fl_Bitmap image_new(idata_new, 16, 16);
+
+void Fl_File_Chooser::cb__i(Fl_Tile*, void*) {
+  update_preview();
+}
+void Fl_File_Chooser::cb_(Fl_Tile* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->user_data()))->cb__i(o,v);
+}
+
+void Fl_File_Chooser::cb_fileList_i(Fl_File_Browser*, void*) {
+  fileListCB();
+}
+void Fl_File_Chooser::cb_fileList(Fl_File_Browser* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_fileList_i(o,v);
+}
+
+void Fl_File_Chooser::cb_previewButton_i(Fl_Check_Button*, void*) {
+  preview(previewButton->value());
+}
+void Fl_File_Chooser::cb_previewButton(Fl_Check_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_previewButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_fileName_i(Fl_File_Input*, void*) {
+  fileNameCB();
+}
+void Fl_File_Chooser::cb_fileName(Fl_File_Input* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_fileName_i(o,v);
+}
+
+void Fl_File_Chooser::cb_okButton_i(Fl_Return_Button*, void*) {
+  // Do any callback that is registered...
+if (callback_)
+  (*callback_)(this, data_);
+
+window->hide();
+}
+void Fl_File_Chooser::cb_okButton(Fl_Return_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_okButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_cancelButton_i(Fl_Button*, void*) {
+  fileName->value("");
+fileList->deselect();
+Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+window->hide();
+}
+void Fl_File_Chooser::cb_cancelButton(Fl_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_cancelButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_favList_i(Fl_File_Browser*, void*) {
+  favoritesCB(favList);
+}
+void Fl_File_Chooser::cb_favList(Fl_File_Browser* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->user_data()))->cb_favList_i(o,v);
+}
+
+void Fl_File_Chooser::cb_favUpButton_i(Fl_Button*, void*) {
+  favoritesCB(favUpButton);
+}
+void Fl_File_Chooser::cb_favUpButton(Fl_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favUpButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_favDeleteButton_i(Fl_Button*, void*) {
+  favoritesCB(favDeleteButton);
+}
+void Fl_File_Chooser::cb_favDeleteButton(Fl_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favDeleteButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_favDownButton_i(Fl_Button*, void*) {
+  favoritesCB(favDownButton);
+}
+void Fl_File_Chooser::cb_favDownButton(Fl_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favDownButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_favCancelButton_i(Fl_Button*, void*) {
+  favWindow->hide();
+}
+void Fl_File_Chooser::cb_favCancelButton(Fl_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favCancelButton_i(o,v);
+}
+
+void Fl_File_Chooser::cb_favOkButton_i(Fl_Return_Button*, void*) {
+  favoritesCB(favOkButton);
+}
+void Fl_File_Chooser::cb_favOkButton(Fl_Return_Button* o, void* v) {
+  ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favOkButton_i(o,v);
+}
+
+Fl_File_Chooser::Fl_File_Chooser(const char *d, const char *p, int t, const char *title) {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = window = new Fl_Double_Window(490, 380, "Choose File");
+    w = o;
+    o->callback((Fl_Callback*)cb_window, (void*)(this));
+    { Fl_Group* o = new Fl_Group(10, 10, 470, 25);
+      { Fl_Choice* o = showChoice = new Fl_Choice(65, 10, 215, 25, "Show:");
+        o->down_box(FL_BORDER_BOX);
+        o->labelfont(1);
+        o->callback((Fl_Callback*)cb_showChoice);
+        Fl_Group::current()->resizable(o);
+        showChoice->label(show_label);
+      }
+      { Fl_Menu_Button* o = favoritesButton = new Fl_Menu_Button(290, 10, 155, 25, "Favorites");
+        o->down_box(FL_BORDER_BOX);
+        o->callback((Fl_Callback*)cb_favoritesButton);
+        o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+        favoritesButton->label(favorites_label);
+      }
+      { Fl_Button* o = newButton = new Fl_Button(455, 10, 25, 25);
+        o->image(image_new);
+        o->labelsize(8);
+        o->callback((Fl_Callback*)cb_newButton);
+        o->tooltip(new_directory_tooltip);
+      }
+      o->end();
+    }
+    { Fl_Tile* o = new Fl_Tile(10, 45, 470, 225);
+      o->callback((Fl_Callback*)cb_);
+      { Fl_File_Browser* o = fileList = new Fl_File_Browser(10, 45, 295, 225);
+        o->type(2);
+        o->callback((Fl_Callback*)cb_fileList);
+        w->hotspot(o);
+      }
+      { Fl_Box* o = previewBox = new Fl_Box(305, 45, 175, 225, "?");
+        o->box(FL_DOWN_BOX);
+        o->labelsize(100);
+        o->align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE);
+      }
+      o->end();
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Group* o = new Fl_Group(10, 275, 470, 95);
+      { Fl_Group* o = new Fl_Group(10, 275, 470, 20);
+        { Fl_Check_Button* o = previewButton = new Fl_Check_Button(10, 275, 73, 20, "Preview");
+          o->down_box(FL_DOWN_BOX);
+          o->value(1);
+          o->shortcut(0x80070);
+          o->callback((Fl_Callback*)cb_previewButton);
+          previewButton->label(preview_label);
+        }
+        { Fl_Box* o = new Fl_Box(115, 275, 365, 20);
+          Fl_Group::current()->resizable(o);
+        }
+        o->end();
+      }
+      { Fl_File_Input* o = fileName = new Fl_File_Input(115, 300, 365, 35);
+        o->labelfont(1);
+        o->callback((Fl_Callback*)cb_fileName);
+        o->when(FL_WHEN_ENTER_KEY);
+        Fl_Group::current()->resizable(o);
+        fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY_ALWAYS);
+      }
+      { Fl_Box* o = new Fl_Box(10, 310, 105, 25, "Filename:");
+        o->labelfont(1);
+        o->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE);
+        o->label(filename_label);
+      }
+      { Fl_Group* o = new Fl_Group(10, 345, 470, 25);
+        { Fl_Return_Button* o = okButton = new Fl_Return_Button(313, 345, 85, 25, "OK");
+          o->callback((Fl_Callback*)cb_okButton);
+          okButton->label(fl_ok);
+        }
+        { Fl_Button* o = cancelButton = new Fl_Button(408, 345, 72, 25, "Cancel");
+          o->callback((Fl_Callback*)cb_cancelButton);
+          o->label(fl_cancel);
+        }
+        { Fl_Box* o = new Fl_Box(10, 345, 30, 25);
+          Fl_Group::current()->resizable(o);
+        }
+        o->end();
+      }
+      o->end();
+    }
+    if (title) window->label(title);
+    o->set_modal();
+    o->end();
+  }
+  { Fl_Double_Window* o = favWindow = new Fl_Double_Window(355, 150, "Manage Favorites");
+    w = o;
+    o->user_data((void*)(this));
+    { Fl_File_Browser* o = favList = new Fl_File_Browser(10, 10, 300, 95);
+      o->type(2);
+      o->callback((Fl_Callback*)cb_favList);
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Group* o = new Fl_Group(320, 10, 25, 95);
+      { Fl_Button* o = favUpButton = new Fl_Button(320, 10, 25, 25, "@8>");
+        o->callback((Fl_Callback*)cb_favUpButton);
+      }
+      { Fl_Button* o = favDeleteButton = new Fl_Button(320, 45, 25, 25, "X");
+        o->labelfont(1);
+        o->callback((Fl_Callback*)cb_favDeleteButton);
+        Fl_Group::current()->resizable(o);
+      }
+      { Fl_Button* o = favDownButton = new Fl_Button(320, 80, 25, 25, "@2>");
+        o->callback((Fl_Callback*)cb_favDownButton);
+      }
+      o->end();
+    }
+    { Fl_Group* o = new Fl_Group(10, 113, 335, 29);
+      { Fl_Button* o = favCancelButton = new Fl_Button(273, 115, 72, 25, "Cancel");
+        o->callback((Fl_Callback*)cb_favCancelButton);
+        favCancelButton->label(fl_cancel);
+      }
+      { Fl_Return_Button* o = favOkButton = new Fl_Return_Button(181, 115, 79, 25, "Save");
+        o->callback((Fl_Callback*)cb_favOkButton);
+        favOkButton->label(save_label);
+      }
+      { Fl_Box* o = new Fl_Box(10, 115, 161, 25);
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    favWindow->label(manage_favorites_label);
+    o->set_modal();
+    o->size_range(181, 150);
+    o->end();
+  }
+  callback_ = 0;
+data_ = 0;
+directory_[0] = 0;
+window->size_range(window->w(), window->h(), Fl::w(), Fl::h());
+type(t);
+filter(p);
+update_favorites();
+value(d);
+type(t);
+int e;
+prefs_.get("preview", e, 1);
+preview(e);
+}
+
+Fl_File_Chooser::~Fl_File_Chooser() {
+  Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+delete window;
+delete favWindow;
+}
+
+void Fl_File_Chooser::callback(void (*cb)(Fl_File_Chooser *, void *), void *d ) {
+  callback_ = cb;
+data_     = d;
+}
+
+void Fl_File_Chooser::color(Fl_Color c) {
+  fileList->color(c);
+}
+
+Fl_Color Fl_File_Chooser::color() {
+  return (fileList->color());
+}
+
+char * Fl_File_Chooser::directory() {
+  return directory_;
+}
+
+const char * Fl_File_Chooser::filter() {
+  return (fileList->filter());
+}
+
+int Fl_File_Chooser::filter_value() {
+  return showChoice->value();
+}
+
+void Fl_File_Chooser::filter_value(int f) {
+  showChoice->value(f);
+showChoiceCB();
+}
+
+void Fl_File_Chooser::hide() {
+  window->hide();
+}
+
+void Fl_File_Chooser::iconsize(uchar s) {
+  fileList->iconsize(s);
+}
+
+uchar Fl_File_Chooser::iconsize() {
+  return (fileList->iconsize());
+}
+
+void Fl_File_Chooser::label(const char *l) {
+  window->label(l);
+}
+
+const char * Fl_File_Chooser::label() {
+  return (window->label());
+}
+
+void Fl_File_Chooser::ok_label(const char *l) {
+  okButton->label(l);
+int w=0, h=0;
+okButton->measure_label(w, h);
+okButton->resize(cancelButton->x() - 50 - w, cancelButton->y(),
+                 w + 40, 25);
+okButton->parent()->init_sizes();
+}
+
+const char * Fl_File_Chooser::ok_label() {
+  return (okButton->label());
+}
+
+void Fl_File_Chooser::show() {
+  window->hotspot(fileList);
+window->show();
+Fl::flush();
+fl_cursor(FL_CURSOR_WAIT);
+rescan();
+fl_cursor(FL_CURSOR_DEFAULT);
+fileName->take_focus();
+}
+
+int Fl_File_Chooser::shown() {
+  return window->shown();
+}
+
+void Fl_File_Chooser::textcolor(Fl_Color c) {
+  fileList->textcolor(c);
+}
+
+Fl_Color Fl_File_Chooser::textcolor() {
+  return (fileList->textcolor());
+}
+
+void Fl_File_Chooser::textfont(uchar f) {
+  fileList->textfont(f);
+}
+
+uchar Fl_File_Chooser::textfont() {
+  return (fileList->textfont());
+}
+
+void Fl_File_Chooser::textsize(uchar s) {
+  fileList->textsize(s);
+}
+
+uchar Fl_File_Chooser::textsize() {
+  return (fileList->textsize());
+}
+
+void Fl_File_Chooser::type(int t) {
+  type_ = t;
+if (t & MULTI)
+  fileList->type(FL_MULTI_BROWSER);
+else
+  fileList->type(FL_HOLD_BROWSER);
+if (t & CREATE)
+  newButton->activate();
+else
+  newButton->deactivate();
+if (t & DIRECTORY)
+  fileList->filetype(Fl_File_Browser::DIRECTORIES);
+else
+  fileList->filetype(Fl_File_Browser::FILES);
+}
+
+int Fl_File_Chooser::type() {
+  return (type_);
+}
+
+void * Fl_File_Chooser::user_data() const {
+  return (data_);
+}
+
+void Fl_File_Chooser::user_data(void *d) {
+  data_ = d;
+}
+
+int Fl_File_Chooser::visible() {
+  return window->visible();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_File_Chooser.fl b/Utilities/FLTK/src/Fl_File_Chooser.fl
new file mode 100644
index 0000000000000000000000000000000000000000..b9687d54c474c821f5776176547e246a846f7c44
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_File_Chooser.fl
@@ -0,0 +1,422 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {../FL/Fl_File_Chooser.H} 
+code_name {.cxx}
+comment {//
+// "$Id: Fl_File_Chooser.fl 4723 2005-12-30 10:13:17Z matt $"
+//
+// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {in_source in_header
+} 
+
+decl {\#include <FL/fl_draw.H>} {} 
+
+class FL_EXPORT Fl_File_Chooser {open
+} {
+  decl {enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 };} {public
+  }
+  decl {static Fl_Preferences prefs_;} {}
+  decl {void (*callback_)(Fl_File_Chooser*, void *);} {}
+  decl {void *data_;} {}
+  decl {char directory_[1024];} {}
+  decl {char pattern_[1024];} {}
+  decl {char preview_text_[2048];} {}
+  decl {int type_;} {}
+  decl {void favoritesButtonCB();} {}
+  decl {void favoritesCB(Fl_Widget *w);} {}
+  decl {void fileListCB();} {}
+  decl {void fileNameCB();} {}
+  decl {void newdir();} {}
+  decl {static void previewCB(Fl_File_Chooser *fc);} {}
+  decl {void showChoiceCB();} {}
+  decl {void update_favorites();} {}
+  decl {void update_preview();} {}
+  Function {Fl_File_Chooser(const char *d, const char *p, int t, const char *title)} {open
+  } {
+    Fl_Window window {
+      label {Choose File}
+      callback {fileName->value("");
+fileList->deselect();
+Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+window->hide();}
+      private xywh {387 242 490 380} type Double resizable
+      code0 {if (title) window->label(title);}
+      code1 {\#include <stdio.h>}
+      code2 {\#include <stdlib.h>}
+      code3 {\#include <string.h>} modal visible
+    } {
+      Fl_Group {} {
+        private xywh {10 10 470 25}
+      } {
+        Fl_Choice showChoice {
+          label {Show:}
+          callback {showChoiceCB();} open
+          private xywh {65 10 215 25} down_box BORDER_BOX labelfont 1 resizable
+          code0 {showChoice->label(show_label);}
+        } {}
+        Fl_Menu_Button favoritesButton {
+          label Favorites
+          callback {favoritesButtonCB();} open
+          private xywh {290 10 155 25} down_box BORDER_BOX align 20
+          code0 {favoritesButton->label(favorites_label);}
+        } {}
+        Fl_Button newButton {
+          callback {newdir();}
+          image {new.xbm} xywh {455 10 25 25} labelsize 8
+          code0 {\#include <FL/Fl_Preferences.H>}
+          code1 {o->tooltip(new_directory_tooltip);}
+        }
+      }
+      Fl_Tile {} {
+        callback {update_preview();}
+        private xywh {10 45 470 225} resizable
+      } {
+        Fl_File_Browser fileList {
+          callback {fileListCB();}
+          private xywh {10 45 295 225} type Hold hotspot
+          code0 {\#include <FL/Fl_File_Browser.H>}
+        }
+        Fl_Box previewBox {
+          label {?}
+          private xywh {305 45 175 225} box DOWN_BOX labelsize 100 align 80
+        }
+      }
+      Fl_Group {} {
+        private xywh {10 275 470 95}
+      } {
+        Fl_Group {} {open
+          private xywh {10 275 470 20}
+        } {
+          Fl_Check_Button previewButton {
+            label Preview
+            callback {preview(previewButton->value());}
+            xywh {10 275 73 20} down_box DOWN_BOX shortcut 0x80070 value 1
+            code0 {previewButton->label(preview_label);}
+          }
+          Fl_Box {} {
+            private xywh {115 275 365 20} resizable
+          }
+        }
+        Fl_File_Input fileName {
+          callback {fileNameCB();}
+          private xywh {115 300 365 35} labelfont 1 when 8 resizable
+          code0 {fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY_ALWAYS);}
+        }
+        Fl_Box {} {
+          label {Filename:}
+          private xywh {10 310 105 25} labelfont 1 align 24
+          code0 {o->label(filename_label);}
+        }
+        Fl_Group {} {open
+          private xywh {10 345 470 25}
+        } {
+          Fl_Return_Button okButton {
+            label OK
+            callback {// Do any callback that is registered...
+if (callback_)
+  (*callback_)(this, data_);
+
+window->hide();} selected
+            private xywh {313 345 85 25}
+            code0 {\#include <FL/fl_ask.H>}
+            code1 {okButton->label(fl_ok);}
+          }
+          Fl_Button cancelButton {
+            label Cancel
+            callback {fileName->value("");
+fileList->deselect();
+Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+window->hide();}
+            private xywh {408 345 72 25}
+            code0 {o->label(fl_cancel);}
+          }
+          Fl_Box {} {
+            private xywh {10 345 30 25} resizable
+          }
+        }
+      }
+    }
+    Fl_Window favWindow {
+      label {Manage Favorites}
+      private xywh {437 187 355 150} type Double resizable
+      code0 {favWindow->label(manage_favorites_label);} modal size_range {181 150 0 0} visible
+    } {
+      Fl_File_Browser favList {
+        callback {favoritesCB(favList);}
+        private xywh {10 10 300 95} type Hold resizable
+      }
+      Fl_Group {} {open
+        xywh {320 10 25 95}
+      } {
+        Fl_Button favUpButton {
+          label {@8>}
+          callback {favoritesCB(favUpButton);}
+          private xywh {320 10 25 25}
+        }
+        Fl_Button favDeleteButton {
+          label X
+          callback {favoritesCB(favDeleteButton);}
+          private xywh {320 45 25 25} labelfont 1 resizable
+        }
+        Fl_Button favDownButton {
+          label {@2>}
+          callback {favoritesCB(favDownButton);}
+          private xywh {320 80 25 25}
+        }
+      }
+      Fl_Group {} {open
+        xywh {10 113 335 29}
+      } {
+        Fl_Button favCancelButton {
+          label Cancel
+          callback {favWindow->hide();}
+          private xywh {273 115 72 25}
+          code0 {favCancelButton->label(fl_cancel);}
+        }
+        Fl_Return_Button favOkButton {
+          label Save
+          callback {favoritesCB(favOkButton);}
+          private xywh {181 115 79 25}
+          code0 {\#include <FL/fl_ask.H>}
+          code1 {favOkButton->label(save_label);}
+        }
+        Fl_Box {} {
+          xywh {10 115 161 25} resizable
+        }
+      }
+    }
+    code {callback_ = 0;
+data_ = 0;
+directory_[0] = 0;
+window->size_range(window->w(), window->h(), Fl::w(), Fl::h());
+type(t);
+filter(p);
+update_favorites();
+value(d);
+type(t);
+int e;
+prefs_.get("preview", e, 1);
+preview(e);} {}
+  }
+  Function {~Fl_File_Chooser()} {} {
+    code {Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+delete window;
+delete favWindow;} {}
+  }
+  Function {callback(void (*cb)(Fl_File_Chooser *, void *), void *d = 0)} {return_type void
+  } {
+    code {callback_ = cb;
+data_     = d;} {}
+  }
+  Function {color(Fl_Color c)} {} {
+    code {fileList->color(c);} {}
+  }
+  Function {color()} {return_type Fl_Color
+  } {
+    code {return (fileList->color());} {}
+  }
+  decl {int count();} {public
+  }
+  decl {void directory(const char *d);} {public
+  }
+  Function {directory()} {return_type {char *}
+  } {
+    code {return directory_;} {}
+  }
+  decl {void filter(const char *p);} {public
+  }
+  Function {filter()} {return_type {const char *}
+  } {
+    code {return (fileList->filter());} {}
+  }
+  Function {filter_value()} {return_type int
+  } {
+    code {return showChoice->value();} {}
+  }
+  Function {filter_value(int f)} {return_type void
+  } {
+    code {showChoice->value(f);
+showChoiceCB();} {}
+  }
+  Function {hide()} {return_type void
+  } {
+    code {window->hide();} {}
+  }
+  Function {iconsize(uchar s)} {return_type void
+  } {
+    code {fileList->iconsize(s);} {}
+  }
+  Function {iconsize()} {return_type uchar
+  } {
+    code {return (fileList->iconsize());} {}
+  }
+  Function {label(const char *l)} {return_type void
+  } {
+    code {window->label(l);} {}
+  }
+  Function {label()} {return_type {const char *}
+  } {
+    code {return (window->label());} {}
+  }
+  Function {ok_label(const char *l)} {return_type void
+  } {
+    code {okButton->label(l);
+int w=0, h=0;
+okButton->measure_label(w, h);
+okButton->resize(cancelButton->x() - 50 - w, cancelButton->y(),
+                 w + 40, 25);
+okButton->parent()->init_sizes();} {}
+  }
+  Function {ok_label()} {return_type {const char *}
+  } {
+    code {return (okButton->label());} {}
+  }
+  decl {void preview(int e);} {public
+  }
+  decl {int preview() const { return previewButton->value(); }} {public
+  }
+  decl {void rescan();} {public
+  }
+  Function {show()} {return_type void
+  } {
+    code {window->hotspot(fileList);
+window->show();
+Fl::flush();
+fl_cursor(FL_CURSOR_WAIT);
+rescan();
+fl_cursor(FL_CURSOR_DEFAULT);
+fileName->take_focus();} {}
+  }
+  Function {shown()} {return_type int
+  } {
+    code {return window->shown();} {}
+  }
+  Function {textcolor(Fl_Color c)} {return_type void
+  } {
+    code {fileList->textcolor(c);} {}
+  }
+  Function {textcolor()} {return_type Fl_Color
+  } {
+    code {return (fileList->textcolor());} {}
+  }
+  Function {textfont(uchar f)} {return_type void
+  } {
+    code {fileList->textfont(f);} {}
+  }
+  Function {textfont()} {return_type uchar
+  } {
+    code {return (fileList->textfont());} {}
+  }
+  Function {textsize(uchar s)} {return_type void
+  } {
+    code {fileList->textsize(s);} {}
+  }
+  Function {textsize()} {return_type uchar
+  } {
+    code {return (fileList->textsize());} {}
+  }
+  Function {type(int t)} {return_type void
+  } {
+    code {type_ = t;
+if (t & MULTI)
+  fileList->type(FL_MULTI_BROWSER);
+else
+  fileList->type(FL_HOLD_BROWSER);
+if (t & CREATE)
+  newButton->activate();
+else
+  newButton->deactivate();
+if (t & DIRECTORY)
+  fileList->filetype(Fl_File_Browser::DIRECTORIES);
+else
+  fileList->filetype(Fl_File_Browser::FILES);} {}
+  }
+  Function {type()} {return_type int
+  } {
+    code {return (type_);} {}
+  }
+  Function {user_data() const} {return_type {void *}
+  } {
+    code {return (data_);} {}
+  }
+  Function {user_data(void *d)} {return_type void
+  } {
+    code {data_ = d;} {}
+  }
+  decl {const char *value(int f = 1);} {public
+  }
+  decl {void value(const char *filename);} {public
+  }
+  Function {visible()} {return_type int
+  } {
+    code {return window->visible();} {}
+  }
+  decl {static const char *add_favorites_label;} {public
+  }
+  decl {static const char *all_files_label;} {public
+  }
+  decl {static const char *custom_filter_label;} {public
+  }
+  decl {static const char *existing_file_label;} {public
+  }
+  decl {static const char *favorites_label;} {public
+  }
+  decl {static const char *filename_label;} {public
+  }
+  decl {static const char *filesystems_label;} {public
+  }
+  decl {static const char *manage_favorites_label;} {public
+  }
+  decl {static const char *new_directory_label;} {public
+  }
+  decl {static const char *new_directory_tooltip;} {public
+  }
+  decl {static const char *preview_label;} {public
+  }
+  decl {static const char *save_label;} {public
+  }
+  decl {static const char *show_label;} {public
+  }
+  decl {static Fl_File_Sort_F *sort;} {public
+  }
+} 
+
+decl {FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0);} {public
+} 
+
+decl {FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0);} {public
+} 
+
+decl {FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*));} {public
+} 
+
+decl {FL_EXPORT void fl_file_chooser_ok_label(const char*l);} {public
+} 
+
+comment {
+//
+// End of "$Id: Fl_File_Chooser.fl 4723 2005-12-30 10:13:17Z matt $".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/src/Fl_File_Chooser2.cxx b/Utilities/FLTK/src/Fl_File_Chooser2.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..648d8a7abe3c14a3e59d97fb8b24a4124b4ec10b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_File_Chooser2.cxx
@@ -0,0 +1,1251 @@
+//
+// "$Id$"
+//
+// More Fl_File_Chooser routines.
+//
+// Copyright 1999-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_File_Chooser::count()             - Return the number of selected files.
+//   Fl_File_Chooser::directory()         - Set the directory in the file chooser.
+//   Fl_File_Chooser::filter()            - Set the filter(s) for the chooser.
+//   Fl_File_Chooser::newdir()            - Make a new directory.
+//   Fl_File_Chooser::value()             - Return a selected filename.
+//   Fl_File_Chooser::rescan()            - Rescan the current directory.
+//   Fl_File_Chooser::favoritesButtonCB() - Handle favorites selections.
+//   Fl_File_Chooser::fileListCB()        - Handle clicks (and double-clicks)
+//                                          in the Fl_File_Browser.
+//   Fl_File_Chooser::fileNameCB()        - Handle text entry in the FileBrowser.
+//   Fl_File_Chooser::showChoiceCB()      - Handle show selections.
+//   compare_dirnames()                   - Compare two directory names.
+//   quote_pathname()                     - Quote a pathname for a menu.
+//   unquote_pathname()                   - Unquote a pathname from a menu.
+//
+
+//
+// Include necessary headers.
+//
+
+#include <FL/Fl_File_Chooser.H>
+#include <FL/filename.H>
+#include <FL/fl_ask.H>
+#include <FL/x.H>
+#include <FL/Fl_Shared_Image.H>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(WIN32) && ! defined (__CYGWIN__)
+#  include <direct.h>
+#  include <io.h>
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define access _access
+#  define mkdir _mkdir
+// Apparently Borland C++ defines DIRECTORY in <direct.h>, which
+// interfers with the Fl_File_Icon enumeration of the same name.
+#  ifdef DIRECTORY
+#    undef DIRECTORY
+#  endif // DIRECTORY
+#else
+#  include <unistd.h>
+#  include <pwd.h>
+#endif /* WIN32 */
+
+
+//
+// File chooser label strings and sort function...
+//
+
+Fl_Preferences	Fl_File_Chooser::prefs_(Fl_Preferences::USER, "fltk.org", "filechooser");
+
+const char	*Fl_File_Chooser::add_favorites_label = "Add to Favorites";
+const char	*Fl_File_Chooser::all_files_label = "All Files (*)";
+const char	*Fl_File_Chooser::custom_filter_label = "Custom Filter";
+const char	*Fl_File_Chooser::existing_file_label = "Please choose an existing file!";
+const char	*Fl_File_Chooser::favorites_label = "Favorites";
+const char	*Fl_File_Chooser::filename_label = "Filename:";
+#ifdef WIN32
+const char	*Fl_File_Chooser::filesystems_label = "My Computer";
+#else
+const char	*Fl_File_Chooser::filesystems_label = "File Systems";
+#endif // WIN32
+const char	*Fl_File_Chooser::manage_favorites_label = "Manage Favorites";
+const char	*Fl_File_Chooser::new_directory_label = "New Directory?";
+const char	*Fl_File_Chooser::new_directory_tooltip = "Create a new directory.";
+const char	*Fl_File_Chooser::preview_label = "Preview";
+const char	*Fl_File_Chooser::save_label = "Save";
+const char	*Fl_File_Chooser::show_label = "Show:";
+Fl_File_Sort_F	*Fl_File_Chooser::sort = fl_numericsort;
+
+
+//
+// Local functions...
+//
+
+static int	compare_dirnames(const char *a, const char *b);
+static void	quote_pathname(char *, const char *, int);
+static void	unquote_pathname(char *, const char *, int);
+
+
+//
+// 'Fl_File_Chooser::count()' - Return the number of selected files.
+//
+
+int				// O - Number of selected files
+Fl_File_Chooser::count() {
+  int		i;		// Looping var
+  int		fcount;		// Number of selected files
+  const char	*filename;	// Filename in input field or list
+
+
+  filename = fileName->value();
+
+  if (!(type_ & MULTI)) {
+    // Check to see if the file name input field is blank...
+    if (!filename || !filename[0]) return 0;
+    else return 1;
+  }
+
+  for (i = 1, fcount = 0; i <= fileList->size(); i ++)
+    if (fileList->selected(i)) {
+      // See if this file is a directory...
+      filename = (char *)fileList->text(i);
+
+      if (filename[strlen(filename) - 1] != '/')
+	fcount ++;
+    }
+
+  if (fcount) return fcount;
+  else if (!filename || !filename[0]) return 0;
+  else return 1;
+}
+
+
+//
+// 'Fl_File_Chooser::directory()' - Set the directory in the file chooser.
+//
+
+void
+Fl_File_Chooser::directory(const char *d)// I - Directory to change to
+{
+  char	*dirptr;			// Pointer into directory
+
+
+//  printf("Fl_File_Chooser::directory(\"%s\")\n", d == NULL ? "(null)" : d);
+
+  // NULL == current directory
+  if (d == NULL)
+    d = ".";
+
+#ifdef WIN32
+  // See if the filename contains backslashes...
+  char	*slash;				// Pointer to slashes
+  char	fixpath[1024];			// Path with slashes converted
+  if (strchr(d, '\\')) {
+    // Convert backslashes to slashes...
+    strlcpy(fixpath, d, sizeof(fixpath));
+
+    for (slash = strchr(fixpath, '\\'); slash; slash = strchr(slash + 1, '\\'))
+      *slash = '/';
+
+    d = fixpath;
+  }
+#endif // WIN32
+
+  if (d[0] != '\0')
+  {
+    // Make the directory absolute...
+#if (defined(WIN32) && ! defined(__CYGWIN__))|| defined(__EMX__)
+    if (d[0] != '/' && d[0] != '\\' && d[1] != ':')
+#else
+    if (d[0] != '/' && d[0] != '\\')
+#endif /* WIN32 || __EMX__ */
+      fl_filename_absolute(directory_, d);
+    else
+      strlcpy(directory_, d, sizeof(directory_));
+
+    // Strip any trailing slash...
+    dirptr = directory_ + strlen(directory_) - 1;
+    if ((*dirptr == '/' || *dirptr == '\\') && dirptr > directory_)
+      *dirptr = '\0';
+
+    // See if we have a trailing .. or . in the filename...
+    dirptr = directory_ + strlen(directory_) - 3;
+    if (dirptr >= directory_ && strcmp(dirptr, "/..") == 0) {
+      // Yes, we have "..", so strip the trailing path...
+      *dirptr = '\0';
+      while (dirptr > directory_) {
+        if (*dirptr == '/') break;
+	dirptr --;
+      }
+
+      if (dirptr >= directory_ && *dirptr == '/')
+        *dirptr = '\0';
+    } else if ((dirptr + 1) >= directory_ && strcmp(dirptr + 1, "/.") == 0) {
+      // Strip trailing "."...
+      dirptr[1] = '\0';
+    }
+  }
+  else
+    directory_[0] = '\0';
+
+  if (shown()) {
+    // Rescan the directory...
+    rescan();
+  }
+}
+
+
+//
+// 'Fl_File_Chooser::favoritesButtonCB()' - Handle favorites selections.
+//
+
+void
+Fl_File_Chooser::favoritesButtonCB()
+{
+  int		v;			// Current selection
+  char		pathname[1024],		// Pathname
+		menuname[2048];		// Menu name
+
+
+  v = favoritesButton->value();
+
+  if (!v) {
+    // Add current directory to favorites...
+    if (getenv("HOME")) v = favoritesButton->size() - 5;
+    else v = favoritesButton->size() - 4;
+
+    sprintf(menuname, "favorite%02d", v);
+
+    prefs_.set(menuname, directory_);
+
+    quote_pathname(menuname, directory_, sizeof(menuname));
+    favoritesButton->add(menuname);
+
+    if (favoritesButton->size() > 104) {
+      ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate();
+    }
+  } else if (v == 1) {
+    // Manage favorites...
+    favoritesCB(0);
+  } else if (v == 2) {
+    // Filesystems/My Computer
+    directory("");
+  } else {
+    unquote_pathname(pathname, favoritesButton->text(v), sizeof(pathname));
+    directory(pathname);
+  }
+}
+
+
+//
+// 'Fl_File_Chooser::favoritesCB()' - Handle favorites dialog.
+//
+
+void
+Fl_File_Chooser::favoritesCB(Fl_Widget *w)
+					// I - Widget
+{
+  int		i;			// Looping var
+  char		name[32],		// Preference name
+		pathname[1024];		// Directory in list
+
+
+  if (!w) {
+    // Load the favorites list...
+    favList->clear();
+    favList->deselect();
+
+    for (i = 0; i < 100; i ++) {
+      // Get favorite directory 0 to 99...
+      sprintf(name, "favorite%02d", i);
+
+      prefs_.get(name, pathname, "", sizeof(pathname));
+
+      // Stop on the first empty favorite...
+      if (!pathname[0]) break;
+
+      // Add the favorite to the list...
+      favList->add(pathname,
+                   Fl_File_Icon::find(pathname, Fl_File_Icon::DIRECTORY));
+    }
+
+    favUpButton->deactivate();
+    favDeleteButton->deactivate();
+    favDownButton->deactivate();
+    favOkButton->deactivate();
+
+    favWindow->hotspot(favList);
+    favWindow->show();
+  } else if (w == favList) {
+    i = favList->value();
+    if (i) {
+      if (i > 1) favUpButton->activate();
+      else favUpButton->deactivate();
+
+      favDeleteButton->activate();
+
+      if (i < favList->size()) favDownButton->activate();
+      else favDownButton->deactivate();
+    } else {
+      favUpButton->deactivate();
+      favDeleteButton->deactivate();
+      favDownButton->deactivate();
+    }
+  } else if (w == favUpButton) {
+    i = favList->value();
+
+    favList->insert(i - 1, favList->text(i), favList->data(i));
+    favList->remove(i + 1);
+    favList->select(i - 1);
+
+    if (i == 2) favUpButton->deactivate();
+
+    favDownButton->activate();
+
+    favOkButton->activate();
+  } else if (w == favDeleteButton) {
+    i = favList->value();
+
+    favList->remove(i);
+
+    if (i > favList->size()) i --;
+    favList->select(i);
+
+    if (i < favList->size()) favDownButton->activate();
+    else favDownButton->deactivate();
+
+    if (i > 1) favUpButton->activate();
+    else favUpButton->deactivate();
+
+    if (!i) favDeleteButton->deactivate();
+
+    favOkButton->activate();
+  } else if (w == favDownButton) {
+    i = favList->value();
+
+    favList->insert(i + 2, favList->text(i), favList->data(i));
+    favList->remove(i);
+    favList->select(i + 1);
+
+    if ((i + 1) == favList->size()) favDownButton->deactivate();
+
+    favUpButton->activate();
+
+    favOkButton->activate();
+  } else if (w == favOkButton) {
+    // Copy the new list over...
+    for (i = 0; i < favList->size(); i ++) {
+      // Set favorite directory 0 to 99...
+      sprintf(name, "favorite%02d", i);
+
+      prefs_.set(name, favList->text(i + 1));
+    }
+
+    // Clear old entries as necessary...
+    for (; i < 100; i ++) {
+      // Clear favorite directory 0 to 99...
+      sprintf(name, "favorite%02d", i);
+
+      prefs_.get(name, pathname, "", sizeof(pathname));
+
+      if (pathname[0]) prefs_.set(name, "");
+      else break;
+    }
+
+    update_favorites();
+
+    favWindow->hide();
+  }
+}
+
+
+//
+// 'Fl_File_Chooser::fileListCB()' - Handle clicks (and double-clicks) in the
+//                                   Fl_File_Browser.
+//
+
+void
+Fl_File_Chooser::fileListCB()
+{
+  char	*filename,			// New filename
+	pathname[1024];			// Full pathname to file
+
+
+  filename = (char *)fileList->text(fileList->value());
+  if (!filename)
+    return;
+
+  if (!directory_[0]) {
+    strlcpy(pathname, filename, sizeof(pathname));
+  } else if (strcmp(directory_, "/") == 0) {
+    snprintf(pathname, sizeof(pathname), "/%s", filename);
+  } else {
+    snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
+  }
+
+  if (Fl::event_clicks()) {
+#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
+    if ((strlen(pathname) == 2 && pathname[1] == ':') ||
+        fl_filename_isdir(pathname))
+#else
+    if (fl_filename_isdir(pathname))
+#endif /* WIN32 || __EMX__ */
+    {
+      // Change directories...
+      directory(pathname);
+
+      // Reset the click count so that a click in the same spot won't
+      // be treated as a triple-click.  We use a value of -1 because
+      // the next click will increment click count to 0, which is what
+      // we really want...
+      Fl::event_clicks(-1);
+    }
+    else
+    {
+      // Hide the window - picked the file...
+      window->hide();
+    }
+  }
+  else
+  {
+    // Check if the user clicks on a directory when picking files;
+    // if so, make sure only that item is selected...
+    filename = pathname + strlen(pathname) - 1;
+
+    if ((type_ & MULTI) && !(type_ & DIRECTORY)) {
+      if (*filename == '/') {
+	// Clicked on a directory, deselect everything else...
+	int i = fileList->value();
+	fileList->deselect();
+	fileList->select(i);
+      } else {
+        // Clicked on a file - see if there are other directories selected...
+        int i;
+	const char *temp;
+	for (i = 1; i <= fileList->size(); i ++) {
+	  if (i != fileList->value() && fileList->selected(i)) {
+	    temp = fileList->text(i);
+	    temp += strlen(temp) - 1;
+	    if (*temp == '/') break;	// Yes, selected directory
+	  }
+	}
+
+        if (i <= fileList->size()) {
+	  i = fileList->value();
+	  fileList->deselect();
+	  fileList->select(i);
+	}
+      }
+    }
+    // Strip any trailing slash from the directory name...
+    if (*filename == '/') *filename = '\0';
+
+//    puts("Setting fileName from fileListCB...");
+    fileName->value(pathname);
+
+    // Update the preview box...
+    Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+    Fl::add_timeout(1.0, (Fl_Timeout_Handler)previewCB, this);
+
+    // Do any callback that is registered...
+    if (callback_) (*callback_)(this, data_);
+
+    // Activate the OK button as needed...
+    if (!fl_filename_isdir(pathname) || (type_ & DIRECTORY))
+      okButton->activate();
+    else
+      okButton->deactivate();
+  }
+}
+
+
+//
+// 'Fl_File_Chooser::fileNameCB()' - Handle text entry in the FileBrowser.
+//
+
+void
+Fl_File_Chooser::fileNameCB()
+{
+  char		*filename,	// New filename
+		*slash,		// Pointer to trailing slash
+		pathname[1024],	// Full pathname to file
+		matchname[256];	// Matching filename
+  int		i,		// Looping var
+		min_match,	// Minimum number of matching chars
+		max_match,	// Maximum number of matching chars
+		num_files,	// Number of files in directory
+		first_line;	// First matching line
+  const char	*file;		// File from directory
+
+
+//  puts("fileNameCB()");
+
+  // Get the filename from the text field...
+  filename = (char *)fileName->value();
+
+  if (!filename || !filename[0]) {
+    okButton->deactivate();
+    return;
+  }
+
+  // Expand ~ and $ variables as needed...
+  if (strchr(filename, '~') || strchr(filename, '$')) {
+    fl_filename_expand(pathname, sizeof(pathname), filename);
+    filename = pathname;
+    value(pathname);
+  }
+
+  // Make sure we have an absolute path...
+#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__)
+  if (directory_[0] != '\0' && filename[0] != '/' &&
+      filename[0] != '\\' &&
+      !(isalpha(filename[0] & 255) && (!filename[1] || filename[1] == ':'))) {
+#else
+  if (directory_[0] != '\0' && filename[0] != '/') {
+#endif /* WIN32 || __EMX__ */
+    fl_filename_absolute(pathname, sizeof(pathname), filename);
+    value(pathname);
+    fileName->mark(fileName->position()); // no selection after expansion
+  } else if (filename != pathname) {
+    // Finally, make sure that we have a writable copy...
+    strlcpy(pathname, filename, sizeof(pathname));
+  }
+
+  filename = pathname;
+
+  // Now process things according to the key pressed...
+  if (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter) {
+    // Enter pressed - select or change directory...
+#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
+    if ((isalpha(pathname[0] & 255) && pathname[1] == ':' && !pathname[2]) ||
+        fl_filename_isdir(pathname) &&
+	compare_dirnames(pathname, directory_)) {
+#else
+    if (fl_filename_isdir(pathname) &&
+	compare_dirnames(pathname, directory_)) {
+#endif /* WIN32 || __EMX__ */
+      directory(pathname);
+    } else if ((type_ & CREATE) || access(pathname, 0) == 0) {
+      if (!fl_filename_isdir(pathname) || (type_ & DIRECTORY)) {
+	// Update the preview box...
+	update_preview();
+
+	// Do any callback that is registered...
+	if (callback_) (*callback_)(this, data_);
+
+	// Hide the window to signal things are done...
+	window->hide();
+      }
+    } else {
+      // File doesn't exist, so beep at and alert the user...
+      fl_alert(existing_file_label);
+    }
+  }
+  else if (Fl::event_key() != FL_Delete &&
+           Fl::event_key() != FL_BackSpace) {
+    // Check to see if the user has entered a directory...
+    if ((slash = strrchr(pathname, '/')) == NULL)
+      slash = strrchr(pathname, '\\');
+
+    if (!slash) return;
+
+    // Yes, change directories if necessary...
+    *slash++ = '\0';
+    filename = slash;
+
+#if defined(WIN32) || defined(__EMX__)
+    if (strcasecmp(pathname, directory_) &&
+        (pathname[0] || strcasecmp("/", directory_))) {
+#else
+    if (strcmp(pathname, directory_) &&
+        (pathname[0] || strcasecmp("/", directory_))) {
+#endif // WIN32 || __EMX__
+      int p = fileName->position();
+      int m = fileName->mark();
+
+      directory(pathname);
+
+      if (filename[0]) {
+	char tempname[1024];
+
+	snprintf(tempname, sizeof(tempname), "%s/%s", directory_, filename);
+	fileName->value(tempname);
+	strlcpy(pathname, tempname, sizeof(pathname));
+      }
+
+      fileName->position(p, m);
+    }
+
+    // Other key pressed - do filename completion as possible...
+    num_files  = fileList->size();
+    min_match  = strlen(filename);
+    max_match  = min_match + 1;
+    first_line = 0;
+
+    for (i = 1; i <= num_files && max_match > min_match; i ++) {
+      file = fileList->text(i);
+
+#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
+      if (strncasecmp(filename, file, min_match) == 0) {
+#else
+      if (strncmp(filename, file, min_match) == 0) {
+#endif // WIN32 || __EMX__
+        // OK, this one matches; check against the previous match
+	if (!first_line) {
+	  // First match; copy stuff over...
+	  strlcpy(matchname, file, sizeof(matchname));
+	  max_match = strlen(matchname);
+
+          // Strip trailing /, if any...
+	  if (matchname[max_match - 1] == '/') {
+	    max_match --;
+	    matchname[max_match] = '\0';
+	  }
+
+	  // And then make sure that the item is visible
+          fileList->topline(i);
+	  first_line = i;
+	} else {
+	  // Succeeding match; compare to find maximum string match...
+	  while (max_match > min_match)
+#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
+	    if (strncasecmp(file, matchname, max_match) == 0)
+#else
+	    if (strncmp(file, matchname, max_match) == 0)
+#endif // WIN32 || __EMX__
+	      break;
+	    else
+	      max_match --;
+
+          // Truncate the string as needed...
+          matchname[max_match] = '\0';
+	}
+      }
+    }
+
+    // If we have any matches, add them to the input field...
+    if (first_line > 0 && min_match == max_match &&
+        max_match == (int)strlen(fileList->text(first_line))) {
+      // This is the only possible match...
+      fileList->deselect(0);
+      fileList->select(first_line);
+      fileList->redraw();
+    } else if (max_match > min_match && first_line) {
+      // Add the matching portion...
+      fileName->replace(filename - pathname, filename - pathname + min_match,
+                        matchname);
+
+      // Highlight it with the cursor at the end of the selection so
+      // s/he can press the right arrow to accept the selection
+      // (Tab and End also do this for both cases.)
+      fileName->position(filename - pathname + max_match,
+	                 filename - pathname + min_match);
+    } else if (max_match == 0) {
+      fileList->deselect(0);
+      fileList->redraw();
+    }
+
+    // See if we need to enable the OK button...
+    if (((type_ & CREATE) || !access(fileName->value(), 0)) &&
+        (!fl_filename_isdir(fileName->value()) || (type_ & DIRECTORY))) {
+      okButton->activate();
+    } else {
+      okButton->deactivate();
+    }
+  } else {
+    // FL_Delete or FL_BackSpace
+    fileList->deselect(0);
+    fileList->redraw();
+    if (((type_ & CREATE) || !access(fileName->value(), 0)) &&
+        (!fl_filename_isdir(fileName->value()) || (type_ & DIRECTORY))) {
+      okButton->activate();
+    } else {
+      okButton->deactivate();
+    }
+  }
+}
+
+
+//
+// 'Fl_File_Chooser::filter()' - Set the filter(s) for the chooser.
+//
+
+void
+Fl_File_Chooser::filter(const char *p)		// I - Pattern(s)
+{
+  char		*copyp,				// Copy of pattern
+		*start,				// Start of pattern
+		*end;				// End of pattern
+  int		allfiles;			// Do we have a "*" pattern?
+  char		temp[1024];			// Temporary pattern string
+
+
+  // Make sure we have a pattern...
+  if (!p || !*p) p = "*";
+
+  // Copy the pattern string...
+  copyp = strdup(p);
+
+  // Separate the pattern string as necessary...
+  showChoice->clear();
+
+  for (start = copyp, allfiles = 0; start && *start; start = end) {
+    end = strchr(start, '\t');
+    if (end) *end++ = '\0';
+
+    if (strcmp(start, "*") == 0) {
+      showChoice->add(all_files_label);
+      allfiles = 1;
+    } else {
+      quote_pathname(temp, start, sizeof(temp));
+      showChoice->add(temp);
+      if (strstr(start, "(*)") != NULL) allfiles = 1;
+    }
+  }
+
+  free(copyp);
+
+  if (!allfiles) showChoice->add(all_files_label);
+
+  showChoice->add(custom_filter_label);
+
+  showChoice->value(0);
+  showChoiceCB();
+}
+
+
+//
+// 'Fl_File_Chooser::newdir()' - Make a new directory.
+//
+
+void
+Fl_File_Chooser::newdir()
+{
+  const char	*dir;		// New directory name
+  char		pathname[1024];	// Full path of directory
+
+
+  // Get a directory name from the user
+  if ((dir = fl_input(new_directory_label, NULL)) == NULL)
+    return;
+
+  // Make it relative to the current directory as needed...
+#if (defined(WIN32) && ! defined (__CYGWIN__)) || defined(__EMX__)
+  if (dir[0] != '/' && dir[0] != '\\' && dir[1] != ':')
+#else
+  if (dir[0] != '/' && dir[0] != '\\')
+#endif /* WIN32 || __EMX__ */
+    snprintf(pathname, sizeof(pathname), "%s/%s", directory_, dir);
+  else
+    strlcpy(pathname, dir, sizeof(pathname));
+
+  // Create the directory; ignore EEXIST errors...
+#if defined(WIN32) && ! defined (__CYGWIN__)
+  if (mkdir(pathname))
+#else
+  if (mkdir(pathname, 0777))
+#endif /* WIN32 */
+    if (errno != EEXIST)
+    {
+      fl_alert("%s", strerror(errno));
+      return;
+    }
+
+  // Show the new directory...
+  directory(pathname);
+}
+
+
+//
+// 'Fl_File_Chooser::preview()' - Enable or disable the preview tile.
+//
+
+void
+Fl_File_Chooser::preview(int e)// I - 1 = enable preview, 0 = disable preview
+{
+  previewButton->value(e);
+  prefs_.set("preview", e);
+
+  Fl_Group *p = previewBox->parent();
+  if (e) {
+    int w = p->w() * 2 / 3;
+    fileList->resize(fileList->x(), fileList->y(),
+                     w, fileList->h());
+    previewBox->resize(fileList->x()+w, previewBox->y(),
+                       p->w()-w, previewBox->h());
+    previewBox->show();
+    update_preview();
+  } else {
+    fileList->resize(fileList->x(), fileList->y(),
+                     p->w(), fileList->h());
+    previewBox->resize(p->x()+p->w(), previewBox->y(),
+                       0, previewBox->h());
+    previewBox->hide();
+  }
+  p->init_sizes();
+
+  fileList->parent()->redraw();
+}
+
+
+//
+// 'Fl_File_Chooser::previewCB()' - Timeout handler for the preview box.
+//
+
+void
+Fl_File_Chooser::previewCB(Fl_File_Chooser *fc) {	// I - File chooser
+  fc->update_preview();
+}
+
+
+//
+// 'Fl_File_Chooser::rescan()' - Rescan the current directory.
+//
+
+void
+Fl_File_Chooser::rescan()
+{
+  char	pathname[1024];		// New pathname for filename field
+
+
+  // Clear the current filename
+  strlcpy(pathname, directory_, sizeof(pathname));
+  if (pathname[0] && pathname[strlen(pathname) - 1] != '/') {
+    strlcat(pathname, "/", sizeof(pathname));
+  }
+//  puts("Setting fileName in rescan()");
+  fileName->value(pathname);
+
+  if (type_ & DIRECTORY)
+    okButton->activate();
+  else
+    okButton->deactivate();
+
+  // Build the file list...
+  fileList->load(directory_, sort);
+
+  // Update the preview box...
+  update_preview();
+}
+
+
+//
+// 'Fl_File_Chooser::showChoiceCB()' - Handle show selections.
+//
+
+void
+Fl_File_Chooser::showChoiceCB()
+{
+  const char	*item,			// Selected item
+		*patstart;		// Start of pattern
+  char		*patend;		// End of pattern
+  char		temp[1024];		// Temporary string for pattern
+
+
+  item = showChoice->text(showChoice->value());
+
+  if (strcmp(item, custom_filter_label) == 0) {
+    if ((item = fl_input(custom_filter_label, pattern_)) != NULL) {
+      strlcpy(pattern_, item, sizeof(pattern_));
+
+      quote_pathname(temp, item, sizeof(temp));
+      showChoice->add(temp);
+      showChoice->value(showChoice->size() - 2);
+    }
+  } else if ((patstart = strchr(item, '(')) == NULL) {
+    strlcpy(pattern_, item, sizeof(pattern_));
+  } else {
+    strlcpy(pattern_, patstart + 1, sizeof(pattern_));
+    if ((patend = strrchr(pattern_, ')')) != NULL) *patend = '\0';
+  }
+
+  fileList->filter(pattern_);
+
+  if (shown()) {
+    // Rescan the directory...
+    rescan();
+  }
+}
+
+
+//
+// 'Fl_File_Chooser::update_favorites()' - Update the favorites menu.
+//
+
+void
+Fl_File_Chooser::update_favorites()
+{
+  int		i;			// Looping var
+  char		pathname[1024],		// Pathname
+		menuname[2048];		// Menu name
+  const char	*home;			// Home directory
+
+
+  favoritesButton->clear();
+  favoritesButton->add("bla");
+  favoritesButton->clear();
+  favoritesButton->add(add_favorites_label, FL_ALT + 'a', 0);
+  favoritesButton->add(manage_favorites_label, FL_ALT + 'm', 0, 0, FL_MENU_DIVIDER);
+  favoritesButton->add(filesystems_label, FL_ALT + 'f', 0);
+    
+  if ((home = getenv("HOME")) != NULL) {
+    quote_pathname(menuname, home, sizeof(menuname));
+    favoritesButton->add(menuname, FL_ALT + 'h', 0);
+  }
+
+  for (i = 0; i < 100; i ++) {
+    sprintf(menuname, "favorite%02d", i);
+    prefs_.get(menuname, pathname, "", sizeof(pathname));
+    if (!pathname[0]) break;
+
+    quote_pathname(menuname, pathname, sizeof(menuname));
+
+    if (i < 10) favoritesButton->add(menuname, FL_ALT + '0' + i, 0);
+    else favoritesButton->add(menuname);
+  }
+
+  if (i == 100) ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate();
+}
+
+
+//
+// 'Fl_File_Chooser::update_preview()' - Update the preview box...
+//
+
+void
+Fl_File_Chooser::update_preview()
+{
+  const char		*filename;	// Current filename
+  Fl_Shared_Image	*image,		// New image
+			*oldimage;	// Old image
+  int			pbw, pbh;	// Width and height of preview box
+  int			w, h;		// Width and height of preview image
+
+
+  if (!previewButton->value()) return;
+
+  if ((filename = value()) == NULL || fl_filename_isdir(filename)) image = NULL;
+  else {
+    window->cursor(FL_CURSOR_WAIT);
+    Fl::check();
+
+    image = Fl_Shared_Image::get(filename);
+
+    if (image) {
+      window->cursor(FL_CURSOR_DEFAULT);
+      Fl::check();
+    }
+  }
+
+  oldimage = (Fl_Shared_Image *)previewBox->image();
+
+  if (oldimage) oldimage->release();
+
+  previewBox->image(0);
+
+  if (!image) {
+    FILE	*fp;
+    int		bytes;
+    char	*ptr;
+
+    if (filename) fp = fopen(filename, "rb");
+    else fp = NULL;
+
+    if (fp != NULL) {
+      // Try reading the first 1k of data for a label...
+      bytes = fread(preview_text_, 1, sizeof(preview_text_) - 1, fp);
+      preview_text_[bytes] = '\0';
+      fclose(fp);
+    } else {
+      // Assume we can't read any data...
+      preview_text_[0] = '\0';
+    }
+
+    window->cursor(FL_CURSOR_DEFAULT);
+    Fl::check();
+
+    // Scan the buffer for printable chars...
+    for (ptr = preview_text_;
+         *ptr && (isprint(*ptr & 255) || isspace(*ptr & 255));
+	 ptr ++);
+
+    if (*ptr || ptr == preview_text_) {
+      // Non-printable file, just show a big ?...
+      previewBox->label(filename ? "?" : 0);
+      previewBox->align(FL_ALIGN_CLIP);
+      previewBox->labelsize(100);
+      previewBox->labelfont(FL_HELVETICA);
+    } else {
+      // Show the first 1k of text...
+      int size = previewBox->h() / 20;
+      if (size < 6) size = 6;
+      else if (size > 14) size = 14;
+
+      previewBox->label(preview_text_);
+      previewBox->align((Fl_Align)(FL_ALIGN_CLIP | FL_ALIGN_INSIDE |
+                                   FL_ALIGN_LEFT | FL_ALIGN_TOP));
+      previewBox->labelsize((uchar)size);
+      previewBox->labelfont(FL_COURIER);
+    }
+  } else {
+    pbw = previewBox->w() - 20;
+    pbh = previewBox->h() - 20;
+
+    if (image->w() > pbw || image->h() > pbh) {
+      w   = pbw;
+      h   = w * image->h() / image->w();
+
+      if (h > pbh) {
+	h = pbh;
+	w = h * image->w() / image->h();
+      }
+
+      oldimage = (Fl_Shared_Image *)image->copy(w, h);
+      previewBox->image((Fl_Image *)oldimage);
+
+      image->release();
+    } else {
+      previewBox->image((Fl_Image *)image);
+    }
+
+    previewBox->align(FL_ALIGN_CLIP);
+    previewBox->label(0);
+  }
+
+  previewBox->redraw();
+}
+
+
+//
+// 'Fl_File_Chooser::value()' - Return a selected filename.
+//
+
+const char *			// O - Filename or NULL
+Fl_File_Chooser::value(int f)	// I - File number
+{
+  int		i;		// Looping var
+  int		fcount;		// Number of selected files
+  const char	*name;		// Current filename
+  static char	pathname[1024];	// Filename + directory
+
+
+  name = fileName->value();
+
+  if (!(type_ & MULTI)) {
+    // Return the filename in the filename field...
+    if (!name || !name[0]) return NULL;
+    else return name;
+  }
+
+  // Return a filename from the list...
+  for (i = 1, fcount = 0; i <= fileList->size(); i ++)
+    if (fileList->selected(i)) {
+      // See if this file is a selected file/directory...
+      name = fileList->text(i);
+
+      fcount ++;
+
+      if (fcount == f) {
+	if (directory_[0]) {
+	  snprintf(pathname, sizeof(pathname), "%s/%s", directory_, name);
+	} else {
+	  strlcpy(pathname, name, sizeof(pathname));
+	}
+
+	return pathname;
+      }
+    }
+
+  // If nothing is selected, use the filename field...
+  if (!name || !name[0]) return NULL;
+  else return name;
+}
+
+
+//
+// 'Fl_File_Chooser::value()' - Set the current filename.
+//
+
+void
+Fl_File_Chooser::value(const char *filename)
+					// I - Filename + directory
+{
+  int	i,				// Looping var
+  	fcount;				// Number of items in list
+  char	*slash;				// Directory separator
+  char	pathname[1024];			// Local copy of filename
+
+
+//  printf("Fl_File_Chooser::value(\"%s\")\n", filename == NULL ? "(null)" : filename);
+
+  // See if the filename is the "My System" directory...
+  if (filename == NULL || !filename[0]) {
+    // Yes, just change the current directory...
+    directory(filename);
+    fileName->value("");
+    okButton->deactivate();
+    return;
+  }
+
+#ifdef WIN32
+  // See if the filename contains backslashes...
+  char	fixpath[1024];			// Path with slashes converted
+  if (strchr(filename, '\\')) {
+    // Convert backslashes to slashes...
+    strlcpy(fixpath, filename, sizeof(fixpath));
+
+    for (slash = strchr(fixpath, '\\'); slash; slash = strchr(slash + 1, '\\'))
+      *slash = '/';
+
+    filename = fixpath;
+  }
+#endif // WIN32
+
+  // See if there is a directory in there...
+  fl_filename_absolute(pathname, sizeof(pathname), filename);
+
+  if ((slash = strrchr(pathname, '/')) != NULL) {
+    // Yes, change the display to the directory... 
+    if (!fl_filename_isdir(pathname)) *slash++ = '\0';
+
+    directory(pathname);
+    if (*slash == '/') slash = pathname;
+  } else {
+    directory(".");
+    slash = pathname;
+  }
+
+  // Set the input field to the absolute path...
+  if (slash > pathname) slash[-1] = '/';
+
+  fileName->value(pathname);
+  fileName->position(0, strlen(pathname));
+  okButton->activate();
+
+  // Then find the file in the file list and select it...
+  fcount = fileList->size();
+
+  fileList->deselect(0);
+  fileList->redraw();
+
+  for (i = 1; i <= fcount; i ++)
+#if defined(WIN32) || defined(__EMX__)
+    if (strcasecmp(fileList->text(i), slash) == 0) {
+#else
+    if (strcmp(fileList->text(i), slash) == 0) {
+#endif // WIN32 || __EMX__
+//      printf("Selecting line %d...\n", i);
+      fileList->topline(i);
+      fileList->select(i);
+      break;
+    }
+}
+
+
+//
+// 'compare_dirnames()' - Compare two directory names.
+//
+
+static int
+compare_dirnames(const char *a, const char *b) {
+  int alen, blen;
+
+  // Get length of each string...
+  alen = strlen(a) - 1;
+  blen = strlen(b) - 1;
+
+  if (alen < 0 || blen < 0) return alen - blen;
+
+  // Check for trailing slashes...
+  if (a[alen] != '/') alen ++;
+  if (b[blen] != '/') blen ++;
+
+  // If the lengths aren't the same, then return the difference...
+  if (alen != blen) return alen - blen;
+
+  // Do a comparison of the first N chars (alen == blen at this point)...
+#ifdef WIN32
+  return strncasecmp(a, b, alen);
+#else
+  return strncmp(a, b, alen);
+#endif // WIN32
+}
+
+
+//
+// 'quote_pathname()' - Quote a pathname for a menu.
+//
+
+static void
+quote_pathname(char       *dst,		// O - Destination string
+               const char *src,		// I - Source string
+	       int        dstsize)	// I - Size of destination string
+{
+  dstsize --;
+
+  while (*src && dstsize > 1) {
+    if (*src == '\\') {
+      // Convert backslash to forward slash...
+      *dst++ = '\\';
+      *dst++ = '/';
+      src ++;
+    } else {
+      if (*src == '/') *dst++ = '\\';
+
+      *dst++ = *src++;
+    }
+  }
+
+  *dst = '\0';
+}
+
+
+//
+// 'unquote_pathname()' - Unquote a pathname from a menu.
+//
+
+static void
+unquote_pathname(char       *dst,	// O - Destination string
+                 const char *src,	// I - Source string
+	         int        dstsize)	// I - Size of destination string
+{
+  dstsize --;
+
+  while (*src && dstsize > 1) {
+    if (*src == '\\') src ++;
+    *dst++ = *src++;
+  }
+
+  *dst = '\0';
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_File_Icon.cxx b/Utilities/FLTK/src/Fl_File_Icon.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d1791d476bbbcbd82f7b16cdd537fb6d8ecc77c9
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_File_Icon.cxx
@@ -0,0 +1,485 @@
+//
+// "$Id$"
+//
+// Fl_File_Icon routines.
+//
+// KDE icon code donated by Maarten De Boer.
+//
+// Copyright 1999-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_File_Icon::Fl_File_Icon()       - Create a new file icon.
+//   Fl_File_Icon::~Fl_File_Icon()      - Remove a file icon.
+//   Fl_File_Icon::add()               - Add data to an icon.
+//   Fl_File_Icon::find()              - Find an icon based upon a given file.
+//   Fl_File_Icon::draw()              - Draw an icon.
+//   Fl_File_Icon::label()             - Set the widgets label to an icon.
+//   Fl_File_Icon::labeltype()         - Draw the icon label.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
+#  include <io.h>
+#  define F_OK	0
+#else
+#  include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+#include <FL/Fl_File_Icon.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <FL/filename.H>
+
+
+//
+// Define missing POSIX/XPG4 macros as needed...
+//
+
+#ifndef S_ISDIR
+#  define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#  define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#  define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#  define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#endif /* !S_ISDIR */
+
+
+//
+// Icon cache...
+//
+
+Fl_File_Icon	*Fl_File_Icon::first_ = (Fl_File_Icon *)0;
+
+
+//
+// 'Fl_File_Icon::Fl_File_Icon()' - Create a new file icon.
+//
+
+Fl_File_Icon::Fl_File_Icon(const char *p,	/* I - Filename pattern */
+                	   int        t,	/* I - File type */
+			   int        nd,	/* I - Number of data values */
+			   short      *d)	/* I - Data values */
+{
+  // Initialize the pattern and type...
+  pattern_ = p;
+  type_    = t;
+
+  // Copy icon data as needed...
+  if (nd)
+  {
+    num_data_   = nd;
+    alloc_data_ = nd + 1;
+    data_       = (short *)calloc(sizeof(short), nd + 1);
+    memcpy(data_, d, nd * sizeof(short));
+  }
+  else
+  {
+    num_data_   = 0;
+    alloc_data_ = 0;
+  }
+
+  // And add the icon to the list of icons...
+  next_  = first_;
+  first_ = this;
+}
+
+
+//
+// 'Fl_File_Icon::~Fl_File_Icon()' - Remove a file icon.
+//
+
+Fl_File_Icon::~Fl_File_Icon()
+{
+  Fl_File_Icon	*current,	// Current icon in list
+		*prev;		// Previous icon in list
+
+
+  // Find the icon in the list...
+  for (current = first_, prev = (Fl_File_Icon *)0;
+       current != this && current != (Fl_File_Icon *)0;
+       prev = current, current = current->next_);
+
+  // Remove the icon from the list as needed...
+  if (current)
+  {
+    if (prev)
+      prev->next_ = current->next_;
+    else
+      first_ = current->next_;
+  }
+
+  // Free any memory used...
+  if (alloc_data_)
+    free(data_);
+}
+
+
+//
+// 'Fl_File_Icon::add()' - Add data to an icon.
+//
+
+short *				// O - Pointer to new data value
+Fl_File_Icon::add(short d)	// I - Data to add
+{
+  short	*dptr;			// Pointer to new data value
+
+
+  // Allocate/reallocate memory as needed
+  if ((num_data_ + 1) >= alloc_data_)
+  {
+    alloc_data_ += 128;
+
+    if (alloc_data_ == 128)
+      dptr = (short *)malloc(sizeof(short) * alloc_data_);
+    else
+      dptr = (short *)realloc(data_, sizeof(short) * alloc_data_);
+
+    if (dptr == NULL)
+      return (NULL);
+
+    data_ = dptr;
+  }
+
+  // Store the new data value and return
+  data_[num_data_++] = d;
+  data_[num_data_]   = END;
+
+  return (data_ + num_data_ - 1);
+}
+
+
+//
+// 'Fl_File_Icon::find()' - Find an icon based upon a given file.
+//
+
+Fl_File_Icon *				// O - Matching file icon or NULL
+Fl_File_Icon::find(const char *filename,// I - Name of file */
+                   int        filetype)	// I - Enumerated file type
+{
+  Fl_File_Icon	*current;		// Current file in list
+#ifndef WIN32
+  struct stat	fileinfo;		// Information on file
+#endif // !WIN32
+  const char	*name;			// Base name of filename
+
+
+  // Get file information if needed...
+  if (filetype == ANY)
+  {
+#ifdef WIN32
+    if (filename[strlen(filename) - 1] == '/')
+      filetype = DIRECTORY;
+    else if (fl_filename_isdir(filename))
+      filetype = DIRECTORY;
+    else
+      filetype = PLAIN;
+#else
+    if (!stat(filename, &fileinfo))
+    {
+      if (S_ISDIR(fileinfo.st_mode))
+        filetype = DIRECTORY;
+#  ifdef S_IFIFO
+      else if (S_ISFIFO(fileinfo.st_mode))
+        filetype = FIFO;
+#  endif // S_IFIFO
+#  if defined(S_ICHR) && defined(S_IBLK)
+      else if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode))
+        filetype = DEVICE;
+#  endif // S_ICHR && S_IBLK
+#  ifdef S_ILNK
+      else if (S_ISLNK(fileinfo.st_mode))
+        filetype = LINK;
+#  endif // S_ILNK
+      else
+        filetype = PLAIN;
+    }
+    else
+      filetype = PLAIN;
+#endif // WIN32
+  }
+
+  // Look at the base name in the filename
+  name = fl_filename_name(filename);
+
+  // Loop through the available file types and return any match that
+  // is found...
+  for (current = first_; current != (Fl_File_Icon *)0; current = current->next_)
+    if ((current->type_ == filetype || current->type_ == ANY) &&
+        (fl_filename_match(filename, current->pattern_) ||
+	 fl_filename_match(name, current->pattern_)))
+      break;
+
+  // Return the match (if any)...
+  return (current);
+}
+
+
+//
+// 'Fl_File_Icon::draw()' - Draw an icon.
+//
+
+void
+Fl_File_Icon::draw(int      x,		// I - Upper-lefthand X
+        	   int      y,		// I - Upper-lefthand Y
+		   int      w,		// I - Width of bounding box
+		   int      h,		// I - Height of bounding box
+        	   Fl_Color ic,		// I - Icon color...
+        	   int      active)	// I - Active or inactive?
+{
+  Fl_Color	c,		// Current color
+		oc;		// Outline color
+  short		*d,		// Pointer to data
+		*dend;		// End of data...
+  short		*prim;		// Pointer to start of primitive...
+  double	scale;		// Scale of icon
+
+
+  // Don't try to draw a NULL array!
+  if (num_data_ == 0)
+    return;
+
+  // Setup the transform matrix as needed...
+  scale = w < h ? w : h;
+
+  fl_push_matrix();
+  fl_translate((float)x + 0.5 * ((float)w - scale),
+               (float)y + 0.5 * ((float)h + scale));
+  fl_scale(scale, -scale);
+
+  // Loop through the array until we see an unmatched END...
+  d    = data_;
+  dend = data_ + num_data_;
+  prim = NULL;
+  c    = ic;
+
+  if (active)
+    fl_color(c);
+  else
+    fl_color(fl_inactive(c));
+
+  while (d < dend)
+    switch (*d)
+    {
+      case END :
+          if (prim)
+            switch (*prim)
+	    {
+	      case LINE :
+		  fl_end_line();
+		  break;
+
+	      case CLOSEDLINE :
+		  fl_end_loop();
+		  break;
+
+	      case POLYGON :
+		  fl_end_complex_polygon();
+		  break;
+
+	      case OUTLINEPOLYGON :
+		  fl_end_complex_polygon();
+
+        	  oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | 
+	                	  ((unsigned short *)prim)[2]);
+                  if (active)
+		  {
+                    if (oc == FL_ICON_COLOR)
+		      fl_color(ic);
+		    else
+		      fl_color(oc);
+		  }
+		  else
+		  {
+                    if (oc == FL_ICON_COLOR)
+		      fl_color(fl_inactive(ic));
+		    else
+		      fl_color(fl_inactive(oc));
+		  }
+
+		  fl_begin_loop();
+
+		  prim += 3;
+		  while (*prim == VERTEX)
+		  {
+		    fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001);
+		    prim += 3;
+		  }
+
+        	  fl_end_loop();
+		  fl_color(c);
+		  break;
+	    }
+
+          prim = NULL;
+	  d ++;
+	  break;
+
+      case COLOR :
+          c = (Fl_Color)((((unsigned short *)d)[1] << 16) | 
+	                   ((unsigned short *)d)[2]);
+
+          if (c == FL_ICON_COLOR)
+	    c = ic;
+
+          if (!active)
+	    c = fl_inactive(c);
+
+          fl_color(c);
+	  d += 3;
+	  break;
+
+      case LINE :
+          prim = d;
+	  d ++;
+	  fl_begin_line();
+	  break;
+
+      case CLOSEDLINE :
+          prim = d;
+	  d ++;
+	  fl_begin_loop();
+	  break;
+
+      case POLYGON :
+          prim = d;
+	  d ++;
+	  fl_begin_complex_polygon();
+	  break;
+
+      case OUTLINEPOLYGON :
+          prim = d;
+	  d += 3;
+	  fl_begin_complex_polygon();
+	  break;
+
+      case VERTEX :
+          if (prim)
+	    fl_vertex(d[1] * 0.0001, d[2] * 0.0001);
+	  d += 3;
+	  break;
+
+      default : // Ignore invalid data...
+          d ++;
+    }
+
+  // If we still have an open primitive, close it...
+  if (prim)
+    switch (*prim)
+    {
+      case LINE :
+	  fl_end_line();
+	  break;
+
+      case CLOSEDLINE :
+	  fl_end_loop();
+	  break;
+
+      case POLYGON :
+	  fl_end_polygon();
+	  break;
+
+      case OUTLINEPOLYGON :
+	  fl_end_polygon();
+
+          oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | 
+	                  ((unsigned short *)prim)[2]);
+          if (active)
+	  {
+            if (oc == FL_ICON_COLOR)
+	      fl_color(ic);
+	    else
+	      fl_color(oc);
+	  }
+	  else
+	  {
+            if (oc == FL_ICON_COLOR)
+	      fl_color(fl_inactive(ic));
+	    else
+	      fl_color(fl_inactive(oc));
+	  }
+
+	  fl_begin_loop();
+
+	  prim += 3;
+	  while (*prim == VERTEX)
+	  {
+	    fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001);
+	    prim += 3;
+	  }
+
+          fl_end_loop();
+	  fl_color(c);
+	  break;
+    }
+
+  // Restore the transform matrix
+  fl_pop_matrix();
+}
+
+
+//
+// 'Fl_File_Icon::label()' - Set the widget's label to an icon.
+//
+
+void
+Fl_File_Icon::label(Fl_Widget *w)	// I - Widget to label
+{
+  Fl::set_labeltype(_FL_ICON_LABEL, labeltype, 0);
+  w->label(_FL_ICON_LABEL, (const char*)this);
+}
+
+
+//
+// 'Fl_File_Icon::labeltype()' - Draw the icon label.
+//
+
+void
+Fl_File_Icon::labeltype(const Fl_Label *o,	// I - Label data
+                	int            x,	// I - X position of label
+			int            y,	// I - Y position of label
+			int            w,	// I - Width of label
+			int            h,	// I - Height of label
+			Fl_Align       a)	// I - Label alignment (not used)
+{
+  Fl_File_Icon *icon;			// Pointer to icon data
+
+
+  (void)a;
+
+  icon = (Fl_File_Icon *)(o->value);
+  if (icon) icon->draw(x, y, w, h, (Fl_Color)(o->color));
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_File_Icon2.cxx b/Utilities/FLTK/src/Fl_File_Icon2.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..29ab501918be48e8cac59d240214a92f42e013b6
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_File_Icon2.cxx
@@ -0,0 +1,1015 @@
+//
+// "$Id$"
+//
+// Fl_File_Icon system icon routines.
+//
+// KDE icon code donated by Maarten De Boer.
+//
+// Copyright 1999-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_File_Icon::load()              - Load an icon file...
+//   Fl_File_Icon::load_fti()          - Load an SGI-format FTI file...
+//   Fl_File_Icon::load_image()        - Load an image icon file...
+//   Fl_File_Icon::load_system_icons() - Load the standard system icons/filetypes.
+//   load_kde_icons()                  - Load KDE icon files.
+//   load_kde_mimelnk()                - Load a KDE "mimelnk" file.
+//   kde_to_fltk_pattern()             - Convert a KDE pattern to a FLTK pattern.
+//   get_kde_val()                     - Get a KDE value.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <ctype.h>
+#include <errno.h>
+#include <FL/math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  include <io.h>
+#  define F_OK	0
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define access _access
+#else
+#  include <unistd.h>
+#endif // WIN32
+
+#include <FL/Fl_File_Icon.H>
+#include <FL/Fl_Shared_Image.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <FL/filename.H>
+
+
+//
+// Define missing POSIX/XPG4 macros as needed...
+//
+
+#ifndef S_ISDIR
+#  define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#  define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#  define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#  define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#endif /* !S_ISDIR */
+
+
+//
+// Local functions...
+//
+
+static void	load_kde_icons(const char *directory, const char *icondir);
+static void	load_kde_mimelnk(const char *filename, const char *icondir);
+static char	*kde_to_fltk_pattern(const char *kdepattern);
+static char	*get_kde_val(char *str, const char *key);
+
+
+//
+// Local globals...
+//
+
+static const char *kdedir = NULL;
+
+
+//
+// 'Fl_File_Icon::load()' - Load an icon file...
+//
+
+void
+Fl_File_Icon::load(const char *f)	// I - File to read from
+{
+  int		i;			// Load status...
+  const char	*ext;			// File extension
+
+
+  ext = fl_filename_ext(f);
+
+  if (ext && strcmp(ext, ".fti") == 0)
+    i = load_fti(f);
+  else
+    i = load_image(f);
+
+  if (i)
+  {
+    Fl::warning("Fl_File_Icon::load(): Unable to load icon file \"%s\".", f);
+    return;
+  }
+}
+
+
+//
+// 'Fl_File_Icon::load_fti()' - Load an SGI-format FTI file...
+//
+
+int					// O - 0 on success, non-zero on error
+Fl_File_Icon::load_fti(const char *fti)	// I - File to read from
+{
+  FILE	*fp;			// File pointer
+  int	ch;			// Current character
+  char	command[255],		// Command string ("vertex", etc.)
+	params[255],		// Parameter string ("10.0,20.0", etc.)
+	*ptr;			// Pointer into strings
+  int	outline;		// Outline polygon
+
+
+  // Try to open the file...
+  if ((fp = fopen(fti, "rb")) == NULL)
+  {
+    Fl::error("Fl_File_Icon::load_fti(): Unable to open \"%s\" - %s",
+              fti, strerror(errno));
+    return -1;
+  }
+
+  // Read the entire file, adding data as needed...
+  outline = 0;
+
+  while ((ch = getc(fp)) != EOF)
+  {
+    // Skip whitespace
+    if (isspace(ch))
+      continue;
+
+    // Skip comments starting with "#"...
+    if (ch == '#')
+    {
+      while ((ch = getc(fp)) != EOF)
+        if (ch == '\n')
+	  break;
+
+      if (ch == EOF)
+        break;
+      else
+        continue;
+    }
+
+    // OK, this character better be a letter...
+    if (!isalpha(ch))
+    {
+      Fl::error("Fl_File_Icon::load_fti(): Expected a letter at file position %ld (saw '%c')",
+                ftell(fp) - 1, ch);
+      break;
+    }
+
+    // Scan the command name...
+    ptr    = command;
+    *ptr++ = ch;
+
+    while ((ch = getc(fp)) != EOF)
+    {
+      if (ch == '(')
+        break;
+      else if (ptr < (command + sizeof(command) - 1))
+        *ptr++ = ch;
+    }
+
+    *ptr++ = '\0';
+
+    // Make sure we stopped on a parenthesis...
+    if (ch != '(')
+    {
+      Fl::error("Fl_File_Icon::load_fti(): Expected a ( at file position %ld (saw '%c')",
+                ftell(fp) - 1, ch);
+      break;
+    }
+
+    // Scan the parameters...
+    ptr = params;
+
+    while ((ch = getc(fp)) != EOF)
+    {
+      if (ch == ')')
+        break;
+      else if (ptr < (params + sizeof(params) - 1))
+        *ptr++ = ch;
+    }
+
+    *ptr++ = '\0';
+
+    // Make sure we stopped on a parenthesis...
+    if (ch != ')')
+    {
+      Fl::error("Fl_File_Icon::load_fti(): Expected a ) at file position %ld (saw '%c')",
+                ftell(fp) - 1, ch);
+      break;
+    }
+
+    // Make sure the next character is a semicolon...
+    if ((ch = getc(fp)) != ';')
+    {
+      Fl::error("Fl_File_Icon::load_fti(): Expected a ; at file position %ld (saw '%c')",
+                ftell(fp) - 1, ch);
+      break;
+    }
+
+    // Now process the command...
+    if (strcmp(command, "color") == 0)
+    {
+      // Set the color; for negative colors blend the two primaries to
+      // produce a composite color.  Also, the following symbolic color
+      // names are understood:
+      //
+      //     name           FLTK color
+      //     -------------  ----------
+      //     iconcolor      FL_ICON_COLOR; mapped to the icon color in
+      //                    Fl_File_Icon::draw()
+      //     shadowcolor    FL_DARK3
+      //     outlinecolor   FL_BLACK
+      if (strcmp(params, "iconcolor") == 0)
+        add_color(FL_ICON_COLOR);
+      else if (strcmp(params, "shadowcolor") == 0)
+        add_color(FL_DARK3);
+      else if (strcmp(params, "outlinecolor") == 0)
+        add_color(FL_BLACK);
+      else
+      {
+        int c = atoi(params);	// Color value
+
+
+        if (c < 0)
+	{
+	  // Composite color; compute average...
+	  c = -c;
+	  add_color(fl_color_average((Fl_Color)(c >> 4),
+	                             (Fl_Color)(c & 15), 0.5f));
+	}
+	else
+	  add_color((Fl_Color)c);
+      }
+    }
+    else if (strcmp(command, "bgnline") == 0)
+      add(LINE);
+    else if (strcmp(command, "bgnclosedline") == 0)
+      add(CLOSEDLINE);
+    else if (strcmp(command, "bgnpolygon") == 0)
+      add(POLYGON);
+    else if (strcmp(command, "bgnoutlinepolygon") == 0)
+    {
+      add(OUTLINEPOLYGON);
+      outline = add(0) - data_;
+      add(0);
+    }
+    else if (strcmp(command, "endoutlinepolygon") == 0 && outline)
+    {
+      unsigned cval; // Color value
+
+      // Set the outline color; see above for valid values...
+      if (strcmp(params, "iconcolor") == 0)
+        cval = FL_ICON_COLOR;
+      else if (strcmp(params, "shadowcolor") == 0)
+        cval = FL_DARK3;
+      else if (strcmp(params, "outlinecolor") == 0)
+        cval = FL_BLACK;
+      else
+      {
+        int c = atoi(params);	// Color value
+
+
+        if (c < 0)
+	{
+	  // Composite color; compute average...
+	  c = -c;
+	  cval = fl_color_average((Fl_Color)(c >> 4), (Fl_Color)(c & 15), 0.5f);
+	}
+	else
+	  cval = c;
+      }
+
+      // Store outline color...
+      data_[outline]     = cval >> 16;
+      data_[outline + 1] = cval;
+
+      outline = 0;
+      add(END);
+    }
+    else if (strncmp(command, "end", 3) == 0)
+      add(END);
+    else if (strcmp(command, "vertex") == 0)
+    {
+      float x, y;		// Coordinates of vertex
+
+
+      if (sscanf(params, "%f,%f", &x, &y) != 2)
+        break;
+
+      add_vertex((short)(int)rint(x * 100.0), (short)(int)rint(y * 100.0));
+    }
+    else
+    {
+      Fl::error("Fl_File_Icon::load_fti(): Unknown command \"%s\" at file position %ld.",
+                command, ftell(fp) - 1);
+      break;
+    }
+  }
+
+  // Close the file and return...
+  fclose(fp);
+
+#ifdef DEBUG
+  printf("Icon File \"%s\":\n", fti);
+  for (int i = 0; i < num_data_; i ++)
+    printf("    %d,\n", data_[i]);
+#endif /* DEBUG */
+
+  return 0;
+}
+
+
+//
+// 'Fl_File_Icon::load_image()' - Load an image icon file...
+//
+
+int					// O - 0 on success, non-0 on error
+Fl_File_Icon::load_image(const char *ifile)	// I - File to read from
+{
+  Fl_Shared_Image	*img;		// Image file
+
+
+  img = Fl_Shared_Image::get(ifile);
+  if (!img || !img->count() || !img->w() || !img->h()) return -1;
+
+  if (img->count() == 1) {
+    int		x, y;		// X & Y in image
+    int		startx;		// Starting X coord
+    Fl_Color	c,		// Current color
+		temp;		// Temporary color
+    const uchar *row;		// Pointer into image
+
+
+    // Loop through grayscale or RGB image...
+    for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += img->ld())
+    {
+      for (x = 0, startx = 0, c = (Fl_Color)-1;
+           x < img->w();
+	   x ++, row += img->d())
+      {
+	switch (img->d())
+	{
+          case 1 :
+              temp = fl_rgb_color(row[0], row[0], row[0]);
+	      break;
+          case 2 :
+	      if (row[1] > 127)
+        	temp = fl_rgb_color(row[0], row[0], row[0]);
+	      else
+		temp = (Fl_Color)-1;
+	      break;
+	  case 3 :
+              temp = fl_rgb_color(row[0], row[1], row[2]);
+	      break;
+	  default :
+	      if (row[3] > 127)
+        	temp = fl_rgb_color(row[0], row[1], row[2]);
+	      else
+		temp = (Fl_Color)-1;
+	      break;
+	}
+
+	if (temp != c)
+	{
+	  if (x > startx && c != (Fl_Color)-1)
+	  {
+	    add_color(c);
+	    add(POLYGON);
+	    add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
+	    add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
+	    add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
+	    add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
+	    add(END);
+	  }
+
+          c      = temp;
+	  startx = x;
+	}
+      }
+
+      if (x > startx && c != (Fl_Color)-1)
+      {
+	add_color(c);
+	add(POLYGON);
+	add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
+	add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
+	add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
+	add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
+	add(END);
+      }
+    }
+  } else {
+    int		i, j;			// Looping vars
+    int		ch;			// Current character
+    int		newch;			// New character
+    int		bg;			// Background color
+    char	val[16];		// Color value
+    const char	*lineptr,		// Pointer into line
+		*const*ptr;		// Pointer into data array
+    int		ncolors,		// Number of colors
+		chars_per_color;	// Characters per color
+    Fl_Color	*colors;		// Colors
+    int		red, green, blue;	// Red, green, and blue values
+    int		x, y;			// X & Y in image
+    int		startx;			// Starting X coord
+
+
+    // Get the pixmap data...
+    ptr = img->data();
+    sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);
+
+    colors = new Fl_Color[1 << (chars_per_color * 8)];
+
+    // Read the colormap...
+    memset(colors, 0, sizeof(Fl_Color) << (chars_per_color * 8));
+    bg = ' ';
+
+    ptr ++;
+
+    if (ncolors < 0) {
+      // Read compressed colormap...
+      const uchar *cmapptr;
+
+      ncolors = -ncolors;
+
+      for (i = 0, cmapptr = (const uchar *)*ptr; i < ncolors; i ++, cmapptr += 4)
+        colors[cmapptr[0]] = fl_rgb_color(cmapptr[1], cmapptr[2], cmapptr[3]);
+
+      ptr ++;
+    } else {
+      for (i = 0; i < ncolors; i ++, ptr ++) {
+	// Get the color's character
+	lineptr = *ptr;
+	ch      = *lineptr++;
+
+        if (chars_per_color > 1) ch = (ch << 8) | *lineptr++;
+
+	// Get the color value...
+	if ((lineptr = strstr(lineptr, "c ")) == NULL) {
+	  // No color; make this black...
+	  colors[ch] = FL_BLACK;
+	} else if (lineptr[2] == '#') {
+	  // Read the RGB triplet...
+	  lineptr += 3;
+	  for (j = 0; j < 12; j ++)
+            if (!isxdigit(lineptr[j]))
+	      break;
+
+	  switch (j) {
+            case 0 :
+		bg = ch;
+	    default :
+		red = green = blue = 0;
+		break;
+
+            case 3 :
+		val[0] = lineptr[0];
+		val[1] = '\0';
+		red = 255 * strtol(val, NULL, 16) / 15;
+
+		val[0] = lineptr[1];
+		val[1] = '\0';
+		green = 255 * strtol(val, NULL, 16) / 15;
+
+		val[0] = lineptr[2];
+		val[1] = '\0';
+		blue = 255 * strtol(val, NULL, 16) / 15;
+		break;
+
+            case 6 :
+            case 9 :
+            case 12 :
+		j /= 3;
+
+		val[0] = lineptr[0];
+		val[1] = lineptr[1];
+		val[2] = '\0';
+		red = strtol(val, NULL, 16);
+
+		val[0] = lineptr[j + 0];
+		val[1] = lineptr[j + 1];
+		val[2] = '\0';
+		green = strtol(val, NULL, 16);
+
+		val[0] = lineptr[2 * j + 0];
+		val[1] = lineptr[2 * j + 1];
+		val[2] = '\0';
+		blue = strtol(val, NULL, 16);
+		break;
+	  }
+
+	  colors[ch] = fl_rgb_color((uchar)red, (uchar)green, (uchar)blue);
+	} else {
+	  // Read a color name...
+	  if (strncasecmp(lineptr + 2, "white", 5) == 0) colors[ch] = FL_WHITE;
+	  else if (strncasecmp(lineptr + 2, "black", 5) == 0) colors[ch] = FL_BLACK;
+	  else if (strncasecmp(lineptr + 2, "none", 4) == 0) {
+            colors[ch] = FL_BLACK;
+	    bg = ch;
+	  } else colors[ch] = FL_GRAY;
+	}
+      }
+    }
+
+    // Read the image data...
+    for (y = 0; y < img->h(); y ++, ptr ++) {
+      lineptr = *ptr;
+      startx  = 0;
+      ch      = bg;
+
+      for (x = 0; x < img->w(); x ++) {
+	newch = *lineptr++;
+
+        if (chars_per_color > 1) newch = (newch << 8) | *lineptr++;
+
+	if (newch != ch) {
+	  if (ch != bg) {
+            add_color(colors[ch]);
+	    add(POLYGON);
+	    add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
+	    add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
+	    add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
+	    add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
+	    add(END);
+          }
+
+	  ch     = newch;
+	  startx = x;
+	}
+      }
+
+      if (ch != bg) {
+	add_color(colors[ch]);
+	add(POLYGON);
+	add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
+	add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
+	add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
+	add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
+	add(END);
+      }
+    }
+
+    // Free the colormap...
+    delete[] colors;
+  }
+
+  img->release();
+
+#ifdef DEBUG
+  printf("Icon File \"%s\":\n", xpm);
+  for (i = 0; i < num_data_; i ++)
+    printf("    %d,\n", data_[i]);
+#endif // DEBUG
+
+  return 0;
+}
+
+
+//
+// 'Fl_File_Icon::load_system_icons()' - Load the standard system icons/filetypes.
+
+void
+Fl_File_Icon::load_system_icons(void) {
+  int		i;		// Looping var
+  Fl_File_Icon	*icon;		// New icons
+  char		filename[1024];	// Filename
+  char		icondir[1024];	// Icon directory
+  static int	init = 0;	// Have the icons been initialized?
+  const char * const icondirs[] = {
+		  "Bluecurve",	// Icon directories to look for, in order
+		  "crystalsvg",
+		  "default.kde",
+		  "hicolor",
+		  NULL
+		};
+  static short	plain[] = {	// Plain file icon
+		  COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
+		  VERTEX, 2000, 1000, VERTEX, 2000, 9000,
+		  VERTEX, 6000, 9000, VERTEX, 8000, 7000,
+		  VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
+		  VERTEX, 6000, 9000, VERTEX, 6000, 7000,
+		  VERTEX, 8000, 7000, END,
+		  COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
+		  VERTEX, 8000, 7000, VERTEX, 8000, 1000,
+		  VERTEX, 2000, 1000, END, LINE, VERTEX, 3000, 7000,
+		  VERTEX, 5000, 7000, END, LINE, VERTEX, 3000, 6000,
+		  VERTEX, 5000, 6000, END, LINE, VERTEX, 3000, 5000,
+		  VERTEX, 7000, 5000, END, LINE, VERTEX, 3000, 4000,
+		  VERTEX, 7000, 4000, END, LINE, VERTEX, 3000, 3000,
+		  VERTEX, 7000, 3000, END, LINE, VERTEX, 3000, 2000,
+		  VERTEX, 7000, 2000, END, 
+		  END
+		};
+  static short	image[] = {	// Image file icon
+		  COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
+		  VERTEX, 2000, 1000, VERTEX, 2000, 9000,
+		  VERTEX, 6000, 9000, VERTEX, 8000, 7000,
+		  VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
+		  VERTEX, 6000, 9000, VERTEX, 6000, 7000,
+		  VERTEX, 8000, 7000, END,
+		  COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
+		  VERTEX, 8000, 7000, VERTEX, 8000, 1000,
+		  VERTEX, 2000, 1000, END,
+		  COLOR, 0, FL_RED, POLYGON, VERTEX, 3500, 2500,
+		  VERTEX, 3000, 3000, VERTEX, 3000, 4000,
+		  VERTEX, 3500, 4500, VERTEX, 4500, 4500,
+		  VERTEX, 5000, 4000, VERTEX, 5000, 3000,
+		  VERTEX, 4500, 2500, END,
+		  COLOR, 0, FL_GREEN, POLYGON, VERTEX, 5500, 2500,
+		  VERTEX, 5000, 3000, VERTEX, 5000, 4000,
+		  VERTEX, 5500, 4500, VERTEX, 6500, 4500,
+		  VERTEX, 7000, 4000, VERTEX, 7000, 3000,
+		  VERTEX, 6500, 2500, END,
+		  COLOR, 0, FL_BLUE, POLYGON, VERTEX, 4500, 3500,
+		  VERTEX, 4000, 4000, VERTEX, 4000, 5000,
+		  VERTEX, 4500, 5500, VERTEX, 5500, 5500,
+		  VERTEX, 6000, 5000, VERTEX, 6000, 4000,
+		  VERTEX, 5500, 3500, END,
+		  END
+		};
+  static short	dir[] = {	// Directory icon
+		  COLOR, -1, -1, POLYGON, VERTEX, 1000, 1000,
+		  VERTEX, 1000, 7500,  VERTEX, 9000, 7500,
+		  VERTEX, 9000, 1000, END,
+		  POLYGON, VERTEX, 1000, 7500, VERTEX, 2500, 9000,
+		  VERTEX, 5000, 9000, VERTEX, 6500, 7500, END,
+		  COLOR, 0, FL_WHITE, LINE, VERTEX, 1500, 1500,
+		  VERTEX, 1500, 7000, VERTEX, 9000, 7000, END,
+		  COLOR, 0, FL_BLACK, LINE, VERTEX, 9000, 7500,
+		  VERTEX, 9000, 1000, VERTEX, 1000, 1000, END,
+		  COLOR, 0, FL_GRAY, LINE, VERTEX, 1000, 1000,
+		  VERTEX, 1000, 7500, VERTEX, 2500, 9000,
+		  VERTEX, 5000, 9000, VERTEX, 6500, 7500,
+		  VERTEX, 9000, 7500, END,
+		  END
+		};
+
+
+  // Add symbols if they haven't been added already...
+  if (!init) {
+    // This method requires the images library...
+    fl_register_images();
+
+    if (!kdedir) {
+      // Figure out where KDE is installed...
+      if ((kdedir = getenv("KDEDIR")) == NULL) {
+        if (!access("/opt/kde", F_OK)) kdedir = "/opt/kde";
+	else if (!access("/usr/local/share/mimelnk", F_OK)) kdedir = "/usr/local";
+        else kdedir = "/usr";
+      }
+    }
+
+    snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
+
+    if (!access(filename, F_OK)) {
+      // Load KDE icons...
+      icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
+
+      for (i = 0; icondirs[i]; i ++) {
+	snprintf(icondir, sizeof(icondir), "%s/share/icons/%s", kdedir,
+		 icondirs[i]);
+
+        if (!access(icondir, F_OK)) break;
+      }
+
+      if (icondirs[i]) {
+        snprintf(filename, sizeof(filename), "%s/16x16/mimetypes/unknown.png",
+	         icondir);
+      } else {
+	snprintf(filename, sizeof(filename), "%s/share/icons/unknown.xpm",
+	         kdedir);
+      }
+
+      if (!access(filename, F_OK)) icon->load_image(filename);
+
+      icon = new Fl_File_Icon("*", Fl_File_Icon::LINK);
+
+      snprintf(filename, sizeof(filename), "%s/16x16/filesystems/link.png",
+               icondir);
+
+      if (!access(filename, F_OK)) icon->load_image(filename);
+
+      snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
+      load_kde_icons(filename, icondir);
+    } else if (!access("/usr/share/icons/folder.xpm", F_OK)) {
+      // Load GNOME icons...
+      icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
+      icon->load_image("/usr/share/icons/page.xpm");
+
+      icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
+      icon->load_image("/usr/share/icons/folder.xpm");
+    } else if (!access("/usr/dt/appconfig/icons", F_OK)) {
+      // Load CDE icons...
+      icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
+      icon->load_image("/usr/dt/appconfig/icons/C/Dtdata.m.pm");
+
+      icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
+      icon->load_image("/usr/dt/appconfig/icons/C/DtdirB.m.pm");
+
+      icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
+      icon->load_image("/usr/dt/appconfig/icons/C/Dtcore.m.pm");
+
+      icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
+      icon->load_image("/usr/dt/appconfig/icons/C/Dtimage.m.pm");
+
+      icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
+      icon->load_image("/usr/dt/appconfig/icons/C/Dtps.m.pm");
+
+      icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
+      icon->load_image("/usr/dt/appconfig/icons/C/DtPrtpr.m.pm");
+    } else if (!access("/usr/lib/filetype", F_OK)) {
+      // Load SGI icons...
+      icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
+      icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
+
+      icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
+      icon->load_fti("/usr/lib/filetype/iconlib/generic.folder.closed.fti");
+
+      icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
+      icon->load_fti("/usr/lib/filetype/default/iconlib/CoreFile.fti");
+
+      icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
+      icon->load_fti("/usr/lib/filetype/system/iconlib/ImageFile.fti");
+
+      if (!access("/usr/lib/filetype/install/iconlib/acroread.doc.fti", F_OK)) {
+	icon = new Fl_File_Icon("*.{eps|ps}", Fl_File_Icon::PLAIN);
+	icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
+
+	icon = new Fl_File_Icon("*.pdf", Fl_File_Icon::PLAIN);
+	icon->load_fti("/usr/lib/filetype/install/iconlib/acroread.doc.fti");
+      } else {
+	icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
+	icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
+      }
+
+      if (!access("/usr/lib/filetype/install/iconlib/html.fti", F_OK)) {
+	icon = new Fl_File_Icon("*.{htm|html|shtml}", Fl_File_Icon::PLAIN);
+        icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
+	icon->load_fti("/usr/lib/filetype/install/iconlib/html.fti");
+      }
+
+      if (!access("/usr/lib/filetype/install/iconlib/color.ps.idle.fti", F_OK)) {
+	icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
+	icon->load_fti("/usr/lib/filetype/install/iconlib/color.ps.idle.fti");
+      }
+    } else {
+      // Create the default icons...
+      new Fl_File_Icon("*", Fl_File_Icon::PLAIN, sizeof(plain) / sizeof(plain[0]), plain);
+      new Fl_File_Icon("*.{bm|bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN,
+                   sizeof(image) / sizeof(image[0]), image);
+      new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY, sizeof(dir) / sizeof(dir[0]), dir);
+    }
+
+    // Mark things as initialized...
+    init = 1;
+
+#ifdef DEBUG
+    int count;
+    Fl_File_Icon *temp;
+    for (count = 0, temp = first_; temp; temp = temp->next_, count ++);
+    printf("count of Fl_File_Icon's is %d...\n", count);
+#endif // DEBUG
+  }
+}
+
+
+//
+// 'load_kde_icons()' - Load KDE icon files.
+//
+
+static void
+load_kde_icons(const char *directory,	// I - Directory to load
+               const char *icondir) {	// I - Location of icons
+  int		i;			// Looping var
+  int		n;			// Number of entries in directory
+  dirent	**entries;		// Entries in directory
+  char		full[1024];		// Full name of file
+
+
+  entries = (dirent **)0;
+  n       = fl_filename_list(directory, &entries);
+
+  for (i = 0; i < n; i ++) {
+    if (entries[i]->d_name[0] != '.') {
+      snprintf(full, sizeof(full), "%s/%s", directory, entries[i]->d_name);
+
+      if (fl_filename_isdir(full)) load_kde_icons(full, icondir);
+      else load_kde_mimelnk(full, icondir);
+    }
+
+    free((void *)entries[i]);
+  }
+
+  free((void*)entries);
+}
+
+
+//
+// 'load_kde_mimelnk()' - Load a KDE "mimelnk" file.
+//
+
+static void
+load_kde_mimelnk(const char *filename,	// I - mimelnk filename
+                 const char *icondir) {	// I - Location of icons
+  FILE		*fp;
+  char		tmp[1024];
+  char		iconfilename[1024];
+  char		pattern[1024];
+  char		mimetype[1024];
+  char		*val;
+  char		full_iconfilename[1024];
+  Fl_File_Icon	*icon;
+
+
+  mimetype[0]     = '\0';
+  pattern[0]      = '\0';
+  iconfilename[0] = '\0';
+
+  if ((fp = fopen(filename, "rb")) != NULL) {
+    while (fgets(tmp, sizeof(tmp), fp)) {
+      if ((val = get_kde_val(tmp, "Icon")) != NULL)
+	strlcpy(iconfilename, val, sizeof(iconfilename));
+      else if ((val = get_kde_val(tmp, "MimeType")) != NULL)
+	strlcpy(mimetype, val, sizeof(mimetype));
+      else if ((val = get_kde_val(tmp, "Patterns")) != NULL)
+	strlcpy(pattern, val, sizeof(pattern));
+    }
+
+    fclose(fp);
+
+#ifdef DEBUG
+    printf("%s: Icon=\"%s\", MimeType=\"%s\", Patterns=\"%s\"\n", filename,
+           iconfilename, mimetype, pattern);
+#endif // DEBUG
+
+    if (!pattern[0] && strncmp(mimetype, "inode/", 6)) return;
+
+    if (iconfilename[0]) {
+      if (iconfilename[0] == '/') {
+        strlcpy(full_iconfilename, iconfilename, sizeof(full_iconfilename));
+      } else if (!access(icondir, F_OK)) {
+        // KDE 3.x and 2.x icons
+	int		i;		// Looping var
+	static const char *paths[] = {	// Subdirs to look in...
+	  "16x16/actions",
+	  "16x16/apps",
+	  "16x16/devices",
+	  "16x16/filesystems",
+	  "16x16/mimetypes",
+/*
+	  "20x20/actions",
+	  "20x20/apps",
+	  "20x20/devices",
+	  "20x20/filesystems",
+	  "20x20/mimetypes",
+
+	  "22x22/actions",
+	  "22x22/apps",
+	  "22x22/devices",
+	  "22x22/filesystems",
+	  "22x22/mimetypes",
+
+	  "24x24/actions",
+	  "24x24/apps",
+	  "24x24/devices",
+	  "24x24/filesystems",
+	  "24x24/mimetypes",
+*/
+	  "32x32/actions",
+	  "32x32/apps",
+	  "32x32/devices",
+	  "32x32/filesystems",
+	  "32x32/mimetypes",
+/*
+	  "36x36/actions",
+	  "36x36/apps",
+	  "36x36/devices",
+	  "36x36/filesystems",
+	  "36x36/mimetypes",
+
+	  "48x48/actions",
+	  "48x48/apps",
+	  "48x48/devices",
+	  "48x48/filesystems",
+	  "48x48/mimetypes",
+
+	  "64x64/actions",
+	  "64x64/apps",
+	  "64x64/devices",
+	  "64x64/filesystems",
+	  "64x64/mimetypes",
+
+	  "96x96/actions",
+	  "96x96/apps",
+	  "96x96/devices",
+	  "96x96/filesystems",
+	  "96x96/mimetypes"
+*/	};
+
+        for (i = 0; i < (int)(sizeof(paths) / sizeof(paths[0])); i ++) {
+          snprintf(full_iconfilename, sizeof(full_iconfilename),
+	           "%s/%s/%s.png", icondir, paths[i], iconfilename);
+
+          if (!access(full_iconfilename, F_OK)) break;
+	}
+
+        if (i >= (int)(sizeof(paths) / sizeof(paths[0]))) return;
+      } else {
+        // KDE 1.x icons
+        snprintf(full_iconfilename, sizeof(full_iconfilename),
+	         "%s/%s", tmp, iconfilename);
+
+        if (access(full_iconfilename, F_OK)) return;
+      }
+
+      if (strncmp(mimetype, "inode/", 6) == 0) {
+	if (!strcmp(mimetype + 6, "directory"))
+	  icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
+	else if (!strcmp(mimetype + 6, "blockdevice"))
+	  icon = new Fl_File_Icon("*", Fl_File_Icon::DEVICE);
+	else if (!strcmp(mimetype + 6, "fifo"))
+	  icon = new Fl_File_Icon("*", Fl_File_Icon::FIFO);
+	else return;
+      } else {
+        icon = new Fl_File_Icon(kde_to_fltk_pattern(pattern),
+                                Fl_File_Icon::PLAIN);
+      }
+
+      icon->load(full_iconfilename);
+    }
+  }
+}
+
+
+//
+// 'kde_to_fltk_pattern()' - Convert a KDE pattern to a FLTK pattern.
+//
+
+static char *
+kde_to_fltk_pattern(const char *kdepattern) {
+  char	*pattern,
+	*patptr;
+
+
+  pattern = (char *)malloc(strlen(kdepattern) + 3);
+  strcpy(pattern, "{");
+  strcpy(pattern + 1, kdepattern);
+
+  if (pattern[strlen(pattern) - 1] == ';') pattern[strlen(pattern) - 1] = '\0';
+
+  strcat(pattern, "}");
+
+  for (patptr = pattern; *patptr; patptr ++) {
+    if (*patptr == ';') *patptr = '|';
+  }
+
+  return (pattern);
+}
+
+
+//
+// 'get_kde_val()' - Get a KDE value.
+//
+
+static char *
+get_kde_val(char       *str,
+            const char *key) {
+  while (*str == *key) {
+    str ++;
+    key ++;
+  }
+
+  if (*key == '\0' && *str == '=') {
+    if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0';
+
+    return (str + 1);
+  }
+
+  return ((char *)0);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_File_Input.cxx b/Utilities/FLTK/src/Fl_File_Input.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..45625b5ee10fcd846b47f87b776618b14b91eae8
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_File_Input.cxx
@@ -0,0 +1,283 @@
+//
+// "$Id$"
+//
+// File_Input header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+// Original version Copyright 1998 by Curtis Edwards.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_File_Input.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_draw.H>
+#include <stdio.h>
+#include "flstring.h"
+
+
+//
+// Height of directory buttons...
+//
+
+#define DIR_HEIGHT	10
+
+
+//
+// Redraw bit for directory bar...
+//
+
+#define FL_DAMAGE_BAR	0x10
+
+
+//
+// 'Fl_File_Input::Fl_File_Input()' - Create a Fl_File_Input widget.
+//
+
+Fl_File_Input::Fl_File_Input(int X, int Y, int W, int H, const char *l)
+  : Fl_Input(X, Y, W, H, l) {
+  buttons_[0] = 0;
+  errorcolor_ = FL_RED;
+  ok_entry_   = 1;
+  pressed_    = -1;
+
+  down_box(FL_UP_BOX);
+}
+
+//
+// 'Fl_File_Input::draw_buttons()' - Draw directory buttons.
+//
+
+void
+Fl_File_Input::draw_buttons() {
+  int	i,					// Looping var
+	X;					// Current X position
+
+
+  if (damage() & (FL_DAMAGE_BAR | FL_DAMAGE_ALL)) {
+    update_buttons();
+  }
+
+  for (X = 0, i = 0; buttons_[i]; i ++)
+  {
+    if ((X + buttons_[i]) > xscroll()) {
+      if (X < xscroll()) {
+        draw_box(pressed_ == i ? fl_down(down_box()) : down_box(),
+                 x(), y(), X + buttons_[i] - xscroll(), DIR_HEIGHT, FL_GRAY);
+      } else if ((X + buttons_[i] - xscroll()) > w()) {
+	draw_box(pressed_ == i ? fl_down(down_box()) : down_box(),
+        	 x() + X - xscroll(), y(), w() - X + xscroll(), DIR_HEIGHT,
+		 FL_GRAY);
+      } else {
+        draw_box(pressed_ == i ? fl_down(down_box()) : down_box(),
+	         x() + X - xscroll(), y(), buttons_[i], DIR_HEIGHT, FL_GRAY);
+      }
+    }
+
+    X += buttons_[i];
+  }
+
+  if (X < w()) {
+    draw_box(pressed_ == i ? fl_down(down_box()) : down_box(),
+             x() + X - xscroll(), y(), w() - X + xscroll(), DIR_HEIGHT, FL_GRAY);
+  }
+}
+
+//
+// 'Fl_File_Input::update_buttons()' - Update the sizes of the directory buttons.
+//
+
+void
+Fl_File_Input::update_buttons() {
+  int		i;				// Looping var
+  const char	*start,				// Start of path component
+		*end;				// End of path component
+
+
+//  puts("update_buttons()");
+
+  // Set the current font & size...
+  fl_font(textfont(), textsize());
+
+  // Loop through the value string, setting widths...
+  for (i = 0, start = value();
+       start && i < (int)(sizeof(buttons_) / sizeof(buttons_[0]) - 1);
+       start = end, i ++) {
+//    printf("    start = \"%s\"\n", start);
+    if ((end = strchr(start, '/')) == NULL)
+#if defined(WIN32) || defined(__EMX__)
+      if ((end = strchr(start, '\\')) == NULL)
+#endif // WIN32 || __EMX__
+      break;
+
+    end ++;
+
+    buttons_[i] = (short)fl_width(start, end - start);
+    if (!i) buttons_[i] += Fl::box_dx(box()) + 6;
+  }
+
+//  printf("    found %d components/buttons...\n", i);
+
+  buttons_[i] = 0;
+}
+
+
+//
+// 'Fl_File_Input::value()' - Set the value of the widget...
+//
+
+int						// O - TRUE on success
+Fl_File_Input::value(const char *str,		// I - New string value
+                     int        len) {		// I - Length of value
+  damage(FL_DAMAGE_BAR);
+  return Fl_Input::value(str,len);
+}
+
+
+int						// O - TRUE on success
+Fl_File_Input::value(const char *str) {		// I - New string value
+  damage(FL_DAMAGE_BAR);
+  return Fl_Input::value(str);
+}
+
+
+//
+// 'Fl_File_Input::draw()' - Draw the file input widget...
+//
+
+void
+Fl_File_Input::draw() {
+  Fl_Boxtype b = box();
+  if (damage() & (FL_DAMAGE_BAR | FL_DAMAGE_ALL)) draw_buttons();
+  // this flag keeps Fl_Input_::drawtext from drawing a bogus box!
+  char must_trick_fl_input_ = 
+    Fl::focus()!=this && !size() && !(damage()&FL_DAMAGE_ALL);
+  if ((damage() & FL_DAMAGE_ALL) || must_trick_fl_input_) 
+    draw_box(b,x(),y()+DIR_HEIGHT,w(),h()-DIR_HEIGHT,color());
+  if (!must_trick_fl_input_) 
+    Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b)+DIR_HEIGHT,
+		        w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b)-DIR_HEIGHT);
+}
+
+
+//
+// 'Fl_File_Input::handle()' - Handle events in the widget...
+//
+
+int						// O - TRUE if we handled event
+Fl_File_Input::handle(int event) 		// I - Event
+{
+//  printf("handle(event = %d)\n", event);
+
+  switch (event) {
+    case FL_MOVE :
+    case FL_ENTER :
+      if (active_r()) {
+	if (Fl::event_y() < (y() + DIR_HEIGHT)) window()->cursor(FL_CURSOR_DEFAULT);
+	else window()->cursor(FL_CURSOR_INSERT);
+      }
+
+      return 1;
+
+    case FL_PUSH :
+    case FL_RELEASE :
+    case FL_DRAG :
+      if (Fl::event_y() < (y() + DIR_HEIGHT) || pressed_ >= 0) return handle_button(event);
+
+      return Fl_Input::handle(event);
+
+    default :
+      if (Fl_Input::handle(event)) {
+	damage(FL_DAMAGE_BAR);
+	return 1;
+      }
+
+      return 0;
+  }
+}
+
+
+//
+// 'Fl_File_Input::handle_button()' - Handle button events in the widget...
+//
+
+int						// O - TRUE if we handled event
+Fl_File_Input::handle_button(int event)		// I - Event
+{
+  int		i,				// Looping var
+		X;				// Current X position
+  char		*start,				// Start of path component
+		*end;				// End of path component
+  char		newvalue[1024];			// New value
+
+
+  // Figure out which button is being pressed...
+  for (X = 0, i = 0; buttons_[i]; i ++)
+  {
+    X += buttons_[i];
+
+    if (X > xscroll() && Fl::event_x() < (x() + X - xscroll())) break;
+  }
+
+//  printf("handle_button(event = %d), button = %d\n", event, i);
+
+  // Redraw the directory bar...
+  if (event == FL_RELEASE) pressed_ = -1;
+  else pressed_ = (short)i;
+
+  window()->make_current();
+  draw_buttons();
+
+  // Return immediately if the user is clicking on the last button or
+  // has not released the mouse button...
+  if (!buttons_[i] || event != FL_RELEASE) return 1;
+
+  // Figure out where to truncate the path...
+  strlcpy(newvalue, value(), sizeof(newvalue));
+
+  for (start = newvalue, end = start; start && i >= 0; start = end, i --) {
+//    printf("    start = \"%s\"\n", start);
+    if ((end = strchr(start, '/')) == NULL)
+#if defined(WIN32) || defined(__EMX__)
+      if ((end = strchr(start, '\\')) == NULL)
+#endif // WIN32 || __EMX__
+      break;
+
+    end ++;
+  }
+
+  if (i < 0) {
+    // Found the end; truncate the value and update the buttons...
+    *start = '\0';
+    value(newvalue, start - newvalue);
+
+    // Then do the callbacks, if necessary...
+    set_changed();
+    if (when() & FL_WHEN_CHANGED) do_callback();
+  }
+
+  return 1;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Font.H b/Utilities/FLTK/src/Fl_Font.H
new file mode 100644
index 0000000000000000000000000000000000000000..bc93e2997046e4c402ff198acae0447cb2460125
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Font.H
@@ -0,0 +1,107 @@
+//
+// "$Id: Fl_Font.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// Font definitions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Two internal fltk data structures:
+//
+// Fl_Fontdesc: an entry into the fl_font() table.  There is one of these
+// for each fltk font number.
+//
+// Fl_FontSize: a structure for an actual system font, with junk to
+// help choose it and info on character sizes.  Each Fl_Fontdesc has a
+// linked list of these.  These are created the first time each system
+// font/size combination is used.
+
+#ifndef FL_FONT_
+#define FL_FONT_
+
+#include <config.h>
+
+#  if USE_XFT
+typedef struct _XftFont XftFont;
+#  endif // USE_XFT
+
+class Fl_FontSize {
+public:
+  Fl_FontSize *next;	// linked list for this Fl_Fontdesc
+#  ifdef WIN32
+  HFONT fid;
+  int width[256];
+  TEXTMETRIC metr;
+  FL_EXPORT Fl_FontSize(const char* fontname, int size);
+#  elif defined(__APPLE_QD__)
+  FL_EXPORT Fl_FontSize(const char* fontname, int size);
+  short font, face, size;
+  short ascent, descent;
+  short width[256];
+  bool knowMetrics;
+#  elif defined(__APPLE_QUARTZ__)
+  FL_EXPORT Fl_FontSize(const char* fontname, int size);
+  char *q_name;
+  int size;
+  short ascent, descent, q_width;
+#  elif USE_XFT
+  XftFont* font;
+  const char* encoding;
+  int size;
+  FL_EXPORT Fl_FontSize(const char* xfontname);
+#  else
+  XFontStruct* font;	// X font information
+  FL_EXPORT Fl_FontSize(const char* xfontname);
+#  endif
+  int minsize;		// smallest point size that should use this
+  int maxsize;		// largest point size that should use this
+#  if HAVE_GL
+  unsigned int listbase;// base of display list, 0 = none
+#  endif
+  FL_EXPORT ~Fl_FontSize();
+};
+
+extern FL_EXPORT Fl_FontSize *fl_fontsize; // the currently selected one
+
+struct Fl_Fontdesc {
+  const char *name;
+  char fontname[128];	// "Pretty" font name
+  Fl_FontSize *first;	// linked list of sizes of this style
+#  ifndef WIN32
+  char **xlist;		// matched X font names
+  int n;		// size of xlist, negative = don't free xlist!
+#  endif
+};
+
+extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table
+
+#  ifndef WIN32
+// functions for parsing X font names:
+FL_EXPORT const char* fl_font_word(const char *p, int n);
+FL_EXPORT char *fl_find_fontsize(char *name);
+#  endif
+
+#endif
+
+//
+// End of "$Id: Fl_Font.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/src/Fl_GIF_Image.cxx b/Utilities/FLTK/src/Fl_GIF_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e40a9d218e0e3a178d09feea3f96acb39c8271bc
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_GIF_Image.cxx
@@ -0,0 +1,384 @@
+//
+// "$Id$"
+//
+// Fl_GIF_Image routines.
+//
+// Copyright 1997-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_GIF_Image.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+// Read a .gif file and convert it to a "xpm" format (actually my
+// modified one with compressed colormaps).
+
+// Extensively modified from original code for gif2ras by
+// Patrick J. Naughton of Sun Microsystems.  The original
+// copyright notice follows:
+
+/* gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
+ *
+ * Copyright (c) 1988 by Patrick J. Naughton
+ *
+ * Author: Patrick J. Naughton
+ * naughton@wind.sun.com
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind.  The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof.  In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * Comments and additions should be sent to the author:
+ *
+ *                     Patrick J. Naughton
+ *                     Sun Microsystems, Inc.
+ *                     2550 Garcia Ave, MS 14-40
+ *                     Mountain View, CA 94043
+ *                     (415) 336-1080
+ */
+
+typedef unsigned char uchar;
+
+#define NEXTBYTE (uchar)getc(GifFile)
+#define GETSHORT(var) var = NEXTBYTE; var += NEXTBYTE << 8
+
+Fl_GIF_Image::Fl_GIF_Image(const char *infname) : Fl_Pixmap((char *const*)0) {
+  FILE *GifFile;	// File to read
+  char **new_data;	// Data array
+
+  if ((GifFile = fopen(infname, "rb")) == NULL) {
+    Fl::error("Fl_GIF_Image: Unable to open %s!", infname);
+    return;
+  }
+
+  {char b[6];
+  if (fread(b,1,6,GifFile)<6) {
+    fclose(GifFile);
+    return; /* quit on eof */
+  }
+  if (b[0]!='G' || b[1]!='I' || b[2] != 'F') {
+    fclose(GifFile);
+    Fl::error("Fl_GIF_Image: %s is not a GIF file.\n", infname);
+    return;
+  }
+  if (b[3]!='8' || b[4]>'9' || b[5]!= 'a')
+    Fl::warning("%s is version %c%c%c.",infname,b[3],b[4],b[5]);
+  }
+
+  int Width; GETSHORT(Width);
+  int Height; GETSHORT(Height);
+
+  uchar ch = NEXTBYTE;
+  char HasColormap = ((ch & 0x80) != 0);
+  int BitsPerPixel = (ch & 7) + 1;
+  int ColorMapSize = 1 << BitsPerPixel;
+  // int OriginalResolution = ((ch>>4)&7)+1;
+  // int SortedTable = (ch&8)!=0;
+  ch = NEXTBYTE; // Background Color index
+  ch = NEXTBYTE; // Aspect ratio is N/64
+
+  // Read in global colormap:
+  uchar transparent_pixel = 0;
+  char has_transparent = 0;
+  uchar Red[256], Green[256], Blue[256]; /* color map */
+  if (HasColormap) {
+    for (int i=0; i < ColorMapSize; i++) {	
+      Red[i] = NEXTBYTE;
+      Green[i] = NEXTBYTE;
+      Blue[i] = NEXTBYTE;
+    }
+  } else {
+    Fl::warning("%s does not have a colormap.", infname);
+    for (int i = 0; i < ColorMapSize; i++)
+      Red[i] = Green[i] = Blue[i] = (uchar)(255 * i / (ColorMapSize-1));
+  }
+
+  int CodeSize;		/* Code size, init from GIF header, increases... */
+  char Interlace;
+
+  for (;;) {
+
+    int i = NEXTBYTE;
+    if (i<0) {
+      fclose(GifFile);
+      Fl::error("Fl_GIF_Image: %s - unexpected EOF",infname); 
+      return;
+    }
+    int blocklen;
+
+    //  if (i == 0x3B) return 0;  eof code
+
+    if (i == 0x21) {		// a "gif extension"
+
+      ch = NEXTBYTE;
+      blocklen = NEXTBYTE;
+
+      if (ch==0xF9 && blocklen==4) { // Netscape animation extension
+
+	char bits;
+	bits = NEXTBYTE;
+	char junk = NEXTBYTE; junk = NEXTBYTE; // GETSHORT(delay);
+	transparent_pixel = NEXTBYTE;
+	if (bits & 1) has_transparent = 1;
+	blocklen = NEXTBYTE;
+
+      } else if (ch == 0xFF) { // Netscape repeat count
+	;
+
+      } else if (ch != 0xFE) { //Gif Comment
+	Fl::warning("%s: unknown gif extension 0x%02x.", infname, ch);
+      }
+    } else if (i == 0x2c) {	// an image
+
+      ch = NEXTBYTE; ch = NEXTBYTE; // GETSHORT(x_position);
+      ch = NEXTBYTE; ch = NEXTBYTE; // GETSHORT(y_position);
+      GETSHORT(Width);
+      GETSHORT(Height);
+      ch = NEXTBYTE;
+      Interlace = ((ch & 0x40) != 0);
+      if (ch&0x80) { 
+	// read local color map
+	int n = 2<<(ch&7);
+	for (i=0; i < n; i++) {	
+	  Red[i] = NEXTBYTE;
+	  Green[i] = NEXTBYTE;
+	  Blue[i] = NEXTBYTE;
+	}
+      }
+      CodeSize = NEXTBYTE+1;
+      break; // okay, this is the image we want
+    } else {
+      Fl::warning("%s: unknown gif code 0x%02x", infname, i);
+      blocklen = 0;
+    }
+
+    // skip the data:
+    while (blocklen>0) {while (blocklen--) {ch = NEXTBYTE;} blocklen=NEXTBYTE;}
+  }
+
+  if (BitsPerPixel >= CodeSize)
+  {
+    // Workaround for broken GIF files...
+    BitsPerPixel = CodeSize - 1;
+    ColorMapSize = 1 << BitsPerPixel;
+  }
+
+  uchar *Image = new uchar[Width*Height];
+
+  int YC = 0, Pass = 0; /* Used to de-interlace the picture */
+  uchar *p = Image;
+  uchar *eol = p+Width;
+
+  int InitCodeSize = CodeSize;
+  int ClearCode = (1 << (CodeSize-1));
+  int EOFCode = ClearCode + 1;
+  int FirstFree = ClearCode + 2;
+  int FinChar = 0;
+  int ReadMask = (1<<CodeSize) - 1;
+  int FreeCode = FirstFree;
+  int OldCode = ClearCode;
+
+  // tables used by LZW decompresser:
+  short int Prefix[4096];
+  uchar Suffix[4096];
+
+  int blocklen = NEXTBYTE;
+  uchar thisbyte = NEXTBYTE; blocklen--;
+  int frombit = 0;
+
+  for (;;) {
+
+/* Fetch the next code from the raster data stream.  The codes can be
+ * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
+ * maintain our location as a pointer and a bit offset.
+ * In addition, gif adds totally useless and annoying block counts
+ * that must be correctly skipped over. */
+    int CurCode = thisbyte;
+    if (frombit+CodeSize > 7) {
+      if (blocklen <= 0) {
+	blocklen = NEXTBYTE;
+	if (blocklen <= 0) break;
+      }
+      thisbyte = NEXTBYTE; blocklen--;
+      CurCode |= thisbyte<<8;
+    }
+    if (frombit+CodeSize > 15) {
+      if (blocklen <= 0) {
+	blocklen = NEXTBYTE;
+	if (blocklen <= 0) break;
+      }
+      thisbyte = NEXTBYTE; blocklen--;
+      CurCode |= thisbyte<<16;
+    }
+    CurCode = (CurCode>>frombit)&ReadMask;
+    frombit = (frombit+CodeSize)%8;
+
+    if (CurCode == ClearCode) {
+      CodeSize = InitCodeSize;
+      ReadMask = (1<<CodeSize) - 1;
+      FreeCode = FirstFree;
+      OldCode = ClearCode;
+      continue;
+    }
+
+    if (CurCode == EOFCode) break;
+
+    uchar OutCode[1025]; // temporary array for reversing codes
+    uchar *tp = OutCode;
+    int i;
+    if (CurCode < FreeCode) i = CurCode;
+    else if (CurCode == FreeCode) {*tp++ = (uchar)FinChar; i = OldCode;}
+    else {Fl::error("Fl_GIF_Image: %s - LZW Barf!", infname); break;}
+
+    while (i >= ColorMapSize) {*tp++ = Suffix[i]; i = Prefix[i];}
+    *tp++ = FinChar = i;
+    do {
+      *p++ = *--tp;
+      if (p >= eol) {
+	if (!Interlace) YC++;
+	else switch (Pass) {
+	case 0: YC += 8; if (YC >= Height) {Pass++; YC = 4;} break;
+	case 1: YC += 8; if (YC >= Height) {Pass++; YC = 2;} break;
+	case 2: YC += 4; if (YC >= Height) {Pass++; YC = 1;} break;
+	case 3: YC += 2; break;
+	}
+	if (YC>=Height) YC=0; /* cheap bug fix when excess data */
+	p = Image + YC*Width;
+	eol = p+Width;
+      }
+    } while (tp > OutCode);
+
+    if (OldCode != ClearCode) {
+      Prefix[FreeCode] = (short)OldCode;
+      Suffix[FreeCode] = FinChar;
+      FreeCode++;
+      if (FreeCode > ReadMask) {
+	if (CodeSize < 12) {
+	  CodeSize++;
+	  ReadMask = (1 << CodeSize) - 1;
+	}
+	else FreeCode--;
+      }
+    }
+    OldCode = CurCode;
+  }
+
+  // We are done reading the file, now convert to xpm:
+
+  // allocate line pointer arrays:
+  w(Width);
+  h(Height);
+  d(1);
+  new_data = new char*[Height+2];
+
+  // transparent pixel must be zero, swap if it isn't:
+  if (has_transparent && transparent_pixel != 0) {
+    // swap transparent pixel with zero
+    p = Image+Width*Height;
+    while (p-- > Image) {
+      if (*p==transparent_pixel) *p = 0;
+      else if (!*p) *p = transparent_pixel;
+    }
+    uchar t;
+    t                        = Red[0];
+    Red[0]                   = Red[transparent_pixel];
+    Red[transparent_pixel]   = t;
+
+    t                        = Green[0];
+    Green[0]                 = Green[transparent_pixel];
+    Green[transparent_pixel] = t;
+
+    t                        = Blue[0];
+    Blue[0]                  = Blue[transparent_pixel];
+    Blue[transparent_pixel]  = t;
+  }
+
+  // find out what colors are actually used:
+  uchar used[256]; uchar remap[256];
+  int i;
+  for (i = 0; i < ColorMapSize; i++) used[i] = 0;
+  p = Image+Width*Height;
+  while (p-- > Image) used[*p] = 1;
+
+  // remap them to start with printing characters:
+  int base = has_transparent && used[0] ? ' ' : ' '+1;
+  int numcolors = 0;
+  for (i = 0; i < ColorMapSize; i++) if (used[i]) {
+    remap[i] = (uchar)(base++);
+    numcolors++;
+  }
+
+  // write the first line of xpm data (use suffix as temp array):
+  int length = sprintf((char*)(Suffix),
+		       "%d %d %d %d",Width,Height,-numcolors,1);
+  new_data[0] = new char[length+1];
+  strcpy(new_data[0], (char*)Suffix);
+
+  // write the colormap
+  new_data[1] = (char*)(p = new uchar[4*numcolors]);
+  for (i = 0; i < ColorMapSize; i++) if (used[i]) {
+    *p++ = remap[i];
+    *p++ = Red[i];
+    *p++ = Green[i];
+    *p++ = Blue[i];
+  }
+
+  // remap the image data:
+  p = Image+Width*Height;
+  while (p-- > Image) *p = remap[*p];
+
+  // split the image data into lines:
+  for (i=0; i<Height; i++) {
+    new_data[i+2] = new char[Width+1];
+    memcpy(new_data[i + 2], (char*)(Image + i*Width), Width);
+    new_data[i + 2][Width] = 0;
+  }
+
+  data((const char **)new_data, Height + 2);
+  alloc_data = 1;
+
+  delete[] Image;
+
+  fclose(GifFile);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Gl_Choice.H b/Utilities/FLTK/src/Fl_Gl_Choice.H
new file mode 100644
index 0000000000000000000000000000000000000000..68a78304408d50f700659af9fb39c2cb7c25c2b4
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Gl_Choice.H
@@ -0,0 +1,132 @@
+//
+// "$Id: Fl_Gl_Choice.H 4052 2005-02-24 21:55:12Z mike $"
+//
+// OpenGL definitions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2001 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@easysw.com".
+//
+
+// Internal interface to set up OpenGL.
+//
+// A "Fl_Gl_Choice" is created from an OpenGL mode and holds information
+// necessary to create a window (on X) and to create an OpenGL "context"
+// (on both X and Win32).
+//
+// fl_create_gl_context takes a window (necessary only on Win32) and an
+// Fl_Gl_Choice and returns a new OpenGL context. All contexts share
+// display lists with each other.
+//
+// On X another fl_create_gl_context is provided to create it for any
+// X visual.
+//
+// fl_set_gl_context makes the given OpenGL context current and makes
+// it draw into the passed window. It tracks the current one context
+// to avoid calling the context switching code when the same context
+// is used, though it is a mystery to me why the GLX/WGL libraries
+// don't do this themselves...
+//
+// fl_no_gl_context clears that cache so the next fl_set_gl_context is
+// guaranteed to work.
+//
+// fl_delete_gl_context destroys the context.
+//
+// This code is used by Fl_Gl_Window, gl_start(), and gl_visual()
+
+#ifndef Fl_Gl_Choice_H
+#define Fl_Gl_Choice_H
+
+// Warning: whatever GLContext is defined to must take exactly the same
+// space in a structure as a void*!!!
+#ifdef WIN32
+#  include <FL/gl.h>
+#  define GLContext HGLRC
+#elif defined(__APPLE_QD__)
+#  include <OpenGL/gl.h>
+#  include <AGL/agl.h>
+#  define GLContext AGLContext
+#elif defined(__APPLE_QUARTZ__)
+// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+#  include <OpenGL/gl.h>
+#  include <AGL/agl.h>
+#  define GLContext AGLContext
+#else
+#  include <GL/glx.h>
+#  define GLContext GLXContext
+#endif
+
+// Describes crap needed to create a GLContext.
+class Fl_Gl_Choice {
+  int mode;
+  const int *alist;
+  Fl_Gl_Choice *next;
+public:
+#ifdef WIN32
+  int pixelformat;	// the visual to use
+  PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
+#elif defined(__APPLE_QD__)
+  AGLPixelFormat pixelformat;
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  AGLPixelFormat pixelformat;
+#else
+  XVisualInfo *vis;	// the visual to use
+  Colormap colormap;	// a colormap for that visual
+#endif
+  // Return one of these structures for a given gl mode.
+  // The second argument is a glX attribute list, and is used if mode is
+  // zero.  This is not supported on Win32:
+  static Fl_Gl_Choice *find(int mode, const int *);
+};
+
+class Fl_Window;
+
+#ifdef WIN32
+
+GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
+
+#elif defined(__APPLE_QD__)
+
+GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
+
+#elif defined(__APPLE_QUARTZ__)
+// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+
+GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
+
+#else
+
+GLContext fl_create_gl_context(XVisualInfo* vis);
+
+static inline
+GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g) {
+  return fl_create_gl_context(g->vis);
+}
+
+#endif
+
+void fl_set_gl_context(Fl_Window*, GLContext);
+void fl_no_gl_context();
+void fl_delete_gl_context(GLContext);
+
+#endif
+
+//
+// End of "$Id: Fl_Gl_Choice.H 4052 2005-02-24 21:55:12Z mike $".
+//
diff --git a/Utilities/FLTK/src/Fl_Gl_Choice.cxx b/Utilities/FLTK/src/Fl_Gl_Choice.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..849c0c1fbc39eabb80ef690e7f7efba7658f5bc4
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Gl_Choice.cxx
@@ -0,0 +1,452 @@
+//
+// "$Id$"
+//
+// OpenGL visual selection code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#if HAVE_GL
+
+#  include <FL/Fl.H>
+#  include <FL/x.H>
+#  include <stdlib.h>
+#  include "Fl_Gl_Choice.H"
+#  include <FL/gl_draw.H>
+#  include "flstring.h"
+
+#  ifdef __APPLE__
+#    include <FL/Fl_Window.H>
+#  endif
+
+#  ifdef WIN32
+void fl_save_dc(HWND, HDC);
+#  endif
+
+static Fl_Gl_Choice *first;
+
+// this assummes one of the two arguments is zero:
+// We keep the list system in Win32 to stay compatible and interpret
+// the list later...
+Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
+  Fl_Gl_Choice *g;
+  
+  for (g = first; g; g = g->next)
+    if (g->mode == m && g->alist == alistp) 
+      return g;
+
+#  ifdef __APPLE_QD__
+  const int *blist;
+  int list[32];
+    
+  if (alistp)
+    blist = alistp;
+  else {
+    int n = 0;
+    if (m & FL_INDEX) {
+      list[n++] = AGL_BUFFER_SIZE;
+      list[n++] = 8; // glut tries many sizes, but this should work...
+    } else {
+      list[n++] = AGL_RGBA;
+      list[n++] = AGL_GREEN_SIZE;
+      list[n++] = (m & FL_RGB8) ? 8 : 1;
+      if (m & FL_ALPHA) {
+	list[n++] = AGL_ALPHA_SIZE;
+	list[n++] = (m & FL_RGB8) ? 8 : 1;
+      }
+      if (m & FL_ACCUM) {
+	list[n++] = AGL_ACCUM_GREEN_SIZE;
+	list[n++] = 1;
+	if (m & FL_ALPHA) {
+	  list[n++] = AGL_ACCUM_ALPHA_SIZE;
+	  list[n++] = 1;
+	}
+      }
+    }
+    if (m & FL_DOUBLE) {
+      list[n++] = AGL_DOUBLEBUFFER;
+    }
+    if (m & FL_DEPTH) {
+      list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
+    }
+    if (m & FL_STENCIL) {
+      list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
+    }
+#    ifdef AGL_STEREO
+    if (m & FL_STEREO) {
+      list[n++] = AGL_STEREO;
+    }
+#    endif
+    list[n] = AGL_NONE;
+    blist = list;
+  }
+  fl_open_display();
+  AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, (GLint*)blist);
+  if (!fmt) return 0;
+
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  const int *blist;
+  int list[32];
+   
+  if (alistp)
+    blist = alistp;
+  else {
+    int n = 0;
+    if (m & FL_INDEX) {
+      list[n++] = AGL_BUFFER_SIZE;
+      list[n++] = 8; // glut tries many sizes, but this should work...
+    } else {
+      list[n++] = AGL_RGBA;
+      list[n++] = AGL_GREEN_SIZE;
+      list[n++] = (m & FL_RGB8) ? 8 : 1;
+      if (m & FL_ALPHA) {
+        list[n++] = AGL_ALPHA_SIZE;
+        list[n++] = (m & FL_RGB8) ? 8 : 1;
+      }
+      if (m & FL_ACCUM) {
+        list[n++] = AGL_ACCUM_GREEN_SIZE;
+        list[n++] = 1;
+        if (m & FL_ALPHA) {
+          list[n++] = AGL_ACCUM_ALPHA_SIZE;
+          list[n++] = 1;
+        }
+      }
+    }
+    if (m & FL_DOUBLE) {
+      list[n++] = AGL_DOUBLEBUFFER;
+    }
+    if (m & FL_DEPTH) {
+      list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
+    }
+    if (m & FL_STENCIL) {
+      list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
+    }
+#    ifdef AGL_STEREO
+    if (m & FL_STEREO) {
+      list[n++] = AGL_STEREO;
+    }
+#    endif
+    list[n] = AGL_NONE;
+    blist = list;
+  }
+  fl_open_display();
+  AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, (GLint*)blist);
+  if (!fmt) return 0;
+  
+#  elif !defined(WIN32)    
+
+  const int *blist;
+  int list[32];
+    
+  if (alistp)
+    blist = alistp;
+  else {
+    int n = 0;
+    if (m & FL_INDEX) {
+      list[n++] = GLX_BUFFER_SIZE;
+      list[n++] = 8; // glut tries many sizes, but this should work...
+    } else {
+      list[n++] = GLX_RGBA;
+      list[n++] = GLX_GREEN_SIZE;
+      list[n++] = (m & FL_RGB8) ? 8 : 1;
+      if (m & FL_ALPHA) {
+	list[n++] = GLX_ALPHA_SIZE;
+	list[n++] = (m & FL_RGB8) ? 8 : 1;
+      }
+      if (m & FL_ACCUM) {
+	list[n++] = GLX_ACCUM_GREEN_SIZE;
+	list[n++] = 1;
+	if (m & FL_ALPHA) {
+	  list[n++] = GLX_ACCUM_ALPHA_SIZE;
+	  list[n++] = 1;
+	}
+      }
+    }
+    if (m & FL_DOUBLE) {
+      list[n++] = GLX_DOUBLEBUFFER;
+    }
+    if (m & FL_DEPTH) {
+      list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
+    }
+    if (m & FL_STENCIL) {
+      list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
+    }
+    if (m & FL_STEREO) {
+      list[n++] = GLX_STEREO;
+    }
+#    if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+    if (m & FL_MULTISAMPLE) {
+      list[n++] = GLX_SAMPLES_SGIS;
+      list[n++] = 4; // value Glut uses
+    }
+#    endif
+    list[n] = 0;
+    blist = list;
+  }
+    
+  fl_open_display();
+  XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
+  if (!visp) {
+#    if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+    if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE,0);
+#    endif
+    return 0;
+  }
+
+#  else
+
+  // Replacement for ChoosePixelFormat() that finds one with an overlay
+  // if possible:
+  if (!fl_gc) fl_GetDC(0);
+  int pixelformat = 0;
+  PIXELFORMATDESCRIPTOR chosen_pfd;
+  for (int i = 1; ; i++) {
+    PIXELFORMATDESCRIPTOR pfd;
+    if (!DescribePixelFormat(fl_gc, i, sizeof(pfd), &pfd)) break;
+    // continue if it does not satisfy our requirements:
+    if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue;
+    if (pfd.iPixelType != ((m&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue;
+    if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue;
+    if ((m & FL_ACCUM) && !pfd.cAccumBits) continue;
+    if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
+    if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue;
+    if ((m & FL_DEPTH) && !pfd.cDepthBits) continue;
+    if ((m & FL_STENCIL) && !pfd.cStencilBits) continue;
+    // see if better than the one we have already:
+    if (pixelformat) {
+      // offering non-generic rendering is better (read: hardware accelleration)
+      if (!(chosen_pfd.dwFlags & PFD_GENERIC_FORMAT) &&
+          (pfd.dwFlags & PFD_GENERIC_FORMAT)) continue;
+      // offering overlay is better:
+      else if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {}
+      // otherwise more bit planes is better:
+      else if (chosen_pfd.cColorBits > pfd.cColorBits) continue;
+      else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue;
+    }
+    pixelformat = i;
+    chosen_pfd = pfd;
+  }
+  //printf("Chosen pixel format is %d\n", pixelformat);
+  if (!pixelformat) return 0;
+
+#  endif
+
+  g = new Fl_Gl_Choice;
+  g->mode = m;
+  g->alist = alistp;
+  g->next = first;
+  first = g;
+
+#  ifdef WIN32
+  g->pixelformat = pixelformat;
+  g->pfd = chosen_pfd;
+#  elif defined(__APPLE_QD__)
+  g->pixelformat = fmt;
+#  elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  g->pixelformat = fmt;
+#  else
+  g->vis = visp;
+
+  if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
+      visp->visualid == fl_visual->visualid &&
+      !getenv("MESA_PRIVATE_CMAP"))
+    g->colormap = fl_colormap;
+  else
+    g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+				  visp->visual, AllocNone);
+#  endif
+
+  return g;
+}
+
+static GLContext *context_list = 0;
+static int nContext = 0, NContext = 0;
+
+static void add_context(GLContext ctx) {
+  if (!ctx) return;
+  if (nContext==NContext) {
+    if (!NContext) NContext = 8;
+    NContext *= 2;
+    context_list = (GLContext*)realloc(
+      context_list, NContext*sizeof(GLContext));
+  }
+  context_list[nContext++] = ctx;
+}
+
+static void del_context(GLContext ctx) {
+  int i; 
+  for (i=0; i<nContext; i++) {
+    if (context_list[i]==ctx) {
+      memmove(context_list+i, context_list+i+1,
+        (nContext-i-1) * sizeof(GLContext));
+      context_list[--nContext] = 0;
+      break;
+    }
+  }
+  if (!nContext) gl_remove_displaylist_fonts();
+}
+
+#  ifdef WIN32
+
+GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+  Fl_X* i = Fl_X::i(window);
+  HDC hdc = i->private_dc;
+  if (!hdc) {
+    hdc = i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
+    fl_save_dc(i->xid, hdc);
+    SetPixelFormat(hdc, g->pixelformat, (PIXELFORMATDESCRIPTOR*)(&g->pfd));
+#    if USE_COLORMAP
+    if (fl_palette) SelectPalette(hdc, fl_palette, FALSE);
+#    endif
+  }
+  GLContext context =
+    layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc);
+  if (context) {
+    if (context_list && context_list[0]) 
+      wglShareLists(context_list[0], context);
+    add_context(context);
+  }
+  return context;
+}
+
+#  elif defined(__APPLE_QD__)
+GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+    GLContext context, shared_ctx = context_list ? context_list[0] : 0;
+    context = aglCreateContext( g->pixelformat, shared_ctx);
+    if (!context) return 0;
+    add_context((GLContext)context);
+    if ( window->parent() ) {
+      Rect wrect; GetWindowPortBounds( fl_xid(window), &wrect );
+      GLint rect[] = { window->x(), wrect.bottom-window->h()-window->y(), window->w(), window->h() }; 
+      aglSetInteger( (GLContext)context, AGL_BUFFER_RECT, rect );
+      aglEnable( (GLContext)context, AGL_BUFFER_RECT );
+    }
+    aglSetDrawable( context, GetWindowPort( fl_xid(window) ) );
+    return (context);
+}
+#  elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+    GLContext context, shared_ctx = context_list ? context_list[0] : 0;
+    context = aglCreateContext( g->pixelformat, shared_ctx);
+    if (!context) return 0;
+    add_context((GLContext)context);
+    if ( window->parent() ) {
+      Rect wrect; GetWindowPortBounds( fl_xid(window), &wrect );
+      GLint rect[] = { window->x(), wrect.bottom-window->h()-window->y(), window->w(), window->h() };
+      aglSetInteger( (GLContext)context, AGL_BUFFER_RECT, rect );
+      aglEnable( (GLContext)context, AGL_BUFFER_RECT );
+    }
+    aglSetDrawable( context, GetWindowPort( fl_xid(window) ) );
+    return (context);
+}
+#  else
+
+GLContext fl_create_gl_context(XVisualInfo* vis) {
+  GLContext shared_ctx = context_list ? context_list[0] : 0;
+  GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1);
+  if (context)
+    add_context(context);
+  return context;
+}
+
+#  endif
+
+static GLContext cached_context;
+static Fl_Window* cached_window;
+
+void fl_set_gl_context(Fl_Window* w, GLContext context) {
+  if (context != cached_context || w != cached_window) {
+    cached_context = context;
+    cached_window = w;
+#  ifdef WIN32
+    wglMakeCurrent(Fl_X::i(w)->private_dc, context);
+#  elif defined(__APPLE_QD__)
+    if ( w->parent() ) { //: resize our GL buffer rectangle
+      Rect wrect; GetWindowPortBounds( fl_xid(w), &wrect );
+      GLint rect[] = { w->x(), wrect.bottom-w->h()-w->y(), w->w(), w->h() };
+      aglSetInteger( context, AGL_BUFFER_RECT, rect );
+      aglEnable( context, AGL_BUFFER_RECT );
+    }
+    aglSetDrawable(context, GetWindowPort( fl_xid(w) ) ); 
+    aglSetCurrentContext(context);
+#  elif defined(__APPLE_QUARTZ__)
+    // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+    if ( w->parent() ) { //: resize our GL buffer rectangle
+      Rect wrect; GetWindowPortBounds( fl_xid(w), &wrect );
+      GLint rect[] = { w->x(), wrect.bottom-w->h()-w->y(), w->w(), w->h() };
+      aglSetInteger( context, AGL_BUFFER_RECT, rect );
+      aglEnable( context, AGL_BUFFER_RECT );
+    }
+    aglSetDrawable(context, GetWindowPort( fl_xid(w) ) );
+    aglSetCurrentContext(context);
+#  else
+    glXMakeCurrent(fl_display, fl_xid(w), context);
+#  endif
+  }
+}
+
+void fl_no_gl_context() {
+  cached_context = 0;
+  cached_window = 0;
+#  ifdef WIN32
+  wglMakeCurrent(0, 0);
+#  elif defined(__APPLE_QD__)
+  aglSetCurrentContext(0);
+#  elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  aglSetCurrentContext(0);
+#  else
+  glXMakeCurrent(fl_display, 0, 0);
+#  endif
+}
+
+void fl_delete_gl_context(GLContext context) {
+  if (cached_context == context) fl_no_gl_context();
+#  ifdef WIN32
+  wglDeleteContext(context);
+#  elif defined(__APPLE_QD__)
+  aglSetCurrentContext( NULL );
+  aglSetDrawable( context, NULL );    
+  aglDestroyContext( context );
+#  elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  aglSetCurrentContext( NULL );
+  aglSetDrawable( context, NULL );
+  aglDestroyContext( context );
+#  else
+  glXDestroyContext(fl_display, context);
+#  endif
+  del_context(context);
+}
+
+#endif // HAVE_GL
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Gl_Overlay.cxx b/Utilities/FLTK/src/Fl_Gl_Overlay.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2e25830249ba247aa53d222c4200359fcc240f78
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Gl_Overlay.cxx
@@ -0,0 +1,250 @@
+//
+// "$Id$"
+//
+// OpenGL overlay code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include "Fl_Gl_Choice.H"
+#include <FL/Fl_Gl_Window.H>
+#include <stdlib.h>
+
+#if !HAVE_GL_OVERLAY
+
+int Fl_Gl_Window::can_do_overlay() {return 0;}
+
+void Fl_Gl_Window::make_overlay() {overlay = this;}
+
+#else
+
+// Methods on Fl_Gl_Window that create an overlay window.  Because
+// many programs don't need the overlay, this is seperated into this
+// source file so it is not linked in if not used.
+
+// Under X this is done by creating another window, of class _Fl_Gl_Overlay
+// which is a subclass of Fl_Gl_Window except it uses the overlay planes.
+// A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.
+
+// Under win32 another GLX context is created to draw into the overlay
+// and it is stored in into the "overlay" pointer.
+
+// In both cases if overlay hardware is unavailable, the overlay is
+// "faked" by drawing into the main layers.  This is indicated by
+// setting overlay == this.
+
+#ifndef WIN32
+////////////////////////////////////////////////////////////////
+// X version
+
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+extern uchar fl_overlay;
+
+class _Fl_Gl_Overlay : public Fl_Gl_Window {
+  void flush();
+  void draw();
+public:
+  void show();
+  _Fl_Gl_Overlay(int x, int y, int w, int h) :
+    Fl_Gl_Window(x,y,w,h) {
+    set_flag(INACTIVE);
+  }
+};
+
+void _Fl_Gl_Overlay::flush() {
+  make_current();
+#ifdef BOXX_BUGS
+  // The BoXX overlay is broken and you must not call swap-buffers. This
+  // code will make it work, but we lose because machines that do support
+  // double-buffered overlays will blink when they don't have to
+  glDrawBuffer(GL_FRONT);
+  draw();
+#else
+  draw();
+  swap_buffers();
+#endif
+  glFlush();
+  valid(1);
+}
+
+void _Fl_Gl_Overlay::draw() {
+  if (!valid_) glClearIndex((GLfloat)fl_transparent_pixel);
+  if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
+  Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
+  uchar save_valid = w->valid_;
+  w->valid_ = valid_;
+  fl_overlay = 1;
+  w->draw_overlay();
+  fl_overlay = 0;
+  valid_ = w->valid_;
+  w->valid_ = save_valid;
+}
+
+void _Fl_Gl_Overlay::show() {
+  if (!shown()) {
+    fl_background_pixel = int(fl_transparent_pixel);
+    Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+    fl_background_pixel = -1;
+    // find the outermost window to tell wm about the colormap:
+    Fl_Window *w = window();
+    for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
+    XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
+    context(fl_create_gl_context(fl_overlay_visual), 1);
+    valid(0);
+  }
+  Fl_Gl_Window::show();
+}
+
+int Fl_Gl_Window::can_do_overlay() {
+  return fl_find_overlay_visual() != 0;
+}
+
+void Fl_Gl_Window::make_overlay() {
+  if (overlay) return;
+  if (can_do_overlay()) {
+    _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
+    overlay = o;
+    add(*o);
+    o->show();
+  } else {
+    overlay = this; // fake the overlay
+  }
+}
+
+#else
+////////////////////////////////////////////////////////////////
+// WIN32 version:
+
+//static COLORREF *palette;
+extern int fl_overlay_depth;
+
+void Fl_Gl_Window::make_overlay() {
+  if (overlay) return;
+
+  GLContext context = fl_create_gl_context(this, g, 1);
+  if (!context) {overlay = this; return;} // fake the overlay
+
+  HDC hdc = Fl_X::i(this)->private_dc;
+  overlay = context;
+  LAYERPLANEDESCRIPTOR pfd;
+  wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd);
+  if (!pfd.iPixelType) {
+    ; // full-color overlay
+  } else {
+    fl_overlay_depth = pfd.cColorBits; // used by gl_color()
+    if (fl_overlay_depth > 8) fl_overlay_depth = 8;
+    COLORREF palette[256];
+    int n = (1<<fl_overlay_depth)-1;
+    // copy all colors except #0 into the overlay palette:
+    for (int i = 0; i <= n; i++) {
+      uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
+      palette[i] = RGB(r,g,b);
+    }
+    // always provide black & white in the last 2 pixels:
+    if (fl_overlay_depth < 8) {
+      palette[n-1] = RGB(0,0,0);
+      palette[n] = RGB(255,255,255);
+    }
+    // and use it:
+    wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
+    wglRealizeLayerPalette(hdc, 1, TRUE);
+  }
+  valid(0);
+  return;
+}
+
+int Fl_Gl_Window::can_do_overlay() {
+  if (!g) {
+    g = Fl_Gl_Choice::find(mode_,alist);
+    if (!g) return 0;
+  }
+  return (g->pfd.bReserved & 15) != 0;
+}
+
+////////////////////////////////////////////////////////////////
+#endif
+
+#endif
+
+void Fl_Gl_Window::redraw_overlay() {
+  if (!shown()) return;
+  make_overlay();
+#ifdef __APPLE__
+  redraw();
+#else
+#ifndef WIN32
+  if (overlay != this)
+    ((Fl_Gl_Window*)overlay)->redraw();
+  else
+#endif
+    damage(FL_DAMAGE_OVERLAY);
+#endif
+}
+
+void Fl_Gl_Window::make_overlay_current() {
+  make_overlay();
+#ifdef __APPLE__
+  // this is not very useful, but unfortunatly, Apple decided
+  // that front buffer drawing can no longer (OS X 10.4) be 
+  // supported on their platforms.
+  make_current();
+#else
+#if HAVE_GL_OVERLAY
+  if (overlay != this) {
+#ifdef WIN32
+    fl_set_gl_context(this, (GLContext)overlay);
+//  if (fl_overlay_depth)
+//    wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
+#else
+    ((Fl_Gl_Window*)overlay)->make_current();
+#endif
+  } else
+#endif
+    glDrawBuffer(GL_FRONT);
+#endif
+}
+
+void Fl_Gl_Window::hide_overlay() {
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+  // nothing needs to be done?  Or should it be erased?
+#else
+  if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
+#endif
+#endif
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Gl_Window.cxx b/Utilities/FLTK/src/Fl_Gl_Window.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..97246c278b46655c31b645860bad8c63a4ac207b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Gl_Window.cxx
@@ -0,0 +1,427 @@
+//
+// "$Id$"
+//
+// OpenGL window code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include "flstring.h"
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include "Fl_Gl_Choice.H"
+#include <FL/Fl_Gl_Window.H>
+#include <stdlib.h>
+
+////////////////////////////////////////////////////////////////
+
+// The symbol SWAP_TYPE defines what is in the back buffer after doing
+// a glXSwapBuffers().
+
+// The OpenGl documentation says that the contents of the backbuffer
+// are "undefined" after glXSwapBuffers().  However, if we know what
+// is in the backbuffers then we can save a good deal of time.  For
+// this reason you can define some symbols to describe what is left in
+// the back buffer.
+
+// Having not found any way to determine this from glx (or wgl) I have
+// resorted to letting the user specify it with an environment variable,
+// GL_SWAP_TYPE, it should be equal to one of these symbols:
+
+// contents of back buffer after glXSwapBuffers():
+#define UNDEFINED 1 	// anything
+#define SWAP 2		// former front buffer (same as unknown)
+#define COPY 3		// unchanged
+#define NODAMAGE 4	// unchanged even by X expose() events
+
+static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable
+
+////////////////////////////////////////////////////////////////
+
+int Fl_Gl_Window::can_do(int a, const int *b) {
+  return Fl_Gl_Choice::find(a,b) != 0;
+}
+
+void Fl_Gl_Window::show() {
+  if (!shown()) {
+    if (!g) {
+      g = Fl_Gl_Choice::find(mode_,alist);
+
+      if (!g && (mode_ & FL_DOUBLE) == FL_SINGLE) {
+        g = Fl_Gl_Choice::find(mode_ | FL_DOUBLE,alist);
+	if (g) mode_ |= FL_FAKE_SINGLE;
+      }
+
+      if (!g) {
+        Fl::error("Insufficient GL support");
+	return;
+      }
+    }
+#if !defined(WIN32) && !defined(__APPLE__)
+    Fl_X::make_xid(this, g->vis, g->colormap);
+    if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show();
+#endif
+  }
+  Fl_Window::show();
+}
+
+void Fl_Gl_Window::invalidate() {
+  valid(0);
+#ifndef WIN32
+  if (overlay) ((Fl_Gl_Window*)overlay)->valid(0);
+#endif
+}
+
+int Fl_Gl_Window::mode(int m, const int *a) {
+  if (m == mode_ && a == alist) return 0;
+#ifndef __APPLE__
+  int oldmode = mode_;
+#endif // !__APPLE__
+#if !defined(WIN32) && !defined(__APPLE__)
+  Fl_Gl_Choice* oldg = g;
+#endif // !WIN32 && !__APPLE__
+  context(0);
+  mode_ = m; alist = a;
+  if (shown()) {
+    g = Fl_Gl_Choice::find(m, a);
+#if defined(WIN32)
+    if (!g || (oldmode^m)&FL_DOUBLE) {
+      hide();
+      show();
+    }
+#elif defined(__APPLE_QD__)
+    redraw();
+#elif defined(__APPLE_QUARTZ__)
+    // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+    redraw();
+#else
+    // under X, if the visual changes we must make a new X window (yuck!):
+    if (!g || g->vis->visualid!=oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) {
+      hide();
+      show();
+    }
+#endif
+  } else {
+    g = 0;
+  }
+  return 1;
+}
+
+#define NON_LOCAL_CONTEXT 0x80000000
+
+void Fl_Gl_Window::make_current() {
+//  puts("Fl_Gl_Window::make_current()");
+//  printf("make_current: context_=%p\n", context_);
+  if (!context_) {
+    mode_ &= ~NON_LOCAL_CONTEXT;
+    context_ = fl_create_gl_context(this, g);
+    valid(0);
+  }
+  fl_set_gl_context(this, context_);
+
+#ifdef __APPLE__
+  // Set the buffer rectangle here, since in resize() we won't have the
+  // correct parent window size to work with...
+  GLint xywh[4];
+
+  if (window()) {
+    xywh[0] = x();
+    xywh[1] = window()->h() - y() - h();
+  } else {
+    xywh[0] = 0;
+    xywh[1] = 0;
+  }
+
+  xywh[2] = w();
+  xywh[3] = h();
+
+  aglEnable(context_, AGL_BUFFER_RECT);
+  aglSetInteger(context_, AGL_BUFFER_RECT, xywh);
+//  printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]);
+#endif // __APPLE__
+
+#if defined(WIN32) && USE_COLORMAP
+  if (fl_palette) {
+    fl_GetDC(fl_xid(this));
+    SelectPalette(fl_gc, fl_palette, FALSE);
+    RealizePalette(fl_gc);
+  }
+#endif // USE_COLORMAP
+  if (mode_ & FL_FAKE_SINGLE) {
+    glDrawBuffer(GL_FRONT);
+    glReadBuffer(GL_FRONT);
+  }
+  current_ = this;
+}
+
+void Fl_Gl_Window::ortho() {
+// Alpha NT seems to have a broken OpenGL that does not like negative coords:
+#ifdef _M_ALPHA
+  glLoadIdentity();
+  glViewport(0, 0, w(), h());
+  glOrtho(0, w(), 0, h(), -1, 1);
+#else
+  GLint v[2];
+  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v);
+  glLoadIdentity();
+  glViewport(w()-v[0], h()-v[1], v[0], v[1]);
+  glOrtho(w()-v[0], w(), h()-v[1], h(), -1, 1);
+#endif
+}
+
+void Fl_Gl_Window::swap_buffers() {
+#ifdef WIN32
+#  if HAVE_GL_OVERLAY
+  // Do not swap the overlay, to match GLX:
+  BOOL ret = wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE);
+  DWORD err = GetLastError();;
+#  else
+  SwapBuffers(Fl_X::i(this)->private_dc);
+#  endif
+#elif defined(__APPLE_QD__)
+  aglSwapBuffers((AGLContext)context_);
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  aglSwapBuffers((AGLContext)context_);
+#else
+  glXSwapBuffers(fl_display, fl_xid(this));
+#endif
+}
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+uchar fl_overlay; // changes how fl_color() works
+int fl_overlay_depth = 0;
+#endif
+
+void Fl_Gl_Window::flush() {
+  uchar save_valid = valid_;
+
+#ifdef __APPLE_QD__
+  //: clear previous clipping in this shared port
+  GrafPtr port = GetWindowPort( fl_xid(this) );
+  Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff );
+  GrafPtr old; GetPort( &old );
+  SetPort( port );
+  ClipRect( &rect );
+  SetPort( old );
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  //: clear previous clipping in this shared port
+  GrafPtr port = GetWindowPort( fl_xid(this) );
+  Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff );
+  GrafPtr old; GetPort( &old );
+  SetPort( port );
+  ClipRect( &rect );
+  SetPort( old );
+#endif
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+
+  bool fixcursor = false; // for fixing the SGI 320 bug
+
+  // Draw into hardware overlay planes if they are damaged:
+  if (overlay && overlay != this
+      && (damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid)) {
+    // SGI 320 messes up overlay with user-defined cursors:
+    if (Fl_X::i(this)->cursor && Fl_X::i(this)->cursor != fl_default_cursor) {
+      fixcursor = true; // make it restore cursor later
+      SetCursor(0);
+    }
+    fl_set_gl_context(this, (GLContext)overlay);
+    if (fl_overlay_depth)
+      wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
+    glDisable(GL_SCISSOR_TEST);
+    glClear(GL_COLOR_BUFFER_BIT);
+    fl_overlay = 1;
+    draw_overlay();
+    fl_overlay = 0;
+    valid(save_valid);
+    wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_OVERLAY1);
+    // if only the overlay was damaged we are done, leave main layer alone:
+    if (damage() == FL_DAMAGE_OVERLAY) {
+      if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
+      return;
+    }
+  }
+#endif
+
+  make_current();
+
+  if (mode_ & FL_DOUBLE) {
+
+    glDrawBuffer(GL_BACK);
+
+    if (!SWAP_TYPE) {
+#ifdef __APPLE_QD__
+      SWAP_TYPE = COPY;
+#elif defined __APPLE_QUARTZ__
+      // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+      SWAP_TYPE = COPY;
+#else
+      SWAP_TYPE = UNDEFINED;
+#endif
+      const char* c = getenv("GL_SWAP_TYPE");
+      if (c) {
+	if (!strcmp(c,"COPY")) SWAP_TYPE = COPY;
+	else if (!strcmp(c, "NODAMAGE")) SWAP_TYPE = NODAMAGE;
+	else if (!strcmp(c, "SWAP")) SWAP_TYPE = SWAP;
+      }
+    }
+
+    if (SWAP_TYPE == NODAMAGE) {
+
+      // don't draw if only overlay damage or expose events:
+      if ((damage()&~(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE)) || !save_valid)
+	draw();
+      swap_buffers();
+
+    } else if (SWAP_TYPE == COPY) {
+
+      // don't draw if only the overlay is damaged:
+      if (damage() != FL_DAMAGE_OVERLAY || !save_valid) draw();
+      swap_buffers();
+
+    } else { // SWAP_TYPE == UNDEFINED
+
+      // If we are faking the overlay, use CopyPixels to act like
+      // SWAP_TYPE == COPY.  Otherwise overlay redraw is way too slow.
+      if (overlay == this) {
+	// don't draw if only the overlay is damaged:
+	if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw();
+	// we use a seperate context for the copy because rasterpos must be 0
+	// and depth test needs to be off:
+	static GLContext ortho_context = 0;
+	static Fl_Gl_Window* ortho_window = 0;
+	int orthoinit = !ortho_context;
+	if (orthoinit) ortho_context = fl_create_gl_context(this, g);
+	fl_set_gl_context(this, ortho_context);
+	if (orthoinit || !save_valid || ortho_window != this) {
+	  glDisable(GL_DEPTH_TEST);
+	  glReadBuffer(GL_BACK);
+	  glDrawBuffer(GL_FRONT);
+	  glLoadIdentity();
+	  glViewport(0, 0, w(), h());
+	  glOrtho(0, w(), 0, h(), -1, 1);
+	  glRasterPos2i(0,0);
+	  ortho_window = this;
+	}
+	glCopyPixels(0,0,w(),h(),GL_COLOR);
+	make_current(); // set current context back to draw overlay
+	damage1_ = 0;
+
+      } else {
+	damage1_ = damage();
+	clear_damage(0xff); draw();
+	swap_buffers();
+      }
+
+    }
+
+    if (overlay==this) { // fake overlay in front buffer
+      glDrawBuffer(GL_FRONT);
+      draw_overlay();
+      glDrawBuffer(GL_BACK);
+      glFlush();
+    }
+
+  } else {	// single-buffered context is simpler:
+
+    draw();
+    if (overlay == this) draw_overlay();
+    glFlush();
+
+  }
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+  if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
+#endif
+  valid(1);
+}
+
+void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
+//  printf("Fl_Gl_Window::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H);
+//  printf("current: x()=%d, y()=%d, w()=%d, h()=%d\n", x(), y(), w(), h());
+
+  if (W != w() || H != h()) valid(0);
+
+#ifdef __APPLE__
+  if (X != x() || Y != y() || W != w() || H != h()) aglUpdateContext(context_);
+#elif !defined(WIN32)
+  if ((W != w() || H != h()) && !resizable() && overlay && overlay != this) {
+    ((Fl_Gl_Window*)overlay)->resize(0,0,W,H);
+  }
+#endif
+
+  Fl_Window::resize(X,Y,W,H);
+}
+
+void Fl_Gl_Window::context(void* v, int destroy_flag) {
+  if (context_ && !(mode_&NON_LOCAL_CONTEXT)) fl_delete_gl_context(context_);
+  context_ = (GLContext)v;
+  if (destroy_flag) mode_ &= ~NON_LOCAL_CONTEXT;
+  else mode_ |= NON_LOCAL_CONTEXT;
+}    
+
+void Fl_Gl_Window::hide() {
+  context(0);
+#if HAVE_GL_OVERLAY && defined(WIN32)
+  if (overlay && overlay != this) {
+    fl_delete_gl_context((GLContext)overlay);
+    overlay = 0;
+  }
+#endif
+  Fl_Window::hide();
+}
+
+Fl_Gl_Window::~Fl_Gl_Window() {
+  hide();
+//  delete overlay; this is done by ~Fl_Group
+}
+
+void Fl_Gl_Window::init() {
+  end(); // we probably don't want any children
+  box(FL_NO_BOX);
+
+  mode_    = FL_RGB | FL_DEPTH | FL_DOUBLE;
+  alist    = 0;
+  context_ = 0;
+  g        = 0;
+  overlay  = 0;
+  valid_   = 0;
+  damage1_ = 0;
+
+#if 0 // This breaks resizing on Linux/X11
+  int H = h();
+  h(1); // Make sure we actually do something in resize()...
+  resize(x(), y(), w(), H);
+#endif // 0
+}
+
+void Fl_Gl_Window::draw_overlay() {}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Group.cxx b/Utilities/FLTK/src/Fl_Group.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a9aecf0976811d8941ad65ae10dd111e663a3d48
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Group.cxx
@@ -0,0 +1,612 @@
+//
+// "$Id$"
+//
+// Group widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// The Fl_Group is the only defined container type in FLTK.
+
+// Fl_Window itself is a subclass of this, and most of the event
+// handling is designed so windows themselves work correctly.
+
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_draw.H>
+#include <stdlib.h>
+
+Fl_Group* Fl_Group::current_;
+
+// Hack: A single child is stored in the pointer to the array, while
+// multiple children are stored in an allocated array:
+Fl_Widget*const* Fl_Group::array() const {
+  return children_ <= 1 ? (Fl_Widget**)(&array_) : array_;
+}
+
+int Fl_Group::find(const Fl_Widget* o) const {
+  Fl_Widget*const* a = array();
+  int i; for (i=0; i < children_; i++) if (*a++ == o) break;
+  return i;
+}
+
+// Metrowerks CodeWarrior and others can't export the static
+// class member: current_, so these methods can't be inlined...
+void Fl_Group::begin() {current_ = this;}
+void Fl_Group::end() {current_ = (Fl_Group*)parent();}
+Fl_Group *Fl_Group::current() {return current_;}
+void Fl_Group::current(Fl_Group *g) {current_ = g;}
+
+extern Fl_Widget* fl_oldfocus; // set by Fl::focus
+
+// For back-compatability, we must adjust all events sent to child
+// windows so they are relative to that window.
+
+static int send(Fl_Widget* o, int event) {
+  if (o->type() < FL_WINDOW) return o->handle(event);
+  switch ( event )
+  {
+  case FL_DND_ENTER:
+  case FL_DND_DRAG:
+    // figure out correct type of event:
+    event = (o->contains(Fl::belowmouse())) ? FL_DND_DRAG : FL_DND_ENTER;
+  }
+  int save_x = Fl::e_x; Fl::e_x -= o->x();
+  int save_y = Fl::e_y; Fl::e_y -= o->y();
+  int ret = o->handle(event);
+  Fl::e_y = save_y;
+  Fl::e_x = save_x;
+  switch ( event )
+  {
+  case FL_ENTER:
+  case FL_DND_ENTER:
+    // Successful completion of FL_ENTER means the widget is now the
+    // belowmouse widget, but only call Fl::belowmouse if the child
+    // widget did not do so:
+    if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o);
+    break;
+  }
+  return ret;
+}
+
+// translate the current keystroke into up/down/left/right for navigation:
+#define ctrl(x) (x^0x40)
+static int navkey() {
+  switch (Fl::event_key()) {
+  case 0: // not an FL_KEYBOARD/FL_SHORTCUT event
+    break;
+  case FL_Tab:
+    if (!Fl::event_state(FL_SHIFT)) return FL_Right;
+  case 0xfe20: // XK_ISO_Left_Tab
+    return FL_Left;
+  case FL_Right:
+    return FL_Right;
+  case FL_Left:
+    return FL_Left;
+  case FL_Up:
+    return FL_Up;
+  case FL_Down:
+    return FL_Down;
+  }
+  return 0;
+}
+
+int Fl_Group::handle(int event) {
+
+  Fl_Widget*const* a = array();
+  int i;
+  Fl_Widget* o;
+
+  switch (event) {
+
+  case FL_FOCUS:
+    switch (navkey()) {
+    default:
+      if (savedfocus_ && savedfocus_->take_focus()) return 1;
+    case FL_Right:
+    case FL_Down:
+      for (i = children(); i--;) if ((*a++)->take_focus()) return 1;
+      break;
+    case FL_Left:
+    case FL_Up:
+      for (i = children(); i--;) if (a[i]->take_focus()) return 1;
+      break;
+    }
+    return 0;
+
+  case FL_UNFOCUS:
+    savedfocus_ = fl_oldfocus;
+    return 0;
+
+  case FL_KEYBOARD:
+    return navigation(navkey());
+
+  case FL_SHORTCUT:
+    for (i = children(); i--;) {
+      o = a[i];
+      if (o->takesevents() && Fl::event_inside(o) && send(o,FL_SHORTCUT))
+	return 1;
+    }
+    for (i = children(); i--;) {
+      o = a[i];
+      if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_SHORTCUT))
+	return 1;
+    }
+    if ((Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) return navigation(FL_Down);
+    return 0;
+
+  case FL_ENTER:
+  case FL_MOVE:
+    for (i = children(); i--;) {
+      o = a[i];
+      if (o->visible() && Fl::event_inside(o)) {
+	if (o->contains(Fl::belowmouse())) {
+	  return send(o,FL_MOVE);
+	} else {
+	  Fl::belowmouse(o);
+	  if (send(o,FL_ENTER)) return 1;
+	}
+      }
+    }
+    Fl::belowmouse(this);
+    return 1;
+
+  case FL_DND_ENTER:
+  case FL_DND_DRAG:
+    for (i = children(); i--;) {
+      o = a[i];
+      if (o->takesevents() && Fl::event_inside(o)) {
+	if (o->contains(Fl::belowmouse())) {
+	  return send(o,FL_DND_DRAG);
+	} else if (send(o,FL_DND_ENTER)) {
+	  if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o);
+	  return 1;
+	}
+      }
+    }
+    Fl::belowmouse(this);
+    return 0;
+
+  case FL_PUSH:
+    for (i = children(); i--;) {
+      o = a[i];
+      if (o->takesevents() && Fl::event_inside(o)) {
+	if (send(o,FL_PUSH)) {
+	  if (Fl::pushed() && !o->contains(Fl::pushed())) Fl::pushed(o);
+	  return 1;
+	}
+      }
+    }
+    return 0;
+
+  case FL_RELEASE:
+  case FL_DRAG:
+    o = Fl::pushed();
+    if (o == this) return 0;
+    else if (o) send(o,event);
+    else {
+      for (i = children(); i--;) {
+	o = a[i];
+	if (o->takesevents() && Fl::event_inside(o)) {
+	  if (send(o,event)) return 1;
+	}
+      }
+    }
+    return 0;
+
+  case FL_MOUSEWHEEL:
+    for (i = children(); i--;) {
+      o = a[i];
+      if (o->takesevents() && Fl::event_inside(o) && send(o,FL_MOUSEWHEEL))
+	return 1;
+    }
+    for (i = children(); i--;) {
+      o = a[i];
+      if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_MOUSEWHEEL))
+	return 1;
+    }
+    return 0;
+
+  case FL_DEACTIVATE:
+  case FL_ACTIVATE:
+    for (i = children(); i--;) {
+      o = *a++;
+      if (o->active()) o->handle(event);
+    }
+    return 1;
+
+  case FL_SHOW:
+  case FL_HIDE:
+    for (i = children(); i--;) {
+      o = *a++;
+      if (event == FL_HIDE && o == Fl::focus()) {
+        // Give up input focus...
+	int old_event = Fl::e_number;
+        o->handle(Fl::e_number = FL_UNFOCUS);
+	Fl::e_number = old_event;
+	Fl::focus(0);
+      }
+      if (o->visible()) o->handle(event);
+    }
+    return 1;
+
+  default:
+    // For all other events, try to give to each child, starting at focus:
+    for (i = 0; i < children(); i ++)
+      if (Fl::focus_ == a[i]) break;
+
+    if (i >= children()) i = 0;
+
+    if (children()) {
+      for (int j = i;;) {
+        if (a[j]->takesevents() || event != FL_MOUSEWHEEL) {
+          if (send(a[j], event)) return 1;
+	}
+        j++;
+        if (j >= children()) j = 0;
+        if (j == i) break;
+      }
+    }
+
+    return 0;
+  }
+}
+
+//void Fl_Group::focus(Fl_Widget *o) {Fl::focus(o); o->handle(FL_FOCUS);}
+
+#if 0
+const char *nameof(Fl_Widget *o) {
+  if (!o) return "NULL";
+  if (!o->label()) return "<no label>";
+  return o->label();
+}
+#endif
+
+// try to move the focus in response to a keystroke:
+int Fl_Group::navigation(int key) {
+  if (children() <= 1) return 0;
+  int i;
+  for (i = 0; ; i++) {
+    if (i >= children_) return 0;
+    if (array_[i]->contains(Fl::focus())) break;
+  }
+  Fl_Widget *previous = array_[i];
+
+  for (;;) {
+    switch (key) {
+    case FL_Right:
+    case FL_Down:
+      i++;
+      if (i >= children_) {
+	if (parent()) return 0;
+	i = 0;
+      }
+      break;
+    case FL_Left:
+    case FL_Up:
+      if (i) i--;
+      else {
+	if (parent()) return 0;
+	i = children_-1;
+      }
+      break;
+    default:
+      return 0;
+    }
+    Fl_Widget* o = array_[i];
+    if (o == previous) return 0;
+    switch (key) {
+    case FL_Down:
+    case FL_Up:
+      // for up/down, the widgets have to overlap horizontally:
+      if (o->x() >= previous->x()+previous->w() ||
+	  o->x()+o->w() <= previous->x()) continue;
+    }
+    if (o->take_focus()) return 1;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l)
+: Fl_Widget(X,Y,W,H,l) {
+  align(FL_ALIGN_TOP);
+  children_ = 0;
+  array_ = 0;
+  savedfocus_ = 0;
+  resizable_ = this;
+  sizes_ = 0; // this is allocated when first resize() is done
+  // Subclasses may want to construct child objects as part of their
+  // constructor, so make sure they are add()'d to this object.
+  // But you must end() the object!
+  begin();
+}
+
+void Fl_Group::clear() {
+  Fl_Widget*const* old_array = array();
+  int old_children = children();
+  // clear everything now, in case fl_fix_focus recursively calls us:
+  children_ = 0;
+  //array_ = 0; //dont do this, it will clobber old_array if only one child
+  savedfocus_ = 0;
+  resizable_ = this;
+  init_sizes();
+  // okay, now it is safe to destroy the children:
+  Fl_Widget*const* a = old_array;
+  for (int i=old_children; i--;) {
+    Fl_Widget* o = *a++;
+    if (o->parent() == this) delete o;
+  }
+  if (old_children > 1) free((void*)old_array);
+}
+
+Fl_Group::~Fl_Group() {
+  clear();
+}
+
+void Fl_Group::insert(Fl_Widget &o, int index) {
+  if (o.parent()) {
+    Fl_Group* g = (Fl_Group*)(o.parent());
+    int n = g->find(o);
+    if (g == this) {
+      if (index > n) index--;
+      if (index == n) return;
+    }
+    g->remove(o);
+  }
+  o.parent_ = this;
+  if (children_ == 0) { // use array pointer to point at single child
+    array_ = (Fl_Widget**)&o;
+  } else if (children_ == 1) { // go from 1 to 2 children
+    Fl_Widget* t = (Fl_Widget*)array_;
+    array_ = (Fl_Widget**)malloc(2*sizeof(Fl_Widget*));
+    if (index) {array_[0] = t; array_[1] = &o;}
+    else {array_[0] = &o; array_[1] = t;}
+  } else {
+    if (!(children_ & (children_-1))) // double number of children
+      array_ = (Fl_Widget**)realloc((void*)array_,
+				    2*children_*sizeof(Fl_Widget*));
+    int j; for (j = children_; j > index; j--) array_[j] = array_[j-1];
+    array_[j] = &o;
+  }
+  children_++;
+  init_sizes();
+}
+
+void Fl_Group::add(Fl_Widget &o) {insert(o, children_);}
+
+void Fl_Group::remove(Fl_Widget &o) {
+  if (!children_) return;
+  int i = find(o);
+  if (i >= children_) return;
+  if (&o == savedfocus_) savedfocus_ = 0;
+  o.parent_ = 0;
+  children_--;
+  if (children_ == 1) { // go from 2 to 1 child
+    Fl_Widget *t = array_[!i];
+    free((void*)array_);
+    array_ = (Fl_Widget**)t;
+  } else if (children_ > 1) { // delete from array
+    for (; i < children_; i++) array_[i] = array_[i+1];
+  }
+  init_sizes();
+}
+
+////////////////////////////////////////////////////////////////
+
+// Rather lame kludge here, I need to detect windows and ignore the
+// changes to X,Y, since all children are relative to X,Y.  That
+// is why I check type():
+
+// sizes array stores the initial positions of widgets as
+// left,right,top,bottom quads.  The first quad is the group, the
+// second is the resizable (clipped to the group), and the
+// rest are the children.  This is a convienent order for the
+// algorithim.  If you change this be sure to fix Fl_Tile which
+// also uses this array!
+
+void Fl_Group::init_sizes() {
+  delete[] sizes_; sizes_ = 0;
+}
+
+short* Fl_Group::sizes() {
+  if (!sizes_) {
+    short* p = sizes_ = new short[4*(children_+2)];
+    // first thing in sizes array is the group's size:
+    if (type() < FL_WINDOW) {p[0] = x(); p[2] = y();} else {p[0] = p[2] = 0;}
+    p[1] = p[0]+w(); p[3] = p[2]+h();
+    // next is the resizable's size:
+    p[4] = p[0]; // init to the group's size
+    p[5] = p[1];
+    p[6] = p[2];
+    p[7] = p[3];
+    Fl_Widget* r = resizable();
+    if (r && r != this) { // then clip the resizable to it
+      int t;
+      t = r->x(); if (t > p[0]) p[4] = t;
+      t +=r->w(); if (t < p[1]) p[5] = t;
+      t = r->y(); if (t > p[2]) p[6] = t;
+      t +=r->h(); if (t < p[3]) p[7] = t;
+    }
+    // next is all the children's sizes:
+    p += 8;
+    Fl_Widget*const* a = array();
+    for (int i=children_; i--;) {
+      Fl_Widget* o = *a++;
+      *p++ = o->x();
+      *p++ = o->x()+o->w();
+      *p++ = o->y();
+      *p++ = o->y()+o->h();
+    }
+  }
+  return sizes_;
+}
+
+void Fl_Group::resize(int X, int Y, int W, int H) {
+
+  if (!resizable() || W==w() && H==h() ) {
+
+    if (type() < FL_WINDOW) {
+      int dx = X-x();
+      int dy = Y-y();
+      Fl_Widget*const* a = array();
+      for (int i=children_; i--;) {
+	Fl_Widget* o = *a++;
+	o->resize(o->x()+dx, o->y()+dy, o->w(), o->h());
+      }
+    }
+
+  } else if (children_) {
+
+    short* p = sizes();
+
+    // get changes in size/position from the initial size:
+    int dx = X - p[0];
+    int dw = W - (p[1]-p[0]);
+    int dy = Y - p[2];
+    int dh = H - (p[3]-p[2]);
+    if (type() >= FL_WINDOW) dx = dy = 0;
+    p += 4;
+
+    // get initial size of resizable():
+    int IX = *p++;
+    int IR = *p++;
+    int IY = *p++;
+    int IB = *p++;
+
+    Fl_Widget*const* a = array();
+    for (int i=children_; i--;) {
+      Fl_Widget* o = *a++;
+#if 1
+      int XX = *p++;
+      if (XX >= IR) XX += dw;
+      else if (XX > IX) XX = IX+((XX-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
+      int R = *p++;
+      if (R >= IR) R += dw;
+      else if (R > IX) R = IX+((R-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
+
+      int YY = *p++;
+      if (YY >= IB) YY += dh;
+      else if (YY > IY) YY = IY+((YY-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
+      int B = *p++;
+      if (B >= IB) B += dh;
+      else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
+#else // much simpler code from Francois Ostiguy:
+      int XX = *p++;
+      if (XX >= IR) XX += dw;
+      else if (XX > IX) XX += dw * (XX-IX)/(IR-IX);
+      int R = *p++;
+      if (R >= IR) R += dw;
+      else if (R > IX) R = R + dw * (R-IX)/(IR-IX);
+
+      int YY = *p++;
+      if (YY >= IB) YY += dh;
+      else if (YY > IY) YY = YY + dh*(YY-IY)/(IB-IY);
+      int B = *p++;
+      if (B >= IB) B += dh;
+      else if (B > IY) B = B + dh*(B-IY)/(IB-IY);
+#endif
+      o->resize(XX+dx, YY+dy, R-XX, B-YY);
+    }
+  }
+
+  Fl_Widget::resize(X,Y,W,H);
+}
+
+void Fl_Group::draw_children() {
+  Fl_Widget*const* a = array();
+  if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing:
+    for (int i=children_; i--;) {
+      Fl_Widget& o = **a++;
+      draw_child(o);
+      draw_outside_label(o);
+    }
+  } else {	// only redraw the children that need it:
+    for (int i=children_; i--;) update_child(**a++);
+  }
+}
+
+void Fl_Group::draw() {
+  if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing:
+    draw_box();
+    draw_label();
+  }
+  draw_children();
+}
+
+// Draw a child only if it needs it:
+void Fl_Group::update_child(Fl_Widget& widget) const {
+  if (widget.damage() && widget.visible() && widget.type() < FL_WINDOW &&
+      fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) {
+    widget.draw();	
+    widget.clear_damage();
+  }
+}
+
+// Force a child to redraw:
+void Fl_Group::draw_child(Fl_Widget& widget) const {
+  if (widget.visible() && widget.type() < FL_WINDOW &&
+      fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) {
+    widget.clear_damage(FL_DAMAGE_ALL);
+    widget.draw();
+    widget.clear_damage();
+  }
+}
+
+extern char fl_draw_shortcut;
+
+// Parents normally call this to draw outside labels:
+void Fl_Group::draw_outside_label(const Fl_Widget& widget) const {
+  if (!widget.visible()) return;
+  // skip any labels that are inside the widget:
+  if (!(widget.align()&15) || (widget.align() & FL_ALIGN_INSIDE)) return;
+  // invent a box that is outside the widget:
+  int a = widget.align();
+  int X = widget.x();
+  int Y = widget.y();
+  int W = widget.w();
+  int H = widget.h();
+  if (a & FL_ALIGN_TOP) {
+    a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
+    Y = y();
+    H = widget.y()-Y;
+  } else if (a & FL_ALIGN_BOTTOM) {
+    a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
+    Y = Y+H;
+    H = y()+h()-Y;
+  } else if (a & FL_ALIGN_LEFT) {
+    a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
+    X = x();
+    W = widget.x()-X-3;
+  } else if (a & FL_ALIGN_RIGHT) {
+    a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
+    X = X+W+3;
+    W = x()+this->w()-X;
+  }
+  widget.draw_label(X,Y,W,H,(Fl_Align)a);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Help_Dialog.cxx b/Utilities/FLTK/src/Fl_Help_Dialog.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c38e7c8c0945ce2447f9fe704dcf6e125655ed72
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Help_Dialog.cxx
@@ -0,0 +1,321 @@
+//
+// "$Id$"
+//
+// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// generated by Fast Light User Interface Designer (fluid) version 1.0107
+
+#include "../FL/Fl_Help_Dialog.H"
+#include "flstring.h"
+#include <FL/fl_ask.H>
+
+void Fl_Help_Dialog::cb_view__i(Fl_Help_View*, void*) {
+  if (view_->filename())
+{
+  if (view_->changed())
+  {
+    index_ ++;
+
+    if (index_ >= 100)
+    {
+      memmove(line_, line_ + 10, sizeof(line_[0]) * 90);
+      memmove(file_, file_ + 10, sizeof(file_[0]) * 90);
+      index_ -= 10;
+    }
+
+    max_ = index_;
+
+    strlcpy(file_[index_], view_->filename(),sizeof(file_[0]));
+    line_[index_] = view_->topline();
+
+    if (index_ > 0)
+      back_->activate();
+    else
+      back_->deactivate();
+
+    forward_->deactivate();
+    window_->label(view_->title());
+  }
+  else // if ! view_->changed()
+  {
+    strlcpy(file_[index_], view_->filename(), sizeof(file_[0]));
+    line_[index_] = view_->topline();
+  }
+} else { // if ! view_->filename()
+  index_ = 0; // hitting an internal page will disable the back/fwd buffer
+  file_[index_][0] = 0; // unnamed internal page
+  line_[index_] = view_->topline();
+  back_->deactivate();
+  forward_->deactivate();
+};
+}
+void Fl_Help_Dialog::cb_view_(Fl_Help_View* o, void* v) {
+  ((Fl_Help_Dialog*)(o->parent()->user_data()))->cb_view__i(o,v);
+}
+
+void Fl_Help_Dialog::cb_Close_i(Fl_Button*, void*) {
+  window_->hide();
+}
+void Fl_Help_Dialog::cb_Close(Fl_Button* o, void* v) {
+  ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_Close_i(o,v);
+}
+
+void Fl_Help_Dialog::cb_back__i(Fl_Button*, void*) {
+  if (index_ > 0)
+  index_ --;
+
+if (index_ == 0)
+  back_->deactivate();
+
+forward_->activate();
+
+int l = line_[index_];
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+  view_->load(file_[index_]);
+
+view_->topline(l);
+}
+void Fl_Help_Dialog::cb_back_(Fl_Button* o, void* v) {
+  ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_back__i(o,v);
+}
+
+void Fl_Help_Dialog::cb_forward__i(Fl_Button*, void*) {
+  if (index_ < max_)
+  index_ ++;
+
+if (index_ >= max_)
+  forward_->deactivate();
+
+back_->activate();
+
+int l = view_->topline();
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+  view_->load(file_[index_]);
+
+view_->topline(l);
+}
+void Fl_Help_Dialog::cb_forward_(Fl_Button* o, void* v) {
+  ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_forward__i(o,v);
+}
+
+void Fl_Help_Dialog::cb_smaller__i(Fl_Button*, void*) {
+  if (view_->textsize() > 8)
+  view_->textsize(view_->textsize() - 2);
+
+if (view_->textsize() <= 8)
+  smaller_->deactivate();
+larger_->activate();
+}
+void Fl_Help_Dialog::cb_smaller_(Fl_Button* o, void* v) {
+  ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_smaller__i(o,v);
+}
+
+void Fl_Help_Dialog::cb_larger__i(Fl_Button*, void*) {
+  if (view_->textsize() < 18)
+  view_->textsize(view_->textsize() + 2);
+
+if (view_->textsize() >= 18)
+  larger_->deactivate();
+smaller_->activate();
+}
+void Fl_Help_Dialog::cb_larger_(Fl_Button* o, void* v) {
+  ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_larger__i(o,v);
+}
+
+void Fl_Help_Dialog::cb_find__i(Fl_Input*, void*) {
+  find_pos_ = view_->find(find_->value(), find_pos_);
+}
+void Fl_Help_Dialog::cb_find_(Fl_Input* o, void* v) {
+  ((Fl_Help_Dialog*)(o->parent()->parent()->parent()->user_data()))->cb_find__i(o,v);
+}
+
+Fl_Help_Dialog::Fl_Help_Dialog() {
+  Fl_Double_Window* w;
+  { Fl_Double_Window* o = window_ = new Fl_Double_Window(530, 385, "Help Dialog");
+    w = o;
+    o->user_data((void*)(this));
+    { Fl_Help_View* o = view_ = new Fl_Help_View(10, 10, 510, 330);
+      o->box(FL_DOWN_BOX);
+      o->color(FL_BACKGROUND_COLOR);
+      o->selection_color(FL_SELECTION_COLOR);
+      o->labeltype(FL_NORMAL_LABEL);
+      o->labelfont(0);
+      o->labelsize(14);
+      o->labelcolor(FL_FOREGROUND_COLOR);
+      o->callback((Fl_Callback*)cb_view_);
+      o->align(FL_ALIGN_TOP);
+      o->when(FL_WHEN_RELEASE);
+      o->end();
+      Fl_Group::current()->resizable(o);
+    }
+    { Fl_Group* o = new Fl_Group(10, 348, 510, 27);
+      { Fl_Button* o = new Fl_Button(456, 350, 64, 25, "Close");
+        o->callback((Fl_Callback*)cb_Close);
+        o->label(fl_close);
+      }
+      { Fl_Button* o = back_ = new Fl_Button(386, 350, 25, 25, "@<-");
+        o->tooltip("Show the previous help page.");
+        o->shortcut(0xff51);
+        o->labelcolor((Fl_Color)2);
+        o->callback((Fl_Callback*)cb_back_);
+      }
+      { Fl_Button* o = forward_ = new Fl_Button(421, 350, 25, 25, "@->");
+        o->tooltip("Show the next help page.");
+        o->shortcut(0xff53);
+        o->labelcolor((Fl_Color)2);
+        o->callback((Fl_Callback*)cb_forward_);
+      }
+      { Fl_Button* o = smaller_ = new Fl_Button(316, 350, 25, 25, "F");
+        o->tooltip("Make the help text smaller.");
+        o->labelfont(1);
+        o->labelsize(10);
+        o->callback((Fl_Callback*)cb_smaller_);
+      }
+      { Fl_Button* o = larger_ = new Fl_Button(351, 350, 25, 25, "F");
+        o->tooltip("Make the help text larger.");
+        o->labelfont(1);
+        o->labelsize(16);
+        o->callback((Fl_Callback*)cb_larger_);
+      }
+      { Fl_Group* o = new Fl_Group(10, 350, 296, 25);
+        o->box(FL_DOWN_BOX);
+        o->color(FL_BACKGROUND2_COLOR);
+        { Fl_Input* o = find_ = new Fl_Input(35, 352, 268, 21, "@search");
+          o->tooltip("find text in document");
+          o->box(FL_FLAT_BOX);
+          o->labelsize(13);
+          o->callback((Fl_Callback*)cb_find_);
+          o->when(FL_WHEN_ENTER_KEY_ALWAYS);
+          Fl_Group::current()->resizable(o);
+        }
+        o->end();
+        Fl_Group::current()->resizable(o);
+      }
+      o->end();
+    }
+    o->size_range(260, 150);
+    o->end();
+  }
+  back_->deactivate();
+forward_->deactivate();
+
+index_    = -1;
+max_      = 0;
+find_pos_ = 0;
+
+fl_register_images();
+}
+
+Fl_Help_Dialog::~Fl_Help_Dialog() {
+  delete window_;
+}
+
+int Fl_Help_Dialog::h() {
+  return (window_->h());
+}
+
+void Fl_Help_Dialog::hide() {
+  window_->hide();
+}
+
+void Fl_Help_Dialog::load(const char *f) {
+  view_->set_changed();
+view_->load(f);
+window_->label(view_->title());
+}
+
+void Fl_Help_Dialog::position(int xx, int yy) {
+  window_->position(xx, yy);
+}
+
+void Fl_Help_Dialog::resize(int xx, int yy, int ww, int hh) {
+  window_->resize(xx, yy, ww, hh);
+}
+
+void Fl_Help_Dialog::show() {
+  window_->show();
+}
+
+void Fl_Help_Dialog::show(int argc, char **argv) {
+  window_->show(argc, argv);
+}
+
+void Fl_Help_Dialog::textsize(uchar s) {
+  view_->textsize(s);
+
+if (s <= 8)
+  smaller_->deactivate();
+else
+  smaller_->activate();
+
+if (s >= 18)
+  larger_->deactivate();
+else
+  larger_->activate();
+}
+
+uchar Fl_Help_Dialog::textsize() {
+  return (view_->textsize());
+}
+
+void Fl_Help_Dialog::topline(const char *n) {
+  view_->topline(n);
+}
+
+void Fl_Help_Dialog::topline(int n) {
+  view_->topline(n);
+}
+
+void Fl_Help_Dialog::value(const char *f) {
+  view_->set_changed();
+view_->value(f);
+window_->label(view_->title());
+}
+
+const char * Fl_Help_Dialog::value() const {
+  return view_->value();
+}
+
+int Fl_Help_Dialog::visible() {
+  return (window_->visible());
+}
+
+int Fl_Help_Dialog::w() {
+  return (window_->w());
+}
+
+int Fl_Help_Dialog::x() {
+  return (window_->x());
+}
+
+int Fl_Help_Dialog::y() {
+  return (window_->y());
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Help_Dialog.fl b/Utilities/FLTK/src/Fl_Help_Dialog.fl
new file mode 100644
index 0000000000000000000000000000000000000000..e06c55500036c0ccc2df500fb757ed8534f09c45
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Help_Dialog.fl
@@ -0,0 +1,269 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0107 
+header_name {../FL/Fl_Help_Dialog.H} 
+code_name {.cxx}
+comment {//
+// "$Id: Fl_Help_Dialog.fl 4721 2005-12-19 16:52:11Z matt $"
+//
+// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+} {in_source in_header
+} 
+
+decl {\#include "flstring.h"} {} 
+
+decl {\#include <FL/fl_ask.H>} {} 
+
+class FL_EXPORT Fl_Help_Dialog {open
+} {
+  decl {int index_;} {}
+  decl {int max_;} {}
+  decl {int line_[100];} {}
+  decl {char file_[100][256];} {}
+  decl {int find_pos_;} {}
+  Function {Fl_Help_Dialog()} {} {
+    Fl_Window window_ {
+      label {Help Dialog} open
+      private xywh {398 65 530 385} type Double resizable size_range {260 150 0 0} visible
+    } {
+      Fl_Group view_ {
+        callback {if (view_->filename())
+{
+  if (view_->changed())
+  {
+    index_ ++;
+
+    if (index_ >= 100)
+    {
+      memmove(line_, line_ + 10, sizeof(line_[0]) * 90);
+      memmove(file_, file_ + 10, sizeof(file_[0]) * 90);
+      index_ -= 10;
+    }
+
+    max_ = index_;
+
+    strlcpy(file_[index_], view_->filename(),sizeof(file_[0]));
+    line_[index_] = view_->topline();
+
+    if (index_ > 0)
+      back_->activate();
+    else
+      back_->deactivate();
+
+    forward_->deactivate();
+    window_->label(view_->title());
+  }
+  else // if ! view_->changed()
+  {
+    strlcpy(file_[index_], view_->filename(), sizeof(file_[0]));
+    line_[index_] = view_->topline();
+  }
+} else { // if ! view_->filename()
+  index_ = 0; // hitting an internal page will disable the back/fwd buffer
+  file_[index_][0] = 0; // unnamed internal page
+  line_[index_] = view_->topline();
+  back_->deactivate();
+  forward_->deactivate();
+}} open
+        private xywh {10 10 510 330} box DOWN_BOX selection_color 15 resizable
+        code0 {\#include <FL/Fl_Help_View.H>}
+        class Fl_Help_View
+      } {}
+      Fl_Group {} {open
+        xywh {10 348 510 27}
+      } {
+        Fl_Button {} {
+          label Close
+          callback {window_->hide();}
+          private xywh {456 350 64 25}
+          code0 {o->label(fl_close);}
+        }
+        Fl_Button back_ {
+          label {@<-}
+          callback {if (index_ > 0)
+  index_ --;
+
+if (index_ == 0)
+  back_->deactivate();
+
+forward_->activate();
+
+int l = line_[index_];
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+  view_->load(file_[index_]);
+
+view_->topline(l);}
+          private tooltip {Show the previous help page.} xywh {386 350 25 25} shortcut 0xff51 labelcolor 2
+        }
+        Fl_Button forward_ {
+          label {@->}
+          callback {if (index_ < max_)
+  index_ ++;
+
+if (index_ >= max_)
+  forward_->deactivate();
+
+back_->activate();
+
+int l = view_->topline();
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+  view_->load(file_[index_]);
+
+view_->topline(l);}
+          private tooltip {Show the next help page.} xywh {421 350 25 25} shortcut 0xff53 labelcolor 2
+        }
+        Fl_Button smaller_ {
+          label F
+          callback {if (view_->textsize() > 8)
+  view_->textsize(view_->textsize() - 2);
+
+if (view_->textsize() <= 8)
+  smaller_->deactivate();
+larger_->activate();}
+          private tooltip {Make the help text smaller.} xywh {316 350 25 25} labelfont 1 labelsize 10
+        }
+        Fl_Button larger_ {
+          label F
+          callback {if (view_->textsize() < 18)
+  view_->textsize(view_->textsize() + 2);
+
+if (view_->textsize() >= 18)
+  larger_->deactivate();
+smaller_->activate();}
+          private tooltip {Make the help text larger.} xywh {351 350 25 25} labelfont 1 labelsize 16
+        }
+        Fl_Group {} {open
+          xywh {10 350 296 25} box DOWN_BOX color 7 resizable
+        } {
+          Fl_Input find_ {
+            label {@search}
+            callback {find_pos_ = view_->find(find_->value(), find_pos_);} selected
+            private tooltip {find text in document} xywh {35 352 268 21} box FLAT_BOX labelsize 13 when 10 resizable
+          }
+        }
+      }
+    }
+    code {back_->deactivate();
+forward_->deactivate();
+
+index_    = -1;
+max_      = 0;
+find_pos_ = 0;
+
+fl_register_images();} {}
+  }
+  Function {~Fl_Help_Dialog()} {} {
+    code {delete window_;} {}
+  }
+  Function {h()} {return_type int
+  } {
+    code {return (window_->h());} {}
+  }
+  Function {hide()} {return_type void
+  } {
+    code {window_->hide();} {}
+  }
+  Function {load(const char *f)} {return_type void
+  } {
+    code {view_->set_changed();
+view_->load(f);
+window_->label(view_->title());} {}
+  }
+  Function {position(int xx, int yy)} {return_type void
+  } {
+    code {window_->position(xx, yy);} {}
+  }
+  Function {resize(int xx, int yy, int ww, int hh)} {return_type void
+  } {
+    code {window_->resize(xx, yy, ww, hh);} {}
+  }
+  Function {show()} {return_type void
+  } {
+    code {window_->show();} {}
+  }
+  Function {show(int argc, char **argv)} {return_type void
+  } {
+    code {window_->show(argc, argv);} {}
+  }
+  Function {textsize(uchar s)} {return_type void
+  } {
+    code {view_->textsize(s);
+
+if (s <= 8)
+  smaller_->deactivate();
+else
+  smaller_->activate();
+
+if (s >= 18)
+  larger_->deactivate();
+else
+  larger_->activate();} {}
+  }
+  Function {textsize()} {return_type uchar
+  } {
+    code {return (view_->textsize());} {}
+  }
+  Function {topline(const char *n)} {return_type void
+  } {
+    code {view_->topline(n);} {}
+  }
+  Function {topline(int n)} {return_type void
+  } {
+    code {view_->topline(n);} {}
+  }
+  Function {value(const char *f)} {return_type void
+  } {
+    code {view_->set_changed();
+view_->value(f);
+window_->label(view_->title());} {}
+  }
+  Function {value() const} {return_type {const char *}
+  } {
+    code {return view_->value();} {}
+  }
+  Function {visible()} {return_type int
+  } {
+    code {return (window_->visible());} {}
+  }
+  Function {w()} {return_type int
+  } {
+    code {return (window_->w());} {}
+  }
+  Function {x()} {return_type int
+  } {
+    code {return (window_->x());} {}
+  }
+  Function {y()} {return_type int
+  } {
+    code {return (window_->y());} {}
+  }
+} 
+
+comment {
+//
+// End of "$Id: Fl_Help_Dialog.fl 4721 2005-12-19 16:52:11Z matt $".
+//} {in_source in_header
+} 
diff --git a/Utilities/FLTK/src/Fl_Help_View.cxx b/Utilities/FLTK/src/Fl_Help_View.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..83c97bcf80f80e5f08a62946579698421b7fb329
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Help_View.cxx
@@ -0,0 +1,2924 @@
+//
+// "$Id$"
+//
+// Fl_Help_View widget routines.
+//
+// Copyright 1997-2005 by Easy Software Products.
+// Image support donated by Matthias Melcher, Copyright 2000.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_Help_View::add_block()       - Add a text block to the list.
+//   Fl_Help_View::add_link()        - Add a new link to the list.
+//   Fl_Help_View::add_target()      - Add a new target to the list.
+//   Fl_Help_View::compare_targets() - Compare two targets.
+//   Fl_Help_View::do_align()        - Compute the alignment for a line in
+//                                     a block.
+//   Fl_Help_View::draw()            - Draw the Fl_Help_View widget.
+//   Fl_Help_View::format()          - Format the help text.
+//   Fl_Help_View::format_table()    - Format a table...
+//   Fl_Help_View::get_align()       - Get an alignment attribute.
+//   Fl_Help_View::get_attr()        - Get an attribute value from the string.
+//   Fl_Help_View::get_color()       - Get an alignment attribute.
+//   Fl_Help_View::handle()          - Handle events in the widget.
+//   Fl_Help_View::Fl_Help_View()    - Build a Fl_Help_View widget.
+//   Fl_Help_View::~Fl_Help_View()   - Destroy a Fl_Help_View widget.
+//   Fl_Help_View::load()            - Load the specified file.
+//   Fl_Help_View::resize()          - Resize the help widget.
+//   Fl_Help_View::topline()         - Set the top line to the named target.
+//   Fl_Help_View::topline()         - Set the top line by number.
+//   Fl_Help_View::value()           - Set the help text directly.
+//   scrollbar_callback()            - A callback for the scrollbar.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl_Help_View.H>
+#include <FL/Fl_Pixmap.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <ctype.h>
+#include <errno.h>
+#include <math.h>
+
+#if defined(WIN32) && ! defined(__CYGWIN__)
+#  include <io.h>
+#  include <direct.h>
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define getcwd _getcwd
+#else
+#  include <unistd.h>
+#endif // WIN32
+
+#define MAX_COLUMNS	200
+
+
+//
+// Typedef the C API sort function type the only way I know how...
+//
+
+extern "C"
+{
+  typedef int (*compare_func_t)(const void *, const void *);
+}
+
+
+//
+// Local functions...
+//
+
+static int	quote_char(const char *);
+static void	scrollbar_callback(Fl_Widget *s, void *);
+static void	hscrollbar_callback(Fl_Widget *s, void *);
+
+
+//
+// Broken image...
+//
+
+static const char *broken_xpm[] =
+		{
+		  "16 24 4 1",
+		  "@ c #000000",
+		  "  c #ffffff",
+		  "+ c none",
+		  "x c #ff0000",
+		  // pixels
+		  "@@@@@@@+++++++++",
+		  "@    @++++++++++",
+		  "@   @+++++++++++",
+		  "@   @++@++++++++",
+		  "@    @@+++++++++",
+		  "@     @+++@+++++",
+		  "@     @++@@++++@",
+		  "@ xxx  @@  @++@@",
+		  "@  xxx    xx@@ @",
+		  "@   xxx  xxx   @",
+		  "@    xxxxxx    @",
+		  "@     xxxx     @",
+		  "@    xxxxxx    @",
+		  "@   xxx  xxx   @",
+		  "@  xxx    xxx  @",
+		  "@ xxx      xxx @",
+		  "@              @",
+		  "@              @",
+		  "@              @",
+		  "@              @",
+		  "@              @",
+		  "@              @",
+		  "@              @",
+		  "@@@@@@@@@@@@@@@@",
+		  NULL
+		};
+
+static Fl_Pixmap broken_image(broken_xpm);
+
+
+//
+// 'Fl_Help_View::add_block()' - Add a text block to the list.
+//
+
+Fl_Help_Block *					// O - Pointer to new block
+Fl_Help_View::add_block(const char   *s,	// I - Pointer to start of block text
+                	int           xx,	// I - X position of block
+			int           yy,	// I - Y position of block
+			int           ww,	// I - Right margin of block
+			int           hh,	// I - Height of block
+			unsigned char border)	// I - Draw border?
+{
+  Fl_Help_Block	*temp;				// New block
+
+
+//  printf("add_block(s = %p, xx = %d, yy = %d, ww = %d, hh = %d, border = %d)\n",
+//         s, xx, yy, ww, hh, border);
+
+  if (nblocks_ >= ablocks_)
+  {
+    ablocks_ += 16;
+
+    if (ablocks_ == 16)
+      blocks_ = (Fl_Help_Block *)malloc(sizeof(Fl_Help_Block) * ablocks_);
+    else
+      blocks_ = (Fl_Help_Block *)realloc(blocks_, sizeof(Fl_Help_Block) * ablocks_);
+  }
+
+  temp = blocks_ + nblocks_;
+  memset(temp, 0, sizeof(Fl_Help_Block));
+  temp->start   = s;
+  temp->end     = s;
+  temp->x       = xx;
+  temp->y       = yy;
+  temp->w       = ww;
+  temp->h       = hh;
+  temp->border  = border;
+  temp->bgcolor = bgcolor_;
+  nblocks_ ++;
+
+  return (temp);
+}
+
+
+//
+// 'Fl_Help_View::add_link()' - Add a new link to the list.
+//
+
+void
+Fl_Help_View::add_link(const char *n,	// I - Name of link
+                      int        xx,	// I - X position of link
+		      int        yy,	// I - Y position of link
+		      int        ww,	// I - Width of link text
+		      int        hh)	// I - Height of link text
+{
+  Fl_Help_Link	*temp;			// New link
+  char		*target;		// Pointer to target name
+
+
+  if (nlinks_ >= alinks_)
+  {
+    alinks_ += 16;
+
+    if (alinks_ == 16)
+      links_ = (Fl_Help_Link *)malloc(sizeof(Fl_Help_Link) * alinks_);
+    else
+      links_ = (Fl_Help_Link *)realloc(links_, sizeof(Fl_Help_Link) * alinks_);
+  }
+
+  temp = links_ + nlinks_;
+
+  temp->x       = xx;
+  temp->y       = yy;
+  temp->w       = xx + ww;
+  temp->h       = yy + hh;
+
+  strlcpy(temp->filename, n, sizeof(temp->filename));
+
+  if ((target = strrchr(temp->filename, '#')) != NULL)
+  {
+    *target++ = '\0';
+    strlcpy(temp->name, target, sizeof(temp->name));
+  }
+  else
+    temp->name[0] = '\0';
+
+  nlinks_ ++;
+}
+
+
+//
+// 'Fl_Help_View::add_target()' - Add a new target to the list.
+//
+
+void
+Fl_Help_View::add_target(const char *n,	// I - Name of target
+                	int        yy)	// I - Y position of target
+{
+  Fl_Help_Target	*temp;			// New target
+
+
+  if (ntargets_ >= atargets_)
+  {
+    atargets_ += 16;
+
+    if (atargets_ == 16)
+      targets_ = (Fl_Help_Target *)malloc(sizeof(Fl_Help_Target) * atargets_);
+    else
+      targets_ = (Fl_Help_Target *)realloc(targets_, sizeof(Fl_Help_Target) * atargets_);
+  }
+
+  temp = targets_ + ntargets_;
+
+  temp->y = yy;
+  strlcpy(temp->name, n, sizeof(temp->name));
+
+  ntargets_ ++;
+}
+
+
+//
+// 'Fl_Help_View::compare_targets()' - Compare two targets.
+//
+
+int							// O - Result of comparison
+Fl_Help_View::compare_targets(const Fl_Help_Target *t0,	// I - First target
+                             const Fl_Help_Target *t1)	// I - Second target
+{
+  return (strcasecmp(t0->name, t1->name));
+}
+
+
+//
+// 'Fl_Help_View::do_align()' - Compute the alignment for a line in a block.
+//
+
+int						// O - New line
+Fl_Help_View::do_align(Fl_Help_Block *block,	// I - Block to add to
+                      int          line,	// I - Current line
+		      int          xx,		// I - Current X position
+		      int          a,		// I - Current alignment
+		      int          &l)		// IO - Starting link
+{
+  int	offset;					// Alignment offset
+
+
+  switch (a)
+  {
+    case RIGHT :	// Right align
+	offset = block->w - xx;
+	break;
+    case CENTER :	// Center
+	offset = (block->w - xx) / 2;
+	break;
+    default :		// Left align
+	offset = 0;
+	break;
+  }
+
+  block->line[line] = block->x + offset;
+
+  if (line < 31)
+    line ++;
+
+  while (l < nlinks_)
+  {
+    links_[l].x += offset;
+    links_[l].w += offset;
+    l ++;
+  }
+
+  return (line);
+}
+
+
+//
+// 'Fl_Help_View::draw()' - Draw the Fl_Help_View widget.
+//
+
+void
+Fl_Help_View::draw()
+{
+  int			i;		// Looping var
+  const Fl_Help_Block	*block;		// Pointer to current block
+  const char		*ptr,		// Pointer to text in block
+			*attrs;		// Pointer to start of element attributes
+  char			*s,		// Pointer into buffer
+			buf[1024],	// Text buffer
+			attr[1024];	// Attribute buffer
+  int			xx, yy, ww, hh;	// Current positions and sizes
+  int			line;		// Current line
+  unsigned char		font, fsize;	// Current font and size
+  int			head, pre,	// Flags for text
+			needspace;	// Do we need whitespace?
+  Fl_Boxtype		b = box() ? box() : FL_DOWN_BOX;
+					// Box to draw...
+  int			underline,	// Underline text?
+                        xtra_ww;        // Extra width for underlined space between words
+
+
+  // Draw the scrollbar(s) and box first...
+  ww = w() ;
+  hh = h();
+  i  = 0;
+
+  draw_box(b, x(), y(), ww, hh, bgcolor_);
+
+  if (hscrollbar_.visible()) {
+    draw_child(hscrollbar_);
+    hh -= 17;
+    i ++;
+  }
+  if (scrollbar_.visible()) {
+    draw_child(scrollbar_);
+    ww -= 17;
+    i ++;
+  }
+  if (i == 2) {
+    fl_color(FL_GRAY);
+    fl_rectf(x() + ww - Fl::box_dw(b) + Fl::box_dx(b),
+             y() + hh - Fl::box_dh(b) + Fl::box_dy(b), 17, 17);
+  }
+
+  if (!value_)
+    return;
+
+  // Clip the drawing to the inside of the box...
+  fl_push_clip(x() + Fl::box_dx(b), y() + Fl::box_dy(b),
+               ww - Fl::box_dw(b), hh - Fl::box_dh(b));
+  fl_color(textcolor_);
+
+  // Draw all visible blocks...
+  for (i = 0, block = blocks_; i < nblocks_; i ++, block ++)
+    if ((block->y + block->h) >= topline_ && block->y < (topline_ + h()))
+    {
+      line      = 0;
+      xx        = block->line[line];
+      yy        = block->y - topline_;
+      hh        = 0;
+      pre       = 0;
+      head      = 0;
+      needspace = 0;
+      underline = 0;
+
+      initfont(font, fsize);
+
+      for (ptr = block->start, s = buf; ptr < block->end;)
+      {
+	if ((*ptr == '<' || isspace(*ptr)) && s > buf)
+	{
+	  if (!head && !pre)
+	  {
+            // Check width...
+            *s = '\0';
+            s  = buf;
+            ww = (int)fl_width(buf);
+
+            if (needspace && xx > block->x)
+	      xx += (int)fl_width(' ');
+
+            if ((xx + ww) > block->w)
+	    {
+	      if (line < 31)
+	        line ++;
+	      xx = block->line[line];
+	      yy += hh;
+	      hh = 0;
+	    }
+
+            fl_draw(buf, xx + x() - leftline_, yy + y());
+	    if (underline) {
+              xtra_ww = isspace(*ptr)?(int)fl_width(' '):0;
+              fl_xyline(xx + x() - leftline_, yy + y() + 1,
+	                xx + x() - leftline_ + ww + xtra_ww);
+            }
+
+            xx += ww;
+	    if ((fsize + 2) > hh)
+	      hh = fsize + 2;
+
+	    needspace = 0;
+	  }
+	  else if (pre)
+	  {
+	    while (isspace(*ptr))
+	    {
+	      if (*ptr == '\n')
+	      {
+	        *s = '\0';
+                s = buf;
+
+                fl_draw(buf, xx + x() - leftline_, yy + y());
+		if (underline) fl_xyline(xx + x() - leftline_, yy + y() + 1,
+	                        	 xx + x() - leftline_ +
+					     (int)fl_width(buf));
+
+		if (line < 31)
+	          line ++;
+		xx = block->line[line];
+		yy += hh;
+		hh = fsize + 2;
+	      }
+	      else if (*ptr == '\t')
+	      {
+		// Do tabs every 8 columns...
+		while (((s - buf) & 7))
+	          *s++ = ' ';
+	      }
+	      else
+	        *s++ = ' ';
+
+              if ((fsize + 2) > hh)
+	        hh = fsize + 2;
+
+              ptr ++;
+	    }
+
+            if (s > buf)
+	    {
+	      *s = '\0';
+	      s = buf;
+
+              fl_draw(buf, xx + x() - leftline_, yy + y());
+	      ww = (int)fl_width(buf);
+	      if (underline) fl_xyline(xx + x() - leftline_, yy + y() + 1,
+	                               xx + x() - leftline_ + ww);
+              xx += ww;
+	    }
+
+	    needspace = 0;
+	  }
+	  else
+	  {
+            s = buf;
+
+	    while (isspace(*ptr))
+              ptr ++;
+	  }
+	}
+
+	if (*ptr == '<')
+	{
+	  ptr ++;
+
+          if (strncmp(ptr, "!--", 3) == 0)
+	  {
+	    // Comment...
+	    ptr += 3;
+	    if ((ptr = strstr(ptr, "-->")) != NULL)
+	    {
+	      ptr += 3;
+	      continue;
+	    }
+	    else
+	      break;
+	  }
+
+	  while (*ptr && *ptr != '>' && !isspace(*ptr))
+            if (s < (buf + sizeof(buf) - 1))
+	      *s++ = *ptr++;
+	    else
+	      ptr ++;
+
+	  *s = '\0';
+	  s = buf;
+
+	  attrs = ptr;
+	  while (*ptr && *ptr != '>')
+            ptr ++;
+
+	  if (*ptr == '>')
+            ptr ++;
+
+	  if (strcasecmp(buf, "HEAD") == 0)
+            head = 1;
+	  else if (strcasecmp(buf, "BR") == 0)
+	  {
+	    if (line < 31)
+	      line ++;
+	    xx = block->line[line];
+            yy += hh;
+	    hh = 0;
+	  }
+	  else if (strcasecmp(buf, "HR") == 0)
+	  {
+	    fl_line(block->x + x(), yy + y(), block->w + x(),
+	            yy + y());
+
+	    if (line < 31)
+	      line ++;
+	    xx = block->line[line];
+            yy += 2 * hh;
+	    hh = 0;
+	  }
+	  else if (strcasecmp(buf, "CENTER") == 0 ||
+        	   strcasecmp(buf, "P") == 0 ||
+        	   strcasecmp(buf, "H1") == 0 ||
+		   strcasecmp(buf, "H2") == 0 ||
+		   strcasecmp(buf, "H3") == 0 ||
+		   strcasecmp(buf, "H4") == 0 ||
+		   strcasecmp(buf, "H5") == 0 ||
+		   strcasecmp(buf, "H6") == 0 ||
+		   strcasecmp(buf, "UL") == 0 ||
+		   strcasecmp(buf, "OL") == 0 ||
+		   strcasecmp(buf, "DL") == 0 ||
+		   strcasecmp(buf, "LI") == 0 ||
+		   strcasecmp(buf, "DD") == 0 ||
+		   strcasecmp(buf, "DT") == 0 ||
+		   strcasecmp(buf, "PRE") == 0)
+	  {
+            if (tolower(buf[0]) == 'h')
+	    {
+	      font  = FL_HELVETICA_BOLD;
+	      fsize = (uchar)(textsize_ + '7' - buf[1]);
+	    }
+	    else if (strcasecmp(buf, "DT") == 0)
+	    {
+	      font  = (uchar)(textfont_ | FL_ITALIC);
+	      fsize = textsize_;
+	    }
+	    else if (strcasecmp(buf, "PRE") == 0)
+	    {
+	      font  = FL_COURIER;
+	      fsize = textsize_;
+	      pre   = 1;
+	    }
+
+            if (strcasecmp(buf, "LI") == 0)
+	    {
+#ifdef __APPLE_QUARTZ__
+              fl_font(FL_SYMBOL, fsize); 
+              fl_draw("\245", xx - fsize + x() - leftline_, yy + y());
+#else
+              fl_font(FL_SYMBOL, fsize);
+              fl_draw("\267", xx - fsize + x() - leftline_, yy + y());
+#endif
+	    }
+
+	    pushfont(font, fsize);
+	  }
+	  else if (strcasecmp(buf, "A") == 0 &&
+	           get_attr(attrs, "HREF", attr, sizeof(attr)) != NULL)
+	  {
+	    fl_color(linkcolor_);
+	    underline = 1;
+	  }
+	  else if (strcasecmp(buf, "/A") == 0)
+	  {
+	    fl_color(textcolor_);
+	    underline = 0;
+	  }
+	  else if (strcasecmp(buf, "FONT") == 0)
+	  {
+	    if (get_attr(attrs, "COLOR", attr, sizeof(attr)) != NULL) {
+	      fl_color(get_color(attr, textcolor_));
+	    }
+
+            if (get_attr(attrs, "FACE", attr, sizeof(attr)) != NULL) {
+	      if (!strncasecmp(attr, "helvetica", 9) ||
+	          !strncasecmp(attr, "arial", 5) ||
+		  !strncasecmp(attr, "sans", 4)) font = FL_HELVETICA;
+              else if (!strncasecmp(attr, "times", 5) ||
+	               !strncasecmp(attr, "serif", 5)) font = FL_TIMES;
+              else if (!strncasecmp(attr, "symbol", 6)) font = FL_SYMBOL;
+	      else font = FL_COURIER;
+            }
+
+            if (get_attr(attrs, "SIZE", attr, sizeof(attr)) != NULL) {
+              if (isdigit(attr[0] & 255)) {
+	        // Absolute size
+	        fsize = (int)(textsize_ * pow(1.2, atof(attr) - 3.0));
+	      } else {
+	        // Relative size
+	        fsize = (int)(fsize * pow(1.2, atof(attr) - 3.0));
+	      }
+	    }
+
+            pushfont(font, fsize);
+	  }
+	  else if (strcasecmp(buf, "/FONT") == 0)
+	  {
+	    fl_color(textcolor_);
+	    popfont(font, fsize);
+	  }
+	  else if (strcasecmp(buf, "U") == 0)
+	    underline = 1;
+	  else if (strcasecmp(buf, "/U") == 0)
+	    underline = 0;
+	  else if (strcasecmp(buf, "B") == 0 ||
+	           strcasecmp(buf, "STRONG") == 0)
+	    pushfont(font |= FL_BOLD, fsize);
+	  else if (strcasecmp(buf, "TD") == 0 ||
+	           strcasecmp(buf, "TH") == 0)
+          {
+	    int tx, ty, tw, th;
+
+	    if (tolower(buf[1]) == 'h')
+	      pushfont(font |= FL_BOLD, fsize);
+	    else
+	      pushfont(font = textfont_, fsize);
+
+            tx = block->x - 4 - leftline_;
+	    ty = block->y - topline_ - fsize - 3;
+            tw = block->w - block->x + 7;
+	    th = block->h + fsize - 5;
+
+            if (tx < 0)
+	    {
+	      tw += tx;
+	      tx  = 0;
+	    }
+
+	    if (ty < 0)
+	    {
+	      th += ty;
+	      ty  = 0;
+	    }
+
+            tx += x();
+	    ty += y();
+
+            if (block->bgcolor != bgcolor_)
+	    {
+	      fl_color(block->bgcolor);
+              fl_rectf(tx, ty, tw, th);
+              fl_color(textcolor_);
+	    }
+
+            if (block->border)
+              fl_rect(tx, ty, tw, th);
+	  }
+	  else if (strcasecmp(buf, "I") == 0 ||
+                   strcasecmp(buf, "EM") == 0)
+	    pushfont(font |= FL_ITALIC, fsize);
+	  else if (strcasecmp(buf, "CODE") == 0 ||
+	           strcasecmp(buf, "TT") == 0)
+	    pushfont(font = FL_COURIER, fsize);
+	  else if (strcasecmp(buf, "KBD") == 0)
+	    pushfont(font = FL_COURIER_BOLD, fsize);
+	  else if (strcasecmp(buf, "VAR") == 0)
+	    pushfont(font = FL_COURIER_ITALIC, fsize);
+	  else if (strcasecmp(buf, "/HEAD") == 0)
+            head = 0;
+	  else if (strcasecmp(buf, "/H1") == 0 ||
+		   strcasecmp(buf, "/H2") == 0 ||
+		   strcasecmp(buf, "/H3") == 0 ||
+		   strcasecmp(buf, "/H4") == 0 ||
+		   strcasecmp(buf, "/H5") == 0 ||
+		   strcasecmp(buf, "/H6") == 0 ||
+		   strcasecmp(buf, "/B") == 0 ||
+		   strcasecmp(buf, "/STRONG") == 0 ||
+		   strcasecmp(buf, "/I") == 0 ||
+		   strcasecmp(buf, "/EM") == 0 ||
+		   strcasecmp(buf, "/CODE") == 0 ||
+		   strcasecmp(buf, "/TT") == 0 ||
+		   strcasecmp(buf, "/KBD") == 0 ||
+		   strcasecmp(buf, "/VAR") == 0)
+	    popfont(font, fsize);
+	  else if (strcasecmp(buf, "/PRE") == 0)
+	  {
+	    popfont(font, fsize);
+	    pre = 0;
+	  }
+	  else if (strcasecmp(buf, "IMG") == 0)
+	  {
+	    Fl_Shared_Image *img = 0;
+	    int		width, height;
+	    char	wattr[8], hattr[8];
+
+
+            get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+            get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+	    width  = get_length(wattr);
+	    height = get_length(hattr);
+
+	    if (get_attr(attrs, "SRC", attr, sizeof(attr))) {
+	      img = get_image(attr, width, height);
+	      if (!width) width = img->w();
+	      if (!height) height = img->h();
+	    }
+
+	    if (!width || !height) {
+              if (get_attr(attrs, "ALT", attr, sizeof(attr)) == NULL) {
+	        strcpy(attr, "IMG");
+              }
+	    }
+
+	    ww = width;
+
+	    if (needspace && xx > block->x)
+	      xx += (int)fl_width(' ');
+
+	    if ((xx + ww) > block->w)
+	    {
+	      if (line < 31)
+		line ++;
+
+	      xx = block->line[line];
+	      yy += hh;
+	      hh = 0;
+	    }
+
+	    if (img) 
+	      img->draw(xx + x() - leftline_,
+	                yy + y() - fl_height() + fl_descent() + 2);
+
+	    xx += ww;
+	    if ((height + 2) > hh)
+	      hh = height + 2;
+
+	    needspace = 0;
+	  }
+	}
+	else if (*ptr == '\n' && pre)
+	{
+	  *s = '\0';
+	  s = buf;
+
+          fl_draw(buf, xx + x() - leftline_, yy + y());
+
+	  if (line < 31)
+	    line ++;
+	  xx = block->line[line];
+	  yy += hh;
+	  hh = fsize + 2;
+	  needspace = 0;
+
+	  ptr ++;
+	}
+	else if (isspace(*ptr))
+	{
+	  if (pre)
+	  {
+	    if (*ptr == ' ')
+	      *s++ = ' ';
+	    else
+	    {
+	      // Do tabs every 8 columns...
+	      while (((s - buf) & 7))
+	        *s++ = ' ';
+            }
+	  }
+
+          ptr ++;
+	  needspace = 1;
+	}
+	else if (*ptr == '&')
+	{
+	  ptr ++;
+
+          int qch = quote_char(ptr);
+
+	  if (qch < 0)
+	    *s++ = '&';
+	  else {
+	    *s++ = qch;
+	    ptr = strchr(ptr, ';') + 1;
+	  }
+
+          if ((fsize + 2) > hh)
+	    hh = fsize + 2;
+	}
+	else
+	{
+	  *s++ = *ptr++;
+
+          if ((fsize + 2) > hh)
+	    hh = fsize + 2;
+        }
+      }
+
+      *s = '\0';
+
+      if (s > buf && !pre && !head)
+      {
+	ww = (int)fl_width(buf);
+
+        if (needspace && xx > block->x)
+	  xx += (int)fl_width(' ');
+
+	if ((xx + ww) > block->w)
+	{
+	  if (line < 31)
+	    line ++;
+	  xx = block->line[line];
+	  yy += hh;
+	  hh = 0;
+	}
+      }
+
+      if (s > buf && !head)
+      {
+        fl_draw(buf, xx + x() - leftline_, yy + y());
+	if (underline) fl_xyline(xx + x() - leftline_, yy + y() + 1,
+	                         xx + x() - leftline_ + ww);
+      }
+    }
+
+  fl_pop_clip();
+}
+
+
+//
+// 'Fl_Help_View::find()' - Find the specified string...
+//
+
+int						// O - Matching position or -1 if not found
+Fl_Help_View::find(const char *s,		// I - String to find
+                   int        p)		// I - Starting position
+{
+  int		i,				// Looping var
+		c;				// Current character
+  Fl_Help_Block	*b;				// Current block
+  const char	*bp,				// Block matching pointer
+		*bs,				// Start of current comparison
+		*sp;				// Search string pointer
+
+
+  // Range check input and value...
+  if (!s || !value_) return -1;
+
+  if (p < 0 || p >= (int)strlen(value_)) p = 0;
+  else if (p > 0) p ++;
+
+  // Look for the string...
+  for (i = nblocks_, b = blocks_; i > 0; i --, b ++) {
+    if (b->end < (value_ + p))
+      continue;
+
+    if (b->start < (value_ + p)) bp = value_ + p;
+    else bp = b->start;
+
+    for (sp = s, bs = bp; *sp && *bp && bp < b->end; bp ++) {
+      if (*bp == '<') {
+        // skip to end of element...
+	while (*bp && bp < b->end && *bp != '>') bp ++;
+	continue;
+      } else if (*bp == '&') {
+        // decode HTML entity...
+	if ((c = quote_char(bp + 1)) < 0) c = '&';
+	else bp = strchr(bp + 1, ';') + 1;
+      } else c = *bp;
+
+      if (tolower(*sp) == tolower(c)) sp ++;
+      else {
+        // No match, so reset to start of search...
+	sp = s;
+	bs ++;
+	bp = bs;
+      }
+    }
+
+    if (!*sp) {
+      // Found a match!
+      topline(b->y - b->h);
+      return (b->end - value_);
+    }
+  }
+
+  // No match!
+  return (-1);
+}
+
+
+//
+// 'Fl_Help_View::format()' - Format the help text.
+//
+
+void
+Fl_Help_View::format()
+{
+  int		i;		// Looping var
+  int		done;		// Are we done yet?
+  Fl_Help_Block	*block,		// Current block
+		*cell;		// Current table cell
+  int		cells[MAX_COLUMNS],
+				// Cells in the current row...
+		row;		// Current table row (block number)
+  const char	*ptr,		// Pointer into block
+		*start,		// Pointer to start of element
+		*attrs;		// Pointer to start of element attributes
+  char		*s,		// Pointer into buffer
+		buf[1024],	// Text buffer
+		attr[1024],	// Attribute buffer
+		wattr[1024],	// Width attribute buffer
+		hattr[1024],	// Height attribute buffer
+		linkdest[1024];	// Link destination
+  int		xx, yy, ww, hh;	// Size of current text fragment
+  int		line;		// Current line in block
+  int		links;		// Links for current line
+  unsigned char	font, fsize;	// Current font and size
+  unsigned char	border;		// Draw border?
+  int		talign,		// Current alignment
+		newalign,	// New alignment
+		head,		// In the <HEAD> section?
+		pre,		// <PRE> text?
+		needspace;	// Do we need whitespace?
+  int		table_width,	// Width of table
+		table_offset;	// Offset of table
+  int		column,		// Current table column number
+		columns[MAX_COLUMNS];
+				// Column widths
+  Fl_Color	tc, rc;		// Table/row background color
+  Fl_Boxtype	b = box() ? box() : FL_DOWN_BOX;
+				// Box to draw...
+
+
+  // Reset document width...
+  hsize_ = w() - 24;
+
+  done = 0;
+  while (!done)
+  {
+    // Reset state variables...
+    done       = 1;
+    nblocks_   = 0;
+    nlinks_    = 0;
+    ntargets_  = 0;
+    size_      = 0;
+    bgcolor_   = color();
+    textcolor_ = textcolor();
+    linkcolor_ = selection_color();
+
+    tc = rc = bgcolor_;
+
+    strcpy(title_, "Untitled");
+
+    if (!value_)
+      return;
+
+    // Setup for formatting...
+    initfont(font, fsize);
+
+    line         = 0;
+    links        = 0;
+    xx           = 4;
+    yy           = fsize + 2;
+    ww           = 0;
+    column       = 0;
+    border       = 0;
+    hh           = 0;
+    block        = add_block(value_, xx, yy, hsize_, 0);
+    row          = 0;
+    head         = 0;
+    pre          = 0;
+    talign       = LEFT;
+    newalign     = LEFT;
+    needspace    = 0;
+    linkdest[0]  = '\0';
+    table_offset = 0;
+
+    for (ptr = value_, s = buf; *ptr;)
+    {
+      if ((*ptr == '<' || isspace(*ptr)) && s > buf)
+      {
+        // Get width...
+        *s = '\0';
+        ww = (int)fl_width(buf);
+
+	if (!head && !pre)
+	{
+          // Check width...
+          if (ww > hsize_) {
+	    hsize_ = ww;
+	    done   = 0;
+	    break;
+	  }
+
+          if (needspace && xx > block->x)
+	    ww += (int)fl_width(' ');
+
+  //        printf("line = %d, xx = %d, ww = %d, block->x = %d, block->w = %d\n",
+  //	       line, xx, ww, block->x, block->w);
+
+          if ((xx + ww) > block->w)
+	  {
+            line     = do_align(block, line, xx, newalign, links);
+	    xx       = block->x;
+	    yy       += hh;
+	    block->h += hh;
+	    hh       = 0;
+	  }
+
+          if (linkdest[0])
+	    add_link(linkdest, xx, yy - fsize, ww, fsize);
+
+	  xx += ww;
+	  if ((fsize + 2) > hh)
+	    hh = fsize + 2;
+
+	  needspace = 0;
+	}
+	else if (pre)
+	{
+          // Add a link as needed...
+          if (linkdest[0])
+	    add_link(linkdest, xx, yy - hh, ww, hh);
+
+	  xx += ww;
+	  if ((fsize + 2) > hh)
+	    hh = fsize + 2;
+
+          // Handle preformatted text...
+	  while (isspace(*ptr))
+	  {
+	    if (*ptr == '\n')
+	    {
+              if (xx > hsize_) break;
+
+              line     = do_align(block, line, xx, newalign, links);
+              xx       = block->x;
+	      yy       += hh;
+	      block->h += hh;
+	      hh       = fsize + 2;
+	    }
+	    else
+              xx += (int)fl_width(' ');
+
+            if ((fsize + 2) > hh)
+	      hh = fsize + 2;
+
+            ptr ++;
+	  }
+
+          if (xx > hsize_) {
+	    hsize_ = xx;
+	    done   = 0;
+	    break;
+	  }
+
+	  needspace = 0;
+	}
+	else
+	{
+          // Handle normal text or stuff in the <HEAD> section...
+	  while (isspace(*ptr))
+            ptr ++;
+	}
+
+	s = buf;
+      }
+
+      if (*ptr == '<')
+      {
+	start = ptr;
+	ptr ++;
+
+        if (strncmp(ptr, "!--", 3) == 0)
+	{
+	  // Comment...
+	  ptr += 3;
+	  if ((ptr = strstr(ptr, "-->")) != NULL)
+	  {
+	    ptr += 3;
+	    continue;
+	  }
+	  else
+	    break;
+	}
+
+	while (*ptr && *ptr != '>' && !isspace(*ptr))
+          if (s < (buf + sizeof(buf) - 1))
+            *s++ = *ptr++;
+	  else
+	    ptr ++;
+
+	*s = '\0';
+	s = buf;
+
+//        puts(buf);
+
+	attrs = ptr;
+	while (*ptr && *ptr != '>')
+          ptr ++;
+
+	if (*ptr == '>')
+          ptr ++;
+
+	if (strcasecmp(buf, "HEAD") == 0)
+          head = 1;
+	else if (strcasecmp(buf, "/HEAD") == 0)
+          head = 0;
+	else if (strcasecmp(buf, "TITLE") == 0)
+	{
+          // Copy the title in the document...
+          for (s = title_;
+	       *ptr != '<' && *ptr && s < (title_ + sizeof(title_) - 1);
+	       *s++ = *ptr++);
+
+	  *s = '\0';
+	  s = buf;
+	}
+	else if (strcasecmp(buf, "A") == 0)
+	{
+          if (get_attr(attrs, "NAME", attr, sizeof(attr)) != NULL)
+	    add_target(attr, yy - fsize - 2);
+
+	  if (get_attr(attrs, "HREF", attr, sizeof(attr)) != NULL)
+	    strlcpy(linkdest, attr, sizeof(linkdest));
+	}
+	else if (strcasecmp(buf, "/A") == 0)
+          linkdest[0] = '\0';
+	else if (strcasecmp(buf, "BODY") == 0)
+	{
+          bgcolor_   = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)),
+	                	 color());
+          textcolor_ = get_color(get_attr(attrs, "TEXT", attr, sizeof(attr)),
+	                	 textcolor());
+          linkcolor_ = get_color(get_attr(attrs, "LINK", attr, sizeof(attr)),
+	                	 selection_color());
+	}
+	else if (strcasecmp(buf, "BR") == 0)
+	{
+          line     = do_align(block, line, xx, newalign, links);
+          xx       = block->x;
+	  block->h += hh;
+          yy       += hh;
+	  hh       = 0;
+	}
+	else if (strcasecmp(buf, "CENTER") == 0 ||
+        	 strcasecmp(buf, "P") == 0 ||
+        	 strcasecmp(buf, "H1") == 0 ||
+		 strcasecmp(buf, "H2") == 0 ||
+		 strcasecmp(buf, "H3") == 0 ||
+		 strcasecmp(buf, "H4") == 0 ||
+		 strcasecmp(buf, "H5") == 0 ||
+		 strcasecmp(buf, "H6") == 0 ||
+		 strcasecmp(buf, "UL") == 0 ||
+		 strcasecmp(buf, "OL") == 0 ||
+		 strcasecmp(buf, "DL") == 0 ||
+		 strcasecmp(buf, "LI") == 0 ||
+		 strcasecmp(buf, "DD") == 0 ||
+		 strcasecmp(buf, "DT") == 0 ||
+		 strcasecmp(buf, "HR") == 0 ||
+		 strcasecmp(buf, "PRE") == 0 ||
+		 strcasecmp(buf, "TABLE") == 0)
+	{
+          block->end = start;
+          line       = do_align(block, line, xx, newalign, links);
+          xx         = block->x;
+          block->h   += hh;
+
+          if (strcasecmp(buf, "UL") == 0 ||
+	      strcasecmp(buf, "OL") == 0 ||
+	      strcasecmp(buf, "DL") == 0)
+          {
+	    block->h += fsize + 2;
+	    xx       += 4 * fsize;
+	  }
+          else if (strcasecmp(buf, "TABLE") == 0)
+	  {
+	    if (get_attr(attrs, "BORDER", attr, sizeof(attr)))
+	      border = (uchar)atoi(attr);
+	    else
+	      border = 0;
+
+            tc = rc = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)), bgcolor_);
+
+	    block->h += fsize + 2;
+
+            format_table(&table_width, columns, start);
+
+            if ((xx + table_width) > hsize_) {
+#ifdef DEBUG
+              printf("xx=%d, table_width=%d, hsize_=%d\n", xx, table_width,
+	             hsize_);
+#endif // DEBUG
+	      hsize_ = xx + table_width;
+	      done   = 0;
+	      break;
+	    }
+
+            switch (get_align(attrs, talign))
+	    {
+	      default :
+	          table_offset = 0;
+	          break;
+
+	      case CENTER :
+	          table_offset = (hsize_ - table_width) / 2 - textsize_;
+	          break;
+
+	      case RIGHT :
+	          table_offset = hsize_ - table_width - textsize_;
+	          break;
+	    }
+
+	    column = 0;
+	  }
+
+          if (tolower(buf[0]) == 'h' && isdigit(buf[1]))
+	  {
+	    font  = FL_HELVETICA_BOLD;
+	    fsize = (uchar)(textsize_ + '7' - buf[1]);
+	  }
+	  else if (strcasecmp(buf, "DT") == 0)
+	  {
+	    font  = (uchar)(textfont_ | FL_ITALIC);
+	    fsize = textsize_;
+	  }
+	  else if (strcasecmp(buf, "PRE") == 0)
+	  {
+	    font  = FL_COURIER;
+	    fsize = textsize_;
+	    pre   = 1;
+	  }
+	  else
+	  {
+	    font  = textfont_;
+	    fsize = textsize_;
+	  }
+
+	  pushfont(font, fsize);
+
+          yy = block->y + block->h;
+          hh = 0;
+
+          if ((tolower(buf[0]) == 'h' && isdigit(buf[1])) ||
+	      strcasecmp(buf, "DD") == 0 ||
+	      strcasecmp(buf, "DT") == 0 ||
+	      strcasecmp(buf, "P") == 0)
+            yy += fsize + 2;
+	  else if (strcasecmp(buf, "HR") == 0)
+	  {
+	    hh += 2 * fsize;
+	    yy += fsize;
+	  }
+
+          if (row)
+	    block = add_block(start, xx, yy, block->w, 0);
+	  else
+	    block = add_block(start, xx, yy, hsize_, 0);
+
+	  needspace = 0;
+	  line      = 0;
+
+	  if (strcasecmp(buf, "CENTER") == 0)
+	    newalign = talign = CENTER;
+	  else
+	    newalign = get_align(attrs, talign);
+	}
+	else if (strcasecmp(buf, "/CENTER") == 0 ||
+		 strcasecmp(buf, "/P") == 0 ||
+		 strcasecmp(buf, "/H1") == 0 ||
+		 strcasecmp(buf, "/H2") == 0 ||
+		 strcasecmp(buf, "/H3") == 0 ||
+		 strcasecmp(buf, "/H4") == 0 ||
+		 strcasecmp(buf, "/H5") == 0 ||
+		 strcasecmp(buf, "/H6") == 0 ||
+		 strcasecmp(buf, "/PRE") == 0 ||
+		 strcasecmp(buf, "/UL") == 0 ||
+		 strcasecmp(buf, "/OL") == 0 ||
+		 strcasecmp(buf, "/DL") == 0 ||
+		 strcasecmp(buf, "/TABLE") == 0)
+	{
+          line       = do_align(block, line, xx, newalign, links);
+          xx         = block->x;
+          block->end = ptr;
+
+          if (strcasecmp(buf, "/UL") == 0 ||
+	      strcasecmp(buf, "/OL") == 0 ||
+	      strcasecmp(buf, "/DL") == 0)
+	  {
+	    xx       -= 4 * fsize;
+	    block->h += fsize + 2;
+	  }
+          else if (strcasecmp(buf, "/TABLE") == 0) 
+          {
+	    block->h += fsize + 2;
+            // the current block is *not* the table block, so the current xx is 
+            // meaningless. Set it back to page x, so the next block will be aligned 
+            // reasonably. This fails fro table-in-table html!
+            xx = 4;
+          }
+	  else if (strcasecmp(buf, "/PRE") == 0)
+	  {
+	    pre = 0;
+	    hh  = 0;
+	  }
+	  else if (strcasecmp(buf, "/CENTER") == 0)
+	    talign = LEFT;
+
+          popfont(font, fsize);
+
+          while (isspace(*ptr))
+	    ptr ++;
+
+          block->h += hh;
+          yy       += hh;
+
+          if (tolower(buf[2]) == 'l')
+            yy += fsize + 2;
+
+          if (row)
+	    block = add_block(ptr, xx, yy, block->w, 0);
+	  else
+	    block = add_block(ptr, xx, yy, hsize_, 0);
+
+	  needspace = 0;
+	  hh        = 0;
+	  line      = 0;
+	  newalign  = talign;
+	}
+	else if (strcasecmp(buf, "TR") == 0)
+	{
+          block->end = start;
+          line       = do_align(block, line, xx, newalign, links);
+          xx         = block->x;
+          block->h   += hh;
+
+          if (row)
+	  {
+            yy = blocks_[row].y + blocks_[row].h;
+
+	    for (cell = blocks_ + row + 1; cell <= block; cell ++)
+	      if ((cell->y + cell->h) > yy)
+		yy = cell->y + cell->h;
+
+            block = blocks_ + row;
+
+            block->h = yy - block->y + 2;
+
+	    for (i = 0; i < column; i ++)
+	      if (cells[i])
+	      {
+		cell = blocks_ + cells[i];
+		cell->h = block->h;
+	      }
+	  }
+
+          memset(cells, 0, sizeof(cells));
+
+	  yy        = block->y + block->h - 4;
+	  hh        = 0;
+          block     = add_block(start, xx, yy, hsize_, 0);
+	  row       = block - blocks_;
+	  needspace = 0;
+	  column    = 0;
+	  line      = 0;
+
+          rc = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)), tc);
+	}
+	else if (strcasecmp(buf, "/TR") == 0 && row)
+	{
+          line       = do_align(block, line, xx, newalign, links);
+          block->end = start;
+	  block->h   += hh;
+
+          xx = blocks_[row].x;
+
+          yy = blocks_[row].y + blocks_[row].h;
+
+	  for (cell = blocks_ + row + 1; cell <= block; cell ++)
+	    if ((cell->y + cell->h) > yy)
+	      yy = cell->y + cell->h;
+
+          block = blocks_ + row;
+
+          block->h = yy - block->y + 2;
+
+	  for (i = 0; i < column; i ++)
+	    if (cells[i])
+	    {
+	      cell = blocks_ + cells[i];
+	      cell->h = block->h;
+	    }
+
+	  yy        = block->y + block->h - 4;
+          block     = add_block(start, xx, yy, hsize_, 0);
+	  needspace = 0;
+	  row       = 0;
+	  line      = 0;
+	}
+	else if ((strcasecmp(buf, "TD") == 0 ||
+                  strcasecmp(buf, "TH") == 0) && row)
+	{
+          int	colspan;		// COLSPAN attribute
+
+
+          line       = do_align(block, line, xx, newalign, links);
+          block->end = start;
+	  block->h   += hh;
+
+          if (strcasecmp(buf, "TH") == 0)
+	    font = (uchar)(textfont_ | FL_BOLD);
+	  else
+	    font = textfont_;
+
+          fsize = textsize_;
+
+          xx = blocks_[row].x + fsize + 3 + table_offset;
+	  for (i = 0; i < column; i ++)
+	    xx += columns[i] + 6;
+
+          if (get_attr(attrs, "COLSPAN", attr, sizeof(attr)) != NULL)
+	    colspan = atoi(attr);
+	  else
+	    colspan = 1;
+
+          for (i = 0, ww = -6; i < colspan; i ++)
+	    ww += columns[column + i] + 6;
+
+          if (block->end == block->start && nblocks_ > 1)
+	  {
+	    nblocks_ --;
+	    block --;
+	  }
+
+	  pushfont(font, fsize);
+
+	  yy        = blocks_[row].y;
+	  hh        = 0;
+          block     = add_block(start, xx, yy, xx + ww, 0, border);
+	  needspace = 0;
+	  line      = 0;
+	  newalign  = get_align(attrs, tolower(buf[1]) == 'h' ? CENTER : LEFT);
+	  talign    = newalign;
+
+          cells[column] = block - blocks_;
+
+	  column += colspan;
+
+          block->bgcolor = get_color(get_attr(attrs, "BGCOLOR", attr,
+	                                      sizeof(attr)), rc);
+	}
+	else if ((strcasecmp(buf, "/TD") == 0 ||
+                  strcasecmp(buf, "/TH") == 0) && row)
+	{
+          popfont(font, fsize);
+	}
+	  else if (strcasecmp(buf, "FONT") == 0)
+	  {
+            if (get_attr(attrs, "FACE", attr, sizeof(attr)) != NULL) {
+	      if (!strncasecmp(attr, "helvetica", 9) ||
+	          !strncasecmp(attr, "arial", 5) ||
+		  !strncasecmp(attr, "sans", 4)) font = FL_HELVETICA;
+              else if (!strncasecmp(attr, "times", 5) ||
+	               !strncasecmp(attr, "serif", 5)) font = FL_TIMES;
+              else if (!strncasecmp(attr, "symbol", 6)) font = FL_SYMBOL;
+	      else font = FL_COURIER;
+            }
+
+            if (get_attr(attrs, "SIZE", attr, sizeof(attr)) != NULL) {
+              if (isdigit(attr[0] & 255)) {
+	        // Absolute size
+	        fsize = (int)(textsize_ * pow(1.2, atoi(attr) - 3.0));
+	      } else {
+	        // Relative size
+	        fsize = (int)(fsize * pow(1.2, atoi(attr)));
+	      }
+	    }
+
+            pushfont(font, fsize);
+	  }
+	  else if (strcasecmp(buf, "/FONT") == 0)
+	    popfont(font, fsize);
+	else if (strcasecmp(buf, "B") == 0 ||
+        	 strcasecmp(buf, "STRONG") == 0)
+	  pushfont(font |= FL_BOLD, fsize);
+	else if (strcasecmp(buf, "I") == 0 ||
+        	 strcasecmp(buf, "EM") == 0)
+	  pushfont(font |= FL_ITALIC, fsize);
+	else if (strcasecmp(buf, "CODE") == 0 ||
+	         strcasecmp(buf, "TT") == 0)
+	  pushfont(font = FL_COURIER, fsize);
+	else if (strcasecmp(buf, "KBD") == 0)
+	  pushfont(font = FL_COURIER_BOLD, fsize);
+	else if (strcasecmp(buf, "VAR") == 0)
+	  pushfont(font = FL_COURIER_ITALIC, fsize);
+	else if (strcasecmp(buf, "/B") == 0 ||
+		 strcasecmp(buf, "/STRONG") == 0 ||
+		 strcasecmp(buf, "/I") == 0 ||
+		 strcasecmp(buf, "/EM") == 0 ||
+		 strcasecmp(buf, "/CODE") == 0 ||
+		 strcasecmp(buf, "/TT") == 0 ||
+		 strcasecmp(buf, "/KBD") == 0 ||
+		 strcasecmp(buf, "/VAR") == 0)
+	  popfont(font, fsize);
+	else if (strcasecmp(buf, "IMG") == 0)
+	{
+	  Fl_Shared_Image	*img = 0;
+	  int		width;
+	  int		height;
+
+
+          get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+          get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+	  width  = get_length(wattr);
+	  height = get_length(hattr);
+
+	  if (get_attr(attrs, "SRC", attr, sizeof(attr))) {
+	    img    = get_image(attr, width, height);
+	    width  = img->w();
+	    height = img->h();
+	  }
+
+	  ww = width;
+
+          if (ww > hsize_) {
+	    hsize_ = ww;
+	    done   = 0;
+	    break;
+	  }
+
+	  if (needspace && xx > block->x)
+	    ww += (int)fl_width(' ');
+
+	  if ((xx + ww) > block->w)
+	  {
+	    line     = do_align(block, line, xx, newalign, links);
+	    xx       = block->x;
+	    yy       += hh;
+	    block->h += hh;
+	    hh       = 0;
+	  }
+
+	  if (linkdest[0])
+	    add_link(linkdest, xx, yy - height, ww, height);
+
+	  xx += ww;
+	  if ((height + 2) > hh)
+	    hh = height + 2;
+
+	  needspace = 0;
+	}
+      }
+      else if (*ptr == '\n' && pre)
+      {
+	if (linkdest[0])
+	  add_link(linkdest, xx, yy - hh, ww, hh);
+
+        if (xx > hsize_) {
+	  hsize_ = xx;
+          done   = 0;
+	  break;
+	}
+
+	line      = do_align(block, line, xx, newalign, links);
+	xx        = block->x;
+	yy        += hh;
+	block->h  += hh;
+	needspace = 0;
+	ptr ++;
+      }
+      else if (isspace(*ptr))
+      {
+	needspace = 1;
+
+	ptr ++;
+      }
+      else if (*ptr == '&' && s < (buf + sizeof(buf) - 1))
+      {
+	ptr ++;
+
+        int qch = quote_char(ptr);
+
+	if (qch < 0)
+	  *s++ = '&';
+	else {
+	  *s++ = qch;
+	  ptr = strchr(ptr, ';') + 1;
+	}
+
+	if ((fsize + 2) > hh)
+          hh = fsize + 2;
+      }
+      else
+      {
+	if (s < (buf + sizeof(buf) - 1))
+          *s++ = *ptr++;
+	else
+          ptr ++;
+
+	if ((fsize + 2) > hh)
+          hh = fsize + 2;
+      }
+    }
+
+    if (s > buf && !head)
+    {
+      *s = '\0';
+      ww = (int)fl_width(buf);
+
+  //    printf("line = %d, xx = %d, ww = %d, block->x = %d, block->w = %d\n",
+  //	   line, xx, ww, block->x, block->w);
+
+      if (ww > hsize_) {
+	hsize_ = ww;
+	done   = 0;
+	break;
+      }
+
+      if (needspace && xx > block->x)
+	ww += (int)fl_width(' ');
+
+      if ((xx + ww) > block->w)
+      {
+	line     = do_align(block, line, xx, newalign, links);
+	xx       = block->x;
+	yy       += hh;
+	block->h += hh;
+	hh       = 0;
+      }
+
+      if (linkdest[0])
+	add_link(linkdest, xx, yy - fsize, ww, fsize);
+
+      xx += ww;
+    }
+
+    do_align(block, line, xx, newalign, links);
+
+    block->end = ptr;
+    size_      = yy + hh;
+  }
+
+
+  if (ntargets_ > 1)
+    qsort(targets_, ntargets_, sizeof(Fl_Help_Target),
+          (compare_func_t)compare_targets);
+
+  int dx = Fl::box_dw(b) - Fl::box_dx(b);
+  int dy = Fl::box_dh(b) - Fl::box_dy(b);
+
+  if (hsize_ > (w() - 24)) {
+    hscrollbar_.show();
+
+    if (size_ < (h() - 24)) {
+      scrollbar_.hide();
+      hscrollbar_.resize(x() + Fl::box_dx(b), y() + h() - 17 - dy, w() - Fl::box_dw(b), 17);
+    } else {
+      scrollbar_.show();
+      scrollbar_.resize(x() + w() - 17 - dx, y() + Fl::box_dy(b), 17, h() - 17 - Fl::box_dh(b));
+      hscrollbar_.resize(x() + Fl::box_dx(b), y() + h() - 17 - dy, w() - 17 - Fl::box_dw(b), 17);
+    }
+  } else {
+    hscrollbar_.hide();
+
+    if (size_ < (h() - 8)) scrollbar_.hide();
+    else {
+      scrollbar_.resize(x() + w() - 17 - dx, y() + Fl::box_dy(b), 17, h() - Fl::box_dh(b));
+      scrollbar_.show();
+    }
+  }
+
+  // Reset scrolling if it needs to be...
+  if (scrollbar_.visible()) {
+    int temph = h() - 8;
+    if (hscrollbar_.visible()) temph -= 16;
+    if ((topline_ + temph) > size_) topline(size_ - temph);
+    else topline(topline_);
+  } else topline(0);
+
+  if (hscrollbar_.visible()) {
+    int tempw = w() - 24;
+    if ((leftline_ + tempw) > hsize_) leftline(hsize_ - tempw);
+    else leftline(leftline_);
+  } else leftline(0);
+}
+
+
+//
+// 'Fl_Help_View::format_table()' - Format a table...
+//
+
+void
+Fl_Help_View::format_table(int        *table_width,	// O - Total table width
+                           int        *columns,		// O - Column widths
+	                   const char *table)		// I - Pointer to start of table
+{
+  int		column,					// Current column
+		num_columns,				// Number of columns
+		colspan,				// COLSPAN attribute
+		width,					// Current width
+		temp_width,				// Temporary width
+		max_width,				// Maximum width
+		incell,					// In a table cell?
+		pre,					// <PRE> text?
+		needspace;				// Need whitespace?
+  char		*s,					// Pointer into buffer
+		buf[1024],				// Text buffer
+		attr[1024],				// Other attribute
+		wattr[1024],				// WIDTH attribute
+		hattr[1024];				// HEIGHT attribute
+  const char	*ptr,					// Pointer into table
+		*attrs,					// Pointer to attributes
+		*start;					// Start of element
+  int		minwidths[MAX_COLUMNS];			// Minimum widths for each column
+  unsigned char	font, fsize;				// Current font and size
+
+
+  // Clear widths...
+  *table_width = 0;
+  for (column = 0; column < MAX_COLUMNS; column ++)
+  {
+    columns[column]   = 0;
+    minwidths[column] = 0;
+  }
+
+  num_columns = 0;
+  colspan     = 0;
+  max_width   = 0;
+  pre         = 0;
+  needspace   = 0;
+  font        = fonts_[nfonts_][0];
+  fsize       = fonts_[nfonts_][1];
+
+  // Scan the table...
+  for (ptr = table, column = -1, width = 0, s = buf, incell = 0; *ptr;)
+  {
+    if ((*ptr == '<' || isspace(*ptr)) && s > buf && incell)
+    {
+      // Check width...
+      if (needspace)
+      {
+        *s++      = ' ';
+	needspace = 0;
+      }
+
+      *s         = '\0';
+      temp_width = (int)fl_width(buf);
+      s          = buf;
+
+      if (temp_width > minwidths[column])
+        minwidths[column] = temp_width;
+
+      width += temp_width;
+
+      if (width > max_width)
+        max_width = width;
+    }
+
+    if (*ptr == '<')
+    {
+      start = ptr;
+
+      for (s = buf, ptr ++; *ptr && *ptr != '>' && !isspace(*ptr);)
+        if (s < (buf + sizeof(buf) - 1))
+          *s++ = *ptr++;
+	else
+	  ptr ++;
+
+      *s = '\0';
+      s = buf;
+
+      attrs = ptr;
+      while (*ptr && *ptr != '>')
+        ptr ++;
+
+      if (*ptr == '>')
+        ptr ++;
+
+      if (strcasecmp(buf, "BR") == 0 ||
+	  strcasecmp(buf, "HR") == 0)
+      {
+        width     = 0;
+	needspace = 0;
+      }
+      else if (strcasecmp(buf, "TABLE") == 0 && start > table)
+        break;
+      else if (strcasecmp(buf, "CENTER") == 0 ||
+               strcasecmp(buf, "P") == 0 ||
+               strcasecmp(buf, "H1") == 0 ||
+	       strcasecmp(buf, "H2") == 0 ||
+	       strcasecmp(buf, "H3") == 0 ||
+	       strcasecmp(buf, "H4") == 0 ||
+	       strcasecmp(buf, "H5") == 0 ||
+	       strcasecmp(buf, "H6") == 0 ||
+	       strcasecmp(buf, "UL") == 0 ||
+	       strcasecmp(buf, "OL") == 0 ||
+	       strcasecmp(buf, "DL") == 0 ||
+	       strcasecmp(buf, "LI") == 0 ||
+	       strcasecmp(buf, "DD") == 0 ||
+	       strcasecmp(buf, "DT") == 0 ||
+	       strcasecmp(buf, "PRE") == 0)
+      {
+        width     = 0;
+	needspace = 0;
+
+        if (tolower(buf[0]) == 'h' && isdigit(buf[1]))
+	{
+	  font  = FL_HELVETICA_BOLD;
+	  fsize = (uchar)(textsize_ + '7' - buf[1]);
+	}
+	else if (strcasecmp(buf, "DT") == 0)
+	{
+	  font  = (uchar)(textfont_ | FL_ITALIC);
+	  fsize = textsize_;
+	}
+	else if (strcasecmp(buf, "PRE") == 0)
+	{
+	  font  = FL_COURIER;
+	  fsize = textsize_;
+	  pre   = 1;
+	}
+	else if (strcasecmp(buf, "LI") == 0)
+	{
+	  width  += 4 * fsize;
+	  font   = textfont_;
+	  fsize  = textsize_;
+	}
+	else
+	{
+	  font  = textfont_;
+	  fsize = textsize_;
+	}
+
+	pushfont(font, fsize);
+      }
+      else if (strcasecmp(buf, "/CENTER") == 0 ||
+	       strcasecmp(buf, "/P") == 0 ||
+	       strcasecmp(buf, "/H1") == 0 ||
+	       strcasecmp(buf, "/H2") == 0 ||
+	       strcasecmp(buf, "/H3") == 0 ||
+	       strcasecmp(buf, "/H4") == 0 ||
+	       strcasecmp(buf, "/H5") == 0 ||
+	       strcasecmp(buf, "/H6") == 0 ||
+	       strcasecmp(buf, "/PRE") == 0 ||
+	       strcasecmp(buf, "/UL") == 0 ||
+	       strcasecmp(buf, "/OL") == 0 ||
+	       strcasecmp(buf, "/DL") == 0)
+      {
+        width     = 0;
+	needspace = 0;
+
+        popfont(font, fsize);
+      }
+      else if (strcasecmp(buf, "TR") == 0 || strcasecmp(buf, "/TR") == 0 ||
+               strcasecmp(buf, "/TABLE") == 0)
+      {
+//        printf("%s column = %d, colspan = %d, num_columns = %d\n",
+//	       buf, column, colspan, num_columns);
+
+        if (column >= 0)
+	{
+	  // This is a hack to support COLSPAN...
+	  max_width /= colspan;
+
+	  while (colspan > 0)
+	  {
+	    if (max_width > columns[column])
+	      columns[column] = max_width;
+
+	    column ++;
+	    colspan --;
+	  }
+	}
+
+	if (strcasecmp(buf, "/TABLE") == 0)
+	  break;
+
+	needspace = 0;
+	column    = -1;
+	width     = 0;
+	max_width = 0;
+	incell    = 0;
+      }
+      else if (strcasecmp(buf, "TD") == 0 ||
+               strcasecmp(buf, "TH") == 0)
+      {
+//        printf("BEFORE column = %d, colspan = %d, num_columns = %d\n",
+//	       column, colspan, num_columns);
+
+        if (column >= 0)
+	{
+	  // This is a hack to support COLSPAN...
+	  max_width /= colspan;
+
+	  while (colspan > 0)
+	  {
+	    if (max_width > columns[column])
+	      columns[column] = max_width;
+
+	    column ++;
+	    colspan --;
+	  }
+	}
+	else
+	  column ++;
+
+        if (get_attr(attrs, "COLSPAN", attr, sizeof(attr)) != NULL)
+	  colspan = atoi(attr);
+	else
+	  colspan = 1;
+
+//        printf("AFTER column = %d, colspan = %d, num_columns = %d\n",
+//	       column, colspan, num_columns);
+
+        if ((column + colspan) >= num_columns)
+	  num_columns = column + colspan;
+
+	needspace = 0;
+	width     = 0;
+	incell    = 1;
+
+        if (strcasecmp(buf, "TH") == 0)
+	  font = (uchar)(textfont_ | FL_BOLD);
+	else
+	  font = textfont_;
+
+        fsize = textsize_;
+
+	pushfont(font, fsize);
+
+        if (get_attr(attrs, "WIDTH", attr, sizeof(attr)) != NULL)
+	  max_width = get_length(attr);
+	else
+	  max_width = 0;
+
+//        printf("max_width = %d\n", max_width);
+      }
+      else if (strcasecmp(buf, "/TD") == 0 ||
+               strcasecmp(buf, "/TH") == 0)
+      {
+	incell = 0;
+        popfont(font, fsize);
+      }
+      else if (strcasecmp(buf, "B") == 0 ||
+               strcasecmp(buf, "STRONG") == 0)
+	pushfont(font |= FL_BOLD, fsize);
+      else if (strcasecmp(buf, "I") == 0 ||
+               strcasecmp(buf, "EM") == 0)
+	pushfont(font |= FL_ITALIC, fsize);
+      else if (strcasecmp(buf, "CODE") == 0 ||
+               strcasecmp(buf, "TT") == 0)
+	pushfont(font = FL_COURIER, fsize);
+      else if (strcasecmp(buf, "KBD") == 0)
+	pushfont(font = FL_COURIER_BOLD, fsize);
+      else if (strcasecmp(buf, "VAR") == 0)
+	pushfont(font = FL_COURIER_ITALIC, fsize);
+      else if (strcasecmp(buf, "/B") == 0 ||
+	       strcasecmp(buf, "/STRONG") == 0 ||
+	       strcasecmp(buf, "/I") == 0 ||
+	       strcasecmp(buf, "/EM") == 0 ||
+	       strcasecmp(buf, "/CODE") == 0 ||
+	       strcasecmp(buf, "/TT") == 0 ||
+	       strcasecmp(buf, "/KBD") == 0 ||
+	       strcasecmp(buf, "/VAR") == 0)
+	popfont(font, fsize);
+      else if (strcasecmp(buf, "IMG") == 0 && incell)
+      {
+	Fl_Shared_Image	*img = 0;
+	int		iwidth, iheight;
+
+
+        get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+        get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+	iwidth  = get_length(wattr);
+	iheight = get_length(hattr);
+
+        if (get_attr(attrs, "SRC", attr, sizeof(attr))) {
+	  img     = get_image(attr, iwidth, iheight);
+	  iwidth  = img->w();
+	  iheight = img->h();
+	}
+
+	if (iwidth > minwidths[column])
+          minwidths[column] = iwidth;
+
+        width += iwidth;
+	if (needspace)
+	  width += (int)fl_width(' ');
+
+	if (width > max_width)
+          max_width = width;
+
+	needspace = 0;
+      }
+    }
+    else if (*ptr == '\n' && pre)
+    {
+      width     = 0;
+      needspace = 0;
+      ptr ++;
+    }
+    else if (isspace(*ptr))
+    {
+      needspace = 1;
+
+      ptr ++;
+    }
+    else if (*ptr == '&' && s < (buf + sizeof(buf) - 1))
+    {
+      ptr ++;
+
+      int qch = quote_char(ptr);
+
+      if (qch < 0)
+	*s++ = '&';
+      else {
+	*s++ = qch;
+	ptr = strchr(ptr, ';') + 1;
+      }
+    }
+    else
+    {
+      if (s < (buf + sizeof(buf) - 1))
+        *s++ = *ptr++;
+      else
+        ptr ++;
+    }
+  }
+
+  // Now that we have scanned the entire table, adjust the table and
+  // cell widths to fit on the screen...
+  if (get_attr(table + 6, "WIDTH", attr, sizeof(attr)))
+    *table_width = get_length(attr);
+  else
+    *table_width = 0;
+
+#ifdef DEBUG
+  printf("num_columns = %d, table_width = %d\n", num_columns, *table_width);
+#endif // DEBUG
+
+  if (num_columns == 0)
+    return;
+
+  // Add up the widths...
+  for (column = 0, width = 0; column < num_columns; column ++)
+    width += columns[column];
+
+#ifdef DEBUG
+  printf("width = %d, w() = %d\n", width, w());
+  for (column = 0; column < num_columns; column ++)
+    printf("    columns[%d] = %d, minwidths[%d] = %d\n", column, columns[column],
+           column, minwidths[column]);
+#endif // DEBUG
+
+  // Adjust the width if needed...
+  int scale_width = *table_width;
+
+  if (scale_width == 0) {
+    if (width > (hsize_ - 24)) scale_width = hsize_ - 24;
+    else scale_width = width;
+  }
+
+  if (width < scale_width) {
+#ifdef DEBUG
+    printf("Scaling table up to %d from %d...\n", scale_width, width);
+#endif // DEBUG
+
+    *table_width = 0;
+
+    scale_width = (scale_width - width) / num_columns;
+
+#ifdef DEBUG
+    printf("adjusted scale_width = %d\n", scale_width);
+#endif // DEBUG
+
+    for (column = 0; column < num_columns; column ++) {
+      columns[column] += scale_width;
+
+      (*table_width) += columns[column];
+    }
+  }
+  else if (width > scale_width) {
+#ifdef DEBUG
+    printf("Scaling table down to %d from %d...\n", scale_width, width);
+#endif // DEBUG
+
+    for (column = 0; column < num_columns; column ++) {
+      width       -= minwidths[column];
+      scale_width -= minwidths[column];
+    }
+
+#ifdef DEBUG
+    printf("adjusted width = %d, scale_width = %d\n", width, scale_width);
+#endif // DEBUG
+
+    if (width > 0) {
+      for (column = 0; column < num_columns; column ++) {
+	columns[column] -= minwidths[column];
+	columns[column] = scale_width * columns[column] / width;
+	columns[column] += minwidths[column];
+      }
+    }
+
+    *table_width = 0;
+    for (column = 0; column < num_columns; column ++) {
+      (*table_width) += columns[column];
+    }
+  }
+  else if (*table_width == 0)
+    *table_width = width;
+
+#ifdef DEBUG
+  printf("FINAL table_width = %d\n", *table_width);
+  for (column = 0; column < num_columns; column ++)
+    printf("    columns[%d] = %d\n", column, columns[column]);
+#endif // DEBUG
+}
+
+
+//
+// 'Fl_Help_View::get_align()' - Get an alignment attribute.
+//
+
+int					// O - Alignment
+Fl_Help_View::get_align(const char *p,	// I - Pointer to start of attrs
+                        int        a)	// I - Default alignment
+{
+  char	buf[255];			// Alignment value
+
+
+  if (get_attr(p, "ALIGN", buf, sizeof(buf)) == NULL)
+    return (a);
+
+  if (strcasecmp(buf, "CENTER") == 0)
+    return (CENTER);
+  else if (strcasecmp(buf, "RIGHT") == 0)
+    return (RIGHT);
+  else
+    return (LEFT);
+}
+
+
+//
+// 'Fl_Help_View::get_attr()' - Get an attribute value from the string.
+//
+
+const char *					// O - Pointer to buf or NULL
+Fl_Help_View::get_attr(const char *p,		// I - Pointer to start of attributes
+                      const char *n,		// I - Name of attribute
+		      char       *buf,		// O - Buffer for attribute value
+		      int        bufsize)	// I - Size of buffer
+{
+  char	name[255],				// Name from string
+	*ptr,					// Pointer into name or value
+	quote;					// Quote
+
+
+  buf[0] = '\0';
+
+  while (*p && *p != '>')
+  {
+    while (isspace(*p))
+      p ++;
+
+    if (*p == '>' || !*p)
+      return (NULL);
+
+    for (ptr = name; *p && !isspace(*p) && *p != '=' && *p != '>';)
+      if (ptr < (name + sizeof(name) - 1))
+        *ptr++ = *p++;
+      else
+        p ++;
+
+    *ptr = '\0';
+
+    if (isspace(*p) || !*p || *p == '>')
+      buf[0] = '\0';
+    else
+    {
+      if (*p == '=')
+        p ++;
+
+      for (ptr = buf; *p && !isspace(*p) && *p != '>';)
+        if (*p == '\'' || *p == '\"')
+	{
+	  quote = *p++;
+
+	  while (*p && *p != quote)
+	    if ((ptr - buf + 1) < bufsize)
+	      *ptr++ = *p++;
+	    else
+	      p ++;
+
+          if (*p == quote)
+	    p ++;
+	}
+	else if ((ptr - buf + 1) < bufsize)
+	  *ptr++ = *p++;
+	else
+	  p ++;
+
+      *ptr = '\0';
+    }
+
+    if (strcasecmp(n, name) == 0)
+      return (buf);
+    else
+      buf[0] = '\0';
+
+    if (*p == '>')
+      return (NULL);
+  }
+
+  return (NULL);
+}
+
+
+//
+// 'Fl_Help_View::get_color()' - Get an alignment attribute.
+//
+
+Fl_Color				// O - Color value
+Fl_Help_View::get_color(const char *n,	// I - Color name
+                        Fl_Color   c)	// I - Default color value
+{
+  int	i;				// Looping var
+  int	rgb, r, g, b;			// RGB values
+  static const struct {			// Color name table
+    const char *name;
+    int r, g, b;
+  }	colors[] = {
+    { "black",		0x00, 0x00, 0x00 },
+    { "red",		0xff, 0x00, 0x00 },
+    { "green",		0x00, 0x80, 0x00 },
+    { "yellow",		0xff, 0xff, 0x00 },
+    { "blue",		0x00, 0x00, 0xff },
+    { "magenta",	0xff, 0x00, 0xff },
+    { "fuchsia",	0xff, 0x00, 0xff },
+    { "cyan",		0x00, 0xff, 0xff },
+    { "aqua",		0x00, 0xff, 0xff },
+    { "white",		0xff, 0xff, 0xff },
+    { "gray",		0x80, 0x80, 0x80 },
+    { "grey",		0x80, 0x80, 0x80 },
+    { "lime",		0x00, 0xff, 0x00 },
+    { "maroon",		0x80, 0x00, 0x00 },
+    { "navy",		0x00, 0x00, 0x80 },
+    { "olive",		0x80, 0x80, 0x00 },
+    { "purple",		0x80, 0x00, 0x80 },
+    { "silver",		0xc0, 0xc0, 0xc0 },
+    { "teal",		0x00, 0x80, 0x80 }
+  };
+
+
+  if (!n || !n[0]) return c;
+
+  if (n[0] == '#') {
+    // Do hex color lookup
+    rgb = strtol(n + 1, NULL, 16);
+
+    if (strlen(n) > 4) {
+      r = rgb >> 16;
+      g = (rgb >> 8) & 255;
+      b = rgb & 255;
+    } else {
+      r = (rgb >> 8) * 17;
+      g = ((rgb >> 4) & 15) * 17;
+      b = (rgb & 15) * 17;
+    }
+    return (fl_rgb_color((uchar)r, (uchar)g, (uchar)b));
+  } else {
+    for (i = 0; i < (int)(sizeof(colors) / sizeof(colors[0])); i ++)
+      if (!strcasecmp(n, colors[i].name)) {
+        return fl_rgb_color(colors[i].r, colors[i].g, colors[i].b);
+      }
+    return c;
+  }
+}
+
+
+//
+// 'Fl_Help_View::get_image()' - Get an inline image.
+//
+
+Fl_Shared_Image *
+Fl_Help_View::get_image(const char *name, int W, int H) {
+  const char	*localname;		// Local filename
+  char		dir[1024];		// Current directory
+  char		temp[1024],		// Temporary filename
+		*tempptr;		// Pointer into temporary name
+  Fl_Shared_Image *ip;			// Image pointer...
+
+  // See if the image can be found...
+  if (strchr(directory_, ':') != NULL && strchr(name, ':') == NULL) {
+    if (name[0] == '/') {
+      strlcpy(temp, directory_, sizeof(temp));
+
+      if ((tempptr = strrchr(strchr(directory_, ':') + 3, '/')) != NULL) {
+        strlcpy(tempptr, name, sizeof(temp) - (tempptr - temp));
+      } else {
+        strlcat(temp, name, sizeof(temp));
+      }
+    } else {
+      snprintf(temp, sizeof(temp), "%s/%s", directory_, name);
+    }
+
+    if (link_) localname = (*link_)(this, temp);
+    else localname = temp;
+  } else if (name[0] != '/' && strchr(name, ':') == NULL) {
+    if (directory_[0]) snprintf(temp, sizeof(temp), "%s/%s", directory_, name);
+    else {
+      getcwd(dir, sizeof(dir));
+      snprintf(temp, sizeof(temp), "file:%s/%s", dir, name);
+    }
+
+    if (link_) localname = (*link_)(this, temp);
+    else localname = temp;
+  } else if (link_) localname = (*link_)(this, name);
+  else localname = name;
+
+  if (!localname) return 0;
+
+  if (strncmp(localname, "file:", 5) == 0) localname += 5;
+
+  if ((ip = Fl_Shared_Image::get(localname, W, H)) == NULL)
+    ip = (Fl_Shared_Image *)&broken_image;
+
+  return ip;
+}
+
+
+//
+// 'Fl_Help_View::get_length()' - Get a length value, either absolute or %.
+//
+
+int
+Fl_Help_View::get_length(const char *l) {	// I - Value
+  int	val;					// Integer value
+
+  if (!l[0]) return 0;
+
+  val = atoi(l);
+  if (l[strlen(l) - 1] == '%') {
+    if (val > 100) val = 100;
+    else if (val < 0) val = 0;
+
+    val = val * (hsize_ - 24) / 100;
+  }
+
+  return val;
+}
+
+
+//
+// 'Fl_Help_View::handle()' - Handle events in the widget.
+//
+
+int				// O - 1 if we handled it, 0 otherwise
+Fl_Help_View::handle(int event)	// I - Event to handle
+{
+  int		i;		// Looping var
+  int		xx, yy;		// Adjusted mouse position
+  Fl_Help_Link	*linkp;		// Current link
+  char		target[32];	// Current target
+
+
+  switch (event)
+  {
+    case FL_PUSH :
+	if (Fl_Group::handle(event))
+	  return (1);
+
+    case FL_MOVE :
+        xx = Fl::event_x() - x() + leftline_;
+	yy = Fl::event_y() - y() + topline_;
+	break;
+
+    case FL_LEAVE :
+        fl_cursor(FL_CURSOR_DEFAULT);
+
+    default :
+	return (Fl_Group::handle(event));
+  }
+
+  // Handle mouse clicks on links...
+  for (i = nlinks_, linkp = links_; i > 0; i --, linkp ++)
+    if (xx >= linkp->x && xx < linkp->w &&
+        yy >= linkp->y && yy < linkp->h)
+      break;
+
+  if (!i)
+  {
+    fl_cursor(FL_CURSOR_DEFAULT);
+    return (1);
+  }
+
+  // Change the cursor for FL_MOTION events, and go to the link for
+  // clicks...
+  if (event == FL_MOVE)
+    fl_cursor(FL_CURSOR_HAND);
+  else
+  {
+    fl_cursor(FL_CURSOR_DEFAULT);
+
+    strlcpy(target, linkp->name, sizeof(target));
+
+    set_changed();
+
+    if (strcmp(linkp->filename, filename_) != 0 && linkp->filename[0])
+    {
+      char	dir[1024];	// Current directory
+      char	temp[1024],	// Temporary filename
+		*tempptr;	// Pointer into temporary filename
+
+
+      if (strchr(directory_, ':') != NULL &&
+          strchr(linkp->filename, ':') == NULL)
+      {
+	if (linkp->filename[0] == '/')
+	{
+          strlcpy(temp, directory_, sizeof(temp));
+          if ((tempptr = strrchr(strchr(directory_, ':') + 3, '/')) != NULL)
+	    strlcpy(tempptr, linkp->filename, sizeof(temp));
+	  else
+	    strlcat(temp, linkp->filename, sizeof(temp));
+	}
+	else
+	  snprintf(temp, sizeof(temp), "%s/%s", directory_, linkp->filename);
+      }
+      else if (linkp->filename[0] != '/' && strchr(linkp->filename, ':') == NULL)
+      {
+	if (directory_[0])
+	  snprintf(temp, sizeof(temp), "%s/%s", directory_, linkp->filename);
+	else
+	{
+	  getcwd(dir, sizeof(dir));
+	  snprintf(temp, sizeof(temp), "file:%s/%s", dir, linkp->filename);
+	}
+      }
+      else
+        strlcpy(temp, linkp->filename, sizeof(temp));
+
+      if (linkp->name[0])
+        snprintf(temp + strlen(temp), sizeof(temp) - strlen(temp), "#%s",
+	         linkp->name);
+
+      load(temp);
+    }
+    else if (target[0])
+      topline(target);
+    else
+      topline(0);
+
+    leftline(0);
+  }
+
+  return (1);
+}
+
+
+//
+// 'Fl_Help_View::Fl_Help_View()' - Build a Fl_Help_View widget.
+//
+
+Fl_Help_View::Fl_Help_View(int        xx,	// I - Left position
+                	   int        yy,	// I - Top position
+			   int        ww,	// I - Width in pixels
+			   int        hh,	// I - Height in pixels
+			   const char *l)
+    : Fl_Group(xx, yy, ww, hh, l),
+      scrollbar_(xx + ww - 17, yy, 17, hh - 17),
+      hscrollbar_(xx, yy + hh - 17, ww - 17, 17)
+{
+  color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
+
+  title_[0]     = '\0';
+  defcolor_     = FL_FOREGROUND_COLOR;
+  bgcolor_      = FL_BACKGROUND_COLOR;
+  textcolor_    = FL_FOREGROUND_COLOR;
+  linkcolor_    = FL_SELECTION_COLOR;
+  textfont_     = FL_TIMES;
+  textsize_     = 12;
+  value_        = NULL;
+
+  ablocks_      = 0;
+  nblocks_      = 0;
+  blocks_       = (Fl_Help_Block *)0;
+
+  nfonts_       = 0;
+
+  link_         = (Fl_Help_Func *)0;
+
+  alinks_       = 0;
+  nlinks_       = 0;
+  links_        = (Fl_Help_Link *)0;
+
+  atargets_     = 0;
+  ntargets_     = 0;
+  targets_      = (Fl_Help_Target *)0;
+
+  directory_[0] = '\0';
+  filename_[0]  = '\0';
+
+  topline_      = 0;
+  leftline_     = 0;
+  size_         = 0;
+  hsize_        = 0;
+
+  scrollbar_.value(0, hh, 0, 1);
+  scrollbar_.step(8.0);
+  scrollbar_.show();
+  scrollbar_.callback(scrollbar_callback);
+
+  hscrollbar_.value(0, ww, 0, 1);
+  hscrollbar_.step(8.0);
+  hscrollbar_.show();
+  hscrollbar_.callback(hscrollbar_callback);
+  hscrollbar_.type(FL_HORIZONTAL);
+  end();
+
+  resize(xx, yy, ww, hh);
+}
+
+
+//
+// 'Fl_Help_View::~Fl_Help_View()' - Destroy a Fl_Help_View widget.
+//
+
+Fl_Help_View::~Fl_Help_View()
+{
+  if (nblocks_)
+    free(blocks_);
+  if (nlinks_)
+    free(links_);
+  if (ntargets_)
+    free(targets_);
+  if (value_)
+    free((void *)value_);
+}
+
+
+//
+// 'Fl_Help_View::load()' - Load the specified file.
+//
+
+int				// O - 0 on success, -1 on error
+Fl_Help_View::load(const char *f)// I - Filename to load (may also have target)
+{
+  FILE		*fp;		// File to read from
+  long		len;		// Length of file
+  char		*target;	// Target in file
+  char		*slash;		// Directory separator
+  const char	*localname;	// Local filename
+  char		error[1024];	// Error buffer
+  char		newname[1024];	// New filename buffer
+
+
+  strlcpy(newname, f, sizeof(newname));
+  if ((target = strrchr(newname, '#')) != NULL)
+    *target++ = '\0';
+
+  if (link_)
+    localname = (*link_)(this, newname);
+  else
+    localname = filename_;
+
+  if (!localname)
+    return (0);
+
+  strlcpy(filename_, newname, sizeof(filename_));
+  strlcpy(directory_, newname, sizeof(directory_));
+
+  // Note: We do not support Windows backslashes, since they are illegal
+  //       in URLs...
+  if ((slash = strrchr(directory_, '/')) == NULL)
+    directory_[0] = '\0';
+  else if (slash > directory_ && slash[-1] != '/')
+    *slash = '\0';
+
+  if (value_ != NULL)
+  {
+    free((void *)value_);
+    value_ = NULL;
+  }
+
+  if (strncmp(localname, "ftp:", 4) == 0 ||
+      strncmp(localname, "http:", 5) == 0 ||
+      strncmp(localname, "https:", 6) == 0 ||
+      strncmp(localname, "ipp:", 4) == 0 ||
+      strncmp(localname, "mailto:", 7) == 0 ||
+      strncmp(localname, "news:", 5) == 0)
+  {
+    // Remote link wasn't resolved...
+    snprintf(error, sizeof(error),
+             "<HTML><HEAD><TITLE>Error</TITLE></HEAD>"
+             "<BODY><H1>Error</H1>"
+	     "<P>Unable to follow the link \"%s\" - "
+	     "no handler exists for this URI scheme.</P></BODY>",
+	     localname);
+    value_ = strdup(error);
+  }
+  else
+  {
+    if (strncmp(localname, "file:", 5) == 0)
+      localname += 5;	// Adjust for local filename...
+
+    if ((fp = fopen(localname, "rb")) != NULL)
+    {
+      fseek(fp, 0, SEEK_END);
+      len = ftell(fp);
+      rewind(fp);
+
+      value_ = (const char *)calloc(len + 1, 1);
+      fread((void *)value_, 1, len, fp);
+      fclose(fp);
+    }
+    else
+    {
+      snprintf(error, sizeof(error),
+               "<HTML><HEAD><TITLE>Error</TITLE></HEAD>"
+               "<BODY><H1>Error</H1>"
+	       "<P>Unable to follow the link \"%s\" - "
+	       "%s.</P></BODY>",
+	       localname, strerror(errno));
+      value_ = strdup(error);
+    }
+  }
+
+  format();
+
+  if (target)
+    topline(target);
+  else
+    topline(0);
+
+  return (0);
+}
+
+
+//
+// 'Fl_Help_View::resize()' - Resize the help widget.
+//
+
+void
+Fl_Help_View::resize(int xx,	// I - New left position
+                     int yy,	// I - New top position
+		     int ww,	// I - New width
+		     int hh)	// I - New height
+{
+  Fl_Boxtype		b = box() ? box() : FL_DOWN_BOX;
+					// Box to draw...
+
+
+  Fl_Widget::resize(xx, yy, ww, hh);
+
+  scrollbar_.resize(x() + w() - 17 - Fl::box_dw(b) + Fl::box_dx(b), y() + Fl::box_dy(b),
+                    17, h() - 17 - Fl::box_dh(b));
+  hscrollbar_.resize(x() + Fl::box_dx(b), y() + h() - 17 - Fl::box_dh(b) + Fl::box_dy(b),
+                     w() - 17 - Fl::box_dw(b), 17);
+
+  format();
+}
+
+
+//
+// 'Fl_Help_View::topline()' - Set the top line to the named target.
+//
+
+void
+Fl_Help_View::topline(const char *n)	// I - Target name
+{
+  Fl_Help_Target key,			// Target name key
+		*target;		// Pointer to matching target
+
+
+  if (ntargets_ == 0)
+    return;
+
+  strlcpy(key.name, n, sizeof(key.name));
+
+  target = (Fl_Help_Target *)bsearch(&key, targets_, ntargets_, sizeof(Fl_Help_Target),
+                                 (compare_func_t)compare_targets);
+
+  if (target != NULL)
+    topline(target->y);
+}
+
+
+//
+// 'Fl_Help_View::topline()' - Set the top line by number.
+//
+
+void
+Fl_Help_View::topline(int t)	// I - Top line number
+{
+  if (!value_)
+    return;
+
+  if (size_ < (h() - 24) || t < 0)
+    t = 0;
+  else if (t > size_)
+    t = size_;
+
+  topline_ = t;
+
+  scrollbar_.value(topline_, h() - 24, 0, size_);
+
+  do_callback();
+
+  redraw();
+}
+
+
+//
+// 'Fl_Help_View::leftline()' - Set the left position.
+//
+
+void
+Fl_Help_View::leftline(int l)	// I - Left position
+{
+  if (!value_)
+    return;
+
+  if (hsize_ < (w() - 24) || l < 0)
+    l = 0;
+  else if (l > hsize_)
+    l = hsize_;
+
+  leftline_ = l;
+
+  hscrollbar_.value(leftline_, w() - 24, 0, hsize_);
+
+  redraw();
+}
+
+
+//
+// 'Fl_Help_View::value()' - Set the help text directly.
+//
+
+void
+Fl_Help_View::value(const char *v)	// I - Text to view
+{
+  if (!v)
+    return;
+
+  if (value_ != NULL)
+    free((void *)value_);
+
+  value_ = strdup(v);
+
+  format();
+
+  set_changed();
+  topline(0);
+  leftline(0);
+}
+
+
+//
+// 'quote_char()' - Return the character code associated with a quoted char.
+//
+
+static int			// O - Code or -1 on error
+quote_char(const char *p) {	// I - Quoted string
+  int	i;			// Looping var
+  static struct {
+    const char	*name;
+    int		namelen;
+    int		code;
+  }	*nameptr,		// Pointer into name array
+	names[] = {		// Quoting names
+    { "Aacute;", 7, 193 },
+    { "aacute;", 7, 225 },
+    { "Acirc;",  6, 194 },
+    { "acirc;",  6, 226 },
+    { "acute;",  6, 180 },
+    { "AElig;",  6, 198 },
+    { "aelig;",  6, 230 },
+    { "Agrave;", 7, 192 },
+    { "agrave;", 7, 224 },
+    { "amp;",    4, '&' },
+    { "Aring;",  6, 197 },
+    { "aring;",  6, 229 },
+    { "Atilde;", 7, 195 },
+    { "atilde;", 7, 227 },
+    { "Auml;",   5, 196 },
+    { "auml;",   5, 228 },
+    { "brvbar;", 7, 166 },
+    { "Ccedil;", 7, 199 },
+    { "ccedil;", 7, 231 },
+    { "cedil;",  6, 184 },
+    { "cent;",   5, 162 },
+    { "copy;",   5, 169 },
+    { "curren;", 7, 164 },
+    { "deg;",    4, 176 },
+    { "divide;", 7, 247 },
+    { "Eacute;", 7, 201 },
+    { "eacute;", 7, 233 },
+    { "Ecirc;",  6, 202 },
+    { "ecirc;",  6, 234 },
+    { "Egrave;", 7, 200 },
+    { "egrave;", 7, 232 },
+    { "ETH;",    4, 208 },
+    { "eth;",    4, 240 },
+    { "Euml;",   5, 203 },
+    { "euml;",   5, 235 },
+    { "frac12;", 7, 189 },
+    { "frac14;", 7, 188 },
+    { "frac34;", 7, 190 },
+    { "gt;",     3, '>' },
+    { "Iacute;", 7, 205 },
+    { "iacute;", 7, 237 },
+    { "Icirc;",  6, 206 },
+    { "icirc;",  6, 238 },
+    { "iexcl;",  6, 161 },
+    { "Igrave;", 7, 204 },
+    { "igrave;", 7, 236 },
+    { "iquest;", 7, 191 },
+    { "Iuml;",   5, 207 },
+    { "iuml;",   5, 239 },
+    { "laquo;",  6, 171 },
+    { "lt;",     3, '<' },
+    { "macr;",   5, 175 },
+    { "micro;",  6, 181 },
+    { "middot;", 7, 183 },
+    { "nbsp;",   5, ' ' },
+    { "not;",    4, 172 },
+    { "Ntilde;", 7, 209 },
+    { "ntilde;", 7, 241 },
+    { "Oacute;", 7, 211 },
+    { "oacute;", 7, 243 },
+    { "Ocirc;",  6, 212 },
+    { "ocirc;",  6, 244 },
+    { "Ograve;", 7, 210 },
+    { "ograve;", 7, 242 },
+    { "ordf;",   5, 170 },
+    { "ordm;",   5, 186 },
+    { "Oslash;", 7, 216 },
+    { "oslash;", 7, 248 },
+    { "Otilde;", 7, 213 },
+    { "otilde;", 7, 245 },
+    { "Ouml;",   5, 214 },
+    { "ouml;",   5, 246 },
+    { "para;",   5, 182 },
+    { "plusmn;", 7, 177 },
+    { "pound;",  6, 163 },
+    { "quot;",   5, '\"' },
+    { "raquo;",  6, 187 },
+    { "reg;",    4, 174 },
+    { "sect;",   5, 167 },
+    { "shy;",    4, 173 },
+    { "sup1;",   5, 185 },
+    { "sup2;",   5, 178 },
+    { "sup3;",   5, 179 },
+    { "szlig;",  6, 223 },
+    { "THORN;",  6, 222 },
+    { "thorn;",  6, 254 },
+    { "times;",  6, 215 },
+    { "Uacute;", 7, 218 },
+    { "uacute;", 7, 250 },
+    { "Ucirc;",  6, 219 },
+    { "ucirc;",  6, 251 },
+    { "Ugrave;", 7, 217 },
+    { "ugrave;", 7, 249 },
+    { "uml;",    4, 168 },
+    { "Uuml;",   5, 220 },
+    { "uuml;",   5, 252 },
+    { "Yacute;", 7, 221 },
+    { "yacute;", 7, 253 },
+    { "yen;",    4, 165 },
+    { "yuml;",   5, 255 }
+  };
+
+  if (!strchr(p, ';')) return -1;
+  if (*p == '#') {
+    if (*(p+1) == 'x' || *(p+1) == 'X') return strtol(p+2, NULL, 16);
+    else return atoi(p+1);
+  }
+  for (i = (int)(sizeof(names) / sizeof(names[0])), nameptr = names; i > 0; i --, nameptr ++)
+    if (strncmp(p, nameptr->name, nameptr->namelen) == 0)
+      return nameptr->code;
+
+  return -1;
+}
+
+
+//
+// 'scrollbar_callback()' - A callback for the scrollbar.
+//
+
+static void
+scrollbar_callback(Fl_Widget *s, void *)
+{
+  ((Fl_Help_View *)(s->parent()))->topline(int(((Fl_Scrollbar*)s)->value()));
+}
+
+
+//
+// 'hscrollbar_callback()' - A callback for the horizontal scrollbar.
+//
+
+static void
+hscrollbar_callback(Fl_Widget *s, void *)
+{
+  ((Fl_Help_View *)(s->parent()))->leftline(int(((Fl_Scrollbar*)s)->value()));
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Image.cxx b/Utilities/FLTK/src/Fl_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..329a71288ab40835d835ef8e14273f7107772a8a
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Image.cxx
@@ -0,0 +1,439 @@
+//
+// "$Id$"
+//
+// Image drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Image.H>
+#include "flstring.h"
+
+#ifdef WIN32
+void fl_release_dc(HWND, HDC); // from Fl_win32.cxx
+#endif
+
+void fl_restore_clip(); // from fl_rect.cxx
+
+//
+// Base image class...
+//
+
+Fl_Image::~Fl_Image() {
+}
+
+void Fl_Image::uncache() {
+}
+
+void Fl_Image::draw(int XP, int YP, int, int, int, int) {
+  draw_empty(XP, YP);
+}
+
+void Fl_Image::draw_empty(int X, int Y) {
+  if (w() > 0 && h() > 0) {
+    fl_color(FL_FOREGROUND_COLOR);
+    fl_rect(X, Y, w(), h());
+    fl_line(X, Y, X + w() - 1, Y + h() - 1);
+    fl_line(X, Y + h() - 1, X + w() - 1, Y);
+  }
+}
+
+Fl_Image *Fl_Image::copy(int W, int H) {
+  return new Fl_Image(W, H, d());
+}
+
+void Fl_Image::color_average(Fl_Color, float) {
+}
+
+void Fl_Image::desaturate() {
+}
+
+void Fl_Image::label(Fl_Widget* widget) {
+  widget->image(this);
+}
+
+void Fl_Image::label(Fl_Menu_Item* m) {
+  Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure);
+  m->label(_FL_IMAGE_LABEL, (const char*)this);
+}
+
+void
+Fl_Image::labeltype(const Fl_Label *lo,		// I - Label
+                    int            lx,		// I - X position
+		    int            ly,		// I - Y position
+		    int            lw,		// I - Width of label
+		    int            lh,		// I - Height of label
+		    Fl_Align       la) {	// I - Alignment
+  Fl_Image	*img;				// Image pointer
+  int		cx, cy;				// Image position
+
+  img = (Fl_Image *)(lo->value);
+
+  if (la & FL_ALIGN_LEFT) cx = 0;
+  else if (la & FL_ALIGN_RIGHT) cx = img->w() - lw;
+  else cx = (img->w() - lw) / 2;
+
+  if (la & FL_ALIGN_TOP) cy = 0;
+  else if (la & FL_ALIGN_BOTTOM) cy = img->h() - lh;
+  else cy = (img->h() - lh) / 2;
+
+  fl_color((Fl_Color)lo->color);
+
+  img->draw(lx, ly, lw, lh, cx, cy);
+}
+
+void
+Fl_Image::measure(const Fl_Label *lo,		// I - Label
+                  int            &lw,		// O - Width of image
+		  int            &lh) {		// O - Height of image
+  Fl_Image *img;				// Image pointer
+
+  img = (Fl_Image *)(lo->value);
+
+  lw = img->w();
+  lh = img->h();
+}
+
+
+//
+// RGB image class...
+//
+
+Fl_RGB_Image::~Fl_RGB_Image() {
+  uncache();
+  if (alloc_array) delete[] (uchar *)array;
+}
+
+void Fl_RGB_Image::uncache() {
+#ifdef __APPLE_QUARTZ__
+  if (id)
+    CGImageRelease((CGImageRef)id);
+#else
+  if (id) {
+    fl_delete_offscreen((Fl_Offscreen)id);
+    id = 0;
+  }
+
+  if (mask) {
+    fl_delete_bitmask((Fl_Bitmask)mask);
+    mask = 0;
+  }
+#endif
+}
+
+Fl_Image *Fl_RGB_Image::copy(int W, int H) {
+  Fl_RGB_Image	*new_image;	// New RGB image
+  uchar		*new_array;	// New array for image data
+
+  // Optimize the simple copy where the width and height are the same,
+  // or when we are copying an empty image...
+  if ((W == w() && H == h()) ||
+      !w() || !h() || !d() || !array) {
+    if (array) {
+      // Make a copy of the image data and return a new Fl_RGB_Image...
+      new_array = new uchar[w() * h() * d()];
+      memcpy(new_array, array, w() * h() * d());
+
+      new_image = new Fl_RGB_Image(new_array, w(), h(), d(), ld());
+      new_image->alloc_array = 1;
+
+      return new_image;
+    } else return new Fl_RGB_Image(array, w(), h(), d(), ld());
+  }
+  if (W <= 0 || H <= 0) return 0;
+
+  // OK, need to resize the image data; allocate memory and 
+  uchar		*new_ptr;	// Pointer into new array
+  const uchar	*old_ptr;	// Pointer into old array
+  int		c,		// Channel number
+		sy,		// Source coordinate
+		dx, dy,		// Destination coordinates
+		xerr, yerr,	// X & Y errors
+		xmod, ymod,	// X & Y moduli
+		xstep, ystep;	// X & Y step increments
+
+
+  // Figure out Bresenheim step/modulus values...
+  xmod   = w() % W;
+  xstep  = (w() / W) * d();
+  ymod   = h() % H;
+  ystep  = h() / H;
+
+  // Allocate memory for the new image...
+  new_array = new uchar [W * H * d()];
+  new_image = new Fl_RGB_Image(new_array, W, H, d());
+  new_image->alloc_array = 1;
+
+  // Scale the image using a nearest-neighbor algorithm...
+  for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) {
+    for (dx = W, xerr = W, old_ptr = array + sy * (w() * d() + ld());
+	 dx > 0;
+	 dx --) {
+      for (c = 0; c < d(); c ++) *new_ptr++ = old_ptr[c];
+
+      old_ptr += xstep;
+      xerr    -= xmod;
+
+      if (xerr <= 0) {
+	xerr    += W;
+	old_ptr += d();
+      }
+    }
+
+    sy   += ystep;
+    yerr -= ymod;
+    if (yerr <= 0) {
+      yerr += H;
+      sy ++;
+    }
+  }
+
+  return new_image;
+}
+
+void Fl_RGB_Image::color_average(Fl_Color c, float i) {
+  // Don't average an empty image...
+  if (!w() || !h() || !d() || !array) return;
+
+  // Delete any existing pixmap/mask objects...
+  uncache();
+
+  // Allocate memory as needed...
+  uchar		*new_array,
+		*new_ptr;
+
+  if (!alloc_array) new_array = new uchar[h() * w() * d()];
+  else new_array = (uchar *)array;
+
+  // Get the color to blend with...
+  uchar		r, g, b;
+  unsigned	ia, ir, ig, ib;
+
+  Fl::get_color(c, r, g, b);
+  if (i < 0.0f) i = 0.0f;
+  else if (i > 1.0f) i = 1.0f;
+
+  ia = (unsigned)(256 * i);
+  ir = r * (256 - ia);
+  ig = g * (256 - ia);
+  ib = b * (256 - ia);
+
+  // Update the image data to do the blend...
+  const uchar	*old_ptr;
+  int		x, y;
+
+  if (d() < 3) {
+    ig = (r * 31 + g * 61 + b * 8) / 100 * (256 - ia);
+
+    for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += ld())
+      for (x = 0; x < w(); x ++) {
+	*new_ptr++ = (*old_ptr++ * ia + ig) >> 8;
+	if (d() > 1) *new_ptr++ = *old_ptr++;
+      }
+  } else {
+    for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += ld())
+      for (x = 0; x < w(); x ++) {
+	*new_ptr++ = (*old_ptr++ * ia + ir) >> 8;
+	*new_ptr++ = (*old_ptr++ * ia + ig) >> 8;
+	*new_ptr++ = (*old_ptr++ * ia + ib) >> 8;
+	if (d() > 3) *new_ptr++ = *old_ptr++;
+      }
+  }
+
+  // Set the new pointers/values as needed...
+  if (!alloc_array) {
+    array       = new_array;
+    alloc_array = 1;
+
+    ld(0);
+  }
+}
+
+void Fl_RGB_Image::desaturate() {
+  // Don't desaturate an empty image...
+  if (!w() || !h() || !d() || !array) return;
+
+  // Can only desaturate color images...
+  if (d() < 3) return;
+
+  // Delete any existing pixmap/mask objects...
+  uncache();
+
+  // Allocate memory for a grayscale image...
+  uchar		*new_array,
+		*new_ptr;
+  int		new_d;
+
+  new_d     = d() - 2;
+  new_array = new uchar[h() * w() * new_d];
+
+  // Copy the image data, converting to grayscale...
+  const uchar	*old_ptr;
+  int		x, y;
+
+  for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += ld())
+    for (x = 0; x < w(); x ++, old_ptr += d()) {
+      *new_ptr++ = (uchar)((31 * old_ptr[0] + 61 * old_ptr[1] + 8 * old_ptr[2]) / 100);
+      if (d() > 3) *new_ptr++ = old_ptr[3];
+    }
+
+  // Free the old array as needed, and then set the new pointers/values...
+  if (alloc_array) delete[] (uchar *)array;
+
+  array       = new_array;
+  alloc_array = 1;
+
+  ld(0);
+  d(new_d);
+}
+
+void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+  // Don't draw an empty image...
+  if (!d() || !array) {
+    draw_empty(XP, YP);
+    return;
+  }
+
+  // account for current clip region (faster on Irix):
+  int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
+  cx += X-XP; cy += Y-YP;
+  // clip the box down to the size of image, quit if empty:
+  if (cx < 0) {W += cx; X -= cx; cx = 0;}
+  if (cx+W > w()) W = w()-cx;
+  if (W <= 0) return;
+  if (cy < 0) {H += cy; Y -= cy; cy = 0;}
+  if (cy+H > h()) H = h()-cy;
+  if (H <= 0) return;
+  if (!id) {
+#ifdef __APPLE_QUARTZ__
+    CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+    CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, w()*h()*d(), 0L);
+    id = CGImageCreate( w(), h(), 8, d()*8, ld()?ld():w()*d(),
+        lut, (d()&1)?kCGImageAlphaNone:kCGImageAlphaLast,
+        src, 0L, false, kCGRenderingIntentDefault);
+    CGColorSpaceRelease(lut);
+    CGDataProviderRelease(src);
+#else
+    id = fl_create_offscreen(w(), h());
+    fl_begin_offscreen((Fl_Offscreen)id);
+    fl_draw_image(array, 0, 0, w(), h(), d(), ld());
+    fl_end_offscreen();
+    if (d() == 2 || d() == 4) {
+      mask = fl_create_alphamask(w(), h(), d(), ld(), array);
+    }
+#endif
+  }
+#ifdef WIN32
+  if (mask) {
+    HDC new_gc = CreateCompatibleDC(fl_gc);
+    int save = SaveDC(new_gc);
+    SelectObject(new_gc, (void*)mask);
+    BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND);
+    SelectObject(new_gc, (void*)id);
+    BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
+    RestoreDC(new_gc,save);
+    DeleteDC(new_gc);
+  } else {
+    fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
+  }
+#elif defined(__APPLE_QD__)
+  if (mask) {
+    Rect src, dst;
+    // MRS: STR #114 says we should be using cx, cy, W, and H...
+//    src.left = 0; src.right = w();
+//    src.top = 0; src.bottom = h();
+//    dst.left = X; dst.right = X+w();
+//    dst.top = Y; dst.bottom = Y+h();
+    src.left = cx; src.right = cx+W;
+    src.top = cy; src.bottom = cy+H;
+    dst.left = X; dst.right = X+W;
+    dst.top = Y; dst.bottom = Y+H;
+    RGBColor rgb;
+    rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff;
+    RGBBackColor(&rgb);
+    rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000;
+    RGBForeColor(&rgb);
+
+#  if 0
+    // MRS: This *should* work, but doesn't on my system (iBook); change to
+    //      "#if 1" and restore the corresponding code in Fl_Bitmap.cxx
+    //      to test the real alpha channel support.
+    CopyDeepMask(GetPortBitMapForCopyBits((GrafPtr)id),
+	         GetPortBitMapForCopyBits((GrafPtr)mask), 
+	         GetPortBitMapForCopyBits(GetWindowPort(fl_window)),
+                 &src, &src, &dst, blend, NULL);
+#  else // Fallback to screen-door transparency...
+    CopyMask(GetPortBitMapForCopyBits((GrafPtr)id),
+	     GetPortBitMapForCopyBits((GrafPtr)mask), 
+	     GetPortBitMapForCopyBits(GetWindowPort(fl_window)),
+             &src, &src, &dst);
+#  endif // 0
+  } else {
+    fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
+  }
+#elif defined(__APPLE_QUARTZ__)
+  if (id && fl_gc) {
+    CGRect rect = { X, Y, W, H };
+    Fl_X::q_begin_image(rect, cx, cy, w(), h());
+    CGContextDrawImage(fl_gc, rect, (CGImageRef)id);
+    Fl_X::q_end_image();
+  }
+#else
+  if (mask) {
+    // I can't figure out how to combine a mask with existing region,
+    // so cut the image down to a clipped rectangle:
+    int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H);
+    cx += nx-X; X = nx;
+    cy += ny-Y; Y = ny;
+    // make X use the bitmap as a mask:
+    XSetClipMask(fl_display, fl_gc, mask);
+    int ox = X-cx; if (ox < 0) ox += w();
+    int oy = Y-cy; if (oy < 0) oy += h();
+    XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy);
+  }
+  fl_copy_offscreen(X, Y, W, H, id, cx, cy);
+  if (mask) {
+    // put the old clip region back
+    XSetClipOrigin(fl_display, fl_gc, 0, 0);
+    fl_restore_clip();
+  }
+#endif
+}
+
+void Fl_RGB_Image::label(Fl_Widget* widget) {
+  widget->image(this);
+}
+
+void Fl_RGB_Image::label(Fl_Menu_Item* m) {
+  Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure);
+  m->label(_FL_IMAGE_LABEL, (const char*)this);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Input.cxx b/Utilities/FLTK/src/Fl_Input.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ef12c7487fc043ccd06fa41ec93ddcaba192b993
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Input.cxx
@@ -0,0 +1,467 @@
+//
+// "$Id$"
+//
+// Input widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This is the "user interface", it decodes user actions into what to
+// do to the text.  See also Fl_Input_.cxx, where the text is actually
+// manipulated (and some ui, in particular the mouse, is done...).
+// In theory you can replace this code with another subclass to change
+// the keybindings.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_ask.H>
+#include "flstring.h"
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+
+void Fl_Input::draw() {
+  if (input_type() == FL_HIDDEN_INPUT) return;
+  Fl_Boxtype b = box();
+  if (damage() & FL_DAMAGE_ALL) draw_box(b, color());
+  Fl_Input_::drawtext(x()+Fl::box_dx(b), y()+Fl::box_dy(b),
+		      w()-Fl::box_dw(b), h()-Fl::box_dh(b));
+}
+
+// kludge so shift causes selection to extend:
+int Fl_Input::shift_position(int p) {
+  return position(p, Fl::event_state(FL_SHIFT) ? mark() : p);
+}
+int Fl_Input::shift_up_down_position(int p) {
+  return up_down_position(p, Fl::event_state(FL_SHIFT));
+}
+
+// If you define this symbol as zero you will get the peculiar fltk
+// behavior where moving off the end of an input field will move the
+// cursor into the next field:
+// define it as 1 to prevent cursor movement from going to next field:
+#define NORMAL_INPUT_MOVE 0
+
+#define ctrl(x) ((x)^0x40)
+
+// List of characters that are legal in a floating point input field.
+// This text string is created at run-time to take the current locale
+// into account (for example, continental Europe uses a comma instead
+// of a decimal point). For back compatibility reasons, we always 
+// allow the decimal point.
+#ifdef HAVE_LOCALECONV
+static const char *standard_fp_chars = ".eE+-"; 
+static const char *legal_fp_chars = 0L;
+#else
+static const char *legal_fp_chars = ".eE+-"; 
+#endif
+
+int Fl_Input::handle_key() {
+
+  char ascii = Fl::event_text()[0];
+
+  int repeat_num=1;
+
+  int del;
+  if (Fl::compose(del)) {
+
+    // Insert characters into numeric fields after checking for legality:
+    if (input_type() == FL_FLOAT_INPUT || input_type() == FL_INT_INPUT) {
+      Fl::compose_reset(); // ignore any foreign letters...
+
+      // initialize the list of legal characters inside a floating point number
+#ifdef HAVE_LOCALECONV
+      if (!legal_fp_chars) {
+        int len = strlen(standard_fp_chars);
+        struct lconv *lc = localeconv();
+        if (lc) {
+          if (lc->decimal_point) len += strlen(lc->decimal_point);
+          if (lc->mon_decimal_point) len += strlen(lc->mon_decimal_point);
+          if (lc->positive_sign) len += strlen(lc->positive_sign);
+          if (lc->negative_sign) len += strlen(lc->negative_sign);
+        }
+        // the following line is not a true memory leak because the array is only
+        // allocated once if required, and automatically freed when the program quits
+        char *chars = (char*)malloc(len+1);
+	legal_fp_chars = chars;
+        strcpy(chars, standard_fp_chars);
+        if (lc) {
+          if (lc->decimal_point) strcat(chars, lc->decimal_point);
+          if (lc->mon_decimal_point) strcat(chars, lc->mon_decimal_point);
+          if (lc->positive_sign) strcat(chars, lc->positive_sign);
+          if (lc->negative_sign) strcat(chars, lc->negative_sign);
+        }
+      }
+#endif // HAVE_LOCALECONV
+
+      // This is complex to allow "0xff12" hex to be typed:
+      if (!position() && (ascii == '+' || ascii == '-') ||
+	  (ascii >= '0' && ascii <= '9') ||
+	  (position()==1 && index(0)=='0' && (ascii=='x' || ascii == 'X')) ||
+	  (position()>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X')
+	   && (ascii>='A'&& ascii<='F' || ascii>='a'&& ascii<='f')) ||
+	  input_type()==FL_FLOAT_INPUT && ascii && strchr(legal_fp_chars, ascii)) {
+	if (readonly()) fl_beep();
+	else replace(position(), mark(), &ascii, 1);
+      }
+      return 1;
+    }
+
+    if (del || Fl::event_length()) {
+      if (readonly()) fl_beep();
+      else replace(position(), del ? position()-del : mark(),
+	           Fl::event_text(), Fl::event_length());
+    }
+    return 1;
+  }
+
+  switch (Fl::event_key()) {
+  case FL_Insert:
+    if (Fl::event_state() & FL_CTRL) ascii = ctrl('C');
+    else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V');
+    break;
+  case FL_Delete:
+    if (Fl::event_state() & FL_SHIFT) ascii = ctrl('X');
+    else ascii = ctrl('D');
+    break;    
+  case FL_Left:
+    ascii = ctrl('B'); break;
+  case FL_Right:
+    ascii = ctrl('F'); break;
+  case FL_Page_Up:
+    fl_font(textfont(),textsize()); //ensure current font is set to ours
+    repeat_num=h()/fl_height(); // number of lines to scroll
+    if (!repeat_num) repeat_num=1;
+  case FL_Up:
+    ascii = ctrl('P'); break;
+  case FL_Page_Down:
+    fl_font(textfont(),textsize());
+    repeat_num=h()/fl_height();
+    if (!repeat_num) repeat_num=1;
+  case FL_Down:
+    ascii = ctrl('N'); break;
+  case FL_Home:
+    if (Fl::event_state() & FL_CTRL) {
+      shift_position(0);
+      return 1;
+    }
+    ascii = ctrl('A');
+    break;
+  case FL_End:
+    if (Fl::event_state() & FL_CTRL) {
+      shift_position(size());
+      return 1;
+    }
+    ascii = ctrl('E'); break;
+    
+  case FL_BackSpace:
+    ascii = ctrl('H'); break;
+  case FL_Enter:
+  case FL_KP_Enter:
+    if (when() & FL_WHEN_ENTER_KEY) {
+      position(size(), 0);
+      maybe_do_callback();
+      return 1;
+    } else if (input_type() == FL_MULTILINE_INPUT && !readonly())
+      return replace(position(), mark(), "\n", 1);
+    else 
+      return 0;	// reserved for shortcuts
+  case FL_Tab:
+    if (Fl::event_state(FL_CTRL|FL_SHIFT) || input_type()!=FL_MULTILINE_INPUT || readonly()) return 0;
+    return replace(position(), mark(), &ascii, 1);
+#ifdef __APPLE__
+  case 'c' :
+  case 'v' :
+  case 'x' :
+  case 'z' :
+//    printf("'%c' (0x%02x) pressed with%s%s%s%s\n", ascii, ascii,
+//           Fl::event_state(FL_SHIFT) ? " FL_SHIFT" : "",
+//           Fl::event_state(FL_CTRL) ? " FL_CTRL" : "",
+//           Fl::event_state(FL_ALT) ? " FL_ALT" : "",
+//           Fl::event_state(FL_META) ? " FL_META" : "");
+    if (Fl::event_state(FL_META)) ascii -= 0x60;
+//    printf("using '%c' (0x%02x)...\n", ascii, ascii);
+    break;
+#endif // __APPLE__
+  }
+
+  int i;
+  switch (ascii) {
+  case ctrl('A'):
+    return shift_position(line_start(position())) + NORMAL_INPUT_MOVE;
+  case ctrl('B'):
+    return shift_position(position()-1) + NORMAL_INPUT_MOVE;
+  case ctrl('C'): // copy
+    return copy(1);
+  case ctrl('D'):
+  case ctrl('?'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    if (mark() != position()) return cut();
+    else return cut(1);
+  case ctrl('E'):
+    return shift_position(line_end(position())) + NORMAL_INPUT_MOVE;
+  case ctrl('F'):
+    return shift_position(position()+1) + NORMAL_INPUT_MOVE;
+  case ctrl('H'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    if (mark() != position()) cut();
+    else cut(-1);
+    return 1;
+  case ctrl('K'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    if (position()>=size()) return 0;
+    i = line_end(position());
+    if (i == position() && i < size()) i++;
+    cut(position(), i);
+    return copy_cuts();
+  case ctrl('N'):
+    i = position();
+    if (line_end(i) >= size()) return NORMAL_INPUT_MOVE;
+    while (repeat_num--) {  
+      i = line_end(i);
+      if (i >= size()) break;
+      i++;
+    }
+    shift_up_down_position(i);
+    return 1;
+  case ctrl('P'):
+    i = position();
+    if (!line_start(i)) return NORMAL_INPUT_MOVE;
+    while(repeat_num--) {
+      i = line_start(i);
+      if (!i) break;
+      i--;
+    }
+    shift_up_down_position(line_start(i));
+    return 1;
+  case ctrl('U'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    return cut(0, size());
+  case ctrl('V'):
+  case ctrl('Y'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    Fl::paste(*this, 1);
+    return 1;
+  case ctrl('X'):
+  case ctrl('W'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    copy(1);
+    return cut();
+  case ctrl('Z'):
+  case ctrl('_'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    return undo();
+  case ctrl('I'):
+  case ctrl('J'):
+  case ctrl('L'):
+  case ctrl('M'):
+    if (readonly()) {
+      fl_beep();
+      return 1;
+    }
+    // insert a few selected control characters literally:
+    if (input_type() != FL_FLOAT_INPUT && input_type() != FL_INT_INPUT)
+      return replace(position(), mark(), &ascii, 1);
+  }
+
+  return 0;
+}
+
+int Fl_Input::handle(int event) {
+  static int dnd_save_position, dnd_save_mark, drag_start = -1, newpos;
+  static Fl_Widget *dnd_save_focus;
+  switch (event) {
+  case FL_FOCUS:
+    switch (Fl::event_key()) {
+    case FL_Right:
+      position(0);
+      break;
+    case FL_Left:
+      position(size());
+      break;
+    case FL_Down:
+      up_down_position(0);
+      break;
+    case FL_Up:
+      up_down_position(line_start(size()));
+      break;
+    case FL_Tab:
+    case 0xfe20: // XK_ISO_Left_Tab
+      position(size(),0);
+      break;
+    default:
+      position(position(),mark());// turns off the saved up/down arrow position
+      break;
+    }
+    break;
+
+  case FL_KEYBOARD:
+    if (Fl::event_key() == FL_Tab && mark() != position()) {
+      // Set the current cursor position to the end of the selection...
+      if (mark() > position())
+        position(mark());
+      else
+        position(position());
+      return (1);
+    } else return handle_key();
+
+  case FL_PUSH:
+    if (Fl::dnd_text_ops()) {
+      int oldpos = position(), oldmark = mark();
+      Fl_Boxtype b = box();
+      Fl_Input_::handle_mouse(
+	x()+Fl::box_dx(b), y()+Fl::box_dy(b),
+	w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
+      newpos = position(); 
+      position( oldpos, oldmark );
+      if (Fl::focus()==this && !Fl::event_state(FL_SHIFT) && input_type()!=FL_SECRET_INPUT &&
+	  (newpos >= mark() && newpos < position() ||
+	  newpos >= position() && newpos < mark())) {
+	// user clicked in the selection, may be trying to drag
+	drag_start = newpos;
+	return 1;
+      }
+      drag_start = -1;
+    }
+
+    if (Fl::focus() != this) {
+      Fl::focus(this);
+      handle(FL_FOCUS);
+    }
+    break;
+
+  case FL_DRAG:
+    if (Fl::dnd_text_ops()) {
+      if (drag_start >= 0) {
+	if (Fl::event_is_click()) return 1; // debounce the mouse
+	// save the position because sometimes we don't get DND_ENTER:
+	dnd_save_position = position();
+	dnd_save_mark = mark();
+	// drag the data:
+	copy(0); Fl::dnd();
+	return 1;
+      }
+    }
+    break;
+
+  case FL_RELEASE:
+    if (Fl::event_button() == 2) {
+      Fl::event_is_click(0); // stop double click from picking a word
+      Fl::paste(*this, 0);
+    } else if (!Fl::event_is_click()) {
+      // copy drag-selected text to the clipboard.
+      copy(0);
+    } else if (Fl::event_is_click() && drag_start >= 0) {
+      // user clicked in the field and wants to reset the cursor position...
+      position(drag_start, drag_start);
+      drag_start = -1;
+    } else if (Fl::event_clicks()) {
+      // user double or triple clicked to select word or whole text
+      copy(0);
+    }
+    // For output widgets, do the callback so the app knows the user
+    // did something with the mouse...
+    if (readonly()) do_callback();
+    return 1;
+
+  case FL_DND_ENTER:
+    Fl::belowmouse(this); // send the leave events first
+    dnd_save_position = position();
+    dnd_save_mark = mark();
+    dnd_save_focus = Fl::focus();
+    if (dnd_save_focus != this) {
+      Fl::focus(this);
+      handle(FL_FOCUS);
+    }
+    // fall through:
+  case FL_DND_DRAG: 
+    //int p = mouse_position(X, Y, W, H);
+#if DND_OUT_XXXX
+    if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark ||
+		      p>=dnd_save_mark && p<=dnd_save_position)) {
+      position(dnd_save_position, dnd_save_mark);
+      return 0;
+    }
+#endif
+    {
+      Fl_Boxtype b = box();
+      Fl_Input_::handle_mouse(
+	x()+Fl::box_dx(b), y()+Fl::box_dy(b),
+	w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
+    }
+    return 1;
+
+  case FL_DND_LEAVE:
+    position(dnd_save_position, dnd_save_mark);
+#if DND_OUT_XXXX
+    if (!focused())
+#endif
+    if (dnd_save_focus != this) {
+      Fl::focus(dnd_save_focus);
+      handle(FL_UNFOCUS);
+    }
+    return 1;
+
+  case FL_DND_RELEASE:
+    take_focus();
+    return 1;
+
+  }
+  Fl_Boxtype b = box();
+  return Fl_Input_::handletext(event,
+	x()+Fl::box_dx(b), y()+Fl::box_dy(b),
+	w()-Fl::box_dw(b), h()-Fl::box_dh(b));
+}
+
+Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l)
+: Fl_Input_(X, Y, W, H, l) {
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Input_.cxx b/Utilities/FLTK/src/Fl_Input_.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..142870bec7d0621f7d2164a27c314c7258caca41
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Input_.cxx
@@ -0,0 +1,882 @@
+//
+// "$Id$"
+//
+// Common input widget routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This is the base class for Fl_Input.  You can use it directly
+// if you are one of those people who like to define their own
+// set of editing keys.  It may also be useful for adding scrollbars
+// to the input field.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Input_.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_ask.H>
+#include <math.h>
+#include "flstring.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+#define MAXBUF 1024
+
+extern void fl_draw(const char*, int, float, float);
+
+////////////////////////////////////////////////////////////////
+
+// Copy string p..e to the buffer, replacing characters with ^X and \nnn
+// as necessary.  Truncate if necessary so the resulting string and
+// null terminator fits in a buffer of size n.  Return new end pointer.
+const char* Fl_Input_::expand(const char* p, char* buf) const {
+  char* o = buf;
+  char* e = buf+(MAXBUF-4);
+  const char* lastspace = p;
+  char* lastspace_out = o;
+  int width_to_lastspace = 0;
+  int word_count = 0;
+  int word_wrap;
+
+  if (input_type()==FL_SECRET_INPUT) {
+    while (o<e && p < value_+size_) {*o++ = '*'; p++;}
+  } else while (o<e) {
+    if (wrap() && (p >= value_+size_ || isspace(*p & 255))) {
+      word_wrap = w() - Fl::box_dw(box()) - 2;
+      width_to_lastspace += (int)fl_width(lastspace_out, o-lastspace_out);
+      if (p > lastspace+1) {
+	if (word_count && width_to_lastspace > word_wrap) {
+	  p = lastspace; o = lastspace_out; break;
+	}
+	word_count++;
+      }
+      lastspace = p;
+      lastspace_out = o;
+    }
+
+    if (p >= value_+size_) break;
+    int c = *p++ & 255;
+    if (c < ' ' || c == 127) {
+      if (c=='\n' && input_type()==FL_MULTILINE_INPUT) {p--; break;}
+      if (c == '\t' && input_type()==FL_MULTILINE_INPUT) {
+	for (c = (o-buf)%8; c<8 && o<e; c++) *o++ = ' ';
+      } else {
+	*o++ = '^';
+	*o++ = c ^ 0x40;
+      }
+    } else if (c == 0xA0) { // nbsp
+      *o++ = ' ';
+    } else {
+      *o++ = c;
+    }
+  }
+  *o = 0;
+  return p;
+}
+
+// After filling in such a buffer, find the width to e
+double Fl_Input_::expandpos(
+  const char* p,	// real string
+  const char* e,	// pointer into real string
+  const char* buf,	// conversion of real string by expand()
+  int* returnn		// return offset into buf here
+) const {
+  int n = 0;
+  if (input_type()==FL_SECRET_INPUT) n = e-p;
+  else while (p<e) {
+    int c = *p++ & 255;
+    if (c < ' ' || c == 127) {
+      if (c == '\t' && input_type()==FL_MULTILINE_INPUT) n += 8-(n%8);
+      else n += 2;
+    } else if (c >= 128 && c < 0xA0) {
+      n += 4;
+    } else {
+      n++;
+    }
+  }
+  if (returnn) *returnn = n;
+  return fl_width(buf, n);
+}
+
+////////////////////////////////////////////////////////////////
+
+// minimal update:
+// Characters from mu_p to end of widget are redrawn.
+// If erase_cursor_only, small part at mu_p is redrawn.
+// Right now minimal update just keeps unchanged characters from
+// being erased, so they don't blink.
+
+void Fl_Input_::minimal_update(int p) {
+  if (damage() & FL_DAMAGE_ALL) return; // don't waste time if it won't be done
+  if (damage() & FL_DAMAGE_EXPOSE) {
+    if (p < mu_p) mu_p = p;
+  } else {
+    mu_p = p;
+  }
+
+  damage(FL_DAMAGE_EXPOSE);
+  erase_cursor_only = 0;
+}
+
+void Fl_Input_::minimal_update(int p, int q) {
+  if (q < p) p = q;
+  minimal_update(p);
+}
+
+////////////////////////////////////////////////////////////////
+
+static double up_down_pos;
+static int was_up_down;
+
+void Fl_Input_::setfont() const {
+ fl_font(textfont(), textsize());
+}
+
+void Fl_Input_::drawtext(int X, int Y, int W, int H) {
+  int do_mu = !(damage()&FL_DAMAGE_ALL);
+
+  if (Fl::focus()!=this && !size()) {
+    if (do_mu) { // we have to erase it if cursor was there
+      draw_box(box(), X-Fl::box_dx(box()), Y-Fl::box_dy(box()),
+               W+Fl::box_dw(box()), H+Fl::box_dh(box()), color());
+    }
+    return;
+  }
+
+  int selstart, selend;
+  if (Fl::focus()!=this && /*Fl::selection_owner()!=this &&*/ Fl::pushed()!=this)
+    selstart = selend = 0;
+  else if (position() <= mark()) {
+    selstart = position(); selend = mark();
+  } else {
+    selend = position(); selstart = mark();
+  }
+
+  setfont();
+  const char *p, *e;
+  char buf[MAXBUF];
+
+  // count how many lines and put the last one into the buffer:
+  // And figure out where the cursor is:
+  int height = fl_height();
+  int lines;
+  int curx, cury;
+  for (p=value(), curx=cury=lines=0; ;) {
+    e = expand(p, buf);
+    if (position() >= p-value() && position() <= e-value()) {
+      curx = int(expandpos(p, value()+position(), buf, 0)+.5);
+      if (Fl::focus()==this && !was_up_down) up_down_pos = curx;
+      cury = lines*height;
+      int newscroll = xscroll_;
+      if (curx > newscroll+W-20) {
+	// figure out scrolling so there is space after the cursor:
+	newscroll = curx+20-W;
+	// figure out the furthest left we ever want to scroll:
+	int ex = int(expandpos(p, e, buf, 0))+2-W;
+	// use minimum of both amounts:
+	if (ex < newscroll) newscroll = ex;
+      } else if (curx < newscroll+20) {
+	newscroll = curx-20;
+      }
+      if (newscroll < 0) newscroll = 0;
+      if (newscroll != xscroll_) {
+	xscroll_ = newscroll;
+	mu_p = 0; erase_cursor_only = 0;
+      }
+    }
+    lines++;
+    if (e >= value_+size_) break;
+    p = e+1;
+  }
+
+  // adjust the scrolling:
+  if (input_type()==FL_MULTILINE_INPUT) {
+    int newy = yscroll_;
+    if (cury < newy) newy = cury;
+    if (cury > newy+H-height) newy = cury-H+height;
+    if (newy < -1) newy = -1;
+    if (newy != yscroll_) {yscroll_ = newy; mu_p = 0; erase_cursor_only = 0;}
+  } else {
+    yscroll_ = -(H-height)/2;
+  }
+
+  fl_clip(X, Y, W, H);
+  Fl_Color tc = active_r() ? textcolor() : fl_inactive(textcolor());
+
+  p = value();
+  // visit each line and draw it:
+  int desc = height-fl_descent();
+  float xpos = X - xscroll_ + 1;
+  int ypos = -yscroll_;
+  for (; ypos < H;) {
+
+    // re-expand line unless it is the last one calculated above:
+    if (lines>1) e = expand(p, buf);
+
+    if (ypos <= -height) goto CONTINUE; // clipped off top
+
+    if (do_mu) {	// for minimal update:
+      const char* pp = value()+mu_p; // pointer to where minimal update starts
+      if (e < pp) goto CONTINUE2; // this line is before the changes
+      if (readonly()) erase_cursor_only = 0; // this isn't the most efficient way
+      if (erase_cursor_only && p > pp) goto CONTINUE2; // this line is after
+      // calculate area to erase:
+      float r = X+W;
+      float xx;
+      if (p >= pp) {
+	xx = X;
+	if (erase_cursor_only) r = xpos+2;
+	else if (readonly()) xx -= 3;
+      } else {
+	xx = xpos+expandpos(p, pp, buf, 0);
+	if (erase_cursor_only) r = xx+2;
+	else if (readonly()) xx -= 3;
+      }
+      // clip to and erase it:
+      fl_push_clip((int)xx-1-height/8, Y+ypos, (int)(r-xx+2+height/4), height);
+      draw_box(box(), X-Fl::box_dx(box()), Y-Fl::box_dy(box()),
+               W+Fl::box_dw(box()), H+Fl::box_dh(box()), color());
+      // it now draws entire line over it
+      // this should not draw letters to left of erased area, but
+      // that is nyi.
+    }
+
+    // Draw selection area if required:
+    if (selstart < selend && selstart <= e-value() && selend > p-value()) {
+      const char* pp = value()+selstart;
+      float x1 = xpos;
+      int offset1 = 0;
+      if (pp > p) {
+	fl_color(tc);
+	x1 += expandpos(p, pp, buf, &offset1);
+	fl_draw(buf, offset1, xpos, (float)(Y+ypos+desc));
+      }
+      pp = value()+selend;
+      float x2 = X+W;
+      int offset2;
+      if (pp <= e) x2 = xpos+expandpos(p, pp, buf, &offset2);
+      else offset2 = strlen(buf);
+      fl_color(selection_color());
+      fl_rectf((int)(x1+0.5), Y+ypos, (int)(x2-x1+0.5), height);
+      fl_color(fl_contrast(textcolor(), selection_color()));
+      fl_draw(buf+offset1, offset2-offset1, x1, (float)(Y+ypos+desc));
+      if (pp < e) {
+	fl_color(tc);
+	fl_draw(buf+offset2, strlen(buf+offset2), x2, (float)(Y+ypos+desc));
+      }
+    } else {
+      // draw unselected text
+      fl_color(tc);
+      fl_draw(buf, strlen(buf), xpos, (float)(Y+ypos+desc));
+    }
+
+    if (do_mu) fl_pop_clip();
+
+  CONTINUE2:
+    // draw the cursor:
+    if (Fl::focus() == this && selstart == selend &&
+	position() >= p-value() && position() <= e-value()) {
+      fl_color(cursor_color());
+      if (readonly()) {
+        fl_line((int)(xpos+curx-2.5f), Y+ypos+height-1,
+	        (int)(xpos+curx+0.5f), Y+ypos+height-4,
+	        (int)(xpos+curx+3.5f), Y+ypos+height-1);
+      } else {
+        fl_rectf((int)(xpos+curx+0.5), Y+ypos, 2, height);
+      }
+    }
+
+  CONTINUE:
+    ypos += height;
+    if (e >= value_+size_) break;
+    if (*e == '\n' || *e == ' ') e++;
+    p = e;
+  }
+
+  // for minimal update, erase all lines below last one if necessary:
+  if (input_type()==FL_MULTILINE_INPUT && do_mu && ypos<H
+      && (!erase_cursor_only || p <= value()+mu_p)) {
+    if (ypos < 0) ypos = 0;
+    fl_push_clip(X, Y+ypos, W, H-ypos);
+    draw_box(box(), X-Fl::box_dx(box()), Y-Fl::box_dy(box()),
+             W+Fl::box_dw(box()), H+Fl::box_dh(box()), color());
+    fl_pop_clip();
+  }
+
+  fl_pop_clip();
+}
+
+static int isword(char c) {
+  return (c&128 || isalnum(c) || strchr("#%&-/@\\_~", c));
+}
+
+int Fl_Input_::word_end(int i) const {
+  if (input_type() == FL_SECRET_INPUT) return size();
+  //while (i < size() && !isword(index(i))) i++;
+  while (i < size() && isword(index(i))) i++;
+  return i;
+}
+
+int Fl_Input_::word_start(int i) const {
+  if (input_type() == FL_SECRET_INPUT) return 0;
+//   if (i >= size() || !isword(index(i)))
+//     while (i > 0 && !isword(index(i-1))) i--;
+  while (i > 0 && isword(index(i-1))) i--;
+  return i;
+}
+
+int Fl_Input_::line_end(int i) const {
+  if (input_type() != FL_MULTILINE_INPUT) return size();
+
+  if (wrap()) {
+    // go to the start of the paragraph:
+    int j = i;
+    while (j > 0 && index(j-1) != '\n') j--;
+    // now measure lines until we get past i, end of that line is real eol:
+    setfont();
+    for (const char* p=value()+j; ;) {
+      char buf[MAXBUF];
+      p = expand(p, buf);
+      if (p-value() >= i) return p-value();
+      p++;
+    }
+  } else {
+    while (i < size() && index(i) != '\n') i++;
+    return i;
+  }
+}
+
+int Fl_Input_::line_start(int i) const {
+  if (input_type() != FL_MULTILINE_INPUT) return 0;
+  int j = i;
+  while (j > 0 && index(j-1) != '\n') j--;
+  if (wrap()) {
+    // now measure lines until we get past i, start of that line is real eol:
+    setfont();
+    for (const char* p=value()+j; ;) {
+      char buf[MAXBUF];
+      const char* e = expand(p, buf);
+      if (e-value() >= i) return p-value();
+      p = e+1;
+    }
+  } else return j;
+}
+
+void Fl_Input_::handle_mouse(int X, int Y, int /*W*/, int /*H*/, int drag) {
+  was_up_down = 0;
+  if (!size()) return;
+  setfont();
+
+  const char *p, *e;
+  char buf[MAXBUF];
+
+  int theline = (input_type()==FL_MULTILINE_INPUT) ?
+    (Fl::event_y()-Y+yscroll_)/fl_height() : 0;
+
+  int newpos = 0;
+  for (p=value();; ) {
+    e = expand(p, buf);
+    theline--; if (theline < 0) break;
+    if (e >= value_+size_) break;
+    p = e+1;
+  }
+  const char *l, *r, *t; double f0 = Fl::event_x()-X+xscroll_;
+  for (l = p, r = e; l<r; ) {
+    double f;
+    t = l+(r-l+1)/2;
+    f = X-xscroll_+expandpos(p, t, buf, 0);
+    if (f <= Fl::event_x()) {l = t; f0 = Fl::event_x()-f;}
+    else r = t-1;
+  }
+  if (l < e) { // see if closer to character on right:
+    double f1 = X-xscroll_+expandpos(p, l+1, buf, 0)-Fl::event_x();
+    if (f1 < f0) l = l+1;
+  }
+  newpos = l-value();
+
+  int newmark = drag ? mark() : newpos;
+  if (Fl::event_clicks()) {
+    if (newpos >= newmark) {
+      if (newpos == newmark) {
+	if (newpos < size()) newpos++;
+	else newmark--;
+      }
+      if (Fl::event_clicks() > 1) {
+	newpos = line_end(newpos);
+	newmark = line_start(newmark);
+      } else {
+	newpos = word_end(newpos);
+	newmark = word_start(newmark);
+      }
+    } else {
+      if (Fl::event_clicks() > 1) {
+	newpos = line_start(newpos);
+	newmark = line_end(newmark);
+      } else {
+	newpos = word_start(newpos);
+	newmark = word_end(newmark);
+      }
+    }
+    // if the multiple click does not increase the selection, revert
+    // to single-click behavior:
+    if (!drag && (mark() > position() ?
+                  (newmark >= position() && newpos <= mark()) :
+                  (newmark >= mark() && newpos <= position()))) {
+      Fl::event_clicks(0);
+      newmark = newpos = l-value();
+    }
+  }
+  position(newpos, newmark);
+}
+
+int Fl_Input_::position(int p, int m) {
+  was_up_down = 0;
+  if (p<0) p = 0;
+  if (p>size()) p = size();
+  if (m<0) m = 0;
+  if (m>size()) m = size();
+  if (p == position_ && m == mark_) return 0;
+  //if (Fl::selection_owner() == this) Fl::selection_owner(0);
+  if (p != m) {
+    if (p != position_) minimal_update(position_, p);
+    if (m != mark_) minimal_update(mark_, m);
+  } else {
+    // new position is a cursor
+    if (position_ == mark_) {
+      // old position was just a cursor
+      if (Fl::focus() == this && !(damage()&FL_DAMAGE_EXPOSE)) {
+	minimal_update(position_); erase_cursor_only = 1;
+      }
+    } else { // old position was a selection
+      minimal_update(position_, mark_);
+    }
+  }
+  position_ = p;
+  mark_ = m;
+  return 1;
+}
+
+int Fl_Input_::up_down_position(int i, int keepmark) {
+  // unlike before, i must be at the start of the line already!
+
+  setfont();
+  char buf[MAXBUF];
+  const char* p = value()+i;
+  const char* e = expand(p, buf);
+  const char *l, *r, *t;
+  for (l = p, r = e; l<r; ) {
+    t = l+(r-l+1)/2;
+    int f = (int)expandpos(p, t, buf, 0);
+    if (f <= up_down_pos) l = t; else r = t-1;
+  }
+  int j = l-value();
+  j = position(j, keepmark ? mark_ : j);
+  was_up_down = 1;
+  return j;
+}
+
+int Fl_Input_::copy(int clipboard) {
+  int b = position();
+  int e = mark();
+  if (b != e) {
+    if (b > e) {b = mark(); e = position();}
+    if (input_type() == FL_SECRET_INPUT) e = b;
+    Fl::copy(value()+b, e-b, clipboard);
+    return 1;
+  }
+  return 0;
+}
+
+#define MAXFLOATSIZE 40
+
+static char* undobuffer;
+static int undobufferlength;
+static Fl_Input_* undowidget;
+static int undoat;	// points after insertion
+static int undocut;	// number of characters deleted there
+static int undoinsert;	// number of characters inserted
+static int yankcut;	// length of valid contents of buffer, even if undocut=0
+
+static void undobuffersize(int n) {
+  if (n > undobufferlength) {
+    if (undobuffer) {
+      do {undobufferlength *= 2;} while (undobufferlength < n);
+      undobuffer = (char*)realloc(undobuffer, undobufferlength);
+    } else {
+      undobufferlength = n+9;
+      undobuffer = (char*)malloc(undobufferlength);
+    }
+  }
+}
+
+// all changes go through here, delete characters b-e and insert text:
+int Fl_Input_::replace(int b, int e, const char* text, int ilen) {
+
+  was_up_down = 0;
+
+  if (b<0) b = 0;
+  if (e<0) e = 0;
+  if (b>size_) b = size_;
+  if (e>size_) e = size_;
+  if (e<b) {int t=b; b=e; e=t;}
+  if (text && !ilen) ilen = strlen(text);
+  if (e<=b && !ilen) return 0; // don't clobber undo for a null operation
+  if (size_+ilen-(e-b) > maximum_size_) {
+    ilen = maximum_size_-size_+(e-b);
+    if (ilen < 0) ilen = 0;
+  }
+
+  put_in_buffer(size_+ilen);
+
+  if (e>b) {
+    if (undowidget == this && b == undoat) {
+      undobuffersize(undocut+(e-b));
+      memcpy(undobuffer+undocut, value_+b, e-b);
+      undocut += e-b;
+    } else if (undowidget == this && e == undoat && !undoinsert) {
+      undobuffersize(undocut+(e-b));
+      memmove(undobuffer+(e-b), undobuffer, undocut);
+      memcpy(undobuffer, value_+b, e-b);
+      undocut += e-b;
+    } else if (undowidget == this && e == undoat && (e-b)<undoinsert) {
+      undoinsert -= e-b;
+    } else {
+      undobuffersize(e-b);
+      memcpy(undobuffer, value_+b, e-b);
+      undocut = e-b;
+      undoinsert = 0;
+    }
+    memmove(buffer+b, buffer+e, size_-e+1);
+    size_ -= e-b;
+    undowidget = this;
+    undoat = b;
+    if (input_type() == FL_SECRET_INPUT) yankcut = 0; else yankcut = undocut;
+  }
+
+  if (ilen) {
+    if (undowidget == this && b == undoat)
+      undoinsert += ilen;
+    else {
+      undocut = 0;
+      undoinsert = ilen;
+    }
+    memmove(buffer+b+ilen, buffer+b, size_-b+1);
+    memcpy(buffer+b, text, ilen);
+    size_ += ilen;
+  }
+  undowidget = this;
+  undoat = b+ilen;
+
+  // Insertions into the word at the end of the line will cause it to
+  // wrap to the next line, so we must indicate that the changes may start
+  // right after the whitespace before the current word.  This will
+  // result in sub-optimal update when such wrapping does not happen
+  // but it is too hard to figure out for now...
+  if (wrap()) {
+    // if there is a space in the pasted text, the whole line may have rewrapped
+    int i;
+    for (i=0; i<ilen; i++) 
+      if (text[i]==' ') break;
+    if (i==ilen)
+      while (b > 0 && !isspace(index(b) & 255) && index(b)!='\n') b--;
+    else
+      while (b > 0 && index(b)!='\n') b--;
+  }
+
+  // make sure we redraw the old selection or cursor:
+  if (mark_ < b) b = mark_;
+  if (position_ < b) b = position_;
+
+  minimal_update(b);
+
+  mark_ = position_ = undoat;
+
+  set_changed();
+  if (when()&FL_WHEN_CHANGED) do_callback();
+  return 1;
+}
+
+int Fl_Input_::undo() {
+  was_up_down = 0;
+  if (undowidget != this || !undocut && !undoinsert) return 0;
+
+  int ilen = undocut;
+  int xlen = undoinsert;
+  int b = undoat-xlen;
+  int b1 = b;
+
+  put_in_buffer(size_+ilen);
+
+  if (ilen) {
+    memmove(buffer+b+ilen, buffer+b, size_-b+1);
+    memcpy(buffer+b, undobuffer, ilen);
+    size_ += ilen;
+    b += ilen;
+  }
+
+  if (xlen) {
+    undobuffersize(xlen);
+    memcpy(undobuffer, buffer+b, xlen);
+    memmove(buffer+b, buffer+b+xlen, size_-xlen-b+1);
+    size_ -= xlen;
+  }
+
+  undocut = xlen;
+  if (xlen) yankcut = xlen;
+  undoinsert = ilen;
+  undoat = b;
+  mark_ = b /* -ilen */;
+  position_ = b;
+
+  if (wrap())
+    while (b1 > 0 && index(b1)!='\n') b1--;
+  minimal_update(b1);
+  set_changed();
+  if (when()&FL_WHEN_CHANGED) do_callback();
+  return 1;
+}
+
+int Fl_Input_::copy_cuts() {
+  // put the yank buffer into the X clipboard
+  if (!yankcut || input_type()==FL_SECRET_INPUT) return 0;
+  Fl::copy(undobuffer, yankcut, 1);
+  return 1;
+}
+
+void Fl_Input_::maybe_do_callback() {
+  if (changed() || (when()&FL_WHEN_NOT_CHANGED)) {
+    do_callback();
+  }
+}
+
+int Fl_Input_::handletext(int event, int X, int Y, int W, int H) {
+  switch (event) {
+
+  case FL_ENTER:
+    if (active_r() && window()) window()->cursor(FL_CURSOR_INSERT);
+    return 1;
+
+  case FL_LEAVE:
+    if (active_r() && window()) window()->cursor(FL_CURSOR_DEFAULT);
+    return 1;
+
+  case FL_FOCUS:
+    if (mark_ == position_) {
+      minimal_update(size()+1);
+    } else //if (Fl::selection_owner() != this)
+      minimal_update(mark_, position_);
+    return 1;
+
+  case FL_UNFOCUS:
+    if (mark_ == position_) {
+      if (!(damage()&FL_DAMAGE_EXPOSE)) {minimal_update(position_); erase_cursor_only = 1;}
+    } else //if (Fl::selection_owner() != this)
+      minimal_update(mark_, position_);
+  case FL_HIDE:
+    if (when() & FL_WHEN_RELEASE) maybe_do_callback();
+    return 1;
+
+  case FL_PUSH:
+    handle_mouse(X, Y, W, H, Fl::event_state(FL_SHIFT));
+
+    if (Fl::focus() != this) {
+      Fl::focus(this);
+      handle(FL_FOCUS);
+    }
+    return 1;
+
+  case FL_DRAG:
+    handle_mouse(X, Y, W, H, 1);
+    return 1;
+
+  case FL_RELEASE:
+    copy(0);
+    return 1;
+
+  case FL_PASTE: {
+    // Don't allow pastes into readonly widgets...
+    if (readonly()) {
+      fl_beep(FL_BEEP_ERROR);
+      return 1;
+    }
+
+    // See if we have anything to paste...
+    if (!Fl::event_text() || !Fl::event_length()) return 1;
+
+    // strip trailing control characters and spaces before pasting:
+    const char* t = Fl::event_text();
+    const char* e = t+Fl::event_length();
+    if (input_type() != FL_MULTILINE_INPUT) while (e > t && isspace(*(e-1) & 255)) e--;
+    if (!t || e <= t) return 1; // Int/float stuff will crash without this test
+    if (input_type() == FL_INT_INPUT) {
+      while (isspace(*t & 255) && t < e) t ++;
+      const char *p = t;
+      if (*p == '+' || *p == '-') p ++;
+      if (strncmp(p, "0x", 2) == 0) {
+        p += 2;
+        while (isxdigit(*p & 255) && p < e) p ++;
+      } else {
+        while (isdigit(*p & 255) && p < e) p ++;
+      }
+      if (p < e) {
+        fl_beep(FL_BEEP_ERROR);
+        return 1;
+      } else return replace(0, size(), t, e - t);
+    } else if (input_type() == FL_FLOAT_INPUT) {
+      while (isspace(*t & 255) && t < e) t ++;
+      const char *p = t;
+      if (*p == '+' || *p == '-') p ++;
+      while (isdigit(*p & 255) && p < e) p ++;
+      if (*p == '.') {
+        p ++;
+        while (isdigit(*p & 255) && p < e) p ++;
+	if (*p == 'e' || *p == 'E') {
+	  p ++;
+	  if (*p == '+' || *p == '-') p ++;
+	  while (isdigit(*p & 255) && p < e) p ++;
+	}
+      }
+      if (p < e) {
+        fl_beep(FL_BEEP_ERROR);
+        return 1;
+      } else return replace(0, size(), t, e - t);
+    }
+    return replace(position(), mark(), t, e-t);}
+
+  default:
+    return 0;
+  }
+}
+
+/*------------------------------*/
+
+Fl_Input_::Fl_Input_(int X, int Y, int W, int H, const char* l)
+: Fl_Widget(X, Y, W, H, l) {
+  box(FL_DOWN_BOX);
+  color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
+  align(FL_ALIGN_LEFT);
+  textsize_ = (uchar)FL_NORMAL_SIZE;
+  textfont_ = FL_HELVETICA;
+  textcolor_ = FL_FOREGROUND_COLOR;
+  cursor_color_ = FL_FOREGROUND_COLOR; // was FL_BLUE
+  mark_ = position_ = size_ = 0;
+  bufsize = 0;
+  buffer  = 0;
+  value_ = "";
+  xscroll_ = yscroll_ = 0;
+  maximum_size_ = 32767;
+}
+
+void Fl_Input_::put_in_buffer(int len) {
+  if (value_ == buffer && bufsize > len) {
+    buffer[size_] = 0;
+    return;
+  }
+  if (!bufsize) {
+    if (len > size_) len += 9; // let a few characters insert before realloc
+    bufsize = len+1; 
+    buffer = (char*)malloc(bufsize);
+  } else if (bufsize <= len) {
+    // we may need to move old value in case it points into buffer:
+    int moveit = (value_ >= buffer && value_ < buffer+bufsize);
+    // enlarge current buffer
+    if (len > size_) {
+      do {bufsize *= 2;} while (bufsize <= len);
+    } else {
+      bufsize = len+1;
+    }
+    // Note: the following code is equivalent to:
+    //
+    //   if (moveit) value_ = value_ - buffer;
+    //   char* nbuffer = (char*)realloc(buffer, bufsize);
+    //   if (moveit) value_ = value_ + nbuffer;
+    //   buffer = nbuffer;
+    //
+    // We just optimized the pointer arithmetic for value_...
+    //
+    char* nbuffer = (char*)realloc(buffer, bufsize);
+    if (moveit) value_ += (nbuffer-buffer);
+    buffer = nbuffer;
+  }
+  memmove(buffer, value_, size_); buffer[size_] = 0;
+  value_ = buffer;
+}
+
+int Fl_Input_::static_value(const char* str, int len) {
+  clear_changed();
+  if (undowidget == this) undowidget = 0;
+  if (str == value_ && len == size_) return 0;
+  if (len) { // non-empty new value:
+    if (xscroll_ || yscroll_) {
+      xscroll_ = yscroll_ = 0;
+      minimal_update(0);
+    } else {
+      int i = 0;
+      // find first different character:
+      if (value_) {
+	for (; i<size_ && i<len && str[i]==value_[i]; i++);
+	if (i==size_ && i==len) return 0;
+      }
+      minimal_update(i);
+    }
+    value_ = str;
+    size_ = len;
+  } else { // empty new value:
+    if (!size_) return 0; // both old and new are empty.
+    size_ = 0;
+    value_ = "";
+    xscroll_ = yscroll_ = 0;
+    minimal_update(0);
+  }
+  position(0, readonly() ? 0 : size());
+  return 1;
+}
+
+int Fl_Input_::static_value(const char* str) {
+  return static_value(str, str ? strlen(str) : 0);
+}
+
+int Fl_Input_::value(const char* str, int len) {
+  int r = static_value(str, len);
+  if (len) put_in_buffer(len);
+  return r;
+}
+
+int Fl_Input_::value(const char* str) {
+  return value(str, str ? strlen(str) : 0);
+}
+
+void Fl_Input_::resize(int X, int Y, int W, int H) {
+  if (W != w()) xscroll_ = 0;
+  if (H != h()) yscroll_ = 0;
+  Fl_Widget::resize(X, Y, W, H);
+}
+
+Fl_Input_::~Fl_Input_() {
+  if (undowidget == this) undowidget = 0;
+  if (bufsize) free((void*)buffer);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_JPEG_Image.cxx b/Utilities/FLTK/src/Fl_JPEG_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8b0fb3c54aade8b22bab96c150320c67ae0eae1b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_JPEG_Image.cxx
@@ -0,0 +1,198 @@
+//
+// "$Id$"
+//
+// Fl_JPEG_Image routines.
+//
+// Copyright 1997-2005 by Easy Software Products.
+// Image support donated by Matthias Melcher, Copyright 2000.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_JPEG_Image::Fl_JPEG_Image() - Load a JPEG image file.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl_JPEG_Image.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+
+// Some releases of the Cygwin JPEG libraries don't have a correctly
+// updated header file for the INT32 data type; the following define
+// from Shane Hill seems to be a usable workaround...
+
+#if defined(WIN32) && defined(__CYGWIN__)
+#  define XMD_H
+#endif // WIN32 && __CYGWIN__
+
+
+extern "C"
+{
+#ifdef HAVE_LIBJPEG
+#  include <jpeglib.h>
+#endif // HAVE_LIBJPEG
+}
+
+
+//
+// Custom JPEG error handling structure...
+//
+
+#ifdef HAVE_LIBJPEG
+struct fl_jpeg_error_mgr {
+  jpeg_error_mgr	pub_;		// Destination manager...
+  jmp_buf		errhand_;	// Error handler
+};
+#endif // HAVE_LIBJPEG
+
+
+//
+// Error handler for JPEG files...
+//
+
+#ifdef HAVE_LIBJPEG
+extern "C" {
+  static void
+  fl_jpeg_error_handler(j_common_ptr dinfo) {	// I - Decompressor info
+    longjmp(((fl_jpeg_error_mgr *)(dinfo->err))->errhand_, 1);
+    return;
+  }
+
+  static void
+  fl_jpeg_output_handler(j_common_ptr dinfo) {	// I - Decompressor info
+    return;
+  }
+}
+#endif // HAVE_LIBJPEG
+
+
+//
+// 'Fl_JPEG_Image::Fl_JPEG_Image()' - Load a JPEG image file.
+//
+
+Fl_JPEG_Image::Fl_JPEG_Image(const char *jpeg)	// I - File to load
+  : Fl_RGB_Image(0,0,0) {
+#ifdef HAVE_LIBJPEG
+  FILE				*fp;	// File pointer
+  jpeg_decompress_struct	dinfo;	// Decompressor info
+  fl_jpeg_error_mgr		jerr;	// Error handler info
+  JSAMPROW			row;	// Sample row pointer
+
+  // the following variables are pointers allocating some private space that
+  // is not reset by 'setjmp()'
+  char* max_finish_decompress_err;      // count errors and give up afer a while
+  char* max_destroy_decompress_err;     // to avoid recusion and deadlock
+
+  // Clear data...
+  alloc_array = 0;
+  array = (uchar *)0;
+
+  // Open the image file...
+  if ((fp = fopen(jpeg, "rb")) == NULL) return;
+
+  // Setup the decompressor info and read the header...
+  dinfo.err                = jpeg_std_error((jpeg_error_mgr *)&jerr);
+  jerr.pub_.error_exit     = fl_jpeg_error_handler;
+  jerr.pub_.output_message = fl_jpeg_output_handler;
+
+  // Setup error loop variables
+  max_finish_decompress_err = (char*)malloc(1);   // allocate space on the frame for error counters
+  max_destroy_decompress_err = (char*)malloc(1);  // otherwise, the variables are reset on the longjmp
+  *max_finish_decompress_err=10;
+  *max_destroy_decompress_err=10;
+
+  if (setjmp(jerr.errhand_))
+  {
+    // JPEG error handling...
+    // if any of the cleanup routines hits another error, we would end up 
+    // in a loop. So instead, we decrement max_err for some upper cleanup limit.
+    if ( ((*max_finish_decompress_err)-- > 0) && array)
+      jpeg_finish_decompress(&dinfo);
+    if ( (*max_destroy_decompress_err)-- > 0)
+      jpeg_destroy_decompress(&dinfo);
+
+    fclose(fp);
+
+    w(0);
+    h(0);
+    d(0);
+
+    if (array) {
+      delete[] (uchar *)array;
+      array = 0;
+      alloc_array = 0;
+    }
+
+    free(max_destroy_decompress_err);
+    free(max_finish_decompress_err);
+    
+    return;
+  }
+
+  jpeg_create_decompress(&dinfo);
+  jpeg_stdio_src(&dinfo, fp);
+  jpeg_read_header(&dinfo, 1);
+
+  dinfo.quantize_colors      = (boolean)FALSE;
+  dinfo.out_color_space      = JCS_RGB;
+  dinfo.out_color_components = 3;
+  dinfo.output_components    = 3;
+
+  jpeg_calc_output_dimensions(&dinfo);
+
+  w(dinfo.output_width); 
+  h(dinfo.output_height);
+  d(dinfo.output_components);
+
+  array = new uchar[w() * h() * d()];
+  alloc_array = 1;
+
+  jpeg_start_decompress(&dinfo);
+
+  while (dinfo.output_scanline < dinfo.output_height) {
+    row = (JSAMPROW)(array +
+                     dinfo.output_scanline * dinfo.output_width *
+                     dinfo.output_components);
+    jpeg_read_scanlines(&dinfo, &row, (JDIMENSION)1);
+  }
+
+  jpeg_finish_decompress(&dinfo);
+  jpeg_destroy_decompress(&dinfo);
+
+  free(max_destroy_decompress_err);
+  free(max_finish_decompress_err);
+
+  fclose(fp);
+#endif // HAVE_LIBJPEG
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Light_Button.cxx b/Utilities/FLTK/src/Fl_Light_Button.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..531064913e05870b40b52e4d0936b40d6bb4a4c7
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Light_Button.cxx
@@ -0,0 +1,152 @@
+//
+// "$Id$"
+//
+// Lighted button widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Subclass of Fl_Button where the "box" indicates whether it is
+// pushed or not, and the "down box" is drawn small and square on
+// the left to indicate the current state.
+
+// The default down_box of zero draws a rectangle designed to look
+// just like Flame's buttons.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/fl_draw.H>
+
+void Fl_Light_Button::draw() {
+  if (box()) draw_box(this==Fl::pushed() ? fl_down(box()) : box(), color());
+  Fl_Color col = value() ? (active_r() ? selection_color() :
+                            fl_inactive(selection_color())) : color();
+  int W;
+  int dx, dy;
+
+  W  = labelsize();
+  dx = Fl::box_dx(box()) + 2;
+  dy = (h() - W) / 2;
+  // if (dy < 0) dy = 0;         // neg. offset o.k. for vertical centering
+
+  if (down_box()) {
+    // draw other down_box() styles:
+    switch (down_box()) {
+      case FL_DOWN_BOX :
+      case FL_UP_BOX :
+      case _FL_PLASTIC_DOWN_BOX :
+      case _FL_PLASTIC_UP_BOX :
+        // Check box...
+        draw_box(down_box(), x()+dx, y()+dy, W, W, FL_BACKGROUND2_COLOR);
+	if (value()) {
+	  fl_color(col);
+	  int tx = x() + dx + 3;
+	  int tw = W - 6;
+	  int d1 = tw/3;
+	  int d2 = tw-d1;
+	  int ty = y() + dy + (W+d2)/2-d1-2;
+	  for (int n = 0; n < 3; n++, ty++) {
+	    fl_line(tx, ty, tx+d1, ty+d1);
+	    fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1);
+	  }
+	}
+        break;
+      case _FL_ROUND_DOWN_BOX :
+      case _FL_ROUND_UP_BOX :
+        // Radio button...
+        draw_box(down_box(), x()+dx, y()+dy, W, W, FL_BACKGROUND2_COLOR);
+	if (value()) {
+	  fl_color(col);
+	  int tW = (W - Fl::box_dw(down_box())) / 2 + 1;
+	  if ((W - tW) & 1) tW++; // Make sure difference is even to center
+	  int tdx = dx + (W - tW) / 2;
+	  int tdy = dy + (W - tW) / 2;
+
+	  switch (tW) {
+	    // Larger circles draw fine...
+	    default :
+              fl_pie(x() + tdx, y() + tdy, tW, tW, 0.0, 360.0);
+	      break;
+
+            // Small circles don't draw well on many systems...
+	    case 6 :
+	      fl_rectf(x() + tdx + 2, y() + tdy, tW - 4, tW);
+	      fl_rectf(x() + tdx + 1, y() + tdy + 1, tW - 2, tW - 2);
+	      fl_rectf(x() + tdx, y() + tdy + 2, tW, tW - 4);
+	      break;
+
+	    case 5 :
+	    case 4 :
+	    case 3 :
+	      fl_rectf(x() + tdx + 1, y() + tdy, tW - 2, tW);
+	      fl_rectf(x() + tdx, y() + tdy + 1, tW, tW - 2);
+	      break;
+
+	    case 2 :
+	    case 1 :
+	      fl_rectf(x() + tdx, y() + tdy, tW, tW);
+	      break;
+	  }
+	}
+        break;
+      default :
+        draw_box(down_box(), x()+dx, y()+dy, W, W, col);
+        break;
+    }
+  } else {
+    // if down_box() is zero, draw light button style:
+    int hh = h()-2*dy - 2;
+    int ww = W/2+1;
+    int xx = dx;
+    if (w()<ww+2*xx) xx = (w()-ww)/2;
+    if (Fl::scheme()) {
+      col = active_r() ? selection_color() : fl_inactive(selection_color());
+      fl_color(value() ? col : fl_color_average(col, FL_BLACK, 0.5f));
+      fl_pie(x()+xx, y()+dy+1, ww, hh, 0, 360);
+    } else {
+      draw_box(FL_THIN_DOWN_BOX, x()+xx, y()+dy+1, ww, hh, col);
+    }
+    dx = (ww + 2 * dx - W) / 2;
+  }
+  draw_label(x()+W+2*dx, y(), w()-W-2*dx, h());
+  if (Fl::focus() == this) draw_focus();
+}
+
+int Fl_Light_Button::handle(int event) {
+  switch (event) {
+  case FL_RELEASE:
+    if (box()) redraw();
+  default:
+    return Fl_Button::handle(event);
+  }
+}
+
+Fl_Light_Button::Fl_Light_Button(int X, int Y, int W, int H, const char* l)
+: Fl_Button(X, Y, W, H, l) {
+  type(FL_TOGGLE_BUTTON);
+  selection_color(FL_YELLOW);
+  align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Menu.cxx b/Utilities/FLTK/src/Fl_Menu.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..34f6b4b9984720159903c8cd4f282fef598c1584
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Menu.cxx
@@ -0,0 +1,853 @@
+//
+// "$Id$"
+//
+// Menu code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Warning: this menu code is quite a mess!
+
+// This file contains code for implementing Fl_Menu_Item, and for
+// methods for bringing up popup menu hierarchies without using the
+// Fl_Menu_ widget.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_Window.H>
+#include <FL/Fl_Menu_.H>
+#include <FL/fl_draw.H>
+#include <stdio.h>
+
+#ifdef __APPLE__
+#  include <Carbon/Carbon.h>
+#endif
+
+int Fl_Menu_Item::size() const {
+  const Fl_Menu_Item* m = this;
+  int nest = 0;
+  for (;;) {
+    if (!m->text) {
+      if (!nest) return (m-this+1);
+      nest--;
+    } else if (m->flags & FL_SUBMENU) {
+      nest++;
+    }
+    m++;
+  }
+}
+
+const Fl_Menu_Item* Fl_Menu_Item::next(int n) const {
+  if (n < 0) return 0; // this is so selected==-1 returns NULL
+  const Fl_Menu_Item* m = this;
+  int nest = 0;
+  if (!m->visible()) n++;
+  while (n>0) {
+    if (!m->text) {
+      if (!nest) return m;
+      nest--;
+    } else if (m->flags&FL_SUBMENU) {
+      nest++;
+    }
+    m++;
+    if (!nest && m->visible()) n--;
+  }
+  return m;
+}
+
+// appearance of current menus are pulled from this parent widget:
+static const Fl_Menu_* button;
+
+////////////////////////////////////////////////////////////////
+
+// tiny window for title of menu:
+class menutitle : public Fl_Menu_Window {
+  void draw();
+public:
+  const Fl_Menu_Item* menu;
+  menutitle(int X, int Y, int W, int H, const Fl_Menu_Item*);
+};
+
+// each vertical menu has one of these:
+class menuwindow : public Fl_Menu_Window {
+  void draw();
+  void drawentry(const Fl_Menu_Item*, int i, int erase);
+public:
+  menutitle* title;
+  int handle(int);
+  int itemheight;	// zero == menubar
+  int numitems;
+  int selected;
+  int drawn_selected;	// last redraw has this selected
+  const Fl_Menu_Item* menu;
+  menuwindow(const Fl_Menu_Item* m, int X, int Y, int W, int H,
+	     const Fl_Menu_Item* picked, const Fl_Menu_Item* title,
+	     int menubar = 0, int menubar_title = 0, int right_edge = 0);
+  ~menuwindow();
+  void set_selected(int);
+  int find_selected(int mx, int my);
+  int titlex(int);
+  void autoscroll(int);
+  void position(int x, int y);
+};
+
+#define LEADING 4 // extra vertical leading
+
+extern char fl_draw_shortcut;
+
+// width of label, including effect of & characters:
+int Fl_Menu_Item::measure(int* hp, const Fl_Menu_* m) const {
+  Fl_Label l;
+  l.value   = text;
+  l.image   = 0;
+  l.deimage = 0;
+  l.type    = labeltype_;
+  l.font    = labelsize_ || labelfont_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA);
+  l.size    = labelsize_ ? labelsize_ : m ? m->textsize() : (uchar)FL_NORMAL_SIZE;
+  l.color   = FL_FOREGROUND_COLOR; // this makes no difference?
+  fl_draw_shortcut = 1;
+  int w = 0; int h = 0;
+  l.measure(w, hp ? *hp : h);
+  fl_draw_shortcut = 0;
+  if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) w += 14;
+  return w;
+}
+
+void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m,
+			int selected) const {
+  Fl_Label l;
+  l.value   = text;
+  l.image   = 0;
+  l.deimage = 0;
+  l.type    = labeltype_;
+  l.font    = labelsize_ || labelfont_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA);
+  l.size    = labelsize_ ? labelsize_ : m ? m->textsize() : (uchar)FL_NORMAL_SIZE;
+  l.color   = labelcolor_ ? labelcolor_ : m ? m->textcolor() : int(FL_FOREGROUND_COLOR);
+  if (!active()) l.color = fl_inactive((Fl_Color)l.color);
+  Fl_Color color = m ? m->color() : FL_GRAY;
+  if (selected) {
+    Fl_Color r = m ? m->selection_color() : FL_SELECTION_COLOR;
+    Fl_Boxtype b = m && m->down_box() ? m->down_box() : FL_FLAT_BOX;
+    if (fl_contrast(r,color)!=r) { // back compatability boxtypes
+      if (selected == 2) { // menu title
+	r = color;
+	b = m ? m->box() : FL_UP_BOX;
+      } else {
+	r = (Fl_Color)(FL_COLOR_CUBE-1); // white
+	l.color = fl_contrast((Fl_Color)labelcolor_, r);
+      }
+    } else {
+      l.color = fl_contrast((Fl_Color)labelcolor_, r);
+    }
+    if (selected == 2) { // menu title
+      fl_draw_box(b, x, y, w, h, r);
+      x += 3;
+      w -= 8;
+    } else {
+      fl_draw_box(b, x+1, y-(LEADING-2)/2, w-2, h+(LEADING-2), r);
+    }
+  }
+
+  if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) {
+    int d = (h - FL_NORMAL_SIZE + 1) / 2;
+    int W = h - 2 * d;
+
+    if (flags & FL_MENU_RADIO) {
+      fl_draw_box(FL_ROUND_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR);
+      if (value()) {
+	fl_color(labelcolor_);
+	int tW = (W - Fl::box_dw(FL_ROUND_DOWN_BOX)) / 2 + 1;
+	if ((W - tW) & 1) tW++;	// Make sure difference is even to center
+	int td = Fl::box_dx(FL_ROUND_DOWN_BOX) + 1;
+	switch (tW) {
+	  // Larger circles draw fine...
+	  default :
+            fl_pie(x + td + 2, y + d + td, tW, tW, 0.0, 360.0);
+	    break;
+
+          // Small circles don't draw well on many systems...
+	  case 6 :
+	    fl_rectf(x + td + 4, y + d + td, tW - 4, tW);
+	    fl_rectf(x + td + 3, y + d + td + 1, tW - 2, tW - 2);
+	    fl_rectf(x + td + 2, y + d + td + 2, tW, tW - 4);
+	    break;
+
+	  case 5 :
+	  case 4 :
+	  case 3 :
+	    fl_rectf(x + td + 3, y + d + td, tW - 2, tW);
+	    fl_rectf(x + td + 2, y + d + td + 1, tW, tW - 2);
+	    break;
+
+	  case 2 :
+	  case 1 :
+	    fl_rectf(x + td + 2, y + d + td, tW, tW);
+	    break;
+	}
+      }
+    } else {
+      fl_draw_box(FL_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR);
+      if (value()) {
+	fl_color(labelcolor_);
+	int tx = x + 5;
+	int tw = W - 6;
+	int d1 = tw/3;
+	int d2 = tw-d1;
+	int ty = y + d + (W+d2)/2-d1-2;
+	for (int n = 0; n < 3; n++, ty++) {
+	  fl_line(tx, ty, tx+d1, ty+d1);
+	  fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1);
+	}
+      }
+    }
+    x += W + 3;
+    w -= W + 3;
+  }
+
+  if (!fl_draw_shortcut) fl_draw_shortcut = 1;
+  l.draw(x+3, y, w>6 ? w-6 : 0, h, FL_ALIGN_LEFT);
+  fl_draw_shortcut = 0;
+}
+
+menutitle::menutitle(int X, int Y, int W, int H, const Fl_Menu_Item* L) :
+  Fl_Menu_Window(X, Y, W, H, 0) {
+  end();
+  set_modal();
+  clear_border();
+  menu = L;
+  if (L->labelcolor_ || Fl::scheme() || L->labeltype_ > FL_NO_LABEL) clear_overlay();
+}
+
+menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
+		       const Fl_Menu_Item* picked, const Fl_Menu_Item* t, 
+		       int menubar, int menubar_title, int right_edge)
+  : Fl_Menu_Window(X, Y, Wp, Hp, 0)
+{
+  int scr_x, scr_y, scr_w, scr_h;
+  int tx = X, ty = Y;
+
+  Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+  if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w;
+
+  end();
+  set_modal();
+  clear_border();
+  menu = m;
+  if (m) m = m->first(); // find the first item that needs to be rendered
+  drawn_selected = -1;
+  if (button) {
+    box(button->box());
+    if (box() == FL_NO_BOX || box() == FL_FLAT_BOX) box(FL_UP_BOX);
+  } else {
+    box(FL_UP_BOX);
+  }
+  color(button && !Fl::scheme() ? button->color() : FL_GRAY);
+  selected = -1;
+  {int j = 0;
+  if (m) for (const Fl_Menu_Item* m1=m; ; m1 = m1->next(), j++) {
+    if (picked) {
+      if (m1 == picked) {selected = j; picked = 0;}
+      else if (m1 > picked) {selected = j-1; picked = 0; Wp = Hp = 0;}
+    }
+    if (!m1->text) break;
+  }
+  numitems = j;}
+
+  if (menubar) {
+    itemheight = 0;
+    title = 0;
+    return;
+  }
+
+  itemheight = 1;
+
+  int hotKeysw = 0;
+  int Wtitle = 0;
+  int Htitle = 0;
+  if (t) Wtitle = t->measure(&Htitle, button) + 12;
+  int W = 0;
+  if (m) for (; m->text; m = m->next()) {
+    int hh; int w1 = m->measure(&hh, button);
+    if (hh+LEADING>itemheight) itemheight = hh+LEADING;
+    if (m->flags&(FL_SUBMENU|FL_SUBMENU_POINTER)) w1 += 14;
+    if (w1 > W) W = w1;
+    if (m->shortcut_) {
+      w1 = int(fl_width(fl_shortcut_label(m->shortcut_))) + 8;
+      if (w1 > hotKeysw) hotKeysw = w1;
+    }
+    if (m->labelcolor_ || Fl::scheme() || m->labeltype_ > FL_NO_LABEL) clear_overlay();
+  }
+  if (selected >= 0 && !Wp) X -= W/2;
+  int BW = Fl::box_dx(box());
+  W += hotKeysw+2*BW+7;
+  if (Wp > W) W = Wp;
+  if (Wtitle > W) W = Wtitle;
+
+  if (X < scr_x) X = scr_x; if (X > scr_x+scr_w-W) X= scr_x+scr_w-W;
+  x(X); w(W);
+  h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3);
+  if (selected >= 0)
+    Y = Y+(Hp-itemheight)/2-selected*itemheight-BW;
+  else {
+    Y = Y+Hp;
+    // if the menu hits the bottom of the screen, we try to draw
+    // it above the menubar instead. We will not adjust any menu
+    // that has a selected item.
+    if (Y+h()>scr_y+scr_h && Y-h()>=scr_y) {
+      if (Hp>1) 
+        // if we know the height of the Fl_Menu_, use it
+        Y = Y-Hp-h();
+      else if (t)
+        // assume that the menubar item height relates to the first
+        // menuitem as well
+        Y = Y-itemheight-h()-Fl::box_dh(box());
+      else
+        // draw the menu to the right
+        Y = Y-h()+itemheight+Fl::box_dy(box());
+    }
+  }
+  if (m) y(Y); else {y(Y-2); w(1); h(1);}
+
+  if (t) {
+    int dy = menubar_title ? Fl::box_dy(button->box())+1 : 2;
+    int ht = menubar_title ? button->h()-dy*2 : Htitle+2*BW+3;
+    title = new menutitle(tx, ty-ht-dy, Wtitle, ht, t);
+  } else
+    title = 0;
+}
+
+menuwindow::~menuwindow() {
+  hide();
+  delete title;
+}
+
+void menuwindow::position(int X, int Y) {
+  if (title) {title->position(X, title->y()+Y-y());}
+  Fl_Menu_Window::position(X, Y);
+  // x(X); y(Y); // don't wait for response from X
+}
+
+// scroll so item i is visible on screen
+void menuwindow::autoscroll(int n) {
+  int scr_x, scr_y, scr_w, scr_h;
+  int Y = y()+Fl::box_dx(box())+2+n*itemheight;
+
+  Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+  if (Y <= scr_y) Y = scr_y-Y+10;
+  else {
+    Y = Y+itemheight-scr_h-scr_y;
+    if (Y < 0) return;
+    Y = -Y-10;
+  }
+  Fl_Menu_Window::position(x(), y()+Y);
+  // y(y()+Y); // don't wait for response from X
+}
+
+////////////////////////////////////////////////////////////////
+
+void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) {
+  if (!m) return; // this happens if -1 is selected item and redrawn
+
+  int BW = Fl::box_dx(box());
+  int xx = BW;
+  int W = w();
+  int ww = W-2*BW-1;
+  int yy = BW+1+n*itemheight;
+  int hh = itemheight - LEADING;
+
+  if (eraseit && n != selected) {
+    fl_push_clip(xx+1, yy-(LEADING-2)/2, ww-2, hh+(LEADING-2));
+    draw_box(box(), 0, 0, w(), h(), button ? button->color() : color());
+    fl_pop_clip();
+  }
+
+  m->draw(xx, yy, ww, hh, button, n==selected);
+
+  // the shortcuts and arrows assumme fl_color() was left set by draw():
+  if (m->submenu()) {
+    int sz = (hh-7)&-2;
+    int y1 = yy+(hh-sz)/2;
+    int x1 = xx+ww-sz-3;
+    fl_polygon(x1+2, y1, x1+2, y1+sz, x1+sz/2+2, y1+sz/2);
+  } else if (m->shortcut_) {
+    Fl_Font f = m->labelsize_ || m->labelfont_ ? (Fl_Font)m->labelfont_ :
+                    button ? button->textfont() : FL_HELVETICA;
+    fl_font(f, m->labelsize_ ? m->labelsize_ :
+                   button ? button->textsize() : FL_NORMAL_SIZE);
+    fl_draw(fl_shortcut_label(m->shortcut_), xx, yy, ww-3, hh, FL_ALIGN_RIGHT);
+  }
+
+  if (m->flags & FL_MENU_DIVIDER) {
+    fl_color(FL_DARK3);
+    fl_xyline(BW-1, yy+hh+(LEADING-2)/2, W-2*BW+2);
+    fl_color(FL_LIGHT3);
+    fl_xyline(BW-1, yy+hh+((LEADING-2)/2+1), W-2*BW+2);
+  }
+}
+
+void menutitle::draw() {
+  menu->draw(0, 0, w(), h(), button, 2);
+}
+
+void menuwindow::draw() {
+  if (damage() != FL_DAMAGE_CHILD) {	// complete redraw
+    fl_draw_box(box(), 0, 0, w(), h(), button ? button->color() : color());
+    if (menu) {
+      const Fl_Menu_Item* m; int j;
+      for (m=menu->first(), j=0; m->text; j++, m = m->next()) drawentry(m, j, 0);
+    }
+  } else {
+    if (damage() & FL_DAMAGE_CHILD && selected!=drawn_selected) { // change selection
+      drawentry(menu->next(drawn_selected), drawn_selected, 1);
+      drawentry(menu->next(selected), selected, 1);
+    }
+  }	    
+  drawn_selected = selected;
+}
+
+void menuwindow::set_selected(int n) {
+  if (n != selected) {selected = n; damage(FL_DAMAGE_CHILD);}
+}
+
+////////////////////////////////////////////////////////////////
+
+int menuwindow::find_selected(int mx, int my) {
+  if (!menu || !menu->text) return -1;
+  mx -= x();
+  my -= y();
+  if (my < 0 || my >= h()) return -1;
+  if (!itemheight) { // menubar
+    int xx = 3; int n = 0;
+    const Fl_Menu_Item* m = menu ? menu->first() : 0;
+    for (; ; m = m->next(), n++) {
+      if (!m->text) return -1;
+      xx += m->measure(0, button) + 16;
+      if (xx > mx) break;
+    }
+    return n;
+  }
+  if (mx < Fl::box_dx(box()) || mx >= w()) return -1;
+  int n = (my-Fl::box_dx(box())-1)/itemheight;
+  if (n < 0 || n>=numitems) return -1;
+  return n;
+}
+
+// return horizontal position for item n in a menubar:
+int menuwindow::titlex(int n) {
+  const Fl_Menu_Item* m;
+  int xx = 3;
+  for (m=menu->first(); n--; m = m->next()) xx += m->measure(0, button) + 16;
+  return xx;
+}
+
+////////////////////////////////////////////////////////////////
+// Fl_Menu_Item::popup(...)
+
+// Because Fl::grab() is done, all events go to one of the menu windows.
+// But the handle method needs to look at all of them to find out
+// what item the user is pointing at.  And it needs a whole lot
+// of other state variables to determine what is going on with
+// the currently displayed menus.
+// So the main loop (handlemenu()) puts all the state in a structure
+// and puts a pointer to it in a static location, so the handle()
+// on menus can refer to it and alter it.  The handle() method
+// changes variables in this state to indicate what item is
+// picked, but does not actually alter the display, instead the
+// main loop does that.  This is because the X mapping and unmapping
+// of windows is slow, and we don't want to fall behind the events.
+
+// values for menustate.state:
+#define INITIAL_STATE 0	// no mouse up or down since popup() called
+#define PUSH_STATE 1	// mouse has been pushed on a normal item
+#define DONE_STATE 2	// exit the popup, the current item was picked
+#define MENU_PUSH_STATE 3 // mouse has been pushed on a menu title
+
+struct menustate {
+  const Fl_Menu_Item* current_item; // what mouse is pointing at
+  int menu_number; // which menu it is in
+  int item_number; // which item in that menu, -1 if none
+  menuwindow* p[20]; // pointers to menus
+  int nummenus;
+  int menubar; // if true p[0] is a menubar
+  int state;
+};
+static menustate* p;
+
+static inline void setitem(const Fl_Menu_Item* i, int m, int n) {
+  p->current_item = i;
+  p->menu_number = m;
+  p->item_number = n;
+}
+
+static void setitem(int m, int n) {
+  menustate &pp = *p;
+  pp.current_item = (n >= 0) ? pp.p[m]->menu->next(n) : 0;
+  pp.menu_number = m;
+  pp.item_number = n;
+}
+
+static int forward(int menu) { // go to next item in menu menu if possible
+  menustate &pp = *p;
+  menuwindow &m = *(pp.p[menu]);
+  int item = (menu == pp.menu_number) ? pp.item_number : m.selected;
+  while (++item < m.numitems) {
+    const Fl_Menu_Item* m1 = m.menu->next(item);
+    if (m1->activevisible()) {setitem(m1, menu, item); return 1;}
+  }
+  return 0;
+}
+
+static int backward(int menu) { // previous item in menu menu if possible
+  menustate &pp = *p;
+  menuwindow &m = *(pp.p[menu]);
+  int item = (menu == pp.menu_number) ? pp.item_number : m.selected;
+  if (item < 0) item = m.numitems;
+  while (--item >= 0) {
+    const Fl_Menu_Item* m1 = m.menu->next(item);
+    if (m1->activevisible()) {setitem(m1, menu, item); return 1;}
+  }
+  return 0;
+}
+
+int menuwindow::handle(int e) {
+  menustate &pp = *p;
+  switch (e) {
+  case FL_KEYBOARD:
+    switch (Fl::event_key()) {
+    case FL_BackSpace:
+    case 0xFE20: // backtab
+    BACKTAB:
+      if (!backward(pp.menu_number)) {pp.item_number = -1;backward(pp.menu_number);}
+      return 1;
+    case FL_Up:
+      if (pp.menubar && pp.menu_number == 0) {
+        // Do nothing...
+      } else if (backward(pp.menu_number)) {
+        // Do nothing...
+      } else if (pp.menubar && pp.menu_number==1) {
+        setitem(0, pp.p[0]->selected);
+      }
+      return 1;
+    case FL_Tab:
+      if (Fl::event_shift()) goto BACKTAB;
+    case FL_Down:
+      if (pp.menu_number || !pp.menubar) forward(pp.menu_number);
+      else if (pp.menu_number < pp.nummenus-1) forward(pp.menu_number+1);
+      return 1;
+    case FL_Right:
+      if (pp.menubar && (pp.menu_number<=0 || pp.menu_number==1 && pp.nummenus==2))
+	forward(0);
+      else if (pp.menu_number < pp.nummenus-1) forward(pp.menu_number+1);
+      return 1;
+    case FL_Left:
+      if (pp.menubar && pp.menu_number<=1) backward(0);
+      else if (pp.menu_number>0)
+	setitem(pp.menu_number-1, pp.p[pp.menu_number-1]->selected);
+      return 1;
+    case FL_Enter:
+    case FL_KP_Enter:
+    case ' ':
+      pp.state = DONE_STATE;
+      return 1;
+    case FL_Escape:
+      setitem(0, -1, 0);
+      pp.state = DONE_STATE;
+      return 1;
+    }
+    break;
+  case FL_SHORTCUT: {
+    for (int mymenu = pp.nummenus; mymenu--;) {
+      menuwindow &mw = *(pp.p[mymenu]);
+      int item; const Fl_Menu_Item* m = mw.menu->find_shortcut(&item);
+      if (m) {
+	setitem(m, mymenu, item);
+	if (!m->submenu()) pp.state = DONE_STATE;
+	return 1;
+      }
+    }} break;
+  case FL_ENTER:
+  case FL_MOVE:
+  case FL_PUSH:
+  case FL_DRAG: {
+#ifdef __QNX__
+    // STR 704: workaround QNX X11 bug - in QNX a FL_MOVE event is sent
+    // right after FL_RELEASE...
+    if (pp.state == DONE_STATE) return 1;
+#endif // __QNX__
+    int mx = Fl::event_x_root();
+    int my = Fl::event_y_root();
+    int item=0; int mymenu = pp.nummenus-1;
+    if (e == FL_PUSH && (!pp.menubar || mymenu) &&
+        (mx < pp.p[mymenu]->x_root() ||
+	 mx >= (pp.p[mymenu]->x_root() + pp.p[mymenu]->w()) ||
+         my < pp.p[mymenu]->y_root() ||
+	 my >= (pp.p[mymenu]->y_root() + pp.p[mymenu]->h()))) {
+      // Clicking outside menu cancels it...
+      setitem(0, -1, 0);
+      pp.state = DONE_STATE;
+      return 1;
+    }
+    for (mymenu = pp.nummenus-1; ; mymenu--) {
+      item = pp.p[mymenu]->find_selected(mx, my);
+      if (item >= 0) break;
+      if (mymenu <= 0) return 0;
+    }
+    if (my == 0 && item > 0) setitem(mymenu, item - 1);
+    else setitem(mymenu, item);
+    if (e == FL_PUSH) {
+      if (pp.current_item && pp.current_item->submenu() // this is a menu title
+	  && item != pp.p[mymenu]->selected // and it is not already on
+	  && !pp.current_item->callback_) // and it does not have a callback
+	pp.state = MENU_PUSH_STATE;
+      else
+	pp.state = PUSH_STATE;
+    }} return 1;
+  case FL_RELEASE:
+    // do nothing if they try to pick inactive items
+    if (pp.current_item && !pp.current_item->activevisible()) {
+      if (pp.state==INITIAL_STATE) {
+        setitem(0, -1, 0);
+        pp.state = DONE_STATE;
+      }
+      return 1;
+    }
+    // Mouse must either be held down/dragged some, or this must be
+    // the second click (not the one that popped up the menu):
+    if (!Fl::event_is_click() || pp.state == PUSH_STATE ||
+	pp.menubar && pp.current_item && !pp.current_item->submenu() // button
+	) {
+#if 0 // makes the check/radio items leave the menu up
+      const Fl_Menu_Item* m = pp.current_item;
+      if (m && button && (m->flags & (FL_MENU_TOGGLE|FL_MENU_RADIO))) {
+	((Fl_Menu_*)button)->picked(m);
+	pp.p[pp.menu_number]->redraw();
+      } else
+#endif
+	pp.state = DONE_STATE;
+    }
+    return 1;
+  }
+  return Fl_Window::handle(e);
+}
+
+const Fl_Menu_Item* Fl_Menu_Item::pulldown(
+    int X, int Y, int W, int H,
+    const Fl_Menu_Item* initial_item,
+    const Fl_Menu_* pbutton,
+    const Fl_Menu_Item* t,
+    int menubar) const
+{
+  Fl_Group::current(0); // fix possible user error...
+
+  button = pbutton;
+  if (pbutton) {
+    for (Fl_Window* w = pbutton->window(); w; w = w->window()) {
+      X += w->x();
+      Y += w->y();
+    }
+  } else {
+    X += Fl::event_x_root()-Fl::event_x();
+    Y += Fl::event_y_root()-Fl::event_y();
+  }
+  menuwindow mw(this, X, Y, W, H, initial_item, t, menubar);
+  Fl::grab(mw);
+  menustate pp; p = &pp;
+  pp.p[0] = &mw;
+  pp.nummenus = 1;
+  pp.menubar = menubar;
+  pp.state = INITIAL_STATE;
+
+  menuwindow* fakemenu = 0; // kludge for buttons in menubar
+
+  // preselected item, pop up submenus if necessary:
+  if (initial_item && mw.selected >= 0) {
+    setitem(0, mw.selected);
+    goto STARTUP;
+  }
+
+  pp.current_item = 0; pp.menu_number = 0; pp.item_number = -1;
+  if (menubar) {
+    // find the initial menu
+    if (!mw.handle(FL_DRAG)) {
+      Fl::release();
+      return 0;
+    }
+  }
+  initial_item = pp.current_item;
+  if (initial_item) goto STARTUP;
+
+  // the main loop, runs until p.state goes to DONE_STATE:
+  for (;;) {
+
+    // make sure all the menus are shown:
+    {for (int k = menubar; k < pp.nummenus; k++)
+      if (!pp.p[k]->shown()) {
+	if (pp.p[k]->title) pp.p[k]->title->show();
+	pp.p[k]->show();
+      }
+    }
+
+    // get events:
+    {const Fl_Menu_Item* oldi = pp.current_item;
+    Fl::wait();
+    if (pp.state == DONE_STATE) break; // done.
+    if (pp.current_item == oldi) continue;}
+    // only do rest if item changes:
+
+    delete fakemenu; fakemenu = 0; // turn off "menubar button"
+
+    if (!pp.current_item) { // pointing at nothing
+      // turn off selection in deepest menu, but don't erase other menus:
+      pp.p[pp.nummenus-1]->set_selected(-1);
+      continue;
+    }
+
+    delete fakemenu; fakemenu = 0;
+    initial_item = 0; // stop the startup code
+    pp.p[pp.menu_number]->autoscroll(pp.item_number);
+
+  STARTUP:
+    menuwindow& cw = *pp.p[pp.menu_number];
+    const Fl_Menu_Item* m = pp.current_item;
+    if (!m->activevisible()) { // pointing at inactive item
+      cw.set_selected(-1);
+      initial_item = 0; // turn off startup code
+      continue;
+    }
+    cw.set_selected(pp.item_number);
+
+    if (m==initial_item) initial_item=0; // stop the startup code if item found
+    if (m->submenu()) {
+      const Fl_Menu_Item* title = m;
+      const Fl_Menu_Item* menutable;
+      if (m->flags&FL_SUBMENU) menutable = m+1;
+      else menutable = (Fl_Menu_Item*)(m)->user_data_;
+      // figure out where new menu goes:
+      int nX, nY;
+      if (!pp.menu_number && pp.menubar) {	// menu off a menubar:
+	nX = cw.x() + cw.titlex(pp.item_number);
+	nY = cw.y() + cw.h();
+	initial_item = 0;
+      } else {
+	nX = cw.x() + cw.w();
+	nY = cw.y() + pp.item_number * cw.itemheight;
+	title = 0;
+      }
+      if (initial_item) { // bring up submenu containing initial item:
+	menuwindow* n = new menuwindow(menutable,X,Y,W,H,initial_item,title,0,0,cw.x());
+	pp.p[pp.nummenus++] = n;
+	// move all earlier menus to line up with this new one:
+	if (n->selected>=0) {
+	  int dy = n->y()-nY;
+	  int dx = n->x()-nX;
+	  for (int menu = 0; menu <= pp.menu_number; menu++) {
+	    menuwindow* tt = pp.p[menu];
+	    int nx = tt->x()+dx; if (nx < 0) {nx = 0; dx = -tt->x();}
+	    int ny = tt->y()+dy; if (ny < 0) {ny = 0; dy = -tt->y();}
+	    tt->position(nx, ny);
+	  }
+	  setitem(pp.nummenus-1, n->selected);
+	  goto STARTUP;
+	}
+      } else if (pp.nummenus > pp.menu_number+1 &&
+		 pp.p[pp.menu_number+1]->menu == menutable) {
+	// the menu is already up:
+	while (pp.nummenus > pp.menu_number+2) delete pp.p[--pp.nummenus];
+	pp.p[pp.nummenus-1]->set_selected(-1);
+      } else {
+	// delete all the old menus and create new one:
+	while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus];
+	pp.p[pp.nummenus++]= new menuwindow(menutable, nX, nY,
+					  title?1:0, 0, 0, title, 0, menubar, cw.x());
+      }
+    } else { // !m->submenu():
+      while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus];
+      if (!pp.menu_number && pp.menubar) {
+	// kludge so "menubar buttons" turn "on" by using menu title:
+	fakemenu = new menuwindow(0,
+				  cw.x()+cw.titlex(pp.item_number),
+				  cw.y()+cw.h(), 0, 0,
+				  0, m, 0, 1);
+	fakemenu->title->show();
+      }
+    }
+  }
+  const Fl_Menu_Item* m = pp.current_item;
+  Fl::release();
+  delete fakemenu;
+  while (pp.nummenus>1) delete pp.p[--pp.nummenus];
+  mw.hide();
+  return m;
+}
+
+const Fl_Menu_Item*
+Fl_Menu_Item::popup(
+  int X, int Y,
+  const char* title,
+  const Fl_Menu_Item* picked,
+  const Fl_Menu_* but
+  ) const
+{
+  static Fl_Menu_Item dummy; // static so it is all zeros
+  dummy.text = title;
+  return pulldown(X, Y, 0, 0, picked, but, title ? &dummy : 0);
+}
+
+// Search only the top level menu for a shortcut.  Either &x in the
+// label or the shortcut fields are used:
+const Fl_Menu_Item* Fl_Menu_Item::find_shortcut(int* ip) const {
+  const Fl_Menu_Item* m = first();
+  if (m) for (int ii = 0; m->text; m = m->next(), ii++) {
+    if (m->activevisible()) {
+      if (Fl::test_shortcut(m->shortcut_)
+	 || Fl_Widget::test_shortcut(m->text)) {
+	if (ip) *ip=ii;
+	return m;
+      }
+    }
+  }
+  return 0;
+}
+
+// Recursive search of all submenus for anything with this key as a
+// shortcut.  Only uses the shortcut field, ignores &x in the labels:
+const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const {
+  const Fl_Menu_Item* m = first();
+  const Fl_Menu_Item* ret = 0;
+  if (m) for (; m->text; m = m->next()) {
+    if (m->activevisible()) {
+      // return immediately any match of an item in top level menu:
+      if (Fl::test_shortcut(m->shortcut_)) return m;
+      // if (Fl_Widget::test_shortcut(m->text)) return m;
+      // only return matches from lower menu if nothing found in top menu:
+      if (!ret && m->submenu()) {
+	const Fl_Menu_Item* s =
+	  (m->flags&FL_SUBMENU) ? m+1:(const Fl_Menu_Item*)m->user_data_;
+	ret = s->test_shortcut();
+      }
+    }
+  }
+  return ret;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Menu_.cxx b/Utilities/FLTK/src/Fl_Menu_.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f5b3c61a2214174f9199be5a44597a202678d39a
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Menu_.cxx
@@ -0,0 +1,232 @@
+//
+// "$Id$"
+//
+// Common menu code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This is a base class for all items that have a menu:
+//	Fl_Menu_Bar, Fl_Menu_Button, Fl_Choice
+// This provides storage for a menu item, functions to add/modify/delete
+// items, and a call for when the user picks a menu item.
+
+// More code in Fl_Menu_add.cxx
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_.H>
+#include "flstring.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+// Set 'pathname' of specified menuitem
+//    If finditem==NULL, mvalue() is used (the most recently picked menuitem)
+//    Returns:
+//       0 : OK
+//      -1 : item not found (name="")
+//      -2 : 'name' not large enough (name="")
+//
+#define SAFE_STRCAT(s) \
+    { len += strlen(s); if ( len >= namelen ) { *name='\0'; return(-2); } else strcat(name,(s)); }
+int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem) const {
+    int len = 0;
+    finditem = finditem ? finditem : mvalue();    
+    name[0] = '\0';
+    for ( int t=0; t<size(); t++ ) {
+        const Fl_Menu_Item *m = &(menu()[t]);
+	if ( m->submenu() ) {				// submenu? descend
+	    if (*name) SAFE_STRCAT("/");
+	    if (m->label()) SAFE_STRCAT(m->label());
+	} else {
+	    if (m->label()) {				// menu item?
+		if ( m == finditem ) {			// found? tack on itemname, done.
+		    SAFE_STRCAT("/");
+		    SAFE_STRCAT(m->label());
+		    return(0);
+		}
+	    } else {					// end of submenu? pop
+	        char *ss = strrchr(name, '/');
+		if ( ss ) { *ss = 0; len = strlen(name); }	// "File/Edit" -> "File"
+		else { name[0] = '\0'; len = 0; }		// "File" -> ""
+		continue;
+	    }
+	}
+    }
+    *name = '\0';
+    return(-1);						// item not found
+}
+
+// FIND MENU ITEM INDEX, GIVEN MENU PATHNAME
+//     eg. "Edit/Copy"
+//     Will also return submenus, eg. "Edit"
+//     Returns NULL if not found.
+//
+const Fl_Menu_Item *
+Fl_Menu_::find_item(const char *name)
+{
+  char menupath[1024] = "";	// File/Export
+
+  for ( int t=0; t < size(); t++ ) {
+    Fl_Menu_Item *m = menu_ + t;
+
+    if (m->flags&FL_SUBMENU) {
+      // IT'S A SUBMENU
+      // we do not support searches through FL_SUBMENU_POINTER links
+      if (menupath[0]) strlcat(menupath, "/", sizeof(menupath));
+      strlcat(menupath, m->label(), sizeof(menupath));
+      if (!strcmp(menupath, name)) return m;
+    } else {
+      if (!m->label()) {
+	// END OF SUBMENU? Pop back one level.
+	char *ss = strrchr(menupath, '/');
+	if ( ss ) *ss = 0;
+	else menupath[0] = '\0';
+	continue;
+      }
+
+      // IT'S A MENU ITEM
+      char itempath[1024];	// eg. Edit/Copy
+      strcpy(itempath, menupath);
+      if (itempath[0]) strlcat(itempath, "/", sizeof(itempath));
+      strlcat(itempath, m->label(), sizeof(itempath));
+      if (!strcmp(itempath, name)) return m;
+    }
+  }
+
+  return (const Fl_Menu_Item *)0;
+}
+
+int Fl_Menu_::value(const Fl_Menu_Item* m) {
+  clear_changed();
+  if (value_ != m) {value_ = m; return 1;}
+  return 0;
+}
+
+// When user picks a menu item, call this.  It will do the callback.
+// Unfortunatly this also casts away const for the checkboxes, but this
+// was necessary so non-checkbox menus can really be declared const...
+const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) {
+  if (v) {
+    if (v->radio()) {
+      if (!v->value()) { // they are turning on a radio item
+	set_changed();
+	((Fl_Menu_Item*)v)->setonly();
+      }
+      redraw();
+    } else if (v->flags & FL_MENU_TOGGLE) {
+      set_changed();
+      ((Fl_Menu_Item*)v)->flags ^= FL_MENU_VALUE;
+      redraw();
+    } else if (v != value_) { // normal item
+      set_changed();
+    }
+    value_ = v;
+    if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) {
+      if (changed() || when()&FL_WHEN_NOT_CHANGED) {
+	if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this);
+	else do_callback();
+      }
+    }
+  }
+  return v;
+}
+
+// turn on one of a set of radio buttons
+void Fl_Menu_Item::setonly() {
+  flags |= FL_MENU_RADIO | FL_MENU_VALUE;
+  Fl_Menu_Item* j;
+  for (j = this; ; ) {	// go down
+    if (j->flags & FL_MENU_DIVIDER) break; // stop on divider lines
+    j++;
+    if (!j->text || !j->radio()) break; // stop after group
+    j->clear();
+  }
+  for (j = this-1; ; j--) { // go up
+    if (!j->text || (j->flags&FL_MENU_DIVIDER) || !j->radio()) break;
+    j->clear();
+  }
+}
+
+Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l)
+: Fl_Widget(X,Y,W,H,l) {
+  set_flag(SHORTCUT_LABEL);
+  box(FL_UP_BOX);
+  when(FL_WHEN_RELEASE_ALWAYS);
+  value_ = menu_ = 0;
+  alloc = 0;
+  selection_color(FL_SELECTION_COLOR);
+  textfont(FL_HELVETICA);
+  textsize((uchar)FL_NORMAL_SIZE);
+  textcolor(FL_FOREGROUND_COLOR);
+  down_box(FL_NO_BOX);
+}
+
+int Fl_Menu_::size() const {
+  if (!menu_) return 0;
+  return menu_->size();
+}
+
+void Fl_Menu_::menu(const Fl_Menu_Item* m) {
+  clear();
+  value_ = menu_ = (Fl_Menu_Item*)m;
+}
+
+// this version is ok with new Fl_Menu_add code with fl_menu_array_owner:
+
+void Fl_Menu_::copy(const Fl_Menu_Item* m, void* ud) {
+  int n = m->size();
+  Fl_Menu_Item* newMenu = new Fl_Menu_Item[n];
+  memcpy(newMenu, m, n*sizeof(Fl_Menu_Item));
+  menu(newMenu);
+  alloc = 1; // make destructor free array, but not strings
+  // for convienence, provide way to change all the user data pointers:
+  if (ud) for (; n--;) {
+    if (newMenu->callback_) newMenu->user_data_ = ud;
+    newMenu++;
+  }
+}
+
+Fl_Menu_::~Fl_Menu_() {
+  clear();
+}
+
+// Fl_Menu::add() uses this to indicate the owner of the dynamically-
+// expanding array.  We must not free this array:
+Fl_Menu_* fl_menu_array_owner = 0;
+
+void Fl_Menu_::clear() {
+  if (alloc) {
+    if (alloc>1) for (int i = size(); i--;)
+      if (menu_[i].text) free((void*)menu_[i].text);
+    if (this == fl_menu_array_owner)
+      fl_menu_array_owner = 0;
+    else
+      delete[] menu_;
+    menu_ = 0;
+    value_ = 0;
+    alloc = 0;
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Menu_Bar.cxx b/Utilities/FLTK/src/Fl_Menu_Bar.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9843e394d3b45e802011ee1b2ab0dc95331f7e46
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Menu_Bar.cxx
@@ -0,0 +1,78 @@
+//
+// "$Id$"
+//
+// Menu bar widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/fl_draw.H>
+
+void Fl_Menu_Bar::draw() {
+  draw_box();
+  if (!menu() || !menu()->text) return;
+  const Fl_Menu_Item* m;
+  int X = x()+6;
+  for (m=menu()->first(); m->text; m = m->next()) {
+    int W = m->measure(0,this) + 16;
+    m->draw(X, y(), W, h(), this);
+    X += W;
+    if (m->flags & FL_MENU_DIVIDER) {
+      int y1 = y() + Fl::box_dy(box());
+      int y2 = y1 + h() - Fl::box_dh(box()) - 1;
+
+      // Draw a vertical divider between menus...
+      fl_color(FL_DARK3);
+      fl_yxline(X - 6, y1, y2);
+      fl_color(FL_LIGHT3);
+      fl_yxline(X - 5, y1, y2);
+    }
+  }
+}
+
+int Fl_Menu_Bar::handle(int event) {
+  const Fl_Menu_Item* v;
+  if (menu() && menu()->text) switch (event) {
+  case FL_ENTER:
+  case FL_LEAVE:
+    return 1;
+  case FL_PUSH:
+    v = 0;
+  J1:
+    v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1);
+    picked(v);
+    return 1;
+  case FL_SHORTCUT:
+    if (visible_r()) {
+      v = menu()->find_shortcut();
+      if (v && v->submenu()) goto J1;
+    }
+    return test_shortcut() != 0;
+  }
+  return 0;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Menu_Button.cxx b/Utilities/FLTK/src/Fl_Menu_Button.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..80768a6e07d0de8b86c9823b4e227a5ee1a9ae8c
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Menu_Button.cxx
@@ -0,0 +1,108 @@
+//
+// "$Id$"
+//
+// Menu button widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/fl_draw.H>
+
+
+static Fl_Menu_Button	*pressed_menu_button_ = 0;
+
+void Fl_Menu_Button::draw() {
+  if (!box() || type()) return;
+  draw_box(pressed_menu_button_ == this ? fl_down(box()) : box(), color());
+  draw_label();
+  if (Fl::focus() == this) draw_focus();
+  if (box() == FL_FLAT_BOX) return; // for XForms compatability
+  int H = (labelsize()-3)&-2;
+  int X = x()+w()-H*2;
+  int Y = y()+(h()-H)/2;
+  fl_color(active_r() ? FL_DARK3 : fl_inactive(FL_DARK3));
+  fl_line(X+H/2, Y+H, X, Y, X+H, Y);
+  fl_color(active_r() ? FL_LIGHT3 : fl_inactive(FL_LIGHT3));
+  fl_line(X+H, Y, X+H/2, Y+H);
+}
+
+const Fl_Menu_Item* Fl_Menu_Button::popup() {
+  const Fl_Menu_Item* m;
+  pressed_menu_button_ = this;
+  redraw();
+  if (!box() || type()) {
+    m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this);
+  } else {
+    m = menu()->pulldown(x(), y(), w(), h(), 0, this);
+  }
+  picked(m);
+  pressed_menu_button_ = 0;
+  redraw();
+  return m;
+}
+
+int Fl_Menu_Button::handle(int e) {
+  if (!menu() || !menu()->text) return 0;
+  switch (e) {
+  case FL_ENTER:
+  case FL_LEAVE:
+    return (box() && !type()) ? 1 : 0;
+  case FL_PUSH:
+    if (!box()) {
+      if (Fl::event_button() != 3) return 0;
+    } else if (type()) {
+      if (!(type() & (1 << (Fl::event_button()-1)))) return 0;
+    }
+    if (Fl::visible_focus()) Fl::focus(this);
+    popup();
+    return 1;
+  case FL_KEYBOARD:
+    if (!box()) return 0;
+    if (Fl::event_key() == ' ' &&
+        !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
+      popup();
+      return 1;
+    } else return 0;
+  case FL_SHORTCUT:
+    if (Fl_Widget::test_shortcut()) {popup(); return 1;}
+    return test_shortcut() != 0;
+  case FL_FOCUS:
+  case FL_UNFOCUS:
+    if (box() && Fl::visible_focus()) {
+      redraw();
+      return 1;
+    }
+  default:
+    return 0;
+  }
+}
+
+Fl_Menu_Button::Fl_Menu_Button(int X,int Y,int W,int H,const char *l)
+: Fl_Menu_(X,Y,W,H,l) {
+  down_box(FL_NO_BOX);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Menu_Window.cxx b/Utilities/FLTK/src/Fl_Menu_Window.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..98bd981343cab07625619c19c2fea6fb34554ba5
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Menu_Window.cxx
@@ -0,0 +1,104 @@
+//
+// "$Id$"
+//
+// Menu window code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This is the window type used by Fl_Menu to make the pop-ups.
+// It draws in the overlay planes if possible.
+
+// Also here is the implementation of the mouse & keyboard grab,
+// which are used so that clicks outside the program's windows
+// can be used to dismiss the menus.
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Menu_Window.H>
+
+// WIN32 note: HAVE_OVERLAY is false
+#if HAVE_OVERLAY
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+static GC gc;	// the GC used by all X windows
+extern uchar fl_overlay; // changes how fl_color(x) works
+#endif
+
+#include <stdio.h>
+
+void Fl_Menu_Window::show() {
+#if HAVE_OVERLAY
+  if (!shown() && overlay() && fl_find_overlay_visual()) {
+    XInstallColormap(fl_display, fl_overlay_colormap);
+    fl_background_pixel = int(fl_transparent_pixel);
+    Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+    fl_background_pixel = -1;
+  } else
+#endif
+    Fl_Single_Window::show();
+}
+
+void Fl_Menu_Window::flush() {
+#if HAVE_OVERLAY
+  if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;}
+  Fl_X *myi = Fl_X::i(this);
+  fl_window = myi->xid;
+  if (!gc) gc = XCreateGC(fl_display, myi->xid, 0, 0);
+  fl_gc = gc;
+  fl_overlay = 1;
+  fl_clip_region(myi->region); myi->region = 0; current_ = this;
+  draw();
+  fl_overlay = 0;
+#else
+  Fl_Single_Window::flush();
+#endif
+}
+
+void Fl_Menu_Window::erase() {
+#if HAVE_OVERLAY
+  if (!gc || !shown()) return;
+//XSetForeground(fl_display, gc, 0);
+//XFillRectangle(fl_display, fl_xid(this), gc, 0, 0, w(), h());
+  XClearWindow(fl_display, fl_xid(this));
+#endif
+}
+
+// Fix the colormap flashing on Maximum Impact Graphics by erasing the
+// menu before unmapping it:
+void Fl_Menu_Window::hide() {
+  erase();
+  Fl_Single_Window::hide();
+}
+
+Fl_Menu_Window::~Fl_Menu_Window() {
+  hide();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Menu_add.cxx b/Utilities/FLTK/src/Fl_Menu_add.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..77a70edd8305c53aa4f084055f6a7170ed37d21a
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Menu_add.cxx
@@ -0,0 +1,268 @@
+//
+// "$Id$"
+//
+// Menu utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Methods to alter the menu in an Fl_Menu_ widget.
+
+// These are for Forms emulation and for dynamically changing the
+// menus.  They are in this source file so they are not linked in if
+// not used, which is what will happen if the the program only uses
+// constant menu tables.
+
+// Not at all guaranteed to be Forms compatable, especially with any
+// string with a % sign in it!
+
+#include <FL/Fl_Menu_.H>
+#include "flstring.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+// If the array is this, we will double-reallocate as necessary:
+static Fl_Menu_Item* local_array = 0;
+static int local_array_alloc = 0; // number allocated
+static int local_array_size = 0; // == size(local_array)
+extern Fl_Menu_* fl_menu_array_owner; // in Fl_Menu_.cxx
+
+// For historical reasons there are matching methods that work on a
+// user-allocated array of Fl_Menu_Item.  These methods are quite
+// depreciated and should not be used.  These old methods use the
+// above pointers to detect if the array belongs to an Fl_Menu_
+// widget, and if so it reallocates as necessary.
+
+// Insert a single Fl_Menu_Item into an array of size at offset n,
+// if this is local_array it will be reallocated if needed.
+static Fl_Menu_Item* insert(
+  Fl_Menu_Item* array, int size,
+  int n,
+  const char *text,
+  int flags
+) {
+  if (array == local_array && size >= local_array_alloc) {
+    local_array_alloc = 2*size;
+    Fl_Menu_Item* newarray = new Fl_Menu_Item[local_array_alloc];
+    memmove(newarray, array, size*sizeof(Fl_Menu_Item));
+    delete[] local_array;
+    local_array = array = newarray;
+  }
+  // move all the later items:
+  memmove(array+n+1, array+n, sizeof(Fl_Menu_Item)*(size-n));
+  // create the new item:
+  Fl_Menu_Item* m = array+n;
+  m->text = text ? strdup(text) : 0;
+  m->shortcut_ = 0;
+  m->callback_ = 0;
+  m->user_data_ = 0;
+  m->flags = flags;
+  m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
+  return array;
+}
+
+// Comparison that does not care about deleted '&' signs:
+static int compare(const char* a, const char* b) {
+  for (;;) {
+    int n = *a-*b;
+    if (n) {
+      if (*a == '&') a++;
+      else if (*b == '&') b++;
+      else return n;
+    } else if (*a) {
+      a++; b++;
+    } else {
+      return 0;
+    }
+  }
+}
+
+// Add an item.  The text is split at '/' characters to automatically
+// produce submenus (actually a totally unnecessary feature as you can
+// now add submenu titles directly by setting SUBMENU in the flags):
+int Fl_Menu_Item::add(
+  const char *mytext,
+  int sc,
+  Fl_Callback *cb,	
+  void *data,
+  int myflags
+) {
+  Fl_Menu_Item *array = this;
+  Fl_Menu_Item *m = this;
+  const char *p;
+  char *q;
+  char buf[1024];
+
+  int msize = array==local_array ? local_array_size : array->size();
+  int flags1 = 0;
+  const char* item;
+
+  // split at slashes to make submenus:
+  for (;;) {
+
+    // leading slash makes us assumme it is a filename:
+    if (*mytext == '/') {item = mytext; break;}
+
+    // leading underscore causes divider line:
+    if (*mytext == '_') {mytext++; flags1 = FL_MENU_DIVIDER;}
+
+    // copy to buf, changing \x to x:
+    q = buf;
+    for (p=mytext; *p && *p != '/'; *q++ = *p++) if (*p=='\\' && p[1]) p++;
+    *q = 0;
+
+    item = buf;
+    if (*p != '/') break; /* not a menu title */
+    mytext = p+1;	/* point at item title */
+
+    /* find a matching menu title: */
+    for (; m->text; m = m->next())
+      if (m->flags&FL_SUBMENU && !compare(item, m->text)) break;
+
+    if (!m->text) { /* create a new menu */
+      int n = m-array;
+      array = insert(array, msize, n, item, FL_SUBMENU|flags1);
+      msize++;
+      array = insert(array, msize, n+1, 0, 0);
+      msize++;
+      m = array+n;
+    }
+    m++;	/* go into the submenu */
+    flags1 = 0;
+  }
+
+  /* find a matching menu item: */
+  for (; m->text; m = m->next())
+    if (!(m->flags&FL_SUBMENU) && !compare(m->text,item)) break;
+
+  if (!m->text) {	/* add a new menu item */
+    int n = m-array;
+    array = insert(array, msize, n, item, myflags|flags1);
+    msize++;
+    if (myflags & FL_SUBMENU) { // add submenu delimiter
+      array = insert(array, msize, n+1, 0, 0);
+      msize++;
+    }
+    m = array+n;
+  }
+
+  /* fill it in */
+  m->shortcut_ = sc;
+  m->callback_ = cb;
+  m->user_data_ = data;
+  m->flags = myflags|flags1;
+
+  if (array == local_array) local_array_size = msize;
+  return m-array;
+}
+
+int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) {
+  // make this widget own the local array:
+  if (this != fl_menu_array_owner) {
+    if (fl_menu_array_owner) {
+      Fl_Menu_* o = fl_menu_array_owner;
+      // the previous owner get's its own correctly-sized array:
+      int value_offset = o->value_-local_array;
+      int n = local_array_size;
+      Fl_Menu_Item* newMenu = o->menu_ = new Fl_Menu_Item[n];
+      memcpy(newMenu, local_array, n*sizeof(Fl_Menu_Item));
+      if (o->value_) o->value_ = newMenu+value_offset;
+    }
+    if (menu_) {
+      // this already has a menu array, use it as the local one:
+      delete[] local_array;
+      if (!alloc) copy(menu_); // duplicate a user-provided static array
+      // add to the menu's current array:
+      local_array_alloc = local_array_size = size();
+      local_array = menu_;
+    } else {
+      // start with a blank array:
+      alloc = 2; // indicates that the strings can be freed
+      if (local_array) {
+	menu_ = local_array;
+      } else {
+	local_array_alloc = 15;
+	local_array = menu_ = new Fl_Menu_Item[local_array_alloc];
+        memset(local_array, 0, sizeof(Fl_Menu_Item) * local_array_alloc);
+      }
+      memset(menu_, 0, sizeof(Fl_Menu_Item));
+      local_array_size = 1;
+    }
+    fl_menu_array_owner = this;
+  }
+  int r = menu_->add(t,s,c,v,f);
+  // if it rellocated array we must fix the pointer:
+  int value_offset = value_-menu_;
+  menu_ = local_array; // in case it reallocated it
+  if (value_) value_ = menu_+value_offset;
+  return r;
+}
+
+// This is a Forms (and SGI GL library) compatable add function, it
+// adds many menu items, with '|' seperating the menu items, and tab
+// seperating the menu item names from an optional shortcut string.
+int Fl_Menu_::add(const char *str) {
+  char buf[1024];
+  int r = 0;
+  while (*str) {
+    int sc = 0;
+    char *c;
+    for (c = buf; c < (buf + sizeof(buf) - 2) && *str && *str != '|'; str++) {
+      if (*str == '\t') {*c++ = 0; sc = fl_old_shortcut(str);}
+      else *c++ = *str;
+    }
+    *c = 0;
+    r = add(buf, sc, 0, 0, 0);
+    if (*str) str++;
+  }
+  return r;
+}
+
+void Fl_Menu_::replace(int i, const char *str) {
+  if (i<0 || i>=size()) return;
+  if (!alloc) copy(menu_);
+  if (alloc > 1) {
+    free((void *)menu_[i].text);
+    str = strdup(str);
+  }
+  menu_[i].text = str;
+}
+
+void Fl_Menu_::remove(int i) {
+  int n = size();
+  if (i<0 || i>=n) return;
+  if (!alloc) copy(menu_);
+  // find the next item, skipping submenus:
+  Fl_Menu_Item* item = menu_+i;
+  const Fl_Menu_Item* next_item = item->next();
+  // delete the text only if all items were created with add():
+  if (alloc > 1) {
+    for (Fl_Menu_Item* m = item; m < next_item; m++)
+      if (m->text) free((void*)(m->text));
+  }
+  // MRS: "n" is the menu size(), which includes the trailing NULL entry...
+  memmove(item, next_item, (menu_+n-next_item)*sizeof(Fl_Menu_Item));
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Menu_global.cxx b/Utilities/FLTK/src/Fl_Menu_global.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b7cba6faf443add86789a3a810d6502c1d6ce4fa
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Menu_global.cxx
@@ -0,0 +1,50 @@
+//
+// "$Id$"
+//
+// Global menu shortcut code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Make all the shortcuts in this menu global.
+// Currently only one menu at a time and you cannot destruct the menu,
+// is this sufficient?
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_.H>
+
+static Fl_Menu_* the_widget;
+
+static int handler(int e) {
+  if (e != FL_SHORTCUT || Fl::modal()) return 0;
+  Fl::first_window(the_widget->window());
+  return the_widget->handle(e);
+}
+
+void Fl_Menu_::global() {
+  if (!the_widget) Fl::add_handler(handler);
+  the_widget = this;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Multi_Label.cxx b/Utilities/FLTK/src/Fl_Multi_Label.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fdf84f364286fe0cb732d71821e2a677d97c5c66
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Multi_Label.cxx
@@ -0,0 +1,80 @@
+//
+// "$Id$"
+//
+// Multi-label widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Allows two labels to be used on a widget (by having one of them
+// be one of these it allows an infinte number!)
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Multi_Label.H>
+
+static void multi_labeltype(
+    const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
+{
+  Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value);
+  Fl_Label local = *o;
+  local.value = b->labela;
+  local.type = b->typea;
+  int W = w; int H = h; local.measure(W, H);
+  local.draw(x,y,w,h,a);
+  if (a & FL_ALIGN_BOTTOM) h -= H;
+  else if (a & FL_ALIGN_TOP) {y += H; h -= H;}
+  else if (a & FL_ALIGN_RIGHT) w -= W;
+  else if (a & FL_ALIGN_LEFT) {x += W; w -= W;}
+  else {int d = (h+H)/2; y += d; h -= d;}
+  local.value = b->labelb;
+  local.type = b->typeb;
+  local.draw(x,y,w,h,a);
+}
+
+// measurement is only correct for left-to-right appending...
+static void multi_measure(const Fl_Label* o, int& w, int& h) {
+  Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value);
+  Fl_Label local = *o;
+  local.value = b->labela;
+  local.type = b->typea;
+  local.measure(w,h);
+  local.value = b->labelb;
+  local.type = b->typeb;
+  int W = 0; int H = 0; local.measure(W,H);
+  w += W; if (H>h) h = H;
+}
+
+void Fl_Multi_Label::label(Fl_Widget* o) {
+  Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure);
+  o->label(_FL_MULTI_LABEL, (const char*)this);
+}
+
+void Fl_Multi_Label::label(Fl_Menu_Item* o) {
+  Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure);
+  o->label(_FL_MULTI_LABEL, (const char*)this);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Overlay_Window.cxx b/Utilities/FLTK/src/Fl_Overlay_Window.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d7ea8252573b28b7bf6624b3da194bdd038ebccc
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Overlay_Window.cxx
@@ -0,0 +1,156 @@
+//
+// "$Id$"
+//
+// Overlay window code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// A window using double-buffering and able to draw an overlay
+// on top of that.  Uses the hardware to draw the overlay if
+// possible, otherwise it just draws in the front buffer.
+#include <FL/Fl.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/Fl_Overlay_Window.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+void Fl_Overlay_Window::show() {
+  Fl_Double_Window::show();
+  if (overlay_ && overlay_ != this) overlay_->show();
+}
+
+void Fl_Overlay_Window::hide() {
+  Fl_Double_Window::hide();
+}
+
+void Fl_Overlay_Window::flush() {
+#ifdef BOXX_BUGS
+  if (overlay_ && overlay_ != this && overlay_->shown()) {
+    // all drawing to windows hidden by overlay windows is ignored, fix this
+    XUnmapWindow(fl_display, fl_xid(overlay_));
+    Fl_Double_Window::flush(0);
+    XMapWindow(fl_display, fl_xid(overlay_));
+    return;
+  }
+#endif
+  int erase_overlay = (damage()&FL_DAMAGE_OVERLAY);
+  clear_damage((uchar)(damage()&~FL_DAMAGE_OVERLAY));
+  Fl_Double_Window::flush(erase_overlay);
+  if (overlay_ == this) draw_overlay();
+}
+
+void Fl_Overlay_Window::resize(int X, int Y, int W, int H) {
+  Fl_Double_Window::resize(X,Y,W,H);
+  if (overlay_ && overlay_!=this) overlay_->resize(0,0,w(),h());
+}
+
+Fl_Overlay_Window::~Fl_Overlay_Window() {
+  hide();
+//  delete overlay; this is done by ~Fl_Group
+}
+
+#if !HAVE_OVERLAY
+
+int Fl_Overlay_Window::can_do_overlay() {return 0;}
+
+void Fl_Overlay_Window::redraw_overlay() {
+  overlay_ = this;
+  clear_damage((uchar)(damage()|FL_DAMAGE_OVERLAY));
+  Fl::damage(FL_DAMAGE_CHILD);
+}
+
+#else
+
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+static GC gc;	// the GC used by all X windows
+extern uchar fl_overlay; // changes how fl_color(x) works
+
+class _Fl_Overlay : public Fl_Window {
+  friend class Fl_Overlay_Window;
+  void flush();
+  void show();
+public:
+  _Fl_Overlay(int x, int y, int w, int h) :
+    Fl_Window(x,y,w,h) {set_flag(INACTIVE);}
+};
+
+int Fl_Overlay_Window::can_do_overlay() {
+  return fl_find_overlay_visual() != 0;
+}
+
+void _Fl_Overlay::show() {
+  if (shown()) {Fl_Window::show(); return;}
+  fl_background_pixel = int(fl_transparent_pixel);
+  Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+  fl_background_pixel = -1;
+  // find the outermost window to tell wm about the colormap:
+  Fl_Window *w = window();
+  for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
+  XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
+}
+
+void _Fl_Overlay::flush() {
+  fl_window = fl_xid(this);
+  if (!gc) gc = XCreateGC(fl_display, fl_xid(this), 0, 0);
+  fl_gc = gc;
+  fl_overlay = 1;
+  Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent();
+  Fl_X *myi = Fl_X::i(this);
+  if (damage() != FL_DAMAGE_EXPOSE) XClearWindow(fl_display, fl_xid(this));
+  fl_clip_region(myi->region); myi->region = 0;
+  w->draw_overlay();
+  fl_overlay = 0;
+}
+
+void Fl_Overlay_Window::redraw_overlay() {
+  if (!fl_display) return; // this prevents fluid -c from opening display
+  if (!overlay_) {
+    if (can_do_overlay()) {
+      Fl_Group::current(this);
+      overlay_ = new _Fl_Overlay(0,0,w(),h());
+      Fl_Group::current(0);
+    } else {
+      overlay_ = this;	// fake the overlay
+    }
+  }
+  if (shown()) {
+    if (overlay_ == this) {
+      clear_damage(damage()|FL_DAMAGE_OVERLAY);
+      Fl::damage(FL_DAMAGE_CHILD);
+    } else if (!overlay_->shown())
+      overlay_->show();
+    else
+      overlay_->redraw();
+  }
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_PNG_Image.cxx b/Utilities/FLTK/src/Fl_PNG_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8763d17e155a2a00fcf42cf46a06aaa2bc992af0
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_PNG_Image.cxx
@@ -0,0 +1,156 @@
+//
+// "$Id$"
+//
+// Fl_PNG_Image routines.
+//
+// Copyright 1997-2005 by Easy Software Products.
+// Image support donated by Matthias Melcher, Copyright 2000.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_PNG_Image::Fl_PNG_Image() - Load a PNG image file.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_PNG_Image.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <stdlib.h>
+
+extern "C"
+{
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+#  include <zlib.h>
+#  ifdef HAVE_PNG_H
+#    include <png.h>
+#  else
+#    include <libpng/png.h>
+#  endif // HAVE_PNG_H
+#endif // HAVE_LIBPNG && HAVE_LIBZ
+}
+
+
+//
+// 'Fl_PNG_Image::Fl_PNG_Image()' - Load a PNG image file.
+//
+
+Fl_PNG_Image::Fl_PNG_Image(const char *png) // I - File to read
+  : Fl_RGB_Image(0,0,0) {
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+  int		i;			// Looping var
+  FILE		*fp;			// File pointer
+  int		channels;		// Number of color channels
+  png_structp	pp;			// PNG read pointer
+  png_infop	info;			// PNG info pointers
+  png_bytep	*rows;			// PNG row pointers
+
+
+  // Open the PNG file...
+  if ((fp = fopen(png, "rb")) == NULL) return;
+
+  // Setup the PNG data structures...
+  pp   = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+  info = png_create_info_struct(pp);
+
+  if (setjmp(pp->jmpbuf))
+  {
+    Fl::warning("PNG file \"%s\" contains errors!\n", png);
+    return;
+  }
+
+  // Initialize the PNG read "engine"...
+  png_init_io(pp, fp);
+
+  // Get the image dimensions and convert to grayscale or RGB...
+  png_read_info(pp, info);
+
+  if (info->color_type == PNG_COLOR_TYPE_PALETTE)
+    png_set_expand(pp);
+
+  if (info->color_type & PNG_COLOR_MASK_COLOR)
+    channels = 3;
+  else
+    channels = 1;
+
+  if ((info->color_type & PNG_COLOR_MASK_ALPHA) || info->num_trans)
+    channels ++;
+
+  w((int)(info->width));
+  h((int)(info->height));
+  d(channels);
+
+  if (info->bit_depth < 8)
+  {
+    png_set_packing(pp);
+    png_set_expand(pp);
+  }
+  else if (info->bit_depth == 16)
+    png_set_strip_16(pp);
+
+#  if defined(HAVE_PNG_GET_VALID) && defined(HAVE_PNG_SET_TRNS_TO_ALPHA)
+  // Handle transparency...
+  if (png_get_valid(pp, info, PNG_INFO_tRNS))
+    png_set_tRNS_to_alpha(pp);
+#  endif // HAVE_PNG_GET_VALID && HAVE_PNG_SET_TRNS_TO_ALPHA
+
+  array = new uchar[w() * h() * d()];
+  alloc_array = 1;
+
+  // Allocate pointers...
+  rows = new png_bytep[h()];
+
+  for (i = 0; i < h(); i ++)
+    rows[i] = (png_bytep)(array + i * w() * d());
+
+  // Read the image, handling interlacing as needed...
+  for (i = png_set_interlace_handling(pp); i > 0; i --)
+    png_read_rows(pp, rows, NULL, h());
+
+#ifdef WIN32
+  // Some Windows graphics drivers don't honor transparency when RGB == white
+  if (channels == 4) {
+    // Convert RGB to 0 when alpha == 0...
+    uchar *ptr = (uchar *)array;
+    for (i = w() * h(); i > 0; i --, ptr += 4)
+      if (!ptr[3]) ptr[0] = ptr[1] = ptr[2] = 0;
+  }
+#endif // WIN32
+
+  // Free memory and return...
+  delete[] rows;
+
+  png_read_end(pp, info);
+  png_destroy_read_struct(&pp, &info, NULL);
+
+  fclose(fp);
+#endif // HAVE_LIBPNG && HAVE_LIBZ
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_PNM_Image.cxx b/Utilities/FLTK/src/Fl_PNM_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fa5b32b626e1fd47d15faedd4ec0ae05e2c5fcfc
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_PNM_Image.cxx
@@ -0,0 +1,182 @@
+//
+// "$Id$"
+//
+// Fl_PNM_Image routines.
+//
+// Copyright 1997-2005 by Easy Software Products.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_PNM_Image::Fl_PNM_Image() - Load a PNM image...
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_PNM_Image.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+
+//
+// 'Fl_PNM_Image::Fl_PNM_Image()' - Load a PNM image...
+//
+
+Fl_PNM_Image::Fl_PNM_Image(const char *name)	// I - File to read
+  : Fl_RGB_Image(0,0,0) {
+  FILE		*fp;		// File pointer
+  int		x, y;		// Looping vars
+  char		line[1024],	// Input line
+		*lineptr;	// Pointer in line
+  uchar		*ptr,		// Pointer to pixel values
+		byte,		// Byte from file
+		bit;		// Bit in pixel
+  int		format,		// Format of PNM file
+		val,		// Pixel value
+		maxval;		// Maximum pixel value
+
+
+  if ((fp = fopen(name, "rb")) == NULL) return;
+
+  //
+  // Read the file header in the format:
+  //
+  //   Pformat
+  //   # comment1
+  //   # comment2
+  //   ...
+  //   # commentN
+  //   width
+  //   height
+  //   max sample
+  //
+
+  lineptr = fgets(line, sizeof(line), fp);
+  if (!lineptr) {
+    fclose(fp);
+    Fl::error("Early end-of-file in PNM file \"%s\"!", name);
+    return;
+  }
+
+  lineptr ++;
+
+  format = atoi(lineptr);
+  while (isdigit(*lineptr)) lineptr ++;
+
+  if (format == 7) lineptr = (char *)"";
+
+  while (lineptr != NULL && w() == 0) {
+    if (*lineptr == '\0' || *lineptr == '#') {
+      lineptr = fgets(line, sizeof(line), fp);
+    } else if (isdigit(*lineptr)) {
+      w(strtol(lineptr, &lineptr, 10));
+    } else lineptr ++;
+  }
+
+  while (lineptr != NULL && h() == 0) {
+    if (*lineptr == '\0' || *lineptr == '#') {
+      lineptr = fgets(line, sizeof(line), fp);
+    } else if (isdigit(*lineptr)) {
+      h(strtol(lineptr, &lineptr, 10));
+    } else lineptr ++;
+  }
+
+  if (format != 1 && format != 4) {
+    maxval = 0;
+
+    while (lineptr != NULL && maxval == 0) {
+      if (*lineptr == '\0' || *lineptr == '#') {
+	lineptr = fgets(line, sizeof(line), fp);
+      } else if (isdigit(*lineptr)) {
+	maxval = strtol(lineptr, &lineptr, 10);
+      } else lineptr ++;
+    }
+  } else maxval = 1;
+
+  // Allocate memory...
+  if (format == 1 || format == 2 || format == 4 || format == 5) d(1);
+  else d(3);
+
+//  printf("%s = %dx%dx%d\n", name, w(), h(), d());
+
+  array       = new uchar[w() * h() * d()];
+  alloc_array = 1;
+
+  // Read the image file...
+  for (y = 0; y < h(); y ++) {
+    ptr = (uchar *)array + y * w() * d();
+
+    switch (format) {
+      case 1 :
+      case 2 :
+          for (x = w(); x > 0; x --)
+            if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
+          break;
+
+      case 3 :
+          for (x = w(); x > 0; x --) {
+            if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
+            if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
+            if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
+          }
+          break;
+
+      case 4 :
+          for (x = w(), byte = (uchar)getc(fp), bit = 128; x > 0; x --) {
+	    if (byte & bit) *ptr++ = 255;
+	    else *ptr++ = 0;
+
+            if (bit > 1) bit >>= 1;
+            else {
+              bit  = 128;
+              byte = (uchar)getc(fp);
+            }
+          }
+          break;
+
+      case 5 :
+      case 6 :
+          fread(ptr, w(), d(), fp);
+          break;
+
+      case 7 : /* XV 3:3:2 thumbnail format */
+          for (x = w(); x > 0; x --) {
+	    byte = (uchar)getc(fp);
+
+	    *ptr++ = (uchar)(255 * ((byte >> 5) & 7) / 7);
+	    *ptr++ = (uchar)(255 * ((byte >> 2) & 7) / 7);
+	    *ptr++ = (uchar)(255 * (byte & 3) / 3);
+	  }
+          break;
+    }
+  }
+
+  fclose(fp);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Pack.cxx b/Utilities/FLTK/src/Fl_Pack.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e82fd19a11f5812ea0231de8bb4a616dde74c848
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Pack.cxx
@@ -0,0 +1,147 @@
+//
+// "$Id$"
+//
+// Packing widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Based on code by Curtis Edwards
+// Group that compresses all it's children together and resizes to surround
+// them on each redraw (only if box() is zero)
+// Bugs: ?
+
+#include <FL/Fl.H>
+#include <FL/Fl_Pack.H>
+#include <FL/fl_draw.H>
+
+Fl_Pack::Fl_Pack(int X, int Y, int W, int H,const char *l)
+: Fl_Group(X, Y, W, H, l) {
+  resizable(0);
+  spacing_ = 0;
+  // type(VERTICAL); // already set like this
+}
+
+void Fl_Pack::draw() {
+  int tx = x()+Fl::box_dx(box());
+  int ty = y()+Fl::box_dy(box());
+  int tw = w()-Fl::box_dw(box());
+  int th = h()-Fl::box_dh(box());
+  int rw, rh;
+  int current_position = (horizontal() ? tx : ty) + spacing_ / 2;
+  int maximum_position = current_position;
+  uchar d = damage();
+  Fl_Widget*const* a = array();
+  if (horizontal()) {
+    rw = -spacing_;
+    rh = th;
+
+    for (int i = children(); i--;)
+      if (child(i)->visible()) {
+	if (child(i) != this->resizable()) rw += child(i)->w();
+	rw += spacing_;
+      }
+  } else {
+    rw = tw;
+    rh = -spacing_;
+
+    for (int i = children(); i--;)
+      if (child(i)->visible()) {
+	if (child(i) != this->resizable()) rh += child(i)->h();
+	rh += spacing_;
+      }
+  }
+  for (int i = children(); i--;) {
+    Fl_Widget* o = *a++;
+    if (o->visible()) {
+      int X,Y,W,H;
+      if (horizontal()) {
+        X = current_position;
+        W = o->w();
+        Y = ty;
+        H = th;
+      } else {
+        X = tx;
+        W = tw;
+        Y = current_position;
+        H = o->h();
+      }
+      // Last child, if resizable, takes all remaining room
+      if(i == 0 && o == this->resizable()) {
+       if(horizontal())
+         W = tw - rw;
+       else
+         H = th - rh;
+      }
+      if (spacing_ && current_position>maximum_position && box() &&
+  	  (X != o->x() || Y != o->y() || d&FL_DAMAGE_ALL)) {
+        fl_color(color());
+        if (horizontal())
+	  fl_rectf(maximum_position, ty, spacing_, th);
+        else
+	  fl_rectf(tx, maximum_position, tw, spacing_);
+      }
+      if (X != o->x() || Y != o->y() || W != o->w() || H != o->h()) {
+        o->resize(X,Y,W,H);
+        o->clear_damage(FL_DAMAGE_ALL);
+      }
+      if (d&FL_DAMAGE_ALL) {
+        draw_child(*o);
+        draw_outside_label(*o);
+      } else update_child(*o);
+      // child's draw() can change it's size, so use new size:
+      current_position += (horizontal() ? o->w() : o->h());
+      if (current_position > maximum_position)
+        maximum_position = current_position;
+      current_position += spacing_;
+    }
+  }
+
+  if (horizontal()) {
+    if (maximum_position < tx+tw && box()) {
+      fl_color(color());
+      fl_rectf(maximum_position, ty, tx+tw-maximum_position, th);
+    }
+    tw = maximum_position-tx;
+  } else {
+    if (maximum_position < ty+th && box()) {
+      fl_color(color());
+      fl_rectf(tx, maximum_position, tw, ty+th-maximum_position);
+    }
+    th = maximum_position-ty;
+  }
+
+  tw += Fl::box_dw(box()); if (tw <= 0) tw = 1;
+  th += Fl::box_dh(box()); if (th <= 0) th = 1;
+  if (tw != w() || th != h()) {
+    Fl_Widget::resize(x(),y(),tw,th);
+    d = FL_DAMAGE_ALL;
+  }
+  if (d&FL_DAMAGE_ALL) {
+    draw_box();
+    draw_label();
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Pixmap.cxx b/Utilities/FLTK/src/Fl_Pixmap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a3fad728a65d662a6397ac88959a9cfbc8d27a07
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Pixmap.cxx
@@ -0,0 +1,495 @@
+//
+// "$Id$"
+//
+// Pixmap drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Draws X pixmap data, keeping it stashed in a server pixmap so it
+// redraws fast.
+
+// See fl_draw_pixmap.cxx for code used to get the actual data into pixmap.
+// Implemented without using the xpm library (which I can't use because
+// it interferes with the color cube used by fl_draw_image).
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Pixmap.H>
+
+#include <stdio.h>
+#include "flstring.h"
+#include <ctype.h>
+
+#ifdef WIN32
+extern void fl_release_dc(HWND, HDC);      // located in Fl_win32.cxx
+#endif
+
+#ifdef __APPLE_QUARTZ__
+extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h);
+#endif
+
+extern uchar **fl_mask_bitmap; // used by fl_draw_pixmap.cxx to store mask
+void fl_restore_clip(); // in fl_rect.cxx
+
+void Fl_Pixmap::measure() {
+  int W, H;
+
+  // ignore empty or bad pixmap data:
+  if (w()<0 && data()) {
+    fl_measure_pixmap(data(), W, H);
+    w(W); h(H);
+  }
+}
+
+void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+  // ignore empty or bad pixmap data:
+  if (!data()) {
+    draw_empty(XP, YP);
+    return;
+  }
+  if (w()<0) measure();
+  if (WP==-1) {
+    WP = w();
+    HP = h();
+  }
+  if (!w()) {
+    draw_empty(XP, YP);
+    return;
+  }
+  // account for current clip region (faster on Irix):
+  int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
+  cx += X-XP; cy += Y-YP;
+  // clip the box down to the size of image, quit if empty:
+  if (cx < 0) {W += cx; X -= cx; cx = 0;}
+  if (cx+W > w()) W = w()-cx;
+  if (W <= 0) return;
+  if (cy < 0) {H += cy; Y -= cy; cy = 0;}
+  if (cy+H > h()) H = h()-cy;
+  if (H <= 0) return;
+  if (!id) {
+#ifdef __APPLE_QUARTZ__
+    id = fl_create_offscreen_with_alpha(w(), h());
+    fl_begin_offscreen((Fl_Offscreen)id);
+    fl_draw_pixmap(data(), 0, 0, FL_GREEN);
+    fl_end_offscreen();
+#else
+    id = fl_create_offscreen(w(), h());
+    fl_begin_offscreen((Fl_Offscreen)id);
+    uchar *bitmap = 0;
+    fl_mask_bitmap = &bitmap;
+    fl_draw_pixmap(data(), 0, 0, FL_BLACK);
+    fl_mask_bitmap = 0;
+    if (bitmap) {
+      mask = fl_create_bitmask(w(), h(), bitmap);
+      delete[] bitmap;
+    }
+    fl_end_offscreen();
+#endif
+  }
+#ifdef WIN32
+  if (mask) {
+    HDC new_gc = CreateCompatibleDC(fl_gc);
+    int save = SaveDC(new_gc);
+    SelectObject(new_gc, (void*)mask);
+    BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND);
+    SelectObject(new_gc, (void*)id);
+    BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
+    RestoreDC(new_gc,save);
+    DeleteDC(new_gc);
+  } else {
+    fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
+  }
+#elif defined(__APPLE_QD__)
+  if (mask) {
+    Rect src, dst;
+    src.left = cx; src.right = cx+W;
+    src.top = cy; src.bottom = cy+H;
+    dst.left = X; dst.right = X+W;
+    dst.top = Y; dst.bottom = Y+H;
+    RGBColor rgb, oldfg, oldbg;
+    GetForeColor(&oldfg);
+    GetBackColor(&oldbg);
+    rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff;
+    RGBBackColor(&rgb);
+    rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000;
+    RGBForeColor(&rgb);
+    CopyMask(GetPortBitMapForCopyBits((GrafPtr)id),
+	     GetPortBitMapForCopyBits((GrafPtr)mask), 
+	     GetPortBitMapForCopyBits(GetWindowPort(fl_window)),
+             &src, &src, &dst);
+    RGBBackColor(&oldbg);
+    RGBForeColor(&oldfg);
+  } else {
+    fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
+  }
+#elif defined(__APPLE_QUARTZ__)
+  fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
+#else
+  if (mask) {
+    // I can't figure out how to combine a mask with existing region,
+    // so cut the image down to a clipped rectangle:
+    int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H);
+    cx += nx-X; X = nx;
+    cy += ny-Y; Y = ny;
+    // make X use the bitmap as a mask:
+    XSetClipMask(fl_display, fl_gc, mask);
+    int ox = X-cx; if (ox < 0) ox += w();
+    int oy = Y-cy; if (oy < 0) oy += h();
+    XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy);
+  }
+  fl_copy_offscreen(X, Y, W, H, id, cx, cy);
+  if (mask) {
+    // put the old clip region back
+    XSetClipOrigin(fl_display, fl_gc, 0, 0);
+    fl_restore_clip();
+  }
+#endif
+}
+
+Fl_Pixmap::~Fl_Pixmap() {
+  uncache();
+  delete_data();
+}
+
+void Fl_Pixmap::uncache() {
+  if (id) {
+    fl_delete_offscreen((Fl_Offscreen)id);
+    id = 0;
+  }
+
+  if (mask) {
+    fl_delete_bitmask((Fl_Bitmask)mask);
+    mask = 0;
+  }
+}
+
+void Fl_Pixmap::label(Fl_Widget* widget) {
+  widget->image(this);
+}
+
+void Fl_Pixmap::label(Fl_Menu_Item* m) {
+  Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, Fl_Image::measure);
+  m->label(_FL_IMAGE_LABEL, (const char*)this);
+}
+
+void Fl_Pixmap::copy_data() {
+  if (alloc_data) return;
+
+  char		**new_data,	// New data array
+		**new_row;	// Current row in image
+  int		i,		// Looping var
+		ncolors,	// Number of colors in image
+		chars_per_pixel,// Characters per color
+		chars_per_line;	// Characters per line 
+
+  // Figure out how many colors there are, and how big they are...
+  sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+  chars_per_line = chars_per_pixel * w() + 1;
+
+  // Allocate memory for the new array...
+  if (ncolors < 0) new_data = new char *[h() + 2];
+  else new_data = new char *[h() + ncolors + 1];
+
+  new_data[0] = new char[strlen(data()[0]) + 1];
+  strcpy(new_data[0], data()[0]);
+
+  // Copy colors...
+  if (ncolors < 0) {
+    // Copy FLTK colormap values...
+    ncolors = -ncolors;
+    new_row = new_data + 1;
+    *new_row = new char[ncolors * 4];
+    memcpy(*new_row, data()[1], ncolors * 4);
+    ncolors = 1;
+    new_row ++;
+  } else {
+    // Copy standard XPM colormap values...
+    for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) {
+      *new_row = new char[strlen(data()[i + 1]) + 1];
+      strcpy(*new_row, data()[i + 1]);
+    }
+  }
+
+  // Copy image data...
+  for (i = 0; i < h(); i ++, new_row ++) {
+    *new_row = new char[chars_per_line];
+    memcpy(*new_row, data()[i + ncolors + 1], chars_per_line);
+  }
+
+  // Update pointers...
+  data((const char **)new_data, h() + ncolors + 1);
+  alloc_data = 1;  
+}
+
+Fl_Image *Fl_Pixmap::copy(int W, int H) {
+  Fl_Pixmap	*new_image;	// New pixmap
+
+  // Optimize the simple copy where the width and height are the same...
+  if (W == w() && H == h()) {
+    // Make an exact copy of the image and return it...
+    new_image = new Fl_Pixmap(data());
+    new_image->copy_data();
+    return new_image;
+  }
+  if (W <= 0 || H <= 0) return 0;
+
+  // OK, need to resize the image data; allocate memory and 
+  char		**new_data,	// New array for image data
+		**new_row,	// Pointer to row in image data
+		*new_ptr,	// Pointer into new array
+		new_info[255];	// New information line
+  const char	*old_ptr;	// Pointer into old array
+  int		i,		// Looping var
+		c,		// Channel number
+		sy,		// Source coordinate
+		dx, dy,		// Destination coordinates
+		xerr, yerr,	// X & Y errors
+		xmod, ymod,	// X & Y moduli
+		xstep, ystep;	// X & Y step increments
+  int		ncolors,	// Number of colors in image
+		chars_per_pixel,// Characters per color
+		chars_per_line;	// Characters per line 
+
+  // Figure out how many colors there are, and how big they are...
+  sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+  chars_per_line = chars_per_pixel * W + 1;
+
+  sprintf(new_info, "%d %d %d %d", W, H, ncolors, chars_per_pixel);
+
+  // Figure out Bresenheim step/modulus values...
+  xmod   = w() % W;
+  xstep  = (w() / W) * chars_per_pixel;
+  ymod   = h() % H;
+  ystep  = h() / H;
+
+  // Allocate memory for the new array...
+  if (ncolors < 0) new_data = new char *[H + 2];
+  else new_data = new char *[H + ncolors + 1];
+  new_data[0] = new char[strlen(new_info) + 1];
+  strcpy(new_data[0], new_info);
+
+  // Copy colors...
+  if (ncolors < 0) {
+    // Copy FLTK colormap values...
+    ncolors = -ncolors;
+    new_row = new_data + 1;
+    *new_row = new char[ncolors * 4];
+    memcpy(*new_row, data()[1], ncolors * 4);
+    ncolors = 1;
+    new_row ++;
+  } else {
+    // Copy standard XPM colormap values...
+    for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) {
+      *new_row = new char[strlen(data()[i + 1]) + 1];
+      strcpy(*new_row, data()[i + 1]);
+    }
+  }
+
+  // Scale the image using a nearest-neighbor algorithm...
+  for (dy = H, sy = 0, yerr = H; dy > 0; dy --, new_row ++) {
+    *new_row = new char[chars_per_line];
+    new_ptr  = *new_row;
+
+    for (dx = W, xerr = W, old_ptr = data()[sy + ncolors + 1];
+	 dx > 0;
+	 dx --) {
+      for (c = 0; c < chars_per_pixel; c ++) *new_ptr++ = old_ptr[c];
+
+      old_ptr += xstep;
+      xerr    -= xmod;
+
+      if (xerr <= 0) {
+	xerr    += W;
+	old_ptr += chars_per_pixel;
+      }
+    }
+
+    *new_ptr = '\0';
+    sy       += ystep;
+    yerr     -= ymod;
+    if (yerr <= 0) {
+      yerr += H;
+      sy ++;
+    }
+  }
+
+  new_image = new Fl_Pixmap((char*const*)new_data);
+  new_image->alloc_data = 1;
+
+  return new_image;
+}
+
+void Fl_Pixmap::color_average(Fl_Color c, float i) {
+  // Delete any existing pixmap/mask objects...
+  uncache();
+
+  // Allocate memory as needed...
+  copy_data();
+
+  // Get the color to blend with...
+  uchar		r, g, b;
+  unsigned	ia, ir, ig, ib;
+
+  Fl::get_color(c, r, g, b);
+  if (i < 0.0f) i = 0.0f;
+  else if (i > 1.0f) i = 1.0f;
+
+  ia = (unsigned)(256 * i);
+  ir = r * (256 - ia);
+  ig = g * (256 - ia);
+  ib = b * (256 - ia);
+
+  // Update the colormap to do the blend...
+  char		line[255];	// New colormap line
+  int		color,		// Looping var
+		ncolors,	// Number of colors in image
+		chars_per_pixel;// Characters per color
+
+
+  sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+
+  if (ncolors < 0) {
+    // Update FLTK colormap...
+    ncolors = -ncolors;
+    uchar *cmap = (uchar *)(data()[1]);
+    for (color = 0; color < ncolors; color ++, cmap += 4) {
+      cmap[1] = (ia * cmap[1] + ir) >> 8;
+      cmap[2] = (ia * cmap[2] + ig) >> 8;
+      cmap[3] = (ia * cmap[3] + ib) >> 8;
+    }
+  } else {
+    // Update standard XPM colormap...
+    for (color = 0; color < ncolors; color ++) {
+      // look for "c word", or last word if none:
+      const char *p = data()[color + 1] + chars_per_pixel + 1;
+      const char *previous_word = p;
+      for (;;) {
+	while (*p && isspace(*p)) p++;
+	char what = *p++;
+	while (*p && !isspace(*p)) p++;
+	while (*p && isspace(*p)) p++;
+	if (!*p) {p = previous_word; break;}
+	if (what == 'c') break;
+	previous_word = p;
+	while (*p && !isspace(*p)) p++;
+      }
+
+      if (fl_parse_color(p, r, g, b)) {
+        r = (ia * r + ir) >> 8;
+        g = (ia * g + ig) >> 8;
+        b = (ia * b + ib) >> 8;
+
+        if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X",
+	                                 data()[color + 1][0],
+	                                 data()[color + 1][1], r, g, b);
+        else sprintf(line, "%c c #%02X%02X%02X", data()[color + 1][0], r, g, b);
+
+        delete[] (char *)data()[color + 1];
+	((char **)data())[color + 1] = new char[strlen(line) + 1];
+	strcpy((char *)data()[color + 1], line);
+      }
+    }
+  }
+}
+
+void Fl_Pixmap::delete_data() {
+  if (alloc_data) {
+    for (int i = 0; i < count(); i ++) delete[] (char *)data()[i];
+    delete[] (char **)data();
+  }
+}
+
+void Fl_Pixmap::set_data(const char * const * p) {
+  int	height,		// Number of lines in image
+	ncolors;	// Number of colors in image
+
+  if (p) {
+    sscanf(p[0],"%*d%d%d", &height, &ncolors);
+    if (ncolors < 0) data(p, height + 2);
+    else data(p, height + ncolors + 1);
+  }
+}
+
+
+void Fl_Pixmap::desaturate() {
+  // Delete any existing pixmap/mask objects...
+  uncache();
+
+  // Allocate memory as needed...
+  copy_data();
+
+  // Update the colormap to grayscale...
+  char		line[255];	// New colormap line
+  int		i,		// Looping var
+		ncolors,	// Number of colors in image
+		chars_per_pixel;// Characters per color
+  uchar		r, g, b;
+
+  sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+
+  if (ncolors < 0) {
+    // Update FLTK colormap...
+    ncolors = -ncolors;
+    uchar *cmap = (uchar *)(data()[1]);
+    for (i = 0; i < ncolors; i ++, cmap += 4) {
+      g = (uchar)((cmap[1] * 31 + cmap[2] * 61 + cmap[3] * 8) / 100);
+      cmap[1] = cmap[2] = cmap[3] = g;
+    }
+  } else {
+    // Update standard XPM colormap...
+    for (i = 0; i < ncolors; i ++) {
+      // look for "c word", or last word if none:
+      const char *p = data()[i + 1] + chars_per_pixel + 1;
+      const char *previous_word = p;
+      for (;;) {
+	while (*p && isspace(*p)) p++;
+	char what = *p++;
+	while (*p && !isspace(*p)) p++;
+	while (*p && isspace(*p)) p++;
+	if (!*p) {p = previous_word; break;}
+	if (what == 'c') break;
+	previous_word = p;
+	while (*p && !isspace(*p)) p++;
+      }
+
+      if (fl_parse_color(p, r, g, b)) {
+        g = (uchar)((r * 31 + g * 61 + b * 8) / 100);
+
+        if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X", data()[i + 1][0],
+	                                 data()[i + 1][1], g, g, g);
+        else sprintf(line, "%c c #%02X%02X%02X", data()[i + 1][0], g, g, g);
+
+        delete[] (char *)data()[i + 1];
+	((char **)data())[i + 1] = new char[strlen(line) + 1];
+	strcpy((char *)data()[i + 1], line);
+      }
+    }
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Positioner.cxx b/Utilities/FLTK/src/Fl_Positioner.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..205ddffc7ab379e6e0314c2989af3a8b46a4faf8
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Positioner.cxx
@@ -0,0 +1,147 @@
+//
+// "$Id$"
+//
+// Positioner widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// The positioner widget from Forms, gives 2D input
+// Written by: Mark Overmars
+
+#include <FL/Fl.H>
+#include <FL/Fl_Positioner.H>
+#include <FL/fl_draw.H>
+
+static double flinear(double val, double smin, double smax, double gmin, double gmax)
+{
+  if (smin == smax) return gmax;
+  else return gmin + (gmax - gmin) * (val - smin) / (smax - smin);
+}
+
+void Fl_Positioner::draw(int X, int Y, int W, int H) {
+  int x1 = X + 4;
+  int y1 = Y + 4;
+  int w1 = W - 2 * 4;
+  int h1 = H - 2 * 4;
+  int xx = int(flinear(xvalue(), xmin, xmax, x1, x1+w1-1)+.5);
+  int yy = int(flinear(yvalue(), ymin, ymax, y1, y1+h1-1)+.5);
+  draw_box(box(), X, Y, W, H, color());
+  fl_color(selection_color());
+  fl_xyline(x1, yy, x1+w1);
+  fl_yxline(xx, y1, y1+h1);
+}
+
+void Fl_Positioner::draw() {
+  draw(x(), y(), w(), h());
+  draw_label();
+}
+
+int Fl_Positioner::value(double X, double Y) {
+  clear_changed();
+  if (X == xvalue_ && Y == yvalue_) return 0;
+  xvalue_ = X; yvalue_ = Y;
+  redraw();
+  return 1;
+}
+
+int Fl_Positioner::xvalue(double X) {
+  return(value(X, yvalue_));
+}
+
+int Fl_Positioner::yvalue(double Y) {
+  return(value(xvalue_, Y));
+}
+
+int Fl_Positioner::handle(int event, int X, int Y, int W, int H) {
+  switch (event) {
+  case FL_PUSH:
+  case FL_DRAG:
+  case FL_RELEASE: {
+    double x1 = X + 4;
+    double y1 = Y + 4;
+    double w1 = W - 2 * 4;
+    double h1 = H - 2 * 4;
+    double xx = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax);
+    if (xstep_) xx = int(xx/xstep_+0.5) * xstep_;
+    if (xmin < xmax) {
+      if (xx < xmin) xx = xmin;
+      if (xx > xmax) xx = xmax;
+    } else {
+      if (xx > xmin) xx = xmin;
+      if (xx < xmax) xx = xmax;
+    }
+    double yy = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax);
+    if (ystep_) yy = int(yy/ystep_+0.5) * ystep_;
+    if (ymin < ymax) {
+      if (yy < ymin) yy = ymin;
+      if (yy > ymax) yy = ymax;
+    } else {
+      if (yy > ymin) yy = ymin;
+      if (yy < ymax) yy = ymax;
+    }
+    if (value(xx, yy)) set_changed();}
+    if (!(when() & FL_WHEN_CHANGED ||
+	  (when() & FL_WHEN_RELEASE && event == FL_RELEASE))) return 1;
+    if (changed() || when()&FL_WHEN_NOT_CHANGED) {
+      if (event == FL_RELEASE) clear_changed();
+      do_callback();
+    }
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+int Fl_Positioner::handle(int e) {
+  return handle(e, x(), y(), w(), h());
+}
+
+Fl_Positioner::Fl_Positioner(int X, int Y, int W, int H, const char* l)
+: Fl_Widget(X, Y, W, H, l) {
+  box(FL_DOWN_BOX);
+  selection_color(FL_RED);
+  align(FL_ALIGN_BOTTOM);
+  when(FL_WHEN_CHANGED);
+  xmin = ymin = 0;
+  xmax = ymax = 1;
+  xvalue_ = yvalue_ = .5;
+  xstep_ = ystep_ = 0;
+}
+
+void Fl_Positioner::xbounds(double a, double b) {
+  if (a != xmin || b != xmax) {
+    xmin = a; xmax = b;
+    redraw();
+  }
+}
+
+void Fl_Positioner::ybounds(double a, double b) {
+  if (a != ymin || b != ymax) {
+    ymin = a; ymax = b;
+    redraw();
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Preferences.cxx b/Utilities/FLTK/src/Fl_Preferences.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..98321d28a7e3db79aac528d019cff9c3c33deb92
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Preferences.cxx
@@ -0,0 +1,1127 @@
+//
+// "$Id$"
+//
+// Preferences methods for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2002-2005 by Matthias Melcher.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+
+#include <FL/Fl.H>
+#include <FL/Fl_Preferences.H>
+#include <FL/filename.H>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "flstring.h"
+#include <sys/stat.h>
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  include <direct.h>
+#  include <io.h>
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define access _access
+#  define mkdir _mkdir
+#elif defined (__APPLE__)
+#  include <Carbon/Carbon.h>
+#  include <unistd.h>
+#else
+#  include <unistd.h>
+#endif
+
+
+char Fl_Preferences::nameBuffer[128];
+
+
+/**
+ * create the initial preferences base
+ * - root: machine or user preferences
+ * - vendor: unique identification of author or vendor of application
+ *     Must be a valid directory name.
+ * - application: vendor unique application name, i.e. "PreferencesTest"
+ *     multiple preferences files can be created per application.
+ *     Must be a valid file name.
+ * example: Fl_Preferences base( Fl_Preferences::USER, "fltk.org", "test01");
+ */
+Fl_Preferences::Fl_Preferences( Root root, const char *vendor, const char *application )
+{
+  node = new Node( "." );
+  rootNode = new RootNode( this, root, vendor, application );
+}
+
+
+/**
+ * create the initial preferences base
+ * - path: an application-supplied path
+ * example: Fl_Preferences base( "/usr/foo" );
+ */
+Fl_Preferences::Fl_Preferences( const char *path, const char *vendor, const char *application )
+{
+  node = new Node( "." );
+  rootNode = new RootNode( this, path, vendor, application );
+}
+
+
+/**
+ * create a Preferences node in relation to a parent node for reading and writing
+ * - parent: base name for group
+ * - group: group name (can contain '/' seperated group names)
+ * example: Fl_Preferences colors( base, "setup/colors" );
+ */
+Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *key )
+{
+  rootNode = parent.rootNode;
+  node = parent.node->addChild( key );
+}
+
+
+/**
+ * create a Preferences node in relation to a parent node for reading and writing
+ * - parent: base name for group
+ * - group: group name (can contain '/' seperated group names)
+ * example: Fl_Preferences colors( base, "setup/colors" );
+ */
+Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *key )
+{
+  rootNode = parent->rootNode;
+  node = parent->node->addChild( key );
+}
+
+
+/**
+ * destroy individual keys
+ * - destroying the base preferences will flush changes to the prefs file
+ * - after destroying the base, none of the depending preferences must be read or written
+ */
+Fl_Preferences::~Fl_Preferences()
+{
+  if (!node->parent()) delete rootNode;
+  // DO NOT delete nodes! The root node will do that after writing the preferences
+}
+
+
+/**
+ * return the number of groups that are contained within a group
+ * example: int n = base.groups();
+ */
+int Fl_Preferences::groups()
+{
+  return node->nChildren();
+}
+
+
+/**
+ * return the group name of the n'th group
+ * - there is no guaranteed order of group names
+ * - the index must be within the range given by groups()
+ * example: printf( "Group(%d)='%s'\n", ix, base.group(ix) );
+ */
+const char *Fl_Preferences::group( int ix )
+{
+  return node->child( ix );
+}
+
+
+/**
+ * return 1, if a group with this name exists
+ * example: if ( base.groupExists( "setup/colors" ) ) ...
+ */
+char Fl_Preferences::groupExists( const char *key )
+{
+  return node->search( key ) ? 1 : 0 ;
+}
+
+
+/**
+ * delete a group
+ * example: setup.deleteGroup( "colors/buttons" );
+ */
+char Fl_Preferences::deleteGroup( const char *key )
+{
+  Node *nd = node->search( key );
+  if ( nd ) return nd->remove();
+  return 0;
+}
+
+
+/**
+ * return the number of entries (name/value) pairs for a group
+ * example: int n = buttonColor.entries();
+ */
+int Fl_Preferences::entries()
+{
+  return node->nEntry;
+}
+
+
+/**
+ * return the name of an entry
+ * - there is no guaranteed order of entry names
+ * - the index must be within the range given by entries()
+ * example: printf( "Entry(%d)='%s'\n", ix, buttonColor.entry(ix) );
+ */
+const char *Fl_Preferences::entry( int ix )
+{
+  return node->entry[ix].name;
+}
+
+
+/**
+ * return 1, if an entry with this name exists
+ * example: if ( buttonColor.entryExists( "red" ) ) ...
+ */
+char Fl_Preferences::entryExists( const char *key )
+{
+  return node->getEntry( key )>=0 ? 1 : 0 ;
+}
+
+
+/**
+ * remove a single entry (name/value pair)
+ * example: buttonColor.deleteEntry( "red" );
+ */
+char Fl_Preferences::deleteEntry( const char *key )
+{
+  return node->deleteEntry( key );
+}
+
+
+/**
+ * read an entry from the group
+ */
+char Fl_Preferences::get( const char *key, int &value, int defaultValue )
+{
+  const char *v = node->get( key );
+  value = v ? atoi( v ) : defaultValue;
+  return ( v != 0 );
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+char Fl_Preferences::set( const char *key, int value )
+{
+  sprintf( nameBuffer, "%d", value );
+  node->set( key, nameBuffer );
+  return 1;
+}
+
+
+/**
+ * read an entry from the group
+ */
+char Fl_Preferences::get( const char *key, float &value, float defaultValue )
+{
+  const char *v = node->get( key );
+  value = v ? (float)atof( v ) : defaultValue;
+  return ( v != 0 );
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+char Fl_Preferences::set( const char *key, float value )
+{
+  sprintf( nameBuffer, "%g", value );
+  node->set( key, nameBuffer );
+  return 1;
+}
+
+
+/**
+ * read an entry from the group
+ */
+char Fl_Preferences::get( const char *key, double &value, double defaultValue )
+{
+  const char *v = node->get( key );
+  value = v ? atof( v ) : defaultValue;
+  return ( v != 0 );
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+char Fl_Preferences::set( const char *key, double value )
+{
+  sprintf( nameBuffer, "%g", value );
+  node->set( key, nameBuffer );
+  return 1;
+}
+
+
+// remove control sequences from a string
+static char *decodeText( const char *src )
+{
+  int len = 0;
+  const char *s = src;
+  for ( ; *s; s++, len++ )
+  {
+    if ( *s == '\\' )
+      if ( isdigit( s[1] ) ) s+=3; else s+=1;
+  }
+  char *dst = (char*)malloc( len+1 ), *d = dst;
+  for ( s = src; *s; s++ )
+  {
+    char c = *s;
+    if ( c == '\\' )
+    {
+      if ( s[1] == '\\' ) { *d++ = c; s++; }
+      else if ( s[1] == 'n' ) { *d++ = '\n'; s++; }
+      else if ( s[1] == 'r' ) { *d++ = '\r'; s++; }
+      else if ( isdigit( s[1] ) ) { *d++ = ((s[1]-'0')<<6) + ((s[2]-'0')<<3) + (s[3]-'0'); s+=3; }
+      else s++; // error
+    }
+    else
+      *d++ = c;
+  }
+  *d = 0;
+  return dst;
+}
+
+
+/**
+ * read a text entry from the group
+ * the text will be moved into the given text buffer
+ * text will be clipped to the buffer size
+ */
+char Fl_Preferences::get( const char *key, char *text, const char *defaultValue, int maxSize )
+{
+  const char *v = node->get( key );
+  if ( v && strchr( v, '\\' ) ) {
+    char *w = decodeText( v );
+    strlcpy(text, w, maxSize);
+    free( w );
+    return 1;
+  }
+  if ( !v ) v = defaultValue;
+  if ( v ) strlcpy(text, v, maxSize);
+  else text = 0;
+  return ( v != defaultValue );
+}
+
+
+/**
+ * read a text entry from the group
+ * 'text' will be changed to point to a new text buffer
+ * the text buffer must be deleted with 'free(text)' by the user.
+ */
+char Fl_Preferences::get( const char *key, char *&text, const char *defaultValue )
+{
+  const char *v = node->get( key );
+  if ( v && strchr( v, '\\' ) )
+  {
+    text = decodeText( v );
+    return 1;
+  }    
+  if ( !v ) v = defaultValue;
+  if ( v )
+    text = strdup( v );
+  else
+    text = 0;
+  return ( v != defaultValue );
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+char Fl_Preferences::set( const char *key, const char *text )
+{
+  const char *s = text;
+  int n=0, ns=0;
+  for ( ; *s; s++ ) { n++; if ( *s<32 || *s=='\\' || *s==0x7f ) ns+=4; }
+  if ( ns )
+  {
+    char *buffer = (char*)malloc( n+ns+1 ), *d = buffer;
+    for ( s=text; *s; ) 
+    { 
+      char c = *s;
+      if ( c=='\\' ) { *d++ = '\\'; *d++ = '\\'; s++; }
+      else if ( c=='\n' ) { *d++ = '\\'; *d++ = 'n'; s++; }
+      else if ( c=='\r' ) { *d++ = '\\'; *d++ = 'r'; s++; }
+      else if ( c<32 || c==0x7f ) 
+	{ *d++ = '\\'; *d++ = '0'+((c>>6)&3); *d++ = '0'+((c>>3)&7); *d++ = '0'+(c&7);  s++; }
+      else *d++ = *s++;
+    }
+    *d = 0;
+    node->set( key, buffer );
+    free( buffer );
+  }
+  else
+    node->set( key, text );
+  return 1;
+}
+
+
+// convert a hex string to binary data
+static void *decodeHex( const char *src, int &size )
+{
+  size = strlen( src )/2;
+  unsigned char *data = (unsigned char*)malloc( size ), *d = data;
+  const char *s = src;
+  int i;
+
+  for ( i=size; i>0; i-- )
+  {
+    int v;
+    char x = tolower(*s++);
+    if ( x >= 'a' ) v = x-'a'+10; else v = x-'0';
+    v = v<<4;
+    x = tolower(*s++);
+    if ( x >= 'a' ) v += x-'a'+10; else v += x-'0';
+    *d++ = (uchar)v;
+  }
+
+  return (void*)data;
+}
+
+
+/**
+ * read a binary entry from the group
+ * the data will be moved into the given destination buffer
+ * data will be clipped to the buffer size
+ */
+char Fl_Preferences::get( const char *key, void *data, const void *defaultValue, int defaultSize, int maxSize )
+{
+  const char *v = node->get( key );
+  if ( v )
+  {
+    int dsize;
+    void *w = decodeHex( v, dsize );
+    memmove( data, w, dsize>maxSize?maxSize:dsize );
+    free( w );
+    return 1;
+  }    
+  if ( defaultValue )
+    memmove( data, defaultValue, defaultSize>maxSize?maxSize:defaultSize );
+  return 0;
+}
+
+
+/**
+ * read a binary entry from the group
+ * 'data' will be changed to point to a new data buffer
+ * the data buffer must be deleted with 'free(data)' by the user.
+ */
+char Fl_Preferences::get( const char *key, void *&data, const void *defaultValue, int defaultSize )
+{
+  const char *v = node->get( key );
+  if ( v )
+  {
+    int dsize;
+    data = decodeHex( v, dsize );
+    return 1;
+  }    
+  if ( defaultValue )
+  {
+    data = (void*)malloc( defaultSize );
+    memmove( data, defaultValue, defaultSize );
+  }
+  else
+    data = 0;
+  return 0;
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+char Fl_Preferences::set( const char *key, const void *data, int dsize )
+{
+  char *buffer = (char*)malloc( dsize*2+1 ), *d = buffer;;
+  unsigned char *s = (unsigned char*)data;
+  for ( ; dsize>0; dsize-- )
+  {
+    static char lu[] = "0123456789abcdef";
+    unsigned char v = *s++;
+    *d++ = lu[v>>4];
+    *d++ = lu[v&0xf];
+  }
+  *d = 0;
+  node->set( key, buffer );
+  free( buffer );
+  return 1;
+}
+
+
+/**
+ * return the size of the value part of an entry
+ */
+int Fl_Preferences::size( const char *key )
+{
+  const char *v = node->get( key );
+  return v ? strlen( v ) : 0 ;
+}
+
+/**
+ * creates a path that is related to the preferences file
+ * and that is usable for application data beyond what is covered 
+ * by Fl_Preferences.
+ * - 'getUserdataPath' actually creates the directory
+ * - 'path' must be large enough to receive a complete file path
+ * example:
+ *   Fl_Preferences prefs( USER, "matthiasm.com", "test" );
+ *   char path[FL_PATH_MAX];
+ *   prefs.getUserdataPath( path );
+ * sample returns:
+ *   Win32: c:/Documents and Settings/matt/Application Data/matthiasm.com/test/
+ *   prefs: c:/Documents and Settings/matt/Application Data/matthiasm.com/test.prefs
+ */
+char Fl_Preferences::getUserdataPath( char *path, int pathlen )
+{
+  if ( rootNode )
+    return rootNode->getPath( path, pathlen );
+  return 0;
+}
+
+/**
+ * write all preferences to disk
+ * - this function works only with the base preference group
+ * - this function is rarely used as deleting the base preferences flushes automatically
+ */
+void Fl_Preferences::flush()
+{
+  if ( rootNode && node->dirty() )
+    rootNode->write();
+}
+
+//-----------------------------------------------------------------------------
+// helper class to create dynamic group and entry names on the fly
+//
+
+/**
+ * create a group name or entry name on the fly
+ * - this version creates a simple unsigned integer as an entry name
+ * example:
+ *   int n, i;
+ *   Fl_Preferences prev( appPrefs, "PreviousFiles" );
+ *   prev.get( "n", 0 );
+ *   for ( i=0; i<n; i++ )
+ *     prev.get( Fl_Preferences::Name(i), prevFile[i], "" );
+ */
+Fl_Preferences::Name::Name( unsigned int n )
+{
+  data_ = (char*)malloc(20);
+  sprintf(data_, "%u", n);
+}
+
+/**
+ * create a group name or entry name on the fly
+ * - this version creates entry names as in 'printf'
+ * example:
+ *   int n, i;
+ *   Fl_Preferences prefs( USER, "matthiasm.com", "test" );
+ *   prev.get( "nFiles", 0 );
+ *   for ( i=0; i<n; i++ )
+ *     prev.get( Fl_Preferences::Name( "File%d", i ), prevFile[i], "" );
+ */
+Fl_Preferences::Name::Name( const char *format, ... )
+{
+  data_ = (char*)malloc(1024);
+  va_list args;
+  va_start(args, format);
+  vsnprintf(data_, 1024, format, args);
+  va_end(args);
+}
+
+// delete the name
+Fl_Preferences::Name::~Name()
+{
+  free(data_);
+}
+
+//-----------------------------------------------------------------------------
+// internal methods, do not modify or use as they will change without notice
+//
+
+int Fl_Preferences::Node::lastEntrySet = -1;
+
+// recursively create a path in the file system
+static char makePath( const char *path ) {
+  if (access(path, 0)) {
+    const char *s = strrchr( path, '/' );
+    if ( !s ) return 0;
+    int len = s-path;
+    char *p = (char*)malloc( len+1 );
+    memcpy( p, path, len );
+    p[len] = 0;
+    makePath( p );
+    free( p );
+#if defined(WIN32) && !defined(__CYGWIN__)
+    return ( mkdir( path ) == 0 );
+#else
+    return ( mkdir( path, 0777 ) == 0 );
+#endif // WIN32 && !__CYGWIN__
+  }
+  return 1;
+}
+
+// strip the filename and create a path
+static void makePathForFile( const char *path )
+{
+  const char *s = strrchr( path, '/' );
+  if ( !s ) return;
+  int len = s-path;
+  char *p = (char*)malloc( len+1 );
+  memcpy( p, path, len );
+  p[len] = 0;
+  makePath( p );
+  free( p );
+}
+
+// create the root node
+// - construct the name of the file that will hold our preferences
+Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char *vendor, const char *application )
+{
+  char filename[ FL_PATH_MAX ]; filename[0] = 0;
+#ifdef WIN32
+#  define FLPREFS_RESOURCE	"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
+  int appDataLen = strlen(vendor) + strlen(application) + 8;
+  DWORD type, nn;
+  LONG err;
+  HKEY key;
+
+  switch (root) {
+    case SYSTEM:
+      err = RegOpenKey( HKEY_LOCAL_MACHINE, FLPREFS_RESOURCE, &key );
+      if (err == ERROR_SUCCESS) {
+	nn = FL_PATH_MAX - appDataLen;
+	err = RegQueryValueEx( key, "Common AppData", 0L, &type, (BYTE*)filename, &nn );
+	if ( ( err != ERROR_SUCCESS ) && ( type == REG_SZ ) )
+	  filename[0] = 0;
+        RegCloseKey(key);
+      }
+      break;
+    case USER:
+      err = RegOpenKey( HKEY_CURRENT_USER, FLPREFS_RESOURCE, &key );
+      if (err == ERROR_SUCCESS) {
+	nn = FL_PATH_MAX - appDataLen;
+	err = RegQueryValueEx( key, "AppData", 0L, &type, (BYTE*)filename, &nn );
+	if ( ( err != ERROR_SUCCESS ) && ( type == REG_SZ ) )
+	{
+	  err = RegQueryValueEx( key, "Personal", 0L, &type, (BYTE*)filename, &nn );
+	  if ( ( err != ERROR_SUCCESS ) && ( type == REG_SZ ) )
+	    filename[0] = 0;
+	}
+        RegCloseKey(key);
+      }
+      break;
+  }
+
+  if (!filename[0]) {
+    strcpy(filename, "C:\\FLTK");
+  }
+
+  snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename),
+           "/%s/%s.prefs", vendor, application);
+  for (char *s = filename; *s; s++) if (*s == '\\') *s = '/';
+#elif defined ( __APPLE__ )
+  FSSpec spec = { 0 };
+  FSRef ref;
+  OSErr err = fnfErr;
+  switch (root) {
+    case SYSTEM:
+      err = FindFolder( kLocalDomain, kPreferencesFolderType,
+			1, &spec.vRefNum, &spec.parID );
+      break;
+    case USER:
+      err = FindFolder( kUserDomain, kPreferencesFolderType, 
+			1, &spec.vRefNum, &spec.parID );
+      break;
+  }
+  FSpMakeFSRef( &spec, &ref );
+  FSRefMakePath( &ref, (UInt8*)filename, FL_PATH_MAX );
+  snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename),
+           "/%s/%s.prefs", vendor, application );
+#else
+  const char *e;
+  switch (root) {
+    case USER:
+      if ((e = getenv("HOME")) != NULL) {
+	strlcpy(filename, e, sizeof(filename));
+
+	if (filename[strlen(filename)-1] != '/') {
+	  strlcat(filename, "/.fltk/", sizeof(filename));
+	} else {
+	  strlcat(filename, ".fltk/", sizeof(filename));
+	}
+	break;
+      }
+
+    case SYSTEM:
+      strcpy(filename, "/etc/fltk/");
+      break;
+  }
+
+  snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename),
+           "%s/%s.prefs", vendor, application);
+#endif
+
+  prefs_       = prefs;
+  filename_    = strdup(filename);
+  vendor_      = strdup(vendor);
+  application_ = strdup(application);
+
+  read();
+}
+
+// create the root node
+// - construct the name of the file that will hold our preferences
+Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, const char *path, const char *vendor, const char *application )
+{
+  char filename[ FL_PATH_MAX ]; filename[0] = 0;
+
+  snprintf(filename, sizeof(filename), "%s/%s.prefs", path, application);
+
+  prefs_       = prefs;
+  filename_    = strdup(filename);
+  vendor_      = strdup(vendor);
+  application_ = strdup(application);
+
+  read();
+}
+
+// destroy the root node and all depending nodes
+Fl_Preferences::RootNode::~RootNode()
+{
+  if ( prefs_->node->dirty() )
+    write();
+  if ( filename_ ) 
+    free( filename_ );
+  if ( vendor_ )
+    free( vendor_ );
+  if ( application_ )
+    free( application_ );
+  delete prefs_->node;
+}
+
+// read a preferences file and construct the group tree and with all entry leafs
+int Fl_Preferences::RootNode::read()
+{
+  char buf[1024];
+  FILE *f = fopen( filename_, "rb" );
+  if ( !f ) return 0;
+  fgets( buf, 1024, f );
+  fgets( buf, 1024, f );
+  fgets( buf, 1024, f );
+  Node *nd = prefs_->node;
+  for (;;)
+  {
+    if ( !fgets( buf, 1024, f ) ) break;	// EOF or Error
+    if ( buf[0]=='[' ) // read a new group
+    {
+      int end = strcspn( buf+1, "]\n\r" );
+      buf[ end+1 ] = 0;
+      nd = prefs_->node->find( buf+1 );
+    }
+    else if ( buf[0]=='+' ) // 
+    { // value of previous name/value pair spans multiple lines
+      int end = strcspn( buf+1, "\n\r" );
+      if ( end != 0 ) // if entry is not empty
+      {
+	buf[ end+1 ] = 0;
+	nd->add( buf+1 );
+      }
+    }
+    else // read a name/value pair
+    {
+      int end = strcspn( buf, "\n\r" );
+      if ( end != 0 ) // if entry is not empty
+      {
+	buf[ end ] = 0;
+	nd->set( buf );
+      }
+    }
+  }
+  fclose( f );
+  return 0;
+}
+
+// write the group tree and all entry leafs
+int Fl_Preferences::RootNode::write()
+{
+  makePathForFile(filename_);
+  FILE *f = fopen( filename_, "wb" );
+  if ( !f ) return 1;
+  fprintf( f, "; FLTK preferences file format 1.0\n" );
+  fprintf( f, "; vendor: %s\n", vendor_ );
+  fprintf( f, "; application: %s\n", application_ );
+  prefs_->node->write( f );
+  fclose( f );
+  return 0;
+}
+
+// get the path to the preferences directory
+char Fl_Preferences::RootNode::getPath( char *path, int pathlen )
+{
+  strlcpy( path, filename_, pathlen);
+
+  char *s;
+  for ( s = path; *s; s++ ) if ( *s == '\\' ) *s = '/';
+  s = strrchr( path, '.' );
+  if ( !s ) return 0;
+  *s = 0;
+  char ret = makePath( path );
+  strcpy( s, "/" );
+  return ret;
+}
+
+// create a node that represents a group
+// - path must be a single word, prferable alnum(), dot and underscore only. Space is ok.
+Fl_Preferences::Node::Node( const char *path )
+{
+  if ( path ) path_ = strdup( path ); else path_ = 0;
+  child_ = 0; next_ = 0; parent_ = 0;
+  entry = 0;
+  nEntry = NEntry = 0;
+  dirty_ = 0;
+}
+
+// delete this and all depending nodes
+Fl_Preferences::Node::~Node()
+{
+  Node *nx;
+  for ( Node *nd = child_; nd; nd = nx )
+  {
+    nx = nd->next_;
+    delete nd;
+  }
+  if ( entry )
+  {
+    for ( int i = 0; i < nEntry; i++ )
+    {
+      if ( entry[i].name ) 
+	free( entry[i].name );
+      if ( entry[i].value )
+	free( entry[i].value );
+    }
+    free( entry );
+  }
+  if ( path_ ) 
+    free( path_ );
+}
+
+// recursively check if any entry is dirty (was changed after loading a fresh prefs file)
+char Fl_Preferences::Node::dirty()
+{
+  if ( dirty_ ) return 1;
+  if ( next_ && next_->dirty() ) return 1;
+  if ( child_ && child_->dirty() ) return 1;
+  return 0;
+}
+
+// write this node (recursively from the last neighbor back to this)
+// write all entries
+// write all children
+int Fl_Preferences::Node::write( FILE *f )
+{
+  if ( next_ ) next_->write( f );
+  fprintf( f, "\n[%s]\n\n", path_ );
+  for ( int i = 0; i < nEntry; i++ )
+  {
+    char *src = entry[i].value;
+    if ( src )
+    { // hack it into smaller pieces if needed
+      fprintf( f, "%s:", entry[i].name );
+      int cnt;
+      for ( cnt = 0; cnt < 60; cnt++ )
+	if ( src[cnt]==0 ) break;
+      fwrite( src, cnt, 1, f );
+      fprintf( f, "\n" );
+      src += cnt;
+      for (;*src;)
+      {
+	for ( cnt = 0; cnt < 80; cnt++ )
+	  if ( src[cnt]==0 ) break;
+        fputc( '+', f );
+	fwrite( src, cnt, 1, f );
+        fputc( '\n', f );
+	src += cnt;
+      }
+    }
+    else
+      fprintf( f, "%s\n", entry[i].name );
+  }
+  if ( child_ ) child_->write( f );
+  dirty_ = 0;
+  return 0;
+}
+
+// set the parent node and create the full path
+void Fl_Preferences::Node::setParent( Node *pn )
+{
+  parent_ = pn;
+  next_ = pn->child_;
+  pn->child_ = this;
+  sprintf( nameBuffer, "%s/%s", pn->path_, path_ );
+  free( path_ );
+  path_ = strdup( nameBuffer );
+}
+
+// add a child to this node and set its path (try to find it first...)
+Fl_Preferences::Node *Fl_Preferences::Node::addChild( const char *path )
+{
+  sprintf( nameBuffer, "%s/%s", path_, path );
+  char *name = strdup( nameBuffer );
+  Node *nd = find( name );
+  free( name );
+  dirty_ = 1;
+  return nd;
+}
+
+// create and set, or change an entry within this node
+void Fl_Preferences::Node::set( const char *name, const char *value )
+{
+  for ( int i=0; i<nEntry; i++ )
+  {
+    if ( strcmp( name, entry[i].name ) == 0 )
+    {
+      if ( !value ) return; // annotation
+      if ( strcmp( value, entry[i].value ) != 0 )
+      {
+	if ( entry[i].value )
+	  free( entry[i].value );
+	entry[i].value = strdup( value );
+	dirty_ = 1;
+      }
+      lastEntrySet = i;
+      return;
+    }
+  }
+  if ( NEntry==nEntry )
+  {
+    NEntry = NEntry ? NEntry*2 : 10;
+    entry = (Entry*)realloc( entry, NEntry * sizeof(Entry) );
+  }
+  entry[ nEntry ].name = strdup( name );
+  entry[ nEntry ].value = value?strdup( value ):0;
+  lastEntrySet = nEntry;
+  nEntry++;
+  dirty_ = 1;
+}
+
+// create or set a value (or annotation) from a single line in the file buffer
+void Fl_Preferences::Node::set( const char *line )
+{
+  // hmm. If we assume that we always read this file in the beginning,
+  // we can handle the dirty flag 'quick and dirty'
+  char dirt = dirty_;
+  if ( line[0]==';' || line[0]==0 || line[0]=='#' )
+  {
+    set( line, 0 );
+  }
+  else
+  {
+    const char *c = strchr( line, ':' );
+    if ( c )
+    {
+      strlcpy( nameBuffer, line, c-line+1);
+      set( nameBuffer, c+1 );
+    }
+    else
+      set( line, "" );
+  }
+  dirty_ = dirt;
+}
+
+// add more data to an existing entry
+void Fl_Preferences::Node::add( const char *line )
+{
+  if ( lastEntrySet<0 || lastEntrySet>=nEntry ) return;
+  char *&dst = entry[ lastEntrySet ].value;
+  int a = strlen( dst );
+  int b = strlen( line );
+  dst = (char*)realloc( dst, a+b+1 );
+  memcpy( dst+a, line, b+1 );
+  dirty_ = 1;
+}
+
+// get the value for a name, returns 0 if no such name
+const char *Fl_Preferences::Node::get( const char *name )
+{
+  int i = getEntry( name );
+  return i>=0 ? entry[i].value : 0 ;
+}
+
+// find the index of an entry, returns -1 if no such entry
+int Fl_Preferences::Node::getEntry( const char *name )
+{
+  for ( int i=0; i<nEntry; i++ )
+  {
+    if ( strcmp( name, entry[i].name ) == 0 )
+    {
+      return i;
+    }
+  }
+  return -1;
+}
+
+// remove one entry form this group
+char Fl_Preferences::Node::deleteEntry( const char *name )
+{
+  int ix = getEntry( name );
+  if ( ix == -1 ) return 0;
+  memmove( entry+ix, entry+ix+1, (nEntry-ix-1) * sizeof(Entry) );
+  nEntry--;
+  dirty_ = 1;
+  return 1;
+}
+
+// find a group somewhere in the tree starting here
+// - this method will always return a valid node (except for memory allocation problems)
+// - if the node was not found, 'find' will create the required branch
+Fl_Preferences::Node *Fl_Preferences::Node::find( const char *path )
+{
+  int len = strlen( path_ );
+  if ( strncmp( path, path_, len ) == 0 )
+  {
+    if ( path[ len ] == 0 ) 
+      return this;
+    if ( path[ len ] == '/' )
+    {
+      Node *nd;
+      for ( nd = child_; nd; nd = nd->next_ )
+      {
+	Node *nn = nd->find( path );
+	if ( nn ) return nn;
+      }
+      const char *s = path+len+1;
+      const char *e = strchr( s, '/' );
+      if (e) strlcpy( nameBuffer, s, e-s+1 );
+      else strlcpy( nameBuffer, s, sizeof(nameBuffer));
+      nd = new Node( nameBuffer );
+      nd->setParent( this );
+      return nd->find( path );
+    }
+  }
+  return 0;
+}
+
+// find a group somewhere in the tree starting here
+// caller must not set 'offset' argument
+// - if the node does not exist, 'search' returns NULL
+// - if the pathname is "." (current node) return this node
+// - if the pathname is "./" (root node) return the topmost node
+// - if the pathname starts with "./", start the search at the root node instead
+Fl_Preferences::Node *Fl_Preferences::Node::search( const char *path, int offset )
+{
+
+  if ( offset == 0 )
+  {
+    if ( path[0] == '.' )
+    {
+      if ( path[1] == 0 )
+      {
+	return this; // user was searching for current node
+      }
+      else if ( path[1] == '/' )
+      {
+	Node *nn = this;
+	while ( nn->parent_ ) nn = nn->parent_;
+	if ( path[2]==0 )
+	{ // user is searching for root ( "./" )
+	  return nn;
+	}
+	return nn->search( path+2, 2 ); // do a relative search on the root node
+      }
+    }
+    offset = strlen( path_ ) + 1;
+  }
+  
+  int len = strlen( path_ );
+  if ( len < offset-1 ) return 0;
+  len -= offset;
+  if ( ( len <= 0 ) || ( strncmp( path, path_+offset, len ) == 0 ) )
+  {
+    if ( len > 0 && path[ len ] == 0 ) 
+      return this;
+    if ( len <= 0 || path[ len ] == '/' )
+    {
+      for ( Node *nd = child_; nd; nd = nd->next_ )
+      {
+	Node *nn = nd->search( path, offset );
+	if ( nn ) return nn;
+      }
+      return 0;
+    }
+  }
+  return 0;
+}
+
+// return the number of child nodes (groups)
+int Fl_Preferences::Node::nChildren()
+{
+  int cnt = 0;
+  for ( Node *nd = child_; nd; nd = nd->next_ )
+    cnt++;
+  return cnt;
+}
+
+// return the n'th child node
+const char *Fl_Preferences::Node::child( int ix )
+{
+  Node *nd;
+  for ( nd = child_; nd; nd = nd->next_ )
+  {
+    if ( !ix-- ) break;
+  }
+  if ( nd && nd->path_ )
+  {
+    char *r = strrchr( nd->path_, '/' );
+    return r ? r+1 : nd->path_ ;
+  }
+  return 0L ;
+}
+
+// remove myself from the list and delete me (and all children)
+char Fl_Preferences::Node::remove()
+{
+  Node *nd = 0, *np;
+  if ( parent_ )
+  {
+    nd = parent_->child_; np = 0L;
+    for ( ; nd; np = nd, nd = nd->next_ )
+    {
+      if ( nd == this )
+      {
+	if ( np ) 
+	  np->next_ = nd->next_; 
+	else 
+	  parent_->child_ = nd->next_;
+	break;
+      }
+    }
+    parent_->dirty_ = 1;
+  }
+  delete this;
+  return ( nd != 0 );
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Progress.cxx b/Utilities/FLTK/src/Fl_Progress.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..88a8ad77305c0861705a5f62ff05c8b4bb812987
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Progress.cxx
@@ -0,0 +1,115 @@
+//
+// "$Id$"
+//
+// Progress bar widget routines.
+//
+// Copyright 2000-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_Progress::draw()        - Draw the check button.
+//   Fl_Progress::Fl_Progress() - Construct a Fl_Progress widget.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Progress.H>
+#include <FL/fl_draw.H>
+
+
+//
+// Fl_Progress is a progress bar widget based off Fl_Widget that shows a
+// standard progress bar...
+//
+
+
+//
+// 'Fl_Progress::draw()' - Draw the check button.
+//
+
+void Fl_Progress::draw()
+{
+  int	progress;	// Size of progress bar...
+  int	bx, by, bw, bh;	// Box areas...
+  int	tx, tw;		// Temporary X + width
+
+
+  // Get the box borders...
+  bx = Fl::box_dx(box());
+  by = Fl::box_dy(box());
+  bw = Fl::box_dw(box());
+  bh = Fl::box_dh(box());
+
+  tx = x() + bx;
+  tw = w() - bw;
+
+  // Draw the progress bar...
+  if (maximum_ > minimum_)
+    progress = (int)(tw * (value_ - minimum_) / (maximum_ - minimum_) + 0.5f);
+  else
+    progress = 0;
+
+  // Draw the box and label...
+  if (progress > 0) {
+    Fl_Color c = labelcolor();
+    labelcolor(fl_contrast(labelcolor(), color2()));
+
+    fl_clip(x(), y(), progress + bx, h());
+      draw_box(box(), x(), y(), w(), h(), active_r() ? color2() : fl_inactive(color2()));
+      draw_label(tx, y() + by, tw, h() - bh);
+    fl_pop_clip();
+
+    labelcolor(c);
+
+    fl_clip(tx + progress, y(), w() - progress, h());
+      draw_box(box(), x(), y(), w(), h(), active_r() ? color() : fl_inactive(color()));
+      draw_label(tx, y() + by, tw, h() - bh);
+    fl_pop_clip();
+  } else {
+    draw_box(box(), x(), y(), w(), h(), color());
+    draw_label(tx, y() + by, tw, h() - bh);
+  }
+}
+
+
+//
+// 'Fl_Progress::Fl_Progress()' - Construct a Fl_Progress widget.
+//
+
+Fl_Progress::Fl_Progress(int X, int Y, int W, int H, const char* l)
+: Fl_Widget(X, Y, W, H, l)
+{
+  align(FL_ALIGN_INSIDE);
+  box(FL_DOWN_BOX);
+  color(FL_BACKGROUND2_COLOR, FL_YELLOW);
+  minimum(0.0f);
+  maximum(100.0f);
+  value(0.0f);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Repeat_Button.cxx b/Utilities/FLTK/src/Fl_Repeat_Button.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..638cc4c8146759f73bea8c4522ee45af3577939b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Repeat_Button.cxx
@@ -0,0 +1,68 @@
+//
+// "$Id$"
+//
+// Repeat button widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Repeat_Button.H>
+
+#define INITIALREPEAT .5
+#define REPEAT .1
+
+void Fl_Repeat_Button::repeat_callback(void *v) {
+  Fl_Button *b = (Fl_Button*)v;
+  Fl::add_timeout(REPEAT,repeat_callback,b);
+  b->do_callback();
+}
+
+int Fl_Repeat_Button::handle(int event) {
+  int newval;
+  switch (event) {
+  case FL_HIDE:
+  case FL_DEACTIVATE:
+  case FL_RELEASE:
+    newval = 0; goto J1;
+  case FL_PUSH:
+  case FL_DRAG:
+    if (Fl::visible_focus()) Fl::focus(this);
+    newval = Fl::event_inside(this);
+  J1:
+    if (value(newval)) {
+      if (newval) {
+	Fl::add_timeout(INITIALREPEAT,repeat_callback,this);
+	do_callback();
+      } else {
+	Fl::remove_timeout(repeat_callback,this);
+      }
+    }
+    return 1;
+  default:
+    return Fl_Button::handle(event);
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Return_Button.cxx b/Utilities/FLTK/src/Fl_Return_Button.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d09f622658a140d3ace589c8dc88da435035cc9a
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Return_Button.cxx
@@ -0,0 +1,72 @@
+//
+// "$Id$"
+//
+// Return button widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/fl_draw.H>
+
+int fl_return_arrow(int x, int y, int w, int h) {
+  int size = w; if (h<size) size = h;
+  int d = (size+2)/4; if (d<3) d = 3;
+  int t = (size+9)/12; if (t<1) t = 1;
+  int x0 = x+(w-2*d-2*t-1)/2;
+  int x1 = x0+d;
+  int y0 = y+h/2;
+  fl_color(FL_LIGHT3);
+  fl_line(x0, y0, x1, y0+d);
+  fl_yxline(x1, y0+d, y0+t, x1+d+2*t, y0-d);
+  fl_yxline(x1, y0-t, y0-d);
+  fl_color(fl_gray_ramp(0));
+  fl_line(x0, y0, x1, y0-d);
+  fl_color(FL_DARK3);
+  fl_xyline(x1+1, y0-t, x1+d, y0-d, x1+d+2*t);
+  return 1;
+}
+
+void Fl_Return_Button::draw() {
+  if (type() == FL_HIDDEN_BUTTON) return;
+  draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(),
+	   value() ? selection_color() : color());
+  int W = h();
+  if (w()/3 < W) W = w()/3;
+  fl_return_arrow(x()+w()-W-4, y(), W, h());
+  draw_label(x(), y(), w()-W+4, h());
+  if (Fl::focus() == this) draw_focus();
+}
+
+int Fl_Return_Button::handle(int event) {
+  if (event == FL_SHORTCUT &&
+      (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) {
+    do_callback();
+    return 1;
+  } else
+    return Fl_Button::handle(event);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Roller.cxx b/Utilities/FLTK/src/Fl_Roller.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9a4947ef64dca62f0b556bc1b4bd60f231de8915
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Roller.cxx
@@ -0,0 +1,180 @@
+//
+// "$Id$"
+//
+// Roller widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Rapid-App style knob
+
+#include <FL/Fl.H>
+#include <FL/Fl_Roller.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+
+int Fl_Roller::handle(int event) {
+  static int ipos;
+  int newpos = horizontal() ? Fl::event_x() : Fl::event_y();
+  switch (event) {
+  case FL_PUSH:
+    if (Fl::visible_focus()) {
+      Fl::focus(this);
+      redraw();
+    }
+    handle_push();
+    ipos = newpos;
+    return 1;
+  case FL_DRAG:
+    handle_drag(clamp(round(increment(previous_value(),newpos-ipos))));
+    return 1;
+  case FL_RELEASE:
+    handle_release();
+    return 1;
+  case FL_KEYBOARD :
+    switch (Fl::event_key()) {
+      case FL_Up:
+        if (horizontal()) return 0;
+	handle_drag(clamp(increment(value(),-1)));
+	return 1;
+      case FL_Down:
+        if (horizontal()) return 0;
+	handle_drag(clamp(increment(value(),1)));
+	return 1;
+      case FL_Left:
+        if (!horizontal()) return 0;
+	handle_drag(clamp(increment(value(),-1)));
+	return 1;
+      case FL_Right:
+        if (!horizontal()) return 0;
+	handle_drag(clamp(increment(value(),1)));
+	return 1;
+      default:
+        return 0;
+    }
+    // break not required because of switch...
+  case FL_FOCUS :
+  case FL_UNFOCUS :
+    if (Fl::visible_focus()) {
+      redraw();
+      return 1;
+    } else return 0;
+  case FL_ENTER :
+  case FL_LEAVE :
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+void Fl_Roller::draw() {
+  if (damage()&FL_DAMAGE_ALL) draw_box();
+  int X = x()+Fl::box_dx(box());
+  int Y = y()+Fl::box_dy(box());
+  int W = w()-Fl::box_dw(box())-1;
+  int H = h()-Fl::box_dh(box())-1;
+  if (W<=0 || H <=0) return;
+  int offset = step() ? int(value()/step()) : 0;
+  const double ARC = 1.5; // 1/2 the number of radians visible
+  const double delta = .2; // radians per knurl
+  if (horizontal()) { // horizontal one
+    // draw shaded ends of wheel:
+    int h1 = W/4+1; // distance from end that shading starts
+    fl_color(color()); fl_rectf(X+h1,Y,W-2*h1,H);
+    for (int i=0; h1; i++) {
+      fl_color((Fl_Color)(FL_GRAY-i-1));
+      int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
+      fl_rectf(X+h2,Y,h1-h2,H);
+      fl_rectf(X+W-h1,Y,h1-h2,H);
+      h1 = h2;
+    }
+    if (active_r()) {
+      // draw ridges:
+      double junk;
+      for (double yy = -ARC+modf(offset*sin(ARC)/(W/2)/delta,&junk)*delta;;
+	   yy += delta) {
+	int yy1 = int((sin(yy)/sin(ARC)+1)*W/2);
+	if (yy1 <= 0) continue; else if (yy1 >= W-1) break;
+	fl_color(FL_DARK3); fl_yxline(X+yy1,Y+1,Y+H-1);
+	if (yy < 0) yy1--; else yy1++;
+	fl_color(FL_LIGHT1);fl_yxline(X+yy1,Y+1,Y+H-1);
+      }
+      // draw edges:
+      h1 = W/8+1; // distance from end the color inverts
+      fl_color(FL_DARK2);
+      fl_xyline(X+h1,Y+H-1,X+W-h1);
+      fl_color(FL_DARK3);
+      fl_yxline(X,Y+H,Y,X+h1);
+      fl_xyline(X+W-h1,Y,X+W);
+      fl_color(FL_LIGHT2);
+      fl_xyline(X+h1,Y-1,X+W-h1);
+      fl_yxline(X+W,Y,Y+H,X+W-h1);
+      fl_xyline(X+h1,Y+H,X);
+    }
+  } else { // vertical one
+    // draw shaded ends of wheel:
+    int h1 = H/4+1; // distance from end that shading starts
+    fl_color(color()); fl_rectf(X,Y+h1,W,H-2*h1);
+    for (int i=0; h1; i++) {
+      fl_color((Fl_Color)(FL_GRAY-i-1));
+      int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
+      fl_rectf(X,Y+h2,W,h1-h2);
+      fl_rectf(X,Y+H-h1,W,h1-h2);
+      h1 = h2;
+    }
+    if (active_r()) {
+      // draw ridges:
+      double junk;
+      for (double yy = -ARC+modf(offset*sin(ARC)/(H/2)/delta,&junk)*delta;
+	   ; yy += delta) {
+	int yy1 = int((sin(yy)/sin(ARC)+1)*H/2);
+	if (yy1 <= 0) continue; else if (yy1 >= H-1) break;
+	fl_color(FL_DARK3); fl_xyline(X+1,Y+yy1,X+W-1);
+	if (yy < 0) yy1--; else yy1++;
+	fl_color(FL_LIGHT1);fl_xyline(X+1,Y+yy1,X+W-1);
+      }
+      // draw edges:
+      h1 = H/8+1; // distance from end the color inverts
+      fl_color(FL_DARK2);
+      fl_yxline(X+W-1,Y+h1,Y+H-h1);
+      fl_color(FL_DARK3);
+      fl_xyline(X+W,Y,X,Y+h1);
+      fl_yxline(X,Y+H-h1,Y+H);
+      fl_color(FL_LIGHT2);
+      fl_yxline(X,Y+h1,Y+H-h1);
+      fl_xyline(X,Y+H,X+W,Y+H-h1);
+      fl_yxline(X+W,Y+h1,Y);
+    }
+  }
+
+  if (Fl::focus() == this) draw_focus(FL_THIN_UP_FRAME, x(), y(), w(), h());
+}
+
+Fl_Roller::Fl_Roller(int X,int Y,int W,int H,const char* L)
+  : Fl_Valuator(X,Y,W,H,L) {
+  box(FL_UP_BOX);
+  step(1,1000);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Round_Button.cxx b/Utilities/FLTK/src/Fl_Round_Button.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7ea65bfd04bec20c700ae916774a2ed422aa6ecb
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Round_Button.cxx
@@ -0,0 +1,44 @@
+//
+// "$Id$"
+//
+// Round button for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// A subclass of Fl_Button that always draws as a round circle.  This
+// circle is smaller than the widget size and can be surrounded by
+// another box type, for compatability with Forms.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Round_Button.H>
+
+Fl_Round_Button::Fl_Round_Button(int X,int Y,int W,int H, const char *l)
+: Fl_Light_Button(X,Y,W,H,l) {
+  box(FL_NO_BOX);
+  down_box(FL_ROUND_DOWN_BOX);
+  selection_color(FL_FOREGROUND_COLOR);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Scroll.cxx b/Utilities/FLTK/src/Fl_Scroll.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..09bf543bf75e2e8d14b9e5b1f529a1b7d641c418
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Scroll.cxx
@@ -0,0 +1,297 @@
+//
+// "$Id$"
+//
+// Scroll widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Tiled_Image.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/fl_draw.H>
+
+// Clear all but the scrollbars...
+void Fl_Scroll::clear() {
+  for (int i=children() - 1; i >= 0; i --) {
+    Fl_Widget* o = child(i);
+    if (o != &hscrollbar && o != &scrollbar) {
+      remove(o);
+      delete o;
+    }
+  }
+}
+
+// Insure the scrollbars are the last children:
+void Fl_Scroll::fix_scrollbar_order() {
+  Fl_Widget** a = (Fl_Widget**)array();
+  if (a[children()-1] != &scrollbar) {
+    int i,j; for (i = j = 0; j < children(); j++)
+      if (a[j] != &hscrollbar && a[j] != &scrollbar) a[i++] = a[j];
+    a[i++] = &hscrollbar;
+    a[i++] = &scrollbar;
+  }
+}
+
+void Fl_Scroll::draw_clip(void* v,int X, int Y, int W, int H) {
+  fl_clip(X,Y,W,H);
+  Fl_Scroll* s = (Fl_Scroll*)v;
+  // erase background as needed...
+  switch (s->box()) {
+    case FL_NO_BOX :
+    case FL_UP_FRAME :
+    case FL_DOWN_FRAME :
+    case FL_THIN_UP_FRAME :
+    case FL_THIN_DOWN_FRAME :
+    case FL_ENGRAVED_FRAME :
+    case FL_EMBOSSED_FRAME :
+    case FL_BORDER_FRAME :
+    case _FL_SHADOW_FRAME :
+    case _FL_ROUNDED_FRAME :
+    case _FL_OVAL_FRAME :
+    case _FL_PLASTIC_UP_FRAME :
+    case _FL_PLASTIC_DOWN_FRAME :
+        if (s->parent() == (Fl_Group *)s->window() && Fl::scheme_bg_) {
+	  Fl::scheme_bg_->draw(X-(X%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w()),
+	                       Y-(Y%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()),
+	                       W+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w(),
+			       H+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h());
+	  break;
+        }
+
+    default :
+	fl_color(s->color());
+	fl_rectf(X,Y,W,H);
+	break;
+  }
+  Fl_Widget*const* a = s->array();
+  for (int i=s->children()-2; i--;) {
+    Fl_Widget& o = **a++;
+    s->draw_child(o);
+    s->draw_outside_label(o);
+  }
+  fl_pop_clip();
+}
+
+void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) {
+  X = x()+Fl::box_dx(box());
+  Y = y()+Fl::box_dy(box());
+  W = w()-Fl::box_dw(box());
+  H = h()-Fl::box_dh(box());
+  if (scrollbar.visible()) {
+    W -= scrollbar.w();
+    if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w();
+  }
+  if (hscrollbar.visible()) {
+    H -= hscrollbar.h();
+    if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h();
+  }
+}
+
+void Fl_Scroll::draw() {
+  fix_scrollbar_order();
+  int X,Y,W,H; bbox(X,Y,W,H);
+
+  uchar d = damage();
+
+  if (d & FL_DAMAGE_ALL) { // full redraw
+    draw_box(box(),x(),y(),w(),h(),color());
+    draw_clip(this, X, Y, W, H);
+  } else {
+    if (d & FL_DAMAGE_SCROLL) {
+      // scroll the contents:
+      fl_scroll(X, Y, W, H, oldx-xposition_, oldy-yposition_, draw_clip, this);
+
+      // Erase the background as needed...
+      Fl_Widget*const* a = array();
+      int L, R, T, B;
+      L = 999999;
+      R = 0;
+      T = 999999;
+      B = 0;
+      for (int i=children()-2; i--; a++) {
+        if ((*a)->x() < L) L = (*a)->x();
+	if (((*a)->x() + (*a)->w()) > R) R = (*a)->x() + (*a)->w();
+        if ((*a)->y() < T) T = (*a)->y();
+	if (((*a)->y() + (*a)->h()) > B) B = (*a)->y() + (*a)->h();
+      }
+      if (L > X) draw_clip(this, X, Y, L - X, H);
+      if (R < (X + W)) draw_clip(this, R, Y, X + W - R, H);
+      if (T > Y) draw_clip(this, X, Y, W, T - Y);
+      if (B < (Y + H)) draw_clip(this, X, B, W, Y + H - B);
+    }
+    if (d & FL_DAMAGE_CHILD) { // draw damaged children
+      fl_clip(X, Y, W, H);
+      Fl_Widget*const* a = array();
+      for (int i=children()-2; i--;) update_child(**a++);
+      fl_pop_clip();
+    }
+  }
+
+  // accumulate bounding box of children:
+  int l = X; int r = X; int t = Y; int b = Y;
+  Fl_Widget*const* a = array();
+  for (int i=children()-2; i--;) {
+    Fl_Object* o = *a++;
+    if (o->x() < l) l = o->x();
+    if (o->y() < t) t = o->y();
+    if (o->x()+o->w() > r) r = o->x()+o->w();
+    if (o->y()+o->h() > b) b = o->y()+o->h();
+  }
+
+  // turn the scrollbars on and off as necessary:
+  // See if children would fit if we had no scrollbars...
+  X = x()+Fl::box_dx(box());
+  Y = y()+Fl::box_dy(box());
+  W = w()-Fl::box_dw(box());
+  H = h()-Fl::box_dh(box());
+  int vneeded = 0;
+  int hneeded = 0;
+  if (type() & VERTICAL) {
+    if ((type() & ALWAYS_ON) || t < Y || b > Y+H) {
+      vneeded = 1;
+      W -= scrollbar.w();
+      if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w();
+    }
+  }
+  if (type() & HORIZONTAL) {
+    if ((type() & ALWAYS_ON) || l < X || r > X+W) {
+      hneeded = 1;
+      H -= hscrollbar.h();
+      if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h();
+      // recheck vertical since we added a horizontal scrollbar
+      if (!vneeded && (type() & VERTICAL)) {
+	if ((type() & ALWAYS_ON) || t < Y || b > Y+H) {
+	  vneeded = 1;
+	  W -= scrollbar.w();
+	  if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w();
+	}
+      }
+    }
+  }
+  // Now that we know what's needed, make it so.
+  if (vneeded && !scrollbar.visible()) {
+    scrollbar.set_visible();
+    d = FL_DAMAGE_ALL;
+  }
+  else if (!vneeded && scrollbar.visible()) {
+    scrollbar.clear_visible();
+    draw_clip(this,
+	      scrollbar.align()&FL_ALIGN_LEFT ? X : X+W-scrollbar.w(),
+	      Y, scrollbar.w(), H);
+    d = FL_DAMAGE_ALL;
+  }
+  if (hneeded && !hscrollbar.visible()) {
+    hscrollbar.set_visible();
+    d = FL_DAMAGE_ALL;
+  }
+  else if (!hneeded && hscrollbar.visible()) {
+    hscrollbar.clear_visible();
+    draw_clip(this,
+	      X, scrollbar.align()&FL_ALIGN_TOP ? Y : Y+H-hscrollbar.h(),
+	      W, hscrollbar.h());
+    d = FL_DAMAGE_ALL;
+  }
+
+  scrollbar.resize(scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w() : X+W,
+		   Y, scrollbar.w(), H);
+  scrollbar.value(oldy = yposition_ = (Y-t), H, 0, b-t);
+
+  hscrollbar.resize(X,
+		    scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H,
+		    W, hscrollbar.h());
+  hscrollbar.value(oldx = xposition_ = (X-l), W, 0, r-l);
+
+  // draw the scrollbars:
+  if (d & FL_DAMAGE_ALL) {
+    draw_child(scrollbar);
+    draw_child(hscrollbar);
+    if (scrollbar.visible() && hscrollbar.visible()) {
+      // fill in the little box in the corner
+      fl_color(color());
+      fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar.w(), hscrollbar.h());
+    }
+  } else {
+    update_child(scrollbar);
+    update_child(hscrollbar);
+  }
+}
+
+void Fl_Scroll::resize(int X, int Y, int W, int H) {
+  fix_scrollbar_order();
+  // move all the children:
+  Fl_Widget*const* a = array();
+  for (int i=children()-2; i--;) {
+    Fl_Object* o = *a++;
+    o->position(o->x()+X-x(), o->y()+Y-y());
+  }
+  Fl_Widget::resize(X,Y,W,H);
+}
+
+void Fl_Scroll::position(int X, int Y) {
+  int dx = xposition_-X;
+  int dy = yposition_-Y;
+  if (!dx && !dy) return;
+  xposition_ = X;
+  yposition_ = Y;
+  Fl_Widget*const* a = array();
+  for (int i=children(); i--;) {
+    Fl_Widget* o = *a++;
+    if (o == &hscrollbar || o == &scrollbar) continue;
+    o->position(o->x()+dx, o->y()+dy);
+  }
+  if (parent() == (Fl_Group *)window() && Fl::scheme_bg_) damage(FL_DAMAGE_ALL);
+  else damage(FL_DAMAGE_SCROLL);
+}
+
+void Fl_Scroll::hscrollbar_cb(Fl_Widget* o, void*) {
+  Fl_Scroll* s = (Fl_Scroll*)(o->parent());
+  s->position(int(((Fl_Scrollbar*)o)->value()), s->yposition());
+}
+
+void Fl_Scroll::scrollbar_cb(Fl_Widget* o, void*) {
+  Fl_Scroll* s = (Fl_Scroll*)(o->parent());
+  s->position(s->xposition(), int(((Fl_Scrollbar*)o)->value()));
+}
+
+#define SLIDER_WIDTH 16
+
+Fl_Scroll::Fl_Scroll(int X,int Y,int W,int H,const char* L)
+  : Fl_Group(X,Y,W,H,L), 
+    scrollbar(X+W-SLIDER_WIDTH,Y,SLIDER_WIDTH,H-SLIDER_WIDTH),
+    hscrollbar(X,Y+H-SLIDER_WIDTH,W-SLIDER_WIDTH,SLIDER_WIDTH) {
+  type(BOTH);
+  xposition_ = 0;
+  yposition_ = 0;
+  hscrollbar.type(FL_HORIZONTAL);
+  hscrollbar.callback(hscrollbar_cb);
+  scrollbar.callback(scrollbar_cb);
+}
+
+int Fl_Scroll::handle(int event) {
+  fix_scrollbar_order();
+  return Fl_Group::handle(event);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Scrollbar.cxx b/Utilities/FLTK/src/Fl_Scrollbar.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..66547b469f242ac93fe4dfbf05999bb1909ff69f
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Scrollbar.cxx
@@ -0,0 +1,257 @@
+//
+// "$Id$"
+//
+// Scroll bar widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Scrollbar.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+
+#define INITIALREPEAT .5
+#define REPEAT .05
+
+void Fl_Scrollbar::increment_cb() {
+  int ls = maximum()>=minimum() ? linesize_ : -linesize_;
+  int i;
+  switch (pushed_) {
+  case 1:
+    i = -ls;
+    break;
+  default:
+    i =  ls;
+    break;
+  case 5:
+    i = -int((maximum()-minimum())*slider_size()/(1.0-slider_size())) + ls;
+    if (i > -ls) i = -ls;
+    break;
+  case 6:
+    i =  int((maximum()-minimum())*slider_size()/(1.0-slider_size())) - ls;
+    if (i < ls) i = ls;
+    break;
+  }
+  handle_drag(clamp(value() + i));
+}
+
+void Fl_Scrollbar::timeout_cb(void* v) {
+  Fl_Scrollbar* s = (Fl_Scrollbar*)v;
+  s->increment_cb();
+  Fl::add_timeout(REPEAT, timeout_cb, s);
+}
+
+int Fl_Scrollbar::handle(int event) {
+  // area of scrollbar:
+  int area;
+  int X=x(); int Y=y(); int W=w(); int H=h();
+
+  // adjust slider area to be inside the arrow buttons:
+  if (horizontal()) {
+    if (W >= 3*H) {X += H; W -= 2*H;}
+  } else {
+    if (H >= 3*W) {Y += W; H -= 2*W;}
+  }
+
+  // which widget part is highlighted?
+  int relx;
+  int ww;
+  if (horizontal()) {
+    relx = Fl::event_x()-X;
+    ww = W;
+  } else {
+    relx = Fl::event_y()-Y;
+    ww = H;
+  }
+  if (relx < 0) area = 1;
+  else if (relx >= ww) area = 2;
+  else {
+    int S = int(slider_size()*ww+.5);
+    int T = (horizontal() ? H : W)/2+1;
+    if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4;
+    if (S < T) S = T;
+    double val =
+      (maximum()-minimum()) ? (value()-minimum())/(maximum()-minimum()) : 0.5;
+    int sliderx;
+    if (val >= 1.0) sliderx = ww-S;
+    else if (val <= 0.0) sliderx = 0;
+    else sliderx = int(val*(ww-S)+.5);
+    if (Fl::event_button() == FL_MIDDLE_MOUSE) area = 8;
+    else if (relx < sliderx) area = 5;
+    else if (relx >= sliderx+S) area = 6;
+    else area = 8;
+  }
+
+  switch (event) {
+  case FL_ENTER:
+  case FL_LEAVE:
+    return 1;
+  case FL_RELEASE:
+      damage(FL_DAMAGE_ALL);
+    if (pushed_) {
+      Fl::remove_timeout(timeout_cb, this);
+      pushed_ = 0;
+    }
+    handle_release();
+    return 1;
+  case FL_PUSH:
+    if (pushed_) return 1;
+    if (area != 8) pushed_ = area;
+    if (pushed_) {
+      handle_push();
+      Fl::add_timeout(INITIALREPEAT, timeout_cb, this);
+      increment_cb();
+      damage(FL_DAMAGE_ALL);
+      return 1;
+    }
+    return Fl_Slider::handle(event, X,Y,W,H);
+  case FL_DRAG:
+    if (pushed_) return 1;
+    return Fl_Slider::handle(event, X,Y,W,H);
+  case FL_MOUSEWHEEL :
+    if (horizontal()) {
+      if (Fl::e_dx==0) return 0;
+      handle_drag(clamp(value() + linesize_ * Fl::e_dx));
+      return 1;
+    } else {
+      if (Fl::e_dy==0) return 0;
+      handle_drag(clamp(value() + linesize_ * Fl::e_dy));
+      return 1;
+    }
+    break;
+  case FL_SHORTCUT:
+  case FL_KEYBOARD: {
+    int v = value();
+    int ls = maximum()>=minimum() ? linesize_ : -linesize_;
+    if (horizontal()) {
+      switch (Fl::event_key()) {
+      case FL_Left:
+	v -= ls;
+	break;
+      case FL_Right:
+	v += ls;
+	break;
+      default:
+	return 0;
+      }
+    } else { // vertical
+      switch (Fl::event_key()) {
+      case FL_Up:
+	v -= ls;
+	break;
+      case FL_Down:
+	v += ls;
+	break;
+      case FL_Page_Up:
+	if (slider_size() >= 1.0) return 0;
+	v -= int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
+	v += ls;
+	break;
+      case FL_Page_Down:
+	if (slider_size() >= 1.0) return 0;
+	v += int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
+	v -= ls;
+	break;
+      case FL_Home:
+	v = int(minimum());
+	break;
+      case FL_End:
+	v = int(maximum());
+	break;
+      default:
+	return 0;
+      }
+    }
+    v = int(clamp(v));
+    if (v != value()) {
+      Fl_Slider::value(v);
+      value_damage();
+      set_changed();
+      do_callback();
+    }
+    return 1;}
+  }
+  return 0;
+}
+
+void Fl_Scrollbar::draw() {
+  if (damage()&FL_DAMAGE_ALL) draw_box();
+  int X = x()+Fl::box_dx(box());
+  int Y = y()+Fl::box_dy(box());
+  int W = w()-Fl::box_dw(box());
+  int H = h()-Fl::box_dh(box());
+  if (horizontal()) {
+    if (W < 3*H) {Fl_Slider::draw(X,Y,W,H); return;}
+    Fl_Slider::draw(X+H,Y,W-2*H,H);
+    if (damage()&FL_DAMAGE_ALL) {
+      draw_box((pushed_==1) ? fl_down(slider()) : slider(),
+	       X, Y, H, H, selection_color());
+      draw_box((pushed_==2) ? fl_down(slider()) : slider(),
+	       X+W-H, Y, H, H, selection_color());
+      if (active_r())
+        fl_color(labelcolor());
+      else
+        fl_color(fl_inactive(labelcolor()));
+      int w1 = (H-4)/3; if (w1 < 1) w1 = 1;
+      int x1 = X+(H-w1-1)/2;
+      int yy1 = Y+(H-2*w1-1)/2;
+      fl_polygon(x1, yy1+w1, x1+w1, yy1+2*w1, x1+w1, yy1);
+      x1 += (W-H);
+      fl_polygon(x1, yy1, x1, yy1+2*w1, x1+w1, yy1+w1);
+    }
+  } else { // vertical
+    if (H < 3*W) {Fl_Slider::draw(X,Y,W,H); return;}
+    Fl_Slider::draw(X,Y+W,W,H-2*W);
+    if (damage()&FL_DAMAGE_ALL) {
+      draw_box((pushed_==1) ? fl_down(slider()) : slider(),
+	       X, Y, W, W, selection_color());
+      draw_box((pushed_==2) ? fl_down(slider()) : slider(),
+	       X, Y+H-W, W, W, selection_color());
+      if (active_r())
+        fl_color(labelcolor());
+      else
+        fl_color(fl_inactive(labelcolor()));
+      int w1 = (W-4)/3; if (w1 < 1) w1 = 1;
+      int x1 = X+(W-2*w1-1)/2;
+      int yy1 = Y+(W-w1-1)/2;
+      fl_polygon(x1, yy1+w1, x1+2*w1, yy1+w1, x1+w1, yy1);
+      yy1 += H-W;
+      fl_polygon(x1, yy1, x1+w1, yy1+w1, x1+2*w1, yy1);
+    }
+  }
+}
+
+Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L)
+  : Fl_Slider(X, Y, W, H, L)
+{
+  box(FL_FLAT_BOX);
+  color(FL_DARK2);
+  slider(FL_UP_BOX);
+  linesize_ = 16;
+  pushed_ = 0;
+  step(1);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Shared_Image.cxx b/Utilities/FLTK/src/Fl_Shared_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b7447ff900f344aa498ba97501fa1997ae9c6577
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Shared_Image.cxx
@@ -0,0 +1,467 @@
+//
+// "$Id$"
+//
+// Shared image code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+#include <FL/Fl.H>
+#include <FL/Fl_Shared_Image.H>
+#include <FL/Fl_XBM_Image.H>
+#include <FL/Fl_XPM_Image.H>
+
+
+//
+// Global class vars...
+//
+
+Fl_Shared_Image **Fl_Shared_Image::images_ = 0;	// Shared images
+int	Fl_Shared_Image::num_images_ = 0;	// Number of shared images
+int	Fl_Shared_Image::alloc_images_ = 0;	// Allocated shared images
+
+Fl_Shared_Handler *Fl_Shared_Image::handlers_ = 0;// Additional format handlers
+int	Fl_Shared_Image::num_handlers_ = 0;	// Number of format handlers
+int	Fl_Shared_Image::alloc_handlers_ = 0;	// Allocated format handlers
+
+
+//
+// Typedef the C API sort function type the only way I know how...
+//
+
+extern "C" {
+  typedef int (*compare_func_t)(const void *, const void *);
+}
+
+
+// Static methods that really should be inline, but some WIN32 compilers
+// can't handle it...
+Fl_Shared_Image **Fl_Shared_Image::images() {
+  return images_;
+}
+
+int Fl_Shared_Image::num_images() {
+  return num_images_;
+}
+
+
+//
+// 'Fl_Shared_Image::compare()' - Compare two shared images...
+//
+
+int
+Fl_Shared_Image::compare(Fl_Shared_Image **i0,		// I - First image
+                         Fl_Shared_Image **i1) {	// I - Second image
+  int i = strcmp((*i0)->name(), (*i1)->name());
+
+  if (i) return i;
+  else if (((*i0)->w() == 0 && (*i1)->original_) ||
+           ((*i1)->w() == 0 && (*i0)->original_)) return 0;
+  else if ((*i0)->w() != (*i1)->w()) return (*i0)->w() - (*i1)->w();
+  else return (*i0)->h() - (*i1)->h();
+}
+
+
+//
+// 'Fl_Shared_Image::Fl_Shared_Image()' - Basic constructor.
+//
+
+Fl_Shared_Image::Fl_Shared_Image() : Fl_Image(0,0,0) {
+  name_        = 0;
+  refcount_    = 1;
+  original_    = 0;
+  image_       = 0;
+  alloc_image_ = 0;
+}
+
+
+//
+// 'Fl_Shared_Image::Fl_Shared_Image()' - Add an image to the image cache.
+//
+
+Fl_Shared_Image::Fl_Shared_Image(const char *n,		// I - Filename
+                                 Fl_Image   *img)	// I - Image
+  : Fl_Image(0,0,0) {
+  name_ = new char[strlen(n) + 1];
+  strcpy((char *)name_, n);
+
+  refcount_    = 1;
+  image_       = img;
+  alloc_image_ = !img;
+  original_    = 1;
+
+  if (!img) reload();
+  else update();
+}
+
+
+//
+// 'Fl_Shared_Image::add()' - Add a shared image to the array.
+//
+
+void
+Fl_Shared_Image::add() {
+  Fl_Shared_Image	**temp;		// New image pointer array...
+
+  if (num_images_ >= alloc_images_) {
+    // Allocate more memory...
+    temp = new Fl_Shared_Image *[alloc_images_ + 32];
+
+    if (alloc_images_) {
+      memcpy(temp, images_, alloc_images_ * sizeof(Fl_Shared_Image *));
+
+      delete[] images_;
+    }
+
+    images_       = temp;
+    alloc_images_ += 32;
+  }
+
+  images_[num_images_] = this;
+  num_images_ ++;
+
+  if (num_images_ > 1) {
+    qsort(images_, num_images_, sizeof(Fl_Shared_Image *),
+          (compare_func_t)compare);
+  }
+}
+
+
+//
+// 'Fl_Shared_Image::update()' - Update the dimensions of the shared images.
+//
+
+void
+Fl_Shared_Image::update() {
+  if (image_) {
+    w(image_->w());
+    h(image_->h());
+    d(image_->d());
+    data(image_->data(), image_->count());
+  }
+}
+
+
+//
+// 'Fl_Shared_Image::~Fl_Shared_Image()' - Destroy a shared image...
+//
+
+Fl_Shared_Image::~Fl_Shared_Image() {
+  if (name_) delete[] (char *)name_;
+  if (alloc_image_) delete image_;
+}
+
+
+//
+// 'Fl_Shared_Image::release()' - Release and possibly destroy a shared image.
+//
+
+void
+Fl_Shared_Image::release() {
+  int	i;	// Looping var...
+
+  refcount_ --;
+  if (refcount_ > 0) return;
+
+  for (i = 0; i < num_images_; i ++)
+    if (images_[i] == this) {
+      num_images_ --;
+
+      if (i < num_images_) {
+        memmove(images_ + i, images_ + i + 1,
+               (num_images_ - i) * sizeof(Fl_Shared_Image *));
+      }
+
+      break;
+    }
+
+  delete this;
+
+  if (num_images_ == 0 && images_) {
+    delete[] images_;
+
+    images_       = 0;
+    alloc_images_ = 0;
+  }
+}
+
+
+//
+// 'Fl_Shared_Image::reload()' - Reload the shared image...
+//
+
+void
+Fl_Shared_Image::reload() {
+  // Load image from disk...
+  int		i;		// Looping var
+  FILE		*fp;		// File pointer
+  uchar		header[64];	// Buffer for auto-detecting files
+  Fl_Image	*img;		// New image
+
+  if (!name_) return;
+
+  if ((fp = fopen(name_, "rb")) != NULL) {
+    fread(header, 1, sizeof(header), fp);
+    fclose(fp);
+  } else {
+    memset(header, 0, sizeof(header));
+  }
+
+  // Load the image as appropriate...
+  if (memcmp(header, "#define", 7) == 0) // XBM file
+    img = new Fl_XBM_Image(name_);
+  else if (memcmp(header, "/* XPM */", 9) == 0) // XPM file
+    img = new Fl_XPM_Image(name_);
+  else {
+    // Not a standard format; try an image handler...
+    for (i = 0, img = 0; i < num_handlers_; i ++) {
+      img = (handlers_[i])(name_, header, sizeof(header));
+
+      if (img) break;
+    }
+  }
+
+  if (img) {
+    if (alloc_image_) delete image_;
+
+    alloc_image_ = 1;
+
+    if ((img->w() != w() && w()) || (img->h() != h() && h())) {
+      // Make sure the reloaded image is the same size as the existing one.
+      Fl_Image *temp = img->copy(w(), h());
+      delete img;
+      image_ = temp;
+    } else {
+      image_ = img;
+    }
+
+    update();
+  }
+}
+
+
+//
+// 'Fl_Shared_Image::copy()' - Copy and resize a shared image...
+//
+
+Fl_Image *
+Fl_Shared_Image::copy(int W, int H) {
+  Fl_Image		*temp_image;	// New image file
+  Fl_Shared_Image	*temp_shared;	// New shared image
+
+  // Make a copy of the image we're sharing...
+  if (!image_) temp_image = 0;
+  else temp_image = image_->copy(W, H);
+
+  // Then make a new shared image...
+  temp_shared = new Fl_Shared_Image();
+
+  temp_shared->name_ = new char[strlen(name_) + 1];
+  strcpy((char *)temp_shared->name_, name_);
+
+  temp_shared->refcount_    = 1;
+  temp_shared->image_       = temp_image;
+  temp_shared->alloc_image_ = 1;
+
+  temp_shared->update();
+
+  return temp_shared;
+}
+
+
+//
+// 'Fl_Shared_Image::color_average()' - Blend colors...
+//
+
+void
+Fl_Shared_Image::color_average(Fl_Color c,	// I - Color to blend with
+                               float    i) {	// I - Blend fraction
+  if (!image_) return;
+
+  image_->color_average(c, i);
+  update();
+}
+
+
+//
+// 'Fl_Shared_Image::desaturate()' - Convert the image to grayscale...
+//
+
+void
+Fl_Shared_Image::desaturate() {
+  if (!image_) return;
+
+  image_->desaturate();
+  update();
+}
+
+
+//
+// 'Fl_Shared_Image::draw()' - Draw a shared image...
+//
+
+void
+Fl_Shared_Image::draw(int X, int Y, int W, int H, int cx, int cy) {
+  if (image_) image_->draw(X, Y, W, H, cx, cy);
+  else Fl_Image::draw(X, Y, W, H, cx, cy);
+}
+
+
+//
+// 'Fl_Shared_Image::uncache()' - Uncache the shared image...
+//
+
+void
+Fl_Shared_Image::uncache()
+{
+  if (image_) image_->uncache();
+}
+
+
+//
+// 'Fl_Shared_Image::find()' - Find a shared image...
+//
+
+Fl_Shared_Image *
+Fl_Shared_Image::find(const char *n, int W, int H) {
+  Fl_Shared_Image	*key,		// Image key
+			**match;	// Matching image
+
+  if (num_images_) {
+    key = new Fl_Shared_Image();
+    key->name_ = new char[strlen(n) + 1];
+    strcpy((char *)key->name_, n);
+    key->w(W);
+    key->h(H);
+
+    match = (Fl_Shared_Image **)bsearch(&key, images_, num_images_,
+                                        sizeof(Fl_Shared_Image *),
+                                        (compare_func_t)compare);
+
+    delete key;
+
+    if (match) {
+      (*match)->refcount_ ++;
+      return *match;
+    }
+  }
+
+  return 0;
+}
+
+
+//
+// 'Fl_Shared_Image::get()' - Get a shared image...
+//
+
+Fl_Shared_Image *
+Fl_Shared_Image::get(const char *n, int W, int H) {
+  Fl_Shared_Image	*temp;		// Image
+
+  if ((temp = find(n, W, H)) != NULL) return temp;
+
+  if ((temp = find(n)) == NULL) {
+    temp = new Fl_Shared_Image(n);
+
+    if (!temp->image_) {
+      delete temp;
+      return NULL;
+    }
+
+    temp->add();
+  }
+
+  if ((temp->w() != W || temp->h() != H) && W && H) {
+    temp = (Fl_Shared_Image *)temp->copy(W, H);
+    temp->add();
+  }
+
+  return temp;
+}
+
+
+//
+// 'Fl_Shared_Image::add_handler()' - Add a shared image handler.
+//
+
+void
+Fl_Shared_Image::add_handler(Fl_Shared_Handler f) {
+  int			i;		// Looping var...
+  Fl_Shared_Handler	*temp;		// New image handler array...
+
+  // First see if we have already added the handler...
+  for (i = 0; i < num_handlers_; i ++) {
+    if (handlers_[i] == f) return;
+  }
+
+  if (num_handlers_ >= alloc_handlers_) {
+    // Allocate more memory...
+    temp = new Fl_Shared_Handler [alloc_handlers_ + 32];
+
+    if (alloc_handlers_) {
+      memcpy(temp, handlers_, alloc_handlers_ * sizeof(Fl_Shared_Handler));
+
+      delete[] handlers_;
+    }
+
+    handlers_       = temp;
+    alloc_handlers_ += 32;
+  }
+
+  handlers_[num_handlers_] = f;
+  num_handlers_ ++;
+}
+
+
+//
+// 'Fl_Shared_Image::remove_handler()' - Remove a shared image handler.
+//
+
+void
+Fl_Shared_Image::remove_handler(Fl_Shared_Handler f) {
+  int	i;				// Looping var...
+
+  // First see if the handler has been added...
+  for (i = 0; i < num_handlers_; i ++) {
+    if (handlers_[i] == f) break;
+  }
+
+  if (i >= num_handlers_) return;
+
+  // OK, remove the handler from the array...
+  num_handlers_ --;
+
+  if (i < num_handlers_) {
+    // Shift later handlers down 1...
+    memmove(handlers_ + i, handlers_ + i + 1,
+           (num_handlers_ - i) * sizeof(Fl_Shared_Handler ));
+  }
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Single_Window.cxx b/Utilities/FLTK/src/Fl_Single_Window.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6392df1c8edb8a57e761b7c1e7f34ad0a3b59a7d
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Single_Window.cxx
@@ -0,0 +1,41 @@
+//
+// "$Id$"
+//
+// Single-buffered window for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//	A window with a single-buffered context
+//
+//	This is provided for systems where the base class is double
+//	buffered.  You can turn it off using this subclass in case
+//	your display looks better without it.
+
+#include <FL/Fl_Single_Window.H>
+
+void Fl_Single_Window::show() {Fl_Window::show();}
+void Fl_Single_Window::flush() {Fl_Window::flush();}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Slider.cxx b/Utilities/FLTK/src/Fl_Slider.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0b58e924f855465fee20e38ee34930f9bae1b8b9
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Slider.cxx
@@ -0,0 +1,295 @@
+//
+// "$Id$"
+//
+// Slider widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Slider.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+
+void Fl_Slider::_Fl_Slider() {
+  slider_size_ = 0;
+  slider_ = 0; // FL_UP_BOX;
+}
+
+Fl_Slider::Fl_Slider(int X, int Y, int W, int H, const char* l)
+: Fl_Valuator(X, Y, W, H, l) {
+  box(FL_DOWN_BOX);
+  _Fl_Slider();
+}
+
+Fl_Slider::Fl_Slider(uchar t, int X, int Y, int W, int H, const char* l)
+  : Fl_Valuator(X, Y, W, H, l) {
+  type(t);
+  box(t==FL_HOR_NICE_SLIDER || t==FL_VERT_NICE_SLIDER ?
+      FL_FLAT_BOX : FL_DOWN_BOX);
+  _Fl_Slider();
+}
+
+void Fl_Slider::slider_size(double v) {
+  if (v <  0) v = 0;
+  if (v > 1) v = 1;
+  if (slider_size_ != float(v)) {
+    slider_size_ = float(v); 
+    damage(FL_DAMAGE_EXPOSE);
+  }
+}
+
+void Fl_Slider::bounds(double a, double b) {
+  if (minimum() != a || maximum() != b) {
+    Fl_Valuator::bounds(a, b); 
+    damage(FL_DAMAGE_EXPOSE);
+  }
+}
+
+int Fl_Slider::scrollvalue(int p, int W, int t, int l) {
+//	p = position, first line displayed
+//	w = window, number of lines displayed
+//	t = top, number of first line
+//	l = length, total number of lines
+  step(1, 1);
+  if (p+W > t+l) l = p+W-t;
+  slider_size(W >= l ? 1.0 : double(W)/double(l));
+  bounds(t, l-W+t);
+  return value(p);
+}
+
+// All slider interaction is done as though the slider ranges from
+// zero to one, and the left (bottom) edge of the slider is at the
+// given position.  Since when the slider is all the way to the
+// right (top) the left (bottom) edge is not all the way over, a
+// position on the widget itself covers a wider range than 0-1,
+// actually it ranges from 0 to 1/(1-size).
+
+void Fl_Slider::draw_bg(int X, int Y, int W, int H) {
+  fl_push_clip(X, Y, W, H);
+  draw_box();
+  fl_pop_clip();
+
+  Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR;
+  if (type() == FL_VERT_NICE_SLIDER) {
+    draw_box(FL_THIN_DOWN_BOX, X+W/2-2, Y, 4, H, black);
+  } else if (type() == FL_HOR_NICE_SLIDER) {
+    draw_box(FL_THIN_DOWN_BOX, X, Y+H/2-2, W, 4, black);
+  }
+}
+
+void Fl_Slider::draw(int X, int Y, int W, int H) {
+
+  double val;
+  if (minimum() == maximum())
+    val = 0.5;
+  else {
+    val = (value()-minimum())/(maximum()-minimum());
+    if (val > 1.0) val = 1.0;
+    else if (val < 0.0) val = 0.0;
+  }
+
+  int ww = (horizontal() ? W : H);
+  int xx, S;
+  if (type()==FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) {
+    S = int(val*ww+.5);
+    if (minimum()>maximum()) {S = ww-S; xx = ww-S;}
+    else xx = 0;
+  } else {
+    S = int(slider_size_*ww+.5);
+    int T = (horizontal() ? H : W)/2+1;
+    if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4;
+    if (S < T) S = T;
+    xx = int(val*(ww-S)+.5);
+  }
+  int xsl, ysl, wsl, hsl;
+  if (horizontal()) {
+    xsl = X+xx;
+    wsl = S;
+    ysl = Y;
+    hsl = H;
+  } else {
+    ysl = Y+xx;
+    hsl = S;
+    xsl = X;
+    wsl = W;
+  }
+
+  draw_bg(X, Y, W, H);
+
+  Fl_Boxtype box1 = slider();
+  if (!box1) {box1 = (Fl_Boxtype)(box()&-2); if (!box1) box1 = FL_UP_BOX;}
+  if (type() == FL_VERT_NICE_SLIDER) {
+    draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY);
+    int d = (hsl-4)/2;
+    draw_box(FL_THIN_DOWN_BOX, xsl+2, ysl+d, wsl-4, hsl-2*d,selection_color());
+  } else if (type() == FL_HOR_NICE_SLIDER) {
+    draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY);
+    int d = (wsl-4)/2;
+    draw_box(FL_THIN_DOWN_BOX, xsl+d, ysl+2, wsl-2*d, hsl-4,selection_color());
+  } else {
+    if (wsl>0 && hsl>0) draw_box(box1, xsl, ysl, wsl, hsl, selection_color());
+  }
+
+  draw_label(xsl, ysl, wsl, hsl);
+  if (Fl::focus() == this) {
+    if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) draw_focus();
+    else draw_focus(box1, xsl, ysl, wsl, hsl);
+  }
+}
+
+void Fl_Slider::draw() {
+  if (damage()&FL_DAMAGE_ALL) draw_box();
+  draw(x()+Fl::box_dx(box()),
+       y()+Fl::box_dy(box()),
+       w()-Fl::box_dw(box()),
+       h()-Fl::box_dh(box()));
+}
+
+int Fl_Slider::handle(int event, int X, int Y, int W, int H) {
+  switch (event) {
+  case FL_PUSH:
+    if (!Fl::event_inside(X, Y, W, H)) return 0;
+    handle_push();
+  case FL_DRAG: {
+
+    double val;
+    if (minimum() == maximum())
+      val = 0.5;
+    else {
+      val = (value()-minimum())/(maximum()-minimum());
+      if (val > 1.0) val = 1.0;
+      else if (val < 0.0) val = 0.0;
+    }
+
+    int ww = (horizontal() ? W : H);
+    int mx = (horizontal() ? Fl::event_x()-X : Fl::event_y()-Y);
+    int S;
+    static int offcenter;
+
+    if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) {
+
+      S = 0;
+      if (event == FL_PUSH) {
+	int xx = int(val*ww+.5);
+	offcenter = mx-xx;
+	if (offcenter < -10 || offcenter > 10) offcenter = 0;
+	else return 1;
+      }
+
+    } else {
+
+      S = int(slider_size_*ww+.5); if (S >= ww) return 0;
+      int T = (horizontal() ? H : W)/2+1;
+      if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4;
+      if (S < T) S = T;
+      if (event == FL_PUSH) {
+	int xx = int(val*(ww-S)+.5);
+	offcenter = mx-xx;
+	if (offcenter < 0) offcenter = 0;
+	else if (offcenter > S) offcenter = S;
+	else return 1;
+      }
+    }
+
+    int xx = mx-offcenter;
+    double v;
+    char tryAgain = 1;
+    while (tryAgain)
+    {
+      tryAgain = 0;
+      if (xx < 0) {
+        xx = 0;
+        offcenter = mx; if (offcenter < 0) offcenter = 0;
+      } else if (xx > (ww-S)) {
+        xx = ww-S;
+        offcenter = mx-xx; if (offcenter > S) offcenter = S;
+      }
+      v = round(xx*(maximum()-minimum())/(ww-S) + minimum());
+      // make sure a click outside the sliderbar moves it:
+      if (event == FL_PUSH && v == value()) {
+        offcenter = S/2;
+        event = FL_DRAG;
+        tryAgain = 1;
+      }
+    }
+    handle_drag(clamp(v));
+    } return 1;
+  case FL_RELEASE:
+    handle_release();
+    return 1;
+  case FL_KEYBOARD :
+    switch (Fl::event_key()) {
+      case FL_Up:
+        if (horizontal()) return 0;
+	handle_drag(clamp(increment(value(),-1)));
+	handle_release();
+	return 1;
+      case FL_Down:
+        if (horizontal()) return 0;
+	handle_drag(clamp(increment(value(),1)));
+	handle_release();
+	return 1;
+      case FL_Left:
+        if (!horizontal()) return 0;
+	handle_drag(clamp(increment(value(),-1)));
+	handle_release();
+	return 1;
+      case FL_Right:
+        if (!horizontal()) return 0;
+	handle_drag(clamp(increment(value(),1)));
+	handle_release();
+	return 1;
+      default:
+        return 0;
+    }
+    // break not required because of switch...
+  case FL_FOCUS :
+  case FL_UNFOCUS :
+    if (Fl::visible_focus()) {
+      redraw();
+      return 1;
+    } else return 0;
+  case FL_ENTER :
+  case FL_LEAVE :
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+int Fl_Slider::handle(int event) {
+  if (event == FL_PUSH && Fl::visible_focus()) {
+    Fl::focus(this);
+    redraw();
+  }
+
+  return handle(event,
+		x()+Fl::box_dx(box()),
+		y()+Fl::box_dy(box()),
+		w()-Fl::box_dw(box()),
+		h()-Fl::box_dh(box()));
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Sys_Menu_Bar.cxx b/Utilities/FLTK/src/Fl_Sys_Menu_Bar.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..002689917570618a0c299ec86e7f6e5f9435830c
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Sys_Menu_Bar.cxx
@@ -0,0 +1,329 @@
+//
+// "$Id$"
+//
+// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/**
+ * This code is a quick hack! It was written as a proof of concept.
+ * It has been tested on the "menubar" sample program and provides
+ * basic functionality. 
+ * 
+ * To use the System Menu Bar, simply replace the main Fl_Menu_Bar
+ * in an application with Fl_Sys_Menu_Bar.
+ *
+ * FLTK features not supported by the Mac System menu
+ *
+ * - no invisible menu items
+ * - no sybolic labels
+ * - embossed labels will be underlined instead
+ * - no font sizes
+ * - Shortcut Characters should be English alphanumeric only, no modifiers yet
+ * - no disable main menus
+ * - changes to menubar in run-time don't update! 
+ *     (disable, etc. - toggle and readio button do!)
+ *
+ * No care was taken to clean up the menu bar after destruction!
+ * ::menu(bar) should only be called once!
+ * Many other calls of the parent class don't work.
+ * Changing the menu items has no effect on the menu bar.
+ */
+
+#if defined(__APPLE__)
+
+#include <FL/x.H>
+#include <FL/Fl.H>
+#include <FL/Fl_Sys_Menu_Bar.H>
+
+#include "flstring.h"
+#include <stdio.h>
+#include <ctype.h>
+
+typedef const Fl_Menu_Item *pFl_Menu_Item;
+
+/**
+ * copy the text of a menuitem into a buffer.
+ * Skip all '&' which would mark the shortcut in FLTK
+ * Skip all Mac control characters ('(', '<', ';', '^', '!' )
+ */
+static void catMenuText( const char *src, char *dst )
+{
+  char c;
+  while ( *dst ) 
+    dst++;
+  if ( *src == '-' ) 
+    src++;
+  while ( ( c = *src++ ) ) 
+  {
+    if ( !strchr( "&(<;^!", c )  )
+      *dst++ = c;
+  }
+  *dst = 0;
+}
+
+/**
+ * append a marker to identify the menu font style
+ * <B, I, U, O, and S
+ */
+static void catMenuFont( const Fl_Menu_Item *m, char *dst )
+{
+  if ( !m->labeltype_ && !m->labelfont_ ) 
+    return;
+  while ( *dst ) 
+    dst++;
+    
+  if ( m->labelfont_ & FL_BOLD )
+    strcat( dst, "<B" );
+  if ( m->labelfont_ & FL_ITALIC )
+    strcat( dst, "<I" );
+  //if ( m->labelfont_ & FL_UNDERLINE )
+  //  strcat( dst, "<U" );
+  
+  if ( m->labeltype_ == FL_EMBOSSED_LABEL )
+      strcat( dst, "<U" );
+  else if ( m->labeltype_ == FL_ENGRAVED_LABEL )
+      strcat( dst, "<O" );
+  else if ( m->labeltype_ == FL_SHADOW_LABEL )
+      strcat( dst, "<S" );
+  //else if ( m->labeltype_ == FL_SYMBOL_LABEL )
+      ; // not supported
+}
+
+/**
+ * append a marker to identify the menu shortcut
+ * <B, I, U, O, and S
+enum {
+  kMenuNoModifiers = 0,
+  kMenuShiftModifier = (1 << 0),
+  kMenuOptionModifier = (1 << 1),
+  kMenuControlModifier = (1 << 2),
+  kMenuNoCommandModifier = (1 << 3)
+}; 
+ */
+static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m )
+{
+  if ( !m->shortcut_ ) 
+    return;
+  if ( m->flags & FL_SUBMENU )
+    return;
+  if ( m->flags & FL_SUBMENU_POINTER )
+    return;
+  char key = m->shortcut_ & 0xff;
+  if ( !isalnum( key ) )
+    return;
+  
+  long macMod = kMenuNoCommandModifier;
+  if ( m->shortcut_ & FL_META ) macMod = kMenuNoModifiers;
+  if ( m->shortcut_ & FL_SHIFT || isupper(key) ) macMod |= kMenuShiftModifier;
+  if ( m->shortcut_ & FL_ALT ) macMod |= kMenuOptionModifier;
+  if ( m->shortcut_ & FL_CTRL ) macMod |= kMenuControlModifier;
+  
+  //SetMenuItemKeyGlyph( mh, miCnt, key );
+  SetItemCmd( mh, miCnt, toupper(key) );
+  SetMenuItemModifiers( mh, miCnt, macMod );
+}
+
+#if 0
+// this function needs to be verified before we compile it back in.
+static void catMenuShortcut( const Fl_Menu_Item *m, char *dst )
+{
+  if ( !m->shortcut_ ) 
+    return;
+  char c = m->shortcut_ & 0xff;
+  if ( !isalnum( c & 0xff ) )
+    return;
+  while ( *dst ) 
+    dst++;
+  if ( m->shortcut_ & FL_CTRL )
+  {
+    sprintf( dst, "/%c", toupper( c ) );
+  }
+  //if ( isalnum( mm->shortcut_ ) && !( mm->flags & FL_SUBMENU ) )
+  //sprintf( buf+strlen(buf), "/%c", mm->shortcut_ );
+}
+#endif
+
+static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m )
+{
+  if ( m->flags & FL_MENU_TOGGLE )
+  {
+    SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 );
+  }
+  else if ( m->flags & FL_MENU_RADIO )
+    SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
+}
+
+static void catMenuFlags( const Fl_Menu_Item *m, char *dst )
+{
+  if ( !m->flags ) 
+    return;
+  while ( *dst ) 
+    dst++;
+  if ( m->flags & FL_MENU_INACTIVE )
+    strcat( dst, "(" );
+}
+
+/**
+ * create a sub menu for a specific menu handle
+ */
+static void createSubMenu( MenuHandle mh, int &cnt, pFl_Menu_Item &mm )
+{
+  char buf[255];
+  int miCnt = 1;
+  while ( mm->text )
+  {
+    MenuHandle smh = 0;
+    buf[1] = 0;
+    catMenuFont( mm, buf+1 );
+    //catMenuShortcut( mm, buf+1 );
+    catMenuText( mm->text, buf+1 );
+    catMenuFlags( mm, buf+1 );
+    if ( mm->flags & (FL_SUBMENU | FL_SUBMENU_POINTER) )
+    {
+      cnt++;
+      smh = NewMenu( cnt, (unsigned char*)"\001 " );
+      sprintf( buf+1+strlen(buf+1), "/\033!%c", cnt );
+    }
+    if ( mm->flags & FL_MENU_DIVIDER )
+      strcat( buf+1, ";-" );
+    buf[0] = strlen( buf+1 );
+    AppendMenu( mh, (unsigned char*)buf );
+    // insert Appearanc manager functions here!
+    setMenuFlags( mh, miCnt, mm );
+    setMenuShortcut( mh, miCnt, mm );
+    SetMenuItemRefCon( mh, miCnt, (UInt32)mm );
+    miCnt++;
+    if ( mm->flags & FL_MENU_DIVIDER )
+      miCnt++;
+    if ( mm->flags & FL_SUBMENU )
+    {
+      createSubMenu( smh, cnt, ++mm );
+    }
+    else if ( mm->flags & FL_SUBMENU_POINTER )
+    {
+      const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
+      createSubMenu( mh, cnt, smm );
+    }
+    mm++;
+  }
+  InsertMenu( mh, -1 );
+}
+ 
+
+/**
+ * create a system menu bar using the given list of menu structs
+ *
+ * \author Matthias Melcher
+ *
+ * @param m list of Fl_Menu_Item
+ */
+void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) 
+{
+  fl_open_display();
+  Fl_Menu_Bar::menu( m );
+  fl_sys_menu_bar = this;
+
+  char buf[255];
+  int cnt = 1; // first menu is no 2. no 1 is the Apple Menu
+
+  const Fl_Menu_Item *mm = m;
+  for (;;)
+  {
+    if ( !mm->text )
+      break;
+    buf[1] = 0;
+    catMenuText( mm->text, buf+1 );
+    buf[0] = strlen( buf+1 );
+    MenuHandle mh = NewMenu( ++cnt, (unsigned char*)buf );
+    if ( mm->flags & FL_SUBMENU )
+      createSubMenu( mh, cnt, ++mm );
+    else if ( mm->flags & FL_SUBMENU_POINTER )
+    {
+      const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
+      createSubMenu( mh, cnt, smm );
+    }
+    
+    InsertMenu( mh, 0 );
+    if ( mm->flags & FL_MENU_INACTIVE ) DisableMenuItem( mh, 0 );
+    mm++;
+  }
+  DrawMenuBar();
+}
+
+/*
+const Fl_Menu_Item* Fl_Sys_Menu_Bar::picked(const Fl_Menu_Item* v) {
+  Fl_menu_Item *ret = Fl_Menu_Bar::picked( v );
+  
+  if ( m->flags & FL_MENU_TOGGLE )
+  {
+    SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 );
+  }
+  
+  return ret;
+}
+*/
+
+void Fl_Sys_Menu_Bar::draw() {
+/* -- nothing to do, system should take care of this
+  draw_box();
+  if (!menu() || !menu()->text) return;
+  const Fl_Menu_Item* m;
+  int X = x()+6;
+  for (m=menu(); m->text; m = m->next()) {
+    int W = m->measure(0,this) + 16;
+    m->draw(X, y(), W, h(), this);
+    X += W;
+  }
+  */
+}
+
+/*
+int Fl_Menu_Bar::handle(int event) {
+  const Fl_Menu_Item* v;
+  if (menu() && menu()->text) switch (event) {
+  case FL_ENTER:
+  case FL_LEAVE:
+    return 1;
+  case FL_PUSH:
+    v = 0;
+  J1:
+    v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1);
+    picked(v);
+    return 1;
+  case FL_SHORTCUT:
+    if (visible_r()) {
+      v = menu()->find_shortcut();
+      if (v && v->submenu()) goto J1;
+    }
+    return test_shortcut() != 0;
+  }
+  return 0;
+}
+*/
+
+#endif /* __APPLE__ */
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Tabs.cxx b/Utilities/FLTK/src/Fl_Tabs.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..59c06b4d591e441c6289daee1bb676457a342a09
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Tabs.cxx
@@ -0,0 +1,353 @@
+//
+// "$Id$"
+//
+// Tab widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This is the "file card tabs" interface to allow you to put lots and lots
+// of buttons and switches in a panel, as popularized by many toolkits.
+
+// Each child widget is a card, and it's label() is printed on the card tab.
+// Clicking the tab makes that card visible.
+
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Tabs.H>
+#include <FL/fl_draw.H>
+
+#define BORDER 2
+#define EXTRASPACE 10
+
+// return the left edges of each tab (plus a fake left edge for a tab
+// past the right-hand one).  These position are actually of the left
+// edge of the slope.  They are either seperated by the correct distance
+// or by EXTRASPACE or by zero.
+// Return value is the index of the selected item.
+
+int Fl_Tabs::tab_positions(int* p, int* wp) {
+  int selected = 0;
+  Fl_Widget*const* a = array();
+  int i;
+  p[0] = Fl::box_dx(box());
+  for (i=0; i<children(); i++) {
+    Fl_Widget* o = *a++;
+    if (o->visible()) selected = i;
+
+    int wt = 0; int ht = 0;
+    o->measure_label(wt,ht);
+
+    wp[i]  = wt+EXTRASPACE;
+    p[i+1] = p[i]+wp[i]+BORDER;
+  }
+  int r = w();
+  if (p[i] <= r) return selected;
+  // uh oh, they are too big:
+  // pack them against right edge:
+  p[i] = r;
+  for (i = children(); i--;) {
+    int l = r-wp[i];
+    if (p[i+1] < l) l = p[i+1];
+    if (p[i] <= l) break;
+    p[i] = l;
+    r -= EXTRASPACE;
+  }
+  // pack them against left edge and truncate width if they still don't fit:
+  for (i = 0; i<children(); i++) {
+    if (p[i] >= i*EXTRASPACE) break;
+    p[i] = i*EXTRASPACE;
+    int W = w()-1-EXTRASPACE*(children()-i) - p[i];
+    if (wp[i] > W) wp[i] = W;
+  }
+  // adjust edges according to visiblity:
+  for (i = children(); i > selected; i--) {
+    p[i] = p[i-1]+wp[i-1];
+  }
+  return selected;
+}
+
+// return space needed for tabs.  Negative to put them on the bottom:
+int Fl_Tabs::tab_height() {
+  int H = h();
+  int H2 = y();
+  Fl_Widget*const* a = array();
+  for (int i=children(); i--;) {
+    Fl_Widget* o = *a++;
+    if (o->y() < y()+H) H = o->y()-y();
+    if (o->y()+o->h() > H2) H2 = o->y()+o->h();
+  }
+  H2 = y()+h()-H2;
+  if (H2 > H) return (H2 <= 0) ? 0 : -H2;
+  else return (H <= 0) ? 0 : H;
+}
+
+// this is used by fluid to pick tabs:
+Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
+  int H = tab_height();
+  if (H < 0) {
+    if (event_y > y()+h() || event_y < y()+h()+H) return 0;
+  } else {
+    if (event_y > y()+H || event_y < y()) return 0;
+  }
+  if (event_x < x()) return 0;
+  int p[128], wp[128];
+  tab_positions(p, wp);
+  for (int i=0; i<children(); i++) {
+    if (event_x < x()+p[i+1]) return child(i);
+  }
+  return 0;
+}
+
+int Fl_Tabs::handle(int event) {
+
+  Fl_Widget *o;
+  int i;
+
+  switch (event) {
+
+  case FL_PUSH: {
+    int H = tab_height();
+    if (H >= 0) {
+      if (Fl::event_y() > y()+H) return Fl_Group::handle(event);
+    } else {
+      if (Fl::event_y() < y()+h()+H) return Fl_Group::handle(event);
+    }}
+  case FL_DRAG:
+  case FL_RELEASE:
+    o = which(Fl::event_x(), Fl::event_y());
+    if (event == FL_RELEASE) {
+      push(0);
+      if (o && value(o)) {
+        set_changed();
+	do_callback();
+      }
+    } else push(o);
+    if (Fl::visible_focus() && event == FL_RELEASE) Fl::focus(this);
+    return 1;
+  case FL_FOCUS:
+  case FL_UNFOCUS:
+    if (!Fl::visible_focus()) return Fl_Group::handle(event);
+    if (Fl::event() == FL_RELEASE ||
+	Fl::event() == FL_SHORTCUT ||
+	Fl::event() == FL_KEYBOARD ||
+	Fl::event() == FL_FOCUS ||
+	Fl::event() == FL_UNFOCUS) {
+      int H = tab_height();
+      if (H >= 0) {
+        H += Fl::box_dy(box());
+	damage(FL_DAMAGE_SCROLL, x(), y(), w(), H);
+      } else {
+        H = Fl::box_dy(box()) - H;
+        damage(FL_DAMAGE_SCROLL, x(), y() + h() - H, w(), H);
+      }
+      if (Fl::event() == FL_FOCUS || Fl::event() == FL_UNFOCUS) return 0;
+      else return 1;
+    } else return Fl_Group::handle(event);
+  case FL_KEYBOARD:
+    switch (Fl::event_key()) {
+      case FL_Left:
+        if (child(0)->visible()) return 0;
+	for (i = 1; i < children(); i ++)
+	  if (child(i)->visible()) break;
+	value(child(i - 1));
+	set_changed();
+	do_callback();
+        return 1;
+      case FL_Right:
+        if (child(children() - 1)->visible()) return 0;
+	for (i = 0; i < children(); i ++)
+	  if (child(i)->visible()) break;
+	value(child(i + 1));
+	set_changed();
+	do_callback();
+        return 1;
+      case FL_Down:
+        redraw();
+        return Fl_Group::handle(FL_FOCUS);
+      default:
+        break;
+    }
+  case FL_SHOW:
+    value(); // update visibilities and fall through
+  default:
+    return Fl_Group::handle(event);
+
+  }
+}
+
+int Fl_Tabs::push(Fl_Widget *o) {
+  if (push_ == o) return 0;
+  if (push_ && !push_->visible() || o && !o->visible())
+    redraw();
+  push_ = o;
+  return 1;
+}
+
+// The value() is the first visible child (or the last child if none
+// are visible) and this also hides any other children.
+// This allows the tabs to be deleted, moved to other groups, and
+// show()/hide() called without it screwing up.
+Fl_Widget* Fl_Tabs::value() {
+  Fl_Widget* v = 0;
+  Fl_Widget*const* a = array();
+  for (int i=children(); i--;) {
+    Fl_Widget* o = *a++;
+    if (v) o->hide();
+    else if (o->visible()) v = o;
+    else if (!i) {o->show(); v = o;}
+  }
+  return v;
+}
+
+// Setting the value hides all other children, and makes this one
+// visible, iff it is really a child:
+int Fl_Tabs::value(Fl_Widget *newvalue) {
+  Fl_Widget*const* a = array();
+  int ret = 0;
+  for (int i=children(); i--;) {
+    Fl_Widget* o = *a++;
+    if (o == newvalue) {
+      if (!o->visible()) ret = 1;
+      o->show();
+    } else {
+      o->hide();
+    }
+  }
+  return ret;
+}
+
+enum {LEFT, RIGHT, SELECTED};
+
+void Fl_Tabs::draw() {
+  Fl_Widget *v = value();
+  int H = tab_height();
+
+  if (damage() & FL_DAMAGE_ALL) { // redraw the entire thing:
+    Fl_Color c = v ? v->color() : color();
+
+    draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), c);
+
+    if (selection_color() != c) {
+      // Draw the top 5 lines of the tab pane in the selection color so
+      // that the user knows which tab is selected...
+      if (H >= 0) fl_push_clip(x(), y() + H, w(), 5);
+      else fl_push_clip(x(), y() + h() - H - 4, w(), 5);
+
+      draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H),
+               selection_color());
+
+      fl_pop_clip();
+    }
+    if (v) draw_child(*v);
+  } else { // redraw the child
+    if (v) update_child(*v);
+  }
+  if (damage() & (FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) {
+    int p[128]; int wp[128];
+    int selected = tab_positions(p,wp);
+    int i;
+    Fl_Widget*const* a = array();
+    for (i=0; i<selected; i++)
+      draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], LEFT);
+    for (i=children()-1; i > selected; i--)
+      draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], RIGHT);
+    if (v) {
+      i = selected;
+      draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], SELECTED);
+    }
+  }
+}
+
+void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) {
+  int sel = (what == SELECTED);
+  int dh = Fl::box_dh(box());
+  int dy = Fl::box_dy(box());
+
+  // compute offsets to make selected tab look bigger
+  int yofs = sel ? 0 : BORDER;
+
+  if ((x2 < x1+W) && what == RIGHT) x1 = x2 - W;
+
+  if (H >= 0) {
+    if (sel) fl_clip(x1, y(), x2 - x1, H + dh - dy);
+    else fl_clip(x1, y(), x2 - x1, H);
+
+    H += dh;
+
+    Fl_Color c = sel ? selection_color() : o->selection_color();
+
+    draw_box(box(), x1, y() + yofs, W, H + 10 - yofs, c);
+
+    // Save the previous label color
+    Fl_Color oc = o->labelcolor();
+
+    // Draw the label using the current color...
+    o->labelcolor(sel ? labelcolor() : o->labelcolor());    
+    o->draw_label(x1, y() + yofs, W, H - yofs, FL_ALIGN_CENTER);
+
+    // Restore the original label color...
+    o->labelcolor(oc);
+
+    if (Fl::focus() == this && o->visible())
+      draw_focus(box(), x1, y(), W, H);
+
+    fl_pop_clip();
+  } else {
+    H = -H;
+
+    if (sel) fl_clip(x1, y() + h() - H - dy, x2 - x1, H + dy);
+    else fl_clip(x1, y() + h() - H, x2 - x1, H);
+
+    H += dh;
+
+    Fl_Color c = sel ? selection_color() : o->selection_color();
+
+    draw_box(box(), x1, y() + h() - H - 10, W, H + 10 - yofs, c);
+
+    // Save the previous label color
+    Fl_Color oc = o->labelcolor();
+
+    // Draw the label using the current color...
+    o->labelcolor(sel ? labelcolor() : o->labelcolor());
+    o->draw_label(x1, y() + h() - H, W, H - yofs, FL_ALIGN_CENTER);
+
+    // Restore the original label color...
+    o->labelcolor(oc);
+
+    if (Fl::focus() == this && o->visible())
+      draw_focus(box(), x1, y() + h() - H, W, H);
+
+    fl_pop_clip();
+  }
+}
+
+Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) :
+  Fl_Group(X,Y,W,H,l)
+{
+  box(FL_THIN_UP_BOX);
+  push_ = 0;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Text_Buffer.cxx b/Utilities/FLTK/src/Fl_Text_Buffer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7495be19ad3692cd3ea39af50e8a37603d7876f5
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Text_Buffer.cxx
@@ -0,0 +1,2524 @@
+//
+// "$Id$"
+//
+// Copyright 2001-2005 by Bill Spitzak and others.
+// Original code Copyright Mark Edel.  Permission to distribute under
+// the LGPL for the FLTK library granted by Mark Edel.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <ctype.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Text_Buffer.H>
+
+
+#define PREFERRED_GAP_SIZE 80
+/* Initial size for the buffer gap (empty space
+in the buffer where text might be inserted
+if the user is typing sequential chars ) */
+
+static void histogramCharacters( const char *string, int length, char hist[ 256 ],
+                                 int init );
+static void subsChars( char *string, int length, char fromChar, char toChar );
+static char chooseNullSubsChar( char hist[ 256 ] );
+static void insertColInLine( const char *line, char *insLine, int column, int insWidth,
+                             int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen,
+                             int *endOffset );
+static void deleteRectFromLine( const char *line, int rectStart, int rectEnd,
+                                int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen,
+                                int *endOffset );
+static void overlayRectInLine( const char *line, char *insLine, int rectStart,
+                               int rectEnd, int tabDist, int useTabs, char nullSubsChar, char *outStr,
+                               int *outLen, int *endOffset );
+
+static void addPadding( char *string, int startIndent, int toIndent,
+                        int tabDist, int useTabs, char nullSubsChar, int *charsAdded );
+static char *copyLine( const char* text, int *lineLen );
+static int countLines( const char *string );
+static int textWidth( const char *text, int tabDist, char nullSubsChar );
+static char *realignTabs( const char *text, int origIndent, int newIndent,
+                          int tabDist, int useTabs, char nullSubsChar, int *newLength );
+static char *expandTabs( const char *text, int startIndent, int tabDist,
+                         char nullSubsChar, int *newLen );
+static char *unexpandTabs( char *text, int startIndent, int tabDist,
+                           char nullSubsChar, int *newLen );
+static int max( int i1, int i2 );
+static int min( int i1, int i2 );
+
+static const char *ControlCodeTable[ 32 ] = {
+  "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
+  "bs", "ht", "nl", "vt", "np", "cr", "so", "si",
+  "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
+  "can", "em", "sub", "esc", "fs", "gs", "rs", "us"};
+
+static char* undobuffer;
+static int undobufferlength;
+static Fl_Text_Buffer* undowidget;
+static int undoat;	// points after insertion
+static int undocut;	// number of characters deleted there
+static int undoinsert;	// number of characters inserted
+static int undoyankcut;	// length of valid contents of buffer, even if undocut=0
+
+static void undobuffersize(int n) {
+  if (n > undobufferlength) {
+    if (undobuffer) {
+      do {undobufferlength *= 2;} while (undobufferlength < n);
+      undobuffer = (char*)realloc(undobuffer, undobufferlength);
+    } else {
+      undobufferlength = n+9;
+      undobuffer = (char*)malloc(undobufferlength);
+    }
+  }
+}
+
+/*
+** Create an empty text buffer of a pre-determined size (use this to
+** avoid unnecessary re-allocation if you know exactly how much the buffer
+** will need to hold
+*/
+Fl_Text_Buffer::Fl_Text_Buffer( int requestedSize ) {
+  mLength = 0;
+  mBuf = (char *)malloc( requestedSize + PREFERRED_GAP_SIZE );
+  mGapStart = 0;
+  mGapEnd = PREFERRED_GAP_SIZE;
+  mTabDist = 8;
+  mUseTabs = 1;
+  mPrimary.mSelected = 0;
+  mPrimary.mRectangular = 0;
+  mPrimary.mStart = mPrimary.mEnd = 0;
+  mSecondary.mSelected = 0;
+  mSecondary.mStart = mSecondary.mEnd = 0;
+  mSecondary.mRectangular = 0;
+  mHighlight.mSelected = 0;
+  mHighlight.mStart = mHighlight.mEnd = 0;
+  mHighlight.mRectangular = 0;
+  mNodifyProcs = NULL;
+  mCbArgs = NULL;
+  mNModifyProcs = 0;
+  mNPredeleteProcs = 0;
+  mPredeleteProcs = NULL;
+  mPredeleteCbArgs = NULL;
+  mCursorPosHint = 0;
+  mNullSubsChar = '\0';
+  mCanUndo = 1;
+#ifdef PURIFY
+{ int i; for (i = mGapStart; i < mGapEnd; i++) mBuf[ i ] = '.'; }
+#endif
+}
+
+/*
+** Free a text buffer
+*/
+Fl_Text_Buffer::~Fl_Text_Buffer() {
+  free( mBuf );
+  if ( mNModifyProcs != 0 ) {
+    delete[] mNodifyProcs;
+    delete[] mCbArgs;
+  }
+  if ( mNPredeleteProcs != 0 ) {
+    delete[] mPredeleteProcs;
+    delete[] mPredeleteCbArgs;
+  }
+}
+
+/*
+** Get the entire contents of a text buffer.  Memory is allocated to contain
+** the returned string, which the caller must free.
+*/
+char * Fl_Text_Buffer::text() {
+  char *t;
+
+  t = (char *)malloc( mLength + 1 );
+  memcpy( t, mBuf, mGapStart );
+  memcpy( &t[ mGapStart ], &mBuf[ mGapEnd ],
+          mLength - mGapStart );
+  t[ mLength ] = '\0';
+  return t;
+}
+
+/*
+** Replace the entire contents of the text buffer
+*/
+void Fl_Text_Buffer::text( const char *t ) {
+  int insertedLength, deletedLength;
+  const char *deletedText;
+
+  call_predelete_callbacks(0, length());
+
+  /* Save information for redisplay, and get rid of the old buffer */
+  deletedText = text();
+  deletedLength = mLength;
+  free( (void *)mBuf );
+
+  /* Start a new buffer with a gap of PREFERRED_GAP_SIZE in the center */
+  insertedLength = strlen( t );
+  mBuf = (char *)malloc( insertedLength + PREFERRED_GAP_SIZE );
+  mLength = insertedLength;
+  mGapStart = insertedLength / 2;
+  mGapEnd = mGapStart + PREFERRED_GAP_SIZE;
+  memcpy( mBuf, t, mGapStart );
+  memcpy( &mBuf[ mGapEnd ], &t[ mGapStart ], insertedLength - mGapStart );
+#ifdef PURIFY
+{ int i; for ( i = mGapStart; i < mGapEnd; i++ ) mBuf[ i ] = '.'; }
+#endif
+
+  /* Zero all of the existing selections */
+  update_selections( 0, deletedLength, 0 );
+
+  /* Call the saved display routine(s) to update the screen */
+  call_modify_callbacks( 0, deletedLength, insertedLength, 0, deletedText );
+  free( (void *)deletedText );
+}
+
+/*
+** Return a copy of the text between "start" and "end" character positions
+** from text buffer "buf".  Positions start at 0, and the range does not
+** include the character pointed to by "end"
+*/
+char * Fl_Text_Buffer::text_range( int start, int end ) {
+  char * s;
+  int copiedLength, part1Length;
+
+  /* Make sure start and end are ok, and allocate memory for returned string.
+     If start is bad, return "", if end is bad, adjust it. */
+  if ( start < 0 || start > mLength ) {
+    s = (char *)malloc( 1 );
+    s[ 0 ] = '\0';
+    return s;
+  }
+  if ( end < start ) {
+    int temp = start;
+    start = end;
+    end = temp;
+  }
+  if ( end > mLength )
+    end = mLength;
+  copiedLength = end - start;
+  s = (char *)malloc( copiedLength + 1 );
+
+  /* Copy the text from the buffer to the returned string */
+  if ( end <= mGapStart ) {
+    memcpy( s, &mBuf[ start ], copiedLength );
+  } else if ( start >= mGapStart ) {
+    memcpy( s, &mBuf[ start + ( mGapEnd - mGapStart ) ], copiedLength );
+  } else {
+    part1Length = mGapStart - start;
+    memcpy( s, &mBuf[ start ], part1Length );
+    memcpy( &s[ part1Length ], &mBuf[ mGapEnd ], copiedLength - part1Length );
+  }
+  s[ copiedLength ] = '\0';
+  return s;
+}
+
+/*
+** Return the character at buffer position "pos".  Positions start at 0.
+*/
+char Fl_Text_Buffer::character( int pos ) {
+  if ( pos < 0 || pos >= mLength )
+    return '\0';
+  if ( pos < mGapStart )
+    return mBuf[ pos ];
+  else
+    return mBuf[ pos + mGapEnd - mGapStart ];
+}
+
+/*
+** Insert null-terminated string "text" at position "pos" in "buf"
+*/
+void Fl_Text_Buffer::insert( int pos, const char *s ) {
+  int nInserted;
+
+  /* if pos is not contiguous to existing text, make it */
+  if ( pos > mLength ) pos = mLength;
+  if ( pos < 0 ) pos = 0;
+
+  /* Even if nothing is deleted, we must call these callbacks */
+  call_predelete_callbacks( pos, 0 );
+
+  /* insert and redisplay */
+  nInserted = insert_( pos, s );
+  mCursorPosHint = pos + nInserted;
+  call_modify_callbacks( pos, 0, nInserted, 0, NULL );
+}
+
+/*
+** Delete the characters between "start" and "end", and insert the
+** null-terminated string "text" in their place in in "buf"
+*/
+void Fl_Text_Buffer::replace( int start, int end, const char *s ) {
+  const char * deletedText;
+  int nInserted;
+
+  // Range check...
+  if (!s) return;
+  if (start < 0) start = 0;
+  if (end > mLength) end = mLength;
+
+  call_predelete_callbacks( start, end-start );
+  deletedText = text_range( start, end );
+  remove_( start, end );
+  //undoyankcut = undocut;
+  nInserted = insert_( start, s );
+  mCursorPosHint = start + nInserted;
+  call_modify_callbacks( start, end - start, nInserted, 0, deletedText );
+  free( (void *)deletedText );
+}
+
+void Fl_Text_Buffer::remove( int start, int end ) {
+  const char * deletedText;
+
+  /* Make sure the arguments make sense */
+  if ( start > end ) {
+    int temp = start;
+    start = end;
+    end = temp;
+  }
+  if ( start > mLength ) start = mLength;
+  if ( start < 0 ) start = 0;
+  if ( end > mLength ) end = mLength;
+  if ( end < 0 ) end = 0;
+
+  if (start == end) return;
+
+  call_predelete_callbacks( start, end-start );
+  /* Remove and redisplay */
+  deletedText = text_range( start, end );
+  remove_( start, end );
+  mCursorPosHint = start;
+  call_modify_callbacks( start, end - start, 0, 0, deletedText );
+  free( (void *)deletedText );
+}
+
+void Fl_Text_Buffer::copy( Fl_Text_Buffer *fromBuf, int fromStart,
+                           int fromEnd, int toPos ) {
+  int copiedLength = fromEnd - fromStart;
+  int part1Length;
+
+  /* Prepare the buffer to receive the new text.  If the new text fits in
+     the current buffer, just move the gap (if necessary) to where
+     the text should be inserted.  If the new text is too large, reallocate
+     the buffer with a gap large enough to accomodate the new text and a
+     gap of PREFERRED_GAP_SIZE */
+  if ( copiedLength > mGapEnd - mGapStart )
+    reallocate_with_gap( toPos, copiedLength + PREFERRED_GAP_SIZE );
+  else if ( toPos != mGapStart )
+    move_gap( toPos );
+
+  /* Insert the new text (toPos now corresponds to the start of the gap) */
+  if ( fromEnd <= fromBuf->mGapStart ) {
+    memcpy( &mBuf[ toPos ], &fromBuf->mBuf[ fromStart ], copiedLength );
+  } else if ( fromStart >= fromBuf->mGapStart ) {
+    memcpy( &mBuf[ toPos ],
+            &fromBuf->mBuf[ fromStart + ( fromBuf->mGapEnd - fromBuf->mGapStart ) ],
+            copiedLength );
+  } else {
+    part1Length = fromBuf->mGapStart - fromStart;
+    memcpy( &mBuf[ toPos ], &fromBuf->mBuf[ fromStart ], part1Length );
+    memcpy( &mBuf[ toPos + part1Length ], &fromBuf->mBuf[ fromBuf->mGapEnd ],
+            copiedLength - part1Length );
+  }
+  mGapStart += copiedLength;
+  mLength += copiedLength;
+  update_selections( toPos, 0, copiedLength );
+}
+
+/*
+** remove text according to the undo variables or insert text 
+** from the undo buffer
+*/
+int Fl_Text_Buffer::undo(int *cursorPos) {
+  if (undowidget != this || !undocut && !undoinsert &&!mCanUndo) return 0;
+
+  int ilen = undocut;
+  int xlen = undoinsert;
+  int b = undoat-xlen;
+
+  if (xlen && undoyankcut && !ilen) {
+    ilen = undoyankcut;
+  }
+
+  if (xlen && ilen) {
+    undobuffersize(ilen+1);
+    undobuffer[ilen] = 0;
+    char *tmp = strdup(undobuffer);
+    replace(b, undoat, tmp);
+    if (cursorPos) *cursorPos = mCursorPosHint;
+    free(tmp);
+  }
+  else if (xlen) {
+    remove(b, undoat);
+    if (cursorPos) *cursorPos = mCursorPosHint;
+  }
+  else if (ilen) {
+    undobuffersize(ilen+1);
+    undobuffer[ilen] = 0;
+    insert(undoat, undobuffer);
+    if (cursorPos) *cursorPos = mCursorPosHint;
+    undoyankcut = 0;
+  }
+
+  return 1;
+}
+
+/*
+** let the undo system know if we can undo changes
+*/
+void Fl_Text_Buffer::canUndo(char flag) {
+  mCanUndo = flag;
+}
+
+/*
+** Insert "text" columnwise into buffer starting at displayed character
+** position "column" on the line beginning at "startPos".  Opens a rectangular
+** space the width and height of "text", by moving all text to the right of
+** "column" right.  If charsInserted and charsDeleted are not NULL, the
+** number of characters inserted and deleted in the operation (beginning
+** at startPos) are returned in these arguments
+*/
+void Fl_Text_Buffer::insert_column( int column, int startPos, const char *s,
+                                    int *charsInserted, int *charsDeleted ) {
+  int nLines, lineStartPos, nDeleted, insertDeleted, nInserted;
+  const char *deletedText;
+
+  nLines = countLines( s );
+  lineStartPos = line_start( startPos );
+  nDeleted = line_end( skip_lines( startPos, nLines ) ) -
+             lineStartPos;
+  call_predelete_callbacks( lineStartPos, nDeleted );
+  deletedText = text_range( lineStartPos, lineStartPos + nDeleted );
+  insert_column_( column, lineStartPos, s, &insertDeleted, &nInserted,
+                  &mCursorPosHint );
+  if ( nDeleted != insertDeleted )
+    Fl::error("Fl_Text_Buffer::insert_column(): internal consistency check ins1 failed");
+  call_modify_callbacks( lineStartPos, nDeleted, nInserted, 0, deletedText );
+  free( (void *) deletedText );
+  if ( charsInserted != NULL )
+    * charsInserted = nInserted;
+  if ( charsDeleted != NULL )
+    * charsDeleted = nDeleted;
+}
+
+/*
+** Overlay "text" between displayed character positions "rectStart" and
+** "rectEnd" on the line beginning at "startPos".  If charsInserted and
+** charsDeleted are not NULL, the number of characters inserted and deleted
+** in the operation (beginning at startPos) are returned in these arguments.
+*/
+void Fl_Text_Buffer::overlay_rectangular( int startPos, int rectStart,
+    int rectEnd, const char *s, int *charsInserted, int *charsDeleted ) {
+  int nLines, lineStartPos, nDeleted, insertDeleted, nInserted;
+  const char *deletedText;
+
+  nLines = countLines( s );
+  lineStartPos = line_start( startPos );
+  nDeleted = line_end( skip_lines( startPos, nLines ) ) -
+             lineStartPos;
+  call_predelete_callbacks( lineStartPos, nDeleted );
+  deletedText = text_range( lineStartPos, lineStartPos + nDeleted );
+  overlay_rectangular_( lineStartPos, rectStart, rectEnd, s, &insertDeleted,
+                        &nInserted, &mCursorPosHint );
+  if ( nDeleted != insertDeleted )
+    Fl::error("Fl_Text_Buffer::overlay_rectangle(): internal consistency check ovly1 failed");
+  call_modify_callbacks( lineStartPos, nDeleted, nInserted, 0, deletedText );
+  free( (void *) deletedText );
+  if ( charsInserted != NULL )
+    * charsInserted = nInserted;
+  if ( charsDeleted != NULL )
+    * charsDeleted = nDeleted;
+}
+
+/*
+** Replace a rectangular area in buf, given by "start", "end", "rectStart",
+** and "rectEnd", with "text".  If "text" is vertically longer than the
+** rectangle, add extra lines to make room for it.
+*/
+void Fl_Text_Buffer::replace_rectangular( int start, int end, int rectStart,
+    int rectEnd, const char *s ) {
+  char *insPtr;
+  const char *deletedText;
+  char *insText = (char *)"";
+  int i, nInsertedLines, nDeletedLines, insLen, hint;
+  int insertDeleted, insertInserted, deleteInserted;
+  int linesPadded = 0;
+
+  /* Make sure start and end refer to complete lines, since the
+     columnar delete and insert operations will replace whole lines */
+  start = line_start( start );
+  end = line_end( end );
+
+  call_predelete_callbacks( start, end-start );
+
+  /* If more lines will be deleted than inserted, pad the inserted text
+     with newlines to make it as long as the number of deleted lines.  This
+     will indent all of the text to the right of the rectangle to the same
+     column.  If more lines will be inserted than deleted, insert extra
+     lines in the buffer at the end of the rectangle to make room for the
+     additional lines in "text" */
+  nInsertedLines = countLines( s );
+  nDeletedLines = count_lines( start, end );
+  if ( nInsertedLines < nDeletedLines ) {
+    insLen = strlen( s );
+    insText = (char *)malloc( insLen + nDeletedLines - nInsertedLines + 1 );
+    strcpy( insText, s );
+    insPtr = insText + insLen;
+    for ( i = 0; i < nDeletedLines - nInsertedLines; i++ )
+      *insPtr++ = '\n';
+    *insPtr = '\0';
+  } else if ( nDeletedLines < nInsertedLines ) {
+    linesPadded = nInsertedLines - nDeletedLines;
+    for ( i = 0; i < linesPadded; i++ )
+      insert_( end, "\n" );
+  } /* else nDeletedLines == nInsertedLines; */
+
+  /* Save a copy of the text which will be modified for the modify CBs */
+  deletedText = text_range( start, end );
+
+  /* Delete then insert */
+  remove_rectangular_( start, end, rectStart, rectEnd, &deleteInserted, &hint );
+  insert_column_( rectStart, start, insText, &insertDeleted, &insertInserted,
+                  &mCursorPosHint );
+
+  /* Figure out how many chars were inserted and call modify callbacks */
+  if ( insertDeleted != deleteInserted + linesPadded )
+    Fl::error("Fl_Text_Buffer::replace_rectangular(): internal consistency check repl1 failed");
+  call_modify_callbacks( start, end - start, insertInserted, 0, deletedText );
+  free( (void *) deletedText );
+  if ( nInsertedLines < nDeletedLines )
+    free( (void *) insText );
+}
+
+/*
+** Remove a rectangular swath of characters between character positions start
+** and end and horizontal displayed-character offsets rectStart and rectEnd.
+*/
+void Fl_Text_Buffer::remove_rectangular( int start, int end, int rectStart,
+    int rectEnd ) {
+  const char * deletedText;
+  int nInserted;
+
+  start = line_start( start );
+  end = line_end( end );
+  call_predelete_callbacks( start, end-start );
+  deletedText = text_range( start, end );
+  remove_rectangular_( start, end, rectStart, rectEnd, &nInserted,
+                       &mCursorPosHint );
+  call_modify_callbacks( start, end - start, nInserted, 0, deletedText );
+  free( (void *) deletedText );
+}
+
+/*
+** Clear a rectangular "hole" out of the buffer between character positions
+** start and end and horizontal displayed-character offsets rectStart and
+** rectEnd.
+*/
+void Fl_Text_Buffer::clear_rectangular( int start, int end, int rectStart,
+                                        int rectEnd ) {
+  int i, nLines;
+  char *newlineString;
+
+  nLines = count_lines( start, end );
+  newlineString = (char *)malloc( nLines + 1 );
+  for ( i = 0; i < nLines; i++ )
+    newlineString[ i ] = '\n';
+  newlineString[ i ] = '\0';
+  overlay_rectangular( start, rectStart, rectEnd, newlineString,
+                       NULL, NULL );
+  free( (void *) newlineString );
+}
+
+char * Fl_Text_Buffer::text_in_rectangle( int start, int end,
+    int rectStart, int rectEnd ) {
+  int lineStart, selLeft, selRight, len;
+  char *textOut, *outPtr, *retabbedStr;
+  const char *textIn;
+
+  start = line_start( start );
+  end = line_end( end );
+  textOut = (char *)malloc( ( end - start ) + 1 );
+  lineStart = start;
+  outPtr = textOut;
+  while ( lineStart <= end ) {
+    rectangular_selection_boundaries( lineStart, rectStart, rectEnd,
+                                      &selLeft, &selRight );
+    textIn = text_range( selLeft, selRight );
+    len = selRight - selLeft;
+    memcpy( outPtr, textIn, len );
+    free( (void *) textIn );
+    outPtr += len;
+    lineStart = line_end( selRight ) + 1;
+    *outPtr++ = '\n';
+  }
+  if ( outPtr != textOut )
+    outPtr--;    /* don't leave trailing newline */
+  *outPtr = '\0';
+
+  /* If necessary, realign the tabs in the selection as if the text were
+     positioned at the left margin */
+  retabbedStr = realignTabs( textOut, rectStart, 0, mTabDist,
+                             mUseTabs, mNullSubsChar, &len );
+  free( (void *) textOut );
+  return retabbedStr;
+}
+
+/*
+** Set the hardware tab distance used by all displays for this buffer,
+** and used in computing offsets for rectangular selection operations.
+*/
+void Fl_Text_Buffer::tab_distance( int tabDist ) {
+  const char * deletedText;
+
+    /* First call the pre-delete callbacks with the previous tab setting 
+       still active. */
+  call_predelete_callbacks( 0, mLength );
+    
+  /* Change the tab setting */
+  mTabDist = tabDist;
+
+  /* Force any display routines to redisplay everything (unfortunately,
+     this means copying the whole buffer contents to provide "deletedText" */
+  deletedText = text();
+  call_modify_callbacks( 0, mLength, mLength, 0, deletedText );
+  free( (void *) deletedText );
+}
+
+void Fl_Text_Buffer::select( int start, int end ) {
+  Fl_Text_Selection oldSelection = mPrimary;
+
+  mPrimary.set( start, end );
+  redisplay_selection( &oldSelection, &mPrimary );
+}
+
+void Fl_Text_Buffer::unselect() {
+  Fl_Text_Selection oldSelection = mPrimary;
+
+  mPrimary.mSelected = 0;
+  redisplay_selection( &oldSelection, &mPrimary );
+}
+
+void Fl_Text_Buffer::select_rectangular( int start, int end, int rectStart,
+    int rectEnd ) {
+  Fl_Text_Selection oldSelection = mPrimary;
+
+  mPrimary.set_rectangular( start, end, rectStart, rectEnd );
+  redisplay_selection( &oldSelection, &mPrimary );
+}
+
+int Fl_Text_Buffer::selection_position( int *start, int *end
+                                      ) {
+  return mPrimary.position( start, end );
+}
+
+int Fl_Text_Buffer::selection_position( int *start, int *end,
+                                        int *isRect, int *rectStart, int *rectEnd ) {
+  return mPrimary.position( start, end, isRect, rectStart,
+                            rectEnd );
+}
+
+char * Fl_Text_Buffer::selection_text() {
+  return selection_text_( &mPrimary );
+}
+
+void Fl_Text_Buffer::remove_selection() {
+  remove_selection_( &mPrimary );
+}
+
+void Fl_Text_Buffer::replace_selection( const char *s ) {
+  replace_selection_( &mPrimary, s );
+}
+
+void Fl_Text_Buffer::secondary_select( int start, int end ) {
+  Fl_Text_Selection oldSelection = mSecondary;
+
+  mSecondary.set( start, end );
+  redisplay_selection( &oldSelection, &mSecondary );
+}
+
+void Fl_Text_Buffer::secondary_unselect() {
+  Fl_Text_Selection oldSelection = mSecondary;
+
+  mSecondary.mSelected = 0;
+  redisplay_selection( &oldSelection, &mSecondary );
+}
+
+void Fl_Text_Buffer::secondary_select_rectangular( int start, int end,
+    int rectStart, int rectEnd ) {
+  Fl_Text_Selection oldSelection = mSecondary;
+
+  mSecondary.set_rectangular( start, end, rectStart, rectEnd );
+  redisplay_selection( &oldSelection, &mSecondary );
+}
+
+int Fl_Text_Buffer::secondary_selection_position( int *start, int *end,
+    int *isRect, int *rectStart, int *rectEnd ) {
+  return mSecondary.position( start, end, isRect, rectStart,
+                              rectEnd );
+}
+
+char * Fl_Text_Buffer::secondary_selection_text() {
+  return selection_text_( &mSecondary );
+}
+
+void Fl_Text_Buffer::remove_secondary_selection() {
+  remove_selection_( &mSecondary );
+}
+
+void Fl_Text_Buffer::replace_secondary_selection( const char *s ) {
+  replace_selection_( &mSecondary, s );
+}
+
+void Fl_Text_Buffer::highlight( int start, int end ) {
+  Fl_Text_Selection oldSelection = mHighlight;
+
+  mHighlight.set( start, end );
+  redisplay_selection( &oldSelection, &mHighlight );
+}
+
+void Fl_Text_Buffer::unhighlight() {
+  Fl_Text_Selection oldSelection = mHighlight;
+
+  mHighlight.mSelected = 0;
+  redisplay_selection( &oldSelection, &mHighlight );
+}
+
+void Fl_Text_Buffer::highlight_rectangular( int start, int end,
+    int rectStart, int rectEnd ) {
+  Fl_Text_Selection oldSelection = mHighlight;
+
+  mHighlight.set_rectangular( start, end, rectStart, rectEnd );
+  redisplay_selection( &oldSelection, &mHighlight );
+}
+
+int Fl_Text_Buffer::highlight_position( int *start, int *end,
+                                        int *isRect, int *rectStart, int *rectEnd ) {
+  return mHighlight.position( start, end, isRect, rectStart,
+                              rectEnd );
+}
+
+char * Fl_Text_Buffer::highlight_text() {
+  return selection_text_( &mHighlight );
+}
+
+/*
+** Add a callback routine to be called when the buffer is modified
+*/
+void Fl_Text_Buffer::add_modify_callback( Fl_Text_Modify_Cb bufModifiedCB,
+    void *cbArg ) {
+  Fl_Text_Modify_Cb * newModifyProcs;
+  void **newCBArgs;
+  int i;
+
+  newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs + 1 ];
+  newCBArgs = new void * [ mNModifyProcs + 1 ];
+  for ( i = 0; i < mNModifyProcs; i++ ) {
+    newModifyProcs[ i + 1 ] = mNodifyProcs[ i ];
+    newCBArgs[ i + 1 ] = mCbArgs[ i ];
+  }
+  if ( mNModifyProcs != 0 ) {
+    delete [] mNodifyProcs;
+    delete [] mCbArgs;
+  }
+  newModifyProcs[ 0 ] = bufModifiedCB;
+  newCBArgs[ 0 ] = cbArg;
+  mNModifyProcs++;
+  mNodifyProcs = newModifyProcs;
+  mCbArgs = newCBArgs;
+}
+
+void Fl_Text_Buffer::remove_modify_callback( Fl_Text_Modify_Cb bufModifiedCB,
+    void *cbArg ) {
+  int i, toRemove = -1;
+  Fl_Text_Modify_Cb *newModifyProcs;
+  void **newCBArgs;
+
+  /* find the matching callback to remove */
+  for ( i = 0; i < mNModifyProcs; i++ ) {
+    if ( mNodifyProcs[ i ] == bufModifiedCB && mCbArgs[ i ] == cbArg ) {
+      toRemove = i;
+      break;
+    }
+  }
+  if ( toRemove == -1 ) {
+    Fl::error("Fl_Text_Buffer::remove_modify_callback(): Can't find modify CB to remove");
+    return;
+  }
+
+  /* Allocate new lists for remaining callback procs and args (if
+     any are left) */
+  mNModifyProcs--;
+  if ( mNModifyProcs == 0 ) {
+    mNModifyProcs = 0;
+    delete[] mNodifyProcs;
+    mNodifyProcs = NULL;
+    delete[] mCbArgs;
+    mCbArgs = NULL;
+    return;
+  }
+  newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs ];
+  newCBArgs = new void * [ mNModifyProcs ];
+
+  /* copy out the remaining members and free the old lists */
+  for ( i = 0; i < toRemove; i++ ) {
+    newModifyProcs[ i ] = mNodifyProcs[ i ];
+    newCBArgs[ i ] = mCbArgs[ i ];
+  }
+  for ( ; i < mNModifyProcs; i++ ) {
+    newModifyProcs[ i ] = mNodifyProcs[ i + 1 ];
+    newCBArgs[ i ] = mCbArgs[ i + 1 ];
+  }
+  delete[] mNodifyProcs;
+  delete[] mCbArgs;
+  mNodifyProcs = newModifyProcs;
+  mCbArgs = newCBArgs;
+}
+
+/*
+** Add a callback routine to be called before text is deleted from the buffer.
+*/
+void Fl_Text_Buffer::add_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB,
+	void *cbArg) {
+    Fl_Text_Predelete_Cb *newPreDeleteProcs;
+    void **newCBArgs;
+    int i;
+    
+    newPreDeleteProcs = new Fl_Text_Predelete_Cb[ mNPredeleteProcs + 1 ];
+    newCBArgs = new void * [ mNPredeleteProcs + 1 ];
+    for ( i = 0; i < mNPredeleteProcs; i++ ) {
+    	newPreDeleteProcs[i + 1] = mPredeleteProcs[i];
+    	newCBArgs[i + 1] = mPredeleteCbArgs[i];
+    }
+    if (! mNPredeleteProcs != 0) {
+		 delete [] mPredeleteProcs;
+		 delete [] mPredeleteCbArgs;
+    }
+    newPreDeleteProcs[0] =  bufPreDeleteCB;
+    newCBArgs[0] = cbArg;
+    mNPredeleteProcs++;
+    mPredeleteProcs = newPreDeleteProcs;
+    mPredeleteCbArgs = newCBArgs;
+}
+
+void Fl_Text_Buffer::remove_predelete_callback(
+   Fl_Text_Predelete_Cb bufPreDeleteCB, void *cbArg) {
+    int i, toRemove = -1;
+    Fl_Text_Predelete_Cb *newPreDeleteProcs;
+    void **newCBArgs;
+
+    /* find the matching callback to remove */
+    for ( i = 0; i < mNPredeleteProcs; i++) {
+    	if (mPredeleteProcs[i] == bufPreDeleteCB && 
+	       mPredeleteCbArgs[i] == cbArg) {
+    	    toRemove = i;
+    	    break;
+    	}
+    }
+    if (toRemove == -1) {
+    	Fl::error("Fl_Text_Buffer::remove_predelete_callback(): Can't find pre-delete CB to remove");
+    	return;
+    }
+    
+    /* Allocate new lists for remaining callback procs and args (if
+       any are left) */
+    mNPredeleteProcs--;
+    if (mNPredeleteProcs == 0) {
+    	mNPredeleteProcs = 0;
+		delete[] mPredeleteProcs;
+    	mPredeleteProcs = NULL;
+		delete[] mPredeleteCbArgs;
+	   mPredeleteCbArgs = NULL;
+	   return;
+    }
+    newPreDeleteProcs = new Fl_Text_Predelete_Cb [ mNPredeleteProcs ];
+    newCBArgs = new void * [ mNPredeleteProcs ];
+    
+    /* copy out the remaining members and free the old lists */
+    for ( i = 0; i < toRemove; i++) {
+    	newPreDeleteProcs[i] = mPredeleteProcs[i];
+    	newCBArgs[i] = mPredeleteCbArgs[i];
+    }
+    for ( ; i < mNPredeleteProcs; i++) {
+	   newPreDeleteProcs[i] = mPredeleteProcs[i+1];
+    	newCBArgs[i] = mPredeleteCbArgs[i+1];
+    }
+    delete[] mPredeleteProcs;
+    delete[] mPredeleteCbArgs;
+    mPredeleteProcs = newPreDeleteProcs;
+    mPredeleteCbArgs = newCBArgs;
+}
+
+/*
+** Return the text from the entire line containing position "pos"
+*/
+char * Fl_Text_Buffer::line_text( int pos ) {
+  return text_range( line_start( pos ), line_end( pos ) );
+}
+
+/*
+** Find the position of the start of the line containing position "pos"
+*/
+int Fl_Text_Buffer::line_start( int pos ) {
+  if ( !findchar_backward( pos, '\n', &pos ) )
+    return 0;
+  return pos + 1;
+}
+
+/*
+** Find the position of the end of the line containing position "pos"
+** (which is either a pointer to the newline character ending the line,
+** or a pointer to one character beyond the end of the buffer)
+*/
+int Fl_Text_Buffer::line_end( int pos ) {
+  if ( !findchar_forward( pos, '\n', &pos ) )
+    pos = mLength;
+  return pos;
+}
+
+int Fl_Text_Buffer::word_start( int pos ) {
+  while ( pos && ( isalnum( character( pos ) ) || character( pos ) == '_' ) ) {
+    pos--;
+  }
+  if ( !( isalnum( character( pos ) ) || character( pos ) == '_' ) ) pos++;
+  return pos;
+}
+
+int Fl_Text_Buffer::word_end( int pos ) {
+  while (pos < length() && (isalnum(character(pos)) || character(pos) == '_' )) {
+    pos++;
+  }
+  return pos;
+}
+
+/*
+** Get a character from the text buffer expanded into it's screen
+** representation (which may be several characters for a tab or a
+** control code).  Returns the number of characters written to "outStr".
+** "indent" is the number of characters from the start of the line
+** for figuring tabs.  Output string is guranteed to be shorter or
+** equal in length to FL_TEXT_MAX_EXP_CHAR_LEN
+*/
+int Fl_Text_Buffer::expand_character( int pos, int indent, char *outStr ) {
+  return expand_character( character( pos ), indent, outStr,
+                           mTabDist, mNullSubsChar );
+}
+
+/*
+** Expand a single character from the text buffer into it's screen
+** representation (which may be several characters for a tab or a
+** control code).  Returns the number of characters added to "outStr".
+** "indent" is the number of characters from the start of the line
+** for figuring tabs.  Output string is guranteed to be shorter or
+** equal in length to FL_TEXT_MAX_EXP_CHAR_LEN
+*/
+int Fl_Text_Buffer::expand_character( char c, int indent, char *outStr, int tabDist,
+                                      char nullSubsChar ) {
+  int i, nSpaces;
+
+  /* Convert tabs to spaces */
+  if ( c == '\t' ) {
+    nSpaces = tabDist - ( indent % tabDist );
+    for ( i = 0; i < nSpaces; i++ )
+      outStr[ i ] = ' ';
+    return nSpaces;
+  }
+
+  /* Convert control codes to readable character sequences */
+  /*... is this safe with international character sets? */
+  if ( ( ( unsigned char ) c ) <= 31 ) {
+    sprintf( outStr, "<%s>", ControlCodeTable[ ( unsigned char ) c ] );
+    return strlen( outStr );
+  } else if ( c == 127 ) {
+    sprintf( outStr, "<del>" );
+    return 5;
+  } else if ( c == nullSubsChar ) {
+    sprintf( outStr, "<nul>" );
+    return 5;
+  }
+
+  /* Otherwise, just return the character */
+  *outStr = c;
+  return 1;
+}
+
+/*
+** Return the length in displayed characters of character "c" expanded
+** for display (as discussed above in BufGetExpandedChar).  If the
+** buffer for which the character width is being measured is doing null
+** substitution, nullSubsChar should be passed as that character (or nul
+** to ignore).
+*/
+int Fl_Text_Buffer::character_width( char c, int indent, int tabDist, char nullSubsChar ) {
+  /* Note, this code must parallel that in Fl_Text_Buffer::ExpandCharacter */
+  if ( c == '\t' )
+    return tabDist - ( indent % tabDist );
+  else if ( ( ( unsigned char ) c ) <= 31 )
+    return strlen( ControlCodeTable[ ( unsigned char ) c ] ) + 2;
+  else if ( c == 127 )
+    return 5;
+  else if ( c == nullSubsChar )
+    return 5;
+  return 1;
+}
+
+/*
+** Count the number of displayed characters between buffer position
+** "lineStartPos" and "targetPos". (displayed characters are the characters
+** shown on the screen to represent characters in the buffer, where tabs and
+** control characters are expanded)
+*/
+int Fl_Text_Buffer::count_displayed_characters( int lineStartPos, int targetPos ) {
+  int pos, charCount = 0;
+  char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ];
+
+  pos = lineStartPos;
+  while ( pos < targetPos )
+    charCount += expand_character( pos++, charCount, expandedChar );
+  return charCount;
+}
+
+/*
+** Count forward from buffer position "startPos" in displayed characters
+** (displayed characters are the characters shown on the screen to represent
+** characters in the buffer, where tabs and control characters are expanded)
+*/
+int Fl_Text_Buffer::skip_displayed_characters( int lineStartPos, int nChars ) {
+  int pos, charCount = 0;
+  char c;
+
+  pos = lineStartPos;
+  while ( charCount < nChars && pos < mLength ) {
+    c = character( pos );
+    if ( c == '\n' )
+      return pos;
+    charCount += character_width( c, charCount, mTabDist, mNullSubsChar );
+    pos++;
+  }
+  return pos;
+}
+
+/*
+** Count the number of newlines between startPos and endPos in buffer "buf".
+** The character at position "endPos" is not counted.
+*/
+int Fl_Text_Buffer::count_lines( int startPos, int endPos ) {
+  int pos, gapLen = mGapEnd - mGapStart;
+  int lineCount = 0;
+
+  pos = startPos;
+  while ( pos < mGapStart ) {
+    if ( pos == endPos )
+      return lineCount;
+    if ( mBuf[ pos++ ] == '\n' )
+      lineCount++;
+  }
+  while ( pos < mLength ) {
+    if ( pos == endPos )
+      return lineCount;
+    if ( mBuf[ pos++ + gapLen ] == '\n' )
+      lineCount++;
+  }
+  return lineCount;
+}
+
+/*
+** Find the first character of the line "nLines" forward from "startPos"
+** in "buf" and return its position
+*/
+int Fl_Text_Buffer::skip_lines( int startPos, int nLines ) {
+  int pos, gapLen = mGapEnd - mGapStart;
+  int lineCount = 0;
+
+  if ( nLines == 0 )
+    return startPos;
+
+  pos = startPos;
+  while ( pos < mGapStart ) {
+    if ( mBuf[ pos++ ] == '\n' ) {
+      lineCount++;
+      if ( lineCount == nLines )
+        return pos;
+    }
+  }
+  while ( pos < mLength ) {
+    if ( mBuf[ pos++ + gapLen ] == '\n' ) {
+      lineCount++;
+      if ( lineCount >= nLines )
+        return pos;
+    }
+  }
+  return pos;
+}
+
+/*
+** Find the position of the first character of the line "nLines" backwards
+** from "startPos" (not counting the character pointed to by "startpos" if
+** that is a newline) in "buf".  nLines == 0 means find the beginning of
+** the line
+*/
+int Fl_Text_Buffer::rewind_lines( int startPos, int nLines ) {
+  int pos, gapLen = mGapEnd - mGapStart;
+  int lineCount = -1;
+
+  pos = startPos - 1;
+  if ( pos <= 0 )
+    return 0;
+
+  while ( pos >= mGapStart ) {
+    if ( mBuf[ pos + gapLen ] == '\n' ) {
+      if ( ++lineCount >= nLines )
+        return pos + 1;
+    }
+    pos--;
+  }
+  while ( pos >= 0 ) {
+    if ( mBuf[ pos ] == '\n' ) {
+      if ( ++lineCount >= nLines )
+        return pos + 1;
+    }
+    pos--;
+  }
+  return 0;
+}
+
+/*
+** Search forwards in buffer for string "searchString", starting with the
+** character "startPos", and returning the result in "foundPos"
+** returns 1 if found, 0 if not.
+*/
+int Fl_Text_Buffer::search_forward( int startPos, const char *searchString,
+                                    int *foundPos, int matchCase )
+{
+  if (!searchString) return 0;
+  int bp;
+  const char* sp;
+  while (startPos < length()) {
+    bp = startPos;
+    sp = searchString;
+    do {
+      if (!*sp) { *foundPos = startPos; return 1; }
+    } while ((matchCase ? character(bp++) == *sp++ :
+                         toupper(character(bp++)) == toupper(*sp++))
+             && bp < length());
+    startPos++;
+  }
+  return 0;
+}
+
+/*
+** Search backwards in buffer for string "searchString", starting with the
+** character BEFORE "startPos", returning the result in "foundPos"
+** returns 1 if found, 0 if not.
+*/
+int Fl_Text_Buffer::search_backward( int startPos, const char *searchString,
+                                     int *foundPos, int matchCase )
+{
+  if (!searchString) return 0;
+  int bp;
+  const char* sp;
+  while (startPos > 0) {
+    bp = startPos-1;
+    sp = searchString+strlen(searchString)-1;
+    do {
+      if (sp < searchString) { *foundPos = bp+1; return 1; }
+    } while ((matchCase ? character(bp--) == *sp-- :
+                         toupper(character(bp--)) == toupper(*sp--))
+             && bp >= 0);
+    startPos--;
+  }
+  return 0;
+}
+
+/*
+** Search forwards in buffer for characters in "searchChars", starting
+** with the character "startPos", and returning the result in "foundPos"
+** returns 1 if found, 0 if not.
+*/
+int Fl_Text_Buffer::findchars_forward( int startPos, const char *searchChars,
+                                    int *foundPos ) {
+  int pos, gapLen = mGapEnd - mGapStart;
+  const char *c;
+
+  pos = startPos;
+  while ( pos < mGapStart ) {
+    for ( c = searchChars; *c != '\0'; c++ ) {
+      if ( mBuf[ pos ] == *c ) {
+        *foundPos = pos;
+        return 1;
+      }
+    }
+    pos++;
+  }
+  while ( pos < mLength ) {
+    for ( c = searchChars; *c != '\0'; c++ ) {
+      if ( mBuf[ pos + gapLen ] == *c ) {
+        *foundPos = pos;
+        return 1;
+      }
+    }
+    pos++;
+  }
+  *foundPos = mLength;
+  return 0;
+}
+
+/*
+** Search backwards in buffer for characters in "searchChars", starting
+** with the character BEFORE "startPos", returning the result in "foundPos"
+** returns 1 if found, 0 if not.
+*/
+int Fl_Text_Buffer::findchars_backward( int startPos, const char *searchChars,
+                                     int *foundPos ) {
+  int pos, gapLen = mGapEnd - mGapStart;
+  const char *c;
+
+  if ( startPos == 0 ) {
+    *foundPos = 0;
+    return 0;
+  }
+  pos = startPos == 0 ? 0 : startPos - 1;
+  while ( pos >= mGapStart ) {
+    for ( c = searchChars; *c != '\0'; c++ ) {
+      if ( mBuf[ pos + gapLen ] == *c ) {
+        *foundPos = pos;
+        return 1;
+      }
+    }
+    pos--;
+  }
+  while ( pos >= 0 ) {
+    for ( c = searchChars; *c != '\0'; c++ ) {
+      if ( mBuf[ pos ] == *c ) {
+        *foundPos = pos;
+        return 1;
+      }
+    }
+    pos--;
+  }
+  *foundPos = 0;
+  return 0;
+}
+
+/*
+** A horrible design flaw in NEdit (from the very start, before we knew that
+** NEdit would become so popular), is that it uses C NULL terminated strings
+** to hold text.  This means editing text containing NUL characters is not
+** possible without special consideration.  Here is the special consideration.
+** The routines below maintain a special substitution-character which stands
+** in for a null, and translates strings an buffers back and forth from/to
+** the substituted form, figure out what to substitute, and figure out
+** when we're in over our heads and no translation is possible.
+*/
+
+/*
+** The primary routine for integrating new text into a text buffer with
+** substitution of another character for ascii nuls.  This substitutes null
+** characters in the string in preparation for being copied or replaced
+** into the buffer, and if neccessary, adjusts the buffer as well, in the
+** event that the string contains the character it is currently using for
+** substitution.  Returns 0, if substitution is no longer possible
+** because all non-printable characters are already in use.
+*/
+int Fl_Text_Buffer::substitute_null_characters( char *string, int len ) {
+  char histogram[ 256 ];
+
+  /* Find out what characters the string contains */
+  histogramCharacters( string, len, histogram, 1 );
+
+  /* Does the string contain the null-substitute character?  If so, re-
+     histogram the buffer text to find a character which is ok in both the
+     string and the buffer, and change the buffer's null-substitution
+     character.  If none can be found, give up and return 0 */
+  if ( histogram[ ( unsigned char ) mNullSubsChar ] != 0 ) {
+    char * bufString;
+    char newSubsChar;
+    bufString = (char*)text();
+    histogramCharacters( bufString, mLength, histogram, 0 );
+    newSubsChar = chooseNullSubsChar( histogram );
+    if ( newSubsChar == '\0' )
+      return 0;
+    subsChars( bufString, mLength, mNullSubsChar, newSubsChar );
+    remove_( 0, mLength );
+    insert_( 0, bufString );
+    free( (void *) bufString );
+    mNullSubsChar = newSubsChar;
+  }
+
+  /* If the string contains null characters, substitute them with the
+     buffer's null substitution character */
+  if ( histogram[ 0 ] != 0 )
+    subsChars( string, len, '\0', mNullSubsChar );
+  return 1;
+}
+
+/*
+** Convert strings obtained from buffers which contain null characters, which
+** have been substituted for by a special substitution character, back to
+** a null-containing string.  There is no time penalty for calling this
+** routine if no substitution has been done.
+*/
+void Fl_Text_Buffer::unsubstitute_null_characters( char *string ) {
+  register char * c, subsChar = mNullSubsChar;
+
+  if ( subsChar == '\0' )
+    return;
+  for ( c = string; *c != '\0'; c++ )
+    if ( *c == subsChar )
+      * c = '\0';
+}
+
+/*
+** Create a pseudo-histogram of the characters in a string (don't actually
+** count, because we don't want overflow, just mark the character's presence
+** with a 1).  If init is true, initialize the histogram before acumulating.
+** if not, add the new data to an existing histogram.
+*/
+static void histogramCharacters( const char *string, int length, char hist[ 256 ],
+                                 int init ) {
+  int i;
+  const char *c;
+
+  if ( init )
+    for ( i = 0; i < 256; i++ )
+      hist[ i ] = 0;
+  for ( c = string; c < &string[ length ]; c++ )
+    hist[ *( ( unsigned char * ) c ) ] |= 1;
+}
+
+/*
+** Substitute fromChar with toChar in string.
+*/
+static void subsChars( char *string, int length, char fromChar, char toChar ) {
+  char * c;
+
+  for ( c = string; c < &string[ length ]; c++ )
+    if ( *c == fromChar ) * c = toChar;
+}
+
+/*
+** Search through ascii control characters in histogram in order of least
+** likelihood of use, find an unused character to use as a stand-in for a
+** null.  If the character set is full (no available characters outside of
+** the printable set, return the null character.
+*/
+static char chooseNullSubsChar( char hist[ 256 ] ) {
+#define N_REPLACEMENTS 25
+  static char replacements[ N_REPLACEMENTS ] = {1, 2, 3, 4, 5, 6, 14, 15, 16, 17, 18, 19,
+      20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31, 11, 7};
+  int i;
+  for ( i = 0; i < N_REPLACEMENTS; i++ )
+    if ( hist[ replacements[ i ] ] == 0 )
+      return replacements[ i ];
+  return '\0';
+}
+
+/*
+** Internal (non-redisplaying) version of BufInsert.  Returns the length of
+** text inserted (this is just strlen(text), however this calculation can be
+** expensive and the length will be required by any caller who will continue
+** on to call redisplay).  pos must be contiguous with the existing text in
+** the buffer (i.e. not past the end).
+*/
+int Fl_Text_Buffer::insert_( int pos, const char *s ) {
+  int insertedLength = strlen( s );
+
+  /* Prepare the buffer to receive the new text.  If the new text fits in
+     the current buffer, just move the gap (if necessary) to where
+     the text should be inserted.  If the new text is too large, reallocate
+     the buffer with a gap large enough to accomodate the new text and a
+     gap of PREFERRED_GAP_SIZE */
+  if ( insertedLength > mGapEnd - mGapStart )
+    reallocate_with_gap( pos, insertedLength + PREFERRED_GAP_SIZE );
+  else if ( pos != mGapStart )
+    move_gap( pos );
+
+  /* Insert the new text (pos now corresponds to the start of the gap) */
+  memcpy( &mBuf[ pos ], s, insertedLength );
+  mGapStart += insertedLength;
+  mLength += insertedLength;
+  update_selections( pos, 0, insertedLength );
+
+  if (mCanUndo) {
+    if ( undowidget==this && undoat==pos && undoinsert ) {
+      undoinsert += insertedLength;
+    }
+    else {
+      undoinsert = insertedLength;
+      undoyankcut = (undoat==pos) ? undocut : 0 ;
+    }
+    undoat = pos+insertedLength;
+    undocut = 0;
+    undowidget = this;
+  }
+
+  return insertedLength;
+}
+
+/*
+** Internal (non-redisplaying) version of BufRemove.  Removes the contents
+** of the buffer between start and end (and moves the gap to the site of
+** the delete).
+*/
+void Fl_Text_Buffer::remove_( int start, int end ) {
+  /* if the gap is not contiguous to the area to remove, move it there */
+
+  if (mCanUndo) {
+    if ( undowidget==this && undoat==end && undocut ) {
+      undobuffersize( undocut+end-start+1 );
+      memmove( undobuffer+end-start, undobuffer, undocut );
+      undocut += end-start;
+    } 
+    else {
+      undocut = end-start;
+      undobuffersize(undocut);
+    }
+    undoat = start;
+    undoinsert = 0;
+    undoyankcut = 0;
+    undowidget = this;
+  }
+
+  if ( start > mGapStart ) {
+    if (mCanUndo)
+      memcpy( undobuffer, mBuf+(mGapEnd-mGapStart)+start, end-start );
+    move_gap( start );
+  }
+  else if ( end < mGapStart ) {
+    if (mCanUndo)
+      memcpy( undobuffer, mBuf+start, end-start );
+    move_gap( end );
+  }
+  else {
+    int prelen = mGapStart - start;
+    if (mCanUndo) {
+      memcpy( undobuffer, mBuf+start, prelen );
+      memcpy( undobuffer+prelen, mBuf+mGapEnd, end-start-prelen);
+    }
+  }
+
+  /* expand the gap to encompass the deleted characters */
+  mGapEnd += end - mGapStart;
+  mGapStart -= mGapStart - start;
+
+  /* update the length */
+  mLength -= end - start;
+
+  /* fix up any selections which might be affected by the change */
+  update_selections( start, end - start, 0 );
+}
+
+/*
+** Insert a column of text without calling the modify callbacks.  Note that
+** in some pathological cases, inserting can actually decrease the size of
+** the buffer because of spaces being coalesced into tabs.  "nDeleted" and
+** "nInserted" return the number of characters deleted and inserted beginning
+** at the start of the line containing "startPos".  "endPos" returns buffer
+** position of the lower left edge of the inserted column (as a hint for
+** routines which need to set a cursor position).
+*/
+void Fl_Text_Buffer::insert_column_( int column, int startPos, const char *insText,
+                                     int *nDeleted, int *nInserted, int *endPos ) {
+  int nLines, start, end, insWidth, lineStart, lineEnd;
+  int expReplLen, expInsLen, len, endOffset;
+  char *c, *outStr, *outPtr, *expText, *insLine;
+  const char *line;
+  const char  *replText;
+  const char *insPtr;
+
+  if ( column < 0 )
+    column = 0;
+
+  /* Allocate a buffer for the replacement string large enough to hold
+     possibly expanded tabs in both the inserted text and the replaced
+     area, as well as per line: 1) an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN
+     characters for padding where tabs and control characters cross the
+     column of the selection, 2) up to "column" additional spaces per
+     line for padding out to the position of "column", 3) padding up
+     to the width of the inserted text if that must be padded to align
+     the text beyond the inserted column.  (Space for additional
+     newlines if the inserted text extends beyond the end of the buffer
+     is counted with the length of insText) */
+  start = line_start( startPos );
+  nLines = countLines( insText ) + 1;
+  insWidth = textWidth( insText, mTabDist, mNullSubsChar );
+  end = line_end( skip_lines( start, nLines - 1 ) );
+  replText = text_range( start, end );
+  expText = expandTabs( replText, 0, mTabDist, mNullSubsChar,
+                        &expReplLen );
+  free( (void *) replText );
+  free( (void *) expText );
+  expText = expandTabs( insText, 0, mTabDist, mNullSubsChar,
+                        &expInsLen );
+  free( (void *) expText );
+  outStr = (char *)malloc( expReplLen + expInsLen +
+                           nLines * ( column + insWidth + FL_TEXT_MAX_EXP_CHAR_LEN ) + 1 );
+
+  /* Loop over all lines in the buffer between start and end removing the
+     text between rectStart and rectEnd and padding appropriately.  Trim
+     trailing space from line (whitespace at the ends of lines otherwise
+     tends to multiply, since additional padding is added to maintain it */
+  outPtr = outStr;
+  lineStart = start;
+  insPtr = insText;
+  for (;;) {
+    lineEnd = line_end( lineStart );
+    line = text_range( lineStart, lineEnd );
+    insLine = copyLine( insPtr, &len );
+    insPtr += len;
+    insertColInLine( line, insLine, column, insWidth, mTabDist,
+                     mUseTabs, mNullSubsChar, outPtr, &len, &endOffset );
+    free( (void *) line );
+    free( (void *) insLine );
+    for ( c = outPtr + len - 1; c > outPtr && isspace( *c ); c-- )
+      len--;
+    outPtr += len;
+    *outPtr++ = '\n';
+    lineStart = lineEnd < mLength ? lineEnd + 1 : mLength;
+    if ( *insPtr == '\0' )
+      break;
+    insPtr++;
+  }
+  if ( outPtr != outStr )
+    outPtr--;   /* trim back off extra newline */
+  *outPtr = '\0';
+
+  /* replace the text between start and end with the new stuff */
+  remove_( start, end );
+  insert_( start, outStr );
+  *nInserted = outPtr - outStr;
+  *nDeleted = end - start;
+  *endPos = start + ( outPtr - outStr ) - len + endOffset;
+  free( (void *) outStr );
+}
+
+/*
+** Delete a rectangle of text without calling the modify callbacks.  Returns
+** the number of characters replacing those between start and end.  Note that
+** in some pathological cases, deleting can actually increase the size of
+** the buffer because of tab expansions.  "endPos" returns the buffer position
+** of the point in the last line where the text was removed (as a hint for
+** routines which need to position the cursor after a delete operation)
+*/
+void Fl_Text_Buffer::remove_rectangular_( int start, int end, int rectStart,
+    int rectEnd, int *replaceLen, int *endPos ) {
+  int nLines, lineStart, lineEnd, len, endOffset;
+  char *outStr, *outPtr, *expText;
+  const char *s, *line;
+
+  /* allocate a buffer for the replacement string large enough to hold
+     possibly expanded tabs as well as an additional  FL_TEXT_MAX_EXP_CHAR_LEN * 2
+     characters per line for padding where tabs and control characters cross
+     the edges of the selection */
+  start = line_start( start );
+  end = line_end( end );
+  nLines = count_lines( start, end ) + 1;
+  s = text_range( start, end );
+  expText = expandTabs( s, 0, mTabDist, mNullSubsChar, &len );
+  free( (void *) s );
+  free( (void *) expText );
+  outStr = (char *)malloc( len + nLines * FL_TEXT_MAX_EXP_CHAR_LEN * 2 + 1 );
+
+  /* loop over all lines in the buffer between start and end removing
+     the text between rectStart and rectEnd and padding appropriately */
+  lineStart = start;
+  outPtr = outStr;
+  endOffset = 0;
+  while ( lineStart <= mLength && lineStart <= end ) {
+    lineEnd = line_end( lineStart );
+    line = text_range( lineStart, lineEnd );
+    deleteRectFromLine( line, rectStart, rectEnd, mTabDist,
+                        mUseTabs, mNullSubsChar, outPtr, &len, &endOffset );
+    free( (void *) line );
+    outPtr += len;
+    *outPtr++ = '\n';
+    lineStart = lineEnd + 1;
+  }
+  if ( outPtr != outStr )
+    outPtr--;   /* trim back off extra newline */
+  *outPtr = '\0';
+
+  /* replace the text between start and end with the newly created string */
+  remove_( start, end );
+  insert_( start, outStr );
+  *replaceLen = outPtr - outStr;
+  *endPos = start + ( outPtr - outStr ) - len + endOffset;
+  free( (void *) outStr );
+}
+
+/*
+** Overlay a rectangular area of text without calling the modify callbacks.
+** "nDeleted" and "nInserted" return the number of characters deleted and
+** inserted beginning at the start of the line containing "startPos".
+** "endPos" returns buffer position of the lower left edge of the inserted
+** column (as a hint for routines which need to set a cursor position).
+*/
+void Fl_Text_Buffer::overlay_rectangular_(int startPos, int rectStart,
+    int rectEnd, const char *insText,
+    int *nDeleted, int *nInserted,
+    int *endPos ) {
+  int nLines, start, end, lineStart, lineEnd;
+  int expInsLen, len, endOffset;
+  char *c, *outStr, *outPtr, *expText, *insLine;
+  const char *line;
+  const char *insPtr;
+
+  /* Allocate a buffer for the replacement string large enough to hold
+     possibly expanded tabs in the inserted text, as well as per line: 1)
+     an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN characters for padding where tabs
+     and control characters cross the column of the selection, 2) up to
+     "column" additional spaces per line for padding out to the position
+     of "column", 3) padding up to the width of the inserted text if that
+     must be padded to align the text beyond the inserted column.  (Space
+     for additional newlines if the inserted text extends beyond the end
+     of the buffer is counted with the length of insText) */
+  start = line_start( startPos );
+  nLines = countLines( insText ) + 1;
+  end = line_end( skip_lines( start, nLines - 1 ) );
+  expText = expandTabs( insText, 0, mTabDist, mNullSubsChar,
+                        &expInsLen );
+  free( (void *) expText );
+  outStr = (char *)malloc( end - start + expInsLen +
+                           nLines * ( rectEnd + FL_TEXT_MAX_EXP_CHAR_LEN ) + 1 );
+
+  /* Loop over all lines in the buffer between start and end overlaying the
+     text between rectStart and rectEnd and padding appropriately.  Trim
+     trailing space from line (whitespace at the ends of lines otherwise
+     tends to multiply, since additional padding is added to maintain it */
+  outPtr = outStr;
+  lineStart = start;
+  insPtr = insText;
+  for (;;) {
+    lineEnd = line_end( lineStart );
+    line = text_range( lineStart, lineEnd );
+    insLine = copyLine( insPtr, &len );
+    insPtr += len;
+    overlayRectInLine( line, insLine, rectStart, rectEnd, mTabDist,
+                       mUseTabs, mNullSubsChar, outPtr, &len, &endOffset );
+    free( (void *) line );
+    free( (void *) insLine );
+    for ( c = outPtr + len - 1; c > outPtr && isspace( *c ); c-- )
+      len--;
+    outPtr += len;
+    *outPtr++ = '\n';
+    lineStart = lineEnd < mLength ? lineEnd + 1 : mLength;
+    if ( *insPtr == '\0' )
+      break;
+    insPtr++;
+  }
+  if ( outPtr != outStr )
+    outPtr--;   /* trim back off extra newline */
+  *outPtr = '\0';
+
+  /* replace the text between start and end with the new stuff */
+  remove_( start, end );
+  insert_( start, outStr );
+  *nInserted = outPtr - outStr;
+  *nDeleted = end - start;
+  *endPos = start + ( outPtr - outStr ) - len + endOffset;
+  free( (void *) outStr );
+}
+
+/*
+** Insert characters from single-line string "insLine" in single-line string
+** "line" at "column", leaving "insWidth" space before continuing line.
+** "outLen" returns the number of characters written to "outStr", "endOffset"
+** returns the number of characters from the beginning of the string to
+** the right edge of the inserted text (as a hint for routines which need
+** to position the cursor).
+*/
+static void insertColInLine( const char *line, char *insLine, int column, int insWidth,
+                             int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen,
+                             int *endOffset ) {
+  char * c, *outPtr, *retabbedStr;
+  const char *linePtr;
+  int indent, toIndent, len, postColIndent;
+
+  /* copy the line up to "column" */
+  outPtr = outStr;
+  indent = 0;
+  for ( linePtr = line; *linePtr != '\0'; linePtr++ ) {
+    len = Fl_Text_Buffer::character_width( *linePtr, indent, tabDist, nullSubsChar );
+    if ( indent + len > column )
+      break;
+    indent += len;
+    *outPtr++ = *linePtr;
+  }
+
+  /* If "column" falls in the middle of a character, and the character is a
+     tab, leave it off and leave the indent short and it will get padded
+     later.  If it's a control character, insert it and adjust indent
+     accordingly. */
+  if ( indent < column && *linePtr != '\0' ) {
+    postColIndent = indent + len;
+    if ( *linePtr == '\t' )
+      linePtr++;
+    else {
+      *outPtr++ = *linePtr++;
+      indent += len;
+    }
+  } else
+    postColIndent = indent;
+
+  /* If there's no text after the column and no text to insert, that's all */
+  if ( *insLine == '\0' && *linePtr == '\0' ) {
+    *outLen = *endOffset = outPtr - outStr;
+    return;
+  }
+
+  /* pad out to column if text is too short */
+  if ( indent < column ) {
+    addPadding( outPtr, indent, column, tabDist, useTabs, nullSubsChar, &len );
+    outPtr += len;
+    indent = column;
+  }
+
+  /* Copy the text from "insLine" (if any), recalculating the tabs as if
+     the inserted string began at column 0 to its new column destination */
+  if ( *insLine != '\0' ) {
+    retabbedStr = realignTabs( insLine, 0, indent, tabDist, useTabs,
+                               nullSubsChar, &len );
+    for ( c = retabbedStr; *c != '\0'; c++ ) {
+      *outPtr++ = *c;
+      len = Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar );
+      indent += len;
+    }
+    free( (void *) retabbedStr );
+  }
+
+  /* If the original line did not extend past "column", that's all */
+  if ( *linePtr == '\0' ) {
+    *outLen = *endOffset = outPtr - outStr;
+    return;
+  }
+
+  /* Pad out to column + width of inserted text + (additional original
+     offset due to non-breaking character at column) */
+  toIndent = column + insWidth + postColIndent - column;
+  addPadding( outPtr, indent, toIndent, tabDist, useTabs, nullSubsChar, &len );
+  outPtr += len;
+  indent = toIndent;
+
+  /* realign tabs for text beyond "column" and write it out */
+  retabbedStr = realignTabs( linePtr, postColIndent, indent, tabDist,
+                             useTabs, nullSubsChar, &len );
+  strcpy( outPtr, retabbedStr );
+  free( (void *) retabbedStr );
+  *endOffset = outPtr - outStr;
+  *outLen = ( outPtr - outStr ) + len;
+}
+
+/*
+** Remove characters in single-line string "line" between displayed positions
+** "rectStart" and "rectEnd", and write the result to "outStr", which is
+** assumed to be large enough to hold the returned string.  Note that in
+** certain cases, it is possible for the string to get longer due to
+** expansion of tabs.  "endOffset" returns the number of characters from
+** the beginning of the string to the point where the characters were
+** deleted (as a hint for routines which need to position the cursor).
+*/
+static void deleteRectFromLine( const char *line, int rectStart, int rectEnd,
+                                int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen,
+                                int *endOffset ) {
+  int indent, preRectIndent, postRectIndent, len;
+  const char *c;
+  char *retabbedStr, *outPtr;
+
+  /* copy the line up to rectStart */
+  outPtr = outStr;
+  indent = 0;
+  for ( c = line; *c != '\0'; c++ ) {
+    if ( indent > rectStart )
+      break;
+    len = Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar );
+    if ( indent + len > rectStart && ( indent == rectStart || *c == '\t' ) )
+      break;
+    indent += len;
+    *outPtr++ = *c;
+  }
+  preRectIndent = indent;
+
+  /* skip the characters between rectStart and rectEnd */
+  for ( ; *c != '\0' && indent < rectEnd; c++ )
+    indent += Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar );
+  postRectIndent = indent;
+
+  /* If the line ended before rectEnd, there's nothing more to do */
+  if ( *c == '\0' ) {
+    *outPtr = '\0';
+    *outLen = *endOffset = outPtr - outStr;
+    return;
+  }
+
+  /* fill in any space left by removed tabs or control characters
+     which straddled the boundaries */
+  indent = max( rectStart + postRectIndent - rectEnd, preRectIndent );
+  addPadding( outPtr, preRectIndent, indent, tabDist, useTabs, nullSubsChar,
+              &len );
+  outPtr += len;
+
+  /* Copy the rest of the line.  If the indentation has changed, preserve
+     the position of non-whitespace characters by converting tabs to
+     spaces, then back to tabs with the correct offset */
+  retabbedStr = realignTabs( c, postRectIndent, indent, tabDist, useTabs,
+                             nullSubsChar, &len );
+  strcpy( outPtr, retabbedStr );
+  free( (void *) retabbedStr );
+  *endOffset = outPtr - outStr;
+  *outLen = ( outPtr - outStr ) + len;
+}
+
+/*
+** Overlay characters from single-line string "insLine" on single-line string
+** "line" between displayed character offsets "rectStart" and "rectEnd".
+** "outLen" returns the number of characters written to "outStr", "endOffset"
+** returns the number of characters from the beginning of the string to
+** the right edge of the inserted text (as a hint for routines which need
+** to position the cursor).
+*/
+static void overlayRectInLine( const char *line, char *insLine, int rectStart,
+                               int rectEnd, int tabDist, int useTabs, char nullSubsChar, char *outStr,
+                               int *outLen, int *endOffset ) {
+  char * c, *outPtr, *retabbedStr;
+  int inIndent, outIndent, len, postRectIndent;
+  const char *linePtr;
+
+  /* copy the line up to "rectStart" */
+  outPtr = outStr;
+  inIndent = outIndent = 0;
+  for ( linePtr = line; *linePtr != '\0'; linePtr++ ) {
+    len = Fl_Text_Buffer::character_width( *linePtr, inIndent, tabDist, nullSubsChar );
+    if ( inIndent + len > rectStart )
+      break;
+    inIndent += len;
+    outIndent += len;
+    *outPtr++ = *linePtr;
+  }
+
+  /* If "rectStart" falls in the middle of a character, and the character
+     is a tab, leave it off and leave the outIndent short and it will get
+     padded later.  If it's a control character, insert it and adjust
+     outIndent accordingly. */
+  if ( inIndent < rectStart && *linePtr != '\0' ) {
+    if ( *linePtr == '\t' ) {
+      linePtr++;
+      inIndent += len;
+    } else {
+      *outPtr++ = *linePtr++;
+      outIndent += len;
+      inIndent += len;
+    }
+  }
+
+  /* skip the characters between rectStart and rectEnd */
+  postRectIndent = rectEnd;
+  for ( ; *linePtr != '\0'; linePtr++ ) {
+    inIndent += Fl_Text_Buffer::character_width( *linePtr, inIndent, tabDist, nullSubsChar );
+    if ( inIndent >= rectEnd ) {
+      linePtr++;
+      postRectIndent = inIndent;
+      break;
+    }
+  }
+
+  /* If there's no text after rectStart and no text to insert, that's all */
+  if ( *insLine == '\0' && *linePtr == '\0' ) {
+    *outLen = *endOffset = outPtr - outStr;
+    return;
+  }
+
+  /* pad out to rectStart if text is too short */
+  if ( outIndent < rectStart ) {
+    addPadding( outPtr, outIndent, rectStart, tabDist, useTabs, nullSubsChar,
+                &len );
+    outPtr += len;
+  }
+  outIndent = rectStart;
+
+  /* Copy the text from "insLine" (if any), recalculating the tabs as if
+     the inserted string began at column 0 to its new column destination */
+  if ( *insLine != '\0' ) {
+    retabbedStr = realignTabs( insLine, 0, rectStart, tabDist, useTabs,
+                               nullSubsChar, &len );
+    for ( c = retabbedStr; *c != '\0'; c++ ) {
+      *outPtr++ = *c;
+      len = Fl_Text_Buffer::character_width( *c, outIndent, tabDist, nullSubsChar );
+      outIndent += len;
+    }
+    free( (void *) retabbedStr );
+  }
+
+  /* If the original line did not extend past "rectStart", that's all */
+  if ( *linePtr == '\0' ) {
+    *outLen = *endOffset = outPtr - outStr;
+    return;
+  }
+
+  /* Pad out to rectEnd + (additional original offset
+     due to non-breaking character at right boundary) */
+  addPadding( outPtr, outIndent, postRectIndent, tabDist, useTabs,
+              nullSubsChar, &len );
+  outPtr += len;
+  outIndent = postRectIndent;
+
+  /* copy the text beyond "rectEnd" */
+  strcpy( outPtr, linePtr );
+  *endOffset = outPtr - outStr;
+  *outLen = ( outPtr - outStr ) + strlen( linePtr );
+}
+
+void Fl_Text_Selection::set( int startpos, int endpos ) {
+  mSelected = startpos != endpos;
+  mRectangular = 0;
+  mStart = min( startpos, endpos );
+  mEnd = max( startpos, endpos );
+}
+
+void Fl_Text_Selection::set_rectangular( int startpos, int endpos,
+    int rectStart, int rectEnd ) {
+  mSelected = rectStart < rectEnd;
+  mRectangular = 1;
+  mStart = startpos;
+  mEnd = endpos;
+  mRectStart = rectStart;
+  mRectEnd = rectEnd;
+}
+
+int Fl_Text_Selection::position( int *startpos, int *endpos ) {
+  if ( !mSelected )
+    return 0;
+  *startpos = mStart;
+  *endpos = mEnd;
+
+  return 1;
+}
+
+int Fl_Text_Selection::position( int *startpos, int *endpos,
+                                 int *isRect, int *rectStart, int *rectEnd ) {
+  if ( !mSelected )
+    return 0;
+  *isRect = mRectangular;
+  *startpos = mStart;
+  *endpos = mEnd;
+  if ( mRectangular ) {
+    *rectStart = mRectStart;
+    *rectEnd = mRectEnd;
+  }
+  return 1;
+}
+
+/*
+** Return true if position "pos" with indentation "dispIndex" is in
+** the Fl_Text_Selection.
+*/
+int Fl_Text_Selection::includes(int pos, int lineStartPos, int dispIndex) {
+  return selected() &&
+         ( (!rectangular() && pos >= start() && pos < end()) ||
+           (rectangular() && pos >= start() && lineStartPos <= end() &&
+            dispIndex >= rect_start() && dispIndex < rect_end())
+         );
+}
+
+
+
+char * Fl_Text_Buffer::selection_text_( Fl_Text_Selection *sel ) {
+  int start, end, isRect, rectStart, rectEnd;
+  char *s;
+
+  /* If there's no selection, return an allocated empty string */
+  if ( !sel->position( &start, &end, &isRect, &rectStart, &rectEnd ) ) {
+    s = (char *)malloc( 1 );
+    *s = '\0';
+    return s;
+  }
+
+  /* If the selection is not rectangular, return the selected range */
+  if ( isRect )
+    return text_in_rectangle( start, end, rectStart, rectEnd );
+  else
+    return text_range( start, end );
+}
+
+void Fl_Text_Buffer::remove_selection_( Fl_Text_Selection *sel ) {
+  int start, end;
+  int isRect, rectStart, rectEnd;
+
+  if ( !sel->position( &start, &end, &isRect, &rectStart, &rectEnd ) )
+    return;
+  if ( isRect )
+    remove_rectangular( start, end, rectStart, rectEnd );
+  else {
+    remove( start, end );
+    //undoyankcut = undocut;
+  }
+}
+
+void Fl_Text_Buffer::replace_selection_( Fl_Text_Selection *sel, const char *s ) {
+  int start, end, isRect, rectStart, rectEnd;
+  Fl_Text_Selection oldSelection = *sel;
+
+  /* If there's no selection, return */
+  if ( !sel->position( &start, &end, &isRect, &rectStart, &rectEnd ) )
+    return;
+
+  /* Do the appropriate type of replace */
+  if ( isRect )
+    replace_rectangular( start, end, rectStart, rectEnd, s );
+  else
+    replace( start, end, s );
+
+  /* Unselect (happens automatically in BufReplace, but BufReplaceRect
+     can't detect when the contents of a selection goes away) */
+  sel->mSelected = 0;
+  redisplay_selection( &oldSelection, sel );
+}
+
+static void addPadding( char *string, int startIndent, int toIndent,
+                        int tabDist, int useTabs, char nullSubsChar, int *charsAdded ) {
+  char * outPtr;
+  int len, indent;
+
+  indent = startIndent;
+  outPtr = string;
+  if ( useTabs ) {
+    while ( indent < toIndent ) {
+      len = Fl_Text_Buffer::character_width( '\t', indent, tabDist, nullSubsChar );
+      if ( len > 1 && indent + len <= toIndent ) {
+        *outPtr++ = '\t';
+        indent += len;
+      } else {
+        *outPtr++ = ' ';
+        indent++;
+      }
+    }
+  } else {
+    while ( indent < toIndent ) {
+      *outPtr++ = ' ';
+      indent++;
+    }
+  }
+  *charsAdded = outPtr - string;
+}
+
+/*
+** Call the stored modify callback procedure(s) for this buffer to update the
+** changed area(s) on the screen and any other listeners.
+*/
+void Fl_Text_Buffer::call_modify_callbacks( int pos, int nDeleted,
+    int nInserted, int nRestyled, const char *deletedText ) {
+  int i;
+
+  for ( i = 0; i < mNModifyProcs; i++ )
+    ( *mNodifyProcs[ i ] ) ( pos, nInserted, nDeleted, nRestyled,
+                             deletedText, mCbArgs[ i ] );
+}
+
+/*
+** Call the stored pre-delete callback procedure(s) for this buffer to update 
+** the changed area(s) on the screen and any other listeners.
+*/
+void Fl_Text_Buffer::call_predelete_callbacks(int pos, int nDeleted) {
+    int i;
+    
+    for (i=0; i<mNPredeleteProcs; i++)
+    	(*mPredeleteProcs[i])(pos, nDeleted, mPredeleteCbArgs[i]);
+}
+
+/*
+** Call the stored redisplay procedure(s) for this buffer to update the
+** screen for a change in a selection.
+*/
+void Fl_Text_Buffer::redisplay_selection( Fl_Text_Selection *oldSelection,
+    Fl_Text_Selection *newSelection ) {
+  int oldStart, oldEnd, newStart, newEnd, ch1Start, ch1End, ch2Start, ch2End;
+
+  /* If either selection is rectangular, add an additional character to
+     the end of the selection to request the redraw routines to wipe out
+     the parts of the selection beyond the end of the line */
+  oldStart = oldSelection->mStart;
+  newStart = newSelection->mStart;
+  oldEnd = oldSelection->mEnd;
+  newEnd = newSelection->mEnd;
+  if ( oldSelection->mRectangular )
+    oldEnd++;
+  if ( newSelection->mRectangular )
+    newEnd++;
+
+  /* If the old or new selection is unselected, just redisplay the
+     single area that is (was) selected and return */
+  if ( !oldSelection->mSelected && !newSelection->mSelected )
+    return;
+  if ( !oldSelection->mSelected ) {
+    call_modify_callbacks( newStart, 0, 0, newEnd - newStart, NULL );
+    return;
+  }
+  if ( !newSelection->mSelected ) {
+    call_modify_callbacks( oldStart, 0, 0, oldEnd - oldStart, NULL );
+    return;
+  }
+
+  /* If the selection changed from normal to rectangular or visa versa, or
+     if a rectangular selection changed boundaries, redisplay everything */
+  if ( ( oldSelection->mRectangular && !newSelection->mRectangular ) ||
+       ( !oldSelection->mRectangular && newSelection->mRectangular ) ||
+       ( oldSelection->mRectangular && (
+           ( oldSelection->mRectStart != newSelection->mRectStart ) ||
+           ( oldSelection->mRectEnd != newSelection->mRectEnd ) ) ) ) {
+    call_modify_callbacks( min( oldStart, newStart ), 0, 0,
+                           max( oldEnd, newEnd ) - min( oldStart, newStart ), NULL );
+    return;
+  }
+
+  /* If the selections are non-contiguous, do two separate updates
+     and return */
+  if ( oldEnd < newStart || newEnd < oldStart ) {
+    call_modify_callbacks( oldStart, 0, 0, oldEnd - oldStart, NULL );
+    call_modify_callbacks( newStart, 0, 0, newEnd - newStart, NULL );
+    return;
+  }
+
+  /* Otherwise, separate into 3 separate regions: ch1, and ch2 (the two
+     changed areas), and the unchanged area of their intersection,
+     and update only the changed area(s) */
+  ch1Start = min( oldStart, newStart );
+  ch2End = max( oldEnd, newEnd );
+  ch1End = max( oldStart, newStart );
+  ch2Start = min( oldEnd, newEnd );
+  if ( ch1Start != ch1End )
+    call_modify_callbacks( ch1Start, 0, 0, ch1End - ch1Start, NULL );
+  if ( ch2Start != ch2End )
+    call_modify_callbacks( ch2Start, 0, 0, ch2End - ch2Start, NULL );
+}
+
+void Fl_Text_Buffer::move_gap( int pos ) {
+  int gapLen = mGapEnd - mGapStart;
+
+  if ( pos > mGapStart )
+    memmove( &mBuf[ mGapStart ], &mBuf[ mGapEnd ],
+             pos - mGapStart );
+  else
+    memmove( &mBuf[ pos + gapLen ], &mBuf[ pos ], mGapStart - pos );
+  mGapEnd += pos - mGapStart;
+  mGapStart += pos - mGapStart;
+}
+
+/*
+** reallocate the text storage in "buf" to have a gap starting at "newGapStart"
+** and a gap size of "newGapLen", preserving the buffer's current contents.
+*/
+void Fl_Text_Buffer::reallocate_with_gap( int newGapStart, int newGapLen ) {
+  char * newBuf;
+  int newGapEnd;
+
+  newBuf = (char *)malloc( mLength + newGapLen );
+  newGapEnd = newGapStart + newGapLen;
+  if ( newGapStart <= mGapStart ) {
+    memcpy( newBuf, mBuf, newGapStart );
+    memcpy( &newBuf[ newGapEnd ], &mBuf[ newGapStart ],
+            mGapStart - newGapStart );
+    memcpy( &newBuf[ newGapEnd + mGapStart - newGapStart ],
+            &mBuf[ mGapEnd ], mLength - mGapStart );
+  } else { /* newGapStart > mGapStart */
+    memcpy( newBuf, mBuf, mGapStart );
+    memcpy( &newBuf[ mGapStart ], &mBuf[ mGapEnd ],
+            newGapStart - mGapStart );
+    memcpy( &newBuf[ newGapEnd ],
+            &mBuf[ mGapEnd + newGapStart - mGapStart ],
+            mLength - newGapStart );
+  }
+  free( (void *) mBuf );
+  mBuf = newBuf;
+  mGapStart = newGapStart;
+  mGapEnd = newGapEnd;
+#ifdef PURIFY
+{int i; for ( i = mGapStart; i < mGapEnd; i++ ) mBuf[ i ] = '.'; }
+#endif
+}
+
+/*
+** Update all of the selections in "buf" for changes in the buffer's text
+*/
+void Fl_Text_Buffer::update_selections( int pos, int nDeleted,
+                                        int nInserted ) {
+  mPrimary.update( pos, nDeleted, nInserted );
+  mSecondary.update( pos, nDeleted, nInserted );
+  mHighlight.update( pos, nDeleted, nInserted );
+}
+
+/*
+** Update an individual selection for changes in the corresponding text
+*/
+void Fl_Text_Selection::update( int pos, int nDeleted,
+                                int nInserted ) {
+  if ( !mSelected || pos > mEnd )
+    return;
+  if ( pos + nDeleted <= mStart ) {
+    mStart += nInserted - nDeleted;
+    mEnd += nInserted - nDeleted;
+  } else if ( pos <= mStart && pos + nDeleted >= mEnd ) {
+    mStart = pos;
+    mEnd = pos;
+    mSelected = 0;
+  } else if ( pos <= mStart && pos + nDeleted < mEnd ) {
+    mStart = pos;
+    mEnd = nInserted + mEnd - nDeleted;
+  } else if ( pos < mEnd ) {
+    mEnd += nInserted - nDeleted;
+    if ( mEnd <= mStart )
+      mSelected = 0;
+  }
+}
+
+/*
+** Search forwards in buffer "buf" for character "searchChar", starting
+** with the character "startPos", and returning the result in "foundPos"
+** returns 1 if found, 0 if not.  (The difference between this and
+** BufSearchForward is that it's optimized for single characters.  The
+** overall performance of the text widget is dependent on its ability to
+** count lines quickly, hence searching for a single character: newline)
+*/
+int Fl_Text_Buffer::findchar_forward( int startPos, char searchChar,
+                                    int *foundPos ) {
+  int pos, gapLen = mGapEnd - mGapStart;
+
+  if (startPos < 0 || startPos >= mLength) {
+    *foundPos = mLength;
+    return 0;
+  }
+
+  pos = startPos;
+  while ( pos < mGapStart ) {
+    if ( mBuf[ pos ] == searchChar ) {
+      *foundPos = pos;
+      return 1;
+    }
+    pos++;
+  }
+  while ( pos < mLength ) {
+    if ( mBuf[ pos + gapLen ] == searchChar ) {
+      *foundPos = pos;
+      return 1;
+    }
+    pos++;
+  }
+  *foundPos = mLength;
+  return 0;
+}
+
+/*
+** Search backwards in buffer "buf" for character "searchChar", starting
+** with the character BEFORE "startPos", returning the result in "foundPos"
+** returns 1 if found, 0 if not.  (The difference between this and
+** BufSearchBackward is that it's optimized for single characters.  The
+** overall performance of the text widget is dependent on its ability to
+** count lines quickly, hence searching for a single character: newline)
+*/
+int Fl_Text_Buffer::findchar_backward( int startPos, char searchChar,
+                                     int *foundPos ) {
+  int pos, gapLen = mGapEnd - mGapStart;
+
+  if ( startPos <= 0 || startPos > mLength ) {
+    *foundPos = 0;
+    return 0;
+  }
+  pos = startPos - 1;
+  while ( pos >= mGapStart ) {
+    if ( mBuf[ pos + gapLen ] == searchChar ) {
+      *foundPos = pos;
+      return 1;
+    }
+    pos--;
+  }
+  while ( pos >= 0 ) {
+    if ( mBuf[ pos ] == searchChar ) {
+      *foundPos = pos;
+      return 1;
+    }
+    pos--;
+  }
+  *foundPos = 0;
+  return 0;
+}
+
+/*
+** Copy from "text" to end up to but not including newline (or end of "text")
+** and return the copy as the function value, and the length of the line in
+** "lineLen"
+*/
+static char *copyLine( const char *text, int *lineLen ) {
+  int len = 0;
+  const char *c;
+  char *outStr;
+
+  for ( c = text; *c != '\0' && *c != '\n'; c++ )
+    len++;
+  outStr = (char *)malloc( len + 1 );
+  strlcpy( outStr, text, len + 1);
+  *lineLen = len;
+  return outStr;
+}
+
+/*
+** Count the number of newlines in a null-terminated text string;
+*/
+static int countLines( const char *string ) {
+  const char * c;
+  int lineCount = 0;
+
+  for ( c = string; *c != '\0'; c++ )
+    if ( *c == '\n' ) lineCount++;
+  return lineCount;
+}
+
+/*
+** Measure the width in displayed characters of string "text"
+*/
+static int textWidth( const char *text, int tabDist, char nullSubsChar ) {
+  int width = 0, maxWidth = 0;
+  const char *c;
+
+  for ( c = text; *c != '\0'; c++ ) {
+    if ( *c == '\n' ) {
+      if ( width > maxWidth )
+        maxWidth = width;
+      width = 0;
+    } else
+      width += Fl_Text_Buffer::character_width( *c, width, tabDist, nullSubsChar );
+  }
+  if ( width > maxWidth )
+    return width;
+  return maxWidth;
+}
+
+/*
+** Find the first and last character position in a line within a rectangular
+** selection (for copying).  Includes tabs which cross rectStart, but not
+** control characters which do so.  Leaves off tabs which cross rectEnd.
+**
+** Technically, the calling routine should convert tab characters which
+** cross the right boundary of the selection to spaces which line up with
+** the edge of the selection.  Unfortunately, the additional memory
+** management required in the parent routine to allow for the changes
+** in string size is not worth all the extra work just for a couple of
+** shifted characters, so if a tab protrudes, just lop it off and hope
+** that there are other characters in the selection to establish the right
+** margin for subsequent columnar pastes of this data.
+*/
+void Fl_Text_Buffer::rectangular_selection_boundaries( int lineStartPos,
+    int rectStart, int rectEnd, int *selStart, int *selEnd ) {
+  int pos, width, indent = 0;
+  char c;
+
+  /* find the start of the selection */
+  for ( pos = lineStartPos; pos < mLength; pos++ ) {
+    c = character( pos );
+    if ( c == '\n' )
+      break;
+    width = Fl_Text_Buffer::character_width( c, indent, mTabDist, mNullSubsChar );
+    if ( indent + width > rectStart ) {
+      if ( indent != rectStart && c != '\t' ) {
+        pos++;
+        indent += width;
+      }
+      break;
+    }
+    indent += width;
+  }
+  *selStart = pos;
+
+  /* find the end */
+  for ( ; pos < mLength; pos++ ) {
+    c = character( pos );
+    if ( c == '\n' )
+      break;
+    width = Fl_Text_Buffer::character_width( c, indent, mTabDist, mNullSubsChar );
+    indent += width;
+    if ( indent > rectEnd ) {
+      if ( indent - width != rectEnd && c != '\t' )
+        pos++;
+      break;
+    }
+  }
+  *selEnd = pos;
+}
+
+/*
+** Adjust the space and tab characters from string "text" so that non-white
+** characters remain stationary when the text is shifted from starting at
+** "origIndent" to starting at "newIndent".  Returns an allocated string
+** which must be freed by the caller with XtFree.
+*/
+static char *realignTabs( const char *text, int origIndent, int newIndent,
+                          int tabDist, int useTabs, char nullSubsChar, int *newLength ) {
+  char * expStr, *outStr;
+  int len;
+
+  /* If the tabs settings are the same, retain original tabs */
+  if ( origIndent % tabDist == newIndent % tabDist ) {
+    len = strlen( text );
+    outStr = (char *)malloc( len + 1 );
+    strcpy( outStr, text );
+    *newLength = len;
+    return outStr;
+  }
+
+  /* If the tab settings are not the same, brutally convert tabs to
+     spaces, then back to tabs in the new position */
+  expStr = expandTabs( text, origIndent, tabDist, nullSubsChar, &len );
+  if ( !useTabs ) {
+    *newLength = len;
+    return expStr;
+  }
+  outStr = unexpandTabs( expStr, newIndent, tabDist, nullSubsChar, newLength );
+  free( (void *) expStr );
+  return outStr;
+}
+
+/*
+** Expand tabs to spaces for a block of text.  The additional parameter
+** "startIndent" if nonzero, indicates that the text is a rectangular selection
+** beginning at column "startIndent"
+*/
+static char *expandTabs( const char *text, int startIndent, int tabDist,
+                         char nullSubsChar, int *newLen ) {
+  char * outStr, *outPtr;
+  const char *c;
+  int indent, len, outLen = 0;
+
+  /* rehearse the expansion to figure out length for output string */
+  indent = startIndent;
+  for ( c = text; *c != '\0'; c++ ) {
+    if ( *c == '\t' ) {
+      len = Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar );
+      outLen += len;
+      indent += len;
+    } else if ( *c == '\n' ) {
+      indent = startIndent;
+      outLen++;
+    } else {
+      indent += Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar );
+      outLen++;
+    }
+  }
+
+  /* do the expansion */
+  outStr = (char *)malloc( outLen + 1 );
+  outPtr = outStr;
+  indent = startIndent;
+  for ( c = text; *c != '\0'; c++ ) {
+    if ( *c == '\t' ) {
+      len = Fl_Text_Buffer::expand_character( *c, indent, outPtr, tabDist, nullSubsChar );
+      outPtr += len;
+      indent += len;
+    } else if ( *c == '\n' ) {
+      indent = startIndent;
+      *outPtr++ = *c;
+    } else {
+      indent += Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar );
+      *outPtr++ = *c;
+    }
+  }
+  outStr[ outLen ] = '\0';
+  *newLen = outLen;
+  return outStr;
+}
+
+/*
+** Convert sequences of spaces into tabs.  The threshold for conversion is
+** when 3 or more spaces can be converted into a single tab, this avoids
+** converting double spaces after a period withing a block of text.
+*/
+static char *unexpandTabs( char *text, int startIndent, int tabDist,
+                           char nullSubsChar, int *newLen ) {
+  char * outStr, *outPtr, *c, expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ];
+  int indent, len;
+
+  outStr = (char *)malloc( strlen( text ) + 1 );
+  outPtr = outStr;
+  indent = startIndent;
+  for ( c = text; *c != '\0'; ) {
+    if ( *c == ' ' ) {
+      len = Fl_Text_Buffer::expand_character( '\t', indent, expandedChar, tabDist,
+                                              nullSubsChar );
+      if ( len >= 3 && !strncmp( c, expandedChar, len ) ) {
+        c += len;
+        *outPtr++ = '\t';
+        indent += len;
+      } else {
+        *outPtr++ = *c++;
+        indent++;
+      }
+    } else if ( *c == '\n' ) {
+      indent = startIndent;
+      *outPtr++ = *c++;
+    } else {
+      *outPtr++ = *c++;
+      indent++;
+    }
+  }
+  *outPtr = '\0';
+  *newLen = outPtr - outStr;
+  return outStr;
+}
+
+static int max( int i1, int i2 ) {
+  return i1 >= i2 ? i1 : i2;
+}
+
+static int min( int i1, int i2 ) {
+  return i1 <= i2 ? i1 : i2;
+}
+
+int
+Fl_Text_Buffer::insertfile(const char *file, int pos, int buflen) {
+  FILE *fp;  int r;
+  if (!(fp = fopen(file, "r"))) return 1;
+  char *buffer = new char[buflen];
+  for (; (r = fread(buffer, 1, buflen - 1, fp)) > 0; pos += r) {
+    buffer[r] = (char)0;
+    insert(pos, buffer);
+  }
+
+  int e = ferror(fp) ? 2 : 0;
+  fclose(fp);
+  delete[] buffer;
+  return e;
+}
+
+int
+Fl_Text_Buffer::outputfile(const char *file, int start, int end, int buflen) {
+  FILE *fp;
+  if (!(fp = fopen(file, "w"))) return 1;
+  for (int n; (n = min(end - start, buflen)); start += n) {
+    const char *p = text_range(start, start + n);
+    int r = fwrite(p, 1, n, fp);
+    free((void *)p);
+    if (r != n) break;
+  }
+
+  int e = ferror(fp) ? 2 : 0;
+  fclose(fp);
+  return e;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Text_Display.cxx b/Utilities/FLTK/src/Fl_Text_Display.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..74e7aebc460d62938d004fc43fe6eeae85960788
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Text_Display.cxx
@@ -0,0 +1,3239 @@
+//
+// "$Id$"
+//
+// Copyright 2001-2005 by Bill Spitzak and others.
+// Original code Copyright Mark Edel.  Permission to distribute under
+// the LGPL for the FLTK library granted by Mark Edel.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <limits.h>
+#include <ctype.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Text_Buffer.H>
+#include <FL/Fl_Text_Display.H>
+#include <FL/Fl_Window.H>
+
+#undef min
+#undef max
+
+// Text area margins.  Left & right margins should be at least 3 so that
+// there is some room for the overhanging parts of the cursor!
+#define TOP_MARGIN 1
+#define BOTTOM_MARGIN 1
+#define LEFT_MARGIN 3
+#define RIGHT_MARGIN 3
+
+#define NO_HINT -1
+
+/* Masks for text drawing methods.  These are or'd together to form an
+   integer which describes what drawing calls to use to draw a string */
+#define FILL_MASK         0x0100
+#define SECONDARY_MASK    0x0200
+#define PRIMARY_MASK      0x0400
+#define HIGHLIGHT_MASK    0x0800
+#define BG_ONLY_MASK      0x1000
+#define TEXT_ONLY_MASK    0x2000
+#define STYLE_LOOKUP_MASK   0xff
+
+/* Maximum displayable line length (how many characters will fit across the
+   widest window).  This amount of memory is temporarily allocated from the
+   stack in the draw_vline() method for drawing strings */
+#define MAX_DISP_LINE_LEN 1000
+
+static int max( int i1, int i2 );
+static int min( int i1, int i2 );
+static int countlines( const char *string );
+
+/* The variables below are used in a timer event to allow smooth
+   scrolling of the text area when the pointer has left the area. */
+static int scroll_direction = 0;
+static int scroll_amount = 0;
+static int scroll_y = 0;
+static int scroll_x = 0;
+
+// CET - FIXME
+#define TMPFONTWIDTH 6
+
+Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H,  const char* l)
+    : Fl_Group(X, Y, W, H, l) {
+  int i;
+
+  mMaxsize = 0;
+  damage_range1_start = damage_range1_end = -1;
+  damage_range2_start = damage_range2_end = -1;
+  dragPos = dragType = dragging = 0;
+  display_insert_position_hint = 0;
+
+  color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
+  box(FL_DOWN_FRAME);
+  textsize((uchar)FL_NORMAL_SIZE);
+  textcolor(FL_FOREGROUND_COLOR);
+  textfont(FL_HELVETICA);
+
+  text_area.x = 0;
+  text_area.y = 0;
+  text_area.w = 0;
+  text_area.h = 0;
+
+  mVScrollBar = new Fl_Scrollbar(0,0,1,1);
+  mVScrollBar->callback((Fl_Callback*)v_scrollbar_cb, this);
+  mHScrollBar = new Fl_Scrollbar(0,0,1,1);
+  mHScrollBar->callback((Fl_Callback*)h_scrollbar_cb, this);
+  mHScrollBar->type(FL_HORIZONTAL);
+
+  end();
+
+  scrollbar_width(16);
+  scrollbar_align(FL_ALIGN_BOTTOM_RIGHT);
+
+  mCursorOn = 0;
+  mCursorPos = 0;
+  mCursorOldY = -100;
+  mCursorToHint = NO_HINT;
+  mCursorStyle = NORMAL_CURSOR;
+  mCursorPreferredCol = -1;
+  mBuffer = 0;
+  mFirstChar = 0;
+  mLastChar = 0;
+  mNBufferLines = 0;
+  mTopLineNum = mTopLineNumHint = 1;
+  mAbsTopLineNum = 1;
+  mNeedAbsTopLineNum = 0;
+  mHorizOffset = mHorizOffsetHint = 0;
+
+  mCursor_color = FL_FOREGROUND_COLOR;
+
+  mFixedFontWidth = -1;
+  mStyleBuffer = 0;
+  mStyleTable = 0;
+  mNStyles = 0;
+  mNVisibleLines = 1;
+  mLineStarts = new int[mNVisibleLines];
+  mLineStarts[0] = 0;
+  for (i=1; i<mNVisibleLines; i++)
+    mLineStarts[i] = -1;
+  mSuppressResync = 0;
+  mNLinesDeleted = 0;
+  mModifyingTabDistance = 0;
+
+  mUnfinishedStyle = 0;
+  mUnfinishedHighlightCB = 0;
+  mHighlightCBArg = 0;
+
+  mLineNumLeft = mLineNumWidth = 0;
+  mContinuousWrap = 0;
+  mWrapMargin = 0;
+  mSuppressResync = mNLinesDeleted = mModifyingTabDistance = 0;
+}
+
+/*
+** Free a text display and release its associated memory.  Note, the text
+** BUFFER that the text display displays is a separate entity and is not
+** freed, nor are the style buffer or style table.
+*/
+Fl_Text_Display::~Fl_Text_Display() {
+  if (scroll_direction) {
+    Fl::remove_timeout(scroll_timer_cb, this);
+    scroll_direction = 0;
+  }
+  if (mBuffer) {
+    mBuffer->remove_modify_callback(buffer_modified_cb, this);
+    mBuffer->remove_predelete_callback(buffer_predelete_cb, this);
+  }
+  if (mLineStarts) delete[] mLineStarts;
+}
+
+/*
+** Attach a text buffer to display, replacing the current buffer (if any)
+*/
+void Fl_Text_Display::buffer( Fl_Text_Buffer *buf ) {
+  /* If the text display is already displaying a buffer, clear it off
+     of the display and remove our callback from it */
+  if ( buf == mBuffer) return;
+  if ( mBuffer != 0 ) {
+    buffer_modified_cb( 0, 0, mBuffer->length(), 0, 0, this );
+    mBuffer->remove_modify_callback( buffer_modified_cb, this );
+    mBuffer->remove_predelete_callback( buffer_predelete_cb, this );
+  }
+
+  /* Add the buffer to the display, and attach a callback to the buffer for
+     receiving modification information when the buffer contents change */
+  mBuffer = buf;
+  if (mBuffer) {
+    mBuffer->add_modify_callback( buffer_modified_cb, this );
+    mBuffer->add_predelete_callback( buffer_predelete_cb, this );
+
+    /* Update the display */
+    buffer_modified_cb( 0, buf->length(), 0, 0, 0, this );
+  }
+
+  /* Resize the widget to update the screen... */
+  resize(x(), y(), w(), h());
+}
+
+/*
+** Attach (or remove) highlight information in text display and redisplay.
+** Highlighting information consists of a style buffer which parallels the
+** normal text buffer, but codes font and color information for the display;
+** a style table which translates style buffer codes (indexed by buffer
+** character - 'A') into fonts and colors; and a callback mechanism for
+** as-needed highlighting, triggered by a style buffer entry of
+** "unfinishedStyle".  Style buffer can trigger additional redisplay during
+** a normal buffer modification if the buffer contains a primary Fl_Text_Selection
+** (see extendRangeForStyleMods for more information on this protocol).
+**
+** Style buffers, tables and their associated memory are managed by the caller.
+*/
+void
+Fl_Text_Display::highlight_data(Fl_Text_Buffer *styleBuffer,
+                                const Style_Table_Entry *styleTable,
+                                int nStyles, char unfinishedStyle,
+                                Unfinished_Style_Cb unfinishedHighlightCB,
+                                void *cbArg ) {
+  mStyleBuffer = styleBuffer;
+  mStyleTable = styleTable;
+  mNStyles = nStyles;
+  mUnfinishedStyle = unfinishedStyle;
+  mUnfinishedHighlightCB = unfinishedHighlightCB;
+  mHighlightCBArg = cbArg;
+
+  mStyleBuffer->canUndo(0);
+#if 0
+  // FIXME: this is in nedit code -- is it needed?	
+    /* Call TextDSetFont to combine font information from style table and
+       primary font, adjust font-related parameters, and then redisplay */
+    TextDSetFont(textD, textD->fontStruct);
+#endif
+  damage(FL_DAMAGE_EXPOSE);
+}
+
+#if 0
+  // FIXME: this is in nedit code -- is it needed?	
+/*
+** Change the (non highlight) font
+*/
+void TextDSetFont(textDisp *textD, XFontStruct *fontStruct) {
+    Display *display = XtDisplay(textD->w);
+    int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent;
+    int width, height, fontWidth;
+    Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel;
+    Pixel highlightFGPixel, highlightBGPixel;
+    XGCValues values;
+    XFontStruct *styleFont;
+    
+    /* If font size changes, cursor will be redrawn in a new position */
+    blankCursorProtrusions(textD);
+    
+    /* If there is a (syntax highlighting) style table in use, find the new
+       maximum font height for this text display */
+    for (i=0; i<textD->nStyles; i++) {
+    	styleFont = textD->styleTable[i].font;
+	if (styleFont != NULL && styleFont->ascent > maxAscent)
+    	    maxAscent = styleFont->ascent;
+    	if (styleFont != NULL && styleFont->descent > maxDescent)
+    	    maxDescent = styleFont->descent;
+    }
+    textD->ascent = maxAscent;
+    textD->descent = maxDescent;
+    
+    /* If all of the current fonts are fixed and match in width, compute */
+    fontWidth = fontStruct->max_bounds.width;
+    if (fontWidth != fontStruct->min_bounds.width)
+	fontWidth = -1;
+    else {
+	for (i=0; i<textD->nStyles; i++) {
+    	    styleFont = textD->styleTable[i].font;
+	    if (styleFont != NULL && (styleFont->max_bounds.width != fontWidth ||
+		    styleFont->max_bounds.width != styleFont->min_bounds.width))
+		fontWidth = -1;
+	}
+    }
+    textD->fixedFontWidth = fontWidth;
+    
+    /* Don't let the height dip below one line, or bad things can happen */
+    if (textD->height < maxAscent + maxDescent)
+        textD->height = maxAscent + maxDescent;
+
+    /* Change the font.  In most cases, this means re-allocating the
+       affected GCs (they are shared with other widgets, and if the primary
+       font changes, must be re-allocated to change it). Unfortunately,
+       this requres recovering all of the colors from the existing GCs */
+    textD->fontStruct = fontStruct;
+    XGetGCValues(display, textD->gc, GCForeground|GCBackground, &values);
+    fgPixel = values.foreground;
+    bgPixel = values.background;
+    XGetGCValues(display, textD->selectGC, GCForeground|GCBackground, &values);
+    selectFGPixel = values.foreground;
+    selectBGPixel = values.background;
+    XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values);
+    highlightFGPixel = values.foreground;
+    highlightBGPixel = values.background;
+    releaseGC(textD->w, textD->gc);
+    releaseGC(textD->w, textD->selectGC);
+    releaseGC(textD->w, textD->highlightGC);
+    releaseGC(textD->w, textD->selectBGGC);
+    releaseGC(textD->w, textD->highlightBGGC);
+    if (textD->lineNumGC != NULL)
+	releaseGC(textD->w, textD->lineNumGC);
+    textD->lineNumGC = NULL;
+    allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
+	    selectBGPixel, highlightFGPixel, highlightBGPixel);
+    XSetFont(display, textD->styleGC, fontStruct->fid);
+    
+    /* Do a full resize to force recalculation of font related parameters */
+    width = textD->width;
+    height = textD->height;
+    textD->width = textD->height = 0;
+    TextDResize(textD, width, height);
+    
+    /* Redisplay */
+    TextDRedisplayRect(textD, textD->left, textD->top, textD->width,
+    	    textD->height);
+    
+    /* Clean up line number area in case spacing has changed */
+    draw_line_numbers(textD, True);
+}
+
+int TextDMinFontWidth(textDisp *textD, Boolean considerStyles) {
+    int fontWidth = textD->fontStruct->max_bounds.width;
+    int i;
+
+    if (considerStyles) {
+        for (i = 0; i < textD->nStyles; ++i) {
+            int thisWidth = (textD->styleTable[i].font)->min_bounds.width;
+            if (thisWidth < fontWidth) {
+                fontWidth = thisWidth;
+            }
+        }
+    }
+    return(fontWidth);
+}
+
+int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles) {
+    int fontWidth = textD->fontStruct->max_bounds.width;
+    int i;
+
+    if (considerStyles) {
+        for (i = 0; i < textD->nStyles; ++i) {
+            int thisWidth = (textD->styleTable[i].font)->max_bounds.width;
+            if (thisWidth > fontWidth) {
+                fontWidth = thisWidth;
+            }
+        }
+    }
+    return(fontWidth);
+}
+#endif
+
+int Fl_Text_Display::longest_vline() {
+  int longest = 0;
+  for (int i = 0; i < mNVisibleLines; i++)
+    longest = max(longest, measure_vline(i));
+  return longest;
+}
+
+/*
+** Change the size of the displayed text area
+*/
+void Fl_Text_Display::resize(int X, int Y, int W, int H) {
+#ifdef DEBUG
+  printf("Fl_Text_Display::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H);
+#endif // DEBUG
+  const int oldWidth = w();
+#ifdef DEBUG
+  printf("    oldWidth=%d, mContinuousWrap=%d, mWrapMargin=%d\n", oldWidth,
+         mContinuousWrap, mWrapMargin);
+#endif // DEBUG
+  Fl_Widget::resize(X,Y,W,H);
+  if (!buffer()) return;
+  X += Fl::box_dx(box());
+  Y += Fl::box_dy(box());
+  W -= Fl::box_dw(box());
+  H -= Fl::box_dh(box());
+
+  text_area.x = X+LEFT_MARGIN;
+  text_area.y = Y+BOTTOM_MARGIN;
+  text_area.w = W-LEFT_MARGIN-RIGHT_MARGIN;
+  text_area.h = H-TOP_MARGIN-BOTTOM_MARGIN;
+  int i;
+
+  /* Find the new maximum font height for this text display */
+  for (i = 0, mMaxsize = fl_height(textfont(), textsize()); i < mNStyles; i++)
+    mMaxsize = max(mMaxsize, fl_height(mStyleTable[i].font, mStyleTable[i].size));
+
+  // did we have scrollbars initially?
+  int hscrollbarvisible = mHScrollBar->visible();
+  int vscrollbarvisible = mVScrollBar->visible();
+
+  // try without scrollbars first
+  mVScrollBar->clear_visible();
+  mHScrollBar->clear_visible();
+
+  for (int again = 1; again;) {
+     again = 0;
+    /* In continuous wrap mode, a change in width affects the total number of
+       lines in the buffer, and can leave the top line number incorrect, and
+       the top character no longer pointing at a valid line start */
+    if (mContinuousWrap && !mWrapMargin && W!=oldWidth) {
+      int oldFirstChar = mFirstChar;
+      mNBufferLines = count_lines(0, buffer()->length(), true);
+      mFirstChar = line_start(mFirstChar);
+      mTopLineNum = count_lines(0, mFirstChar, true)+1;
+      absolute_top_line_number(oldFirstChar);
+
+#ifdef DEBUG
+      printf("    mNBufferLines=%d\n", mNBufferLines);
+#endif // DEBUG
+    }
+ 
+    /* reallocate and update the line starts array, which may have changed
+       size and / or contents.  */
+    int nvlines = (text_area.h + mMaxsize - 1) / mMaxsize;
+    if (nvlines < 1) nvlines = 1;
+    if (mNVisibleLines != nvlines) {
+      mNVisibleLines = nvlines;
+      if (mLineStarts) delete[] mLineStarts;
+      mLineStarts = new int [mNVisibleLines];
+    }
+
+    calc_line_starts(0, mNVisibleLines);
+    calc_last_char();
+
+    // figure the scrollbars
+    if (scrollbar_width()) {
+      /* Decide if the vertical scroll bar needs to be visible */
+      if (scrollbar_align() & (FL_ALIGN_LEFT|FL_ALIGN_RIGHT) &&
+          mNBufferLines >= mNVisibleLines - 1)
+      {
+        mVScrollBar->set_visible();
+        if (scrollbar_align() & FL_ALIGN_LEFT) {
+          text_area.x = X+scrollbar_width()+LEFT_MARGIN;
+          text_area.w = W-scrollbar_width()-LEFT_MARGIN-RIGHT_MARGIN;
+          mVScrollBar->resize(X, text_area.y-TOP_MARGIN, scrollbar_width(),
+                              text_area.h+TOP_MARGIN+BOTTOM_MARGIN);
+        } else {
+          text_area.x = X+LEFT_MARGIN;
+          text_area.w = W-scrollbar_width()-LEFT_MARGIN-RIGHT_MARGIN;
+          mVScrollBar->resize(X+W-scrollbar_width(), text_area.y-TOP_MARGIN,
+                              scrollbar_width(), text_area.h+TOP_MARGIN+BOTTOM_MARGIN);
+        }
+      }
+
+      /*
+         Decide if the horizontal scroll bar needs to be visible.  If there
+         is a vertical scrollbar, a horizontal is always created too.  This
+         is because the alternatives are unatractive:
+          * Dynamically creating a horizontal scrollbar based on the currently
+            visible lines is what the original nedit does, but it always wastes
+            space for the scrollbar even when it's not used.  Since the FLTK
+            widget dynamically allocates the space for the scrollbar and
+            rearranges the widget to make room for it, this would create a very
+            visually displeasing "bounce" effect when the vertical scrollbar is
+            dragged.  Trust me, I tried it and it looks really bad.
+          * The other alternative would be to keep track of what the longest
+            line in the entire buffer is and base the scrollbar on that.  I
+            didn't do this because I didn't see any easy way to do that using
+            the nedit code and this could involve a lengthy calculation for
+            large buffers.  If an efficient and non-costly way of doing this
+            can be found, this might be a way to go.
+      */
+      /* WAS: Suggestion: Try turning the horizontal scrollbar on when
+	 you first see a line that is too wide in the window, but then
+	 don't turn it off (ie mix both of your solutions). */
+      if (scrollbar_align() & (FL_ALIGN_TOP|FL_ALIGN_BOTTOM) &&
+          (mVScrollBar->visible() || longest_vline() > text_area.w))
+      {
+        if (!mHScrollBar->visible()) {
+          mHScrollBar->set_visible();
+          again = 1; // loop again to see if we now need vert. & recalc sizes
+        }
+        if (scrollbar_align() & FL_ALIGN_TOP) {
+          text_area.y = Y + scrollbar_width()+TOP_MARGIN;
+          text_area.h = H - scrollbar_width()-TOP_MARGIN-BOTTOM_MARGIN;
+          mHScrollBar->resize(text_area.x-LEFT_MARGIN, Y,
+                              text_area.w+LEFT_MARGIN+RIGHT_MARGIN, scrollbar_width());
+        } else {
+          text_area.y = Y+TOP_MARGIN;
+          text_area.h = H - scrollbar_width()-TOP_MARGIN-BOTTOM_MARGIN;
+          mHScrollBar->resize(text_area.x-LEFT_MARGIN, Y+H-scrollbar_width(),
+                              text_area.w+LEFT_MARGIN+RIGHT_MARGIN, scrollbar_width());
+        }
+      }
+    }
+  }
+
+  // user request to change viewport
+  if (mTopLineNumHint != mTopLineNum || mHorizOffsetHint != mHorizOffset)
+    scroll_(mTopLineNumHint, mHorizOffsetHint);
+
+  // everything will fit in the viewport
+  if (mNBufferLines < mNVisibleLines || mBuffer == NULL || mBuffer->length() == 0)
+    scroll_(1, mHorizOffset);
+  /* if empty lines become visible, there may be an opportunity to
+     display more text by scrolling down */
+  else while (mLineStarts[mNVisibleLines-2] == -1)
+    scroll_(mTopLineNum-1, mHorizOffset);
+
+  // user request to display insert position
+  if (display_insert_position_hint)
+    display_insert();
+
+  // in case horizontal offset is now greater than longest line
+  int maxhoffset = max(0, longest_vline()-text_area.w);
+  if (mHorizOffset > maxhoffset)
+    scroll_(mTopLineNumHint, maxhoffset);
+
+  mTopLineNumHint = mTopLineNum;
+  mHorizOffsetHint = mHorizOffset;
+  display_insert_position_hint = 0;
+
+  if (mContinuousWrap ||
+      hscrollbarvisible != mHScrollBar->visible() ||
+      vscrollbarvisible != mVScrollBar->visible())
+    redraw();
+
+  update_v_scrollbar();
+  update_h_scrollbar();
+}
+
+/*
+** Refresh a rectangle of the text display.  left and top are in coordinates of
+** the text drawing window
+*/
+void Fl_Text_Display::draw_text( int left, int top, int width, int height ) {
+  int fontHeight, firstLine, lastLine, line;
+
+  /* find the line number range of the display */
+  fontHeight = mMaxsize ? mMaxsize : textsize_;
+  firstLine = ( top - text_area.y - fontHeight + 1 ) / fontHeight;
+  lastLine = ( top + height - text_area.y ) / fontHeight + 1;
+
+  fl_push_clip( left, top, width, height );
+
+  /* draw the lines */
+  for ( line = firstLine; line <= lastLine; line++ )
+    draw_vline( line, left, left + width, 0, INT_MAX );
+
+    /* draw the line numbers if exposed area includes them */
+    if (mLineNumWidth != 0 && left <= mLineNumLeft + mLineNumWidth)
+	draw_line_numbers(false);
+
+  fl_pop_clip();
+}
+
+void Fl_Text_Display::redisplay_range(int startpos, int endpos) {
+  if (damage_range1_start == -1 && damage_range1_end == -1) {
+    damage_range1_start = startpos;
+    damage_range1_end = endpos;
+  } else if ((startpos >= damage_range1_start && startpos <= damage_range1_end) ||
+             (endpos >= damage_range1_start && endpos <= damage_range1_end)) {
+    damage_range1_start = min(damage_range1_start, startpos);
+    damage_range1_end = max(damage_range1_end, endpos);
+  } else if (damage_range2_start == -1 && damage_range2_end == -1) {
+    damage_range2_start = startpos;
+    damage_range2_end = endpos;
+  } else {
+    damage_range2_start = min(damage_range2_start, startpos);
+    damage_range2_end = max(damage_range2_end, endpos);
+  }
+  damage(FL_DAMAGE_SCROLL);
+}
+/*
+** Refresh all of the text between buffer positions "start" and "end"
+** not including the character at the position "end".
+** If end points beyond the end of the buffer, refresh the whole display
+** after pos, including blank lines which are not technically part of
+** any range of characters.
+*/
+void Fl_Text_Display::draw_range(int startpos, int endpos) {
+  int i, startLine, lastLine, startIndex, endIndex;
+
+  /* If the range is outside of the displayed text, just return */
+  if ( endpos < mFirstChar || ( startpos > mLastChar &&
+       !empty_vlines() ) ) return;
+
+  /* Clean up the starting and ending values */
+  if ( startpos < 0 ) startpos = 0;
+  if ( startpos > mBuffer->length() ) startpos = mBuffer->length();
+  if ( endpos < 0 ) endpos = 0;
+  if ( endpos > mBuffer->length() ) endpos = mBuffer->length();
+
+  /* Get the starting and ending lines */
+  if ( startpos < mFirstChar )
+    startpos = mFirstChar;
+  if ( !position_to_line( startpos, &startLine ) )
+    startLine = mNVisibleLines - 1;
+  if ( endpos >= mLastChar ) {
+    lastLine = mNVisibleLines - 1;
+  } else {
+    if ( !position_to_line( endpos, &lastLine ) ) {
+      /* shouldn't happen */
+      lastLine = mNVisibleLines - 1;
+    }
+  }
+
+  /* Get the starting and ending positions within the lines */
+  startIndex = mLineStarts[ startLine ] == -1 ? 0 :
+               startpos - mLineStarts[ startLine ];
+  if ( endpos >= mLastChar )
+    endIndex = INT_MAX;
+  else if ( mLineStarts[ lastLine ] == -1 )
+    endIndex = 0;
+  else
+    endIndex = endpos - mLineStarts[ lastLine ];
+
+  /* If the starting and ending lines are the same, redisplay the single
+     line between "start" and "end" */
+  if ( startLine == lastLine ) {
+    draw_vline( startLine, 0, INT_MAX, startIndex, endIndex );
+    return;
+  }
+
+  /* Redisplay the first line from "start" */
+  draw_vline( startLine, 0, INT_MAX, startIndex, INT_MAX );
+
+  /* Redisplay the lines in between at their full width */
+  for ( i = startLine + 1; i < lastLine; i++ )
+    draw_vline( i, 0, INT_MAX, 0, INT_MAX );
+
+  /* Redisplay the last line to "end" */
+  draw_vline( lastLine, 0, INT_MAX, 0, endIndex );
+}
+
+/*
+** Set the position of the text insertion cursor for text display
+*/
+void Fl_Text_Display::insert_position( int newPos ) {
+  /* make sure new position is ok, do nothing if it hasn't changed */
+  if ( newPos == mCursorPos )
+    return;
+  if ( newPos < 0 ) newPos = 0;
+  if ( newPos > mBuffer->length() ) newPos = mBuffer->length();
+
+  /* cursor movement cancels vertical cursor motion column */
+  mCursorPreferredCol = -1;
+
+  /* erase the cursor at it's previous position */
+  redisplay_range(mCursorPos - 1, mCursorPos + 1);
+
+  mCursorPos = newPos;
+
+  /* draw cursor at its new position */
+  redisplay_range(mCursorPos - 1, mCursorPos + 1);
+}
+
+void Fl_Text_Display::show_cursor(int b) {
+  mCursorOn = b;
+  redisplay_range(mCursorPos - 1, mCursorPos + 1);
+}
+
+void Fl_Text_Display::cursor_style(int style) {
+  mCursorStyle = style;
+  if (mCursorOn) show_cursor();
+}
+
+void Fl_Text_Display::wrap_mode(int wrap, int wrapMargin) {
+  mWrapMargin = wrapMargin;
+  mContinuousWrap = wrap;
+
+  if (buffer()) {
+    /* wrapping can change change the total number of lines, re-count */
+    mNBufferLines = count_lines(0, buffer()->length(), true);
+
+    /* changing wrap margins wrap or changing from wrapped mode to non-wrapped
+       can leave the character at the top no longer at a line start, and/or
+       change the line number */
+    mFirstChar = line_start(mFirstChar);
+    mTopLineNum = count_lines(0, mFirstChar, true) + 1;
+
+    reset_absolute_top_line_number();
+
+    /* update the line starts array */
+    calc_line_starts(0, mNVisibleLines);
+    calc_last_char();
+  } else {
+    // No buffer, so just clear the state info for later...
+    mNBufferLines  = 0;
+    mFirstChar     = 0;
+    mTopLineNum    = 1;
+    mAbsTopLineNum = 0;
+  }
+
+  resize(x(), y(), w(), h());
+}
+
+/*
+** Insert "text" at the current cursor location.  This has the same
+** effect as inserting the text into the buffer using BufInsert and
+** then moving the insert position after the newly inserted text, except
+** that it's optimized to do less redrawing.
+*/
+void Fl_Text_Display::insert(const char* text) {
+  int pos = mCursorPos;
+
+  mCursorToHint = pos + strlen( text );
+  mBuffer->insert( pos, text );
+  mCursorToHint = NO_HINT;
+}
+
+/*
+** Insert "text" (which must not contain newlines), overstriking the current
+** cursor location.
+*/
+void Fl_Text_Display::overstrike(const char* text) {
+  int startPos = mCursorPos;
+  Fl_Text_Buffer *buf = mBuffer;
+  int lineStart = buf->line_start( startPos );
+  int textLen = strlen( text );
+  int i, p, endPos, indent, startIndent, endIndent;
+  const char *c;
+  char ch, *paddedText = NULL;
+
+  /* determine how many displayed character positions are covered */
+  startIndent = mBuffer->count_displayed_characters( lineStart, startPos );
+  indent = startIndent;
+  for ( c = text; *c != '\0'; c++ )
+    indent += Fl_Text_Buffer::character_width( *c, indent, buf->tab_distance(), buf->null_substitution_character() );
+  endIndent = indent;
+
+  /* find which characters to remove, and if necessary generate additional
+     padding to make up for removed control characters at the end */
+  indent = startIndent;
+  for ( p = startPos; ; p++ ) {
+    if ( p == buf->length() )
+      break;
+    ch = buf->character( p );
+    if ( ch == '\n' )
+      break;
+    indent += Fl_Text_Buffer::character_width( ch, indent, buf->tab_distance(), buf->null_substitution_character() );
+    if ( indent == endIndent ) {
+      p++;
+      break;
+    } else if ( indent > endIndent ) {
+      if ( ch != '\t' ) {
+        p++;
+        paddedText = new char [ textLen + FL_TEXT_MAX_EXP_CHAR_LEN + 1 ];
+        strcpy( paddedText, text );
+        for ( i = 0; i < indent - endIndent; i++ )
+          paddedText[ textLen + i ] = ' ';
+        paddedText[ textLen + i ] = '\0';
+      }
+      break;
+    }
+  }
+  endPos = p;
+
+  mCursorToHint = startPos + textLen;
+  buf->replace( startPos, endPos, paddedText == NULL ? text : paddedText );
+  mCursorToHint = NO_HINT;
+  if ( paddedText != NULL )
+    delete [] paddedText;
+}
+
+/*
+** Translate a buffer text position to the XY location where the top left
+** of the cursor would be positioned to point to that character.  Returns
+** 0 if the position is not displayed because it is VERTICALLY out
+** of view.  If the position is horizontally out of view, returns the
+** X coordinate where the position would be if it were visible.
+*/
+
+int Fl_Text_Display::position_to_xy( int pos, int* X, int* Y ) {
+  int charIndex, lineStartPos, fontHeight, lineLen;
+  int visLineNum, charLen, outIndex, xStep, charStyle;
+  char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ];
+  const char *lineStr;
+
+//  printf("position_to_xy(pos=%d, X=%p, Y=%p)\n", pos, X, Y);
+
+  /* If position is not displayed, return false */
+  if (pos < mFirstChar || (pos > mLastChar && !empty_vlines())) {
+//    printf("    returning 0\n"
+//           "    mFirstChar=%d, mLastChar=%d, empty_vlines()=0\n",
+//	   mFirstChar, mLastChar);
+    return 0;
+  }
+
+  /* Calculate Y coordinate */
+  if (!position_to_line(pos, &visLineNum)) {
+//    puts("    returning 0\n"
+//         "    position_to_line()=0");
+    return 0;
+  }
+
+  if (visLineNum < 0 || visLineNum > mNBufferLines) {
+//    printf("    returning 0\n"
+//           "    visLineNum=%d, mNBufferLines=%d\n",
+//	   visLineNum, mNBufferLines);
+    return 0;
+  }
+
+  fontHeight = mMaxsize;
+  *Y = text_area.y + visLineNum * fontHeight;
+
+  /* Get the text, length, and  buffer position of the line. If the position
+     is beyond the end of the buffer and should be at the first position on
+     the first empty line, don't try to get or scan the text  */
+  lineStartPos = mLineStarts[visLineNum];
+  if ( lineStartPos == -1 ) {
+    *X = text_area.x - mHorizOffset;
+    return 1;
+  }
+  lineLen = vline_length( visLineNum );
+  lineStr = mBuffer->text_range( lineStartPos, lineStartPos + lineLen );
+
+  /* Step through character positions from the beginning of the line
+     to "pos" to calculate the X coordinate */
+  xStep = text_area.x - mHorizOffset;
+  outIndex = 0;
+  for ( charIndex = 0; charIndex < lineLen && charIndex < pos - lineStartPos; charIndex++ ) {
+    charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar,
+              mBuffer->tab_distance(), mBuffer->null_substitution_character() );
+    charStyle = position_style( lineStartPos, lineLen, charIndex,
+                                outIndex );
+    xStep += string_width( expandedChar, charLen, charStyle );
+    outIndex += charLen;
+  }
+  *X = xStep;
+  free((char *)lineStr);
+  return 1;
+}
+
+/*
+** Find the line number of position "pos".  Note: this only works for
+** displayed lines.  If the line is not displayed, the function returns
+** 0 (without the mLineStarts array it could turn in to very long
+** calculation involving scanning large amounts of text in the buffer).
+** If continuous wrap mode is on, returns the absolute line number (as opposed
+** to the wrapped line number which is used for scrolling).
+*/
+int Fl_Text_Display::position_to_linecol( int pos, int* lineNum, int* column ) {
+  int retVal;
+    
+    /* In continuous wrap mode, the absolute (non-wrapped) line count is
+       maintained separately, as needed.  Only return it if we're actually
+       keeping track of it and pos is in the displayed text */
+    if (mContinuousWrap) {
+	if (!maintaining_absolute_top_line_number() ||
+       pos < mFirstChar || pos > mLastChar)
+	    return 0;
+	*lineNum = mAbsTopLineNum + buffer()->count_lines(mFirstChar, pos);
+	*column
+     = buffer()->count_displayed_characters(buffer()->line_start(pos), pos);
+	return 1;
+    }
+
+  retVal = position_to_line( pos, lineNum );
+  if ( retVal ) {
+    *column = mBuffer->count_displayed_characters(
+                mLineStarts[ *lineNum ], pos );
+    *lineNum += mTopLineNum;
+  }
+  return retVal;
+}
+
+/*
+** Return 1 if position (X, Y) is inside of the primary Fl_Text_Selection
+*/
+int Fl_Text_Display::in_selection( int X, int Y ) {
+  int row, column, pos = xy_to_position( X, Y, CHARACTER_POS );
+  Fl_Text_Buffer *buf = mBuffer;
+
+  xy_to_rowcol( X, Y, &row, &column, CHARACTER_POS );
+  if (range_touches_selection(buf->primary_selection(), mFirstChar, mLastChar))
+    column = wrapped_column(row, column);
+  return buf->primary_selection()->includes(pos, buf->line_start( pos ), column);
+}
+
+/*
+** Correct a column number based on an unconstrained position (as returned by
+** TextDXYToUnconstrainedPosition) to be relative to the last actual newline
+** in the buffer before the row and column position given, rather than the
+** last line start created by line wrapping.  This is an adapter
+** for rectangular selections and code written before continuous wrap mode,
+** which thinks that the unconstrained column is the number of characters
+** from the last newline.  Obviously this is time consuming, because it
+** invloves character re-counting.
+*/
+int Fl_Text_Display::wrapped_column(int row, int column) {
+    int lineStart, dispLineStart;
+    
+    if (!mContinuousWrap || row < 0 || row > mNVisibleLines)
+    	return column;
+    dispLineStart = mLineStarts[row];
+    if (dispLineStart == -1)
+    	return column;
+    lineStart = buffer()->line_start(dispLineStart);
+    return column
+		 + buffer()->count_displayed_characters(lineStart, dispLineStart);
+}
+
+/*
+** Correct a row number from an unconstrained position (as returned by
+** TextDXYToUnconstrainedPosition) to a straight number of newlines from the
+** top line of the display.  Because rectangular selections are based on
+** newlines, rather than display wrapping, and anywhere a rectangular selection
+** needs a row, it needs it in terms of un-wrapped lines.
+*/
+int Fl_Text_Display::wrapped_row(int row) {
+    if (!mContinuousWrap || row < 0 || row > mNVisibleLines)
+    	return row;
+    return buffer()->count_lines(mFirstChar, mLineStarts[row]);
+}
+
+/*
+** Scroll the display to bring insertion cursor into view.
+**
+** Note: it would be nice to be able to do this without counting lines twice
+** (scroll_() counts them too) and/or to count from the most efficient
+** starting point, but the efficiency of this routine is not as important to
+** the overall performance of the text display.
+*/
+void Fl_Text_Display::display_insert() {
+  int hOffset, topLine, X, Y;
+  hOffset = mHorizOffset;
+  topLine = mTopLineNum;
+
+//	FIXME: I don't understand this well enough to know if it is correct
+//	       it is different than nedit 5.3
+  if (insert_position() < mFirstChar) {
+    topLine -= count_lines(insert_position(), mFirstChar, false);
+  } else if (mLineStarts[mNVisibleLines-2] != -1) {
+    int lastChar = buffer()->line_end(mLineStarts[mNVisibleLines-2]);
+    if (insert_position() >= lastChar)
+      topLine
+        += count_lines(lastChar - (wrap_uses_character(mLastChar) ? 0 : 1),
+                        insert_position(), false);
+  }
+
+  /* Find the new setting for horizontal offset (this is a bit ungraceful).
+     If the line is visible, just use PositionToXY to get the position
+     to scroll to, otherwise, do the vertical scrolling first, then the
+     horizontal */
+  if (!position_to_xy( mCursorPos, &X, &Y )) {
+    scroll_(topLine, hOffset);
+    if (!position_to_xy( mCursorPos, &X, &Y ))
+      return;   /* Give up, it's not worth it (but why does it fail?) */
+  }
+  if (X > text_area.x + text_area.w)
+    hOffset += X-(text_area.x + text_area.w);
+  else if (X < text_area.x)
+    hOffset += X-text_area.x;
+
+  /* Do the scroll */
+  if (topLine != mTopLineNum || hOffset != mHorizOffset)
+    scroll_(topLine, hOffset);
+}
+
+void Fl_Text_Display::show_insert_position() {
+  display_insert_position_hint = 1;
+  resize(x(), y(), w(), h());
+}
+
+/*
+** Cursor movement functions
+*/
+int Fl_Text_Display::move_right() {
+  if ( mCursorPos >= mBuffer->length() )
+    return 0;
+  insert_position( mCursorPos + 1 );
+  return 1;
+}
+
+int Fl_Text_Display::move_left() {
+  if ( mCursorPos <= 0 )
+    return 0;
+  insert_position( mCursorPos - 1 );
+  return 1;
+}
+
+int Fl_Text_Display::move_up() {
+  int lineStartPos, column, prevLineStartPos, newPos, visLineNum;
+
+  /* Find the position of the start of the line.  Use the line starts array
+     if possible */
+  if ( position_to_line( mCursorPos, &visLineNum ) )
+    lineStartPos = mLineStarts[ visLineNum ];
+  else {
+    lineStartPos = buffer()->line_start( mCursorPos );
+    visLineNum = -1;
+  }
+  if ( lineStartPos == 0 )
+    return 0;
+
+  /* Decide what column to move to, if there's a preferred column use that */
+  column = mCursorPreferredCol >= 0 ? mCursorPreferredCol :
+           mBuffer->count_displayed_characters( lineStartPos, mCursorPos );
+
+  /* count forward from the start of the previous line to reach the column */
+  if ( visLineNum != -1 && visLineNum != 0 )
+    prevLineStartPos = mLineStarts[ visLineNum - 1 ];
+  else
+    prevLineStartPos = buffer()->rewind_lines( lineStartPos, 1 );
+  newPos = mBuffer->skip_displayed_characters( prevLineStartPos, column );
+    if (mContinuousWrap)
+    	newPos = min(newPos, line_end(prevLineStartPos, true));
+
+  /* move the cursor */
+  insert_position( newPos );
+
+  /* if a preferred column wasn't aleady established, establish it */
+  mCursorPreferredCol = column;
+  return 1;
+}
+
+int Fl_Text_Display::move_down() {
+  int lineStartPos, column, nextLineStartPos, newPos, visLineNum;
+
+  if ( mCursorPos == mBuffer->length() )
+    return 0;
+  if ( position_to_line( mCursorPos, &visLineNum ) )
+    lineStartPos = mLineStarts[ visLineNum ];
+  else {
+    lineStartPos = buffer()->line_start( mCursorPos );
+    visLineNum = -1;
+  }
+  column = mCursorPreferredCol >= 0 ? mCursorPreferredCol :
+           mBuffer->count_displayed_characters( lineStartPos, mCursorPos );
+  nextLineStartPos = skip_lines( lineStartPos, 1, true );
+  newPos = mBuffer->skip_displayed_characters( nextLineStartPos, column );
+    if (mContinuousWrap)
+    	newPos = min(newPos, line_end(nextLineStartPos, true));
+
+  insert_position( newPos );
+  mCursorPreferredCol = column;
+  return 1;
+}
+
+/*
+** Same as BufCountLines, but takes in to account wrapping if wrapping is
+** turned on.  If the caller knows that startPos is at a line start, it
+** can pass "startPosIsLineStart" as True to make the call more efficient
+** by avoiding the additional step of scanning back to the last newline.
+*/
+int Fl_Text_Display::count_lines(int startPos, int endPos,
+    	bool startPosIsLineStart) {
+    int retLines, retPos, retLineStart, retLineEnd;
+
+#ifdef DEBUG
+    printf("Fl_Text_Display::count_line(startPos=%d, endPos=%d, startPosIsLineStart=%d\n",
+           startPos, endPos, startPosIsLineStart);
+#endif // DEBUG
+
+    /* If we're not wrapping use simple (and more efficient) BufCountLines */
+    if (!mContinuousWrap)
+    	return buffer()->count_lines(startPos, endPos);
+    
+    wrapped_line_counter(buffer(), startPos, endPos, INT_MAX,
+	    startPosIsLineStart, 0, &retPos, &retLines, &retLineStart,
+	    &retLineEnd);
+
+#ifdef DEBUG
+    printf("retPos=%d, retLines=%d, retLineStart=%d, retLineEnd=%d\n",
+           retPos, retLines, retLineStart, retLineEnd);
+#endif // DEBUG
+
+    return retLines;
+}
+
+/*
+** Same as BufCountForwardNLines, but takes in to account line breaks when
+** wrapping is turned on. If the caller knows that startPos is at a line start,
+** it can pass "startPosIsLineStart" as True to make the call more efficient
+** by avoiding the additional step of scanning back to the last newline.
+*/
+int Fl_Text_Display::skip_lines(int startPos, int nLines,
+    bool startPosIsLineStart) {
+    int retLines, retPos, retLineStart, retLineEnd;
+    
+    /* if we're not wrapping use more efficient BufCountForwardNLines */
+    if (!mContinuousWrap)
+    	return buffer()->skip_lines(startPos, nLines);
+    
+    /* wrappedLineCounter can't handle the 0 lines case */
+    if (nLines == 0)
+    	return startPos;
+    
+    /* use the common line counting routine to count forward */
+    wrapped_line_counter(buffer(), startPos, buffer()->length(),
+    	    nLines, startPosIsLineStart, 0, &retPos, &retLines, &retLineStart,
+    	    &retLineEnd);
+    return retPos;
+}
+
+/*
+** Same as BufEndOfLine, but takes in to account line breaks when wrapping
+** is turned on.  If the caller knows that startPos is at a line start, it
+** can pass "startPosIsLineStart" as True to make the call more efficient
+** by avoiding the additional step of scanning back to the last newline.
+**
+** Note that the definition of the end of a line is less clear when continuous
+** wrap is on.  With continuous wrap off, it's just a pointer to the newline
+** that ends the line.  When it's on, it's the character beyond the last
+** DISPLAYABLE character on the line, where a whitespace character which has
+** been "converted" to a newline for wrapping is not considered displayable.
+** Also note that, a line can be wrapped at a non-whitespace character if the
+** line had no whitespace.  In this case, this routine returns a pointer to
+** the start of the next line.  This is also consistent with the model used by
+** visLineLength.
+*/
+int Fl_Text_Display::line_end(int pos, bool startPosIsLineStart) {
+    int retLines, retPos, retLineStart, retLineEnd;
+    
+    /* If we're not wrapping use more efficien BufEndOfLine */
+    if (!mContinuousWrap)
+    	return buffer()->line_end(pos);
+    
+    if (pos == buffer()->length())
+    	return pos;
+    wrapped_line_counter(buffer(), pos, buffer()->length(), 1,
+    	    startPosIsLineStart, 0, &retPos, &retLines, &retLineStart,
+	    &retLineEnd);
+    return retLineEnd;
+}
+
+/*
+** Same as BufStartOfLine, but returns the character after last wrap point
+** rather than the last newline.
+*/
+int Fl_Text_Display::line_start(int pos) {
+    int retLines, retPos, retLineStart, retLineEnd;
+    
+    /* If we're not wrapping, use the more efficient BufStartOfLine */
+    if (!mContinuousWrap)
+    	return buffer()->line_start(pos);
+
+    wrapped_line_counter(buffer(), buffer()->line_start(pos), pos, INT_MAX, true, 0,
+			 &retPos, &retLines, &retLineStart, &retLineEnd);
+    return retLineStart;
+}
+
+/*
+** Same as BufCountBackwardNLines, but takes in to account line breaks when
+** wrapping is turned on.
+*/
+int Fl_Text_Display::rewind_lines(int startPos, int nLines) {
+    Fl_Text_Buffer *buf = buffer();
+    int pos, lineStart, retLines, retPos, retLineStart, retLineEnd;
+    
+    /* If we're not wrapping, use the more efficient BufCountBackwardNLines */
+    if (!mContinuousWrap)
+    	return buf->rewind_lines(startPos, nLines);
+
+    pos = startPos;
+    while (true) {
+	lineStart = buf->line_start(pos);
+	wrapped_line_counter(buf, lineStart, pos, INT_MAX,
+	    	true, 0, &retPos, &retLines, &retLineStart, &retLineEnd);
+	if (retLines > nLines)
+    	    return skip_lines(lineStart, retLines-nLines,
+    	    	    true);
+    	nLines -= retLines;
+    	pos = lineStart - 1;
+    	if (pos < 0)
+    	    return 0;
+    	nLines -= 1;
+    }
+}
+
+static inline int fl_isseparator(int c) {
+  return c != '$' && c != '_' && (isspace(c) || ispunct(c));
+}
+
+void Fl_Text_Display::next_word() {
+  int pos = insert_position();
+  while (pos < buffer()->length() && !fl_isseparator(buffer()->character(pos))) {
+    pos++;
+  }
+  while (pos < buffer()->length() && fl_isseparator(buffer()->character(pos))) {
+    pos++;
+  }
+
+  insert_position( pos );
+}
+
+void Fl_Text_Display::previous_word() {
+  int pos = insert_position();
+  if (pos==0) return;
+  pos--;
+  while (pos && fl_isseparator(buffer()->character(pos))) {
+    pos--;
+  }
+  while (pos && !fl_isseparator(buffer()->character(pos))) {
+    pos--;
+  }
+  if (fl_isseparator(buffer()->character(pos))) pos++;
+
+  insert_position( pos );
+}
+
+/*
+** Callback attached to the text buffer to receive delete information before
+** the modifications are actually made.
+*/
+void Fl_Text_Display::buffer_predelete_cb(int pos, int nDeleted, void *cbArg) {
+    Fl_Text_Display *textD = (Fl_Text_Display *)cbArg;
+    if (textD->mContinuousWrap && 
+        (textD->mFixedFontWidth == -1 || textD->mModifyingTabDistance))
+	/* Note: we must perform this measurement, even if there is not a
+	   single character deleted; the number of "deleted" lines is the
+	   number of visual lines spanned by the real line in which the 
+	   modification takes place. 
+	   Also, a modification of the tab distance requires the same
+	   kind of calculations in advance, even if the font width is "fixed",
+	   because when the width of the tab characters changes, the layout 
+	   of the text may be completely different. */
+	textD->measure_deleted_lines(pos, nDeleted);
+    else
+	textD->mSuppressResync = 0; /* Probably not needed, but just in case */
+}
+
+/*
+** Callback attached to the text buffer to receive modification information
+*/
+void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted,
+    int nRestyled, const char *deletedText, void *cbArg ) {
+  int linesInserted, linesDeleted, startDispPos, endDispPos;
+  Fl_Text_Display *textD = ( Fl_Text_Display * ) cbArg;
+  Fl_Text_Buffer *buf = textD->mBuffer;
+  int oldFirstChar = textD->mFirstChar;
+  int scrolled, origCursorPos = textD->mCursorPos;
+  int wrapModStart, wrapModEnd;
+
+  /* buffer modification cancels vertical cursor motion column */
+  if ( nInserted != 0 || nDeleted != 0 )
+    textD->mCursorPreferredCol = -1;
+
+    /* Count the number of lines inserted and deleted, and in the case
+       of continuous wrap mode, how much has changed */
+    if (textD->mContinuousWrap) {
+    	textD->find_wrap_range(deletedText, pos, nInserted, nDeleted,
+    	    	&wrapModStart, &wrapModEnd, &linesInserted, &linesDeleted);
+    } else {
+   linesInserted = nInserted == 0 ? 0 :
+                  buf->count_lines( pos, pos + nInserted );
+   linesDeleted = nDeleted == 0 ? 0 : countlines( deletedText );
+    }
+
+  /* Update the line starts and mTopLineNum */
+  if ( nInserted != 0 || nDeleted != 0 ) {
+   if (textD->mContinuousWrap) {
+     textD->update_line_starts( wrapModStart, wrapModEnd-wrapModStart,
+                     nDeleted + pos-wrapModStart + (wrapModEnd-(pos+nInserted)),
+                     linesInserted, linesDeleted, &scrolled );
+   } else {
+     textD->update_line_starts( pos, nInserted, nDeleted, linesInserted,
+                               linesDeleted, &scrolled );
+   }
+  } else
+    scrolled = 0;
+
+    /* If we're counting non-wrapped lines as well, maintain the absolute
+       (non-wrapped) line number of the text displayed */
+    if (textD->maintaining_absolute_top_line_number() &&
+        (nInserted != 0 || nDeleted != 0)) {
+	if (pos + nDeleted < oldFirstChar)
+	    textD->mAbsTopLineNum += buf->count_lines(pos, pos + nInserted) -
+		    countlines(deletedText);
+	else if (pos < oldFirstChar)
+	    textD->reset_absolute_top_line_number();
+    }    	    
+
+  /* Update the line count for the whole buffer */
+  textD->mNBufferLines += linesInserted - linesDeleted;
+
+  /* Update the cursor position */
+  if ( textD->mCursorToHint != NO_HINT ) {
+    textD->mCursorPos = textD->mCursorToHint;
+    textD->mCursorToHint = NO_HINT;
+  } else if ( textD->mCursorPos > pos ) {
+    if ( textD->mCursorPos < pos + nDeleted )
+      textD->mCursorPos = pos;
+    else
+      textD->mCursorPos += nInserted - nDeleted;
+  }
+
+  // refigure scrollbars & stuff
+  textD->resize(textD->x(), textD->y(), textD->w(), textD->h());
+
+  // don't need to do anything else if not visible?
+  if (!textD->visible_r()) return;
+
+  /* If the changes caused scrolling, re-paint everything and we're done. */
+  if ( scrolled ) {
+    textD->damage(FL_DAMAGE_EXPOSE);
+    if ( textD->mStyleBuffer )   /* See comments in extendRangeForStyleMods */
+      textD->mStyleBuffer->primary_selection()->selected(0);
+    return;
+  }
+
+  /* If the changes didn't cause scrolling, decide the range of characters
+     that need to be re-painted.  Also if the cursor position moved, be
+     sure that the redisplay range covers the old cursor position so the
+     old cursor gets erased, and erase the bits of the cursor which extend
+     beyond the left and right edges of the text. */
+  startDispPos = textD->mContinuousWrap ? wrapModStart : pos;
+  if ( origCursorPos == startDispPos && textD->mCursorPos != startDispPos )
+    startDispPos = min( startDispPos, origCursorPos - 1 );
+  if ( linesInserted == linesDeleted ) {
+    if ( nInserted == 0 && nDeleted == 0 )
+      endDispPos = pos + nRestyled;
+    else {
+      endDispPos = textD->mContinuousWrap ? wrapModEnd :
+            buf->line_end( pos + nInserted ) + 1;
+      // CET - FIXME      if ( origCursorPos >= startDispPos &&
+      //                ( origCursorPos <= endDispPos || endDispPos == buf->length() ) )
+    }
+
+	if (linesInserted > 1) textD->draw_line_numbers(false);
+  } else {
+    endDispPos = textD->mLastChar + 1;
+    // CET - FIXME   if ( origCursorPos >= pos )
+        /* If more than one line is inserted/deleted, a line break may have
+           been inserted or removed in between, and the line numbers may
+           have changed. If only one line is altered, line numbers cannot
+           be affected (the insertion or removal of a line break always 
+           results in at least two lines being redrawn). */
+	textD->draw_line_numbers(false);
+  }
+
+  /* If there is a style buffer, check if the modification caused additional
+     changes that need to be redisplayed.  (Redisplaying separately would
+     cause double-redraw on almost every modification involving styled
+     text).  Extend the redraw range to incorporate style changes */
+  if ( textD->mStyleBuffer )
+    textD->extend_range_for_styles( &startDispPos, &endDispPos );
+
+  /* Redisplay computed range */
+  textD->redisplay_range( startDispPos, endDispPos );
+}
+
+/*
+** In continuous wrap mode, internal line numbers are calculated after
+** wrapping.  A separate non-wrapped line count is maintained when line
+** numbering is turned on.  There is some performance cost to maintaining this
+** line count, so normally absolute line numbers are not tracked if line
+** numbering is off.  This routine allows callers to specify that they still
+** want this line count maintained (for use via TextDPosToLineAndCol).
+** More specifically, this allows the line number reported in the statistics
+** line to be calibrated in absolute lines, rather than post-wrapped lines.
+*/
+void Fl_Text_Display::maintain_absolute_top_line_number(int state) {
+    mNeedAbsTopLineNum = state;
+    reset_absolute_top_line_number();
+}
+
+/*
+** Returns the absolute (non-wrapped) line number of the first line displayed.
+** Returns 0 if the absolute top line number is not being maintained.
+*/
+int Fl_Text_Display::get_absolute_top_line_number() {
+    if (!mContinuousWrap)
+	return mTopLineNum;
+    if (maintaining_absolute_top_line_number())
+	return mAbsTopLineNum;
+    return 0;
+}
+
+/*
+** Re-calculate absolute top line number for a change in scroll position.
+*/
+void Fl_Text_Display::absolute_top_line_number(int oldFirstChar) {
+    if (maintaining_absolute_top_line_number()) {
+	if (mFirstChar < oldFirstChar)
+	    mAbsTopLineNum -= buffer()->count_lines(mFirstChar, oldFirstChar);
+	else
+	    mAbsTopLineNum += buffer()->count_lines(oldFirstChar, mFirstChar);
+    }
+}
+
+/*
+** Return true if a separate absolute top line number is being maintained
+** (for displaying line numbers or showing in the statistics line).
+*/
+int Fl_Text_Display::maintaining_absolute_top_line_number() {
+    return mContinuousWrap &&
+	    (mLineNumWidth != 0 || mNeedAbsTopLineNum);
+}
+
+/*
+** Count lines from the beginning of the buffer to reestablish the
+** absolute (non-wrapped) top line number.  If mode is not continuous wrap,
+** or the number is not being maintained, does nothing.
+*/
+void Fl_Text_Display::reset_absolute_top_line_number() {
+    mAbsTopLineNum = 1;
+    absolute_top_line_number(0);
+}
+
+/*
+** Find the line number of position "pos" relative to the first line of
+** displayed text. Returns 0 if the line is not displayed.
+*/
+int Fl_Text_Display::position_to_line( int pos, int *lineNum ) {
+  int i;
+
+  *lineNum = 0;
+  if ( pos < mFirstChar ) return 0;
+  if ( pos > mLastChar ) {
+    if ( empty_vlines() ) {
+      if ( mLastChar < mBuffer->length() ) {
+        if ( !position_to_line( mLastChar, lineNum ) ) {
+          Fl::error("Fl_Text_Display::position_to_line(): Consistency check ptvl failed");
+          return 0;
+        }
+        return ++( *lineNum ) <= mNVisibleLines - 1;
+      } else {
+        position_to_line( mLastChar - 1, lineNum );
+        return 1;
+      }
+    }
+    return 0;
+  }
+
+  for ( i = mNVisibleLines - 1; i >= 0; i-- ) {
+    if ( mLineStarts[ i ] != -1 && pos >= mLineStarts[ i ] ) {
+      *lineNum = i;
+      return 1;
+    }
+  }
+  return 0;   /* probably never be reached */
+}
+
+/*
+** Draw the text on a single line represented by "visLineNum" (the
+** number of lines down from the top of the display), limited by
+** "leftClip" and "rightClip" window coordinates and "leftCharIndex" and
+** "rightCharIndex" character positions (not including the character at
+** position "rightCharIndex").
+*/
+void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip,
+                                 int leftCharIndex, int rightCharIndex) {
+  Fl_Text_Buffer * buf = mBuffer;
+  int i, X, Y, startX, charIndex, lineStartPos, lineLen, fontHeight;
+  int stdCharWidth, charWidth, startIndex, charStyle, style;
+  int charLen, outStartIndex, outIndex;
+  int dispIndexOffset;
+  char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ], outStr[ MAX_DISP_LINE_LEN ];
+  char *outPtr;
+  const char *lineStr;
+
+//  printf("draw_vline(visLineNum=%d, leftClip=%d, rightClip=%d, leftCharIndex=%d, rightCharIndex=%d)\n",
+//         visLineNum, leftClip, rightClip, leftCharIndex, rightCharIndex);
+//  printf("nNVisibleLines=%d\n", mNVisibleLines);
+
+  /* If line is not displayed, skip it */
+  if ( visLineNum < 0 || visLineNum >= mNVisibleLines )
+    return;
+
+  /* Calculate Y coordinate of the string to draw */
+  fontHeight = mMaxsize;
+  Y = text_area.y + visLineNum * fontHeight;
+
+  /* Get the text, length, and  buffer position of the line to display */
+  lineStartPos = mLineStarts[ visLineNum ];
+//  printf("lineStartPos=%d\n", lineStartPos);
+  if ( lineStartPos == -1 ) {
+    lineLen = 0;
+    lineStr = NULL;
+  } else {
+    lineLen = vline_length( visLineNum );
+    lineStr = buf->text_range( lineStartPos, lineStartPos + lineLen );
+  }
+
+  /* Space beyond the end of the line is still counted in units of characters
+     of a standardized character width (this is done mostly because style
+     changes based on character position can still occur in this region due
+	  to rectangular Fl_Text_Selections).  stdCharWidth must be non-zero to
+     prevent a potential infinite loop if X does not advance */
+  stdCharWidth = TMPFONTWIDTH;   //mFontStruct->max_bounds.width;
+  if ( stdCharWidth <= 0 ) {
+    Fl::error("Fl_Text_Display::draw_vline(): bad font measurement");
+    free((void *)lineStr);
+    return;
+  }
+
+  /* Shrink the clipping range to the active display area */
+  leftClip = max( text_area.x, leftClip );
+  rightClip = min( rightClip, text_area.x + text_area.w );
+
+  /* Rectangular Fl_Text_Selections are based on "real" line starts (after
+	  a newline or start of buffer).  Calculate the difference between the
+	  last newline position and the line start we're using.  Since scanning
+	  back to find a newline is expensive, only do so if there's actually a
+	  rectangular Fl_Text_Selection which needs it */
+    if (mContinuousWrap && (range_touches_selection(buf->primary_selection(),
+    	    lineStartPos, lineStartPos + lineLen) || range_touches_selection(
+    	    buf->secondary_selection(), lineStartPos, lineStartPos + lineLen) ||
+    	    range_touches_selection(buf->highlight_selection(), lineStartPos,
+    	    lineStartPos + lineLen))) {
+    	dispIndexOffset = buf->count_displayed_characters(
+    	    	buf->line_start(lineStartPos), lineStartPos);
+    } else
+    	dispIndexOffset = 0;
+
+  /* Step through character positions from the beginning of the line (even if
+     that's off the left edge of the displayed area) to find the first
+     character position that's not clipped, and the X coordinate for drawing
+     that character */
+  X = text_area.x - mHorizOffset;
+  outIndex = 0;
+  for ( charIndex = 0; ; charIndex++ ) {
+    charLen = charIndex >= lineLen ? 1 :
+              Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex,
+                                                expandedChar, buf->tab_distance(), buf->null_substitution_character() );
+    style = position_style( lineStartPos, lineLen, charIndex,
+                            outIndex + dispIndexOffset );
+    charWidth = charIndex >= lineLen ? stdCharWidth :
+                string_width( expandedChar, charLen, style );
+    if ( X + charWidth >= leftClip && charIndex >= leftCharIndex ) {
+      startIndex = charIndex;
+      outStartIndex = outIndex;
+      startX = X;
+      break;
+    }
+    X += charWidth;
+    outIndex += charLen;
+  }
+
+  /* Scan character positions from the beginning of the clipping range, and
+     draw parts whenever the style changes (also note if the cursor is on
+     this line, and where it should be drawn to take advantage of the x
+     position which we've gone to so much trouble to calculate) */
+  /* since characters between style may overlap, we draw the full 
+     background first */
+  int sX = startX;
+  outPtr = outStr;
+  outIndex = outStartIndex;
+  X = startX;
+  for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) {
+    charLen = charIndex >= lineLen ? 1 :
+              Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar,
+                                                buf->tab_distance(), buf->null_substitution_character() );
+    charStyle = position_style( lineStartPos, lineLen, charIndex,
+                                outIndex + dispIndexOffset );
+    for ( i = 0; i < charLen; i++ ) {
+      if ( i != 0 && charIndex < lineLen && lineStr[ charIndex ] == '\t' )
+        charStyle = position_style( lineStartPos, lineLen,
+                                    charIndex, outIndex + dispIndexOffset );
+      if ( charStyle != style ) {
+        draw_string( style|BG_ONLY_MASK, sX, Y, X, outStr, outPtr - outStr );
+        outPtr = outStr;
+        sX = X;
+        style = charStyle;
+      }
+      if ( charIndex < lineLen ) {
+        *outPtr = expandedChar[ i ];
+        charWidth = string_width( &expandedChar[ i ], 1, charStyle );
+      } else
+        charWidth = stdCharWidth;
+      outPtr++;
+      X += charWidth;
+      outIndex++;
+    }
+    if ( outPtr - outStr + FL_TEXT_MAX_EXP_CHAR_LEN >= MAX_DISP_LINE_LEN || X >= rightClip )
+      break;
+  }
+  draw_string( style|BG_ONLY_MASK, sX, Y, X, outStr, outPtr - outStr );
+
+  /* now draw the text over the previously erased background */
+  outPtr = outStr;
+  outIndex = outStartIndex;
+  X = startX;
+  for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) {
+    charLen = charIndex >= lineLen ? 1 :
+              Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar,
+                                                buf->tab_distance(), buf->null_substitution_character() );
+    charStyle = position_style( lineStartPos, lineLen, charIndex,
+                                outIndex + dispIndexOffset );
+    for ( i = 0; i < charLen; i++ ) {
+      if ( i != 0 && charIndex < lineLen && lineStr[ charIndex ] == '\t' )
+        charStyle = position_style( lineStartPos, lineLen,
+                                    charIndex, outIndex + dispIndexOffset );
+      if ( charStyle != style ) {
+        draw_string( style|TEXT_ONLY_MASK, startX, Y, X, outStr, outPtr - outStr );
+        outPtr = outStr;
+        startX = X;
+        style = charStyle;
+      }
+      if ( charIndex < lineLen ) {
+        *outPtr = expandedChar[ i ];
+        charWidth = string_width( &expandedChar[ i ], 1, charStyle );
+      } else
+        charWidth = stdCharWidth;
+      outPtr++;
+      X += charWidth;
+      outIndex++;
+    }
+    if ( outPtr - outStr + FL_TEXT_MAX_EXP_CHAR_LEN >= MAX_DISP_LINE_LEN || X >= rightClip )
+      break;
+  }
+
+  /* Draw the remaining style segment */
+  draw_string( style|TEXT_ONLY_MASK, startX, Y, X, outStr, outPtr - outStr );
+
+  /* Draw the cursor if part of it appeared on the redisplayed part of
+     this line.  Also check for the cases which are not caught as the
+     line is scanned above: when the cursor appears at the very end
+     of the redisplayed section. */
+  /*  CET - FIXME
+    if ( mCursorOn )
+    {
+      if ( hasCursor )
+        draw_cursor( cursorX, Y );
+      else if ( charIndex < lineLen && ( lineStartPos + charIndex + 1 == cursorPos )
+                && X == rightClip )
+      {
+        if ( cursorPos >= buf->length() )
+          draw_cursor( X - 1, Y );
+        else
+        {
+          draw_cursor( X - 1, Y );
+        }
+      }
+    }
+  */
+  if ( lineStr != NULL )
+    free((void *)lineStr);
+}
+
+/*
+** Draw a string or blank area according to parameter "style", using the
+** appropriate colors and drawing method for that style, with top left
+** corner at X, y.  If style says to draw text, use "string" as source of
+** characters, and draw "nChars", if style is FILL, erase
+** rectangle where text would have drawn from X to toX and from Y to
+** the maximum Y extent of the current font(s).
+*/
+void Fl_Text_Display::draw_string( int style, int X, int Y, int toX,
+                                   const char *string, int nChars ) {
+  const Style_Table_Entry * styleRec;
+
+  /* Draw blank area rather than text, if that was the request */
+  if ( style & FILL_MASK ) {
+    if (style & TEXT_ONLY_MASK) return;
+    clear_rect( style, X, Y, toX - X, mMaxsize );
+    return;
+  }
+
+  /* Set font, color, and gc depending on style.  For normal text, GCs
+     for normal drawing, or drawing within a Fl_Text_Selection or highlight are
+     pre-allocated and pre-configured.  For syntax highlighting, GCs are
+     configured here, on the fly. */
+
+  Fl_Font font = textfont();
+  int fsize = textsize();
+  Fl_Color foreground;
+  Fl_Color background;
+
+  if ( style & STYLE_LOOKUP_MASK ) {
+    int si = (style & STYLE_LOOKUP_MASK) - 'A';
+    if (si < 0) si = 0;
+    else if (si >= mNStyles) si = mNStyles - 1;
+
+    styleRec = mStyleTable + si;
+    font  = styleRec->font;
+    fsize = styleRec->size;
+
+    if (style & (HIGHLIGHT_MASK | PRIMARY_MASK)) {
+      if (Fl::focus() == this) background = selection_color();
+      else background = fl_color_average(color(), selection_color(), 0.5f);
+    } else background = color();
+
+    foreground = fl_contrast(styleRec->color, background);
+  } else if (style & (HIGHLIGHT_MASK | PRIMARY_MASK)) {
+    if (Fl::focus() == this) background = selection_color();
+    else background = fl_color_average(color(), selection_color(), 0.5f);
+    foreground = fl_contrast(textcolor(), background);
+  } else {
+    foreground = textcolor();
+    background = color();
+  }
+
+  if (!(style & TEXT_ONLY_MASK)) {
+    fl_color( background );
+    fl_rectf( X, Y, toX - X, mMaxsize );
+  }
+  if (!(style & BG_ONLY_MASK)) {
+    fl_color( foreground );
+    fl_font( font, fsize );
+    fl_draw( string, nChars, X, Y + mMaxsize - fl_descent());
+  }
+
+  // CET - FIXME
+  /* If any space around the character remains unfilled (due to use of
+     different sized fonts for highlighting), fill in above or below
+     to erase previously drawn characters */
+  /*
+      if (fs->ascent < mAscent)
+        clear_rect( style, X, Y, toX - X, mAscent - fs->ascent);
+      if (fs->descent < mDescent)
+        clear_rect( style, X, Y + mAscent + fs->descent, toX - x,
+                mDescent - fs->descent);
+  */
+  /* Underline if style is secondary Fl_Text_Selection */
+
+  /*
+      if (style & SECONDARY_MASK)
+        XDrawLine(XtDisplay(mW), XtWindow(mW), gc, x,
+                y + mAscent, toX - 1, Y + fs->ascent);
+  */
+}
+
+/*
+** Clear a rectangle with the appropriate background color for "style"
+*/
+void Fl_Text_Display::clear_rect( int style, int X, int Y,
+                                  int width, int height ) {
+  /* A width of zero means "clear to end of window" to XClearArea */
+  if ( width == 0 )
+    return;
+
+  if ( Fl::focus() != this ) {
+    if (style & (HIGHLIGHT_MASK | PRIMARY_MASK)) {
+      fl_color(fl_color_average(color(), selection_color(), 0.5f));
+    } else {
+      fl_color( color() );
+    }
+    fl_rectf( X, Y, width, height );
+  } else if ( style & HIGHLIGHT_MASK ) {
+    fl_color( fl_contrast(textcolor(), color()) );
+    fl_rectf( X, Y, width, height );
+  } else if ( style & PRIMARY_MASK ) {
+    fl_color( selection_color() );
+    fl_rectf( X, Y, width, height );
+  } else {
+    fl_color( color() );
+    fl_rectf( X, Y, width, height );
+  }
+}
+
+
+
+/*
+** Draw a cursor with top center at X, y.
+*/
+void Fl_Text_Display::draw_cursor( int X, int Y ) {
+  typedef struct {
+    int x1, y1, x2, y2;
+  }
+  Segment;
+
+  Segment segs[ 5 ];
+  int left, right, cursorWidth, midY;
+  //    int fontWidth = mFontStruct->min_bounds.width, nSegs = 0;
+  int fontWidth = TMPFONTWIDTH; // CET - FIXME
+  int nSegs = 0;
+  int fontHeight = mMaxsize;
+  int bot = Y + fontHeight - 1;
+
+  if ( X < text_area.x - 1 || X > text_area.x + text_area.w )
+    return;
+
+  /* For cursors other than the block, make them around 2/3 of a character
+     width, rounded to an even number of pixels so that X will draw an
+     odd number centered on the stem at x. */
+  cursorWidth = 4;   //(fontWidth/3) * 2;
+  left = X - cursorWidth / 2;
+  right = left + cursorWidth;
+
+  /* Create segments and draw cursor */
+  if ( mCursorStyle == CARET_CURSOR ) {
+    midY = bot - fontHeight / 5;
+    segs[ 0 ].x1 = left; segs[ 0 ].y1 = bot; segs[ 0 ].x2 = X; segs[ 0 ].y2 = midY;
+    segs[ 1 ].x1 = X; segs[ 1 ].y1 = midY; segs[ 1 ].x2 = right; segs[ 1 ].y2 = bot;
+    segs[ 2 ].x1 = left; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = midY - 1;
+    segs[ 3 ].x1 = X; segs[ 3 ].y1 = midY - 1; segs[ 3 ].x2 = right; segs[ 3 ].y2 = bot;
+    nSegs = 4;
+  } else if ( mCursorStyle == NORMAL_CURSOR ) {
+    segs[ 0 ].x1 = left; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = right; segs[ 0 ].y2 = Y;
+    segs[ 1 ].x1 = X; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = X; segs[ 1 ].y2 = bot;
+    segs[ 2 ].x1 = left; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = right; segs[ 2 ].y2 = bot;
+    nSegs = 3;
+  } else if ( mCursorStyle == HEAVY_CURSOR ) {
+    segs[ 0 ].x1 = X - 1; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = X - 1; segs[ 0 ].y2 = bot;
+    segs[ 1 ].x1 = X; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = X; segs[ 1 ].y2 = bot;
+    segs[ 2 ].x1 = X + 1; segs[ 2 ].y1 = Y; segs[ 2 ].x2 = X + 1; segs[ 2 ].y2 = bot;
+    segs[ 3 ].x1 = left; segs[ 3 ].y1 = Y; segs[ 3 ].x2 = right; segs[ 3 ].y2 = Y;
+    segs[ 4 ].x1 = left; segs[ 4 ].y1 = bot; segs[ 4 ].x2 = right; segs[ 4 ].y2 = bot;
+    nSegs = 5;
+  } else if ( mCursorStyle == DIM_CURSOR ) {
+    midY = Y + fontHeight / 2;
+    segs[ 0 ].x1 = X; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = X; segs[ 0 ].y2 = Y;
+    segs[ 1 ].x1 = X; segs[ 1 ].y1 = midY; segs[ 1 ].x2 = X; segs[ 1 ].y2 = midY;
+    segs[ 2 ].x1 = X; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = bot;
+    nSegs = 3;
+  } else if ( mCursorStyle == BLOCK_CURSOR ) {
+    right = X + fontWidth;
+    segs[ 0 ].x1 = X; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = right; segs[ 0 ].y2 = Y;
+    segs[ 1 ].x1 = right; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = right; segs[ 1 ].y2 = bot;
+    segs[ 2 ].x1 = right; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = bot;
+    segs[ 3 ].x1 = X; segs[ 3 ].y1 = bot; segs[ 3 ].x2 = X; segs[ 3 ].y2 = Y;
+    nSegs = 4;
+  }
+  fl_color( mCursor_color );
+
+  for ( int k = 0; k < nSegs; k++ ) {
+    fl_line( segs[ k ].x1, segs[ k ].y1, segs[ k ].x2, segs[ k ].y2 );
+  }
+}
+
+/*
+** Determine the drawing method to use to draw a specific character from "buf".
+** "lineStartPos" gives the character index where the line begins, "lineIndex",
+** the number of characters past the beginning of the line, and "dispIndex",
+** the number of displayed characters past the beginning of the line.  Passing
+** lineStartPos of -1 returns the drawing style for "no text".
+**
+** Why not just: position_style(pos)?  Because style applies to blank areas
+** of the window beyond the text boundaries, and because this routine must also
+** decide whether a position is inside of a rectangular Fl_Text_Selection, and do
+** so efficiently, without re-counting character positions from the start of the
+** line.
+**
+** Note that style is a somewhat incorrect name, drawing method would
+** be more appropriate.
+*/
+int Fl_Text_Display::position_style( int lineStartPos,
+                                     int lineLen, int lineIndex, int dispIndex ) {
+  Fl_Text_Buffer * buf = mBuffer;
+  Fl_Text_Buffer *styleBuf = mStyleBuffer;
+  int pos, style = 0;
+
+  if ( lineStartPos == -1 || buf == NULL )
+    return FILL_MASK;
+
+  pos = lineStartPos + min( lineIndex, lineLen );
+
+  if ( lineIndex >= lineLen )
+    style = FILL_MASK;
+  else if ( styleBuf != NULL ) {
+    style = ( unsigned char ) styleBuf->character( pos );
+    if (style == mUnfinishedStyle && mUnfinishedHighlightCB) {
+        /* encountered "unfinished" style, trigger parsing */
+        (mUnfinishedHighlightCB)( pos, mHighlightCBArg);
+        style = (unsigned char) styleBuf->character( pos);
+    }
+  }
+  if (buf->primary_selection()->includes(pos, lineStartPos, dispIndex))
+    style |= PRIMARY_MASK;
+  if (buf->highlight_selection()->includes(pos, lineStartPos, dispIndex))
+    style |= HIGHLIGHT_MASK;
+  if (buf->secondary_selection()->includes(pos, lineStartPos, dispIndex))
+    style |= SECONDARY_MASK;
+  return style;
+}
+
+/*
+** Find the width of a string in the font of a particular style
+*/
+int Fl_Text_Display::string_width( const char *string, int length, int style ) {
+  Fl_Font font;
+  int fsize;
+
+  if ( style & STYLE_LOOKUP_MASK ) {
+    int si = (style & STYLE_LOOKUP_MASK) - 'A';
+    if (si < 0) si = 0;
+    else if (si >= mNStyles) si = mNStyles - 1;
+
+    font  = mStyleTable[si].font;
+    fsize = mStyleTable[si].size;
+  } else {
+    font  = textfont();
+    fsize = textsize();
+  }
+  fl_font( font, fsize );
+
+  return ( int ) ( fl_width( string, length ) );
+}
+
+/*
+** Translate window coordinates to the nearest (insert cursor or character
+** cell) text position.  The parameter posType specifies how to interpret the
+** position: CURSOR_POS means translate the coordinates to the nearest cursor
+** position, and CHARACTER_POS means return the position of the character
+** closest to (X, Y).
+*/
+int Fl_Text_Display::xy_to_position( int X, int Y, int posType ) {
+  int charIndex, lineStart, lineLen, fontHeight;
+  int charWidth, charLen, charStyle, visLineNum, xStep, outIndex;
+  char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ];
+  const char *lineStr;
+
+  /* Find the visible line number corresponding to the Y coordinate */
+  fontHeight = mMaxsize;
+  visLineNum = ( Y - text_area.y ) / fontHeight;
+  if ( visLineNum < 0 )
+    return mFirstChar;
+  if ( visLineNum >= mNVisibleLines )
+    visLineNum = mNVisibleLines - 1;
+
+  /* Find the position at the start of the line */
+  lineStart = mLineStarts[ visLineNum ];
+
+  /* If the line start was empty, return the last position in the buffer */
+  if ( lineStart == -1 )
+    return mBuffer->length();
+
+  /* Get the line text and its length */
+  lineLen = vline_length( visLineNum );
+  lineStr = mBuffer->text_range( lineStart, lineStart + lineLen );
+
+  /* Step through character positions from the beginning of the line
+     to find the character position corresponding to the X coordinate */
+  xStep = text_area.x - mHorizOffset;
+  outIndex = 0;
+  for ( charIndex = 0; charIndex < lineLen; charIndex++ ) {
+    charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar,
+              mBuffer->tab_distance(), mBuffer->null_substitution_character() );
+    charStyle = position_style( lineStart, lineLen, charIndex, outIndex );
+    charWidth = string_width( expandedChar, charLen, charStyle );
+    if ( X < xStep + ( posType == CURSOR_POS ? charWidth / 2 : charWidth ) ) {
+      free((char *)lineStr);
+      return lineStart + charIndex;
+    }
+    xStep += charWidth;
+    outIndex += charLen;
+  }
+
+  /* If the X position was beyond the end of the line, return the position
+     of the newline at the end of the line */
+  free((char *)lineStr);
+  return lineStart + lineLen;
+}
+
+/*
+** Translate window coordinates to the nearest row and column number for
+** positioning the cursor.  This, of course, makes no sense when the font is
+** proportional, since there are no absolute columns.  The parameter posType
+** specifies how to interpret the position: CURSOR_POS means translate the
+** coordinates to the nearest position between characters, and CHARACTER_POS
+** means translate the position to the nearest character cell.
+*/
+void Fl_Text_Display::xy_to_rowcol( int X, int Y, int *row,
+                                    int *column, int posType ) {
+  int fontHeight = mMaxsize;
+  int fontWidth = TMPFONTWIDTH;   //mFontStruct->max_bounds.width;
+
+  /* Find the visible line number corresponding to the Y coordinate */
+  *row = ( Y - text_area.y ) / fontHeight;
+  if ( *row < 0 ) * row = 0;
+  if ( *row >= mNVisibleLines ) * row = mNVisibleLines - 1;
+  *column = ( ( X - text_area.x ) + mHorizOffset +
+              ( posType == CURSOR_POS ? fontWidth / 2 : 0 ) ) / fontWidth;
+  if ( *column < 0 ) * column = 0;
+}
+
+/*
+** Offset the line starts array, mTopLineNum, mFirstChar and lastChar, for a new
+** vertical scroll position given by newTopLineNum.  If any currently displayed
+** lines will still be visible, salvage the line starts values, otherwise,
+** count lines from the nearest known line start (start or end of buffer, or
+** the closest value in the mLineStarts array)
+*/
+void Fl_Text_Display::offset_line_starts( int newTopLineNum ) {
+  int oldTopLineNum = mTopLineNum;
+  int oldFirstChar = mFirstChar;
+  int lineDelta = newTopLineNum - oldTopLineNum;
+  int nVisLines = mNVisibleLines;
+  int *lineStarts = mLineStarts;
+  int i, lastLineNum;
+  Fl_Text_Buffer *buf = mBuffer;
+
+  /* If there was no offset, nothing needs to be changed */
+  if ( lineDelta == 0 )
+    return;
+
+  /* Find the new value for mFirstChar by counting lines from the nearest
+     known line start (start or end of buffer, or the closest value in the
+     lineStarts array) */
+  lastLineNum = oldTopLineNum + nVisLines - 1;
+  if ( newTopLineNum < oldTopLineNum && newTopLineNum < -lineDelta ) {
+    mFirstChar = skip_lines( 0, newTopLineNum - 1, true );
+  } else if ( newTopLineNum < oldTopLineNum ) {
+    mFirstChar = buffer()->rewind_lines( mFirstChar, -lineDelta );
+  } else if ( newTopLineNum < lastLineNum ) {
+    mFirstChar = lineStarts[ newTopLineNum - oldTopLineNum ];
+  } else if ( newTopLineNum - lastLineNum < mNBufferLines - newTopLineNum ) {
+    mFirstChar = skip_lines( lineStarts[ nVisLines - 1 ],
+                                       newTopLineNum - lastLineNum, true );
+  } else {
+    mFirstChar = buffer()->rewind_lines( buf->length(), mNBufferLines - newTopLineNum + 1 );
+  }
+
+  /* Fill in the line starts array */
+  if ( lineDelta < 0 && -lineDelta < nVisLines ) {
+    for ( i = nVisLines - 1; i >= -lineDelta; i-- )
+      lineStarts[ i ] = lineStarts[ i + lineDelta ];
+    calc_line_starts( 0, -lineDelta );
+  } else if ( lineDelta > 0 && lineDelta < nVisLines ) {
+    for ( i = 0; i < nVisLines - lineDelta; i++ )
+      lineStarts[ i ] = lineStarts[ i + lineDelta ];
+    calc_line_starts( nVisLines - lineDelta, nVisLines - 1 );
+  } else
+    calc_line_starts( 0, nVisLines );
+
+  /* Set lastChar and mTopLineNum */
+  calc_last_char();
+  mTopLineNum = newTopLineNum;
+
+    /* If we're numbering lines or being asked to maintain an absolute line
+       number, re-calculate the absolute line number */
+    absolute_top_line_number(oldFirstChar);
+}
+
+/*
+** Update the line starts array, mTopLineNum, mFirstChar and lastChar for text
+** display "textD" after a modification to the text buffer, given by the
+** position where the change began "pos", and the nmubers of characters
+** and lines inserted and deleted.
+*/
+void Fl_Text_Display::update_line_starts( int pos, int charsInserted,
+    int charsDeleted, int linesInserted, int linesDeleted, int *scrolled ) {
+  int * lineStarts = mLineStarts;
+  int i, lineOfPos, lineOfEnd, nVisLines = mNVisibleLines;
+  int charDelta = charsInserted - charsDeleted;
+  int lineDelta = linesInserted - linesDeleted;
+
+  /* If all of the changes were before the displayed text, the display
+     doesn't change, just update the top line num and offset the line
+     start entries and first and last characters */
+  if ( pos + charsDeleted < mFirstChar ) {
+    mTopLineNum += lineDelta;
+    for ( i = 0; i < nVisLines && lineStarts[i] != -1; i++ )
+      lineStarts[ i ] += charDelta;
+    mFirstChar += charDelta;
+    mLastChar += charDelta;
+    *scrolled = 0;
+    return;
+  }
+
+  /* The change began before the beginning of the displayed text, but
+     part or all of the displayed text was deleted */
+  if ( pos < mFirstChar ) {
+    /* If some text remains in the window, anchor on that  */
+    if ( position_to_line( pos + charsDeleted, &lineOfEnd ) &&
+         ++lineOfEnd < nVisLines && lineStarts[ lineOfEnd ] != -1 ) {
+      mTopLineNum = max( 1, mTopLineNum + lineDelta );
+      mFirstChar = buffer()->rewind_lines(
+            lineStarts[ lineOfEnd ] + charDelta, lineOfEnd );
+      /* Otherwise anchor on original line number and recount everything */
+    } else {
+      if ( mTopLineNum > mNBufferLines + lineDelta ) {
+        mTopLineNum = 1;
+        mFirstChar = 0;
+      } else
+        mFirstChar = skip_lines( 0, mTopLineNum - 1, true );
+    }
+    calc_line_starts( 0, nVisLines - 1 );
+    /* calculate lastChar by finding the end of the last displayed line */
+    calc_last_char();
+    *scrolled = 1;
+    return;
+  }
+
+  /* If the change was in the middle of the displayed text (it usually is),
+     salvage as much of the line starts array as possible by moving and
+     offsetting the entries after the changed area, and re-counting the
+     added lines or the lines beyond the salvaged part of the line starts
+     array */
+  if ( pos <= mLastChar ) {
+    /* find line on which the change began */
+    position_to_line( pos, &lineOfPos );
+    /* salvage line starts after the changed area */
+    if ( lineDelta == 0 ) {
+      for ( i = lineOfPos + 1; i < nVisLines && lineStarts[ i ] != -1; i++ )
+        lineStarts[ i ] += charDelta;
+    } else if ( lineDelta > 0 ) {
+      for ( i = nVisLines - 1; i >= lineOfPos + lineDelta + 1; i-- )
+        lineStarts[ i ] = lineStarts[ i - lineDelta ] +
+                          ( lineStarts[ i - lineDelta ] == -1 ? 0 : charDelta );
+    } else /* (lineDelta < 0) */ {
+      for ( i = max( 0, lineOfPos + 1 ); i < nVisLines + lineDelta; i++ )
+        lineStarts[ i ] = lineStarts[ i - lineDelta ] +
+                          ( lineStarts[ i - lineDelta ] == -1 ? 0 : charDelta );
+    }
+    /* fill in the missing line starts */
+    if ( linesInserted >= 0 )
+      calc_line_starts( lineOfPos + 1, lineOfPos + linesInserted );
+    if ( lineDelta < 0 )
+      calc_line_starts( nVisLines + lineDelta, nVisLines );
+    /* calculate lastChar by finding the end of the last displayed line */
+    calc_last_char();
+    *scrolled = 0;
+    return;
+  }
+
+  /* Change was past the end of the displayed text, but displayable by virtue
+     of being an insert at the end of the buffer into visible blank lines */
+  if ( empty_vlines() ) {
+    position_to_line( pos, &lineOfPos );
+    calc_line_starts( lineOfPos, lineOfPos + linesInserted );
+    calc_last_char();
+    *scrolled = 0;
+    return;
+  }
+
+  /* Change was beyond the end of the buffer and not visible, do nothing */
+  *scrolled = 0;
+}
+
+/*
+** Scan through the text in the "textD"'s buffer and recalculate the line
+** starts array values beginning at index "startLine" and continuing through
+** (including) "endLine".  It assumes that the line starts entry preceding
+** "startLine" (or mFirstChar if startLine is 0) is good, and re-counts
+** newlines to fill in the requested entries.  Out of range values for
+** "startLine" and "endLine" are acceptable.
+*/
+void Fl_Text_Display::calc_line_starts( int startLine, int endLine ) {
+  int startPos, bufLen = mBuffer->length();
+  int line, lineEnd, nextLineStart, nVis = mNVisibleLines;
+  int *lineStarts = mLineStarts;
+
+  /* Clean up (possibly) messy input parameters */
+  if ( endLine < 0 ) endLine = 0;
+  if ( endLine >= nVis ) endLine = nVis - 1;
+  if ( startLine < 0 ) startLine = 0;
+  if ( startLine >= nVis ) startLine = nVis - 1;
+  if ( startLine > endLine )
+    return;
+
+  /* Find the last known good line number -> position mapping */
+  if ( startLine == 0 ) {
+    lineStarts[ 0 ] = mFirstChar;
+    startLine = 1;
+  }
+  startPos = lineStarts[ startLine - 1 ];
+
+  /* If the starting position is already past the end of the text,
+     fill in -1's (means no text on line) and return */
+  if ( startPos == -1 ) {
+    for ( line = startLine; line <= endLine; line++ )
+      lineStarts[ line ] = -1;
+    return;
+  }
+
+  /* Loop searching for ends of lines and storing the positions of the
+     start of the next line in lineStarts */
+  for ( line = startLine; line <= endLine; line++ ) {
+    find_line_end(startPos, true, &lineEnd, &nextLineStart);
+    startPos = nextLineStart;
+    if ( startPos >= bufLen ) {
+      /* If the buffer ends with a newline or line break, put
+         buf->length() in the next line start position (instead of
+         a -1 which is the normal marker for an empty line) to
+         indicate that the cursor may safely be displayed there */
+      if ( line == 0 || ( lineStarts[ line - 1 ] != bufLen &&
+                          lineEnd != nextLineStart ) ) {
+        lineStarts[ line ] = bufLen;
+        line++;
+      }
+      break;
+    }
+    lineStarts[ line ] = startPos;
+  }
+
+  /* Set any entries beyond the end of the text to -1 */
+  for ( ; line <= endLine; line++ )
+    lineStarts[ line ] = -1;
+}
+
+/*
+** Given a Fl_Text_Display with a complete, up-to-date lineStarts array, update
+** the lastChar entry to point to the last buffer position displayed.
+*/
+void Fl_Text_Display::calc_last_char() {
+  int i;
+  for (i = mNVisibleLines - 1; i >= 0 && mLineStarts[i] == -1; i--) ;
+  mLastChar = i < 0 ? 0 : line_end(mLineStarts[i], true);
+}
+
+void Fl_Text_Display::scroll(int topLineNum, int horizOffset) {
+  mTopLineNumHint = topLineNum;
+  mHorizOffsetHint = horizOffset;
+  resize(x(), y(), w(), h());
+}
+
+void Fl_Text_Display::scroll_(int topLineNum, int horizOffset) {
+  /* Limit the requested scroll position to allowable values */
+  if (topLineNum > mNBufferLines + 3 - mNVisibleLines)
+    topLineNum = mNBufferLines + 3 - mNVisibleLines;
+  if (topLineNum < 1) topLineNum = 1;
+
+  if (horizOffset > longest_vline() - text_area.w)
+    horizOffset = longest_vline() - text_area.w;
+  if (horizOffset < 0) horizOffset = 0;
+
+  /* Do nothing if scroll position hasn't actually changed or there's no
+     window to draw in yet */
+  if (mHorizOffset == horizOffset && mTopLineNum == topLineNum)
+    return;
+
+  /* If the vertical scroll position has changed, update the line
+     starts array and related counters in the text display */
+  offset_line_starts(topLineNum);
+
+  /* Just setting mHorizOffset is enough information for redisplay */
+  mHorizOffset = horizOffset;
+
+  // redraw all text
+  damage(FL_DAMAGE_EXPOSE);
+}
+
+/*
+** Update the minimum, maximum, slider size, page increment, and value
+** for vertical scroll bar.
+*/
+void Fl_Text_Display::update_v_scrollbar() {
+  /* The Vert. scroll bar value and slider size directly represent the top
+     line number, and the number of visible lines respectively.  The scroll
+     bar maximum value is chosen to generally represent the size of the whole
+     buffer, with minor adjustments to keep the scroll bar widget happy */
+#ifdef DEBUG
+  printf("Fl_Text_Display::update_v_scrollbar():\n"
+         "    mTopLineNum=%d, mNVisibleLines=%d, mNBufferLines=%d\n",
+	 mTopLineNum, mNVisibleLines, mNBufferLines);
+#endif // DEBUG
+
+  mVScrollBar->value(mTopLineNum, mNVisibleLines, 1, mNBufferLines+2);
+  mVScrollBar->linesize(3);
+}
+
+/*
+** Update the minimum, maximum, slider size, page increment, and value
+** for the horizontal scroll bar.
+*/
+void Fl_Text_Display::update_h_scrollbar() {
+  int sliderMax = max(longest_vline(), text_area.w + mHorizOffset);
+  mHScrollBar->value( mHorizOffset, text_area.w, 0, sliderMax );
+}
+
+/*
+** Callbacks for drag or valueChanged on scroll bars
+*/
+void Fl_Text_Display::v_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) {
+  if (b->value() == textD->mTopLineNum) return;
+  textD->scroll(b->value(), textD->mHorizOffset);
+}
+
+void Fl_Text_Display::h_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) {
+  if (b->value() == textD->mHorizOffset) return;
+  textD->scroll(textD->mTopLineNum, b->value());
+}
+
+/*
+** Refresh the line number area.  If clearAll is False, writes only over
+** the character cell areas.  Setting clearAll to True will clear out any
+** stray marks outside of the character cell area, which might have been
+** left from before a resize or font change.
+*/
+void Fl_Text_Display::draw_line_numbers(bool clearAll) {
+#if 0
+	 // FIXME: don't want this yet, so will leave for another time
+
+    int y, line, visLine, nCols, lineStart;
+    char lineNumString[12];
+    int lineHeight = mMaxsize ? mMaxsize : textsize_;
+    int charWidth = TMPFONTWIDTH;   //mFontStruct->max_bounds.width;
+    
+    /* Don't draw if mLineNumWidth == 0 (line numbers are hidden), or widget is
+       not yet realized */
+    if (mLineNumWidth == 0 || visible_r())
+    	return;
+    
+    /* GC is allocated on demand, since not everyone will use line numbering */
+    if (textD->lineNumGC == NULL) {
+	XGCValues values;
+ 	values.foreground = textD->lineNumFGPixel;
+	values.background = textD->bgPixel;
+	values.font = textD->fontStruct->fid;
+   	textD->lineNumGC = XtGetGC(textD->w,
+		GCFont| GCForeground | GCBackground, &values);
+    }
+    
+    /* Erase the previous contents of the line number area, if requested */
+    if (clearAll)
+    	XClearArea(XtDisplay(textD->w), XtWindow(textD->w), textD->lineNumLeft,
+		textD->top, textD->lineNumWidth, textD->height, False);
+    
+    /* Draw the line numbers, aligned to the text */
+    nCols = min(11, textD->lineNumWidth / charWidth);
+    y = textD->top;
+    line = getAbsTopLineNum(textD);
+    for (visLine=0; visLine < textD->nVisibleLines; visLine++) {
+	lineStart = textD->lineStarts[visLine];
+	if (lineStart != -1 && (lineStart==0 ||
+		BufGetCharacter(textD->buffer, lineStart-1)=='\n')) {
+	    sprintf(lineNumString, "%*d", nCols, line);
+	    XDrawImageString(XtDisplay(textD->w), XtWindow(textD->w),
+		    textD->lineNumGC, textD->lineNumLeft, y + textD->ascent,
+		    lineNumString, strlen(lineNumString));
+	    line++;
+	} else {
+	    XClearArea(XtDisplay(textD->w), XtWindow(textD->w),
+		    textD->lineNumLeft, y, textD->lineNumWidth,
+		    textD->ascent + textD->descent, False);
+	    if (visLine == 0)
+		line++;
+	}
+	y += lineHeight;
+    }
+#endif
+}
+
+static int max( int i1, int i2 ) {
+  return i1 >= i2 ? i1 : i2;
+}
+
+static int min( int i1, int i2 ) {
+  return i1 <= i2 ? i1 : i2;
+}
+
+/*
+** Count the number of newlines in a null-terminated text string;
+*/
+static int countlines( const char *string ) {
+  const char * c;
+  int lineCount = 0;
+
+  if (!string) return 0;
+
+  for ( c = string; *c != '\0'; c++ )
+    if ( *c == '\n' ) lineCount++;
+  return lineCount;
+}
+
+/*
+** Return the width in pixels of the displayed line pointed to by "visLineNum"
+*/
+int Fl_Text_Display::measure_vline( int visLineNum ) {
+  int i, width = 0, len, style, lineLen = vline_length( visLineNum );
+  int charCount = 0, lineStartPos = mLineStarts[ visLineNum ];
+  char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ];
+
+  if (lineStartPos < 0 || lineLen == 0) return 0;
+  if ( mStyleBuffer == NULL ) {
+    for ( i = 0; i < lineLen; i++ ) {
+      len = mBuffer->expand_character( lineStartPos + i,
+                                       charCount, expandedChar );
+
+      fl_font( textfont(), textsize() );
+
+      width += ( int ) fl_width( expandedChar, len );
+
+      charCount += len;
+    }
+  } else {
+    for ( i = 0; i < lineLen; i++ ) {
+      len = mBuffer->expand_character( lineStartPos + i,
+                                       charCount, expandedChar );
+      style = ( unsigned char ) mStyleBuffer->character(
+                lineStartPos + i ) - 'A';
+
+      if (style < 0) style = 0;
+      else if (style >= mNStyles) style = mNStyles - 1;
+
+      fl_font( mStyleTable[ style ].font, mStyleTable[ style ].size );
+
+      width += ( int ) fl_width( expandedChar, len );
+
+      charCount += len;
+    }
+  }
+  return width;
+}
+
+/*
+** Return true if there are lines visible with no corresponding buffer text
+*/
+int Fl_Text_Display::empty_vlines() {
+  return mNVisibleLines > 0 &&
+         mLineStarts[ mNVisibleLines - 1 ] == -1;
+}
+
+/*
+** Return the length of a line (number of displayable characters) by examining
+** entries in the line starts array rather than by scanning for newlines
+*/
+int Fl_Text_Display::vline_length( int visLineNum ) {
+  int nextLineStart, lineStartPos;
+
+  if (visLineNum < 0 || visLineNum >= mNVisibleLines)
+    return (0);
+
+  lineStartPos = mLineStarts[ visLineNum ];
+
+  if ( lineStartPos == -1 )
+    return 0;
+  if ( visLineNum + 1 >= mNVisibleLines )
+    return mLastChar - lineStartPos;
+  nextLineStart = mLineStarts[ visLineNum + 1 ];
+  if ( nextLineStart == -1 )
+    return mLastChar - lineStartPos;
+  if (wrap_uses_character(nextLineStart-1))
+    return nextLineStart-1 - lineStartPos;
+  return nextLineStart - lineStartPos;
+}
+
+/*
+** When continuous wrap is on, and the user inserts or deletes characters,
+** wrapping can happen before and beyond the changed position.  This routine
+** finds the extent of the changes, and counts the deleted and inserted lines
+** over that range.  It also attempts to minimize the size of the range to
+** what has to be counted and re-displayed, so the results can be useful
+** both for delimiting where the line starts need to be recalculated, and
+** for deciding what part of the text to redisplay.
+*/
+void Fl_Text_Display::find_wrap_range(const char *deletedText, int pos,
+    	int nInserted, int nDeleted, int *modRangeStart, int *modRangeEnd,
+    	int *linesInserted, int *linesDeleted) {
+    int length, retPos, retLines, retLineStart, retLineEnd;
+    Fl_Text_Buffer *deletedTextBuf, *buf = buffer();
+    int nVisLines = mNVisibleLines;
+    int *lineStarts = mLineStarts;
+    int countFrom, countTo, lineStart, adjLineStart, i;
+    int visLineNum = 0, nLines = 0;
+    
+    /*
+    ** Determine where to begin searching: either the previous newline, or
+    ** if possible, limit to the start of the (original) previous displayed
+    ** line, using information from the existing line starts array
+    */
+    if (pos >= mFirstChar && pos <= mLastChar) {
+    	for (i=nVisLines-1; i>0; i--)
+    	    if (lineStarts[i] != -1 && pos >= lineStarts[i])
+    		break;
+    	if (i > 0) {
+    	    countFrom = lineStarts[i-1];
+    	    visLineNum = i-1;
+    	} else
+    	    countFrom = buf->line_start(pos);
+    } else
+    	countFrom = buf->line_start(pos);
+
+    
+    /*
+    ** Move forward through the (new) text one line at a time, counting
+    ** displayed lines, and looking for either a real newline, or for the
+    ** line starts to re-sync with the original line starts array
+    */
+    lineStart = countFrom;
+    *modRangeStart = countFrom;
+    while (true) {
+    	
+    	/* advance to the next line.  If the line ended in a real newline
+    	   or the end of the buffer, that's far enough */
+    	wrapped_line_counter(buf, lineStart, buf->length(), 1, true, 0,
+    	    	&retPos, &retLines, &retLineStart, &retLineEnd);
+    	if (retPos >= buf->length()) {
+    	    countTo = buf->length();
+    	    *modRangeEnd = countTo;
+    	    if (retPos != retLineEnd)
+    	    	nLines++;
+    	    break;
+    	} else
+    	    lineStart = retPos;
+    	nLines++;
+    	if (lineStart > pos + nInserted &&
+    	    	buf->character(lineStart-1) == '\n') {
+    	    countTo = lineStart;
+    	    *modRangeEnd = lineStart;
+    	    break;
+    	}
+        
+	/* Don't try to resync in continuous wrap mode with non-fixed font
+	   sizes; it would result in a chicken-and-egg dependency between
+	   the calculations for the inserted and the deleted lines. 
+           If we're in that mode, the number of deleted lines is calculated in
+           advance, without resynchronization, so we shouldn't resynchronize
+           for the inserted lines either. */
+	if (mSuppressResync)
+	    continue;
+    	
+    	/* check for synchronization with the original line starts array
+    	   before pos, if so, the modified range can begin later */
+     	if (lineStart <= pos) {
+    	    while (visLineNum<nVisLines && lineStarts[visLineNum] < lineStart)
+    		visLineNum++;
+     	    if (visLineNum < nVisLines && lineStarts[visLineNum] == lineStart) {
+    		countFrom = lineStart;
+    		nLines = 0;
+    		if (visLineNum+1 < nVisLines && lineStarts[visLineNum+1] != -1)
+    		    *modRangeStart = min(pos, lineStarts[visLineNum+1]-1);
+    		else
+    		    *modRangeStart = countFrom;
+    	    } else
+    	    	*modRangeStart = min(*modRangeStart, lineStart-1);
+    	}
+    	
+   	/* check for synchronization with the original line starts array
+    	   after pos, if so, the modified range can end early */
+    	else if (lineStart > pos + nInserted) {
+    	    adjLineStart = lineStart - nInserted + nDeleted;
+    	    while (visLineNum<nVisLines && lineStarts[visLineNum]<adjLineStart)
+    	    	visLineNum++;
+    	    if (visLineNum < nVisLines && lineStarts[visLineNum] != -1 &&
+    	    	    lineStarts[visLineNum] == adjLineStart) {
+    	    	countTo = line_end(lineStart, true);
+    	    	*modRangeEnd = lineStart;
+    	    	break;
+    	    }
+    	}
+    }
+    *linesInserted = nLines;
+
+
+    /* Count deleted lines between countFrom and countTo as the text existed
+       before the modification (that is, as if the text between pos and
+       pos+nInserted were replaced by "deletedText").  This extra context is
+       necessary because wrapping can occur outside of the modified region
+       as a result of adding or deleting text in the region. This is done by
+       creating a textBuffer containing the deleted text and the necessary
+       additional context, and calling the wrappedLineCounter on it.
+       
+       NOTE: This must not be done in continuous wrap mode when the font
+	     width is not fixed. In that case, the calculation would try
+	     to access style information that is no longer available (deleted
+	     text), or out of date (updated highlighting), possibly leading 
+	     to completely wrong calculations and/or even crashes eventually.
+	     (This is not theoretical; it really happened.)
+	     
+	     In that case, the calculation of the number of deleted lines
+	     has happened before the buffer was modified (only in that case,
+	     because resynchronization of the line starts is impossible
+	     in that case, which makes the whole calculation less efficient).
+    */
+    if (mSuppressResync) {
+	*linesDeleted = mNLinesDeleted;
+	mSuppressResync = 0;
+	return;
+    }
+
+    length = (pos-countFrom) + nDeleted +(countTo-(pos+nInserted));
+    deletedTextBuf = new Fl_Text_Buffer(length);
+    deletedTextBuf->copy(buffer(), countFrom, pos, 0);
+    if (nDeleted != 0)
+    	deletedTextBuf->insert(pos-countFrom, deletedText);
+    deletedTextBuf->copy(buffer(), 
+    	    pos+nInserted, countTo, pos-countFrom+nDeleted);
+    /* Note that we need to take into account an offset for the style buffer:
+       the deletedTextBuf can be out of sync with the style buffer. */
+    wrapped_line_counter(deletedTextBuf, 0, length, INT_MAX, true, 
+	    countFrom, &retPos, &retLines, &retLineStart, &retLineEnd, false);
+    delete deletedTextBuf;
+    *linesDeleted = retLines;
+    mSuppressResync = 0;
+}
+
+/*
+** This is a stripped-down version of the findWrapRange() function above,
+** intended to be used to calculate the number of "deleted" lines during
+** a buffer modification. It is called _before_ the modification takes place.
+** 
+** This function should only be called in continuous wrap mode with a
+** non-fixed font width. In that case, it is impossible to calculate
+** the number of deleted lines, because the necessary style information 
+** is no longer available _after_ the modification. In other cases, we
+** can still perform the calculation afterwards (possibly even more
+** efficiently).
+*/
+void Fl_Text_Display::measure_deleted_lines(int pos, int nDeleted) {
+    int retPos, retLines, retLineStart, retLineEnd;
+    Fl_Text_Buffer *buf = buffer();
+    int nVisLines = mNVisibleLines;
+    int *lineStarts = mLineStarts;
+    int countFrom, lineStart;
+    int visLineNum = 0, nLines = 0, i;
+    /*
+    ** Determine where to begin searching: either the previous newline, or
+    ** if possible, limit to the start of the (original) previous displayed
+    ** line, using information from the existing line starts array
+    */
+    if (pos >= mFirstChar && pos <= mLastChar) {
+    	for (i=nVisLines-1; i>0; i--)
+    	    if (lineStarts[i] != -1 && pos >= lineStarts[i])
+    		break;
+    	if (i > 0) {
+    	    countFrom = lineStarts[i-1];
+    	    visLineNum = i-1;
+    	} else
+    	    countFrom = buf->line_start(pos);
+    } else
+    	countFrom = buf->line_start(pos);
+    
+    /*
+    ** Move forward through the (new) text one line at a time, counting
+    ** displayed lines, and looking for either a real newline, or for the
+    ** line starts to re-sync with the original line starts array
+    */
+    lineStart = countFrom;
+    while (true) {
+    	/* advance to the next line.  If the line ended in a real newline
+    	   or the end of the buffer, that's far enough */
+    	wrapped_line_counter(buf, lineStart, buf->length(), 1, true, 0,
+    	    	&retPos, &retLines, &retLineStart, &retLineEnd);
+    	if (retPos >= buf->length()) {
+    	    if (retPos != retLineEnd)
+    	    	nLines++;
+    	    break;
+    	} else
+    	    lineStart = retPos;
+    	nLines++;
+    	if (lineStart > pos + nDeleted &&
+    	    	buf->character(lineStart-1) == '\n') {
+    	    break;
+    	}
+	
+	/* Unlike in the findWrapRange() function above, we don't try to 
+	   resync with the line starts, because we don't know the length 
+	   of the inserted text yet, nor the updated style information. 
+	   
+	   Because of that, we also shouldn't resync with the line starts
+	   after the modification either, because we must perform the
+	   calculations for the deleted and inserted lines in the same way. 
+	   
+	   This can result in some unnecessary recalculation and redrawing
+	   overhead, and therefore we should only use this two-phase mode
+	   of calculation when it's really needed (continuous wrap + variable
+	   font width). */
+    }
+    mNLinesDeleted = nLines;
+    mSuppressResync = 1;
+}
+
+/*
+** Count forward from startPos to either maxPos or maxLines (whichever is
+** reached first), and return all relevant positions and line count.
+** The provided textBuffer may differ from the actual text buffer of the
+** widget. In that case it must be a (partial) copy of the actual text buffer
+** and the styleBufOffset argument must indicate the starting position of the
+** copy, to take into account the correct style information.
+**
+** Returned values:
+**
+**   retPos:	    Position where counting ended.  When counting lines, the
+**  	    	    position returned is the start of the line "maxLines"
+**  	    	    lines beyond "startPos".
+**   retLines:	    Number of line breaks counted
+**   retLineStart:  Start of the line where counting ended
+**   retLineEnd:    End position of the last line traversed
+*/
+void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos,
+	int maxPos, int maxLines, bool startPosIsLineStart, int styleBufOffset,
+	int *retPos, int *retLines, int *retLineStart, int *retLineEnd,
+	bool countLastLineMissingNewLine) {
+    int lineStart, newLineStart = 0, b, p, colNum, wrapMargin;
+    int maxWidth, i, foundBreak, width;
+	 bool countPixels;
+    int nLines = 0, tabDist = buffer()->tab_distance();
+    unsigned char c;
+    char nullSubsChar = buffer()->null_substitution_character();
+    
+    /* If the font is fixed, or there's a wrap margin set, it's more efficient
+       to measure in columns, than to count pixels.  Determine if we can count
+       in columns (countPixels == False) or must count pixels (countPixels ==
+       True), and set the wrap target for either pixels or columns */
+    if (mFixedFontWidth != -1 || mWrapMargin != 0) {
+    	countPixels = false;
+	wrapMargin = mWrapMargin ? mWrapMargin : text_area.w / (mFixedFontWidth + 1);
+        maxWidth = INT_MAX;
+    } else {
+    	countPixels = true;
+    	wrapMargin = INT_MAX;
+    	maxWidth = text_area.w;
+    }
+    
+    /* Find the start of the line if the start pos is not marked as a
+       line start. */
+    if (startPosIsLineStart)
+	lineStart = startPos;
+    else
+	lineStart = line_start(startPos);
+    
+    /*
+    ** Loop until position exceeds maxPos or line count exceeds maxLines.
+    ** (actually, contines beyond maxPos to end of line containing maxPos,
+    ** in case later characters cause a word wrap back before maxPos)
+    */
+    colNum = 0;
+    width = 0;
+    for (p=lineStart; p<buf->length(); p++) {
+    	c = (unsigned char)buf->character(p);
+
+    	/* If the character was a newline, count the line and start over,
+    	   otherwise, add it to the width and column counts */
+    	if (c == '\n') {
+    	    if (p >= maxPos) {
+    		*retPos = maxPos;
+    		*retLines = nLines;
+    		*retLineStart = lineStart;
+    		*retLineEnd = maxPos;
+    		return;
+    	    }
+    	    nLines++;
+    	    if (nLines >= maxLines) {
+    		*retPos = p + 1;
+    		*retLines = nLines;
+    		*retLineStart = p + 1;
+    		*retLineEnd = p;
+    		return;
+    	    }
+    	    lineStart = p + 1;
+    	    colNum = 0;
+    	    width = 0;
+    	} else {
+    	    colNum += Fl_Text_Buffer::character_width(c, colNum, tabDist, nullSubsChar);
+    	    if (countPixels)
+    	    	width += measure_proportional_character(c, colNum, p+styleBufOffset);
+    	}
+
+    	/* If character exceeded wrap margin, find the break point
+    	   and wrap there */
+    	if (colNum > wrapMargin || width > maxWidth) {
+    	    foundBreak = false;
+    	    for (b=p; b>=lineStart; b--) {
+    	    	c = (unsigned char)buf->character(b);
+    	    	if (c == '\t' || c == ' ') {
+    	    	    newLineStart = b + 1;
+    	    	    if (countPixels) {
+    	    	    	colNum = 0;
+    	    	    	width = 0;
+    	    	    	for (i=b+1; i<p+1; i++) {
+    	    	    	    width += measure_proportional_character(
+				    buf->character(i), colNum, 
+				    i+styleBufOffset);
+    	    	    	    colNum++;
+    	    	    	}
+    	    	    } else
+    	    	    	colNum = buf->count_displayed_characters(b+1, p+1);
+    	    	    foundBreak = true;
+    	    	    break;
+    	    	}
+    	    }
+    	    if (!foundBreak) { /* no whitespace, just break at margin */
+    	    	newLineStart = max(p, lineStart+1);
+    	    	colNum = Fl_Text_Buffer::character_width(c, colNum, tabDist, nullSubsChar);
+    	    	if (countPixels)
+   	    	    width = measure_proportional_character(c, colNum, p+styleBufOffset);
+    	    }
+    	    if (p >= maxPos) {
+    		*retPos = maxPos;
+    		*retLines = maxPos < newLineStart ? nLines : nLines + 1;
+    		*retLineStart = maxPos < newLineStart ? lineStart :
+    		    	newLineStart;
+    		*retLineEnd = maxPos;
+    		return;
+    	    }
+    	    nLines++;
+    	    if (nLines >= maxLines) {
+    		*retPos = foundBreak ? b + 1 : max(p, lineStart+1);
+    		*retLines = nLines;
+    		*retLineStart = lineStart;
+    		*retLineEnd = foundBreak ? b : p;
+    		return;
+    	    }
+    	    lineStart = newLineStart;
+    	}
+    }
+
+    /* reached end of buffer before reaching pos or line target */
+    *retPos = buf->length();
+    *retLines = nLines;
+	 if (countLastLineMissingNewLine && colNum > 0)
+      ++(*retLines);
+    *retLineStart = lineStart;
+    *retLineEnd = buf->length();
+}
+
+/*
+** Measure the width in pixels of a character "c" at a particular column
+** "colNum" and buffer position "pos".  This is for measuring characters in
+** proportional or mixed-width highlighting fonts.
+**
+** A note about proportional and mixed-width fonts: the mixed width and
+** proportional font code in nedit does not get much use in general editing,
+** because nedit doesn't allow per-language-mode fonts, and editing programs
+** in a proportional font is usually a bad idea, so very few users would
+** choose a proportional font as a default.  There are still probably mixed-
+** width syntax highlighting cases where things don't redraw properly for
+** insertion/deletion, though static display and wrapping and resizing
+** should now be solid because they are now used for online help display.
+*/
+int Fl_Text_Display::measure_proportional_character(char c, int colNum, int pos) {
+    int charLen, style;
+    char expChar[ FL_TEXT_MAX_EXP_CHAR_LEN ];
+    Fl_Text_Buffer *styleBuf = mStyleBuffer;
+    
+    charLen = Fl_Text_Buffer::expand_character(c, colNum, expChar, 
+	    buffer()->tab_distance(), buffer()->null_substitution_character());
+    if (styleBuf == 0) {
+	style = 0;
+    } else {
+	style = (unsigned char)styleBuf->character(pos);
+	if (style == mUnfinishedStyle && mUnfinishedHighlightCB) {
+    	    /* encountered "unfinished" style, trigger parsing */
+    	    (mUnfinishedHighlightCB)(pos, mHighlightCBArg);
+    	    style = (unsigned char)styleBuf->character(pos);
+	}
+    }
+    return string_width(expChar, charLen, style);
+}
+
+/*
+** Finds both the end of the current line and the start of the next line.  Why?
+** In continuous wrap mode, if you need to know both, figuring out one from the
+** other can be expensive or error prone.  The problem comes when there's a
+** trailing space or tab just before the end of the buffer.  To translate an
+** end of line value to or from the next lines start value, you need to know
+** whether the trailing space or tab is being used as a line break or just a
+** normal character, and to find that out would otherwise require counting all
+** the way back to the beginning of the line.
+*/
+void Fl_Text_Display::find_line_end(int startPos, bool startPosIsLineStart,
+    	int *lineEnd, int *nextLineStart) {
+    int retLines, retLineStart;
+    
+    /* if we're not wrapping use more efficient BufEndOfLine */
+    if (!mContinuousWrap) {
+    	*lineEnd = buffer()->line_end(startPos);
+    	*nextLineStart = min(buffer()->length(), *lineEnd + 1);
+    	return;
+    }
+    
+    /* use the wrapped line counter routine to count forward one line */
+    wrapped_line_counter(buffer(), startPos, buffer()->length(),
+    	    1, startPosIsLineStart, 0, nextLineStart, &retLines,
+    	    &retLineStart, lineEnd);
+    return;
+}
+
+/*
+** Line breaks in continuous wrap mode usually happen at newlines or
+** whitespace.  This line-terminating character is not included in line
+** width measurements and has a special status as a non-visible character.
+** However, lines with no whitespace are wrapped without the benefit of a
+** line terminating character, and this distinction causes endless trouble
+** with all of the text display code which was originally written without
+** continuous wrap mode and always expects to wrap at a newline character.
+**
+** Given the position of the end of the line, as returned by TextDEndOfLine
+** or BufEndOfLine, this returns true if there is a line terminating
+** character, and false if there's not.  On the last character in the
+** buffer, this function can't tell for certain whether a trailing space was
+** used as a wrap point, and just guesses that it wasn't.  So if an exact
+** accounting is necessary, don't use this function.
+*/ 
+int Fl_Text_Display::wrap_uses_character(int lineEndPos) {
+    char c;
+    
+    if (!mContinuousWrap || lineEndPos == buffer()->length())
+    	return 1;
+    
+    c = buffer()->character(lineEndPos);
+    return c == '\n' || ((c == '\t' || c == ' ') &&
+    	    lineEndPos + 1 != buffer()->length());
+}
+
+/*
+** Return true if the selection "sel" is rectangular, and touches a
+** buffer position withing "rangeStart" to "rangeEnd"
+*/
+int Fl_Text_Display::range_touches_selection(Fl_Text_Selection *sel,
+   int rangeStart, int rangeEnd) {
+    return sel->selected() && sel->rectangular() && sel->end() >= rangeStart &&
+    	    sel->start() <= rangeEnd;
+}
+
+/*
+** Extend the range of a redraw request (from *start to *end) with additional
+** redraw requests resulting from changes to the attached style buffer (which
+** contains auxiliary information for coloring or styling text).
+*/
+void Fl_Text_Display::extend_range_for_styles( int *startpos, int *endpos ) {
+  Fl_Text_Selection * sel = mStyleBuffer->primary_selection();
+  int extended = 0;
+
+  /* The peculiar protocol used here is that modifications to the style
+     buffer are marked by selecting them with the buffer's primary Fl_Text_Selection.
+     The style buffer is usually modified in response to a modify callback on
+     the text buffer BEFORE Fl_Text_Display.c's modify callback, so that it can keep
+     the style buffer in step with the text buffer.  The style-update
+     callback can't just call for a redraw, because Fl_Text_Display hasn't processed
+     the original text changes yet.  Anyhow, to minimize redrawing and to
+     avoid the complexity of scheduling redraws later, this simple protocol
+     tells the text display's buffer modify callback to extend it's redraw
+     range to show the text color/and font changes as well. */
+  if ( sel->selected() ) {
+    if ( sel->start() < *startpos ) {
+      *startpos = sel->start();
+      extended = 1;
+    }
+    if ( sel->end() > *endpos ) {
+      *endpos = sel->end();
+      extended = 1;
+    }
+  }
+
+  /* If the Fl_Text_Selection was extended due to a style change, and some of the
+     fonts don't match in spacing, extend redraw area to end of line to
+     redraw characters exposed by possible font size changes */
+  if ( mFixedFontWidth == -1 && extended )
+    *endpos = mBuffer->line_end( *endpos ) + 1;
+}
+
+// The draw() method.  It tries to minimize what is draw as much as possible.
+void Fl_Text_Display::draw(void) {
+  // don't even try if there is no associated text buffer!
+  if (!buffer()) { draw_box(); return; }
+
+  fl_push_clip(x(),y(),w(),h());	// prevent drawing outside widget area
+
+  // draw the non-text, non-scrollbar areas.
+  if (damage() & FL_DAMAGE_ALL) {
+//    printf("drawing all (box = %d)\n", box());
+    // draw the box()
+    int W = w(), H = h();
+    draw_box(box(), x(), y(), W, H, color());
+
+    if (mHScrollBar->visible())
+      W -= scrollbar_width();
+    if (mVScrollBar->visible())
+      H -= scrollbar_width();
+
+    // left margin
+    fl_rectf(text_area.x-LEFT_MARGIN, text_area.y-TOP_MARGIN,
+             LEFT_MARGIN, text_area.h+TOP_MARGIN+BOTTOM_MARGIN,
+             color());
+
+    // right margin
+    fl_rectf(text_area.x+text_area.w, text_area.y-TOP_MARGIN,
+             RIGHT_MARGIN, text_area.h+TOP_MARGIN+BOTTOM_MARGIN,
+             color());
+
+    // top margin
+    fl_rectf(text_area.x, text_area.y-TOP_MARGIN,
+             text_area.w, TOP_MARGIN, color());
+
+    // bottom margin
+    fl_rectf(text_area.x, text_area.y+text_area.h,
+             text_area.w, BOTTOM_MARGIN, color());
+
+    // draw that little box in the corner of the scrollbars
+    if (mVScrollBar->visible() && mHScrollBar->visible())
+      fl_rectf(mVScrollBar->x(), mHScrollBar->y(),
+               mVScrollBar->w(), mHScrollBar->h(),
+               FL_GRAY);
+
+    // blank the previous cursor protrusions
+  }
+  else if (damage() & (FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE)) {
+//    printf("blanking previous cursor extrusions at Y: %d\n", mCursorOldY);
+    // CET - FIXME - save old cursor position instead and just draw side needed?
+    fl_push_clip(text_area.x-LEFT_MARGIN,
+                 text_area.y,
+                 text_area.w+LEFT_MARGIN+RIGHT_MARGIN,
+                 text_area.h);
+    fl_rectf(text_area.x-LEFT_MARGIN, mCursorOldY,
+             LEFT_MARGIN, mMaxsize, color());
+    fl_rectf(text_area.x+text_area.w, mCursorOldY,
+             RIGHT_MARGIN, mMaxsize, color());
+    fl_pop_clip();
+  }
+
+  // draw the scrollbars
+  if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_CHILD)) {
+    mVScrollBar->damage(FL_DAMAGE_ALL);
+    mHScrollBar->damage(FL_DAMAGE_ALL);
+  }
+  update_child(*mVScrollBar);
+  update_child(*mHScrollBar);
+
+  // draw all of the text
+  if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_EXPOSE)) {
+    //printf("drawing all text\n");
+    int X, Y, W, H;
+    if (fl_clip_box(text_area.x, text_area.y, text_area.w, text_area.h,
+                    X, Y, W, H)) {
+      // Draw text using the intersected clipping box...
+      // (this sets the clipping internally)
+      draw_text(X, Y, W, H);
+    } else {
+      // Draw the whole area...
+      draw_text(text_area.x, text_area.y, text_area.w, text_area.h);
+    }
+  }
+  else if (damage() & FL_DAMAGE_SCROLL) {
+    // draw some lines of text
+    fl_push_clip(text_area.x, text_area.y,
+                 text_area.w, text_area.h);
+    //printf("drawing text from %d to %d\n", damage_range1_start, damage_range1_end);
+    draw_range(damage_range1_start, damage_range1_end);
+    if (damage_range2_end != -1) {
+      //printf("drawing text from %d to %d\n", damage_range2_start, damage_range2_end);
+      draw_range(damage_range2_start, damage_range2_end);
+    }
+    damage_range1_start = damage_range1_end = -1;
+    damage_range2_start = damage_range2_end = -1;
+    fl_pop_clip();
+  }
+
+  // draw the text cursor
+  if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE)
+      && !buffer()->primary_selection()->selected() &&
+      mCursorOn && Fl::focus() == this ) {
+    fl_push_clip(text_area.x-LEFT_MARGIN,
+                 text_area.y,
+                 text_area.w+LEFT_MARGIN+RIGHT_MARGIN,
+                 text_area.h);
+
+    int X, Y;
+    if (position_to_xy(mCursorPos, &X, &Y)) draw_cursor(X, Y);
+//    else puts("position_to_xy() failed - unable to draw cursor!");
+    //printf("drew cursor at pos: %d (%d,%d)\n", mCursorPos, X, Y);
+    mCursorOldY = Y;
+    fl_pop_clip();
+  }
+  fl_pop_clip();
+}
+
+// this processes drag events due to mouse for Fl_Text_Display and
+// also drags due to cursor movement with shift held down for
+// Fl_Text_Editor
+void fl_text_drag_me(int pos, Fl_Text_Display* d) {
+  if (d->dragType == Fl_Text_Display::DRAG_CHAR) {
+    if (pos >= d->dragPos) {
+      d->buffer()->select(d->dragPos, pos);
+    } else {
+      d->buffer()->select(pos, d->dragPos);
+    }
+    d->insert_position(pos);
+  } else if (d->dragType == Fl_Text_Display::DRAG_WORD) {
+    if (pos >= d->dragPos) {
+      d->insert_position(d->word_end(pos));
+      d->buffer()->select(d->word_start(d->dragPos), d->word_end(pos));
+    } else {
+      d->insert_position(d->word_start(pos));
+      d->buffer()->select(d->word_start(pos), d->word_end(d->dragPos));
+    }
+  } else if (d->dragType == Fl_Text_Display::DRAG_LINE) {
+    if (pos >= d->dragPos) {
+      d->insert_position(d->buffer()->line_end(pos)+1);
+      d->buffer()->select(d->buffer()->line_start(d->dragPos),
+                          d->buffer()->line_end(pos)+1);
+    } else {
+      d->insert_position(d->buffer()->line_start(pos));
+      d->buffer()->select(d->buffer()->line_start(pos),
+                          d->buffer()->line_end(d->dragPos)+1);
+    }
+  }
+}
+
+// This timer event scrolls the text view proportionally to
+// how far the mouse pointer has left the text area. This 
+// allows for smooth scrolling without "wiggeling" the mouse.
+void Fl_Text_Display::scroll_timer_cb(void *user_data) {
+  Fl_Text_Display *w = (Fl_Text_Display*)user_data;
+  int pos;
+  switch (scroll_direction) {
+  case 1: // mouse is to the right, scroll left
+    w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount);
+    pos = w->xy_to_position(w->text_area.x + w->text_area.w, scroll_y, CURSOR_POS);
+    break;
+  case 2: // mouse is to the left, scroll right
+    w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount);
+    pos = w->xy_to_position(w->text_area.x, scroll_y, CURSOR_POS);
+    break;
+  case 3: // mouse is above, scroll down
+    w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset);
+    pos = w->xy_to_position(scroll_x, w->text_area.y, CURSOR_POS);
+    break;
+  case 4: // mouse is below, scroll up
+    w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset);
+    pos = w->xy_to_position(scroll_x, w->text_area.y + w->text_area.h, CURSOR_POS);
+    break;
+  default:
+    return;
+  }
+  fl_text_drag_me(pos, w);
+  Fl::repeat_timeout(.1, scroll_timer_cb, user_data);
+}
+
+
+int Fl_Text_Display::handle(int event) {
+  if (!buffer()) return 0;
+  // This isn't very elegant!
+  if (!Fl::event_inside(text_area.x, text_area.y, text_area.w, text_area.h) &&
+      !dragging && event != FL_LEAVE && event != FL_ENTER &&
+      event != FL_MOVE && event != FL_FOCUS && event != FL_UNFOCUS &&
+      event != FL_KEYBOARD && event != FL_KEYUP) {
+    return Fl_Group::handle(event);
+  }
+
+  switch (event) {
+    case FL_ENTER:
+    case FL_MOVE:
+      if (active_r()) {
+        if (Fl::event_inside(text_area.x, text_area.y, text_area.w, text_area.h)) window()->cursor(FL_CURSOR_INSERT);
+	else window()->cursor(FL_CURSOR_DEFAULT);
+	return 1;
+      } else {
+        return 0;
+      }
+
+    case FL_LEAVE:
+    case FL_HIDE:
+      if (active_r() && window()) {
+        window()->cursor(FL_CURSOR_DEFAULT);
+
+	return 1;
+      } else {
+	return 0;
+      }
+
+    case FL_PUSH: {
+	if (Fl::focus() != this) {
+	  Fl::focus(this);
+	  handle(FL_FOCUS);
+	}
+        if (Fl::event_state()&FL_SHIFT) return handle(FL_DRAG);
+        dragging = 1;
+        int pos = xy_to_position(Fl::event_x(), Fl::event_y(), CURSOR_POS);
+        dragType = Fl::event_clicks();
+        dragPos = pos;
+        if (dragType == DRAG_CHAR)
+          buffer()->unselect();
+        else if (dragType == DRAG_WORD)
+          buffer()->select(word_start(pos), word_end(pos));
+        else if (dragType == DRAG_LINE)
+          buffer()->select(buffer()->line_start(pos), buffer()->line_end(pos)+1);
+
+        if (buffer()->primary_selection()->selected())
+          insert_position(buffer()->primary_selection()->end());
+        else
+          insert_position(pos);
+        show_insert_position();
+        return 1;
+      }
+
+    case FL_DRAG: {
+        if (dragType < 0) return 1;
+        int X = Fl::event_x(), Y = Fl::event_y(), pos;
+        // if we leave the text_area, we start a timer event
+        // that will take care of scrolling and selecting
+        if (Y < text_area.y) {
+          scroll_x = X;
+          scroll_amount = (Y - text_area.y) / 5 - 1;
+          if (!scroll_direction) {
+            Fl::add_timeout(.01, scroll_timer_cb, this);
+          }
+          scroll_direction = 3;
+        } else if (Y >= text_area.y+text_area.h) {
+          scroll_x = X;
+          scroll_amount = (Y - text_area.y - text_area.h) / 5 + 1;
+          if (!scroll_direction) {
+            Fl::add_timeout(.01, scroll_timer_cb, this);
+          }
+          scroll_direction = 4;
+        } else if (X < text_area.x) {
+          scroll_y = Y;
+          scroll_amount = (X - text_area.x) / 2 - 1;
+          if (!scroll_direction) {
+            Fl::add_timeout(.01, scroll_timer_cb, this);
+          }
+          scroll_direction = 2;
+        } else if (X >= text_area.x+text_area.w) {
+          scroll_y = Y;
+          scroll_amount = (X - text_area.x - text_area.w) / 2 + 1;
+          if (!scroll_direction) {
+            Fl::add_timeout(.01, scroll_timer_cb, this);
+          }
+          scroll_direction = 1;
+        } else {
+          if (scroll_direction) {
+            Fl::remove_timeout(scroll_timer_cb, this);
+            scroll_direction = 0;
+          }
+          pos = xy_to_position(X, Y, CURSOR_POS);
+          fl_text_drag_me(pos, this);
+        }
+        return 1;
+      }
+
+    case FL_RELEASE: {
+        dragging = 0;
+        if (scroll_direction) {
+          Fl::remove_timeout(scroll_timer_cb, this);
+          scroll_direction = 0;
+        }
+
+        // convert from WORD or LINE selection to CHAR
+        if (insert_position() >= dragPos)
+          dragPos = buffer()->primary_selection()->start();
+        else
+          dragPos = buffer()->primary_selection()->end();
+        dragType = DRAG_CHAR;
+
+        const char* copy = buffer()->selection_text();
+        if (*copy) Fl::copy(copy, strlen(copy), 0);
+        free((void*)copy);
+        return 1;
+      }
+
+    case FL_MOUSEWHEEL:
+      if (Fl::event_dy()) return mVScrollBar->handle(event);
+      else return mHScrollBar->handle(event);
+
+    case FL_FOCUS:
+    case FL_UNFOCUS:
+      if (buffer()->selected()) redraw();
+
+      return 1;
+
+    case FL_KEYBOARD:
+      // Copy?
+      if ((Fl::event_state()&(FL_CTRL|FL_COMMAND)) && Fl::event_key()=='c') {
+          if (!buffer()->selected()) return 1;
+          const char *copy = buffer()->selection_text();
+          if (*copy) Fl::copy(copy, strlen(copy), 1);
+          free((void*)copy);
+          return 1;
+      }
+
+      // Select all ?
+      if ((Fl::event_state()&(FL_CTRL|FL_COMMAND)) && Fl::event_key()=='a') {
+          buffer()->select(0,buffer()->length());
+          return 1;
+      }
+      break;
+  }
+
+  return 0;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Text_Editor.cxx b/Utilities/FLTK/src/Fl_Text_Editor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cea3bb1991c21d0c5ec98979eab5633f356b96f5
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Text_Editor.cxx
@@ -0,0 +1,485 @@
+//
+// "$Id$"
+//
+// Copyright 2001-2005 by Bill Spitzak and others.
+// Original code Copyright Mark Edel.  Permission to distribute under
+// the LGPL for the FLTK library granted by Mark Edel.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <ctype.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Text_Editor.H>
+#include <FL/fl_ask.H>
+
+
+Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H,  const char* l)
+    : Fl_Text_Display(X, Y, W, H, l) {
+  mCursorOn = 1;
+  insert_mode_ = 1;
+  key_bindings = 0;
+
+  // handle the default key bindings
+  add_default_key_bindings(&key_bindings);
+
+  // handle everything else
+  default_key_function(kf_default);
+}
+
+Fl_Text_Editor::Key_Binding* Fl_Text_Editor::global_key_bindings = 0;
+
+// These are the default key bindings every widget should start with
+static struct {
+  int key;
+  int state;
+  Fl_Text_Editor::Key_Func func;
+} default_key_bindings[] = {
+  { FL_Escape,    FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_ignore     },
+  { FL_Enter,     FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter      },
+  { FL_KP_Enter,  FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter      },
+  { FL_BackSpace, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_backspace  },
+  { FL_Insert,    FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_insert     },
+  { FL_Delete,    FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_delete     },
+  { FL_Home,      0,                        Fl_Text_Editor::kf_move       },
+  { FL_End,       0,                        Fl_Text_Editor::kf_move       },
+  { FL_Left,      0,                        Fl_Text_Editor::kf_move       },
+  { FL_Up,        0,                        Fl_Text_Editor::kf_move       },
+  { FL_Right,     0,                        Fl_Text_Editor::kf_move       },
+  { FL_Down,      0,                        Fl_Text_Editor::kf_move       },
+  { FL_Page_Up,   0,                        Fl_Text_Editor::kf_move       },
+  { FL_Page_Down, 0,                        Fl_Text_Editor::kf_move       },
+  { FL_Home,      FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_End,       FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_Left,      FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_Up,        FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_Right,     FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_Down,      FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_Page_Up,   FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_Page_Down, FL_SHIFT,                 Fl_Text_Editor::kf_shift_move },
+  { FL_Home,      FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_End,       FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_Left,      FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_Up,        FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_Right,     FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_Down,      FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_Page_Up,   FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_Page_Down, FL_CTRL,                  Fl_Text_Editor::kf_ctrl_move  },
+  { FL_Home,      FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+  { FL_End,       FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+  { FL_Left,      FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+  { FL_Up,        FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+  { FL_Right,     FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+  { FL_Down,      FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+  { FL_Page_Up,   FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+  { FL_Page_Down, FL_CTRL|FL_SHIFT,         Fl_Text_Editor::kf_c_s_move   },
+//{ FL_Clear,	  0,                        Fl_Text_Editor::delete_to_eol },
+  { 'z',          FL_CTRL,                  Fl_Text_Editor::kf_undo	  },
+  { '/',          FL_CTRL,                  Fl_Text_Editor::kf_undo	  },
+  { 'x',          FL_CTRL,                  Fl_Text_Editor::kf_cut        },
+  { FL_Delete,    FL_SHIFT,                 Fl_Text_Editor::kf_cut        },
+  { 'c',          FL_CTRL,                  Fl_Text_Editor::kf_copy       },
+  { FL_Insert,    FL_CTRL,                  Fl_Text_Editor::kf_copy       },
+  { 'v',          FL_CTRL,                  Fl_Text_Editor::kf_paste      },
+  { FL_Insert,    FL_SHIFT,                 Fl_Text_Editor::kf_paste      },
+  { 'a',          FL_CTRL,                  Fl_Text_Editor::kf_select_all },
+
+#ifdef __APPLE__
+  // Define CMD+key accelerators...
+  { 'z',          FL_COMMAND,               Fl_Text_Editor::kf_undo       },
+  { 'x',          FL_COMMAND,               Fl_Text_Editor::kf_cut        },
+  { 'c',          FL_COMMAND,               Fl_Text_Editor::kf_copy       },
+  { 'v',          FL_COMMAND,               Fl_Text_Editor::kf_paste      },
+  { 'a',          FL_COMMAND,               Fl_Text_Editor::kf_select_all },
+#endif // __APPLE__
+
+  { 0,            0,                        0                             }
+};
+
+void Fl_Text_Editor::add_default_key_bindings(Key_Binding** list) {
+  for (int i = 0; default_key_bindings[i].key; i++) {
+    add_key_binding(default_key_bindings[i].key,
+                    default_key_bindings[i].state,
+                    default_key_bindings[i].func,
+                    list);
+  }
+}
+
+Fl_Text_Editor::Key_Func
+Fl_Text_Editor::bound_key_function(int key, int state, Key_Binding* list) {
+  Key_Binding* cur;
+  for (cur = list; cur; cur = cur->next)
+    if (cur->key == key)
+      if (cur->state == FL_TEXT_EDITOR_ANY_STATE || cur->state == state)
+        break;
+  if (!cur) return 0;
+  return cur->function;
+}
+
+void
+Fl_Text_Editor::remove_all_key_bindings(Key_Binding** list) {
+  Key_Binding *cur, *next;
+  for (cur = *list; cur; cur = next) {
+    next = cur->next;
+    delete cur;
+  }
+  *list = 0;
+}
+
+void
+Fl_Text_Editor::remove_key_binding(int key, int state, Key_Binding** list) {
+  Key_Binding *cur, *last = 0;
+  for (cur = *list; cur; last = cur, cur = cur->next)
+    if (cur->key == key && cur->state == state) break;
+  if (!cur) return;
+  if (last) last->next = cur->next;
+  else *list = cur->next;
+  delete cur;
+}
+
+void
+Fl_Text_Editor::add_key_binding(int key, int state, Key_Func function,
+                                Key_Binding** list) {
+  Key_Binding* kb = new Key_Binding;
+  kb->key = key;
+  kb->state = state;
+  kb->function = function;
+  kb->next = *list;
+  *list = kb;
+}
+
+////////////////////////////////////////////////////////////////
+
+#define NORMAL_INPUT_MOVE 0
+
+static void kill_selection(Fl_Text_Editor* e) {
+  if (e->buffer()->selected()) {
+    e->insert_position(e->buffer()->primary_selection()->start());
+    e->buffer()->remove_selection();
+  }
+}
+
+int Fl_Text_Editor::kf_default(int c, Fl_Text_Editor* e) {
+  if (!c || (!isprint(c) && c != '\t')) return 0;
+  char s[2] = "\0";
+  s[0] = (char)c;
+  kill_selection(e);
+  if (e->insert_mode()) e->insert(s);
+  else e->overstrike(s);
+  e->show_insert_position();
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+  return 1;
+}
+
+int Fl_Text_Editor::kf_ignore(int, Fl_Text_Editor*) {
+  return 0; // don't handle
+}
+
+int Fl_Text_Editor::kf_backspace(int, Fl_Text_Editor* e) {
+  if (!e->buffer()->selected() && e->move_left())
+    e->buffer()->select(e->insert_position(), e->insert_position()+1);
+  kill_selection(e);
+  e->show_insert_position();
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+  return 1;
+}
+
+int Fl_Text_Editor::kf_enter(int, Fl_Text_Editor* e) {
+  kill_selection(e);
+  e->insert("\n");
+  e->show_insert_position();
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+  return 1;
+}
+
+extern void fl_text_drag_me(int pos, Fl_Text_Display* d);
+
+int Fl_Text_Editor::kf_move(int c, Fl_Text_Editor* e) {
+  int i;
+  int selected = e->buffer()->selected();
+  if (!selected)
+    e->dragPos = e->insert_position();
+  e->buffer()->unselect();
+  switch (c) {
+  case FL_Home:
+      e->insert_position(e->buffer()->line_start(e->insert_position()));
+      break;
+    case FL_End:
+      e->insert_position(e->buffer()->line_end(e->insert_position()));
+      break;
+    case FL_Left:
+      e->move_left();
+      break;
+    case FL_Right:
+      e->move_right();
+      break;
+    case FL_Up:
+      e->move_up();
+      break;
+    case FL_Down:
+      e->move_down();
+      break;
+    case FL_Page_Up:
+      for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_up();
+      break;
+    case FL_Page_Down:
+      for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_down();
+      break;
+  }
+  e->show_insert_position();
+  return 1;
+}
+
+int Fl_Text_Editor::kf_shift_move(int c, Fl_Text_Editor* e) {
+  kf_move(c, e);
+  fl_text_drag_me(e->insert_position(), e);
+  return 1;
+}
+
+int Fl_Text_Editor::kf_ctrl_move(int c, Fl_Text_Editor* e) {
+  if (!e->buffer()->selected())
+    e->dragPos = e->insert_position();
+  if (c != FL_Up && c != FL_Down) {
+    e->buffer()->unselect();
+    e->show_insert_position();
+  }
+  switch (c) {
+    case FL_Home:
+      e->insert_position(0);
+      e->scroll(0, 0);
+      break;
+    case FL_End:
+      e->insert_position(e->buffer()->length());
+      e->scroll(e->count_lines(0, e->buffer()->length(), 1), 0);
+      break;
+    case FL_Left:
+      e->previous_word();
+      break;
+    case FL_Right:
+      e->next_word();
+      break;
+    case FL_Up:
+      e->scroll(e->mTopLineNum-1, e->mHorizOffset);
+      break;
+    case FL_Down:
+      e->scroll(e->mTopLineNum+1, e->mHorizOffset);
+      break;
+    case FL_Page_Up:
+      e->insert_position(e->mLineStarts[0]);
+      break;
+    case FL_Page_Down:
+      e->insert_position(e->mLineStarts[e->mNVisibleLines-2]);
+      break;
+  }
+  return 1;
+}
+
+int Fl_Text_Editor::kf_c_s_move(int c, Fl_Text_Editor* e) {
+  kf_ctrl_move(c, e);
+  fl_text_drag_me(e->insert_position(), e);
+  return 1;
+}
+
+int Fl_Text_Editor::kf_home(int, Fl_Text_Editor* e) {
+    return kf_move(FL_Home, e);
+}
+
+int Fl_Text_Editor::kf_end(int, Fl_Text_Editor* e) {
+  return kf_move(FL_End, e);
+}
+
+int Fl_Text_Editor::kf_left(int, Fl_Text_Editor* e) {
+  return kf_move(FL_Left, e);
+}
+
+int Fl_Text_Editor::kf_up(int, Fl_Text_Editor* e) {
+  return kf_move(FL_Up, e);
+}
+
+int Fl_Text_Editor::kf_right(int, Fl_Text_Editor* e) {
+  return kf_move(FL_Right, e);
+}
+
+int Fl_Text_Editor::kf_down(int, Fl_Text_Editor* e) {
+  return kf_move(FL_Down, e);
+}
+
+int Fl_Text_Editor::kf_page_up(int, Fl_Text_Editor* e) {
+  return kf_move(FL_Page_Up, e);
+}
+
+int Fl_Text_Editor::kf_page_down(int, Fl_Text_Editor* e) {
+  return kf_move(FL_Page_Down, e);
+}
+
+
+int Fl_Text_Editor::kf_insert(int, Fl_Text_Editor* e) {
+  e->insert_mode(e->insert_mode() ? 0 : 1);
+  return 1;
+}
+
+int Fl_Text_Editor::kf_delete(int, Fl_Text_Editor* e) {
+  if (!e->buffer()->selected())
+    e->buffer()->select(e->insert_position(), e->insert_position()+1);
+  kill_selection(e);
+  e->show_insert_position();
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+  return 1;
+}
+
+int Fl_Text_Editor::kf_copy(int, Fl_Text_Editor* e) {
+  if (!e->buffer()->selected()) return 1;
+  const char *copy = e->buffer()->selection_text();
+  if (*copy) Fl::copy(copy, strlen(copy), 1);
+  free((void*)copy);
+  e->show_insert_position();
+  return 1;
+}
+
+int Fl_Text_Editor::kf_cut(int c, Fl_Text_Editor* e) {
+  kf_copy(c, e);
+  kill_selection(e);
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+  return 1;
+}
+
+int Fl_Text_Editor::kf_paste(int, Fl_Text_Editor* e) {
+  kill_selection(e);
+  Fl::paste(*e, 1);
+  e->show_insert_position();
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+  return 1;
+}
+
+int Fl_Text_Editor::kf_select_all(int, Fl_Text_Editor* e) {
+  e->buffer()->select(0, e->buffer()->length());
+  return 1;
+}
+
+int Fl_Text_Editor::kf_undo(int , Fl_Text_Editor* e) {
+  e->buffer()->unselect();
+  int crsr;
+  int ret = e->buffer()->undo(&crsr);
+  e->insert_position(crsr);
+  e->show_insert_position();
+  e->set_changed();
+  if (e->when()&FL_WHEN_CHANGED) e->do_callback();
+  return ret;
+}
+
+int Fl_Text_Editor::handle_key() {
+  // Call FLTK's rules to try to turn this into a printing character.
+  // This uses the right-hand ctrl key as a "compose prefix" and returns
+  // the changes that should be made to the text, as a number of
+  // bytes to delete and a string to insert:
+  int del;
+  if (Fl::compose(del)) {
+    if (del) buffer()->select(insert_position()-del, insert_position());
+    kill_selection(this);
+    if (Fl::event_length()) {
+      if (insert_mode()) insert(Fl::event_text());
+      else overstrike(Fl::event_text());
+    }
+    show_insert_position();
+    set_changed();
+    if (when()&FL_WHEN_CHANGED) do_callback();
+    return 1;
+  }
+
+  int key = Fl::event_key(), state = Fl::event_state(), c = Fl::event_text()[0];
+  state &= FL_SHIFT|FL_CTRL|FL_ALT|FL_META; // only care about these states
+  Key_Func f;
+  f = bound_key_function(key, state, global_key_bindings);
+  if (!f) f = bound_key_function(key, state, key_bindings);
+  if (f) return f(key, this);
+  if (default_key_function_ && !state) return default_key_function_(c, this);
+  return 0;
+}
+
+void Fl_Text_Editor::maybe_do_callback() {
+//  printf("Fl_Text_Editor::maybe_do_callback()\n");
+//  printf("changed()=%d, when()=%x\n", changed(), when());
+  if (changed() || (when()&FL_WHEN_NOT_CHANGED)) do_callback();
+}
+
+int Fl_Text_Editor::handle(int event) {
+  if (!buffer()) return 0;
+
+  if (event == FL_PUSH && Fl::event_button() == 2) {
+    dragType = -1;
+    Fl::paste(*this, 0);
+    Fl::focus(this);
+    set_changed();
+    if (when()&FL_WHEN_CHANGED) do_callback();
+    return 1;
+  }
+
+  switch (event) {
+    case FL_FOCUS:
+      show_cursor(mCursorOn); // redraws the cursor
+      if (buffer()->selected()) redraw(); // Redraw selections...
+      Fl::focus(this);
+      return 1;
+
+    case FL_UNFOCUS:
+      show_cursor(mCursorOn); // redraws the cursor
+      if (buffer()->selected()) redraw(); // Redraw selections...
+    case FL_HIDE:
+      if (when() & FL_WHEN_RELEASE) maybe_do_callback();
+      return 1;
+
+    case FL_KEYBOARD:
+      return handle_key();
+
+    case FL_PASTE:
+      if (!Fl::event_text()) {
+        fl_beep();
+	return 1;
+      }
+      buffer()->remove_selection();
+      if (insert_mode()) insert(Fl::event_text());
+      else overstrike(Fl::event_text());
+      show_insert_position();
+      set_changed();
+      if (when()&FL_WHEN_CHANGED) do_callback();
+      return 1;
+
+    case FL_ENTER:
+// MRS: WIN32 only?  Need to test!
+//    case FL_MOVE:
+      show_cursor(mCursorOn);
+      return 1;
+  }
+
+  return Fl_Text_Display::handle(event);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Tile.cxx b/Utilities/FLTK/src/Fl_Tile.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ead237cad63ea30a3236c49599b12f44c3375e55
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Tile.cxx
@@ -0,0 +1,203 @@
+//
+// "$Id$"
+//
+// Tile widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Group of 2 or 4 "tiles" that can be resized by dragging border
+// The size of the first child determines where the resize border is.
+// The resizebox is used to limit where the border can be dragged to.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Tile.H>
+#include <FL/Fl_Window.H>
+#include <stdlib.h>
+
+// Drag the edges that were initially at oldx,oldy to newx,newy:
+// pass zero as oldx or oldy to disable drag in that direction:
+
+void Fl_Tile::position(int oix, int oiy, int newx, int newy) {
+  Fl_Widget*const* a = array();
+  short* p = sizes();
+  p += 8; // skip group & resizable's saved size
+  for (int i=children(); i--; p += 4) {
+    Fl_Widget* o = *a++;
+    if (o == resizable()) continue;
+    int X = o->x();
+    int R = X+o->w();
+    if (oix) {
+      int t = p[0];
+      if (t == oix || t>oix && X<newx || t<oix && X>newx) X = newx;
+      t = p[1];
+      if (t == oix || t>oix && R<newx || t<oix && R>newx) R = newx;
+    }
+    int Y = o->y();
+    int B = Y+o->h();
+    if (oiy) {
+      int t = p[2];
+      if (t == oiy || t>oiy && Y<newy || t<oiy && Y>newy) Y = newy;
+      t = p[3];
+      if (t == oiy || t>oiy && B<newy || t<oiy && B>newy) B = newy;
+    }
+    o->damage_resize(X,Y,R-X,B-Y);
+  }
+}
+
+// move the lower-right corner (sort of):
+void Fl_Tile::resize(int X,int Y,int W,int H) {
+  // remember how much to move the child widgets:
+  int dx = X-x();
+  int dy = Y-y();
+  int dw = W-w();
+  int dh = H-h();
+  short* p = sizes();
+  // resize this (skip the Fl_Group resize):
+  Fl_Widget::resize(X,Y,W,H);
+  // find bottom-right of resiable:
+  int OR = p[5];
+  int NR = X+W-(p[1]-OR);
+  int OB = p[7];
+  int NB = Y+H-(p[3]-OB);
+  // move everything to be on correct side of new resizable:
+  Fl_Widget*const* a = array();
+  p += 8;
+  for (int i=children(); i--;) {
+    Fl_Widget* o = *a++;
+    int xx = o->x()+dx;
+    int R = xx+o->w();
+    if (*p++ >= OR) xx += dw; else if (xx > NR) xx = NR;
+    if (*p++ >= OR) R += dw; else if (R > NR) R = NR;
+    int yy = o->y()+dy;
+    int B = yy+o->h();
+    if (*p++ >= OB) yy += dh; else if (yy > NB) yy = NB;
+    if (*p++ >= OB) B += dh; else if (B > NB) B = NB;
+    o->resize(xx,yy,R-xx,B-yy); o->redraw();
+  }
+}
+
+static void set_cursor(Fl_Tile*t, Fl_Cursor c) {
+  static Fl_Cursor cursor;
+  if (cursor == c || !t->window()) return;
+  cursor = c;
+#ifdef __sgi
+  t->window()->cursor(c,FL_RED,FL_WHITE);
+#else
+  t->window()->cursor(c);
+#endif
+}
+
+static Fl_Cursor cursors[4] = {
+  FL_CURSOR_DEFAULT,
+  FL_CURSOR_WE,
+  FL_CURSOR_NS,
+  FL_CURSOR_MOVE};
+
+int Fl_Tile::handle(int event) {
+  static int sdrag;
+  static int sdx, sdy;
+  static int sx, sy;
+#define DRAGH 1
+#define DRAGV 2
+#define GRABAREA 4
+
+  int mx = Fl::event_x();
+  int my = Fl::event_y();
+
+  switch (event) {
+
+  case FL_MOVE:
+  case FL_ENTER:
+  case FL_PUSH: {
+    int mindx = 100;
+    int mindy = 100;
+    int oldx = 0;
+    int oldy = 0;
+    Fl_Widget*const* a = array();
+    short* q = sizes();
+    short* p = q+8;
+    for (int i=children(); i--; p += 4) {
+      Fl_Widget* o = *a++;
+      if (o == resizable()) continue;
+      if (p[1]<q[1] && o->y()<=my+GRABAREA && o->y()+o->h()>=my-GRABAREA) {
+	int t = mx - (o->x()+o->w());
+	if (abs(t) < mindx) {
+	  sdx = t;
+	  mindx = abs(t);
+	  oldx = p[1];
+	}
+      }
+      if (p[3]<q[3] && o->x()<=mx+GRABAREA && o->x()+o->w()>=mx-GRABAREA) {
+	int t = my - (o->y()+o->h());
+	if (abs(t) < mindy) {
+	  sdy = t;
+	  mindy = abs(t);
+	  oldy = p[3];
+	}
+      }
+    }
+    sdrag = 0; sx = sy = 0;
+    if (mindx <= GRABAREA) {sdrag = DRAGH; sx = oldx;}
+    if (mindy <= GRABAREA) {sdrag |= DRAGV; sy = oldy;}
+    set_cursor(this, cursors[sdrag]);
+    if (sdrag) return 1;
+    return Fl_Group::handle(event);
+  }
+
+  case FL_LEAVE:
+    set_cursor(this, FL_CURSOR_DEFAULT);
+    break;
+
+  case FL_DRAG:
+    // This is necessary if CONSOLIDATE_MOTION in Fl_x.cxx is turned off:
+    // if (damage()) return 1; // don't fall behind
+  case FL_RELEASE: {
+    if (!sdrag) return 0; // should not happen
+    Fl_Widget* r = resizable(); if (!r) r = this;
+    int newx;
+    if (sdrag&DRAGH) {
+      newx = Fl::event_x()-sdx;
+      if (newx < r->x()) newx = r->x();
+      else if (newx > r->x()+r->w()) newx = r->x()+r->w();
+    } else
+      newx = sx;
+    int newy;
+    if (sdrag&DRAGV) {
+      newy = Fl::event_y()-sdy;
+      if (newy < r->y()) newy = r->y();
+      else if (newy > r->y()+r->h()) newy = r->y()+r->h();
+    } else
+      newy = sy;
+    position(sx,sy,newx,newy);
+    if (event == FL_DRAG) set_changed();
+    do_callback();
+    return 1;}
+
+  }
+
+  return Fl_Group::handle(event);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Tiled_Image.cxx b/Utilities/FLTK/src/Fl_Tiled_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c2058e3bc9f35e9892cc5bb7e1fc17d9d8d74878
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Tiled_Image.cxx
@@ -0,0 +1,139 @@
+//
+// "$Id$"
+//
+// Tiled image code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Tiled_Image.H>
+#include <FL/fl_draw.H>
+
+
+//
+// 'Fl_Tiled_Image::Fl_Tiled_Image()' - Constructor.
+//
+// Use a width and height of 0 to tile the whole window/widget.
+//
+
+Fl_Tiled_Image::Fl_Tiled_Image(Fl_Image *i,	// I - Image to tile
+                               int      W,	// I - Width of tiled area
+			       int      H) :	// I - Height of tiled area
+  Fl_Image(W,H,0) {
+  image_       = i;
+  alloc_image_ = 0;
+
+  if (W == 0) w(Fl::w());
+  if (H == 0) h(Fl::h());
+}
+
+
+//
+// 'Fl_Tiled_Image::~Fl_Tiled_Image()' - Destructor.
+//
+
+Fl_Tiled_Image::~Fl_Tiled_Image() {
+  if (alloc_image_) delete image_;
+}
+
+
+//
+// 'Fl_Tiled_Image::copy()' - Copy and resize a tiled image...
+//
+
+Fl_Image *			// O - New image
+Fl_Tiled_Image::copy(int W,	// I - New width
+                     int H) {	// I - New height
+  if (W == w() && H == h()) return this;
+  else return new Fl_Tiled_Image(image_, W, H);
+}
+
+
+//
+// 'Fl_Tiled_Image::color_average()' - Blend colors...
+//
+
+void
+Fl_Tiled_Image::color_average(Fl_Color c,	// I - Color to blend with
+                              float    i) {	// I - Blend fraction
+  if (!alloc_image_) {
+    image_       = image_->copy();
+    alloc_image_ = 1;
+  }
+
+  image_->color_average(c, i);
+}
+
+
+//
+// 'Fl_Tiled_Image::desaturate()' - Convert the image to grayscale...
+//
+
+void
+Fl_Tiled_Image::desaturate() {
+  if (!alloc_image_) {
+    image_       = image_->copy();
+    alloc_image_ = 1;
+  }
+
+  image_->desaturate();
+}
+
+
+//
+// 'Fl_Tiled_Image::draw()' - Draw a shared image...
+//
+
+void
+Fl_Tiled_Image::draw(int X,	// I - Starting X position
+                     int Y,	// I - Starting Y position
+		     int W,	// I - Width of area to be filled
+		     int H,	// I - Height of area to be filled
+		     int cx,	// I - "Source" X position
+		     int cy) {	// I - "Source" Y position
+  if (!image_->w() || !image_->h()) return;
+  if (W == 0) W = Fl::w();
+  if (H == 0) H = Fl::h();
+
+  fl_clip(X, Y, W, H);
+
+  X += cx;
+  Y += cy;
+
+  X = X - (X % image_->w());
+  Y = Y - (Y % image_->h());
+
+  W += X;
+  H += Y;
+
+  for (int yy = Y; yy < H; yy += image_->h())
+    for (int xx = X; xx < W; xx += image_->w())
+      image_->draw(xx, yy);
+
+  fl_pop_clip();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Tooltip.cxx b/Utilities/FLTK/src/Fl_Tooltip.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2834b3cec1d31ceba3c24a16ad2a8cb1c1d1d3a5
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Tooltip.cxx
@@ -0,0 +1,262 @@
+//
+// "$Id$"
+//
+// Tooltip source file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl_Tooltip.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Menu_Window.H>
+
+#include <stdio.h>
+
+float		Fl_Tooltip::delay_ = 1.0f;
+float		Fl_Tooltip::hoverdelay_ = 0.2f;
+int		Fl_Tooltip::enabled_ = 1;
+unsigned	Fl_Tooltip::color_ = fl_color_cube(FL_NUM_RED - 1,
+		                                   FL_NUM_GREEN - 1,
+						   FL_NUM_BLUE - 2);
+unsigned	Fl_Tooltip::textcolor_ = FL_BLACK;
+int		Fl_Tooltip::font_ = FL_HELVETICA;
+int		Fl_Tooltip::size_ = FL_NORMAL_SIZE;
+
+#define MAX_WIDTH 400
+
+static const char* tip;
+
+class Fl_TooltipBox : public Fl_Menu_Window {
+public:
+  Fl_TooltipBox() : Fl_Menu_Window(0, 0) {
+    set_override();
+    end();
+  }
+  void draw();
+  void layout();
+  void show() {
+    if (tip) Fl_Menu_Window::show();
+  }
+};
+
+Fl_Widget* Fl_Tooltip::widget_ = 0;
+static Fl_TooltipBox *window = 0;
+static int X,Y,W,H;
+
+void Fl_TooltipBox::layout() {
+  fl_font(Fl_Tooltip::font(), Fl_Tooltip::size());
+  int ww, hh;
+  ww = MAX_WIDTH;
+  fl_measure(tip, ww, hh, FL_ALIGN_LEFT|FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
+  ww += 6; hh += 6;
+
+  // find position on the screen of the widget:
+  int ox = Fl::event_x_root();
+  //int ox = X+W/2;
+  int oy = Y + H+2;
+  for (Fl_Widget* p = Fl_Tooltip::current(); p; p = p->window()) {
+    //ox += p->x();
+    oy += p->y();
+  }
+  int scr_x, scr_y, scr_w, scr_h;
+  Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+  if (ox+ww > scr_x+scr_w) ox = scr_x+scr_w - ww;
+  if (ox < scr_x) ox = scr_x;
+  if (H > 30) {
+    oy = Fl::event_y_root()+13;
+    if (oy+hh > scr_y+scr_h) oy -= 23+hh;
+  } else {
+    if (oy+hh > scr_y+scr_h) oy -= (4+hh+H);
+  }
+  if (oy < scr_y) oy = scr_y;
+
+  resize(ox, oy, ww, hh);
+}
+
+void Fl_TooltipBox::draw() {
+  draw_box(FL_BORDER_BOX, 0, 0, w(), h(), Fl_Tooltip::color());
+  fl_color(Fl_Tooltip::textcolor());
+  fl_font(Fl_Tooltip::font(), Fl_Tooltip::size());
+  fl_draw(tip, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP));
+}
+
+static char recent_tooltip;
+
+static void recent_timeout(void*) {
+#ifdef DEBUG
+  puts("recent_timeout();");
+#endif // DEBUG
+
+  recent_tooltip = 0;
+}
+
+static char recursion;
+
+static void tooltip_timeout(void*) {
+#ifdef DEBUG
+  puts("tooltip_timeout();");
+#endif // DEBUG
+
+  if (recursion) return;
+  recursion = 1;
+  if (!tip || !*tip) {
+    if (window) window->hide();
+  } else {
+    //if (Fl::grab()) return;
+    if (!window) window = new Fl_TooltipBox;
+    // this cast bypasses the normal Fl_Window label() code:
+    ((Fl_Widget*)window)->label(tip);
+    window->layout();
+    window->redraw();
+//    printf("tooltip_timeout: Showing window %p with tooltip \"%s\"...\n",
+//           window, tip ? tip : "(null)");
+    window->show();
+  }
+
+  Fl::remove_timeout(recent_timeout);
+  recent_tooltip = 1;
+  recursion = 0;
+}
+
+// If this widget or one of it's parents has a tooltip, enter it. This
+// will do nothing if this is the current widget (even if the mouse moved
+// out so an exit() was done and then moved back in). If no tooltip can
+// be found do Fl_Tooltip::exit_(). If you don't want this behavior (for instance
+// if you want the tooltip to reappear when the mouse moves back in)
+// call the fancier enter_area() below.
+void
+Fl_Tooltip::enter_(Fl_Widget* w) {
+#ifdef DEBUG
+  printf("Fl_Tooltip::enter_(w=%p)\n", w);
+  printf("    window=%p\n", window);
+#endif // DEBUG
+
+  // find the enclosing group with a tooltip:
+  Fl_Widget* tw = w;
+  for (;;) {
+    if (!tw) {exit_(0); return;}
+    if (tw == widget_) return;
+    if (tw->tooltip()) break;
+    tw = tw->parent();
+  }
+  enter_area(w, 0, 0, w->w(), w->h(), tw->tooltip());
+}
+
+// Acts as though enter(widget) was done but does not pop up a
+// tooltip.  This is useful to prevent a tooltip from reappearing when
+// a modal overlapping window is deleted. FLTK does this automatically
+// when you click the mouse button.
+void Fl_Tooltip::current(Fl_Widget* w) {
+#ifdef DEBUG
+  printf("Fl_Tooltip::current(w=%p)\n", w);
+#endif // DEBUG
+
+  exit_(0);
+  // find the enclosing group with a tooltip:
+  Fl_Widget* tw = w;
+  for (;;) {
+    if (!tw) return;
+    if (tw->tooltip()) break;
+    tw = tw->parent();
+  }
+  // act just like Fl_Tooltip::enter_() except we can remember a zero:
+  widget_ = w;
+}
+
+// Hide any visible tooltip.
+void
+Fl_Tooltip::exit_(Fl_Widget *w) {
+#ifdef DEBUG
+  printf("Fl_Tooltip::exit_(w=%p)\n", w);
+  printf("    widget=%p, window=%p\n", widget_, window);
+#endif // DEBUG
+
+  if (!widget_ || w == window) return;
+  widget_ = 0;
+  Fl::remove_timeout(tooltip_timeout);
+  Fl::remove_timeout(recent_timeout);
+  if (window) window->hide();
+  if (recent_tooltip) {
+    if (Fl::event_state() & FL_BUTTONS) recent_tooltip = 0;
+    else Fl::add_timeout(Fl_Tooltip::hoverdelay(), recent_timeout);
+  }
+}
+
+// Get ready to display a tooltip. The widget and the xywh box inside
+// it define an area the tooltip is for, this along with the current
+// mouse position places the tooltip (the mouse is assummed to point
+// inside or near the box).
+void
+Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char* t)
+{
+#ifdef DEBUG
+  printf("Fl_Tooltip::enter_area(wid=%p, x=%d, y=%d, w=%d, h=%d, t=\"%s\")\n",
+         wid, x, y, w, h, t ? t : "(null)");
+  printf("    recursion=%d, window=%p\n", recursion, window);
+#endif // DEBUG
+
+  if (recursion) return;
+  if (!t || !*t || !enabled()) {
+    exit_(0);
+    return;
+  }
+  // do nothing if it is the same:
+  if (wid==widget_ /*&& x==X && y==Y && w==W && h==H*/ && t==tip) return;
+  Fl::remove_timeout(tooltip_timeout);
+  Fl::remove_timeout(recent_timeout);
+  // remember it:
+  widget_ = wid; X = x; Y = y; W = w; H = h; tip = t;
+  // popup the tooltip immediately if it was recently up:
+  if (recent_tooltip) {
+    if (window) window->hide();
+    Fl::add_timeout(Fl_Tooltip::hoverdelay(), tooltip_timeout);
+  } else if (Fl_Tooltip::delay() < .1) {
+#ifdef WIN32
+    // possible fix for the Windows titlebar, it seems to want the
+    // window to be destroyed, moving it messes up the parenting:
+    if (window) window->hide();
+#endif // WIN32
+    tooltip_timeout(0);
+  } else {
+    if (window) window->hide();
+    Fl::add_timeout(Fl_Tooltip::delay(), tooltip_timeout);
+  }
+
+#ifdef DEBUG
+  printf("    tip=\"%s\", window->shown()=%d\n", tip ? tip : "(null)",
+         window ? window->shown() : 0);
+#endif // DEBUG
+}
+
+void Fl_Widget::tooltip(const char *tt) {
+  static char beenhere = 0;
+  if (!beenhere) {
+    beenhere          = 1;
+    Fl_Tooltip::enter = Fl_Tooltip::enter_;
+    Fl_Tooltip::exit  = Fl_Tooltip::exit_;
+  }
+  tooltip_ = tt;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Valuator.cxx b/Utilities/FLTK/src/Fl_Valuator.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..296951022fbb65ec86fc13a797e682d25108e612
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Valuator.cxx
@@ -0,0 +1,149 @@
+//
+// "$Id$"
+//
+// Valuator widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Base class for sliders and all other one-value "knobs"
+
+#include <FL/Fl.H>
+#include <FL/Fl_Valuator.H>
+#include <FL/math.h>
+#include <stdio.h>
+#include "flstring.h"
+
+Fl_Valuator::Fl_Valuator(int X, int Y, int W, int H, const char* L)
+  : Fl_Widget(X,Y,W,H,L) {
+  align(FL_ALIGN_BOTTOM);
+  when(FL_WHEN_CHANGED);
+  value_ = 0;
+  previous_value_ = 1;
+  min = 0;
+  max = 1;
+  A = 0.0;
+  B = 1;
+}
+
+const double epsilon = 4.66e-10;
+
+void Fl_Valuator::step(double s) {
+  if (s < 0) s = -s;
+  A = rint(s);
+  B = 1;
+  while (fabs(s-A/B) > epsilon && B<=(0x7fffffff/10)) {B *= 10; A = rint(s*B);}
+}
+
+void Fl_Valuator::precision(int p) {
+  A = 1.0;
+  for (B = 1; p--;) B *= 10;
+}
+
+void Fl_Valuator::value_damage() {damage(FL_DAMAGE_EXPOSE);} // by default do partial-redraw
+
+int Fl_Valuator::value(double v) {
+  clear_changed();
+  if (v == value_) return 0;
+  value_ = v;
+  value_damage();
+  return 1;
+}
+
+double Fl_Valuator::softclamp(double v) {
+  int which = (min<=max);
+  double p = previous_value_;
+  if ((v<min)==which && p!=min && (p<min)!=which) return min;
+  else if ((v>max)==which && p!=max && (p>max)!=which) return max;
+  else return v;
+}
+
+// inline void Fl_Valuator::handle_push() {previous_value_ = value_;}
+
+void Fl_Valuator::handle_drag(double v) {
+  if (v != value_) {
+    value_ = v;
+    value_damage();
+    set_changed();
+    if (when() & FL_WHEN_CHANGED) do_callback();
+  }
+}
+
+void Fl_Valuator::handle_release() {
+  if (when()&FL_WHEN_RELEASE) {
+    // insure changed() is off even if no callback is done.  It may have
+    // been turned on by the drag, and then the slider returned to it's
+    // initial position:
+    clear_changed();
+    // now do the callback only if slider in new position or always is on:
+    if (value_ != previous_value_ || when() & FL_WHEN_NOT_CHANGED) {
+      do_callback();
+    }
+  }
+}
+
+double Fl_Valuator::round(double v) {
+  if (A) return rint(v*B/A)*A/B;
+  else return v;
+}
+
+double Fl_Valuator::clamp(double v) {
+  if ((v<min)==(min<=max)) return min;
+  else if ((v>max)==(min<=max)) return max;
+  else return v;
+}
+
+double Fl_Valuator::increment(double v, int n) {
+  if (!A) return v+n*(max-min)/100;
+  if (min > max) n = -n;
+  return (rint(v*B/A)+n)*A/B;
+}
+
+int Fl_Valuator::format(char* buffer) {
+  double v = value();
+  // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT
+  if (!A || !B) return snprintf(buffer, 128, "%g", v);
+
+  // Figure out how many digits are required to correctly format the
+  // value.
+  int i, c = 0;
+  char temp[32];
+  // output a number with many digits after the decimal point. This
+  // seems to be needed to get high precission
+  snprintf(temp, sizeof(temp), "%.12f", A/B);
+  // strip all trailing 0's
+  for (i=strlen(temp)-1; i>0; i--) {
+    if (temp[i]!='0') break;
+  }
+  // count digits until we find the decimal point (or comma or whatever
+  // letter is set in the current locale)
+  for (; i>0; i--, c++) {
+    if (!isdigit(temp[i])) break;
+  }
+
+  // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT
+  return snprintf(buffer, 128, "%.*f", c, v);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Value_Input.cxx b/Utilities/FLTK/src/Fl_Value_Input.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d3f5c6e610321dace6d9784a3d34bd02e481cf37
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Value_Input.cxx
@@ -0,0 +1,133 @@
+//
+// "$Id$"
+//
+// Value input widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// FLTK widget for drag-adjusting a floating point value.
+// Warning: this works by making a child Fl_Input object, even
+// though this object is *not* an Fl_Group.  May be a kludge?
+
+#include <FL/Fl.H>
+#include <FL/Fl_Value_Input.H>
+#include <FL/Fl_Group.H>
+#include <stdlib.h>
+#include <FL/math.h>
+
+
+void Fl_Value_Input::input_cb(Fl_Widget*, void* v) {
+  Fl_Value_Input& t = *(Fl_Value_Input*)v;
+  double nv;
+  if ((t.step() - floor(t.step()))>0.0 || t.step() == 0.0) nv = strtod(t.input.value(), 0);
+  else nv = strtol(t.input.value(), 0, 0);
+  if (nv != t.value() || t.when() & FL_WHEN_NOT_CHANGED) {
+    t.set_value(nv);
+    t.set_changed();
+    if (t.when()) t.do_callback();
+  }
+}
+
+void Fl_Value_Input::draw() {
+  if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL);
+  input.box(box());
+  input.color(color(), selection_color());
+  input.draw();
+  input.clear_damage();
+}
+
+void Fl_Value_Input::resize(int X, int Y, int W, int H) {
+  Fl_Valuator::resize(X, Y, W, H);
+  input.resize(X, Y, W, H);
+}
+
+void Fl_Value_Input::value_damage() {
+  char buf[128];
+  format(buf);
+  input.value(buf);
+  input.mark(input.position()); // turn off selection highlight
+}
+
+int Fl_Value_Input::handle(int event) {
+  double v;
+  int delta;
+  int mx = Fl::event_x_root();
+  static int ix, drag;
+  input.when(when());
+  switch (event) {
+  case FL_PUSH:
+    if (!step()) goto DEFAULT;
+    ix = mx;
+    drag = Fl::event_button();
+    handle_push();
+    return 1;
+  case FL_DRAG:
+    if (!step()) goto DEFAULT;
+    delta = mx-ix;
+    if (delta > 5) delta -= 5;
+    else if (delta < -5) delta += 5;
+    else delta = 0;
+    switch (drag) {
+    case 3: v = increment(previous_value(), delta*100); break;
+    case 2: v = increment(previous_value(), delta*10); break;
+    default:v = increment(previous_value(), delta); break;
+    }
+    v = round(v);
+    handle_drag(soft()?softclamp(v):clamp(v));;
+    return 1;
+  case FL_RELEASE:
+    if (!step()) goto DEFAULT;
+    if (value() != previous_value() || !Fl::event_is_click())
+      handle_release();
+    else {
+      input.handle(FL_PUSH);
+      input.handle(FL_RELEASE);
+    }
+    return 1;
+  case FL_FOCUS:
+    return input.take_focus();
+  default:
+  DEFAULT:
+    input.type(((step() - floor(step()))>0.0 || step() == 0.0) ? FL_FLOAT_INPUT : FL_INT_INPUT);
+    return input.handle(event);
+  }
+}
+
+Fl_Value_Input::Fl_Value_Input(int X, int Y, int W, int H, const char* l)
+: Fl_Valuator(X, Y, W, H, l), input(X, Y, W, H, 0) {
+  soft_ = 0;
+  if (input.parent())  // defeat automatic-add
+    ((Fl_Group*)input.parent())->remove(input);
+  input.parent((Fl_Group *)this); // kludge!
+  input.callback(input_cb, this);
+  input.when(FL_WHEN_CHANGED);
+  box(input.box());
+  color(input.color());
+  selection_color(input.selection_color());
+  align(FL_ALIGN_LEFT);
+  value_damage();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Value_Output.cxx b/Utilities/FLTK/src/Fl_Value_Output.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6574bf10652365a884a45ff3963aefbb661592d7
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Value_Output.cxx
@@ -0,0 +1,103 @@
+//
+// "$Id$"
+//
+// Value output widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Fltk widget for drag-adjusting a floating point value.
+// This is much lighter than Fl_Value_Input because it has no text editor
+// If step() is zero then it can be used to display a floating-point value
+
+#include <FL/Fl.H>
+#include <FL/Fl_Value_Output.H>
+#include <FL/fl_draw.H>
+
+void Fl_Value_Output::draw() {
+  Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
+  int X = x()+Fl::box_dx(b);
+  int Y = y()+Fl::box_dy(b);
+  int W = w()-Fl::box_dw(b);
+  int H = h()-Fl::box_dh(b);
+  if (damage()&~FL_DAMAGE_CHILD)
+    draw_box(b, color());
+  else {
+    fl_color(color());
+    fl_rectf(X, Y, W, H);
+  }
+  char buf[128];
+  format(buf);
+  fl_color(active_r() ? textcolor() : fl_inactive(textcolor()));
+  fl_font(textfont(), textsize());
+  fl_draw(buf,X,Y,W,H,FL_ALIGN_LEFT);
+}
+
+int Fl_Value_Output::handle(int event) {
+  if (!step()) return 0;
+  double v;
+  int delta;
+  int mx = Fl::event_x();
+  static int ix, drag;
+  switch (event) {
+  case FL_PUSH:
+    ix = mx;
+    drag = Fl::event_button();
+    handle_push();
+    return 1;
+  case FL_DRAG:
+    delta = Fl::event_x()-ix;
+    if (delta > 5) delta -= 5;
+    else if (delta < -5) delta += 5;
+    else delta = 0;
+    switch (drag) {
+    case 3: v = increment(previous_value(),delta*100); break;
+    case 2: v = increment(previous_value(),delta*10); break;
+    default:v = increment(previous_value(),delta); break;
+    }
+    v = round(v);
+    handle_drag(soft()?softclamp(v):clamp(v));;
+    return 1;
+  case FL_RELEASE:
+    handle_release();
+    return 1;
+  case FL_ENTER :
+  case FL_LEAVE :
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+Fl_Value_Output::Fl_Value_Output(int X, int Y, int W, int H,const char *l)
+: Fl_Valuator(X,Y,W,H,l) {
+  box(FL_NO_BOX);
+  align(FL_ALIGN_LEFT);
+  textfont_ = FL_HELVETICA;
+  textsize_ = (uchar)FL_NORMAL_SIZE;
+  textcolor_ = FL_FOREGROUND_COLOR;
+  soft_ = 0;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Value_Slider.cxx b/Utilities/FLTK/src/Fl_Value_Slider.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ac7ca2efbc5841ce66020e082886e1ae0cd1e821
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Value_Slider.cxx
@@ -0,0 +1,82 @@
+//
+// "$Id$"
+//
+// Value slider widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Value_Slider.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+
+Fl_Value_Slider::Fl_Value_Slider(int X, int Y, int W, int H, const char*l)
+: Fl_Slider(X,Y,W,H,l) {
+  step(1,100);
+  textfont_ = FL_HELVETICA;
+  textsize_ = 10;
+  textcolor_ = FL_FOREGROUND_COLOR;
+}
+
+void Fl_Value_Slider::draw() {
+  int sxx = x(), syy = y(), sww = w(), shh = h();
+  int bxx = x(), byy = y(), bww = w(), bhh = h();
+  if (horizontal()) {
+    bww = 35; sxx += 35; sww -= 35;
+  } else {
+    syy += 25; bhh = 25; shh -= 25;
+  }
+  if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color());
+  Fl_Slider::draw(sxx+Fl::box_dx(box()),
+		  syy+Fl::box_dy(box()),
+		  sww-Fl::box_dw(box()),
+		  shh-Fl::box_dh(box()));
+  draw_box(box(),bxx,byy,bww,bhh,color());
+  char buf[128];
+  format(buf);
+  fl_font(textfont(), textsize());
+  fl_color(active_r() ? textcolor() : fl_inactive(textcolor()));
+  fl_draw(buf, bxx, byy, bww, bhh, FL_ALIGN_CLIP);
+}
+
+int Fl_Value_Slider::handle(int event) {
+  if (event == FL_PUSH && Fl::visible_focus()) {
+    Fl::focus(this);
+    redraw();
+  }
+  int sxx = x(), syy = y(), sww = w(), shh = h();
+  if (horizontal()) {
+    sxx += 35; sww -= 35;
+  } else {
+    syy += 25; shh -= 25;
+  }
+  return Fl_Slider::handle(event,
+			   sxx+Fl::box_dx(box()),
+			   syy+Fl::box_dy(box()),
+			   sww-Fl::box_dw(box()),
+			   shh-Fl::box_dh(box()));
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Widget.cxx b/Utilities/FLTK/src/Fl_Widget.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3c637767bdc2bc7b3df3e2e6608e0ee34968e7ea
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Widget.cxx
@@ -0,0 +1,283 @@
+//
+// "$Id$"
+//
+// Base widget class for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Tooltip.H>
+#include <FL/fl_draw.H>
+#include <stdlib.h>
+#include "flstring.h"
+
+
+////////////////////////////////////////////////////////////////
+// for compatability with Forms, all widgets without callbacks are
+// inserted into a "queue" when they are activated, and the forms
+// compatability interaction functions (fl_do_events, etc) will
+// read one widget at a time from this queue and return it:
+
+const int QUEUE_SIZE = 20;
+
+static Fl_Widget *obj_queue[QUEUE_SIZE];
+static int obj_head, obj_tail;
+
+void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) {
+#if 0
+  // This is necessary for strict forms compatability but is confusing.
+  // Use the parent's callback if this widget does not have one.
+  for (Fl_Widget *p = o->parent(); p; p = p->parent())
+    if (p->callback() != default_callback) {
+      p->do_callback(o,v);
+      return;
+    }
+#endif
+  obj_queue[obj_head++] = o;
+  if (obj_head >= QUEUE_SIZE) obj_head = 0;
+  if (obj_head == obj_tail) {
+    obj_tail++;
+    if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
+  }
+}
+
+Fl_Widget *Fl::readqueue() {
+  if (obj_tail==obj_head) return 0;
+  Fl_Widget *o = obj_queue[obj_tail++];
+  if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
+  return o;
+}
+    
+////////////////////////////////////////////////////////////////
+
+int Fl_Widget::handle(int) {
+  return 0;
+}
+
+int FL_NORMAL_SIZE = 14;
+
+Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {
+
+  x_ = X; y_ = Y; w_ = W; h_ = H;
+
+  label_.value	 = L;
+  label_.image   = 0;
+  label_.deimage = 0;
+  label_.type	 = FL_NORMAL_LABEL;
+  label_.font	 = FL_HELVETICA;
+  label_.size	 = (uchar)FL_NORMAL_SIZE;
+  label_.color	 = FL_FOREGROUND_COLOR;
+  tooltip_       = 0;
+  callback_	 = default_callback;
+  user_data_ 	 = 0;
+  type_		 = 0;
+  flags_	 = VISIBLE_FOCUS;
+  damage_	 = 0;
+  box_		 = FL_NO_BOX;
+  color_	 = FL_GRAY;
+  color2_	 = FL_GRAY;
+  align_	 = FL_ALIGN_CENTER;
+  when_		 = FL_WHEN_RELEASE;
+
+  parent_ = 0;
+  if (Fl_Group::current()) Fl_Group::current()->add(this);
+}
+
+void Fl_Widget::resize(int X, int Y, int W, int H) {
+  x_ = X; y_ = Y; w_ = W; h_ = H;
+}
+
+// this is useful for parent widgets to call to resize children:
+int Fl_Widget::damage_resize(int X, int Y, int W, int H) {
+  if (x() == X && y() == Y && w() == W && h() == H) return 0;
+  resize(X, Y, W, H);
+  redraw();
+  return 1;
+}
+
+int Fl_Widget::take_focus() {
+  if (!takesevents()) return 0;
+  if (!visible_focus()) return 0;
+  if (!handle(FL_FOCUS)) return 0; // see if it wants it
+  if (contains(Fl::focus())) return 1; // it called Fl::focus for us
+  Fl::focus(this);
+  return 1;
+}
+
+extern void fl_throw_focus(Fl_Widget*); // in Fl_x.cxx
+
+// Destruction does not remove from any parent group!  And groups when
+// destroyed destroy all their children.  This is convienent and fast.
+// However, it is only legal to destroy a "root" such as an Fl_Window,
+// and automatic destructors may be called.
+Fl_Widget::~Fl_Widget() {
+  if (flags() & COPIED_LABEL) free((void *)(label_.value));
+  parent_ = 0; // Don't throw focus to a parent widget.
+  fl_throw_focus(this);
+}
+
+// draw a focus box for the widget...
+void
+Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const {
+  if (!Fl::visible_focus()) return;
+  switch (B) {
+    case FL_DOWN_BOX:
+    case FL_DOWN_FRAME:
+    case FL_THIN_DOWN_BOX:
+    case FL_THIN_DOWN_FRAME:
+      X ++;
+      Y ++;
+    default:
+      break;
+  }
+
+  fl_color(fl_contrast(FL_BLACK, color()));
+
+#if defined(WIN32) || defined(__APPLE_QD__)
+  // Windows 95/98/ME do not implement the dotted line style, so draw
+  // every other pixel around the focus area...
+  //
+  // Also, QuickDraw (MacOS) does not support line styles specifically,
+  // and the hack we use in fl_line_style() will not draw horizontal lines
+  // on odd-numbered rows...
+  int i, xx, yy;
+
+  X += Fl::box_dx(B);
+  Y += Fl::box_dy(B);
+  W -= Fl::box_dw(B) + 2;
+  H -= Fl::box_dh(B) + 2;
+
+  for (xx = 0, i = 1; xx < W; xx ++, i ++) if (i & 1) fl_point(X + xx, Y);
+  for (yy = 0; yy < H; yy ++, i ++) if (i & 1) fl_point(X + W, Y + yy);
+  for (xx = W; xx > 0; xx --, i ++) if (i & 1) fl_point(X + xx, Y + H);
+  for (yy = H; yy > 0; yy --, i ++) if (i & 1) fl_point(X, Y + yy);
+#else
+  fl_line_style(FL_DOT);
+  fl_rect(X + Fl::box_dx(B), Y + Fl::box_dy(B),
+          W - Fl::box_dw(B) - 1, H - Fl::box_dh(B) - 1);
+  fl_line_style(FL_SOLID);
+#endif // WIN32
+}
+
+
+void Fl_Widget::activate() {
+  if (!active()) {
+    clear_flag(INACTIVE);
+    if (active_r()) {
+      redraw();
+      redraw_label();
+      handle(FL_ACTIVATE);
+      if (inside(Fl::focus())) Fl::focus()->take_focus();
+    }
+  }
+}
+
+void Fl_Widget::deactivate() {
+  if (active_r()) {
+    set_flag(INACTIVE);
+    redraw();
+    redraw_label();
+    handle(FL_DEACTIVATE);
+    fl_throw_focus(this);
+  } else {
+    set_flag(INACTIVE);
+  }
+}
+
+int Fl_Widget::active_r() const {
+  for (const Fl_Widget* o = this; o; o = o->parent())
+    if (!o->active()) return 0;
+  return 1;
+}
+
+void Fl_Widget::show() {
+  if (!visible()) {
+    clear_flag(INVISIBLE);
+    if (visible_r()) {
+      redraw();
+      redraw_label();
+      handle(FL_SHOW);
+      if (inside(Fl::focus())) Fl::focus()->take_focus();
+    }
+  }
+}
+
+void Fl_Widget::hide() {
+  if (visible_r()) {
+    set_flag(INVISIBLE);
+    for (Fl_Widget *p = parent(); p; p = p->parent())
+      if (p->box() || !p->parent()) {p->redraw(); break;}
+    handle(FL_HIDE);
+    fl_throw_focus(this);
+  } else {
+    set_flag(INVISIBLE);
+  }
+}
+
+int Fl_Widget::visible_r() const {
+  for (const Fl_Widget* o = this; o; o = o->parent())
+    if (!o->visible()) return 0;
+  return 1;
+}
+
+// return true if widget is inside (or equal to) this:
+// Returns false for null widgets.
+int Fl_Widget::contains(const Fl_Widget *o) const {
+  for (; o; o = o->parent_) if (o == this) return 1;
+  return 0;
+}
+
+
+void
+Fl_Widget::label(const char *a) {
+  if (flags() & COPIED_LABEL) {
+    // reassigning a copied label remains the same copied label
+    if (label_.value == a)
+      return;
+    free((void *)(label_.value));
+    clear_flag(COPIED_LABEL);
+  }
+  label_.value=a;
+  redraw_label();
+}
+
+
+void
+Fl_Widget::copy_label(const char *a) {
+  if (flags() & COPIED_LABEL) free((void *)(label_.value));
+  if (a) {
+    set_flag(COPIED_LABEL);
+    label_.value=strdup(a);
+  } else {
+    clear_flag(COPIED_LABEL);
+    label_.value=(char *)0;
+  }
+  redraw_label();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Window.cxx b/Utilities/FLTK/src/Fl_Window.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d8aa8e91d0cb83fa45fc0e601d87c605e896257e
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Window.cxx
@@ -0,0 +1,176 @@
+//
+// "$Id$"
+//
+// Window widget class for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// The Fl_Window is a window in the fltk library.
+// This is the system-independent portions.  The huge amount of 
+// crap you need to do to communicate with X is in Fl_x.cxx, the
+// equivalent (but totally different) crap for MSWindows is in Fl_win32.cxx
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <stdlib.h>
+#include "flstring.h"
+
+#ifdef __APPLE_QUARTZ__
+#include <FL/fl_draw.h>
+#endif
+
+void Fl_Window::_Fl_Window() {
+  type(FL_WINDOW);
+  box(FL_FLAT_BOX);
+  if (Fl::scheme_bg_) {
+    labeltype(FL_NORMAL_LABEL);
+    align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+    image(Fl::scheme_bg_);
+  } else {
+    labeltype(FL_NO_LABEL);
+  }
+  i = 0;
+  xclass_ = 0;
+  icon_ = 0;
+  iconlabel_ = 0;
+  resizable(0);
+  size_range_set = 0;
+  minw = maxw = minh = maxh = 0;
+  callback((Fl_Callback*)default_callback);
+}
+
+Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l)
+: Fl_Group(X, Y, W, H, l) {
+  cursor_default = FL_CURSOR_DEFAULT;
+  cursor_fg      = FL_BLACK;
+  cursor_bg      = FL_WHITE;
+
+  _Fl_Window();
+  set_flag(FL_FORCE_POSITION);
+}
+
+Fl_Window::Fl_Window(int W, int H, const char *l)
+// fix common user error of a missing end() with current(0):
+  : Fl_Group((Fl_Group::current(0),0), 0, W, H, l) {
+  cursor_default = FL_CURSOR_DEFAULT;
+  cursor_fg      = FL_BLACK;
+  cursor_bg      = FL_WHITE;
+
+  _Fl_Window();
+  clear_visible();
+}
+
+Fl_Window *Fl_Widget::window() const {
+  for (Fl_Widget *o = parent(); o; o = o->parent())
+    if (o->type() >= FL_WINDOW) return (Fl_Window*)o;
+  return 0;
+}
+
+int Fl_Window::x_root() const {
+  Fl_Window *p = window();
+  if (p) return p->x_root() + x();
+  return x();
+}
+
+int Fl_Window::y_root() const {
+  Fl_Window *p = window();
+  if (p) return p->y_root() + y();
+  return y();
+}
+
+void Fl_Window::draw() {
+  const char *savelabel = label();
+  uchar saveflags = flags();
+  int savex = x(); x(0);
+  int savey = y(); y(0);
+  // Make sure we don't draw the window title in the window background...
+  Fl_Widget::label(0);
+  Fl_Group::draw();
+#ifdef __APPLE_QUARTZ__
+  if (!parent() && resizable()) {
+    int dx = Fl::box_dw(box())-Fl::box_dx(box());
+    int dy = Fl::box_dh(box())-Fl::box_dy(box());
+    if (dx<=0) dx = 1;
+    if (dy<=0) dy = 1;
+    int x1 = w()-dx-1, x2 = x1, y1 = h()-dx-1, y2 = y1;
+    Fl_Color c[4] = {
+      color(),
+      fl_color_average(color(), FL_WHITE, 0.7f),
+      fl_color_average(color(), FL_BLACK, 0.6f),
+      fl_color_average(color(), FL_BLACK, 0.8f),
+    };
+    int i;
+    for (i=dx; i<12; i++) {
+      fl_color(c[i&3]);
+      fl_line(x1--, y1, x2, y2--);
+    }
+  }
+#endif
+  // Restore the label...
+  Fl_Widget::label(savelabel);
+  set_flag(saveflags);
+  y(savey);
+  x(savex);
+}
+
+void Fl_Window::label(const char *name) {label(name, iconlabel());}
+
+void Fl_Window::copy_label(const char *a) {
+  if (flags() & COPIED_LABEL) {
+    free((void *)label());
+    clear_flag(COPIED_LABEL);
+  }
+  if (a) a = strdup(a);
+  label(a, iconlabel());
+  set_flag(COPIED_LABEL);
+}
+
+
+void Fl_Window::iconlabel(const char *iname) {
+  uchar saveflags = flags();
+  label(label(), iname);
+  set_flag(saveflags);
+}
+
+// the Fl::atclose pointer is provided for back compatability.  You
+// can now just change the callback for the window instead.
+
+void Fl::default_atclose(Fl_Window* window, void* v) {
+  window->hide();
+  Fl_Widget::default_callback(window, v); // put on Fl::read_queue()
+}
+
+void (*Fl::atclose)(Fl_Window*, void*) = default_atclose;
+
+void Fl_Window::default_callback(Fl_Window* win, void* v) {
+  Fl::atclose(win, v);
+}
+
+Fl_Window *Fl_Window::current() {
+  return current_;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Window_fullscreen.cxx b/Utilities/FLTK/src/Fl_Window_fullscreen.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8437368455a1924372dfedb678360a9117b0b25e
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Window_fullscreen.cxx
@@ -0,0 +1,99 @@
+//
+// "$Id$"
+//
+// Fullscreen window support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Turning the border on/off by changing the motif_wm_hints property
+// works on Irix 4DWM.  Does not appear to work for any other window
+// manager.  Fullscreen still works on some window managers (fvwm is one)
+// because they allow the border to be placed off-screen.
+
+// Unfortunatly most X window managers ignore changes to the border
+// and refuse to position the border off-screen, so attempting to make
+// the window full screen will lose the size of the border off the
+// bottom and right.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+#ifdef __APPLE__
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#endif 
+
+void Fl_Window::border(int b) {
+  if (b) {
+    if (border()) return;
+    clear_flag(FL_NOBORDER);
+  } else {
+    if (!border()) return;
+    set_flag(FL_NOBORDER);
+  }
+#ifdef WIN32
+  // not yet implemented, but it's possible
+  // for full fullscreen we have to make the window topmost as well
+#elif defined(__APPLE_QD__)
+  // warning: not implemented in Quickdraw/Carbon
+#elif defined(__APPLE_QUARTZ__)
+  // warning: not implemented in Quartz/Carbon
+#else
+  if (shown()) Fl_X::i(this)->sendxjunk();
+#endif
+}
+
+void Fl_Window::fullscreen() {
+#ifndef WIN32
+  //this would clobber the fake wm, since it relies on the border flags to
+  //determine its thickness
+  border(0);
+#endif
+#if defined(__APPLE__) || defined(WIN32)
+  int sx, sy, sw, sh;
+  Fl::screen_xywh(sx, sy, sw, sh, x()+w()/2, y()+h()/2);
+  // if we are on the main screen, we will leave the system menu bar unobstructed
+  if (Fl::x()>=sx && Fl::y()>=sy && Fl::x()+Fl::w()<=sx+sw && Fl::y()+Fl::h()<=sy+sh) {
+    sx = Fl::x(); sy = Fl::y(); 
+    sw = Fl::w(); sh = Fl::h();
+  }
+  if (x()==sx) x(sx+1); // make sure that we actually execute the resize
+  resize(sx, sy, sw, sh);
+#else
+  if (!x()) x(1); // force it to call XResizeWindow()
+  resize(0,0,Fl::w(),Fl::h());
+#endif
+}
+
+void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
+  // this order produces less blinking on IRIX:
+  resize(X,Y,W,H);
+#ifndef WIN32
+  border(1);
+#endif
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Window_hotspot.cxx b/Utilities/FLTK/src/Fl_Window_hotspot.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ea2c5fb642373dd2c010579b9f1b9070a1d12d35
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Window_hotspot.cxx
@@ -0,0 +1,90 @@
+//
+// "$Id$"
+//
+// Common hotspot routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#include <stdio.h>
+
+void Fl_Window::hotspot(int X, int Y, int offscreen) {
+  int mx,my;
+
+  // Update the screen position based on the mouse position.
+  Fl::get_mouse(mx,my);
+  X = mx-X; Y = my-Y;
+
+  // If offscreen is 0 (the default), make sure that the window
+  // stays on the screen, if possible.
+  if (!offscreen) {
+#if defined(WIN32) || defined(__APPLE__)
+    // These will be used by reference, so we must passed different variables
+    int bt,bx,by;
+    x(X);y(Y);
+    Fl_X::fake_X_wm(this, X, Y, bt, bx, by);
+    //force FL_FORCE_POSITION to be set in Fl_Window::resize()
+    if (X==x()) x(X-1);
+#else
+    int scr_x, scr_y, scr_w, scr_h;
+    Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+
+    if (border()) {
+      // Ensure border is on screen; these values are generic enough
+      // to work with many window managers, and are based on KDE defaults.
+      const int top = 20;
+      const int left = 4;
+      const int right = 4;
+      const int bottom = 8;
+      if (X+w()+right > scr_w-scr_x) X = scr_w-scr_x-right-w();
+      if (X-left < scr_x) X = left;
+      if (Y+h()+bottom > scr_h-scr_y) Y = scr_h-scr_y-bottom-h();
+      if (Y-top < scr_y) Y = top;
+    }
+    // now insure contents are on-screen (more important than border):
+    if (X+w() > scr_w-scr_x) X = scr_w-scr_x-w();
+    if (X < scr_x) X = scr_x;
+    if (Y+h() > scr_h-scr_y) Y = scr_h-scr_y-h();
+    if (Y < scr_y) Y = scr_y;
+#endif
+  }
+
+  position(X,Y);
+}
+
+void Fl_Window::hotspot(const Fl_Widget *o, int offscreen) {
+  int X = o->w()/2;
+  int Y = o->h()/2;
+  while (o != this && o) {
+    X += o->x(); Y += o->y();
+    o = o->window();
+  }
+  hotspot(X,Y,offscreen);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Window_iconize.cxx b/Utilities/FLTK/src/Fl_Window_iconize.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c19e542dd25b560fc098c8dd7d4e6729a9614e42
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Window_iconize.cxx
@@ -0,0 +1,49 @@
+//
+// "$Id$"
+//
+// Window minification code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/x.H>
+
+extern char fl_show_iconic; // in Fl_x.cxx
+
+void Fl_Window::iconize() {
+  if (!shown()) {
+    fl_show_iconic = 1;
+    show();
+  } else {
+#ifdef WIN32
+    ShowWindow(i->xid, SW_SHOWMINNOACTIVE);
+#elif defined(__APPLE__)
+    CollapseWindow( i->xid, true );
+#else
+    XIconifyWindow(fl_display, i->xid, fl_screen);
+#endif
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_Wizard.cxx b/Utilities/FLTK/src/Fl_Wizard.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cf88f90583cd0b5d93cc521acf5ff7b040a2bc55
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_Wizard.cxx
@@ -0,0 +1,210 @@
+//
+// "$Id$"
+//
+// Fl_Wizard widget routines.
+//
+// Copyright 1997-2005 by Easy Software Products.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_Wizard::Fl_Wizard() - Create an Fl_Wizard widget.
+//   Fl_Wizard::draw()      - Draw the wizard border and visible child.
+//   Fl_Wizard::next()      - Show the next child.
+//   Fl_Wizard::prev()      - Show the previous child.
+//   Fl_Wizard::value()     - Return the current visible child.
+//   Fl_Wizard::value()     - Set the visible child.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl_Wizard.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_draw.H>
+
+
+//
+// 'Fl_Wizard::Fl_Wizard()' - Create an Fl_Wizard widget.
+//
+
+Fl_Wizard::Fl_Wizard(int        xx,	// I - Lefthand position
+                     int        yy,	// I - Upper position
+		     int        ww,	// I - Width
+		     int        hh,	// I - Height
+		     const char *l) :	// I - Label
+    Fl_Group(xx, yy, ww, hh, l)
+{
+  box(FL_THIN_UP_BOX);
+
+  value_ = (Fl_Widget *)0;
+}
+
+
+//
+// 'Fl_Wizard::draw()' - Draw the wizard border and visible child.
+//
+
+void
+Fl_Wizard::draw()
+{
+  Fl_Widget	*kid;	// Visible child
+
+
+  kid = value();
+
+  if (damage() & FL_DAMAGE_ALL)
+  {
+    // Redraw everything...
+    if (kid)
+    {
+      draw_box(box(), x(), y(), w(), h(), kid->color());
+      draw_child(*kid);
+    }
+    else
+      draw_box(box(), x(), y(), w(), h(), color());
+
+  }
+  else if (kid)
+    update_child(*kid);
+}
+
+
+//
+// 'Fl_Wizard::next()' - Show the next child.
+//
+
+void
+Fl_Wizard::next()
+{
+  int			num_kids;
+  Fl_Widget	* const *kids;
+
+
+  if ((num_kids = children()) == 0)
+    return;
+
+  for (kids = array(); num_kids > 0; kids ++, num_kids --)
+    if ((*kids)->visible())
+      break;
+
+  if (num_kids > 1)
+    value(kids[1]);
+}
+
+
+//
+// 'Fl_Wizard::prev()' - Show the previous child.
+//
+
+
+void
+Fl_Wizard::prev()
+{
+  int			num_kids;
+  Fl_Widget	* const *kids;
+
+
+  if ((num_kids = children()) == 0)
+    return;
+
+  for (kids = array(); num_kids > 0; kids ++, num_kids --)
+    if ((*kids)->visible())
+      break;
+
+  if (num_kids > 0 && num_kids < children())
+    value(kids[-1]);
+}
+
+
+//
+// 'Fl_Wizard::value()' - Return the current visible child.
+//
+
+Fl_Widget *
+Fl_Wizard::value()
+{
+  int			num_kids;
+  Fl_Widget	* const *kids;
+  Fl_Widget		*kid;
+
+
+  if ((num_kids = children()) == 0)
+    return ((Fl_Widget *)0);
+
+  for (kids = array(), kid = (Fl_Widget *)0; num_kids > 0; kids ++, num_kids --)
+  {
+    if ((*kids)->visible())
+    {
+      if (kid)
+        (*kids)->hide();
+      else
+        kid = *kids;
+    }
+  }
+
+  if (!kid)
+  {
+    kids --;
+    kid = *kids;
+    kid->show();
+  }
+
+  return (kid);
+}
+
+
+//
+// 'Fl_Wizard::value()' - Set the visible child.
+//
+
+void
+Fl_Wizard::value(Fl_Widget *kid)
+{
+  int			num_kids;
+  Fl_Widget	* const *kids;
+
+
+  if ((num_kids = children()) == 0)
+    return;
+
+  for (kids = array(); num_kids > 0; kids ++, num_kids --)
+  {
+    if (*kids == kid)
+    {
+      if (!kid->visible())
+        kid->show();
+    }
+    else
+      (*kids)->hide();
+  }
+
+  // This will restore the mouse pointer to the window's default cursor
+  // whenever the wizard pane is changed.  Otherwise text widgets that
+  // show the next pane may leave the cursor set to the I beam, etc...
+  if (window()) window()->cursor(FL_CURSOR_DEFAULT);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_XBM_Image.cxx b/Utilities/FLTK/src/Fl_XBM_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..49773bd82e6c1edf1d361ca6b7e3b88ab21dd3bd
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_XBM_Image.cxx
@@ -0,0 +1,106 @@
+//
+// "$Id$"
+//
+// Fl_XBM_Image routines.
+//
+// Copyright 1997-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   Fl_XBM_Image::Fl_XBM_Image() - Load an XBM file.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_XBM_Image.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+//
+// 'Fl_XBM_Image::Fl_XBM_Image()' - Load an XBM file.
+//
+
+Fl_XBM_Image::Fl_XBM_Image(const char *name) : Fl_Bitmap((const char *)0,0,0) {
+  FILE	*f;
+  uchar	*ptr;
+
+  if ((f = fopen(name, "rb")) == NULL) return;
+
+  char buffer[1024];
+  char junk[1024];
+  int wh[2]; // width and height
+  int i;
+  for (i = 0; i<2; i++) {
+    for (;;) {
+      if (!fgets(buffer,1024,f)) {
+        fclose(f);
+	return;
+      }
+      int r = sscanf(buffer,"#define %s %d",junk,&wh[i]);
+      if (r >= 2) break;
+    }
+  }
+
+  // skip to data array:
+  for (;;) {
+    if (!fgets(buffer,1024,f)) {
+      fclose(f);
+      return;
+    }
+    if (!strncmp(buffer,"static ",7)) break;
+  }
+
+  // Allocate memory...
+  w(wh[0]);
+  h(wh[1]);
+
+  int n = ((wh[0]+7)/8)*wh[1];
+  array = new uchar[n];
+
+  // read the data:
+  for (i = 0, ptr = (uchar *)array; i < n;) {
+    if (!fgets(buffer,1024,f)) {
+      fclose(f);
+      return;
+    }
+    const char *a = buffer;
+    while (*a && i<n) {
+      unsigned int t;
+      if (sscanf(a," 0x%x",&t)>0) {
+        *ptr++ = (uchar)t;
+	i ++;
+      }
+      while (*a && *a++ != ',');
+    }
+  }
+
+  fclose(f);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_XColor.H b/Utilities/FLTK/src/Fl_XColor.H
new file mode 100644
index 0000000000000000000000000000000000000000..c0f893cd97ecde4fc2930069a105942de5f70516
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_XColor.H
@@ -0,0 +1,46 @@
+//
+// "$Id: Fl_XColor.H 4288 2005-04-16 00:13:17Z mike $"
+//
+// X-specific color definitions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2001 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <config.h>
+#include <FL/Enumerations.H>
+
+// one of these for each color in fltk's "colormap":
+// if overlays are enabled, another one for the overlay
+struct Fl_XColor {
+  unsigned char r,g,b;	// actual color used by X
+  unsigned char mapped;	// true when XAllocColor done
+  unsigned long pixel;	// the X pixel to use
+};
+extern Fl_XColor fl_xmap[/*overlay*/][256];
+
+// mask & shifts to produce xcolor for truecolor visuals:
+extern unsigned char fl_redmask, fl_greenmask, fl_bluemask;
+extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift;
+
+//
+// End of "$Id: Fl_XColor.H 4288 2005-04-16 00:13:17Z mike $".
+//
diff --git a/Utilities/FLTK/src/Fl_XPM_Image.cxx b/Utilities/FLTK/src/Fl_XPM_Image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..31228a32d5e4a3817b5351a36aafc42046a2b145
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_XPM_Image.cxx
@@ -0,0 +1,131 @@
+//
+// "$Id$"
+//
+// Fl_XPM_Image routines.
+//
+// Copyright 1997-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_XPM_Image.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+
+//
+// 'hexdigit()' - Convert a hex digit to an integer.
+//
+
+static int hexdigit(int x) {	// I - Hex digit...
+  if (isdigit(x)) return x-'0';
+  if (isupper(x)) return x-'A'+10;
+  if (islower(x)) return x-'a'+10;
+  return 20;
+}
+
+#define MAXSIZE 2048
+#define INITIALLINES 256
+
+Fl_XPM_Image::Fl_XPM_Image(const char *name) : Fl_Pixmap((char *const*)0) {
+  FILE *f;
+
+  if ((f = fopen(name, "rb")) == NULL) return;
+
+  // read all the c-strings out of the file:
+  char** new_data = new char *[INITIALLINES];
+  char** temp_data;
+  int malloc_size = INITIALLINES;
+  char buffer[MAXSIZE+20];
+  int i = 0;
+  while (fgets(buffer,MAXSIZE+20,f)) {
+    if (buffer[0] != '\"') continue;
+    char *myp = buffer;
+    char *q = buffer+1;
+    while (*q != '\"' && myp < buffer+MAXSIZE) {
+      if (*q == '\\') switch (*++q) {
+      case '\r':
+      case '\n':
+	fgets(q,(buffer+MAXSIZE+20)-q,f); break;
+      case 0:
+	break;
+      case 'x': {
+	q++;
+	int n = 0;
+	for (int x = 0; x < 3; x++) {
+	  int xd = hexdigit(*q);
+	  if (xd > 15) break;
+	  n = (n<<4)+xd;
+	  q++;
+	}
+	*myp++ = n;
+      } break;
+      default: {
+	int c = *q++;
+	if (c>='0' && c<='7') {
+	  c -= '0';
+	  for (int x=0; x<2; x++) {
+	    int xd = hexdigit(*q);
+	    if (xd>7) break;
+	    c = (c<<3)+xd;
+	    q++;
+	  }
+	}
+	*myp++ = c;
+      } break;
+      } else {
+	*myp++ = *q++;
+      }
+    }
+    *myp++ = 0;
+    if (i >= malloc_size) {
+      temp_data = new char *[malloc_size + INITIALLINES];
+      memcpy(temp_data, new_data, sizeof(char *) * malloc_size);
+      delete[] new_data;
+      new_data = temp_data;
+      malloc_size += INITIALLINES;
+    }
+    new_data[i] = new char[myp-buffer+1];
+    memcpy(new_data[i], buffer,myp-buffer);
+    new_data[i][myp-buffer] = 0;
+    i++;
+  }
+
+  fclose(f);
+
+  data((const char **)new_data, i);
+  alloc_data = 1;
+
+  measure();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_abort.cxx b/Utilities/FLTK/src/Fl_abort.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7a0648a00425b2048722f77de10099e337e2617c
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_abort.cxx
@@ -0,0 +1,102 @@
+//
+// "$Id$"
+//
+// Warning/error message code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This method is in it's own source file so that stdlib and stdio
+// do not need to be included in Fl.cxx:
+// You can also override this by redefining all of these.
+
+#include <FL/Fl.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "flstring.h"
+
+#ifdef WIN32
+#  include <windows.h>
+
+static void warning(const char *, ...) {
+  // Show nothing for warnings under WIN32...
+}
+
+static void error(const char *format, ...) {
+  va_list args;
+  char buf[1024];
+  va_start(args, format);
+  vsnprintf(buf, 1024, format, args);
+  va_end(args);
+  MessageBox(0,buf,"Error",MB_ICONEXCLAMATION|MB_SYSTEMMODAL);
+}
+
+static void fatal(const char *format, ...) {
+  va_list args;
+  char buf[1024];
+  va_start(args, format);
+  vsnprintf(buf, 1024, format, args);
+  va_end(args);
+  MessageBox(0,buf,"Error",MB_ICONSTOP|MB_SYSTEMMODAL);
+  ::exit(1);
+}
+
+#else
+
+static void warning(const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  vfprintf(stderr, format, args);
+  va_end(args);
+  fputc('\n', stderr);
+  fflush(stderr);
+}
+
+static void error(const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  vfprintf(stderr, format, args);
+  va_end(args);
+  fputc('\n', stderr);
+  fflush(stderr);
+}
+
+static void fatal(const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  vfprintf(stderr, format, args);
+  va_end(args);
+  fputc('\n', stderr);
+  fflush(stderr);
+  ::exit(1);
+}
+
+#endif
+
+void (*Fl::warning)(const char* format, ...) = ::warning;
+void (*Fl::error)(const char* format, ...) = ::error;
+void (*Fl::fatal)(const char* format, ...) = ::fatal;
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_add_idle.cxx b/Utilities/FLTK/src/Fl_add_idle.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1afc4e987761ad88e0099cc55f0c3c1ab765e449
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_add_idle.cxx
@@ -0,0 +1,100 @@
+//
+// "$Id$"
+//
+// Idle routine support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Allows you to manage an arbitrary set of idle() callbacks.
+// Replaces the older set_idle() call (which is used to implement this)
+
+#include <FL/Fl.H>
+
+struct idle_cb {
+  void (*cb)(void*);
+  void* data;
+  idle_cb *next;
+};
+
+// the callbacks are stored linked in a ring.  last points at the one
+// just called, first at the next to call.  last->next == first.
+
+static idle_cb* first;
+static idle_cb* last;
+static idle_cb* freelist;
+
+static void call_idle() {
+  idle_cb* p = first;
+  last = p; first = p->next;
+  p->cb(p->data); // this may call add_idle() or remove_idle()!
+}
+
+void Fl::add_idle(void (*cb)(void*), void* data) {
+  idle_cb* p = freelist;
+  if (p) freelist = p->next;
+  else p = new idle_cb;
+  p->cb = cb;
+  p->data = data;
+  if (first) {
+    last->next = p;
+    last = p;
+    p->next = first;
+  } else {
+    first = last = p;
+    p->next = p;
+    set_idle(call_idle);
+  }
+}
+
+int Fl::has_idle(void (*cb)(void*), void* data) {
+  idle_cb* p = first;
+  if (!p) return 0;
+  for (;; p = p->next) {
+    if (p->cb == cb && p->data == data) return 1;
+    if (p==last) return 0;
+  }
+}
+
+void Fl::remove_idle(void (*cb)(void*), void* data) {
+  idle_cb* p = first;
+  if (!p) return;
+  idle_cb* l = last;
+  for (;; p = p->next) {
+    if (p->cb == cb && p->data == data) break;
+    if (p==last) return; // not found
+    l = p;
+  }
+  if (l == p) { // only one
+    first = last = 0;
+    set_idle(0);
+  } else {
+    last = l;
+    first = l->next = p->next;
+  }
+  p->next = freelist;
+  freelist = p;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_arg.cxx b/Utilities/FLTK/src/Fl_arg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c6b2e60a7beac0822ea77e7951c1aab26171c6c0
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_arg.cxx
@@ -0,0 +1,424 @@
+//
+// "$Id$"
+//
+// Optional argument initialization code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// OPTIONAL initialization code for a program using fltk.
+// You do not need to call this!  Feel free to make up your own switches.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Tooltip.H>
+#include <FL/filename.H>
+#include <FL/fl_draw.H>
+#include <ctype.h>
+#include "flstring.h"
+
+#if defined(WIN32) || defined(__APPLE__)
+int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*);
+#  define NoValue	0x0000
+#  define XValue  	0x0001
+#  define YValue	0x0002
+#  define WidthValue  	0x0004
+#  define HeightValue  	0x0008
+#  define AllValues 	0x000F
+#  define XNegative 	0x0010
+#  define YNegative 	0x0020
+#endif
+
+static int fl_match(const char *a, const char *s, int atleast = 1) {
+  const char *b = s;
+  while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;}
+  return !*a && b >= s+atleast;
+}
+
+// flags set by previously parsed arguments:
+extern char fl_show_iconic; // in Fl_x.cxx
+static char arg_called;
+static char return_i;
+static const char *name;
+static const char *geometry;
+static const char *title;
+// these are in Fl_get_system_colors and are set by the switches:
+extern const char *fl_fg;
+extern const char *fl_bg;
+extern const char *fl_bg2;
+
+// consume a switch from argv.  Returns number of words eaten, 0 on error:
+int Fl::arg(int argc, char **argv, int &i) {
+  arg_called = 1;
+  const char *s = argv[i];
+
+  if (!s) {i++; return 1;}	// something removed by calling program?
+
+  // a word that does not start with '-', or a word after a '--', or
+  // the word '-' by itself all start the "non-switch arguments" to
+  // a program.  Return 0 to indicate that we don't understand the
+  // word, but set a flag (return_i) so that args() will return at
+  // that point:
+  if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;}
+  s++; // point after the dash
+
+  if (fl_match(s, "iconic")) {
+    fl_show_iconic = 1;
+    i++;
+    return 1;
+  } else if (fl_match(s, "kbd")) {
+    Fl::visible_focus(1);
+    i++;
+    return 1;
+  } else if (fl_match(s, "nokbd", 3)) {
+    Fl::visible_focus(0);
+    i++;
+    return 1;
+  } else if (fl_match(s, "dnd", 2)) {
+    Fl::dnd_text_ops(1);
+    i++;
+    return 1;
+  } else if (fl_match(s, "nodnd", 3)) {
+    Fl::dnd_text_ops(0);
+    i++;
+    return 1;
+  } else if (fl_match(s, "tooltips", 2)) {
+    Fl_Tooltip::enable();
+    i++;
+    return 1;
+  } else if (fl_match(s, "notooltips", 3)) {
+    Fl_Tooltip::disable();
+    i++;
+    return 1;
+  }
+#ifdef __APPLE__
+  // The Finder application in MacOS X passes the "-psn_N_NNNNN" option
+  // to all apps...
+  else if (strncmp(s, "psn_", 4) == 0) {
+    i++;
+    return 1;
+  }
+#endif // __APPLE__
+
+  const char *v = argv[i+1];
+  if (i >= argc-1 || !v)
+    return 0;	// all the rest need an argument, so if missing it is an error
+
+  if (fl_match(s, "geometry")) {
+
+    int flags, gx, gy; unsigned int gw, gh;
+    flags = XParseGeometry(v, &gx, &gy, &gw, &gh);
+    if (!flags) return 0;
+    geometry = v;
+
+#if !defined(WIN32) && !defined(__APPLE__)
+  } else if (fl_match(s, "display", 2)) {
+    Fl::display(v);
+#endif
+
+  } else if (fl_match(s, "title", 2)) {
+    title = v;
+
+  } else if (fl_match(s, "name", 2)) {
+    name = v;
+
+  } else if (fl_match(s, "bg2", 3) || fl_match(s, "background2", 11)) {
+    fl_bg2 = v;
+
+  } else if (fl_match(s, "bg", 2) || fl_match(s, "background", 10)) {
+    fl_bg = v;
+
+  } else if (fl_match(s, "fg", 2) || fl_match(s, "foreground", 10)) {
+    fl_fg = v;
+
+  } else if (fl_match(s, "scheme", 1)) {
+    Fl::scheme(v);
+
+  } else return 0; // unrecognized
+
+  i += 2;
+  return 2;
+}
+
+// consume all switches from argv.  Returns number of words eaten.
+// Returns zero on error.  'i' will either point at first word that
+// does not start with '-', at the error word, or after a '--', or at
+// argc.  If your program does not take any word arguments you can
+// report an error if i < argc.
+
+int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) {
+  arg_called = 1;
+  i = 1; // skip argv[0]
+  while (i < argc) {
+    if (cb && cb(argc,argv,i)) continue;
+    if (!arg(argc,argv,i)) return return_i ? i : 0;
+  }
+  return i;
+}
+
+// show a main window, use any parsed arguments
+void Fl_Window::show(int argc, char **argv) {
+  if (argc && !arg_called) Fl::args(argc,argv);
+
+  Fl::get_system_colors();
+
+#if !defined(WIN32) && !defined(__APPLE__)
+  // Get defaults for drag-n-drop and focus...
+  const char *key = 0, *val;
+
+  if (Fl::first_window()) key = Fl::first_window()->xclass();
+  if (!key) key = "fltk";
+
+  val = XGetDefault(fl_display, key, "dndTextOps");
+  if (val) Fl::dnd_text_ops(strcasecmp(val, "true") == 0 ||
+                            strcasecmp(val, "on") == 0 ||
+                            strcasecmp(val, "yes") == 0);
+
+  val = XGetDefault(fl_display, key, "tooltips");
+  if (val) Fl_Tooltip::enable(strcasecmp(val, "true") == 0 ||
+                              strcasecmp(val, "on") == 0 ||
+                              strcasecmp(val, "yes") == 0);
+
+  val = XGetDefault(fl_display, key, "visibleFocus");
+  if (val) Fl::visible_focus(strcasecmp(val, "true") == 0 ||
+                             strcasecmp(val, "on") == 0 ||
+                             strcasecmp(val, "yes") == 0);
+#endif // !WIN32 && !__APPLE__
+
+  // set colors first, so background_pixel is correct:
+  static char beenhere;
+  if (!beenhere) {
+    if (geometry) {
+      int fl = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
+      fl = XParseGeometry(geometry, &gx, &gy, &gw, &gh);
+      if (fl & XNegative) gx = Fl::w()-w()+gx;
+      if (fl & YNegative) gy = Fl::h()-h()+gy;
+      //  int mw,mh; minsize(mw,mh);
+      //  if (mw > gw) gw = mw;
+      //  if (mh > gh) gh = mh;
+      Fl_Widget *r = resizable();
+      if (!r) resizable(this);
+      // for WIN32 we assumme window is not mapped yet:
+      if (fl & (XValue | YValue))
+	x(-1), resize(gx,gy,gw,gh);
+      else
+	size(gw,gh);
+      resizable(r);
+    }
+  }
+
+  // set the class, which is used by X version of get_system_colors:
+  if (name) {xclass(name); name = 0;}
+  else if (!xclass()) xclass(fl_filename_name(argv[0]));
+
+  if (title) {label(title); title = 0;}
+  else if (!label()) label(xclass());
+
+  if (!beenhere) {
+    beenhere = 1;
+    Fl::scheme(Fl::scheme()); // opens display!  May call Fl::fatal()
+  }
+
+  // Show the window AFTER we have set the colors and scheme.
+  show();
+
+#if !defined(WIN32) && !defined(__APPLE__)
+  // set the command string, used by state-saving window managers:
+  int j;
+  int n=0; for (j=0; j<argc; j++) n += strlen(argv[j])+1;
+  char *buffer = new char[n];
+  char *p = buffer;
+  for (j=0; j<argc; j++) for (const char *q = argv[j]; (*p++ = *q++););
+  XChangeProperty(fl_display, fl_xid(this), XA_WM_COMMAND, XA_STRING, 8, 0,
+		  (unsigned char *)buffer, p-buffer-1);
+  delete[] buffer;
+#endif // !WIN32 && !__APPLE__
+}
+
+// Calls useful for simple demo programs, with automatic help message:
+
+static const char * const helpmsg =
+"options are:\n"
+" -bg2 color\n"
+" -bg color\n"
+" -di[splay] host:n.n\n"
+" -dn[d]\n"
+" -fg color\n"
+" -g[eometry] WxH+X+Y\n"
+" -i[conic]\n"
+" -k[bd]\n"
+" -na[me] classname\n"
+" -nod[nd]\n"
+" -nok[bd]\n"
+" -not[ooltips]\n"
+" -s[cheme] scheme\n"
+" -ti[tle] windowtitle\n"
+" -to[oltips]";
+
+const char * const Fl::help = helpmsg+13;
+
+void Fl::args(int argc, char **argv) {
+  int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg);
+}
+
+#if defined(WIN32) || defined(__APPLE__)
+
+/* the following function was stolen from the X sources as indicated. */
+
+/* Copyright 	Massachusetts Institute of Technology  1985, 1986, 1987 */
+/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
+
+/*
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  M.I.T. makes no representations about the
+suitability of this software for any purpose.  It is provided "as is"
+without express or implied warranty.
+*/
+
+/*
+ *    XParseGeometry parses strings of the form
+ *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ *   width, height, xoffset, and yoffset are unsigned integers.
+ *   Example:  "=80x24+300-49"
+ *   The equal sign is optional.
+ *   It returns a bitmask that indicates which of the four values
+ *   were actually found in the string.  For each value found,
+ *   the corresponding argument is updated;  for each value
+ *   not found, the corresponding argument is left unchanged. 
+ */
+
+static int ReadInteger(char* string, char** NextString)
+{
+  register int Result = 0;
+  int Sign = 1;
+    
+  if (*string == '+')
+    string++;
+  else if (*string == '-') {
+    string++;
+    Sign = -1;
+  }
+  for (; (*string >= '0') && (*string <= '9'); string++) {
+    Result = (Result * 10) + (*string - '0');
+  }
+  *NextString = string;
+  if (Sign >= 0)
+    return (Result);
+  else
+    return (-Result);
+}
+
+int XParseGeometry(const char* string, int* x, int* y,
+		   unsigned int* width, unsigned int* height)
+{
+  int mask = NoValue;
+  register char *strind;
+  unsigned int tempWidth = 0, tempHeight = 0;
+  int tempX = 0, tempY = 0;
+  char *nextCharacter;
+
+  if ( (string == NULL) || (*string == '\0')) return(mask);
+  if (*string == '=')
+    string++;  /* ignore possible '=' at beg of geometry spec */
+
+  strind = (char *)string;
+  if (*strind != '+' && *strind != '-' && *strind != 'x') {
+    tempWidth = ReadInteger(strind, &nextCharacter);
+    if (strind == nextCharacter) 
+      return (0);
+    strind = nextCharacter;
+    mask |= WidthValue;
+  }
+
+  if (*strind == 'x' || *strind == 'X') {	
+    strind++;
+    tempHeight = ReadInteger(strind, &nextCharacter);
+    if (strind == nextCharacter)
+      return (0);
+    strind = nextCharacter;
+    mask |= HeightValue;
+  }
+
+  if ((*strind == '+') || (*strind == '-')) {
+    if (*strind == '-') {
+      strind++;
+      tempX = -ReadInteger(strind, &nextCharacter);
+      if (strind == nextCharacter)
+	return (0);
+      strind = nextCharacter;
+      mask |= XNegative;
+
+    } else {
+      strind++;
+      tempX = ReadInteger(strind, &nextCharacter);
+      if (strind == nextCharacter)
+	return(0);
+      strind = nextCharacter;
+      }
+    mask |= XValue;
+    if ((*strind == '+') || (*strind == '-')) {
+      if (*strind == '-') {
+	strind++;
+	tempY = -ReadInteger(strind, &nextCharacter);
+	if (strind == nextCharacter)
+	  return(0);
+	strind = nextCharacter;
+	mask |= YNegative;
+
+      } else {
+	strind++;
+	tempY = ReadInteger(strind, &nextCharacter);
+	if (strind == nextCharacter)
+	  return(0);
+	strind = nextCharacter;
+      }
+      mask |= YValue;
+    }
+  }
+	
+  /* If strind isn't at the end of the string the it's an invalid
+     geometry specification. */
+
+  if (*strind != '\0') return (0);
+
+  if (mask & XValue)
+    *x = tempX;
+  if (mask & YValue)
+    *y = tempY;
+  if (mask & WidthValue)
+    *width = tempWidth;
+  if (mask & HeightValue)
+    *height = tempHeight;
+  return (mask);
+}
+
+#endif // ifdef WIN32
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_compose.cxx b/Utilities/FLTK/src/Fl_compose.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f05e6bc1f05ddf5e7a97fa0714680ddb998c7b3f
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_compose.cxx
@@ -0,0 +1,167 @@
+//
+// "$Id$"
+//
+// Character compose processing for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+
+//
+// MRS: Uncomment the following define to get the original (pre-1.1.2)
+//      dead key support code.  The original code apparently did not
+//      work on Belgian keyboards.
+//
+
+//#define OLD_DEAD_KEY_CODE
+
+
+static const char* const compose_pairs =
+"  ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "
+"`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss"
+"`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y";
+
+#if !defined(WIN32) && defined(OLD_DEAD_KEY_CODE) // X only
+// X dead-key lookup table.  This turns a dead-key keysym into the
+// first of two characters for one of the compose sequences.  These
+// keysyms start at 0xFE50.
+// Win32 handles the dead keys before FLTK can see them.  This is
+// unfortunate, because you don't get the preview effect.
+static char dead_keys[] = {
+  '`',	// XK_dead_grave
+  '\'',	// XK_dead_acute
+  '^',	// XK_dead_circumflex
+  '~',	// XK_dead_tilde
+  '_',	// XK_dead_macron
+  0,	// XK_dead_breve
+  '.',	// XK_dead_abovedot
+  ':',	// XK_dead_diaeresis
+  '*',	// XK_dead_abovering
+  0,	// XK_dead_doubleacute
+  'v',	// XK_dead_caron
+  ','	// XK_dead_cedilla
+//   0,	// XK_dead_ogonek
+//   0,	// XK_dead_iota
+//   0,	// XK_dead_voiced_sound
+//   0,	// XK_dead_semivoiced_sound
+//   0	// XK_dead_belowdot
+};
+#endif // !WIN32 && OLD_DEAD_KEY_CODE
+
+int Fl::compose_state = 0;
+
+int Fl::compose(int& del) {
+
+  del = 0;
+  unsigned char ascii = (unsigned)e_text[0];
+
+  // Alt+letters are reserved for shortcuts.  But alt+foreign letters
+  // has to be allowed, because some key layouts require alt to be held
+  // down in order to type them...
+  //
+  // OSX users sometimes need to hold down ALT for keys, so we only check
+  // for META on OSX...
+#ifdef __APPLE__
+  if ((e_state & FL_META) && !(ascii & 128)) return 0;
+#else
+  if ((e_state & (FL_ALT|FL_META)) && !(ascii & 128)) return 0;
+#endif // __APPLE__
+
+  if (compose_state == 1) { // after the compose key
+
+    if (ascii == ' ') { // space turns into nbsp
+      e_text[0] = char(0xA0);
+      compose_state = 0;
+      return 1;
+    } else if (ascii < ' ' || ascii == 127) {
+      compose_state = 0;
+      return 0;
+    }
+
+    // see if it is either character of any pair:
+    for (const char *p = compose_pairs; *p; p += 2) 
+      if (p[0] == ascii || p[1] == ascii) {
+	if (p[1] == ' ') e_text[0] = (p-compose_pairs)/2+0xA0;
+	compose_state = ascii;
+	return 1;
+      }
+
+    if (e_length) { // compose key also "quotes" control characters
+      compose_state = 0;
+      return 1;
+    }
+
+  } else if (compose_state) { // second character of compose
+
+    char c1 = char(compose_state); // retrieve first character
+    // now search for the pair in either order:
+    for (const char *p = compose_pairs; *p; p += 2) {
+      if (p[0] == ascii && p[1] == c1 || p[1] == ascii && p[0] == c1) {
+	e_text[0] = (p-compose_pairs)/2+0xA0;
+	del = 1; // delete the old character and insert new one
+	compose_state = 0;
+	return 1;
+      }
+    }
+
+  }
+
+  int i = e_keysym;
+
+  // See if they type the compose prefix key:
+  if (i == FL_Control_R || i == 0xff20/* Multi-Key */) {
+    compose_state = 1;
+    return 1;
+  }
+
+#ifndef WIN32 // X only
+  // See if they typed a dead key.  This gets it into the same state as
+  // typing prefix+accent:
+  if (i >= 0xfe50 && i <= 0xfe5b) {
+#  ifdef OLD_DEAD_KEY_CODE
+    ascii = dead_keys[i-0xfe50];
+    for (const char *p = compose_pairs; *p; p += 2)
+      if (p[0] == ascii) {
+	compose_state = ascii;
+	return 1;
+      }
+#  else
+    ascii = e_text[0];
+    for (const char *p = compose_pairs; *p; p += 2)
+      if (p[0] == ascii ||
+          (p[1] == ' ' && (p - compose_pairs) / 2 + 0xA0 == ascii)) {
+        compose_state = p[0];
+        return 1;
+      }
+#  endif // OLD_DEAD_KEY_CODE
+    compose_state = 0;
+    return 1;
+  }
+#endif
+
+  // Only insert non-control characters:
+  if (e_length && (ascii & ~31 && ascii!=127)) {compose_state = 0; return 1;}
+
+  return 0;
+}
+
diff --git a/Utilities/FLTK/src/Fl_display.cxx b/Utilities/FLTK/src/Fl_display.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8afc2583e78e8bbca083e20aaa415786294a1037
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_display.cxx
@@ -0,0 +1,54 @@
+//
+// "$Id$"
+//
+// Display function for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Startup method to set what display to use.
+// Using setenv makes programs that are exec'd use the same display.
+
+#include <FL/Fl.H>
+#include <stdlib.h>
+#include "flstring.h"
+
+void Fl::display(const char *d) {
+#if defined(__APPLE__) || defined(WIN32)
+  (void)d;
+#else
+  static char e[1024];
+  strcpy(e,"DISPLAY=");
+  strlcat(e,d,sizeof(e));
+  for (char *c = e+8; *c!=':'; c++) {
+    if (!*c) {
+      strlcat(e,":0.0",sizeof(e));
+      break;
+    }
+  }
+  putenv(e);
+#endif // __APPLE__
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_get_key.cxx b/Utilities/FLTK/src/Fl_get_key.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..02efea25d524cc1f88394fce13776d7d74d80a8d
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_get_key.cxx
@@ -0,0 +1,69 @@
+//
+// "$Id$"
+//
+// Keyboard state routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifdef WIN32
+#  include "Fl_get_key_win32.cxx"
+#elif defined(__APPLE__)
+#  include "Fl_get_key_mac.cxx"
+#else
+
+// Return the current state of a key.  This is the X version.  I identify
+// keys (mostly) by the X keysym.  So this turns the keysym into a keycode
+// and looks it up in the X key bit vector, which Fl_x.cxx keeps track of.
+
+#  include <FL/Fl.H>
+#  include <FL/x.H>
+
+extern char fl_key_vector[32]; // in Fl_x.cxx
+
+int Fl::event_key(int k) {
+  if (k > FL_Button && k <= FL_Button+8)
+    return Fl::event_state(8<<(k-FL_Button));
+  int i;
+#  ifdef __sgi
+  // get some missing PC keyboard keys:
+  if (k == FL_Meta_L) i = 147;
+  else if (k == FL_Meta_R) i = 148;
+  else if (k == FL_Menu) i = 149;
+  else
+#  endif
+    i = XKeysymToKeycode(fl_display, k);
+  if (i==0) return 0;
+  return fl_key_vector[i/8] & (1 << (i%8));
+}
+
+int Fl::get_key(int k) {
+  fl_open_display();
+  XQueryKeymap(fl_display, fl_key_vector);
+  return event_key(k);
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_get_key_mac.cxx b/Utilities/FLTK/src/Fl_get_key_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..39f0d4b97e447a9cf624fecfc2e0a3d780fc355e
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_get_key_mac.cxx
@@ -0,0 +1,107 @@
+//
+// "$Id$"
+//
+// MacOS keyboard state routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Return the current state of a key.  Keys are named by fltk symbols,
+// which are actually X keysyms.  So this has to translate to macOS
+// symbols.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+// convert an FLTK (X) keysym to a MacOS symbol:
+// See also the inverse converter in Fl_mac.cxx
+// This table is in numeric order by FLTK symbol order for binary search:
+
+static const struct {unsigned short vk, fltk;} vktab[] = {
+  { 49, ' ' }, { 39, '\'' }, { 43, ',' }, { 27, '-' }, { 47, '.' }, { 44, '/' }, 
+  { 29, '0' }, { 18, '1'  }, { 19, '2'  }, { 20, '3'  }, 
+  { 21, '4' }, { 23, '5'  }, { 22, '6'  }, { 26, '7'  }, 
+  { 28, '8' }, { 25, '9'  }, { 41, ';'  }, { 24, '='  },
+  {  0, 'A' }, { 11, 'B'  }, {  8, 'C'  }, {  2, 'D'  }, 
+  { 14, 'E' }, {  3, 'F'  }, {  5, 'G'  }, {  4, 'H'  }, 
+  { 34, 'I' }, { 38, 'J'  }, { 40, 'K'  }, { 37, 'L'  }, 
+  { 46, 'M' }, { 45, 'N'  }, { 31, 'O'  }, { 35, 'P'  }, 
+  { 12, 'Q' }, { 15, 'R'  }, {  1, 'S'  }, { 17, 'T'  }, 
+  { 32, 'U' }, {  9, 'V'  }, { 13, 'W'  }, {  7, 'X'  }, 
+  { 16, 'Y' }, {  6, 'Z'  }, 
+  { 33, '[' }, { 30, ']' }, { 50, '`' },  { 42, '|' },
+  { 51, FL_BackSpace }, { 48, FL_Tab }, { 36, FL_Enter }, { 127, FL_Pause },
+  { 107, FL_Scroll_Lock }, { 53, FL_Escape }, { 0x73, FL_Home }, { 123, FL_Left },
+  { 126, FL_Up }, { 124, FL_Right }, { 125, FL_Down }, { 0x74, FL_Page_Up },
+  { 0x79, FL_Page_Down },  { 119, FL_End }, { 0x71, FL_Print }, { 127, FL_Insert },
+  { 0x6e, FL_Menu }, { 114, FL_Help }, { 0x47, FL_Num_Lock }, 
+  { 76, FL_KP_Enter }, { 67, FL_KP+'*' }, { 69, FL_KP+'+'}, { 78, FL_KP+'-' }, { 65, FL_KP+'.' }, { 75, FL_KP+'/' }, 
+  { 82, FL_KP+'0' }, { 83, FL_KP+'1' }, { 84, FL_KP+'2' }, { 85, FL_KP+'3' }, 
+  { 86, FL_KP+'4' }, { 87, FL_KP+'5' }, { 88, FL_KP+'6' }, { 89, FL_KP+'7' }, 
+  { 91, FL_KP+'8' }, { 92, FL_KP+'9' }, { 81, FL_KP+'=' }, 
+  { 0x7a, FL_F+1 }, { 0x78, FL_F+2  }, { 0x63, FL_F+3  }, { 0x76, FL_F+4  }, 
+  { 0x60, FL_F+5 }, { 0x61, FL_F+6  }, { 0x62, FL_F+7  }, { 0x64, FL_F+8  }, 
+  { 0x65, FL_F+9 }, { 0x6D, FL_F+10 }, { 0x67, FL_F+11 }, { 0x6f, FL_F+12 }, 
+  { 56, FL_Shift_L }, { 56, FL_Shift_R }, { 59, FL_Control_L }, { 59, FL_Control_R }, 
+  { 57, FL_Caps_Lock }, { 55, FL_Meta_L }, { 55, FL_Meta_R },
+  { 58, FL_Alt_L }, { 58, FL_Alt_R }, { 0x75, FL_Delete },
+};
+
+static int fltk2mac(int fltk) {
+  int a = 0;
+  int b = sizeof(vktab)/sizeof(*vktab);
+  while (a < b) {
+    int c = (a+b)/2;
+    if (vktab[c].fltk == fltk) return vktab[c].vk;
+    if (vktab[c].fltk < fltk) a = c+1; else b = c;
+  }
+  return 127;
+}
+
+//: returns true, if that key was pressed during the last event
+int Fl::event_key(int k) {
+  return get_key(k);
+}
+
+#include <stdio.h>
+
+//: returns true, if that key is pressed right now
+int Fl::get_key(int k) {
+  KeyMap foo;
+  GetKeys(foo);
+#ifdef MAC_TEST_FOR_KEYCODES
+ static int cnt = 0;
+ if (cnt++>1024) {
+  cnt = 0;
+  printf("%08x %08x %08x %08x\n", (ulong*)(foo)[3], (ulong*)(foo)[2], (ulong*)(foo)[1], (ulong*)(foo)[0]);
+ }
+#endif
+  int i = fltk2mac(k);
+  unsigned char *b = (unsigned char*)foo;
+  return (b[i>>3]>>(i&7))&1;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_get_key_win32.cxx b/Utilities/FLTK/src/Fl_get_key_win32.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..eaa677a5abc2f9e80e57daf6d27f75c0a42f1fc7
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_get_key_win32.cxx
@@ -0,0 +1,138 @@
+//
+// "$Id$"
+//
+// WIN32 keyboard state routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Return the current state of a key.  Keys are named by fltk symbols,
+// which are actually X keysyms.  So this has to translate to MSWindows
+// VK_x symbols.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+// convert an Fltk (X) keysym to a MSWindows VK symbol:
+// See also the inverse converter in Fl_win32.cxx
+// This table is in numeric order by Fltk symbol order for binary search:
+
+static const struct {unsigned short vk, fltk;} vktab[] = {
+  {VK_SPACE,	' '},
+  {'1',		'!'},
+  {0xde,	'\"'},
+  {'3',		'#'},
+  {'4',		'$'},
+  {'5',		'%'},
+  {'7',		'&'},
+  {0xde,	'\''},
+  {'9',		'('},
+  {'0',		')'},
+  {'8',		'*'},
+  {0xbb,	'+'},
+  {0xbc,	','},
+  {0xbd,	'-'},
+  {0xbe,	'.'},
+  {0xbf,	'/'},
+  {0xba,	':'},
+  {0xba,	';'},
+  {0xbc,	'<'},
+  {0xbb,	'='},
+  {0xbe,	'>'},
+  {0xbf,	'?'},
+  {'2',		'@'},
+  {0xdb,	'['},
+  {0xdc,	'\\'},
+  {0xdd,	']'},
+  {'6',		'^'},
+  {0xbd,	'_'},
+  {0xc0,	'`'},
+  {0xdb,	'{'},
+  {0xdc,	'|'},
+  {0xdd,	'}'},
+  {0xc0,	'~'},
+  {VK_BACK,	FL_BackSpace},
+  {VK_TAB,	FL_Tab},
+  {VK_CLEAR,	0xff0b/*XK_Clear*/},
+  {VK_RETURN,	FL_Enter},
+  {VK_PAUSE,	FL_Pause},
+  {VK_SCROLL,	FL_Scroll_Lock},
+  {VK_ESCAPE,	FL_Escape},
+  {VK_HOME,	FL_Home},
+  {VK_LEFT,	FL_Left},
+  {VK_UP,	FL_Up},
+  {VK_RIGHT,	FL_Right},
+  {VK_DOWN,	FL_Down},
+  {VK_PRIOR,	FL_Page_Up},
+  {VK_NEXT,	FL_Page_Down},
+  {VK_END,	FL_End},
+  {VK_SNAPSHOT,	FL_Print},
+  {VK_INSERT,	FL_Insert},
+  {VK_APPS,	FL_Menu},
+  {VK_NUMLOCK,	FL_Num_Lock},
+//{VK_???,	FL_KP_Enter},
+  {VK_MULTIPLY,	FL_KP+'*'},
+  {VK_ADD,	FL_KP+'+'},
+  {VK_SUBTRACT,	FL_KP+'-'},
+  {VK_DECIMAL,	FL_KP+'.'},
+  {VK_DIVIDE,	FL_KP+'/'},
+  {VK_LSHIFT,	FL_Shift_L},
+  {VK_RSHIFT,	FL_Shift_R},
+  {VK_LCONTROL,	FL_Control_L},
+  {VK_RCONTROL,	FL_Control_R},
+  {VK_CAPITAL,	FL_Caps_Lock},
+  {VK_LWIN,	FL_Meta_L},
+  {VK_RWIN,	FL_Meta_R},
+  {VK_LMENU,	FL_Alt_L},
+  {VK_RMENU,	FL_Alt_R},
+  {VK_DELETE,	FL_Delete}
+};
+
+static int fltk2ms(int fltk) {
+  if (fltk >= '0' && fltk <= '9') return fltk;
+  if (fltk >= 'A' && fltk <= 'Z') return fltk;
+  if (fltk >= 'a' && fltk <= 'z') return fltk-('a'-'A');
+  if (fltk > FL_F && fltk <= FL_F+16) return fltk-(FL_F-(VK_F1-1));
+  if (fltk >= FL_KP+'0' && fltk<=FL_KP+'9') return fltk-(FL_KP+'0'-VK_NUMPAD0);
+  int a = 0;
+  int b = sizeof(vktab)/sizeof(*vktab);
+  while (a < b) {
+    int c = (a+b)/2;
+    if (vktab[c].fltk == fltk) return vktab[c].vk;
+    if (vktab[c].fltk < fltk) a = c+1; else b = c;
+  }
+  return 0;
+}
+
+int Fl::event_key(int k) {
+  return GetKeyState(fltk2ms(k))&~1;
+}
+
+int Fl::get_key(int k) {
+  uchar foo[256];
+  GetKeyboardState(foo);
+  return foo[fltk2ms(k)]&~1;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_get_system_colors.cxx b/Utilities/FLTK/src/Fl_get_system_colors.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1193647ffff35ec0f784ba186f7c9d2b2e281f48
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_get_system_colors.cxx
@@ -0,0 +1,348 @@
+//
+// "$Id$"
+//
+// System color support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: add line #include "fltk-config.h" */
+#include "fltk-config.h"
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/math.h>
+#include "flstring.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_Tiled_Image.H>
+#include "tile.xpm"
+
+#if defined(__APPLE__) && defined(__MWERKS__)
+extern "C" int putenv(const char*);
+#endif // __APPLE__ && __MWERKS__
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define putenv _putenv
+#endif // WIN32 && !__CYGWIN__
+
+static char	fl_bg_set = 0;
+static char	fl_bg2_set = 0;
+static char	fl_fg_set = 0;
+
+
+void Fl::background(uchar r, uchar g, uchar b) {
+  fl_bg_set = 1;
+
+  // replace the gray ramp so that FL_GRAY is this color
+  if (!r) r = 1; else if (r==255) r = 254;
+  double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+  if (!g) g = 1; else if (g==255) g = 254;
+  double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+  if (!b) b = 1; else if (b==255) b = 254;
+  double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+  for (int i = 0; i < FL_NUM_GRAY; i++) {
+    double gray = i/(FL_NUM_GRAY-1.0);
+    Fl::set_color(fl_gray_ramp(i),
+		  uchar(pow(gray,powr)*255+.5),
+		  uchar(pow(gray,powg)*255+.5),
+		  uchar(pow(gray,powb)*255+.5));
+  }
+}
+
+void Fl::foreground(uchar r, uchar g, uchar b) {
+  fl_fg_set = 1;
+
+  Fl::set_color(FL_FOREGROUND_COLOR,r,g,b);
+}
+
+void Fl::background2(uchar r, uchar g, uchar b) {
+  fl_bg2_set = 1;
+
+  Fl::set_color(FL_BACKGROUND2_COLOR,r,g,b);
+  Fl::set_color(FL_FOREGROUND_COLOR,
+                get_color(fl_contrast(FL_FOREGROUND_COLOR,FL_BACKGROUND2_COLOR)));
+}
+
+// these are set by Fl::args() and override any system colors:
+const char *fl_fg = NULL;
+const char *fl_bg = NULL;
+const char *fl_bg2 = NULL;
+
+static void set_selection_color(uchar r, uchar g, uchar b) {
+  Fl::set_color(FL_SELECTION_COLOR,r,g,b);
+}
+
+#if defined(WIN32) || defined(__APPLE__)
+
+#  include <stdio.h>
+// simulation of XParseColor:
+int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) {
+  if (*p == '#') p++;
+  int n = strlen(p);
+  int m = n/3;
+  const char *pattern = 0;
+  switch(m) {
+  case 1: pattern = "%1x%1x%1x"; break;
+  case 2: pattern = "%2x%2x%2x"; break;
+  case 3: pattern = "%3x%3x%3x"; break;
+  case 4: pattern = "%4x%4x%4x"; break;
+  default: return 0;
+  }
+  int R,G,B; if (sscanf(p,pattern,&R,&G,&B) != 3) return 0;
+  switch(m) {
+  case 1: R *= 0x11; G *= 0x11; B *= 0x11; break;
+  case 3: R >>= 4; G >>= 4; B >>= 4; break;
+  case 4: R >>= 8; G >>= 8; B >>= 8; break;
+  }
+  r = (uchar)R; g = (uchar)G; b = (uchar)B;
+  return 1;
+}
+#else
+// Wrapper around XParseColor...
+int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) {
+  XColor x;
+  if (!fl_display) fl_open_display();
+  if (XParseColor(fl_display, fl_colormap, p, &x)) {
+    r = (uchar)(x.red>>8);
+    g = (uchar)(x.green>>8);
+    b = (uchar)(x.blue>>8);
+    return 1;
+  } else return 0;
+}
+#endif // WIN32 || __APPLE__
+
+#if defined(WIN32)
+static void
+getsyscolor(int what, const char* arg, void (*func)(uchar,uchar,uchar))
+{
+  if (arg) {
+    uchar r,g,b;
+    if (!fl_parse_color(arg, r,g,b))
+      Fl::error("Unknown color: %s", arg);
+    else
+      func(r,g,b);
+  } else {
+    DWORD x = GetSysColor(what);
+    func(uchar(x&255), uchar(x>>8), uchar(x>>16));
+  }
+}
+
+void Fl::get_system_colors() {
+  if (!fl_bg2_set) getsyscolor(COLOR_WINDOW,	fl_bg2,Fl::background2);
+  if (!fl_fg_set) getsyscolor(COLOR_WINDOWTEXT,	fl_fg, Fl::foreground);
+  if (!fl_bg_set) getsyscolor(COLOR_BTNFACE,	fl_bg, Fl::background);
+  getsyscolor(COLOR_HIGHLIGHT,	0,     set_selection_color);
+}
+
+#elif defined(__APPLE__)
+// MacOS X currently supports two color schemes - Blue and Graphite.
+// Since we aren't emulating the Aqua interface (even if Apple would
+// let us), we use some defaults that are similar to both.  The
+// Fl::scheme("plastic") color/box scheme provides a usable Aqua-like
+// look-n-feel...
+void Fl::get_system_colors()
+{
+  fl_open_display();
+
+  if (!fl_bg2_set) background2(0xff, 0xff, 0xff);
+  if (!fl_fg_set) foreground(0, 0, 0);
+  if (!fl_bg_set) background(0xd8, 0xd8, 0xd8);
+  set_selection_color(0x00, 0x00, 0x80);
+}
+#else
+
+// Read colors that KDE writes to the xrdb database.
+
+// XGetDefault does not do the expected thing: it does not like
+// periods in either word. Therefore it cannot match class.Text.background.
+// However *.Text.background is matched by pretending the program is "Text".
+// But this will also match *.background if there is no *.Text.background
+// entry, requiring users to put in both (unless they want the text fields
+// the same color as the windows).
+
+static void
+getsyscolor(const char *key1, const char* key2, const char *arg, const char *defarg, void (*func)(uchar,uchar,uchar))
+{
+  if (!arg) {
+    arg = XGetDefault(fl_display, key1, key2);
+    if (!arg) arg = defarg;
+  }
+  XColor x;
+  if (!XParseColor(fl_display, fl_colormap, arg, &x))
+    Fl::error("Unknown color: %s", arg);
+  else
+    func(x.red>>8, x.green>>8, x.blue>>8);
+}
+
+void Fl::get_system_colors()
+{
+  fl_open_display();
+  const char* key1 = 0;
+  if (Fl::first_window()) key1 = Fl::first_window()->xclass();
+  if (!key1) key1 = "fltk";
+  if (!fl_bg2_set) getsyscolor("Text","background",	fl_bg2,	"#ffffff", Fl::background2);
+  if (!fl_fg_set) getsyscolor(key1,  "foreground",	fl_fg,	"#000000", Fl::foreground);
+  if (!fl_bg_set) getsyscolor(key1,  "background",	fl_bg,	"#c0c0c0", Fl::background);
+  getsyscolor(key1,  "selectBackground",0,	"#000080", set_selection_color);
+}
+
+#endif
+
+
+//// Simple implementation of 2.0 Fl::scheme() interface...
+#define D1 BORDER_WIDTH
+#define D2 (BORDER_WIDTH+BORDER_WIDTH)
+
+extern void	fl_up_box(int, int, int, int, Fl_Color);
+extern void	fl_down_box(int, int, int, int, Fl_Color);
+extern void	fl_thin_up_box(int, int, int, int, Fl_Color);
+extern void	fl_thin_down_box(int, int, int, int, Fl_Color);
+extern void	fl_round_up_box(int, int, int, int, Fl_Color);
+extern void	fl_round_down_box(int, int, int, int, Fl_Color);
+
+extern void	fl_up_frame(int, int, int, int, Fl_Color);
+extern void	fl_down_frame(int, int, int, int, Fl_Color);
+extern void	fl_thin_up_frame(int, int, int, int, Fl_Color);
+extern void	fl_thin_down_frame(int, int, int, int, Fl_Color);
+
+const char	*Fl::scheme_ = (const char *)0;
+Fl_Image	*Fl::scheme_bg_ = (Fl_Image *)0;
+
+static Fl_Pixmap	tile(tile_xpm);
+
+int Fl::scheme(const char *s) {
+  if (!s) {
+    if ((s = getenv("FLTK_SCHEME")) == NULL) {
+#if !defined(WIN32) && !defined(__APPLE__)
+      const char* key = 0;
+      if (Fl::first_window()) key = Fl::first_window()->xclass();
+      if (!key) key = "fltk";
+      fl_open_display();
+      s = XGetDefault(fl_display, key, "scheme");
+#endif // !WIN32 && !__APPLE__
+    }
+  }
+
+  if (s) {
+    if (!strcasecmp(s, "none") || !strcasecmp(s, "base") || !*s) s = 0;
+    else s = strdup(s);
+  }
+  if (scheme_) free((void*)scheme_);
+  scheme_ = s;
+
+  // Save the new scheme in the FLTK_SCHEME env var so that child processes
+  // inherit it...
+  static char e[1024];
+  strcpy(e,"FLTK_SCHEME=");
+  if (s) strlcat(e,s,sizeof(e));
+  putenv(e);
+
+  // Load the scheme...
+  return reload_scheme();
+}
+
+int Fl::reload_scheme() {
+  Fl_Window *win;
+
+  if (scheme_ && !strcasecmp(scheme_, "plastic")) {
+    // Update the tile image to match the background color...
+    uchar r, g, b;
+    int nr, ng, nb;
+    int i;
+//    static uchar levels[3] = { 0xff, 0xef, 0xe8 };
+    // OSX 10.3 and higher use a background with less contrast...
+    static uchar levels[3] = { 0xff, 0xf8, 0xf4 };
+
+    get_color(FL_GRAY, r, g, b);
+
+//    printf("FL_GRAY = 0x%02x 0x%02x 0x%02x\n", r, g, b);
+
+    for (i = 0; i < 3; i ++) {
+      nr = levels[i] * r / 0xe8;
+      if (nr > 255) nr = 255;
+
+      ng = levels[i] * g / 0xe8;
+      if (ng > 255) ng = 255;
+
+      nb = levels[i] * b / 0xe8;
+      if (nb > 255) nb = 255;
+
+      sprintf(tile_cmap[i], "%c c #%02x%02x%02x", "Oo."[i], nr, ng, nb);
+//      puts(tile_cmap[i]);
+    }
+
+    tile.uncache();
+
+    if (!scheme_bg_) scheme_bg_ = new Fl_Tiled_Image(&tile, w(), h());
+
+    // Load plastic buttons, etc...
+    set_boxtype(FL_UP_FRAME,        FL_PLASTIC_UP_FRAME);
+    set_boxtype(FL_DOWN_FRAME,      FL_PLASTIC_DOWN_FRAME);
+    set_boxtype(FL_THIN_UP_FRAME,   FL_PLASTIC_UP_FRAME);
+    set_boxtype(FL_THIN_DOWN_FRAME, FL_PLASTIC_DOWN_FRAME);
+
+    set_boxtype(FL_UP_BOX,          FL_PLASTIC_UP_BOX);
+    set_boxtype(FL_DOWN_BOX,        FL_PLASTIC_DOWN_BOX);
+    set_boxtype(FL_THIN_UP_BOX,     FL_PLASTIC_THIN_UP_BOX);
+    set_boxtype(FL_THIN_DOWN_BOX,   FL_PLASTIC_THIN_DOWN_BOX);
+    set_boxtype(_FL_ROUND_UP_BOX,   FL_PLASTIC_ROUND_UP_BOX);
+    set_boxtype(_FL_ROUND_DOWN_BOX, FL_PLASTIC_ROUND_DOWN_BOX);
+  } else {
+    // Use the standard FLTK look-n-feel...
+    if (scheme_bg_) {
+      delete scheme_bg_;
+      scheme_bg_ = (Fl_Image *)0;
+    }
+
+    set_boxtype(FL_UP_FRAME,        fl_up_frame, D1, D1, D2, D2);
+    set_boxtype(FL_DOWN_FRAME,      fl_down_frame, D1, D1, D2, D2);
+    set_boxtype(FL_THIN_UP_FRAME,   fl_thin_up_frame, 1, 1, 2, 2);
+    set_boxtype(FL_THIN_DOWN_FRAME, fl_thin_down_frame, 1, 1, 2, 2);
+
+    set_boxtype(FL_UP_BOX,          fl_up_box, D1, D1, D2, D2);
+    set_boxtype(FL_DOWN_BOX,        fl_down_box, D1, D1, D2, D2);
+    set_boxtype(FL_THIN_UP_BOX,     fl_thin_up_box, 1, 1, 2, 2);
+    set_boxtype(FL_THIN_DOWN_BOX,   fl_thin_down_box, 1, 1, 2, 2);
+    set_boxtype(_FL_ROUND_UP_BOX,   fl_round_up_box, 3, 3, 6, 6);
+    set_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box, 3, 3, 6, 6);
+  }
+
+  // Set (or clear) the background tile for all windows...
+  for (win = first_window(); win; win = next_window(win)) {
+    win->labeltype(scheme_bg_ ? FL_NORMAL_LABEL : FL_NO_LABEL);
+    win->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+    win->image(scheme_bg_);
+    win->redraw();
+  }
+
+  return 1;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_grab.cxx b/Utilities/FLTK/src/Fl_grab.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a1a5ee5a82092236225717f316a1e245965909e0
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_grab.cxx
@@ -0,0 +1,108 @@
+//
+// "$Id$"
+//
+// Grab/release code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/Fl.H>
+
+////////////////////////////////////////////////////////////////
+// "Grab" is done while menu systems are up.  This has several effects:
+// Events are all sent to the "grab window", which does not even
+// have to be displayed (and in the case of Fl_Menu.cxx it isn't).
+// The system is also told to "grab" events and send them to this app.
+// This also modifies how Fl_Window::show() works, on X it turns on
+// override_redirect, it does similar things on WIN32.
+
+extern void fl_fix_focus(); // in Fl.cxx
+
+#ifdef WIN32
+// We have to keep track of whether we have captured the mouse, since
+// MSWindows shows little respect for this... Grep for fl_capture to
+// see where and how this is used.
+extern HWND fl_capture;
+#endif
+
+#ifdef __APPLE__
+// MacOS Carbon does not seem to have a mechanism to grab the mouse pointer
+extern WindowRef fl_capture;
+#endif
+
+void Fl::grab(Fl_Window* win) {
+  if (win) {
+    if (!grab_) {
+#ifdef WIN32
+      SetActiveWindow(fl_capture = fl_xid(first_window()));
+      SetCapture(fl_capture);
+#elif defined(__APPLE__)
+      fl_capture = fl_xid( first_window() );
+      SetUserFocusWindow( fl_capture );
+#else
+      XGrabPointer(fl_display,
+		   fl_xid(first_window()),
+		   1,
+		   ButtonPressMask|ButtonReleaseMask|
+		   ButtonMotionMask|PointerMotionMask,
+		   GrabModeAsync,
+		   GrabModeAsync, 
+		   None,
+		   0,
+		   fl_event_time);
+      XGrabKeyboard(fl_display,
+		    fl_xid(first_window()),
+		    1,
+		    GrabModeAsync,
+		    GrabModeAsync, 
+		    fl_event_time);
+#endif
+    }
+    grab_ = win;
+  } else {
+    if (grab_) {
+#ifdef WIN32
+      fl_capture = 0;
+      ReleaseCapture();
+#elif defined(__APPLE__)
+      fl_capture = 0;
+      SetUserFocusWindow( (WindowRef)kUserFocusAuto );
+#else
+      XUngrabKeyboard(fl_display, fl_event_time);
+      XUngrabPointer(fl_display, fl_event_time);
+      // this flush is done in case the picked menu item goes into
+      // an infinite loop, so we don't leave the X server locked up:
+      XFlush(fl_display);
+#endif
+      grab_ = 0;
+      fl_fix_focus();
+    }
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_lock.cxx b/Utilities/FLTK/src/Fl_lock.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4a47f908213683c50f98c4168b6d22c30933048b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_lock.cxx
@@ -0,0 +1,211 @@
+//
+// "$Id$"
+//
+// Multi-threading support code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+
+#include <FL/Fl.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+/*
+   From Bill:
+
+   I would prefer that FLTK contain the minimal amount of extra
+   stuff for doing threads.  There are other portable thread
+   wrapper libraries out there and FLTK should not be providing
+   another.  This file is an attempt to make minimal additions
+   and make them self-contained in this source file.
+
+   Fl::lock() - recursive lock.  You must call this before the
+   first call to Fl::wait()/run() to initialize the thread
+   system. The lock is locked all the time except when
+   Fl::wait() is waiting for events.
+
+   Fl::unlock() - release the recursive lock.
+
+   Fl::awake(void*) - Causes Fl::wait() to return (with the lock
+   locked) even if there are no events ready.
+
+   Fl::thread_message() - returns an argument sent to an
+   Fl::awake() call, or returns NULL if none.  WARNING: the
+   current implementation only has a one-entry queue and only
+   returns the most recent value!
+*/
+
+
+////////////////////////////////////////////////////////////////
+// Windows threading...
+#ifdef WIN32
+#  include <windows.h>
+#  include <process.h>
+#  include <FL/x.H>
+
+// These pointers are in Fl_win32.cxx:
+extern void (*fl_lock_function)();
+extern void (*fl_unlock_function)();
+
+// The main thread's ID
+static DWORD main_thread;
+
+// Microsoft's version of a MUTEX...
+CRITICAL_SECTION cs;
+
+//
+// 'unlock_function()' - Release the lock.
+//
+
+static void unlock_function() {
+  LeaveCriticalSection(&cs);
+}
+
+//
+// 'lock_function()' - Get the lock.
+//
+
+static void lock_function() {
+  EnterCriticalSection(&cs);
+}
+
+//
+// 'Fl::lock()' - Lock access to FLTK data structures...
+//
+
+void Fl::lock() {
+  if (!main_thread) InitializeCriticalSection(&cs);
+
+  lock_function();
+
+  if (!main_thread) {
+    fl_lock_function   = lock_function;
+    fl_unlock_function = unlock_function;
+    main_thread        = GetCurrentThreadId();
+  }
+}
+
+//
+// 'Fl::unlock()' - Unlock access to FLTK data structures...
+//
+
+void Fl::unlock() {
+  unlock_function();
+}
+
+
+//
+// 'Fl::awake()' - Let the main thread know an update is pending.
+//
+// When called from a thread, it causes FLTK to awake from Fl::wait()...
+//
+
+void Fl::awake(void* msg) {
+  PostThreadMessage( main_thread, fl_wake_msg, (WPARAM)msg, 0);
+}
+
+////////////////////////////////////////////////////////////////
+// POSIX threading...
+#elif HAVE_PTHREAD
+#  include <unistd.h>
+#  include <pthread.h>
+
+#  if defined (PTHREAD_MUTEX_RECURSIVE_NP)
+// Linux supports recursive locks, use them directly:
+
+static bool minit;
+static pthread_mutex_t fltk_mutex;
+// this is needed for the Fl_Mutex constructor:
+pthread_mutexattr_t Fl_Mutex_attrib = {PTHREAD_MUTEX_RECURSIVE_NP};
+
+static void lock_function() {
+  if (!minit) {
+    pthread_mutex_init(&fltk_mutex, &Fl_Mutex_attrib);
+    minit = true;
+  }
+  pthread_mutex_lock(&fltk_mutex);
+}
+
+void Fl::unlock() {
+  pthread_mutex_unlock(&fltk_mutex);
+}
+
+#  else
+// Make a recursive lock out of the pthread mutex:
+
+static pthread_mutex_t fltk_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t owner;
+static int counter;
+
+static void lock_function() {
+  if (!counter || owner != pthread_self()) {
+    pthread_mutex_lock(&fltk_mutex);
+    owner = pthread_self();
+  }
+  counter++;
+}
+
+void Fl::unlock() {
+  if (!--counter) pthread_mutex_unlock(&fltk_mutex);
+}
+
+#  endif
+
+// Pipe for thread messaging...
+static int thread_filedes[2];
+
+// These pointers are in Fl_x.cxx:
+extern void (*fl_lock_function)();
+extern void (*fl_unlock_function)();
+
+static void* thread_message_;
+void* Fl::thread_message() {
+  void* r = thread_message_;
+  thread_message_ = 0;
+  return r;
+}
+
+static void thread_awake_cb(int fd, void*) {
+  read(fd, &thread_message_, sizeof(void*));
+}
+
+void Fl::lock() {
+  lock_function();
+  if (!thread_filedes[1]) { // initialize the mt support
+    // Init threads communication pipe to let threads awake FLTK from wait
+    pipe(thread_filedes);
+    Fl::add_fd(thread_filedes[0], FL_READ, thread_awake_cb);
+    fl_lock_function   = lock_function;
+    fl_unlock_function = Fl::unlock;
+  }
+}
+
+void Fl::awake(void* msg) {
+  write(thread_filedes[1], &msg, sizeof(void*));
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_mac.cxx b/Utilities/FLTK/src/Fl_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..18a507e4c8d983c0957a40b4af998f04b0b44fd2
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_mac.cxx
@@ -0,0 +1,2244 @@
+//
+// "$Id$"
+//
+// MacOS specific code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//// From the inner edge of a MetroWerks CodeWarrior CD:
+// (without permission)
+//
+// Three Compiles for 68Ks under the sky,
+// Seven Compiles for PPCs in their fragments of code,
+// Nine Compiles for Mortal Carbon doomed to die,
+// One Compile for Mach-O Cocoa on its Mach-O throne,
+// in the Land of MacOS X where the Drop-Shadows lie.
+// 
+// One Compile to link them all, One Compile to merge them,
+// One Compile to copy them all and in the bundle bind them,
+// in the Land of MacOS X where the Drop-Shadows lie.
+
+// warning: the Apple Quartz version still uses some Quickdraw calls,
+//          mostly to get around the single active context in QD and 
+//          to implement clipping. This should be changed into pure
+//          Quartz calls in the near future.
+
+// we don't need the following definition because we deliver only
+// true mouse moves.  On very slow systems however, this flag may
+// still be useful.
+#define CONSOLIDATE_MOTION 0
+extern "C" {
+#include <pthread.h>
+}
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/Fl_Tooltip.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Sys_Menu_Bar.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <unistd.h>
+
+// #define DEBUG_SELECT		// UNCOMMENT FOR SELECT()/THREAD DEBUGGING
+#ifdef DEBUG_SELECT
+#include <stdio.h>		// testing
+#define DEBUGMSG(msg)		if ( msg ) fprintf(stderr, msg);
+#define DEBUGPERRORMSG(msg)	if ( msg ) perror(msg)
+#define DEBUGTEXT(txt)		txt
+#else
+#define DEBUGMSG(msg)
+#define DEBUGPERRORMSG(msg)
+#define DEBUGTEXT(txt)		NULL
+#endif /*DEBUG_SELECT*/
+
+// external functions
+extern Fl_Window* fl_find(Window);
+extern void fl_fix_focus();
+
+// forward definition of functions in this file
+static void handleUpdateEvent( WindowPtr xid );
+//+ int fl_handle(const EventRecord &event);
+static int FSSpec2UnixPath( FSSpec *fs, char *dst );
+
+// public variables
+int fl_screen;
+CGContextRef fl_gc = 0;
+Handle fl_system_menu;
+Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0;
+CursHandle fl_default_cursor;
+WindowRef fl_capture = 0;            // we need this to compensate for a missing(?) mouse capture
+ulong fl_event_time;                 // the last timestamp from an x event
+char fl_key_vector[32];              // used by Fl::get_key()
+bool fl_show_iconic;                 // true if called from iconize() - shows the next created window in collapsed state
+int fl_disable_transient_for;        // secret method of removing TRANSIENT_FOR
+const Fl_Window* fl_modal_for;       // parent of modal() window
+Fl_Region fl_window_region = 0;
+Window fl_window;
+Fl_Window *Fl_Window::current_;
+EventRef fl_os_event;		// last (mouse) event
+
+// forward declarations of variables in this file
+static int got_events = 0;
+static Fl_Window* resize_from_system;
+static CursPtr default_cursor_ptr;
+static Cursor default_cursor;
+static WindowRef fl_os_capture = 0; // the dispatch handler will redirect mose move and drag events to these windows
+
+#if CONSOLIDATE_MOTION
+static Fl_Window* send_motion;
+extern Fl_Window* fl_xmousewin;
+#endif
+
+enum { kEventClassFLTK = 'fltk' };
+enum { kEventFLTKBreakLoop = 1, kEventFLTKDataReady };
+
+/**
+* Mac keyboard lookup table
+ */
+static unsigned short macKeyLookUp[128] =
+{
+    'a', 's', 'd', 'f', 'h', 'g', 'z', 'x',
+    'c', 'v', 0/*ISO extra ('#' on German keyboard)*/, 'b', 'q', 'w', 'e', 'r',
+
+    'y', 't', '1', '2', '3', '4', '6', '5',
+    '=', '9', '7', '-', '8', '0', ']', 'o',
+
+    'u', '[', 'i', 'p', FL_Enter, 'l', 'j', '\'',
+    'k', ';', '\\', ',', '/', 'n', 'm', '.',
+
+    FL_Tab, ' ', '`', FL_BackSpace, 0/*kp_enter on powerbook G4*/, FL_Escape, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, FL_KP+'.', FL_Right, FL_KP+'*', 0, FL_KP+'+', FL_Left, FL_Num_Lock,
+    FL_Down, 0, 0, FL_KP+'/', FL_KP_Enter, FL_Up, FL_KP+'-', 0,
+
+    0, FL_KP+'=', FL_KP+'0', FL_KP+'1', FL_KP+'2', FL_KP+'3', FL_KP+'4', FL_KP+'5',
+    FL_KP+'6', FL_KP+'7', 0, FL_KP+'8', FL_KP+'9', 0, 0, 0,
+
+    FL_F+5, FL_F+6, FL_F+7, FL_F+3, FL_F+8, FL_F+9, 0, FL_F+11,
+    0, 0, FL_Print, FL_Scroll_Lock, 0, FL_F+10, FL_Menu, FL_F+12,
+
+    0, FL_Pause, FL_Help, FL_Home, FL_Page_Up, FL_Delete, FL_F+4, FL_End,
+    FL_F+2, FL_Page_Down, FL_F+1, FL_Left, FL_Right, FL_Down, FL_Up, 0,
+};
+
+/**
+ * convert the current mouse chord into the FLTK modifier state
+ */
+static void mods_to_e_state( UInt32 mods )
+{
+  long state = 0;
+  if ( mods & kEventKeyModifierNumLockMask ) state |= FL_NUM_LOCK;
+  if ( mods & cmdKey ) state |= FL_META;
+  if ( mods & (optionKey|rightOptionKey) ) state |= FL_ALT;
+  if ( mods & (controlKey|rightControlKey) ) state |= FL_CTRL;
+  if ( mods & (shiftKey|rightShiftKey) ) state |= FL_SHIFT;
+  if ( mods & alphaLock ) state |= FL_CAPS_LOCK;
+  Fl::e_state = ( Fl::e_state & 0xff000000 ) | state;
+  //printf( "State 0x%08x (%04x)\n", Fl::e_state, mods );
+}
+
+
+/**
+ * convert the current mouse chord into the FLTK keysym
+ */
+static void mods_to_e_keysym( UInt32 mods )
+{
+  if ( mods & cmdKey ) Fl::e_keysym = FL_Meta_L;
+  else if ( mods & kEventKeyModifierNumLockMask ) Fl::e_keysym = FL_Num_Lock;
+  else if ( mods & optionKey ) Fl::e_keysym = FL_Alt_L;
+  else if ( mods & rightOptionKey ) Fl::e_keysym = FL_Alt_R;
+  else if ( mods & controlKey ) Fl::e_keysym = FL_Control_L;
+  else if ( mods & rightControlKey ) Fl::e_keysym = FL_Control_R;
+  else if ( mods & shiftKey ) Fl::e_keysym = FL_Shift_L;
+  else if ( mods & rightShiftKey ) Fl::e_keysym = FL_Shift_R;
+  else if ( mods & alphaLock ) Fl::e_keysym = FL_Caps_Lock;
+  else Fl::e_keysym = 0;
+  //printf( "to sym 0x%08x (%04x)\n", Fl::e_keysym, mods );
+}
+// these pointers are set by the Fl::lock() function:
+static void nothing() {}
+void (*fl_lock_function)() = nothing;
+void (*fl_unlock_function)() = nothing;
+
+//
+// Select interface -- how it's implemented:
+//     When the user app configures one or more file descriptors to monitor
+//     with Fl::add_fd(), we start a separate thread to select() the  data,
+//     sending a custom OSX 'FLTK data ready event' to the parent  thread's
+//     RunApplicationLoop(), so that it triggers the data  ready  callbacks
+//     in the parent thread.                               -erco 04/04/04
+//     
+#define POLLIN  1
+#define POLLOUT 4
+#define POLLERR 8
+
+// Class to handle select() 'data ready'
+class DataReady
+{
+    struct FD
+    {
+      int fd;
+      short events;
+      void (*cb)(int, void*);
+      void* arg;
+    };
+    int nfds, fd_array_size;
+    FD *fds;
+    pthread_t tid;		// select()'s thread id
+
+    // Data that needs to be locked (all start with '_')
+    pthread_mutex_t _datalock;	// data lock
+    fd_set _fdsets[3];		// r/w/x sets user wants to monitor
+    int _maxfd;			// max fd count to monitor
+    int _cancelpipe[2];		// pipe used to help cancel thread
+    void *_userdata;		// thread's userdata
+
+public:
+    DataReady()
+    {
+      nfds = 0;
+      fd_array_size = 0;
+      fds = 0;
+      tid = 0;
+
+      pthread_mutex_init(&_datalock, NULL);
+      FD_ZERO(&_fdsets[0]); FD_ZERO(&_fdsets[1]); FD_ZERO(&_fdsets[2]);
+      _cancelpipe[0] = _cancelpipe[1] = 0;
+      _userdata = 0;
+      _maxfd = 0;
+    }
+
+    ~DataReady()
+    {
+        CancelThread(DEBUGTEXT("DESTRUCTOR\n"));
+        if (fds) { free(fds); fds = 0; }
+	nfds = 0;
+    }
+
+    // Locks
+    //    The convention for locks: volatile vars start with '_',
+    //    and must be locked before use. Locked code is prefixed 
+    //    with /*LOCK*/ to make painfully obvious esp. in debuggers. -erco
+    //
+    void DataLock() { pthread_mutex_lock(&_datalock); }
+    void DataUnlock() { pthread_mutex_unlock(&_datalock); }
+
+    // Accessors
+    int IsThreadRunning() { return(tid ? 1 : 0); }
+    int GetNfds() { return(nfds); }
+    int GetCancelPipe(int ix) { return(_cancelpipe[ix]); }
+    fd_set GetFdset(int ix) { return(_fdsets[ix]); }
+
+    // Methods
+    void AddFD(int n, int events, void (*cb)(int, void*), void *v);
+    void RemoveFD(int n, int events);
+    int CheckData(fd_set& r, fd_set& w, fd_set& x);
+    void HandleData(fd_set& r, fd_set& w, fd_set& x);
+    static void* DataReadyThread(void *self);
+    void StartThread(void *userdata);
+    void CancelThread(const char *reason);
+};
+
+static DataReady dataready;
+
+void DataReady::AddFD(int n, int events, void (*cb)(int, void*), void *v)
+{
+  RemoveFD(n, events);
+  int i = nfds++;
+  if (i >= fd_array_size) 
+  {
+    FD *temp;
+    fd_array_size = 2*fd_array_size+1;
+    if (!fds) { temp = (FD*)malloc(fd_array_size*sizeof(FD)); }
+    else { temp = (FD*)realloc(fds, fd_array_size*sizeof(FD)); }
+    if (!temp) return;
+    fds = temp;
+  }
+  fds[i].cb  = cb;
+  fds[i].arg = v;
+  fds[i].fd  = n;
+  fds[i].events = events;
+  DataLock();
+  /*LOCK*/  if (events & POLLIN)  FD_SET(n, &_fdsets[0]);
+  /*LOCK*/  if (events & POLLOUT) FD_SET(n, &_fdsets[1]);
+  /*LOCK*/  if (events & POLLERR) FD_SET(n, &_fdsets[2]);
+  /*LOCK*/  if (n > _maxfd) _maxfd = n;
+  DataUnlock();
+}
+
+// Remove an FD from the array
+void DataReady::RemoveFD(int n, int events)
+{
+  int i,j;
+  for (i=j=0; i<nfds; i++)
+  {
+    if (fds[i].fd == n) 
+    {
+      int e = fds[i].events & ~events;
+      if (!e) continue; // if no events left, delete this fd
+      fds[i].events = e;
+    }
+    // move it down in the array if necessary:
+    if (j<i)
+      { fds[j] = fds[i]; }
+    j++;
+  }
+  nfds = j;
+  DataLock();
+  /*LOCK*/  if (events & POLLIN)  FD_CLR(n, &_fdsets[0]);
+  /*LOCK*/  if (events & POLLOUT) FD_CLR(n, &_fdsets[1]);
+  /*LOCK*/  if (events & POLLERR) FD_CLR(n, &_fdsets[2]);
+  /*LOCK*/  if (n == _maxfd) _maxfd--;
+  DataUnlock();
+}
+
+// CHECK IF USER DATA READY, RETURNS r/w/x INDICATING WHICH IF ANY
+int DataReady::CheckData(fd_set& r, fd_set& w, fd_set& x)
+{
+  int ret;
+  DataLock();
+  /*LOCK*/  timeval t = { 0, 1 };		// quick check
+  /*LOCK*/  r = _fdsets[0], w = _fdsets[1], x = _fdsets[2];
+  /*LOCK*/  ret = ::select(_maxfd+1, &r, &w, &x, &t);
+  DataUnlock();
+  if ( ret == -1 )
+    { DEBUGPERRORMSG("CheckData(): select()"); }
+  return(ret);
+}
+
+// HANDLE DATA READY CALLBACKS
+void DataReady::HandleData(fd_set& r, fd_set& w, fd_set& x)
+{
+  for (int i=0; i<nfds; i++) 
+  {
+    int f = fds[i].fd;
+    short revents = 0;
+    if (FD_ISSET(f, &r)) revents |= POLLIN;
+    if (FD_ISSET(f, &w)) revents |= POLLOUT;
+    if (FD_ISSET(f, &x)) revents |= POLLERR;
+    if (fds[i].events & revents) 
+    {
+      DEBUGMSG("DOING CALLBACK: ");
+      fds[i].cb(f, fds[i].arg);
+      DEBUGMSG("DONE\n");
+    }
+  }
+}
+
+// DATA READY THREAD
+//    This thread watches for changes in user's file descriptors.
+//    Sends a 'data ready event' to the main thread if any change.
+//
+void* DataReady::DataReadyThread(void *o)
+{
+  DataReady *self = (DataReady*)o;
+  while ( 1 )					// loop until thread cancel or error
+  {
+    // Thread safe local copies of data before each select()
+    self->DataLock();
+    /*LOCK*/  int maxfd = self->_maxfd;
+    /*LOCK*/  fd_set r = self->GetFdset(0);
+    /*LOCK*/  fd_set w = self->GetFdset(1);
+    /*LOCK*/  fd_set x = self->GetFdset(2);
+    /*LOCK*/  void *userdata = self->_userdata;
+    /*LOCK*/  int cancelpipe = self->GetCancelPipe(0);
+    /*LOCK*/  if ( cancelpipe > maxfd ) maxfd = cancelpipe;
+    /*LOCK*/  FD_SET(cancelpipe, &r);		// add cancelpipe to fd's to watch
+    /*LOCK*/  FD_SET(cancelpipe, &x);
+    self->DataUnlock();
+    // timeval t = { 1000, 0 };	// 1000 seconds;
+    timeval t = { 2, 0 };	// HACK: 2 secs prevents 'hanging' problem
+    int ret = ::select(maxfd+1, &r, &w, &x, &t);
+    pthread_testcancel();	// OSX 10.0.4 and older: needed for parent to cancel
+    switch ( ret )
+    {
+      case 0:	// NO DATA
+        continue;
+      case -1:	// ERROR
+      {
+        DEBUGPERRORMSG("CHILD THREAD: select() failed");
+        return(NULL);		// error? exit thread
+      }
+      default:	// DATA READY
+      {
+	if (FD_ISSET(cancelpipe, &r) || FD_ISSET(cancelpipe, &x)) 	// cancel?
+	    { return(NULL); }						// just exit
+        DEBUGMSG("CHILD THREAD: DATA IS READY\n");
+        EventRef drEvent;
+        CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady,
+		     0, kEventAttributeUserEvent, &drEvent);
+        EventQueueRef eventqueue = (EventQueueRef)userdata;
+        PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard );
+        ReleaseEvent( drEvent );
+        return(NULL);		// done with thread
+      }
+    }
+  }
+}
+
+// START 'DATA READY' THREAD RUNNING, CREATE INTER-THREAD PIPE
+void DataReady::StartThread(void *new_userdata)
+{
+  CancelThread(DEBUGTEXT("STARTING NEW THREAD\n"));
+  DataLock();
+  /*LOCK*/  pipe(_cancelpipe);	// pipe for sending cancel msg to thread
+  /*LOCK*/  _userdata = new_userdata;
+  DataUnlock();
+  DEBUGMSG("*** START THREAD\n");
+  pthread_create(&tid, NULL, DataReadyThread, (void*)this);
+}
+
+// CANCEL 'DATA READY' THREAD, CLOSE PIPE
+void DataReady::CancelThread(const char *reason)
+{
+  if ( tid )
+  {
+    DEBUGMSG("*** CANCEL THREAD: ");
+    DEBUGMSG(reason);
+    if ( pthread_cancel(tid) == 0 )		// cancel first
+    {
+      DataLock();
+      /*LOCK*/  write(_cancelpipe[1], "x", 1);	// wake thread from select
+      DataUnlock();
+      pthread_join(tid, NULL);			// wait for thread to finish
+    }
+    tid = 0;
+    DEBUGMSG("(JOINED) OK\n");
+  }
+  // Close pipe if open
+  DataLock();
+  /*LOCK*/  if ( _cancelpipe[0] ) { close(_cancelpipe[0]); _cancelpipe[0] = 0; }
+  /*LOCK*/  if ( _cancelpipe[1] ) { close(_cancelpipe[1]); _cancelpipe[1] = 0; }
+  DataUnlock();
+}
+
+void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v )
+    { dataready.AddFD(n, events, cb, v); }
+
+void Fl::add_fd(int fd, void (*cb)(int, void*), void* v)
+    { dataready.AddFD(fd, POLLIN, cb, v); }
+
+void Fl::remove_fd(int n, int events)
+    { dataready.RemoveFD(n, events); }
+
+void Fl::remove_fd(int n)
+    { dataready.RemoveFD(n, -1); }
+
+/**
+ * Check if there is actually a message pending!
+ */
+int fl_ready()
+{
+  EventRef event;
+  return !ReceiveNextEvent(0, NULL, 0.0, false, &event);
+}
+
+/**
+ * handle Apple Menu items (can be created using the Fl_Sys_Menu_Bar
+ * returns eventNotHandledErr if the menu item could not be handled
+ */
+OSStatus HandleMenu( HICommand *cmd )
+{
+  OSStatus ret = eventNotHandledErr;
+  // attributes, commandIDm menu.menuRef, menu.menuItemIndex
+  UInt32 ref;
+  OSErr rrc = GetMenuItemRefCon( cmd->menu.menuRef, cmd->menu.menuItemIndex, &ref );
+  //printf( "%d, %08x, %08x, %d, %d, %8x\n", rrc, cmd->attributes, cmd->commandID, cmd->menu.menuRef, cmd->menu.menuItemIndex, rrc );
+  if ( rrc==noErr && ref )
+  {
+    Fl_Menu_Item *m = (Fl_Menu_Item*)ref;
+    //printf( "Menu: %s\n", m->label() );
+    fl_sys_menu_bar->picked( m );
+    if ( m->flags & FL_MENU_TOGGLE ) // update the menu toggle symbol
+      SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, (m->flags & FL_MENU_VALUE ) ? 0x12 : 0 );
+    if ( m->flags & FL_MENU_RADIO ) // update all radio buttons in this menu
+    {
+      Fl_Menu_Item *j = m;
+      int i = cmd->menu.menuItemIndex;
+      for (;;)
+      {
+        if ( j->flags & FL_MENU_DIVIDER )
+          break;
+        j++; i++;
+        if ( !j->text || !j->radio() )
+          break;
+        SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
+      }
+      j = m-1; i = cmd->menu.menuItemIndex-1;
+      for ( ; i>0; j--, i-- )
+      {
+        if ( !j->text || j->flags&FL_MENU_DIVIDER || !j->radio() )
+          break;
+        SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
+      }
+      SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
+    }
+    ret = noErr; // done handling this event
+  }
+  HiliteMenu(0);
+  return ret;
+}
+
+
+/**
+ * We can make every event pass through this function
+ * - mouse events need to be manipulated to use a mouse focus window
+ * - keyboard, mouse and some window  events need to quit the Apple Event Loop
+ *   so FLTK can continue its own management
+ */
+static pascal OSStatus carbonDispatchHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
+{
+  OSStatus ret = eventNotHandledErr;
+  HICommand cmd;
+
+  fl_lock_function();
+
+  got_events = 1;
+
+  switch ( GetEventClass( event ) )
+  {
+  case kEventClassMouse:
+    switch ( GetEventKind( event ) )
+    {
+    case kEventMouseUp:
+    case kEventMouseMoved:
+    case kEventMouseDragged:
+      if ( fl_capture )
+        ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_capture ) );
+      else if ( fl_os_capture ){
+        ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_os_capture ) );
+	fl_os_capture = 0;
+      }
+      break;
+    }
+    break;
+  case kEventClassCommand:
+    switch (GetEventKind( event ) )
+    {
+      case kEventCommandProcess:
+        GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &cmd );
+        ret = HandleMenu( &cmd );
+        break;
+    }
+    break;
+  case kEventClassFLTK:
+    switch ( GetEventKind( event ) )
+    {
+    case kEventFLTKBreakLoop:
+      ret = noErr;
+      break;
+    case kEventFLTKDataReady:
+      {
+	dataready.CancelThread(DEBUGTEXT("DATA READY EVENT\n"));
+
+        // CHILD THREAD TELLS US DATA READY
+	//     Check to see what's ready, and invoke user's cb's
+	//
+	fd_set r,w,x;
+	switch(dataready.CheckData(r,w,x))
+	{
+	  case 0:	// NO DATA
+	    break;
+	  case -1:	// ERROR
+	    break;
+	  default:	// DATA READY
+	    dataready.HandleData(r,w,x);
+	    break;
+        }
+      }
+      ret = noErr;
+      break;
+    }
+  }
+  if ( ret == eventNotHandledErr )
+    ret = CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect
+
+  fl_unlock_function();
+
+  return ret;
+}
+
+
+/**
+ * break the current event loop
+ */
+static void breakMacEventLoop()
+{
+  EventRef breakEvent;
+
+  fl_lock_function();
+
+  CreateEvent( 0, kEventClassFLTK, kEventFLTKBreakLoop, 0, kEventAttributeUserEvent, &breakEvent );
+  PostEventToQueue( GetCurrentEventQueue(), breakEvent, kEventPriorityStandard );
+  ReleaseEvent( breakEvent );
+
+  fl_unlock_function();
+}
+
+//
+// MacOS X timers
+//
+
+struct MacTimeout {
+    Fl_Timeout_Handler callback;
+    void* data;
+    EventLoopTimerRef timer;
+};
+static MacTimeout* mac_timers;
+static int mac_timer_alloc;
+static int mac_timer_used;
+
+
+static void realloc_timers()
+{
+    if (mac_timer_alloc == 0) {
+        mac_timer_alloc = 8;
+    }
+    MacTimeout* new_timers = new MacTimeout[mac_timer_alloc * 2];
+    memmove(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used);
+    MacTimeout* delete_me = mac_timers;
+    mac_timers = new_timers;
+    delete [] delete_me;
+    mac_timer_alloc *= 2;
+}
+
+static void delete_timer(MacTimeout& t)
+{
+    RemoveEventLoopTimer(t.timer);
+    memset(&t, 0, sizeof(MacTimeout));
+}
+
+
+static pascal void do_timer(EventLoopTimerRef timer, void* data)
+{
+   for (int i = 0;  i < mac_timer_used;  ++i) {
+        MacTimeout& t = mac_timers[i];
+        if (t.timer == timer  &&  t.data == data) {
+            (*t.callback)(data);
+            break;
+        }
+    }
+    breakMacEventLoop();
+}
+
+/**
+ * This function is the central event handler.
+ * It reads events from the event queue using the given maximum time
+ * Funny enough, it returns the same time that it got as the argument. 
+ */
+static double do_queued_events( double time = 0.0 ) 
+{
+  static bool been_here = 0;
+  static RgnHandle rgn;
+  
+  // initialize events and a region that enables mouse move events
+  if (!been_here) {
+    rgn = NewRgn();
+    Point mp;
+    GetMouse(&mp);
+    SetRectRgn(rgn, mp.h, mp.v, mp.h, mp.v);
+    SetEventMask(everyEvent);
+    been_here = 1;
+  }
+  OSStatus ret;
+  static EventTargetRef target = 0;
+  if ( !target ) 
+  {
+    target = GetEventDispatcherTarget();
+
+    EventHandlerUPP dispatchHandler = NewEventHandlerUPP( carbonDispatchHandler ); // will not be disposed by Carbon...
+    static EventTypeSpec dispatchEvents[] = {
+        { kEventClassWindow, kEventWindowShown },
+        { kEventClassWindow, kEventWindowHidden },
+        { kEventClassWindow, kEventWindowActivated },
+        { kEventClassWindow, kEventWindowDeactivated },
+        { kEventClassWindow, kEventWindowClose },
+        { kEventClassKeyboard, kEventRawKeyDown },
+        { kEventClassKeyboard, kEventRawKeyRepeat },
+        { kEventClassKeyboard, kEventRawKeyUp },
+        { kEventClassKeyboard, kEventRawKeyModifiersChanged },
+        { kEventClassMouse, kEventMouseDown },
+        { kEventClassMouse, kEventMouseUp },
+        { kEventClassMouse, kEventMouseMoved },
+        { kEventClassMouse, 11 }, // MightyMouse wheels
+        { kEventClassMouse, kEventMouseWheelMoved },
+        { kEventClassMouse, kEventMouseDragged },
+        { kEventClassFLTK, kEventFLTKBreakLoop },
+        { kEventClassFLTK, kEventFLTKDataReady } };
+    ret = InstallEventHandler( target, dispatchHandler, GetEventTypeCount(dispatchEvents), dispatchEvents, 0, 0L );
+    static EventTypeSpec appEvents[] = {
+        { kEventClassCommand, kEventCommandProcess } };
+    ret = InstallApplicationEventHandler( dispatchHandler, GetEventTypeCount(appEvents), appEvents, 0, 0L );
+  }
+
+  got_events = 0;
+
+  // Check for re-entrant condition
+  if ( dataready.IsThreadRunning() )
+    { dataready.CancelThread(DEBUGTEXT("AVOID REENTRY\n")); }
+
+  // Start thread to watch for data ready
+  if ( dataready.GetNfds() )
+      { dataready.StartThread((void*)GetCurrentEventQueue()); }
+
+  fl_unlock_function();
+
+  EventRef event;
+  EventTimeout timeout = time;
+  if (!ReceiveNextEvent(0, NULL, timeout, true, &event)) {
+    got_events = 1;
+    OSErr ret = SendEventToEventTarget( event, target );
+    if (ret!=noErr) {
+      EventRecord clevent;
+      ConvertEventRefToEventRecord(event, &clevent);
+      if (clevent.what==kHighLevelEvent) {
+        ret = AEProcessAppleEvent(&clevent);
+      }
+    }
+    if (   ret==eventNotHandledErr
+        && GetEventClass(event)==kEventClassMouse
+        && GetEventKind(event)==kEventMouseDown ) {
+      WindowRef win; Point pos;
+      GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
+        NULL, sizeof(pos), NULL, &pos);
+      if (MacFindWindow(pos, &win)==inMenuBar) {
+        MenuSelect(pos);
+      }
+    }
+    ReleaseEvent( event );
+  }
+
+  fl_lock_function();
+
+#if CONSOLIDATE_MOTION
+  if (send_motion && send_motion == fl_xmousewin) {
+    send_motion = 0;
+    Fl::handle(FL_MOVE, fl_xmousewin);
+  }
+#endif
+
+  return time;
+}
+
+
+/**
+ * This public function handles all events. It wait a maximum of 
+ * 'time' secods for an event. This version returns 1 if events
+ * other than the timeout timer were processed.
+ *
+ * \todo there is no socket handling in this code whatsoever
+ */
+int fl_wait( double time ) 
+{
+  do_queued_events( time );
+  return (got_events);
+}
+
+
+/**
+ * event handler for Apple-Q key combination
+ * this is also called from the Carbon Window handler after all windows were closed
+ */
+static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon )
+{
+  fl_lock_function();
+
+  while ( Fl_X::first ) {
+    Fl_X *x = Fl_X::first;
+    Fl::handle( FL_CLOSE, x->w );
+    if ( Fl_X::first == x ) {
+      fl_unlock_function();
+      return noErr; // FLTK has not close all windows, so we return to the main program now
+    }
+  }
+
+  fl_unlock_function();
+
+  return noErr;
+}
+
+
+/**
+ * Carbon Window handler
+ * This needs to be linked into all new window event handlers
+ */
+static pascal OSStatus carbonWindowHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
+{
+  UInt32 kind = GetEventKind( event );
+  OSStatus ret = eventNotHandledErr;
+  Fl_Window *window = (Fl_Window*)userData;
+
+  Rect currentBounds, originalBounds;
+  WindowClass winClass;
+  static Fl_Window *activeWindow = 0;
+  
+  fl_lock_function();
+  
+  switch ( kind )
+  {
+  case kEventWindowBoundsChanging:
+    GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds );
+    GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds );
+    break;
+  case kEventWindowDrawContent:
+    handleUpdateEvent( fl_xid( window ) );
+    ret = noErr;
+    break;
+  case kEventWindowBoundsChanged: {
+    GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds );
+    GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds );
+    int X = currentBounds.left, W = currentBounds.right-X;
+    int Y = currentBounds.top, H = currentBounds.bottom-Y;
+    resize_from_system = window;
+    window->resize( X, Y, W, H );
+    if ( ( originalBounds.right - originalBounds.left != W ) 
+      || ( originalBounds.bottom - originalBounds.top != H ) )
+    {
+      if ( window->shown() ) 
+        handleUpdateEvent( fl_xid( window ) );
+    } 
+    break; }
+  case kEventWindowShown:
+    if ( !window->parent() )
+    {
+      GetWindowClass( fl_xid( window ), &winClass );
+      if ( winClass != kHelpWindowClass ) {	// help windows can't get the focus!
+        Fl::handle( FL_FOCUS, window);
+        activeWindow = window;
+      }
+      Fl::handle( FL_SHOW, window);
+      mods_to_e_state(GetCurrentKeyModifiers());
+    }
+    break;
+  case kEventWindowHidden:
+    if ( !window->parent() ) Fl::handle( FL_HIDE, window);
+    break;
+  case kEventWindowActivated:
+    if ( window!=activeWindow ) 
+    {
+      GetWindowClass( fl_xid( window ), &winClass );
+      if ( winClass != kHelpWindowClass ) {	// help windows can't get the focus!
+        Fl::handle( FL_FOCUS, window);
+        activeWindow = window;
+      }
+    }
+    break;
+  case kEventWindowDeactivated:
+    if ( window==activeWindow ) 
+    {
+      Fl::handle( FL_UNFOCUS, window);
+      activeWindow = 0;
+    }
+    break;
+  case kEventWindowClose:
+    Fl::handle( FL_CLOSE, window ); // this might or might not close the window
+    // if there are no more windows, send a high-level quit event
+    if (!Fl_X::first) QuitAppleEventHandler( 0, 0, 0 );
+    ret = noErr; // returning noErr tells Carbon to stop following up on this event
+    break;
+  }
+
+  fl_unlock_function();
+
+  return ret;
+}
+
+
+/**
+ * Carbon Mousewheel handler
+ * This needs to be linked into all new window event handlers
+ */
+static pascal OSStatus carbonMousewheelHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
+{
+  // Handle the new "MightyMouse" mouse wheel events. Please, someone explain
+  // to me why Apple changed the API on this even though the current API
+  // supports two wheels just fine. Matthias,
+  fl_lock_function();
+
+  fl_os_event = event;
+  Fl_Window *window = (Fl_Window*)userData;
+
+  EventMouseWheelAxis axis;
+  GetEventParameter( event, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &axis );
+  long delta;
+  GetEventParameter( event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(long), NULL, &delta );
+//  fprintf(stderr, "axis=%d, delta=%d\n", axis, delta);
+  if ( axis == kEventMouseWheelAxisX ) {
+    Fl::e_dx = -delta;
+    Fl::e_dy = 0;
+    if ( Fl::e_dx) Fl::handle( FL_MOUSEWHEEL, window );
+  } else if ( axis == kEventMouseWheelAxisY ) {
+    Fl::e_dx = 0;
+    Fl::e_dy = -delta;
+    if ( Fl::e_dy) Fl::handle( FL_MOUSEWHEEL, window );
+  } else {
+    fl_unlock_function();
+
+    return eventNotHandledErr;
+  }
+
+  fl_unlock_function();
+  
+  return noErr;
+}
+
+
+/**
+ * convert the current mouse chord into the FLTK modifier state
+ */
+static void chord_to_e_state( UInt32 chord )
+{
+  static ulong state[] = 
+  { 
+    0, FL_BUTTON1, FL_BUTTON3, FL_BUTTON1|FL_BUTTON3, FL_BUTTON2,
+    FL_BUTTON2|FL_BUTTON1, FL_BUTTON2|FL_BUTTON3, 
+    FL_BUTTON2|FL_BUTTON1|FL_BUTTON3
+  };
+  Fl::e_state = ( Fl::e_state & 0xff0000 ) | state[ chord & 0x07 ];
+}
+
+
+/**
+ * Carbon Mouse Button Handler
+ */
+static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
+{
+  static int keysym[] = { 0, FL_Button+1, FL_Button+3, FL_Button+2 };
+  static int px, py;
+
+  fl_lock_function();
+  
+  fl_os_event = event;
+  Fl_Window *window = (Fl_Window*)userData;
+  Point pos;
+  GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &pos );
+  EventMouseButton btn;
+  GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &btn );
+  UInt32 clickCount;
+  GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL, sizeof(UInt32), NULL, &clickCount );
+  UInt32 chord;
+  GetEventParameter( event, kEventParamMouseChord, typeUInt32, NULL, sizeof(UInt32), NULL, &chord );
+  WindowRef xid = fl_xid(window), tempXid;
+  int sendEvent = 0, part;
+  switch ( GetEventKind( event ) )
+  {
+  case kEventMouseDown:
+    part = FindWindow( pos, &tempXid );
+    if ( part != inContent ) {
+      fl_unlock_function();
+      return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us
+    }
+    if ( !IsWindowActive( xid ) )
+      CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect
+    // normal handling of mouse-down follows
+    fl_os_capture = xid;
+    sendEvent = FL_PUSH;
+    Fl::e_is_click = 1; px = pos.h; py = pos.v;
+    if (clickCount>1) 
+      Fl::e_clicks++;
+    else
+      Fl::e_clicks = 0;
+    // fall through
+  case kEventMouseUp:
+    if ( !window ) break;
+    if ( !sendEvent ) {
+      sendEvent = FL_RELEASE; 
+    }
+    Fl::e_keysym = keysym[ btn ];
+    // fall through
+  case kEventMouseMoved:
+    if ( !sendEvent ) { 
+      sendEvent = FL_MOVE; chord = 0; 
+    }
+    // fall through
+  case kEventMouseDragged:
+    if ( !sendEvent ) {
+      sendEvent = FL_MOVE; // Fl::handle will convert into FL_DRAG
+      if (abs(pos.h-px)>5 || abs(pos.v-py)>5) 
+        Fl::e_is_click = 0;
+    }
+    chord_to_e_state( chord );
+    GrafPtr oldPort;
+    GetPort( &oldPort );
+    SetPort( GetWindowPort(xid) ); // \todo replace this! There must be some GlobalToLocal call that has a port as an argument
+    SetOrigin(0, 0);
+    Fl::e_x_root = pos.h;
+    Fl::e_y_root = pos.v;
+    GlobalToLocal( &pos );
+    Fl::e_x = pos.h;
+    Fl::e_y = pos.v;
+    SetPort( oldPort );
+    Fl::handle( sendEvent, window );
+    break;
+  }
+
+  fl_unlock_function();
+  
+  return noErr;
+}
+
+
+/**
+ * convert the keyboard return code into the symbol on the keycaps
+ */
+static unsigned short keycode_to_sym( UInt32 keyCode, UInt32 mods, unsigned short deflt )
+{
+  static Ptr map = 0;
+  UInt32 state = 0;
+  if (!map) {
+    map = (Ptr)GetScriptManagerVariable(smKCHRCache);
+    if (!map) {
+      long kbID = GetScriptManagerVariable(smKeyScript);
+      map = *GetResource('KCHR', kbID);
+    }
+  }
+  if (map)
+    return KeyTranslate(map, keyCode|mods, &state );
+  return deflt;
+}
+
+/**
+ * handle carbon keyboard events
+ */
+pascal OSStatus carbonKeyboardHandler( 
+  EventHandlerCallRef nextHandler, EventRef event, void *userData )
+{
+  static char buffer[5];
+  int sendEvent = 0;
+  Fl_Window *window = (Fl_Window*)userData;
+  UInt32 mods;
+  static UInt32 prevMods = 0xffffffff;
+
+  fl_lock_function();
+  
+  int kind = GetEventKind(event);
+  
+  // get the modifiers for any of the events
+  GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, 
+                     NULL, sizeof(UInt32), NULL, &mods );
+  if ( prevMods == 0xffffffff ) prevMods = mods;
+  
+  // get the key code only for key events
+  UInt32 keyCode = 0;
+  unsigned char key = 0;
+  unsigned short sym = 0;
+  if (kind!=kEventRawKeyModifiersChanged) {
+    GetEventParameter( event, kEventParamKeyCode, typeUInt32, 
+                       NULL, sizeof(UInt32), NULL, &keyCode );
+    GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, 
+                       NULL, sizeof(char), NULL, &key );
+  }
+  /* output a human readbale event identifier for debugging
+  const char *ev = "";
+  switch (kind) {
+    case kEventRawKeyDown: ev = "kEventRawKeyDown"; break;
+    case kEventRawKeyRepeat: ev = "kEventRawKeyRepeat"; break;
+    case kEventRawKeyUp: ev = "kEventRawKeyUp"; break;
+    case kEventRawKeyModifiersChanged: ev = "kEventRawKeyModifiersChanged"; break;
+    default: ev = "unknown";
+  }
+  printf("%08x %08x %08x '%c' %s \n", mods, keyCode, key, key, ev);
+  */
+  switch (kind)
+  {
+  case kEventRawKeyDown:
+  case kEventRawKeyRepeat:
+    sendEvent = FL_KEYBOARD;
+    // fall through
+  case kEventRawKeyUp:
+    if ( !sendEvent ) sendEvent = FL_KEYUP;
+    // if the user pressed alt/option, event_key should have the keycap, 
+    // but event_text should generate the international symbol
+    if ( isalpha(key) )
+      sym = tolower(key);
+    else if ( Fl::e_state&FL_CTRL && key<32 )
+      sym = key+96;
+    else if ( Fl::e_state&FL_ALT ) // find the keycap of this key
+      sym = keycode_to_sym( keyCode & 0x7f, 0, macKeyLookUp[ keyCode & 0x7f ] );
+    else
+      sym = macKeyLookUp[ keyCode & 0x7f ];
+    Fl::e_keysym = sym;
+    if ( keyCode==0x4c ) key=0x0d;
+    // Matt: the Mac has no concept of a NumLock key, or at least not visible
+    // Matt: to Carbon. The kEventKeyModifierNumLockMask is only set when
+    // Matt: a numeric keypad key is pressed and does not correspond with
+    // Matt: the NumLock light in PowerBook keyboards.
+    if ( (sym >= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) ||
+            sym == FL_Tab || sym == FL_Enter) {
+      buffer[0] = key;
+      Fl::e_length = 1;
+    } else {
+      buffer[0] = 0;
+      Fl::e_length = 0;
+    }
+    Fl::e_text = buffer;
+    // insert UnicodeHandling here!
+    break;
+  case kEventRawKeyModifiersChanged: {
+    UInt32 tMods = prevMods ^ mods;
+    if ( tMods )
+    {
+      mods_to_e_keysym( tMods );
+      if ( Fl::e_keysym ) 
+        sendEvent = ( prevMods<mods ) ? FL_KEYBOARD : FL_KEYUP;
+      Fl::e_length = 0;
+      buffer[0] = 0;
+      prevMods = mods;
+    }
+    mods_to_e_state( mods );
+    break; }
+  }
+  while (window->parent()) window = window->window();
+  if (sendEvent && Fl::handle(sendEvent,window)) {
+    fl_unlock_function();  
+    return noErr; // return noErr if FLTK handled the event
+  } else {
+    fl_unlock_function();
+    //return CallNextEventHandler( nextHandler, event );;
+    // Matt: I had better results (no duplicate events) always returning
+    // Matt: 'noErr'. System keyboard events still seem to work just fine.
+    return noErr;
+  }
+}
+
+
+
+/**
+ * Open callback function to call...
+ */
+
+static void	(*open_cb)(const char *) = 0;
+
+
+/**
+ * Event handler for Apple-O key combination and also for file opens
+ * via the finder...
+ */
+
+static OSErr OpenAppleEventHandler(const AppleEvent *appleEvt,
+                                   AppleEvent *reply,
+				   UInt32 refcon) {
+  OSErr err;
+  AEDescList documents;
+  long i, n;
+  FSSpec fileSpec;
+  AEKeyword keyWd;
+  DescType typeCd;
+  Size actSz;
+  char filename[1024];
+
+  if (!open_cb) return noErr;
+
+  // Initialize the document list...
+  AECreateDesc(typeNull, NULL, 0, &documents);
+ 
+  // Get the open parameter(s)...
+  err = AEGetParamDesc(appleEvt, keyDirectObject, typeAEList, &documents);
+  if (err != noErr) {
+    AEDisposeDesc(&documents);
+    return err;
+  }
+
+  // Lock access to FLTK in this thread...
+  fl_lock_function();
+
+  // Open the documents via the callback...
+  if (AECountItems(&documents, &n) == noErr) {
+    for (i = 1; i <= n; i ++) {
+      // Get the next FSSpec record...
+      AEGetNthPtr(&documents, i, typeFSS, &keyWd, &typeCd,
+                  (Ptr)&fileSpec, sizeof(fileSpec),
+		  (actSz = sizeof(fileSpec), &actSz));
+
+      // Convert to a UNIX path...
+      FSSpec2UnixPath(&fileSpec, filename);
+
+      // Call the callback with the filename...
+      (*open_cb)(filename);
+    }
+  }
+
+  // Unlock access to FLTK for all threads...
+  fl_unlock_function();
+
+  // Get rid of the document list...
+  AEDisposeDesc(&documents);
+
+  return noErr;
+}
+
+
+/**
+ * Install an open documents event handler...
+ */
+
+void fl_open_callback(void (*cb)(const char *)) {
+  open_cb = cb;
+  if (cb) {
+    AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
+                          NewAEEventHandlerUPP((AEEventHandlerProcPtr)
+			      OpenAppleEventHandler), 0, false);
+  } else {
+    AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
+                          NewAEEventHandlerUPP((AEEventHandlerProcPtr)
+			      OpenAppleEventHandler), false);
+  }
+}
+
+
+/**
+ * initialize the Mac toolboxes and set the default menubar
+ */
+void fl_open_display() {
+  static char beenHereDoneThat = 0;
+  if ( !beenHereDoneThat )  {
+    beenHereDoneThat = 1;
+    
+    FlushEvents(everyEvent,0);
+
+    MoreMasters(); // \todo Carbon suggests MoreMasterPointers()
+    AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false );
+
+    // create the Mac Handle for the default cursor (a pointer to a pointer)
+    GetQDGlobalsArrow(&default_cursor);
+    default_cursor_ptr = &default_cursor;
+    fl_default_cursor  = &default_cursor_ptr;
+    
+    ClearMenuBar();
+    AppendResMenu( GetMenuHandle( 1 ), 'DRVR' );
+    DrawMenuBar();
+  }
+}
+
+
+/**
+ * get rid of allocated resources
+ */
+void fl_close_display()  {
+}
+
+
+/**
+ * smallest x ccordinate in screen space
+ */
+int Fl::x() {
+  BitMap r;
+  GetQDGlobalsScreenBits(&r);
+  return r.bounds.left;
+}
+
+
+/**
+ * smallest y ccordinate in screen space
+ */
+int Fl::y() {
+  BitMap r;
+  GetQDGlobalsScreenBits(&r);
+  return r.bounds.top + 20; // \todo 20 pixel menu bar?
+}
+
+
+/**
+ * screen width (single monitor!?)
+ */
+int Fl::w() {
+  BitMap r;
+  GetQDGlobalsScreenBits(&r);
+  return r.bounds.right - r.bounds.left;
+}
+
+
+/**
+ * screen height (single monitor!?)
+ */
+int Fl::h() {
+  BitMap r;
+  GetQDGlobalsScreenBits(&r);
+  return r.bounds.bottom - r.bounds.top - 20;
+}
+
+
+/**
+ * get the current mouse pointer world coordinates
+ */
+void Fl::get_mouse(int &x, int &y) 
+{
+  fl_open_display();
+  Point loc; 
+  GetMouse( &loc );
+  LocalToGlobal( &loc );
+  x = loc.h;
+  y = loc.v;
+}
+
+
+/**
+ * convert Mac keystrokes to FLTK
+ */
+unsigned short mac2fltk(ulong macKey) 
+{
+  unsigned short cc = macKeyLookUp[(macKey>>8)&0x7f];
+  if (cc) return cc;
+  return macKey&0xff;
+}
+
+
+/**
+ * Initialize the given port for redraw and call the windw's flush() to actually draw the content
+ */ 
+void Fl_X::flush()
+{
+  w->flush();
+#ifdef __APPLE_QD__
+  GrafPtr port; 
+  GetPort( &port );
+  if ( port )
+    QDFlushPortBuffer( port, 0 );
+#elif defined (__APPLE_QUARTZ__)
+  if (fl_gc) 
+    CGContextFlush(fl_gc);
+#endif          
+  SetOrigin( 0, 0 );
+}
+
+
+/**
+ * Handle all clipping and redraw for the given port
+ * There are two different callers for this event:
+ * 1: the OS can request a redraw and provides all clipping itself
+ * 2: Fl::flush() wants all redraws now
+ */    
+void handleUpdateEvent( WindowPtr xid ) 
+{
+  Fl_Window *window = fl_find( xid );
+  if ( !window ) return;
+  GrafPtr oldPort;
+  GetPort( &oldPort );
+  SetPort( GetWindowPort(xid) );
+  Fl_X *i = Fl_X::i( window );
+  i->wait_for_expose = 0;
+  if ( window->damage() ) {
+    if ( i->region ) {
+      InvalWindowRgn( xid, i->region );
+    }
+  }
+  if ( i->region ) { // no region, so the sytem will take the update region from the OS
+    DisposeRgn( i->region );
+    i->region = 0;
+  }
+  for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext )
+  {
+    cx->w->clear_damage(window->damage()|FL_DAMAGE_EXPOSE);
+    cx->flush();
+    cx->w->clear_damage();
+  }
+  window->clear_damage(window->damage()|FL_DAMAGE_EXPOSE);
+  i->flush();
+  window->clear_damage();
+  SetPort( oldPort );
+}     
+
+
+/**
+ * \todo this is a leftover from OS9 times. Please check how much applies to Carbon!
+ */
+int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) {
+  int W, H, xoff, yoff, dx, dy;
+  int ret = bx = by = bt = 0;
+  if (w->border() && !w->parent()) {
+    if (w->maxw != w->minw || w->maxh != w->minh) {
+      ret = 2;
+      bx = 6; // \todo Mac : GetSystemMetrics(SM_CXSIZEFRAME);
+      by = 6; // \todo Mac : get Mac window frame size GetSystemMetrics(SM_CYSIZEFRAME);
+    } else {
+      ret = 1;
+      bx = 6; // \todo Mac : GetSystemMetrics(SM_CXFIXEDFRAME);
+      by = 6; // \todo Mac : GetSystemMetrics(SM_CYFIXEDFRAME);
+    }
+    bt = 22; // \todo Mac : GetSystemMetrics(SM_CYCAPTION);
+  }
+  //The coordinates of the whole window, including non-client area
+  xoff = bx;
+  yoff = by + bt;
+  dx = 2*bx;
+  dy = 2*by + bt;
+  X = w->x()-xoff;
+  Y = w->y()-yoff;
+  W = w->w()+dx;
+  H = w->h()+dy;
+
+  //Proceed to positioning the window fully inside the screen, if possible
+
+  // let's get a little elaborate here. Mac OS X puts a lot of stuff on the desk
+  // that we want to avoid when positioning our window, namely the Dock and the
+  // top menu bar (and even more stuff in 10.4 Tiger). So we will go through the
+  // list of all available screens and find the one that this window is most
+  // likely to go to, and then reposition it to fit withing the 'good' area.
+  Rect r;
+  // find the screen, that the center of this window will fall into
+  int R = X+W, B = Y+H; // right and bottom
+  int cx = (X+R)/2, cy = (Y+B)/2; // center of window;
+  GDHandle gd = 0L;
+  for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
+  GDPtr gp = *gd;
+  if (    cx >= gp->gdRect.left && cx <= gp->gdRect.right
+       && cy >= gp->gdRect.top  && cy <= gp->gdRect.bottom)
+    break;
+  }
+  // if the center doesn't fall on a screen, try the top left
+  if (!gd) {
+    for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
+      GDPtr gp = *gd;
+      if (    X >= gp->gdRect.left && X <= gp->gdRect.right
+           && Y >= gp->gdRect.top  && Y <= gp->gdRect.bottom)
+        break;
+    }
+  }
+  // if that doesn't fall on a screen, try the top right
+  if (!gd) {
+    for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
+      GDPtr gp = *gd;
+      if (    R >= gp->gdRect.left && R <= gp->gdRect.right
+           && Y >= gp->gdRect.top  && Y <= gp->gdRect.bottom)
+        break;
+    }
+  }
+  // if that doesn't fall on a screen, try the bottom left
+  if (!gd) {
+    for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
+      GDPtr gp = *gd;
+      if (    X >= gp->gdRect.left && X <= gp->gdRect.right
+           && B >= gp->gdRect.top  && B <= gp->gdRect.bottom)
+        break;
+    }
+  }
+  // last resort, try the bottom right
+  if (!gd) {
+    for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
+      GDPtr gp = *gd;
+      if (    R >= gp->gdRect.left && R <= gp->gdRect.right
+           && B >= gp->gdRect.top  && B <= gp->gdRect.bottom)
+        break;
+    }
+  }
+  // if we still have not found a screen, we will use the main
+  // screen, the one that has the application menu bar.
+  if (!gd) gd = GetMainDevice();
+  if (gd) {
+    GetAvailableWindowPositioningBounds(gd, &r);
+    if ( R > r.right )  X -= R - r.right;
+    if ( B > r.bottom ) Y -= B - r.bottom;
+    if ( X < r.left )   X = r.left;
+    if ( Y < r.top )    Y = r.top;
+  }
+
+  //Return the client area's top left corner in (X,Y)
+  X+=xoff;
+  Y+=yoff;
+
+  return ret;
+}
+
+/**
+ * convert a Mac FSSpec structure into a Unix filename 
+ */
+static int FSSpec2UnixPath( FSSpec *fs, char *dst )
+{
+  FSRef fsRef;
+  FSpMakeFSRef( fs, &fsRef );
+  FSRefMakePath( &fsRef, (UInt8*)dst, 1024 );
+  return strlen(dst);
+}
+
+static DragReference currDragRef = 0;
+static char *currDragData = 0L;
+static int currDragSize = 0; 
+static OSErr currDragErr = noErr;
+Fl_Window *fl_dnd_target_window = 0;
+#include <FL/fl_draw.H>
+
+/**
+ * Fill the currDrag* variables with the current DnD ASCII text.
+ */
+static OSErr fillCurrentDragData(DragReference dragRef)
+{
+  OSErr ret = noErr;
+  char *dst = 0L;
+  
+  // shortcut through this whole procedure if this is still the same drag event
+  if (dragRef==currDragRef)
+    return currDragErr;
+  
+  // clear currDrag* for a new drag event
+  currDragRef = dragRef;
+  if (currDragData) free(currDragData);
+  currDragData = 0;
+  currDragSize = 0;
+  
+  // fill currDRag* with ASCII data, if available
+  UInt16 i, nItem;
+  ItemReference itemRef;
+  FlavorFlags flags;
+  Size itemSize, size = 0;
+  CountDragItems( dragRef, &nItem );
+  for ( i = 1; i <= nItem; i++ )
+  {
+    GetDragItemReferenceNumber( dragRef, i, &itemRef );
+    ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags );
+    if ( ret == noErr )
+    {
+      GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize );
+      size += itemSize;
+    }
+    ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags );
+    if ( ret == noErr )
+    {
+      size += 1024; //++ ouch! We should create the full pathname and figure out its length
+    }
+  }
+
+  if ( !size )
+  {
+    currDragErr = userCanceledErr;
+    return currDragErr;
+  }
+
+  currDragSize = size + nItem - 1;
+  currDragData = dst = (char*)malloc( size+nItem );;
+
+  for ( i = 1; i <= nItem; i++ )
+  {
+    GetDragItemReferenceNumber( dragRef, i, &itemRef );
+    ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags );
+    if ( ret == noErr )
+    {
+      GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize );
+      GetFlavorData( dragRef, itemRef, 'TEXT', dst, &itemSize, 0L );
+      dst += itemSize;
+      *dst++ = '\n'; // add our element seperator
+    }
+    ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags );
+    if ( ret == noErr )
+    {
+      HFSFlavor hfs; itemSize = sizeof( hfs );
+      GetFlavorData( dragRef, itemRef, 'hfs ', &hfs, &itemSize, 0L );
+      itemSize = FSSpec2UnixPath( &hfs.fileSpec, dst );
+      dst += itemSize;
+      if ( itemSize>1 && ( hfs.fileType=='fold' || hfs.fileType=='disk' ) ) 
+        *dst++ = '/';
+      *dst++ = '\n'; // add our element seperator
+    }
+  }
+
+  dst[-1] = 0;
+  currDragSize = dst - currDragData - 1;
+  currDragErr = ret;
+  return ret;
+}
+
+/**
+ * Drag'n'drop tracking handler
+ */
+static pascal OSErr dndTrackingHandler( DragTrackingMessage msg, WindowPtr w, void *userData, DragReference dragRef )
+{
+  Fl_Window *target = (Fl_Window*)userData;
+  Point mp;
+  static int px, py;
+  
+  fillCurrentDragData(dragRef);
+  Fl::e_length = currDragSize;
+  Fl::e_text = currDragData;
+  
+  switch ( msg )
+  {
+  case kDragTrackingEnterWindow:
+    // check if 'TEXT' is available
+    GetDragMouse( dragRef, &mp, 0 );
+    Fl::e_x_root = px = mp.h;
+    Fl::e_y_root = py = mp.v;
+    Fl::e_x = px - target->x();
+    Fl::e_y = py - target->y();
+    fl_dnd_target_window = target;
+    if ( Fl::handle( FL_DND_ENTER, target ) )
+      fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
+    else
+      fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
+    breakMacEventLoop();
+    return noErr;
+  case kDragTrackingInWindow:
+    GetDragMouse( dragRef, &mp, 0 );
+    if ( mp.h==px && mp.v==py )
+      break;	//+ return previous condition for dnd hiliting
+    Fl::e_x_root = px = mp.h;
+    Fl::e_y_root = py = mp.v;
+    Fl::e_x = px - target->x();
+    Fl::e_y = py - target->y();
+    fl_dnd_target_window = target;
+    if ( Fl::handle( FL_DND_DRAG, target ) )
+      fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
+    else
+      fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
+    breakMacEventLoop();
+    return noErr;
+    break;
+  case kDragTrackingLeaveWindow:
+    // HideDragHilite()
+    fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
+    if ( fl_dnd_target_window )
+    {
+      Fl::handle( FL_DND_LEAVE, fl_dnd_target_window );
+      fl_dnd_target_window = 0;
+    }
+    breakMacEventLoop();
+    return noErr;
+  }
+  return noErr;
+}
+
+
+/**
+ * Drag'n'drop receive handler
+ */
+static pascal OSErr dndReceiveHandler( WindowPtr w, void *userData, DragReference dragRef )
+{
+  Point mp;
+  OSErr ret;
+  
+  Fl_Window *target = fl_dnd_target_window = (Fl_Window*)userData;
+  GetDragMouse( dragRef, &mp, 0 );
+  Fl::e_x_root = mp.h;
+  Fl::e_y_root = mp.v;
+  Fl::e_x = Fl::e_x_root - target->x();
+  Fl::e_y = Fl::e_y_root - target->y();
+  if ( !Fl::handle( FL_DND_RELEASE, target ) )
+    return userCanceledErr;
+
+  ret = fillCurrentDragData(dragRef);
+  if (ret==userCanceledErr)
+    return userCanceledErr;
+  
+  Fl::e_length = currDragSize;
+  Fl::e_text = currDragData;
+//  printf("Sending following text to widget %p:\n%s\n", Fl::belowmouse(), Fl::e_text);
+  int old_event = Fl::e_number;
+  Fl::belowmouse()->handle(Fl::e_number = FL_PASTE);
+  Fl::e_number = old_event;
+  
+  if (currDragData) {
+    free(currDragData);
+  }
+  currDragData = 0L;
+  currDragRef = 0;
+  Fl::e_text = 0L;
+  Fl::e_length = 0;
+  fl_dnd_target_window = 0L;
+  
+  breakMacEventLoop();
+  return noErr;
+}
+
+
+/**
+ * go ahead, create that (sub)window
+ * \todo we should make menu windows slightly transparent for the new Mac look
+ */
+void Fl_X::make(Fl_Window* w)
+{
+  static int xyPos = 100;
+  if ( w->parent() ) // create a subwindow
+  {
+    Fl_Group::current(0);
+    Rect wRect;
+    wRect.top    = w->y();
+    wRect.left   = w->x();
+    wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1;
+    wRect.right  = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1;
+    // our subwindow needs this structure to know about its clipping. 
+    Fl_X* x = new Fl_X;
+    x->other_xid = 0;
+    x->region = 0;
+    x->subRegion = 0;
+    x->cursor = fl_default_cursor;
+    x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz
+    Fl_Window *win = w->window();
+    Fl_X *xo = Fl_X::i(win);
+    w->set_visible();
+    if (xo) {
+      x->xidNext = xo->xidChildren;
+      x->xidChildren = 0L;
+      xo->xidChildren = x;
+      x->xid = fl_xid(win);
+      x->w = w; w->i = x;
+      x->wait_for_expose = 0;
+      x->next = Fl_X::first; // must be in the list for ::flush()
+      Fl_X::first = x;
+      int old_event = Fl::e_number;
+      w->handle(Fl::e_number = FL_SHOW);
+      Fl::e_number = old_event;
+      w->redraw(); // force draw to happen
+    }
+    fl_show_iconic = 0;
+  }
+  else // create a desktop window
+  {
+    Fl_Group::current(0);
+    fl_open_display();
+    int winclass = kDocumentWindowClass;
+    int winattr = kWindowStandardHandlerAttribute | kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute;
+    int xp = w->x();
+    int yp = w->y();
+    int wp = w->w();
+    int hp = w->h();
+    if (w->size_range_set) {
+      if ( w->minh != w->maxh || w->minw != w->maxw)
+        winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute;
+    } else {
+      if (w->resizable()) {
+        Fl_Widget *o = w->resizable();
+        int minw = o->w(); if (minw > 100) minw = 100;
+        int minh = o->h(); if (minh > 100) minh = 100;
+        w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
+        winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute;
+      } else {
+        w->size_range(w->w(), w->h(), w->w(), w->h());
+      }
+    }
+    int xwm = xp, ywm = yp, bt, bx, by;
+
+    if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) {
+      // menu windows and tooltips
+      if (w->modal()||w->override()) {
+        winclass = kHelpWindowClass;
+        winattr  = 0;
+      } else {
+        winattr = 512; // kWindowNoTitleBarAttribute;
+      }
+    } else if (w->modal()) {
+      winclass = kMovableModalWindowClass;
+    }
+
+    if (by+bt) {
+      wp += 2*bx;
+      hp += 2*by+bt;
+    }
+    if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) {
+      // use the Carbon functions below for default window positioning
+      w->x(xyPos+Fl::x());
+      w->y(xyPos+Fl::y());
+      xyPos += 25;
+      if (xyPos>200) xyPos = 100;
+    } else {
+      if (!Fl::grab()) {
+        xp = xwm; yp = ywm;
+        w->x(xp);w->y(yp);
+      }
+      xp -= bx;
+      yp -= by+bt;
+    }
+
+    if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) {
+      // find some other window to be "transient for":
+      Fl_Window* w = Fl_X::first->w;
+      while (w->parent()) w = w->window(); // todo: this code does not make any sense! (w!=w??)
+    }
+
+    Rect wRect;
+    wRect.top    = w->y();
+    wRect.left   = w->x();
+    wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1;
+    wRect.right  = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1;
+
+    const char *name = w->label();
+    Str255 pTitle; 
+    if (name) {
+      if (strlen(name) > 255) pTitle[0] = 255;
+      else pTitle[0] = strlen(name);
+
+      memcpy(pTitle+1, name, pTitle[0]);
+    } else pTitle[0] = 0;
+
+    Fl_X* x = new Fl_X;
+    x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows
+    x->region = 0;
+    x->subRegion = 0;
+    x->cursor = fl_default_cursor;
+    x->xidChildren = 0;
+    x->xidNext = 0;
+    x->gc = 0;
+
+    winattr &= GetAvailableWindowAttributes( winclass );	// make sure that the window will open
+    CreateNewWindow( winclass, winattr, &wRect, &(x->xid) );
+    SetWTitle(x->xid, pTitle);
+    MoveWindow(x->xid, wRect.left, wRect.top, 1);	// avoid Carbon Bug on old OS
+    if (w->non_modal() && !w->modal()) {
+      // Major kludge: this is to have the regular look, but stay above the document windows
+      SetWindowClass(x->xid, kFloatingWindowClass);
+    }
+    if (!(w->flags() & Fl_Window::FL_FORCE_POSITION))
+    {
+      WindowRef pw = Fl_X::first ? Fl_X::first->xid : 0 ;
+      if (w->modal()) {
+        RepositionWindow(x->xid, pw, kWindowAlertPositionOnParentWindowScreen);
+      } else if (w->non_modal()) {
+        RepositionWindow(x->xid, pw, kWindowCenterOnParentWindowScreen);
+      } else {
+        RepositionWindow(x->xid, pw, kWindowCascadeOnParentWindowScreen);
+      }
+    }
+    x->w = w; w->i = x;
+    x->wait_for_expose = 1;
+    x->next = Fl_X::first;
+    Fl_X::first = x;
+    w->set_visible();
+    { // Install Carbon Event handlers 
+      OSStatus ret;
+      EventHandlerUPP mousewheelHandler = NewEventHandlerUPP( carbonMousewheelHandler ); // will not be disposed by Carbon...
+      static EventTypeSpec mousewheelEvents[] = {
+        { kEventClassMouse, kEventMouseWheelMoved } };
+      ret = InstallWindowEventHandler( x->xid, mousewheelHandler,
+	        (int)(sizeof(mousewheelEvents)/sizeof(mousewheelEvents[0])),
+		mousewheelEvents, w, 0L );
+      EventHandlerUPP mouseHandler = NewEventHandlerUPP( carbonMouseHandler ); // will not be disposed by Carbon...
+      static EventTypeSpec mouseEvents[] = {
+        { kEventClassMouse, kEventMouseDown },
+        { kEventClassMouse, kEventMouseUp },
+        { kEventClassMouse, kEventMouseMoved },
+        { kEventClassMouse, kEventMouseDragged } };
+      ret = InstallWindowEventHandler( x->xid, mouseHandler, 4, mouseEvents, w, 0L );
+      EventHandlerUPP keyboardHandler = NewEventHandlerUPP( carbonKeyboardHandler ); // will not be disposed by Carbon...
+      static EventTypeSpec keyboardEvents[] = {
+        { kEventClassKeyboard, kEventRawKeyDown },
+        { kEventClassKeyboard, kEventRawKeyRepeat },
+        { kEventClassKeyboard, kEventRawKeyUp },
+        { kEventClassKeyboard, kEventRawKeyModifiersChanged } };
+      ret = InstallWindowEventHandler( x->xid, keyboardHandler, 4, keyboardEvents, w, 0L );
+      EventHandlerUPP windowHandler = NewEventHandlerUPP( carbonWindowHandler ); // will not be disposed by Carbon...
+      static EventTypeSpec windowEvents[] = {
+        { kEventClassWindow, kEventWindowDrawContent },
+        { kEventClassWindow, kEventWindowShown },
+        { kEventClassWindow, kEventWindowHidden },
+        { kEventClassWindow, kEventWindowActivated },
+        { kEventClassWindow, kEventWindowDeactivated },
+        { kEventClassWindow, kEventWindowClose },
+        { kEventClassWindow, kEventWindowBoundsChanging },
+        { kEventClassWindow, kEventWindowBoundsChanged } };
+      ret = InstallWindowEventHandler( x->xid, windowHandler, 8, windowEvents, w, 0L );
+      ret = InstallTrackingHandler( dndTrackingHandler, x->xid, w );
+      ret = InstallReceiveHandler( dndReceiveHandler, x->xid, w );
+    }
+
+    if ( ! Fl_X::first->next ) // if this is the first window, we need to bring the application to the front
+    { 
+      ProcessSerialNumber psn;
+      OSErr err = GetCurrentProcess( &psn );
+      if ( err==noErr ) SetFrontProcess( &psn );
+    }
+    
+    if (fl_show_iconic) { 
+      fl_show_iconic = 0;
+      CollapseWindow( x->xid, true ); // \todo Mac ; untested
+    } else if (winclass != kHelpWindowClass) {
+      Fl_Tooltip::enter(0);
+    }
+
+    ShowWindow(x->xid);
+
+    Rect rect;
+    GetWindowBounds(x->xid, kWindowContentRgn, &rect);
+    w->x(rect.left); w->y(rect.top);
+    w->w(rect.right-rect.left); w->h(rect.bottom-rect.top);
+
+    int old_event = Fl::e_number;
+    w->handle(Fl::e_number = FL_SHOW);
+    Fl::e_number = old_event;
+    w->redraw(); // force draw to happen
+    w->set_visible();
+    
+    if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); }
+  }
+}
+
+
+/**
+ * this is a leftover from X Windows
+ */
+void Fl_Window::size_range_() {
+  size_range_set = 1;
+}
+
+
+/**
+ * returns pointer to the filename, or null if name ends with ':'
+ */
+const char *fl_filename_name( const char *name ) 
+{
+  const char *p, *q;
+  if (!name) return (0);
+  for ( p = q = name ; *p ; ) 
+  {
+    if ( ( p[0] == ':' ) && ( p[1] == ':' ) ) 
+    {
+      q = p+2;
+      p++;
+    }
+    else if (p[0] == '/')
+      q = p + 1;
+    p++;
+  }
+  return q;
+}
+
+
+/**
+ * set the window title bar
+ * \todo make the titlebar icon work!
+ */
+void Fl_Window::label(const char *name,const char */*iname*/) {
+  Fl_Widget::label(name);
+  Str255 pTitle;
+
+  if (name) { pTitle[0] = strlen(name); memcpy(pTitle+1, name, pTitle[0]); }
+  else pTitle[0] = 0;
+
+  if (shown() || i) SetWTitle(fl_xid(this), pTitle);
+}
+
+
+/**
+ * make a window visible
+ */
+void Fl_Window::show() {
+  image(Fl::scheme_bg_);
+  if (Fl::scheme_bg_) {
+    labeltype(FL_NORMAL_LABEL);
+    align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  } else {
+    labeltype(FL_NO_LABEL);
+  }
+  if (!shown() || !i) {
+    Fl_X::make(this);
+  } else {
+      if ( !parent() )
+      {
+        if ( IsWindowCollapsed( i->xid ) ) CollapseWindow( i->xid, false );
+        if (!fl_capture) {
+          BringToFront(i->xid);
+          SelectWindow(i->xid);
+        }
+      }
+  }
+}
+
+
+/**
+ * resize a window
+ */
+void Fl_Window::resize(int X,int Y,int W,int H) {
+  int is_a_resize = (W != w() || H != h());
+//  printf("Fl_Winodw::resize(X=%d, Y=%d, W=%d, H=%d), is_a_resize=%d, resize_from_system=%p, this=%p\n",
+//         X, Y, W, H, is_a_resize, resize_from_system, this);
+  if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION);
+  else if (!is_a_resize) return;
+  if ( (resize_from_system!=this) && (!parent()) && shown()) {
+    MoveWindow(i->xid, X, Y, 0);
+    if (is_a_resize) {
+      if (!resizable()) size_range(W>0 ? W : 1, H>0 ? H : 1, W>0 ? W : 1, H>0 ? H : 1);
+      SizeWindow(i->xid, W>0 ? W : 1, H>0 ? H : 1, 1);
+      Rect all; all.top=-32000; all.bottom=32000; all.left=-32000; all.right=32000;
+      InvalWindowRect( i->xid, &all );    
+    }
+  } else if (resize_from_system == this && size_range_set && !parent() && shown()) {
+    if (size_range_set) {
+      if (W < minw) W = minw;
+      else if (W > maxw && maxw) W = maxw;
+      if (H < minh) H = minh;
+      else if (H > maxh && maxh) H = maxh;
+    }
+    SizeWindow(i->xid, W>0 ? W : 1, H>0 ? H : 1, 1);
+  }
+  resize_from_system = 0;
+  if (is_a_resize) {
+    Fl_Group::resize(X,Y,W,H);
+    if (shown()) { 
+      redraw(); 
+      //if (!parent()) i->wait_for_expose = 1; 
+    }
+  } else {
+    x(X); y(Y); 
+  }
+}
+
+
+/**
+ * make all drawing go into this window (called by subclass flush() impl.)
+ */
+void Fl_Window::make_current() 
+{
+#ifdef __APPLE_QUARTZ__
+  Fl_X::q_release_context();
+#endif
+  if ( !fl_window_region )
+    fl_window_region = NewRgn();
+  fl_window = i->xid;
+  current_ = this;
+
+  SetPort( GetWindowPort(i->xid) ); // \todo check for the handling of doublebuffered windows
+
+  int xp = 0, yp = 0;
+  Fl_Window *win = this;
+  while ( win ) 
+  {
+    if ( !win->window() )
+      break;
+    xp += win->x();
+    yp += win->y();
+    win = (Fl_Window*)win->window();
+  }
+  SetOrigin( -xp, -yp );
+  
+  SetRectRgn( fl_window_region, 0, 0, w(), h() );
+  
+  // \todo for performance reasons: we don't have to create this unless the child windows moved
+  for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext )
+  {
+    Fl_Window *cw = cx->w;
+    if (!cw->visible_r()) continue;
+    Fl_Region r = NewRgn();
+    SetRectRgn( r, cw->x() - xp, cw->y() - yp, 
+                   cw->x() + cw->w() - xp, cw->y() + cw->h() - yp );
+    DiffRgn( fl_window_region, r, fl_window_region );
+    DisposeRgn( r );
+  }
+  
+  fl_clip_region( 0 );
+  SetPortClipRegion( GetWindowPort(i->xid), fl_window_region );
+#ifdef __APPLE_QUARTZ__
+  QDBeginCGContext(GetWindowPort(i->xid), &i->gc);
+  fl_gc = i->gc;
+  CGContextSaveGState(fl_gc);
+  Fl_X::q_fill_context();
+#endif
+  return;
+}
+
+// helper function to manage the current CGContext fl_gc
+#ifdef __APPLE_QUARTZ__
+extern Fl_Color fl_color_;
+extern class Fl_FontSize *fl_fontsize;
+extern void fl_font(class Fl_FontSize*);
+extern void fl_quartz_restore_line_style_();
+
+// FLTK has only on global graphics state. This function copies the FLTK state into the
+// current Quartz context
+void Fl_X::q_fill_context() {
+  if (!fl_gc) return;
+  int hgt = 0;
+  if (fl_window) {
+    Rect portRect; 
+    GetPortBounds(GetWindowPort( fl_window ), &portRect);
+    hgt = portRect.bottom-portRect.top;
+  } else {
+    hgt = CGBitmapContextGetHeight(fl_gc);
+  }
+  CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f);
+  CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
+  static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
+  CGContextSetTextMatrix(fl_gc, font_mx);
+  fl_font(fl_fontsize);
+  fl_color(fl_color_);
+  fl_quartz_restore_line_style_();
+}
+
+// The only way to reste clipping to its original state is to pop the current graphics
+// state and restore the global state.
+void Fl_X::q_clear_clipping() {
+  if (!fl_gc) return;
+  CGContextRestoreGState(fl_gc);
+  CGContextSaveGState(fl_gc);
+}
+
+// Give the Quartz context back to the system
+void Fl_X::q_release_context(Fl_X *x) {
+  if (x && x->gc!=fl_gc) return;
+  if (!fl_gc) return;
+  CGContextRestoreGState(fl_gc);
+  if (fl_window) QDEndCGContext(GetWindowPort(fl_window), &fl_gc);
+  fl_gc = 0;
+}
+
+void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) {
+  CGContextSaveGState(fl_gc);
+  CGAffineTransform mx = CGContextGetCTM(fl_gc);
+  CGRect r2 = rect;
+  r2.origin.x -= 0.5f;
+  r2.origin.y -= 0.5f;
+  CGContextClipToRect(fl_gc, r2);
+  mx.d = -1.0; mx.tx = -mx.tx;
+  CGContextConcatCTM(fl_gc, mx);
+  rect.origin.x = rect.origin.x - cx;
+  rect.origin.y = (mx.ty+0.5f) - rect.origin.y - h + cy;
+  rect.size.width = w;
+  rect.size.height = h;
+}
+
+void Fl_X::q_end_image() {
+  CGContextRestoreGState(fl_gc);
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////
+// Cut & paste.
+
+Fl_Widget *fl_selection_requestor = 0;
+char *fl_selection_buffer[2];
+int fl_selection_length[2];
+int fl_selection_buffer_length[2];
+static ScrapRef myScrap = 0;
+
+/**
+ * create a selection
+ * owner: widget that created the selection
+ * stuff: pointer to selected data
+ * size of selected data
+ */
+void Fl::copy(const char *stuff, int len, int clipboard) {
+  if (!stuff || len<0) return;
+  if (len+1 > fl_selection_buffer_length[clipboard]) {
+    delete[] fl_selection_buffer[clipboard];
+    fl_selection_buffer[clipboard] = new char[len+100];
+    fl_selection_buffer_length[clipboard] = len+100;
+  }
+  memcpy(fl_selection_buffer[clipboard], stuff, len);
+  fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
+  fl_selection_length[clipboard] = len;
+  if (clipboard) {
+    ClearCurrentScrap();
+    OSStatus ret = GetCurrentScrap( &myScrap );
+    if ( ret != noErr ) {
+      myScrap = 0;
+      return;
+    }
+    // Previous version changed \n to \r before sending the text, but I would
+    // prefer to leave the local buffer alone, so a copied buffer may be
+    // needed. Check to see if this is necessary on OS/X.
+    PutScrapFlavor( myScrap, kScrapFlavorTypeText, 0,
+		    len, fl_selection_buffer[1] );
+  }
+}
+
+// Call this when a "paste" operation happens:
+void Fl::paste(Fl_Widget &receiver, int clipboard) {
+  if (clipboard) {
+    // see if we own the selection, if not go get it:
+    ScrapRef scrap = 0;
+    Size len = 0;
+    if (GetCurrentScrap(&scrap) == noErr && scrap != myScrap &&
+	GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &len) == noErr) {
+      if ( len > fl_selection_buffer_length[1] ) {
+	fl_selection_buffer_length[1] = len + 32;
+	delete[] fl_selection_buffer[1];
+	fl_selection_buffer[1] = new char[len];
+      }
+      GetScrapFlavorData( scrap, kScrapFlavorTypeText, &len,
+			  fl_selection_buffer[1] );
+      fl_selection_length[1] = len;
+      // turn all \r characters into \n:
+      for (int x = 0; x < len; x++) {
+	if (fl_selection_buffer[1][x] == '\r')
+	  fl_selection_buffer[1][x] = '\n';
+      }
+    }
+  }
+  Fl::e_text = fl_selection_buffer[clipboard];
+  Fl::e_length = fl_selection_length[clipboard];
+  if (!Fl::e_text) Fl::e_text = (char *)"";
+  receiver.handle(FL_PASTE);
+  return;
+}
+
+void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+    int timer_id = -1;
+    for (int i = 0;  i < mac_timer_used;  ++i) {
+        if ( !mac_timers[i].timer ) {
+            timer_id = i;
+            break;
+        }
+    }
+    if (timer_id == -1) {
+        if (mac_timer_used == mac_timer_alloc) {
+            realloc_timers();
+        }
+        timer_id = mac_timer_used++;
+    }
+
+    EventTimerInterval fireDelay = (EventTimerInterval) time;
+    EventLoopTimerUPP  timerUPP = NewEventLoopTimerUPP(do_timer);
+    EventLoopTimerRef  timerRef;
+    OSStatus err = InstallEventLoopTimer(GetMainEventLoop(), fireDelay, 0, timerUPP, data, &timerRef);
+    if (err == noErr) {
+        mac_timers[timer_id].callback = cb;
+        mac_timers[timer_id].data     = data;
+        mac_timers[timer_id].timer    = timerRef;
+    }
+}
+
+void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+    remove_timeout(cb, data);
+    add_timeout(time, cb, data);
+}
+
+int Fl::has_timeout(Fl_Timeout_Handler cb, void* data)
+{
+   for (int i = 0;  i < mac_timer_used;  ++i) {
+        MacTimeout& t = mac_timers[i];
+        if (t.callback == cb  &&  t.data == data) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
+{
+   for (int i = 0;  i < mac_timer_used;  ++i) {
+        MacTimeout& t = mac_timers[i];
+        if (t.callback == cb  && ( t.data == data || data == NULL)) {
+            delete_timer(t);
+        }
+    }
+}
+
+
+
+//
+// End of "$Id$".
+//
+
diff --git a/Utilities/FLTK/src/Fl_own_colormap.cxx b/Utilities/FLTK/src/Fl_own_colormap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..106e5d46da939a00c8276fea5c8f025dc4296d65
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_own_colormap.cxx
@@ -0,0 +1,85 @@
+//
+// "$Id$"
+//
+// Private colormap support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Using the default system colormap can be a bad idea on PseudoColor
+// visuals, since typically every application uses the default colormap and
+// you can run out of colormap entries easily.
+//
+// The solution is to always create a new colormap on PseudoColor displays
+// and copy the first 16 colors from the default colormap so that we won't
+// get huge color changes when switching windows.
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/Fl.H>
+
+#ifdef WIN32
+// There is probably something relevant to do on MSWindows 8-bit displays
+// but I don't know what it is
+
+void Fl::own_colormap() {}
+
+#elif defined(__APPLE__)
+// MacOS X always provides a TrueColor interface...
+
+void Fl::own_colormap() {}
+#else
+// X version
+
+void Fl::own_colormap() {
+  fl_open_display();
+#if USE_COLORMAP
+  switch (fl_visual->c_class) {
+  case GrayScale :
+  case PseudoColor :
+  case DirectColor :
+    break;
+  default:
+    return; // don't do anything for non-colormapped visuals
+  }
+  int i;
+  XColor colors[16];
+  // Get the first 16 colors from the default colormap...
+  for (i = 0; i < 16; i ++) colors[i].pixel = i;
+  XQueryColors(fl_display, fl_colormap, colors, 16);
+  // Create a new colormap...
+  fl_colormap = XCreateColormap(fl_display,
+				RootWindow(fl_display,fl_screen),
+				fl_visual->visual, AllocNone);
+  // Copy those first 16 colors to our own colormap:
+  for (i = 0; i < 16; i ++)
+    XAllocColor(fl_display, fl_colormap, colors + i);
+#endif
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_visual.cxx b/Utilities/FLTK/src/Fl_visual.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ab16581056baab06608228d01a13bf95fe8c221b
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_visual.cxx
@@ -0,0 +1,123 @@
+//
+// "$Id$"
+//
+// Visual support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Set the default visual according to passed switches:
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/Fl.H>
+
+#ifdef WIN32
+int Fl::visual(int flags) {
+  fl_GetDC(0);
+  if (flags & FL_DOUBLE) return 0;
+  if (!(flags & FL_INDEX) &&
+    GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0;
+  if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0;
+  return 1;
+}
+#elif defined(__APPLE__)
+
+// \todo Mac : need to implement Visual flags
+int Fl::visual(int flags) {
+  (void)flags;
+  return 1;
+}
+
+#else
+
+#if USE_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+
+static int test_visual(XVisualInfo& v, int flags) {
+  if (v.screen != fl_screen) return 0;
+#if USE_COLORMAP
+  if (!(flags & FL_INDEX)) {
+    if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
+    if (v.depth <= 8) return 0; // fltk will work better in colormap mode
+  }
+  if (flags & FL_RGB8) {
+    if (v.depth < 24) return 0;
+  }
+  // for now, fltk does not like colormaps of more than 8 bits:
+  if ((v.c_class&1) && v.depth > 8) return 0;
+#else
+  // simpler if we can't use colormapped visuals at all:
+  if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
+#endif
+#if USE_XDBE
+  if (flags & FL_DOUBLE) {
+    static XdbeScreenVisualInfo *xdbejunk;
+    if (!xdbejunk) {
+      int event_base, error_base;
+      if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
+      Drawable root = RootWindow(fl_display,fl_screen);
+      int numscreens = 1;
+      xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens);
+      if (!xdbejunk) return 0;
+    }
+    for (int j = 0; ; j++) {
+      if (j >= xdbejunk->count) return 0;
+      if (xdbejunk->visinfo[j].visual == v.visualid) break;
+    }
+  }
+#endif
+  return 1;
+}
+
+int Fl::visual(int flags) {
+#if USE_XDBE == 0
+  if (flags & FL_DOUBLE) return 0;
+#endif
+  fl_open_display();
+  // always use default if possible:
+  if (test_visual(*fl_visual, flags)) return 1;
+  // get all the visuals:
+  XVisualInfo vTemplate;
+  int num;
+  XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num);
+  // find all matches, use the one with greatest depth:
+  XVisualInfo *found = 0;
+  for (int i=0; i<num; i++) if (test_visual(visualList[i], flags)) {
+    if (!found || found->depth < visualList[i].depth)
+      found = &visualList[i];
+  }
+  if (!found) {XFree((void*)visualList); return 0;}
+  fl_visual = found;
+  fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+				fl_visual->visual, AllocNone);
+  return 1;
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_win32.cxx b/Utilities/FLTK/src/Fl_win32.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..36372b29647e1de4ecfa0ffc6b075136fe792eb2
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_win32.cxx
@@ -0,0 +1,1664 @@
+//
+// "$Id$"
+//
+// WIN32-specific code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This file contains win32-specific code for fltk which is always linked
+// in.  Search other files for "WIN32" or filenames ending in _win32.cxx
+// for other system-specific code.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include <FL/Enumerations.H>
+#include "flstring.h"
+#include "Fl_Font.H"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <time.h>
+#ifdef __CYGWIN__
+#  include <sys/time.h>
+#  include <unistd.h>
+#else
+#  include <winsock.h>
+#endif
+#include <winuser.h>
+#include <commctrl.h>
+
+// The following include files require GCC 3.x or a non-GNU compiler...
+#if !defined(__GNUC__) || __GNUC__ >= 3
+#  include <ole2.h>
+#  include <shellapi.h>
+#endif // !__GNUC__ || __GNUC__ >= 3
+
+
+//
+// USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
+//
+// This currently doesn't appear to work; needs to be fixed!
+//
+
+//#define USE_ASYNC_SELECT
+
+
+//
+// USE_TRACK_MOUSE - define it if you have TrackMouseEvent()...
+//
+// Apparently, at least some versions of Cygwin/MingW don't provide
+// the TrackMouseEvent() function.  You can define this by hand
+// if you have it - this is only needed to support subwindow
+// enter/leave notification under Windows.
+//
+
+//#define USE_TRACK_MOUSE
+
+#if !defined(__GNUC__)
+#  define USE_TRACK_MOUSE
+#endif // !__GNUC__
+
+
+//
+// WM_SYNCPAINT is an "undocumented" message, which is finally defined in
+// VC++ 6.0.
+//
+
+#ifndef WM_SYNCPAINT
+#  define WM_SYNCPAINT 0x0088
+#endif
+
+#ifndef WM_MOUSELEAVE
+#  define WM_MOUSELEAVE 0x02a3
+#endif
+
+#ifndef WM_MOUSEWHEEL
+#  define WM_MOUSEWHEEL 0x020a
+#endif
+
+#ifndef WHEEL_DELTA
+#  define WHEEL_DELTA 120	// according to MSDN.
+#endif
+
+
+//
+// WM_FLSELECT is the user-defined message that we get when one of
+// the sockets has pending data, etc.
+//
+
+#define WM_FLSELECT	(WM_APP+1)	// WM_APP is used for hide-window
+
+
+////////////////////////////////////////////////////////////////
+// interface to poll/select call:
+
+// fd's are only implemented for sockets.  Microsoft Windows does not
+// have a unified IO system, so it doesn't support select() on files,
+// devices, or pipes...
+//
+// Microsoft provides the Berkeley select() call and an asynchronous
+// select function that sends a WIN32 message when the select condition
+// exists...
+static int maxfd = 0;
+#ifndef USE_ASYNC_SELECT
+static fd_set fdsets[3];
+#endif // !USE_ASYNC_SELECT
+
+#define POLLIN 1
+#define POLLOUT 4
+#define POLLERR 8
+
+#if !defined(__GNUC__) || __GNUC__ >= 3
+extern IDropTarget *flIDropTarget;
+#endif // !__GNUC__ || __GNUC__ >= 3
+
+static int nfds = 0;
+static int fd_array_size = 0;
+static struct FD {
+  int fd;
+  short events;
+  void (*cb)(int, void*);
+  void* arg;
+} *fd = 0;
+
+void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
+  remove_fd(n,events);
+  int i = nfds++;
+  if (i >= fd_array_size) {
+    fd_array_size = 2*fd_array_size+1;
+    fd = (FD*)realloc(fd, fd_array_size*sizeof(FD));
+  }
+  fd[i].fd = n;
+  fd[i].events = (short)events;
+  fd[i].cb = cb;
+  fd[i].arg = v;
+
+#ifdef USE_ASYNC_SELECT
+  int mask = 0;
+  if (events & POLLIN) mask |= FD_READ;
+  if (events & POLLOUT) mask |= FD_WRITE;
+  if (events & POLLERR) mask |= FD_CLOSE;
+  WSAAsyncSelect(n, fl_window, WM_FLSELECT, mask);
+#else
+  if (events & POLLIN) FD_SET((unsigned)n, &fdsets[0]);
+  if (events & POLLOUT) FD_SET((unsigned)n, &fdsets[1]);
+  if (events & POLLERR) FD_SET((unsigned)n, &fdsets[2]);
+  if (n > maxfd) maxfd = n;
+#endif // USE_ASYNC_SELECT
+}
+
+void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) {
+  Fl::add_fd(fd, POLLIN, cb, v);
+}
+
+void Fl::remove_fd(int n, int events) {
+  int i,j;
+  for (i=j=0; i<nfds; i++) {
+    if (fd[i].fd == n) {
+      short e = fd[i].events & ~events;
+      if (!e) continue; // if no events left, delete this fd
+      fd[i].events = e;
+    }
+    // move it down in the array if necessary:
+    if (j<i) {
+      fd[j]=fd[i];
+    }
+    j++;
+  }
+  nfds = j;
+
+#ifdef USE_ASYNC_SELECT
+  WSAAsyncSelect(n, 0, 0, 0);
+#else
+  if (events & POLLIN) FD_CLR(unsigned(n), &fdsets[0]);
+  if (events & POLLOUT) FD_CLR(unsigned(n), &fdsets[1]);
+  if (events & POLLERR) FD_CLR(unsigned(n), &fdsets[2]);
+#endif // USE_ASYNC_SELECT
+}
+
+void Fl::remove_fd(int n) {
+  remove_fd(n, -1);
+}
+
+// these pointers are set by the Fl::lock() function:
+static void nothing() {}
+void (*fl_lock_function)() = nothing;
+void (*fl_unlock_function)() = nothing;
+
+static void* thread_message_;
+void* Fl::thread_message() {
+  void* r = thread_message_;
+  thread_message_ = 0;
+  return r;
+}
+
+MSG fl_msg;
+
+// This is never called with time_to_wait < 0.0.
+// It *should* return negative on error, 0 if nothing happens before
+// timeout, and >0 if any callbacks were done.  This version only
+// returns zero if nothing happens during a 0.0 timeout, otherwise
+// it returns 1.
+int fl_wait(double time_to_wait) {
+  int have_message = 0;
+
+#ifndef USE_ASYNC_SELECT
+  if (nfds) {
+    // For WIN32 we need to poll for socket input FIRST, since
+    // the event queue is not something we can select() on...
+    timeval t;
+    t.tv_sec = 0;
+    t.tv_usec = 0;
+
+    fd_set fdt[3];
+    fdt[0] = fdsets[0];
+    fdt[1] = fdsets[1];
+    fdt[2] = fdsets[2];
+    if (::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t)) {
+      // We got something - do the callback!
+      for (int i = 0; i < nfds; i ++) {
+	int f = fd[i].fd;
+	short revents = 0;
+	if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
+	if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
+	if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
+	if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
+      }
+      time_to_wait = 0.0; // just peek for any messages
+#ifdef __CYGWIN__
+    }
+#else
+    } else {
+      // we need to check them periodically, so set a short timeout:
+      if (time_to_wait > .001) time_to_wait = .001;
+    }
+#endif
+  }
+#endif // USE_ASYNC_SELECT
+
+  if (Fl::idle || Fl::damage()) 
+    time_to_wait = 0.0;
+
+  fl_unlock_function();
+
+  time_to_wait = (time_to_wait > 10000 ? 10000 : time_to_wait);
+  int t_msec = (int) (time_to_wait * 1000.0 + 0.5);
+  int ret_val = MsgWaitForMultipleObjects(0, NULL, FALSE, t_msec, QS_ALLINPUT);
+
+  fl_lock_function();
+
+  // Execute the message we got, and all other pending messages:
+  have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
+  if (have_message > 0) {
+    while (have_message != 0 && have_message != -1) {
+#ifdef USE_ASYNC_SELECT
+      if (fl_msg.message == WM_FLSELECT) {
+	// Got notification for socket
+	for (int i = 0; i < nfds; i ++)
+          if (fd[i].fd == (int)fl_msg.wParam) {
+	    (fd[i].cb)(fd[i].fd, fd[i].arg);
+	    break;
+	  }
+	// looks like it is best to do the dispatch-message anyway:
+      }
+#endif
+
+      if (fl_msg.message == fl_wake_msg)  // Used for awaking wait() from another thread
+	thread_message_ = (void*)fl_msg.wParam;
+
+      TranslateMessage(&fl_msg);
+      DispatchMessage(&fl_msg);
+      have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
+    }
+  }
+  Fl::flush();
+
+  // idle processing
+  static char in_idle;
+  if (Fl::idle && !in_idle) {
+    in_idle = 1;
+    Fl::idle();
+    in_idle = 0;
+  }
+
+  run_checks();
+  
+  // This should return 0 if only timer events were handled:
+  return 1;
+}
+
+// fl_ready() is just like fl_wait(0.0) except no callbacks are done:
+int fl_ready() {
+  if (PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE)) return 1;
+#ifdef USE_ASYNC_SELECT
+  return 0;
+#else
+  timeval t;
+  t.tv_sec = 0;
+  t.tv_usec = 0;
+  fd_set fdt[3];
+  fdt[0] = fdsets[0];
+  fdt[1] = fdsets[1];
+  fdt[2] = fdsets[2];
+  return ::select(0,&fdt[0],&fdt[1],&fdt[2],&t);
+#endif // USE_ASYNC_SELECT
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl::x()
+{
+  RECT r;
+
+  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+  return r.left;
+}
+
+int Fl::y()
+{
+  RECT r;
+
+  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+  return r.top;
+}
+
+int Fl::h()
+{
+  RECT r;
+
+  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+  return r.bottom - r.top;
+}
+
+int Fl::w()
+{
+  RECT r;
+
+  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+  return r.right - r.left;
+}
+
+void Fl::get_mouse(int &x, int &y) {
+  POINT p;
+  GetCursorPos(&p);
+  x = p.x;
+  y = p.y;
+}
+
+////////////////////////////////////////////////////////////////
+// code used for selections:
+
+char *fl_selection_buffer[2];
+int fl_selection_length[2];
+int fl_selection_buffer_length[2];
+char fl_i_own_selection[2];
+
+// Convert \n -> \r\n
+class Lf2CrlfConvert {
+  char *out;
+  int outlen;
+public:
+  Lf2CrlfConvert(const char *in, int inlen) {
+    outlen = 0;
+    const char *i;
+    char *o;
+    int lencount;
+    // Predict size of \r\n conversion buffer
+    for ( i=in, lencount = inlen; lencount--; ) {
+      if ( *i == '\r' && *(i+1) == '\n' )	// leave \r\n untranslated
+	{ i+=2; outlen+=2; }
+      else if ( *i == '\n' )			// \n by itself? leave room to insert \r
+	{ i++; outlen+=2; }
+      else
+	{ ++i; ++outlen; }
+    }
+    // Alloc conversion buffer + NULL
+    out = new char[outlen+1];
+    // Handle \n -> \r\n conversion
+    for ( i=in, o=out, lencount = inlen; lencount--; ) {
+      if ( *i == '\r' && *(i+1) == '\n' )	// leave \r\n untranslated
+        { *o++ = *i++; *o++ = *i++; }
+      else if ( *i == '\n' )			// \n by itself? insert \r
+        { *o++ = '\r'; *o++ = *i++; }
+      else
+        { *o++ = *i++; }
+    }
+    *o++ = 0;
+  }
+  ~Lf2CrlfConvert() {
+    delete[] out;
+  }
+  int GetLength() const { return(outlen); }
+  const char* GetValue() const { return(out); }
+};
+
+// call this when you create a selection:
+void Fl::copy(const char *stuff, int len, int clipboard) {
+  if (!stuff || len<0) return;
+
+  // Convert \n -> \r\n (for old apps like Notepad, DOS)
+  Lf2CrlfConvert buf(stuff, len);
+  len = buf.GetLength();
+  stuff = buf.GetValue();
+
+  if (len+1 > fl_selection_buffer_length[clipboard]) {
+    delete[] fl_selection_buffer[clipboard];
+    fl_selection_buffer[clipboard] = new char[len+100];
+    fl_selection_buffer_length[clipboard] = len+100;
+  }
+  memcpy(fl_selection_buffer[clipboard], stuff, len);
+  fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
+  fl_selection_length[clipboard] = len;
+  if (clipboard) {
+    // set up for "delayed rendering":
+    if (OpenClipboard(fl_xid(Fl::first_window()))) {
+      // if the system clipboard works, use it
+      EmptyClipboard();
+      SetClipboardData(CF_TEXT, NULL);
+      CloseClipboard();
+      fl_i_own_selection[clipboard] = 0;
+    } else {
+      // only if it fails, instruct paste() to use the internal buffers
+      fl_i_own_selection[clipboard] = 1;
+    }
+  }
+}
+
+// Call this when a "paste" operation happens:
+void Fl::paste(Fl_Widget &receiver, int clipboard) {
+  if (!clipboard || fl_i_own_selection[clipboard]) {
+    // We already have it, do it quickly without window server.
+    // Notice that the text is clobbered if set_selection is
+    // called in response to FL_PASTE!
+
+    // Convert \r\n -> \n
+    char *i = fl_selection_buffer[clipboard];
+    if (i==0L) {
+      Fl::e_text = 0; 
+      return;
+    }
+    Fl::e_text = new char[fl_selection_length[clipboard]+1];
+    char *o = Fl::e_text;
+    while (*i) {
+      if ( *i == '\r' && *(i+1) == '\n') i++;
+      else *o++ = *i++;
+    }
+    *o = 0;
+    Fl::e_length = o - Fl::e_text;
+    receiver.handle(FL_PASTE);
+    delete [] Fl::e_text;
+    Fl::e_text = 0;
+  } else {
+    if (!OpenClipboard(NULL)) return;
+    HANDLE h = GetClipboardData(CF_TEXT);
+    if (h) {
+      Fl::e_text = (LPSTR)GlobalLock(h);
+      LPSTR a,b;
+      a = b = Fl::e_text;
+      while (*a) { // strip the CRLF pairs ($%$#@^)
+	if (*a == '\r' && a[1] == '\n') a++;
+	else *b++ = *a++;
+      }
+      *b = 0;
+      Fl::e_length = b - Fl::e_text;
+      receiver.handle(FL_PASTE);
+      GlobalUnlock(h);
+    }
+    CloseClipboard();
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+HWND fl_capture;
+
+static int mouse_event(Fl_Window *window, int what, int button,
+			WPARAM wParam, LPARAM lParam)
+{
+  static int px, py, pmx, pmy;
+  POINT pt;
+  Fl::e_x = pt.x = (signed short)LOWORD(lParam);
+  Fl::e_y = pt.y = (signed short)HIWORD(lParam);
+  ClientToScreen(fl_xid(window), &pt);
+  Fl::e_x_root = pt.x;
+  Fl::e_y_root = pt.y;
+  while (window->parent()) {
+    Fl::e_x += window->x();
+    Fl::e_y += window->y();
+    window = window->window();
+  }
+
+  ulong state = Fl::e_state & 0xff0000; // keep shift key states
+#if 0
+  // mouse event reports some shift flags, perhaps save them?
+  if (wParam & MK_SHIFT) state |= FL_SHIFT;
+  if (wParam & MK_CONTROL) state |= FL_CTRL;
+#endif
+  if (wParam & MK_LBUTTON) state |= FL_BUTTON1;
+  if (wParam & MK_MBUTTON) state |= FL_BUTTON2;
+  if (wParam & MK_RBUTTON) state |= FL_BUTTON3;
+  Fl::e_state = state;
+
+  switch (what) {
+  case 1: // double-click
+    if (Fl::e_is_click) {Fl::e_clicks++; goto J1;}
+  case 0: // single-click
+    Fl::e_clicks = 0;
+  J1:
+    if (!fl_capture) SetCapture(fl_xid(window));
+    Fl::e_keysym = FL_Button + button;
+    Fl::e_is_click = 1;
+    px = pmx = Fl::e_x_root; py = pmy = Fl::e_y_root;
+    return Fl::handle(FL_PUSH,window);
+
+  case 2: // release:
+    if (!fl_capture) ReleaseCapture();
+    Fl::e_keysym = FL_Button + button;
+    return Fl::handle(FL_RELEASE,window);
+
+  case 3: // move:
+  default: // avoid compiler warning
+    // MSWindows produces extra events even if mouse does not move, ignore em:
+    if (Fl::e_x_root == pmx && Fl::e_y_root == pmy) return 1;
+    pmx = Fl::e_x_root; pmy = Fl::e_y_root;
+    if (abs(Fl::e_x_root-px)>5 || abs(Fl::e_y_root-py)>5) Fl::e_is_click = 0;
+    return Fl::handle(FL_MOVE,window);
+
+  }
+}
+
+// convert a MSWindows VK_x to an Fltk (X) Keysym:
+// See also the inverse converter in Fl_get_key_win32.cxx
+// This table is in numeric order by VK:
+static const struct {unsigned short vk, fltk, extended;} vktab[] = {
+  {VK_BACK,	FL_BackSpace},
+  {VK_TAB,	FL_Tab},
+  {VK_CLEAR,	FL_KP+'5',	0xff0b/*XK_Clear*/},
+  {VK_RETURN,	FL_Enter,	FL_KP_Enter},
+  {VK_SHIFT,	FL_Shift_L,	FL_Shift_R},
+  {VK_CONTROL,	FL_Control_L,	FL_Control_R},
+  {VK_MENU,	FL_Alt_L,	FL_Alt_R},
+  {VK_PAUSE,	FL_Pause},
+  {VK_CAPITAL,	FL_Caps_Lock},
+  {VK_ESCAPE,	FL_Escape},
+  {VK_SPACE,	' '},
+  {VK_PRIOR,	FL_KP+'9',	FL_Page_Up},
+  {VK_NEXT,	FL_KP+'3',	FL_Page_Down},
+  {VK_END,	FL_KP+'1',	FL_End},
+  {VK_HOME,	FL_KP+'7',	FL_Home},
+  {VK_LEFT,	FL_KP+'4',	FL_Left},
+  {VK_UP,	FL_KP+'8',	FL_Up},
+  {VK_RIGHT,	FL_KP+'6',	FL_Right},
+  {VK_DOWN,	FL_KP+'2',	FL_Down},
+  {VK_SNAPSHOT,	FL_Print},	// does not work on NT
+  {VK_INSERT,	FL_KP+'0',	FL_Insert},
+  {VK_DELETE,	FL_KP+'.',	FL_Delete},
+  {VK_LWIN,	FL_Meta_L},
+  {VK_RWIN,	FL_Meta_R},
+  {VK_APPS,	FL_Menu},
+  {VK_MULTIPLY,	FL_KP+'*'},
+  {VK_ADD,	FL_KP+'+'},
+  {VK_SUBTRACT,	FL_KP+'-'},
+  {VK_DECIMAL,	FL_KP+'.'},
+  {VK_DIVIDE,	FL_KP+'/'},
+  {VK_NUMLOCK,	FL_Num_Lock},
+  {VK_SCROLL,	FL_Scroll_Lock},
+  {0xba,	';'},
+  {0xbb,	'='},
+  {0xbc,	','},
+  {0xbd,	'-'},
+  {0xbe,	'.'},
+  {0xbf,	'/'},
+  {0xc0,	'`'},
+  {0xdb,	'['},
+  {0xdc,	'\\'},
+  {0xdd,	']'},
+  {0xde,	'\''}
+};
+static int ms2fltk(int vk, int extended) {
+  static unsigned short vklut[256];
+  static unsigned short extendedlut[256];
+  if (!vklut[1]) { // init the table
+    unsigned int i;
+    for (i = 0; i < 256; i++) vklut[i] = tolower(i);
+    for (i=VK_F1; i<=VK_F16; i++) vklut[i] = i+(FL_F-(VK_F1-1));
+    for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0);
+    for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) {
+      vklut[vktab[i].vk] = vktab[i].fltk;
+      extendedlut[vktab[i].vk] = vktab[i].extended;
+    }
+    for (i = 0; i < 256; i++) if (!extendedlut[i]) extendedlut[i] = vklut[i];
+  }
+  return extended ? extendedlut[vk] : vklut[vk];
+}
+
+#if USE_COLORMAP
+extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////
+/// Win32 timers
+///
+
+struct Win32Timer
+{
+    UINT_PTR handle;
+    Fl_Timeout_Handler callback;
+    void *data;
+};
+static Win32Timer* win32_timers;
+static int win32_timer_alloc;
+static int win32_timer_used;
+static HWND s_TimerWnd;
+
+static void realloc_timers()
+{
+    if (win32_timer_alloc == 0) {
+        win32_timer_alloc = 8;
+    }
+    size_t size = sizeof(Win32Timer);
+    Win32Timer* new_timers = new Win32Timer[win32_timer_alloc * 2];
+    memmove(new_timers, win32_timers, sizeof(Win32Timer) * win32_timer_used);
+    Win32Timer* delete_me = win32_timers;
+    win32_timers = new_timers;
+    delete [] delete_me;
+    win32_timer_alloc *= 2;
+}
+
+static void delete_timer(Win32Timer& t)
+{
+    KillTimer(s_TimerWnd, t.handle);
+    memset(&t, 0, sizeof(Win32Timer));
+}
+
+/// END TIMERS
+/////////////////////////////////////////////////////////////////////////////
+
+static Fl_Window* resize_bug_fix;
+
+extern void fl_save_pen(void);
+extern void fl_restore_pen(void);
+
+static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+  // Copy the message to fl_msg so add_handler code can see it, it is
+  // already there if this is called by DispatchMessage, but not if
+  // Windows calls this directly.
+  fl_msg.hwnd = hWnd;
+  fl_msg.message = uMsg;
+  fl_msg.wParam = wParam;
+  fl_msg.lParam = lParam;
+  //fl_msg.time = ???
+  //fl_msg.pt = ???
+  //fl_msg.lPrivate = ???
+
+  Fl_Window *window = fl_find(hWnd);
+
+  if (window) switch (uMsg) {
+
+  case WM_QUIT: // this should not happen?
+    Fl::fatal("WM_QUIT message");
+
+  case WM_CLOSE: // user clicked close box
+    Fl::handle(FL_CLOSE, window);
+    PostQuitMessage(0);
+    return 0;
+
+  case WM_SYNCPAINT :
+  case WM_NCPAINT :
+  case WM_ERASEBKGND :
+    // Andreas Weitl - WM_SYNCPAINT needs to be passed to DefWindowProc
+    // so that Windows can generate the proper paint messages...
+    // Similarly, WM_NCPAINT and WM_ERASEBKGND need this, too...
+    break;
+
+  case WM_PAINT: {
+    Fl_Region R;
+    Fl_X *i = Fl_X::i(window);
+    i->wait_for_expose = 0;
+    char redraw_whole_window = false;
+    if (!i->region && window->damage()) {
+      // Redraw the whole window...
+      i->region = CreateRectRgn(0, 0, window->w(), window->h());
+      redraw_whole_window = true;
+    }
+
+    // We need to merge WIN32's damage into FLTK's damage.
+    R = CreateRectRgn(0,0,0,0);
+    int r = GetUpdateRgn(hWnd,R,0);
+    if (r==NULLREGION && !redraw_whole_window) {
+      break;
+    }
+
+    if (i->region) {
+      // Also tell WIN32 that we are drawing someplace else as well...
+      InvalidateRgn(hWnd, i->region, FALSE);
+      CombineRgn(i->region, i->region, R, RGN_OR);
+      XDestroyRegion(R);
+    } else {
+      i->region = R;
+    }
+
+    window->clear_damage((uchar)(window->damage()|FL_DAMAGE_EXPOSE));
+    // These next two statements should not be here, so that all update
+    // is deferred until Fl::flush() is called during idle.  However WIN32
+    // apparently is very unhappy if we don't obey it and draw right now.
+    // Very annoying!
+    fl_GetDC(hWnd); // Make sure we have a DC for this window...
+    fl_save_pen();
+    i->flush();
+    fl_restore_pen();
+    if (window->type() == FL_DOUBLE_WINDOW) ValidateRgn(hWnd,0);
+    else ValidateRgn(hWnd,i->region);
+    window->clear_damage();
+    } return 0;
+
+  case WM_LBUTTONDOWN:  mouse_event(window, 0, 1, wParam, lParam); return 0;
+  case WM_LBUTTONDBLCLK:mouse_event(window, 1, 1, wParam, lParam); return 0;
+  case WM_LBUTTONUP:    mouse_event(window, 2, 1, wParam, lParam); return 0;
+  case WM_MBUTTONDOWN:  mouse_event(window, 0, 2, wParam, lParam); return 0;
+  case WM_MBUTTONDBLCLK:mouse_event(window, 1, 2, wParam, lParam); return 0;
+  case WM_MBUTTONUP:    mouse_event(window, 2, 2, wParam, lParam); return 0;
+  case WM_RBUTTONDOWN:  mouse_event(window, 0, 3, wParam, lParam); return 0;
+  case WM_RBUTTONDBLCLK:mouse_event(window, 1, 3, wParam, lParam); return 0;
+  case WM_RBUTTONUP:    mouse_event(window, 2, 3, wParam, lParam); return 0;
+
+  case WM_MOUSEMOVE:
+#ifdef USE_TRACK_MOUSE
+    if (Fl::belowmouse() != window) {
+      TRACKMOUSEEVENT tme;
+      tme.cbSize    = sizeof(TRACKMOUSEEVENT);
+      tme.dwFlags   = TME_LEAVE;
+      tme.hwndTrack = hWnd;
+      _TrackMouseEvent(&tme);
+    }
+#endif // USE_TRACK_MOUSE
+    mouse_event(window, 3, 0, wParam, lParam);
+    return 0;
+
+  case WM_MOUSELEAVE:
+    Fl::belowmouse(0);
+    if (!window->parent()) Fl::handle(FL_LEAVE, window);
+    break;
+
+  case WM_SETFOCUS:
+    Fl::handle(FL_FOCUS, window);
+    break;
+
+  case WM_KILLFOCUS:
+    Fl::handle(FL_UNFOCUS, window);
+    Fl::flush(); // it never returns to main loop when deactivated...
+    break;
+
+  case WM_SHOWWINDOW:
+    if (!window->parent()) {
+      Fl::handle(wParam ? FL_SHOW : FL_HIDE, window);
+    }
+    break;
+
+  case WM_ACTIVATEAPP:
+    // From eric@vfx.sel.sony.com, we should process WM_ACTIVATEAPP
+    // messages to restore the correct state of the shift/ctrl/alt/lock
+    // keys...  Added control, shift, alt, and meta keys, and changed
+    // to use GetAsyncKeyState and do it when wParam is 1
+    // (that means we have focus...)
+    if (wParam)
+    {
+      ulong state = 0;
+      if (GetAsyncKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK;
+      if (GetAsyncKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK;
+      if (GetAsyncKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
+      if (GetAsyncKeyState(VK_CONTROL)&~1) state |= FL_CTRL;
+      if (GetAsyncKeyState(VK_SHIFT)&~1) state |= FL_SHIFT;
+      if (GetAsyncKeyState(VK_MENU)) state |= FL_ALT;
+      if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1) state |= FL_META;
+      Fl::e_state = state;
+      return 0;
+    }
+    break;
+
+  case WM_KEYDOWN:
+  case WM_SYSKEYDOWN:
+  case WM_KEYUP:
+  case WM_SYSKEYUP:
+    // save the keysym until we figure out the characters:
+    Fl::e_keysym = ms2fltk(wParam,lParam&(1<<24));
+    // See if TranslateMessage turned it into a WM_*CHAR message:
+    if (PeekMessage(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE)) {
+      uMsg = fl_msg.message;
+      wParam = fl_msg.wParam;
+      lParam = fl_msg.lParam;
+    }
+  case WM_DEADCHAR:
+  case WM_SYSDEADCHAR:
+  case WM_CHAR:
+  case WM_SYSCHAR: {
+    ulong state = Fl::e_state & 0xff000000; // keep the mouse button state
+    // if GetKeyState is expensive we might want to comment some of these out:
+    if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT;
+    if (GetKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK;
+    if (GetKeyState(VK_CONTROL)&~1) state |= FL_CTRL;
+    // Alt gets reported for the Alt-GR switch on foreign keyboards.
+    // so we need to check the event as well to get it right:
+    if ((lParam&(1<<29)) //same as GetKeyState(VK_MENU)
+	&& uMsg != WM_CHAR) state |= FL_ALT;
+    if (GetKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK;
+    if ((GetKeyState(VK_LWIN)|GetKeyState(VK_RWIN))&~1) {
+      // WIN32 bug?  GetKeyState returns garbage if the user hit the
+      // meta key to pop up start menu.  Sigh.
+      if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1)
+	state |= FL_META;
+    }
+    if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
+    Fl::e_state = state;
+    if (lParam & (1<<31)) { // key up events.
+      if (Fl::handle(FL_KEYUP, window)) return 0;
+      break;
+    }
+    static char buffer[2];
+    if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
+      buffer[0] = char(wParam);
+      Fl::e_length = 1;
+    } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
+      if (state & FL_NUM_LOCK) {
+        // Convert to regular keypress...
+	buffer[0] = Fl::e_keysym-FL_KP;
+	Fl::e_length = 1;
+      } else {
+        // Convert to special keypress...
+	buffer[0] = 0;
+	Fl::e_length = 0;
+	switch (Fl::e_keysym) {
+	  case FL_KP + '0' :
+	    Fl::e_keysym = FL_Insert;
+	    break;
+	  case FL_KP + '1' :
+	    Fl::e_keysym = FL_End;
+	    break;
+	  case FL_KP + '2' :
+	    Fl::e_keysym = FL_Down;
+	    break;
+	  case FL_KP + '3' :
+	    Fl::e_keysym = FL_Page_Down;
+	    break;
+	  case FL_KP + '4' :
+	    Fl::e_keysym = FL_Left;
+	    break;
+	  case FL_KP + '6' :
+	    Fl::e_keysym = FL_Right;
+	    break;
+	  case FL_KP + '7' :
+	    Fl::e_keysym = FL_Home;
+	    break;
+	  case FL_KP + '8' :
+	    Fl::e_keysym = FL_Up;
+	    break;
+	  case FL_KP + '9' :
+	    Fl::e_keysym = FL_Page_Up;
+	    break;
+	  case FL_KP + '.' :
+	    Fl::e_keysym = FL_Delete;
+	    break;
+	  case FL_KP + '/' :
+	  case FL_KP + '*' :
+	  case FL_KP + '-' :
+	  case FL_KP + '+' :
+	    buffer[0] = Fl::e_keysym-FL_KP;
+	    Fl::e_length = 1;
+	    break;
+	}
+      }
+    } else {
+      buffer[0] = 0;
+      Fl::e_length = 0;
+    }
+    Fl::e_text = buffer;
+    // for (int i = lParam&0xff; i--;)
+    while (window->parent()) window = window->window();
+    if (Fl::handle(FL_KEYBOARD,window)) return 0;
+    break;}
+
+  case WM_MOUSEWHEEL: {
+    static int delta = 0; // running total of all motion
+    delta += (SHORT)(HIWORD(wParam));
+    Fl::e_dy = -delta / WHEEL_DELTA;
+    delta += Fl::e_dy * WHEEL_DELTA;
+    if (Fl::e_dy) Fl::handle(FL_MOUSEWHEEL, window);
+    return 0;
+  }
+
+  case WM_GETMINMAXINFO:
+    Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam);
+    break;
+
+  case WM_SIZE:
+    if (!window->parent()) {
+      if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) {
+	Fl::handle(FL_HIDE, window);
+      } else {
+	Fl::handle(FL_SHOW, window);
+	resize_bug_fix = window;
+	window->size(LOWORD(lParam), HIWORD(lParam));
+      }
+    }
+    break;
+
+  case WM_MOVE: {
+    resize_bug_fix = window;
+    int nx = LOWORD(lParam);
+    int ny = HIWORD(lParam);
+    if (nx & 0x8000) nx -= 65536;
+    if (ny & 0x8000) ny -= 65536;
+    window->position(nx, ny); }
+    break;
+
+  case WM_SETCURSOR:
+    if (LOWORD(lParam) == HTCLIENT) {
+      while (window->parent()) window = window->window();
+      SetCursor(Fl_X::i(window)->cursor);
+      return 0;
+    }
+    break;
+
+#if USE_COLORMAP
+  case WM_QUERYNEWPALETTE :
+    fl_GetDC(hWnd);
+    if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE);
+    break;
+
+  case WM_PALETTECHANGED:
+    fl_GetDC(hWnd);
+    if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc);
+    break;
+
+  case WM_CREATE :
+    fl_GetDC(hWnd);
+    fl_select_palette();
+    break;
+#endif
+
+  case WM_DESTROYCLIPBOARD:
+    fl_i_own_selection[1] = 0;
+    return 1;
+
+  case WM_RENDERALLFORMATS:
+    fl_i_own_selection[1] = 0;
+    // Windoze seems unhappy unless I do these two steps. Documentation
+    // seems to vary on whether opening the clipboard is necessary or
+    // is in fact wrong:
+    CloseClipboard();
+    OpenClipboard(NULL);
+    // fall through...
+  case WM_RENDERFORMAT: {
+    HANDLE h = GlobalAlloc(GHND, fl_selection_length[1]+1);
+    if (h) {
+      LPSTR p = (LPSTR)GlobalLock(h);
+      memcpy(p, fl_selection_buffer[1], fl_selection_length[1]);
+      p[fl_selection_length[1]] = 0;
+      GlobalUnlock(h);
+      SetClipboardData(CF_TEXT, h);
+    }
+    // Windoze also seems unhappy if I don't do this. Documentation very
+    // unclear on what is correct:
+    if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard();
+    return 1;}
+
+  default:
+    if (Fl::handle(0,0)) return 0;
+    break;
+  }
+
+  return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+////////////////////////////////////////////////////////////////
+// This function gets the dimensions of the top/left borders and
+// the title bar, if there is one, based on the FL_BORDER, FL_MODAL
+// and FL_NONMODAL flags, and on the window's size range.
+// It returns the following values:
+//
+// value | border | title bar
+//   0   |  none  |   no
+//   1   |  fix   |   yes
+//   2   |  size  |   yes
+
+int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) {
+  int W, H, xoff, yoff, dx, dy;
+  int ret = bx = by = bt = 0;
+
+  int fallback = 1;
+  if (!w->parent()) {
+    HWND hwnd = fl_xid(w);
+    if (hwnd) {
+      // The block below calculates the window borders by requesting the
+      // required decorated window rectangle for a desired client rectangle.
+      // If any part of the function above fails, we will drop to a 
+      // fallback to get the best guess which is always available.
+      HWND hwnd = fl_xid(w);
+      // request the style flags of this window, as WIN32 sees them
+      LONG style = GetWindowLong(hwnd, GWL_STYLE);
+      LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+      RECT r;
+      r.left = w->x();
+      r.top = w->y();
+      r.right = w->x()+w->w();
+      r.bottom = w->y()+w->h();
+      // get the decoration rectangle for the desired client rectangle
+      BOOL ok = AdjustWindowRectEx(&r, style, FALSE, exstyle);
+      if (ok) {
+        X = r.left;
+        Y = r.top;
+        W = r.right - r.left;
+        H = r.bottom - r.top;
+        bx = w->x() - r.left;
+        by = r.bottom - w->y() - w->h(); // height of the bootm frame
+        bt = w->y() - r.top - by; // height of top caption bar
+        xoff = bx;
+        yoff = by + bt;
+        dx = W - w->w();
+        dy = H - w->h();
+        if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh))
+          ret = 2;
+        else
+          ret = 1;
+        fallback = 0;
+      }
+    }
+  }
+  // This is the original (pre 1.1.7) routine to calculate window border sizes.
+  if (fallback) {
+    if (w->border() && !w->parent()) {
+      if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
+        ret = 2;
+        bx = GetSystemMetrics(SM_CXSIZEFRAME);
+        by = GetSystemMetrics(SM_CYSIZEFRAME);
+      } else {
+        ret = 1;
+        bx = GetSystemMetrics(SM_CXFIXEDFRAME);
+        by = GetSystemMetrics(SM_CYFIXEDFRAME);
+      }
+      bt = GetSystemMetrics(SM_CYCAPTION);
+    }
+    //The coordinates of the whole window, including non-client area
+    xoff = bx;
+    yoff = by + bt;
+    dx = 2*bx;
+    dy = 2*by + bt;
+    X = w->x()-xoff;
+    Y = w->y()-yoff;
+    W = w->w()+dx;
+    H = w->h()+dy;
+  }
+
+  //Proceed to positioning the window fully inside the screen, if possible
+  //Make border's lower right corner visible
+  int scr_x, scr_y, scr_w, scr_h;
+  Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y);
+  if (scr_x+scr_w < X+W) X = scr_x+scr_w - W;
+  if (scr_y+scr_h < Y+H) Y = scr_y+scr_h - H;
+  //Make border's upper left corner visible
+  if (X<scr_x) X = scr_x;
+  if (Y<scr_y) Y = scr_y;
+  //Make client area's lower right corner visible
+  if (scr_x+scr_w < X+dx+ w->w()) X = scr_x+scr_w - w->w() - dx;
+  if (scr_y+scr_h < Y+dy+ w->h()) Y = scr_y+scr_h - w->h() - dy;
+  //Make client area's upper left corner visible
+  if (X+xoff < scr_x) X = scr_x-xoff;
+  if (Y+yoff < scr_y) Y = scr_y-yoff;
+  //Return the client area's top left corner in (X,Y)
+  X+=xoff;
+  Y+=yoff;
+
+  return ret;
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Window::resize(int X,int Y,int W,int H) {
+  UINT flags = SWP_NOSENDCHANGING | SWP_NOZORDER 
+             | SWP_NOACTIVATE | SWP_NOOWNERZORDER;
+  int is_a_resize = (W != w() || H != h());
+  int resize_from_program = (this != resize_bug_fix);
+  if (!resize_from_program) resize_bug_fix = 0;
+  if (X != x() || Y != y()) {
+    set_flag(FL_FORCE_POSITION);
+  } else {
+    if (!is_a_resize) return;
+    flags |= SWP_NOMOVE;
+  }
+  if (is_a_resize) {
+    Fl_Group::resize(X,Y,W,H);
+    if (shown()) {redraw(); i->wait_for_expose = 1;}
+  } else {
+    x(X); y(Y);
+    flags |= SWP_NOSIZE;
+  }
+  if (!border()) flags |= SWP_NOACTIVATE;
+  if (resize_from_program && shown()) {
+    if (!resizable()) size_range(w(),h(),w(),h());
+    int dummy_x, dummy_y, bt, bx, by;
+    //Ignore window managing when resizing, so that windows (and more
+    //specifically menus) can be moved offscreen.
+    if (Fl_X::fake_X_wm(this, dummy_x, dummy_y, bt, bx, by)) {
+      X -= bx;
+      Y -= by+bt;
+      W += 2*bx;
+      H += 2*by+bt;
+    }
+    SetWindowPos(i->xid, 0, X, Y, W, H, flags);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+/*
+ * This silly little class remembers the name of all window classes 
+ * we register to avoid double registration. It has the added bonus 
+ * of freeing everything on application colse as well.
+ */
+class NameList {
+public:
+  NameList() { name = (char**)malloc(sizeof(char**)); NName = 1; nName = 0; }
+  ~NameList() { 
+    int i;
+    for (i=0; i<nName; i++) free(name[i]);
+    if (name) free(name); 
+  }
+  void add_name(const char *n) {
+    if (NName==nName) {
+      NName += 5;
+      name = (char**)realloc(name, NName * sizeof(char*));
+    }
+    name[nName++] = strdup(n);
+  }
+  char has_name(const char *n) {
+    int i;
+    for (i=0; i<nName; i++) {
+      if (strcmp(name[i], n)==0) return 1;
+    }
+    return 0;
+  }
+private:
+  char **name;
+  int nName, NName;
+};
+
+void fl_fix_focus(); // in Fl.cxx
+
+char fl_show_iconic;	// hack for Fl_Window::iconic()
+// int fl_background_pixel = -1; // color to use for background
+HCURSOR fl_default_cursor;
+UINT fl_wake_msg = 0;
+int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
+
+Fl_X* Fl_X::make(Fl_Window* w) {
+  Fl_Group::current(0); // get rid of very common user bug: forgot end()
+
+  static NameList class_name_list;
+  static const char *first_class_name = 0L;
+  const char *class_name = w->xclass();
+  if (!class_name) class_name = first_class_name; // reuse first class name used
+  if (!class_name) class_name = "FLTK"; // default to create a "FLTK" WNDCLASS
+  if (!first_class_name) {
+    first_class_name = class_name;
+  }
+
+  if (!class_name_list.has_name(class_name)) {
+    WNDCLASSEX wc;
+    memset(&wc, 0, sizeof(wc));
+    wc.cbSize = sizeof(WNDCLASSEX);
+    // Documentation states a device context consumes about 800 bytes
+    // of memory... so who cares? If 800 bytes per window is what it
+    // takes to speed things up, I'm game.
+    //wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS;
+    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
+    wc.lpfnWndProc = (WNDPROC)WndProc;
+    wc.hInstance = fl_display;
+    if (!w->icon())
+      w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
+    wc.hIcon = wc.hIconSm = (HICON)w->icon();
+    wc.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
+    //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
+    //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
+    wc.lpszClassName = class_name;
+    RegisterClassEx(&wc);
+    class_name_list.add_name(class_name);
+  }
+
+  const char* message_name = "FLTK::ThreadWakeup";
+  if (!fl_wake_msg) fl_wake_msg = RegisterWindowMessage(message_name);
+
+  HWND parent;
+  DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+  DWORD styleEx = WS_EX_LEFT;
+
+  int xp = w->x();
+  int yp = w->y();
+  int wp = w->w();
+  int hp = w->h();
+
+  int showit = 1;
+
+  if (w->parent()) {
+    style |= WS_CHILD;
+    styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
+    parent = fl_xid(w->window());
+  } else {
+    if (!w->size_range_set) {
+      if (w->resizable()) {
+	Fl_Widget *o = w->resizable();
+	int minw = o->w(); if (minw > 100) minw = 100;
+	int minh = o->h(); if (minh > 100) minh = 100;
+	w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
+      } else {
+	w->size_range(w->w(), w->h(), w->w(), w->h());
+      }
+    }
+    styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
+    int xwm = xp , ywm = yp , bt, bx, by;
+    switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) {
+      // No border (used for menus)
+      case 0: style |= WS_POPUP;
+              styleEx |= WS_EX_TOOLWINDOW;
+	      break;
+
+      // Thin border and title bar
+      case 1: style |= WS_DLGFRAME | WS_CAPTION; break;
+
+      // Thick, resizable border and title bar, with maximize button
+      case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break;
+    }
+    if (by+bt) {
+      if (!w->modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX;
+      wp += 2*bx;
+      hp += 2*by+bt;
+    }
+    if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) {
+      xp = yp = CW_USEDEFAULT;
+    } else {
+      if (!Fl::grab()) {
+	xp = xwm; yp = ywm;
+        w->x(xp);w->y(yp);
+      }
+      xp -= bx;
+      yp -= by+bt;
+    }
+
+    parent = 0;
+    if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) {
+      // find some other window to be "transient for":
+      Fl_Window* w = Fl_X::first->w;
+      while (w->parent()) w = w->window();
+      parent = fl_xid(w);
+      if (!w->visible()) showit = 0;
+    } else if (Fl::grab()) parent = fl_xid(Fl::grab());
+  }
+
+  Fl_X* x = new Fl_X;
+  x->other_xid = 0;
+  x->setwindow(w);
+  x->region = 0;
+  x->private_dc = 0;
+  x->cursor = fl_default_cursor;
+  x->xid = CreateWindowEx(
+    styleEx,
+    class_name, w->label(), style,
+    xp, yp, wp, hp,
+    parent,
+    NULL, // menu
+    fl_display,
+    NULL // creation parameters
+    );
+  x->next = Fl_X::first;
+  Fl_X::first = x;
+
+  x->wait_for_expose = 1;
+  if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;}
+  if (showit) {
+    w->set_visible();
+    int old_event = Fl::e_number;
+    w->handle(Fl::e_number = FL_SHOW); // get child windows to appear
+    Fl::e_number = old_event;
+    w->redraw(); // force draw to happen
+  }
+  // If we've captured the mouse, we dont want do activate any
+  // other windows from the code, or we loose the capture.
+  ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
+	     (Fl::grab() || (style & WS_POPUP)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
+
+  // Drag-n-drop requires GCC 3.x or a non-GNU compiler...
+#if !defined(__GNUC__) || __GNUC__ >= 3
+  // Register all windows for potential drag'n'drop operations
+  static char oleInitialized = 0;
+  if (!oleInitialized) { OleInitialize(0L); oleInitialized=1; }
+
+  RegisterDragDrop(x->xid, flIDropTarget);
+#endif // !__GNUC__ || __GNUC__ >= 3
+
+  if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
+  return x;
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+/// Win32 timers
+///
+
+
+static LRESULT CALLBACK s_TimerProc(HWND hwnd, UINT msg,
+                                    WPARAM wParam, LPARAM lParam)
+{
+    switch (msg) {
+    case WM_TIMER:
+        {
+            unsigned int id = wParam - 1;
+            if (id < win32_timer_used && win32_timers[id].handle) {
+                Fl_Timeout_Handler cb   = win32_timers[id].callback;
+                void*              data = win32_timers[id].data;
+                delete_timer(win32_timers[id]);
+                if (cb) {
+                    (*cb)(data);
+                }
+            }
+        }
+        return 0;
+
+    default:
+        break;
+    }
+
+    return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+    repeat_timeout(time, cb, data);
+}
+
+void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+    int timer_id = -1;
+    for (int i = 0;  i < win32_timer_used;  ++i) {
+        if ( !win32_timers[i].handle ) {
+            timer_id = i;
+            break;
+        }
+    }
+    if (timer_id == -1) {
+        if (win32_timer_used == win32_timer_alloc) {
+            realloc_timers();
+        }
+        timer_id = win32_timer_used++;
+    }
+    unsigned int elapsed = (unsigned int)(time * 1000);
+
+    if ( !s_TimerWnd ) {
+        const char* timer_class = "FLTimer";
+        WNDCLASSEX wc;
+        memset(&wc, 0, sizeof(wc));
+        wc.cbSize = sizeof (wc);
+        wc.style = CS_CLASSDC;
+        wc.lpfnWndProc = (WNDPROC)s_TimerProc;
+        wc.hInstance = fl_display;
+        wc.lpszClassName = timer_class;
+        ATOM atom = RegisterClassEx(&wc);
+        // create a zero size window to handle timer events
+        s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW,
+                                    timer_class, "",
+                                    WS_POPUP,
+                                    0, 0, 0, 0,
+                                    NULL, NULL, fl_display, NULL);
+        // just in case this OS won't let us create a 0x0 size window:
+        if (!s_TimerWnd) 
+          s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW,
+                                    timer_class, "",
+                                    WS_POPUP,
+                                    0, 0, 1, 1,
+                                    NULL, NULL, fl_display, NULL);
+        ShowWindow(s_TimerWnd, SW_SHOWNOACTIVATE);
+    }
+
+    win32_timers[timer_id].callback = cb;
+    win32_timers[timer_id].data     = data;
+
+    win32_timers[timer_id].handle =
+        SetTimer(s_TimerWnd, timer_id + 1, elapsed, NULL);
+}
+
+int Fl::has_timeout(Fl_Timeout_Handler cb, void* data)
+{
+    for (int i = 0;  i < win32_timer_used;  ++i) {
+        Win32Timer& t = win32_timers[i];
+        if (t.handle  &&  t.callback == cb  &&  t.data == data) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
+{
+    int i;
+    for (i = 0;  i < win32_timer_used;  ++i) {
+        Win32Timer& t = win32_timers[i];
+        if (t.handle  &&  t.callback == cb  &&
+            (t.data == data  ||  data == NULL)) {
+            delete_timer(t);
+        }
+    }
+}
+
+/// END TIMERS
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+////////////////////////////////////////////////////////////////
+
+HINSTANCE fl_display = GetModuleHandle(NULL);
+
+void Fl_Window::size_range_() {
+  size_range_set = 1;
+}
+
+void Fl_X::set_minmax(LPMINMAXINFO minmax)
+{
+  int td, wd, hd, dummy_x, dummy_y;
+
+  fake_X_wm(w, dummy_x, dummy_y, td, wd, hd);
+  wd *= 2;
+  hd *= 2;
+  hd += td;
+
+  minmax->ptMinTrackSize.x = w->minw + wd;
+  minmax->ptMinTrackSize.y = w->minh + hd;
+  if (w->maxw) {
+    minmax->ptMaxTrackSize.x = w->maxw + wd;
+    minmax->ptMaxSize.x = w->maxw + wd;
+  }
+  if (w->maxh) {
+    minmax->ptMaxTrackSize.y = w->maxh + hd;
+    minmax->ptMaxSize.y = w->maxh + hd;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/filename.H> // need so FL_EXPORT fl_filename_name works
+
+// returns pointer to the filename, or null if name ends with '/'
+const char *fl_filename_name(const char *name) {
+  const char *p,*q;
+  if (!name) return (0);
+  q = name;
+  if (q[0] && q[1]==':') q += 2; // skip leading drive letter
+  for (p = q; *p; p++) if (*p == '/' || *p == '\\') q = p+1;
+  return q;
+}
+
+void Fl_Window::label(const char *name,const char *iname) {
+  Fl_Widget::label(name);
+  iconlabel_ = iname;
+  if (shown() && !parent()) {
+    if (!name) name = "";
+    SetWindowText(i->xid, name);
+    // if (!iname) iname = fl_filename_name(name);
+    // should do something with iname here...
+  }
+}
+
+////////////////////////////////////////////////////////////////
+// Implement the virtual functions for the base Fl_Window class:
+
+// If the box is a filled rectangle, we can make the redisplay *look*
+// faster by using X's background pixel erasing.  We can make it
+// actually *be* faster by drawing the frame only, this is done by
+// setting fl_boxcheat, which is seen by code in fl_drawbox.cxx:
+// For WIN32 it looks like all windows share a background color, so
+// I use FL_GRAY for this and only do this cheat for windows that are
+// that color.
+// Actually it is totally disabled.
+// Fl_Widget *fl_boxcheat;
+//static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);}
+
+void Fl_Window::show() {
+  image(Fl::scheme_bg_);
+  if (Fl::scheme_bg_) {
+    labeltype(FL_NORMAL_LABEL);
+    align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  } else {
+    labeltype(FL_NO_LABEL);
+  }
+  if (!shown()) {
+    // if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color());
+    Fl_X::make(this);
+  } else {
+    // Once again, we would lose the capture if we activated the window.
+    if (IsIconic(i->xid)) OpenIcon(i->xid);
+    if (!fl_capture) BringWindowToTop(i->xid);
+    //ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE);
+  }
+}
+
+Fl_Window *Fl_Window::current_;
+// the current context
+HDC fl_gc = 0;
+// the current window handle, initially set to -1 so we can correctly
+// allocate fl_GetDC(0)
+HWND fl_window = NULL;
+
+// Here we ensure only one GetDC is ever in place.
+HDC fl_GetDC(HWND w) {
+  if (fl_gc) {
+    if (w == fl_window  &&  fl_window != NULL) return fl_gc;
+    if (fl_window) fl_release_dc(fl_window, fl_gc); // ReleaseDC
+  }
+  fl_gc = GetDC(w);
+  fl_save_dc(w, fl_gc);
+  fl_window = w;
+  // calling GetDC seems to always reset these: (?)
+  SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
+  SetBkMode(fl_gc, TRANSPARENT);
+  return fl_gc;
+}
+
+// make X drawing go into this window (called by subclass flush() impl.)
+void Fl_Window::make_current() {
+  fl_GetDC(fl_xid(this));
+
+#if USE_COLORMAP
+  // Windows maintains a hardware and software color palette; the
+  // SelectPalette() call updates the current soft->hard mapping
+  // for all drawing calls, so we must select it here before any
+  // code does any drawing...
+
+  fl_select_palette();
+#endif // USE_COLORMAP
+
+  current_ = this;
+  fl_clip_region(0);
+}
+
+/* Make sure that all allocated fonts are released. This works only if 
+   Fl::run() is allowed to exit by closing all windows. Calling 'exit(int)'
+   will not automatically free any fonts. */
+void fl_free_fonts(void)
+{
+// remove the Fl_FontSize chains
+  int i;
+  Fl_Fontdesc * s;
+  Fl_FontSize * f;
+  Fl_FontSize * ff;
+  for (i=0; i<FL_FREE_FONT; i++) {
+    s = fl_fonts + i;
+    for (f=s->first; f; f=ff) {
+      ff = f->next;
+      delete(f);
+      s->first = ff;
+    }
+  }
+}
+
+
+///////////////////////////////////////////////////////////////////////
+//
+//  The following routines help fix a problem with the leaking of Windows
+//  Device Context (DC) objects. The 'proper' protocol is for a program to
+//  acquire a DC, save its state, do the modifications needed for drawing,
+//  perform the drawing, restore the initial state, and release the DC. In
+//  FLTK, the save and restore steps have previously been omitted and DCs are
+//  not properly released, leading to a great number of DC leaks. As some
+//  Windows "OSs" will hang when any process exceeds roughly 10,000 GDI objects,
+//  it is important to control GDI leaks, which are much more important than memory
+//  leaks. The following struct, global variable, and routines help implement
+//  the above protocol for those cases where the GetDC and RestoreDC are not in
+//  the same routine. For each GetDC, fl_save_dc is used to create an entry in 
+//  a linked list that saves the window handle, the DC handle, and the initial
+//  state. When the DC is to be released, 'fl_release_dc' is called. It restores
+//  the initial state and releases the DC. When the program exits, 'fl_cleanup_dc_list'
+//  frees any remaining nodes in the list.
+
+struct Win_DC_List {      // linked list 
+  HWND    window;         // window handle
+  HDC     dc;             // device context handle
+  int     saved_dc;       // initial state of DC
+  Win_DC_List * next;     // pointer to next item
+};
+
+static Win_DC_List * win_DC_list = 0;
+
+void fl_save_dc( HWND w, HDC dc) {
+  Win_DC_List * t;
+  t = new Win_DC_List;
+  t->window = w;
+  t->dc = dc;
+  t->saved_dc = SaveDC(dc);
+  if (win_DC_list)
+    t->next = win_DC_list;
+  else
+    t->next = NULL;
+  win_DC_list = t;
+}
+
+void fl_release_dc(HWND w, HDC dc) {
+  Win_DC_List * t= win_DC_list;
+  Win_DC_List * prev = 0;
+  if (!t)
+    return;
+  do {
+    if (t->dc == dc) {
+      RestoreDC(dc, t->saved_dc);
+      ReleaseDC(w, dc);
+      if (!prev) {
+        win_DC_list = t->next;   // delete first item
+      } else {
+        prev->next = t->next;       // one in the middle
+      }
+      delete (t);
+      return;
+    }
+    prev = t;
+    t = t->next;
+  } while (t);
+}
+
+void fl_cleanup_dc_list(void) {          // clean up the list
+  Win_DC_List * t = win_DC_list;
+  if (!t)return;
+  do {
+    RestoreDC(t->dc, t->saved_dc);
+    ReleaseDC(t->window, t->dc);
+    win_DC_list = t->next;
+    delete (t);
+    t = win_DC_list;
+  } while(t);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/Fl_x.cxx b/Utilities/FLTK/src/Fl_x.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cde677408dc17ea78dddd054d83c5f8e7db0b55f
--- /dev/null
+++ b/Utilities/FLTK/src/Fl_x.cxx
@@ -0,0 +1,1354 @@
+//
+// "$Id$"
+//
+// X specific code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifdef WIN32
+//#  include "Fl_win32.cxx"
+#elif defined(__APPLE__)
+//#  include "Fl_mac.cxx"
+#else
+
+#  define CONSOLIDATE_MOTION 1
+/**** Define this if your keyboard lacks a backspace key... ****/
+/* #define BACKSPACE_HACK 1 */
+
+#  include <FL/Fl.H>
+#  include <FL/x.H>
+#  include <FL/Fl_Window.H>
+#  include <stdio.h>
+#  include <stdlib.h>
+#  include "flstring.h"
+#  include <unistd.h>
+#  include <sys/time.h>
+
+////////////////////////////////////////////////////////////////
+// interface to poll/select call:
+
+#  if USE_POLL
+
+#    include <poll.h>
+static pollfd *pollfds = 0;
+
+#  else
+#    if HAVE_SYS_SELECT_H
+#      include <sys/select.h>
+#    endif /* HAVE_SYS_SELECT_H */
+
+// The following #define is only needed for HP-UX 9.x and earlier:
+//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
+
+static fd_set fdsets[3];
+static int maxfd;
+#    define POLLIN 1
+#    define POLLOUT 4
+#    define POLLERR 8
+
+#  endif /* USE_POLL */
+
+static int nfds = 0;
+static int fd_array_size = 0;
+struct FD {
+#  if !USE_POLL
+  int fd;
+  short events;
+#  endif
+  void (*cb)(int, void*);
+  void* arg;
+};
+
+static FD *fd = 0;
+
+void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
+  remove_fd(n,events);
+  int i = nfds++;
+  if (i >= fd_array_size) {
+    FD *temp;
+    fd_array_size = 2*fd_array_size+1;
+
+    if (!fd) temp = (FD*)malloc(fd_array_size*sizeof(FD));
+    else temp = (FD*)realloc(fd, fd_array_size*sizeof(FD));
+
+    if (!temp) return;
+    fd = temp;
+
+#  if USE_POLL
+    pollfd *tpoll;
+
+    if (!pollfds) tpoll = (pollfd*)malloc(fd_array_size*sizeof(pollfd));
+    else tpoll = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd));
+
+    if (!tpoll) return;
+    pollfds = tpoll;
+#  endif
+  }
+  fd[i].cb = cb;
+  fd[i].arg = v;
+#  if USE_POLL
+  pollfds[i].fd = n;
+  pollfds[i].events = events;
+#  else
+  fd[i].fd = n;
+  fd[i].events = events;
+  if (events & POLLIN) FD_SET(n, &fdsets[0]);
+  if (events & POLLOUT) FD_SET(n, &fdsets[1]);
+  if (events & POLLERR) FD_SET(n, &fdsets[2]);
+  if (n > maxfd) maxfd = n;
+#  endif
+}
+
+void Fl::add_fd(int n, void (*cb)(int, void*), void* v) {
+  Fl::add_fd(n, POLLIN, cb, v);
+}
+
+void Fl::remove_fd(int n, int events) {
+  int i,j;
+  maxfd = -1; // recalculate maxfd on the fly
+  for (i=j=0; i<nfds; i++) {
+#  if USE_POLL
+    if (pollfds[i].fd == n) {
+      int e = pollfds[i].events & ~events;
+      if (!e) continue; // if no events left, delete this fd
+      pollfds[j].events = e;
+    }
+#  else
+    if (fd[i].fd == n) {
+      int e = fd[i].events & ~events;
+      if (!e) continue; // if no events left, delete this fd
+      fd[i].events = e;
+    }
+#  endif
+    if (fd[i].fd > maxfd) maxfd = fd[i].fd;
+    // move it down in the array if necessary:
+    if (j<i) {
+      fd[j] = fd[i];
+#  if USE_POLL
+      pollfds[j] = pollfds[i];
+#  endif
+    }
+    j++;
+  }
+  nfds = j;
+#  if !USE_POLL
+  if (events & POLLIN) FD_CLR(n, &fdsets[0]);
+  if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
+  if (events & POLLERR) FD_CLR(n, &fdsets[2]);
+#  endif
+}
+
+void Fl::remove_fd(int n) {
+  remove_fd(n, -1);
+}
+
+#if CONSOLIDATE_MOTION
+static Fl_Window* send_motion;
+extern Fl_Window* fl_xmousewin;
+#endif
+static bool in_a_window; // true if in any of our windows, even destroyed ones
+static void do_queued_events() {
+  in_a_window = true;
+  while (XEventsQueued(fl_display,QueuedAfterReading)) {
+    XEvent xevent;
+    XNextEvent(fl_display, &xevent);
+    fl_handle(xevent);
+  }
+  // we send FL_LEAVE only if the mouse did not enter some other window:
+  if (!in_a_window) Fl::handle(FL_LEAVE, 0);
+#if CONSOLIDATE_MOTION
+  else if (send_motion == fl_xmousewin) {
+    send_motion = 0;
+    Fl::handle(FL_MOVE, fl_xmousewin);
+  }
+#endif
+}
+
+// these pointers are set by the Fl::lock() function:
+static void nothing() {}
+void (*fl_lock_function)() = nothing;
+void (*fl_unlock_function)() = nothing;
+
+// This is never called with time_to_wait < 0.0:
+// It should return negative on error, 0 if nothing happens before
+// timeout, and >0 if any callbacks were done.
+int fl_wait(double time_to_wait) {
+
+  // OpenGL and other broken libraries call XEventsQueued
+  // unnecessarily and thus cause the file descriptor to not be ready,
+  // so we must check for already-read events:
+  if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;}
+
+#  if !USE_POLL
+  fd_set fdt[3];
+  fdt[0] = fdsets[0];
+  fdt[1] = fdsets[1];
+  fdt[2] = fdsets[2];
+#  endif
+  int n;
+
+  fl_unlock_function();
+
+  if (time_to_wait < 2147483.648) {
+#  if USE_POLL
+    n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
+#  else
+    timeval t;
+    t.tv_sec = int(time_to_wait);
+    t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec));
+    n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
+#  endif
+  } else {
+#  if USE_POLL
+    n = ::poll(pollfds, nfds, -1);
+#  else
+    n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
+#  endif
+  }
+
+  fl_lock_function();
+
+  if (n > 0) {
+    for (int i=0; i<nfds; i++) {
+#  if USE_POLL
+      if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg);
+#  else
+      int f = fd[i].fd;
+      short revents = 0;
+      if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
+      if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
+      if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
+      if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
+#  endif
+    }
+  }
+  return n;
+}
+
+// fl_ready() is just like fl_wait(0.0) except no callbacks are done:
+int fl_ready() {
+  if (XQLength(fl_display)) return 1;
+#  if USE_POLL
+  return ::poll(pollfds, nfds, 0);
+#  else
+  timeval t;
+  t.tv_sec = 0;
+  t.tv_usec = 0;
+  fd_set fdt[3];
+  fdt[0] = fdsets[0];
+  fdt[1] = fdsets[1];
+  fdt[2] = fdsets[2];
+  return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
+#  endif
+}
+
+////////////////////////////////////////////////////////////////
+
+Display *fl_display;
+Window fl_message_window;
+int fl_screen;
+XVisualInfo *fl_visual;
+Colormap fl_colormap;
+
+static Atom WM_DELETE_WINDOW;
+static Atom WM_PROTOCOLS;
+static Atom fl_MOTIF_WM_HINTS;
+static Atom TARGETS;
+static Atom CLIPBOARD;
+Atom fl_XdndAware;
+Atom fl_XdndSelection;
+Atom fl_XdndEnter;
+Atom fl_XdndTypeList;
+Atom fl_XdndPosition;
+Atom fl_XdndLeave;
+Atom fl_XdndDrop;
+Atom fl_XdndStatus;
+Atom fl_XdndActionCopy;
+Atom fl_XdndFinished;
+//Atom fl_XdndProxy;
+Atom fl_XdndURIList;
+
+
+static void fd_callback(int,void *) {
+  do_queued_events();
+}
+
+extern "C" {
+  static int io_error_handler(Display*) {
+    Fl::fatal("X I/O error");
+    return 0;
+  }
+
+  static int xerror_handler(Display* d, XErrorEvent* e) {
+    char buf1[128], buf2[128];
+    sprintf(buf1, "XRequest.%d", e->request_code);
+    XGetErrorDatabaseText(d,"",buf1,buf1,buf2,128);
+    XGetErrorText(d, e->error_code, buf1, 128);
+    Fl::warning("%s: %s 0x%lx", buf2, buf1, e->resourceid);
+    return 0;
+  }
+}
+
+void fl_open_display() {
+  if (fl_display) return;
+
+  XSetIOErrorHandler(io_error_handler);
+  XSetErrorHandler(xerror_handler);
+
+  Display *d = XOpenDisplay(0);
+  if (!d) Fl::fatal("Can't open display: %s",XDisplayName(0));
+
+  fl_open_display(d);
+}
+
+void fl_open_display(Display* d) {
+  fl_display = d;
+
+  WM_DELETE_WINDOW      = XInternAtom(d, "WM_DELETE_WINDOW",	0);
+  WM_PROTOCOLS          = XInternAtom(d, "WM_PROTOCOLS",	0);
+  fl_MOTIF_WM_HINTS     = XInternAtom(d, "_MOTIF_WM_HINTS",	0);
+  TARGETS               = XInternAtom(d, "TARGETS",		0);
+  CLIPBOARD		= XInternAtom(d, "CLIPBOARD",		0);
+  fl_XdndAware          = XInternAtom(d, "XdndAware",		0);
+  fl_XdndSelection      = XInternAtom(d, "XdndSelection",	0);
+  fl_XdndEnter          = XInternAtom(d, "XdndEnter",		0);
+  fl_XdndTypeList       = XInternAtom(d, "XdndTypeList",	0);
+  fl_XdndPosition       = XInternAtom(d, "XdndPosition",	0);
+  fl_XdndLeave          = XInternAtom(d, "XdndLeave",		0);
+  fl_XdndDrop           = XInternAtom(d, "XdndDrop",		0);
+  fl_XdndStatus         = XInternAtom(d, "XdndStatus",		0);
+  fl_XdndActionCopy     = XInternAtom(d, "XdndActionCopy",	0);
+  fl_XdndFinished       = XInternAtom(d, "XdndFinished",	0);
+  //fl_XdndProxy        = XInternAtom(d, "XdndProxy",		0);
+  fl_XdndEnter          = XInternAtom(d, "XdndEnter",		0);
+  fl_XdndURIList        = XInternAtom(d, "text/uri-list",	0);
+
+  Fl::add_fd(ConnectionNumber(d), POLLIN, fd_callback);
+
+  fl_screen = DefaultScreen(d);
+
+  fl_message_window =
+    XCreateSimpleWindow(d, RootWindow(d,fl_screen), 0,0,1,1,0, 0, 0);
+
+// construct an XVisualInfo that matches the default Visual:
+  XVisualInfo templt; int num;
+  templt.visualid = XVisualIDFromVisual(DefaultVisual(d, fl_screen));
+  fl_visual = XGetVisualInfo(d, VisualIDMask, &templt, &num);
+  fl_colormap = DefaultColormap(d, fl_screen);
+
+#if !USE_COLORMAP
+  Fl::visual(FL_RGB);
+#endif
+}
+
+void fl_close_display() {
+  Fl::remove_fd(ConnectionNumber(fl_display));
+  XCloseDisplay(fl_display);
+}
+
+int Fl::h() {
+  fl_open_display();
+  return DisplayHeight(fl_display,fl_screen);
+}
+
+int Fl::w() {
+  fl_open_display();
+  return DisplayWidth(fl_display,fl_screen);
+}
+
+void Fl::get_mouse(int &xx, int &yy) {
+  fl_open_display();
+  Window root = RootWindow(fl_display, fl_screen);
+  Window c; int mx,my,cx,cy; unsigned int mask;
+  XQueryPointer(fl_display,root,&root,&c,&mx,&my,&cx,&cy,&mask);
+  xx = mx;
+  yy = my;
+}
+
+////////////////////////////////////////////////////////////////
+// Code used for paste and DnD into the program:
+
+Fl_Widget *fl_selection_requestor;
+char *fl_selection_buffer[2];
+int fl_selection_length[2];
+int fl_selection_buffer_length[2];
+char fl_i_own_selection[2];
+
+// Call this when a "paste" operation happens:
+void Fl::paste(Fl_Widget &receiver, int clipboard) {
+  if (fl_i_own_selection[clipboard]) {
+    // We already have it, do it quickly without window server.
+    // Notice that the text is clobbered if set_selection is
+    // called in response to FL_PASTE!
+    Fl::e_text = fl_selection_buffer[clipboard];
+    Fl::e_length = fl_selection_length[clipboard];
+    if (!Fl::e_text) Fl::e_text = (char *)"";
+    receiver.handle(FL_PASTE);
+    return;
+  }
+  // otherwise get the window server to return it:
+  fl_selection_requestor = &receiver;
+  Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
+  XConvertSelection(fl_display, property, XA_STRING, property,
+		    fl_xid(Fl::first_window()), fl_event_time);
+}
+
+Window fl_dnd_source_window;
+Atom *fl_dnd_source_types; // null-terminated list of data types being supplied
+Atom fl_dnd_type;
+Atom fl_dnd_source_action;
+Atom fl_dnd_action;
+
+void fl_sendClientMessage(Window window, Atom message,
+                                 unsigned long d0,
+                                 unsigned long d1=0,
+                                 unsigned long d2=0,
+                                 unsigned long d3=0,
+                                 unsigned long d4=0)
+{
+  XEvent e;
+  e.xany.type = ClientMessage;
+  e.xany.window = window;
+  e.xclient.message_type = message;
+  e.xclient.format = 32;
+  e.xclient.data.l[0] = (long)d0;
+  e.xclient.data.l[1] = (long)d1;
+  e.xclient.data.l[2] = (long)d2;
+  e.xclient.data.l[3] = (long)d3;
+  e.xclient.data.l[4] = (long)d4;
+  XSendEvent(fl_display, window, 0, 0, &e);
+}
+
+////////////////////////////////////////////////////////////////
+// Code for copying to clipboard and DnD out of the program:
+
+void Fl::copy(const char *stuff, int len, int clipboard) {
+  if (!stuff || len<0) return;
+  if (len+1 > fl_selection_buffer_length[clipboard]) {
+    delete[] fl_selection_buffer[clipboard];
+    fl_selection_buffer[clipboard] = new char[len+100];
+    fl_selection_buffer_length[clipboard] = len+100;
+  }
+  memcpy(fl_selection_buffer[clipboard], stuff, len);
+  fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
+  fl_selection_length[clipboard] = len;
+  fl_i_own_selection[clipboard] = 1;
+  Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
+  XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
+}
+
+////////////////////////////////////////////////////////////////
+
+const XEvent* fl_xevent; // the current x event
+ulong fl_event_time; // the last timestamp from an x event
+
+char fl_key_vector[32]; // used by Fl::get_key()
+
+// Record event mouse position and state from an XEvent:
+
+static int px, py;
+static ulong ptime;
+
+static void set_event_xy() {
+#  if CONSOLIDATE_MOTION
+  send_motion = 0;
+#  endif
+  Fl::e_x_root  = fl_xevent->xbutton.x_root;
+  Fl::e_x       = fl_xevent->xbutton.x;
+  Fl::e_y_root  = fl_xevent->xbutton.y_root;
+  Fl::e_y       = fl_xevent->xbutton.y;
+  Fl::e_state   = fl_xevent->xbutton.state << 16;
+  fl_event_time = fl_xevent->xbutton.time;
+#  ifdef __sgi
+  // get the meta key off PC keyboards:
+  if (fl_key_vector[18]&0x18) Fl::e_state |= FL_META;
+#  endif
+  // turn off is_click if enough time or mouse movement has passed:
+  if (abs(Fl::e_x_root-px)+abs(Fl::e_y_root-py) > 3 ||
+      fl_event_time >= ptime+1000)
+    Fl::e_is_click = 0;
+}
+
+// if this is same event as last && is_click, increment click count:
+static inline void checkdouble() {
+  if (Fl::e_is_click == Fl::e_keysym)
+    Fl::e_clicks++;
+  else {
+    Fl::e_clicks = 0;
+    Fl::e_is_click = Fl::e_keysym;
+  }
+  px = Fl::e_x_root;
+  py = Fl::e_y_root;
+  ptime = fl_event_time;
+}
+
+static Fl_Window* resize_bug_fix;
+
+extern "C" {
+  static Bool fake_keyup_test(Display*, XEvent* event, char* previous) {
+     return
+      event->type == KeyPress &&
+      event->xkey.keycode == ((XKeyEvent*)previous)->keycode &&
+      event->xkey.time == ((XKeyEvent*)previous)->time;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+static char unknown[] = "<unknown>";
+const int unknown_len = 10;
+
+int fl_handle(const XEvent& thisevent)
+{
+  XEvent xevent = thisevent;
+  fl_xevent = &thisevent;
+  Window xid = xevent.xany.window;
+
+  switch (xevent.type) {
+
+  case KeymapNotify:
+    memcpy(fl_key_vector, xevent.xkeymap.key_vector, 32);
+    return 0;
+
+  case MappingNotify:
+    XRefreshKeyboardMapping((XMappingEvent*)&xevent.xmapping);
+    return 0;
+
+  case SelectionNotify: {
+    if (!fl_selection_requestor) return 0;
+    static unsigned char* buffer;
+    if (buffer) {XFree(buffer); buffer = 0;}
+    long bytesread = 0;
+    if (fl_xevent->xselection.property) for (;;) {
+      // The Xdnd code pastes 64K chunks together, possibly to avoid
+      // bugs in X servers, or maybe to avoid an extra round-trip to
+      // get the property length.  I copy this here:
+      Atom actual; int format; unsigned long count, remaining;
+      unsigned char* portion;
+      if (XGetWindowProperty(fl_display,
+			     fl_xevent->xselection.requestor,
+			     fl_xevent->xselection.property,
+			     bytesread/4, 65536, 1, 0,
+			     &actual, &format, &count, &remaining,
+			     &portion)) break; // quit on error
+      if (bytesread) { // append to the accumulated buffer
+	buffer = (unsigned char*)realloc(buffer, bytesread+count*format/8+remaining);
+	memcpy(buffer+bytesread, portion, count*format/8);
+	XFree(portion);
+      } else {	// Use the first section without moving the memory:
+	buffer = portion;
+      }
+      bytesread += count*format/8;
+      if (!remaining) break;
+    }
+    Fl::e_text = buffer ? (char*)buffer : (char *)"";
+    Fl::e_length = bytesread;
+    int old_event = Fl::e_number;
+    fl_selection_requestor->handle(Fl::e_number = FL_PASTE);
+    Fl::e_number = old_event;
+    // Detect if this paste is due to Xdnd by the property name (I use
+    // XA_SECONDARY for that) and send an XdndFinished message. It is not
+    // clear if this has to be delayed until now or if it can be done
+    // immediatly after calling XConvertSelection.
+    if (fl_xevent->xselection.property == XA_SECONDARY &&
+	fl_dnd_source_window) {
+      fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished,
+                           fl_xevent->xselection.requestor);
+      fl_dnd_source_window = 0; // don't send a second time
+    }
+    return 1;}
+
+  case SelectionClear: {
+    int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
+    fl_i_own_selection[clipboard] = 0;
+    return 1;}
+
+  case SelectionRequest: {
+    XSelectionEvent e;
+    e.type = SelectionNotify;
+    e.requestor = fl_xevent->xselectionrequest.requestor;
+    e.selection = fl_xevent->xselectionrequest.selection;
+    int clipboard = e.selection == CLIPBOARD;
+    e.target = fl_xevent->xselectionrequest.target;
+    e.time = fl_xevent->xselectionrequest.time;
+    e.property = fl_xevent->xselectionrequest.property;
+    if (e.target == TARGETS) {
+      Atom a = XA_STRING;
+      XChangeProperty(fl_display, e.requestor, e.property,
+		      XA_ATOM, sizeof(Atom)*8, 0, (unsigned char*)&a,
+		      sizeof(Atom));
+    } else if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) {
+      XChangeProperty(fl_display, e.requestor, e.property,
+		      e.target, 8, 0,
+		      (unsigned char *)fl_selection_buffer[clipboard],
+		      fl_selection_length[clipboard]);
+    } else {
+//    char* x = XGetAtomName(fl_display,e.target);
+//    fprintf(stderr,"selection request of %s\n",x);
+//    XFree(x);
+      e.property = 0;
+    }
+    XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
+    return 1;
+
+  // events where interesting window id is in a different place:
+  case CirculateNotify:
+  case CirculateRequest:
+  case ConfigureNotify:
+  case ConfigureRequest:
+  case CreateNotify:
+  case DestroyNotify:
+  case GravityNotify:
+  case MapNotify:
+  case MapRequest:
+  case ReparentNotify:
+  case UnmapNotify:
+    xid = xevent.xmaprequest.window;
+    break;
+  }
+
+  int event = 0;
+  Fl_Window* window = fl_find(xid);
+
+  if (window) switch (xevent.type) {
+
+  case ClientMessage: {
+    Atom message = fl_xevent->xclient.message_type;
+    const long* data = fl_xevent->xclient.data.l;
+    if ((Atom)(data[0]) == WM_DELETE_WINDOW) {
+      event = FL_CLOSE;
+    } else if (message == fl_XdndEnter) {
+      fl_xmousewin = window;
+      in_a_window = true;
+      fl_dnd_source_window = data[0];
+      // version number is data[1]>>24
+//      printf("XdndEnter, version %ld\n", data[1] >> 24);
+      if (data[1]&1) {
+	// get list of data types:
+	Atom actual; int format; unsigned long count, remaining;
+	unsigned char *buffer = 0;
+	XGetWindowProperty(fl_display, fl_dnd_source_window, fl_XdndTypeList,
+			   0, 0x8000000L, False, XA_ATOM, &actual, &format,
+			   &count, &remaining, &buffer);
+	if (actual != XA_ATOM || format != 32 || count<4 || !buffer)
+	  goto FAILED;
+	delete [] fl_dnd_source_types;
+	fl_dnd_source_types = new Atom[count+1];
+	for (unsigned i = 0; i < count; i++)
+	  fl_dnd_source_types[i] = ((Atom*)buffer)[i];
+	fl_dnd_source_types[count] = 0;
+      } else {
+      FAILED:
+	// less than four data types, or if the above messes up:
+	if (!fl_dnd_source_types) fl_dnd_source_types = new Atom[4];
+	fl_dnd_source_types[0] = data[2];
+	fl_dnd_source_types[1] = data[3];
+	fl_dnd_source_types[2] = data[4];
+	fl_dnd_source_types[3] = 0;
+      }
+
+      // Loop through the source types and pick the first text type...
+      int i;
+
+      for (i = 0; fl_dnd_source_types[i]; i ++)
+      {
+//        printf("fl_dnd_source_types[%d] = %ld (%s)\n", i,
+//	       fl_dnd_source_types[i],
+//	       XGetAtomName(fl_display, fl_dnd_source_types[i]));
+
+        if (!strncmp(XGetAtomName(fl_display, fl_dnd_source_types[i]),
+	             "text/", 5))
+	  break;
+      }
+
+      if (fl_dnd_source_types[i])
+        fl_dnd_type = fl_dnd_source_types[i];
+      else
+        fl_dnd_type = fl_dnd_source_types[0];
+
+      event = FL_DND_ENTER;
+      Fl::e_text = unknown;
+      Fl::e_length = unknown_len;
+      break;
+
+    } else if (message == fl_XdndPosition) {
+      fl_xmousewin = window;
+      in_a_window = true;
+      fl_dnd_source_window = data[0];
+      Fl::e_x_root = data[2]>>16;
+      Fl::e_y_root = data[2]&0xFFFF;
+      if (window) {
+	Fl::e_x = Fl::e_x_root-window->x();
+	Fl::e_y = Fl::e_y_root-window->y();
+      }
+      fl_event_time = data[3];
+      fl_dnd_source_action = data[4];
+      fl_dnd_action = fl_XdndActionCopy;
+      Fl::e_text = unknown;
+      Fl::e_length = unknown_len;
+      int accept = Fl::handle(FL_DND_DRAG, window);
+      fl_sendClientMessage(data[0], fl_XdndStatus,
+                           fl_xevent->xclient.window,
+                           accept ? 1 : 0,
+                           0, // used for xy rectangle to not send position inside
+                           0, // used for width+height of rectangle
+                           accept ? fl_dnd_action : None);
+      return 1;
+
+    } else if (message == fl_XdndLeave) {
+      fl_dnd_source_window = 0; // don't send a finished message to it
+      event = FL_DND_LEAVE;
+      Fl::e_text = unknown;
+      Fl::e_length = unknown_len;
+      break;
+
+    } else if (message == fl_XdndDrop) {
+      fl_xmousewin = window;
+      in_a_window = true;
+      fl_dnd_source_window = data[0];
+      fl_event_time = data[2];
+      Window to_window = fl_xevent->xclient.window;
+      Fl::e_text = unknown;
+      Fl::e_length = unknown_len;
+      if (Fl::handle(FL_DND_RELEASE, window)) {
+	fl_selection_requestor = Fl::belowmouse();
+	XConvertSelection(fl_display, fl_XdndSelection,
+			  fl_dnd_type, XA_SECONDARY,
+			  to_window, fl_event_time);
+      } else {
+	// Send the finished message if I refuse the drop.
+	// It is not clear whether I can just send finished always,
+	// or if I have to wait for the SelectionNotify event as the
+	// code is currently doing.
+	fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished, to_window);
+	fl_dnd_source_window = 0;
+      }
+      return 1;
+
+    }
+    break;}
+
+  case UnmapNotify:
+    event = FL_HIDE;
+    break;
+
+  case Expose:
+    Fl_X::i(window)->wait_for_expose = 0;
+#  if 0
+    // try to keep windows on top even if WM_TRANSIENT_FOR does not work:
+    // opaque move/resize window managers do not like this, so I disabled it.
+    if (Fl::first_window()->non_modal() && window != Fl::first_window())
+      Fl::first_window()->show();
+#  endif
+
+  case GraphicsExpose:
+    window->damage(FL_DAMAGE_EXPOSE, xevent.xexpose.x, xevent.xexpose.y,
+		   xevent.xexpose.width, xevent.xexpose.height);
+    return 1;
+
+  case FocusIn:
+    event = FL_FOCUS;
+    break;
+
+  case FocusOut:
+    event = FL_UNFOCUS;
+    break;
+
+  case KeyPress:
+  case KeyRelease: {
+  KEYPRESS:
+    int keycode = xevent.xkey.keycode;
+    fl_key_vector[keycode/8] |= (1 << (keycode%8));
+    static char buffer[21];
+    int len;
+    KeySym keysym;
+    if (xevent.type == KeyPress) {
+      event = FL_KEYDOWN;
+      //static XComposeStatus compose;
+      len = XLookupString((XKeyEvent*)&(xevent.xkey),
+	                  buffer, 20, &keysym, 0/*&compose*/);
+      if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets
+	// force it to type a character (not sure if this ever is needed):
+	if (!len) {buffer[0] = char(keysym); len = 1;}
+	// ignore all effects of shift on the keysyms, which makes it a lot
+	// easier to program shortcuts and is Windoze-compatable:
+	keysym = XKeycodeToKeysym(fl_display, keycode, 0);
+      }
+      // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not
+      //      set until set_event_xy() is called later...
+      if ((xevent.xkey.state & ControlMask) && keysym == '-') buffer[0] = 0x1f; // ^_
+      buffer[len] = 0;
+      Fl::e_text = buffer;
+      Fl::e_length = len;
+    } else {
+      // Stupid X sends fake key-up events when a repeating key is held
+      // down, probably due to some back compatability problem. Fortunately
+      // we can detect this because the repeating KeyPress event is in
+      // the queue, get it and execute it instead:
+      XEvent temp;
+      if (XCheckIfEvent(fl_display,&temp,fake_keyup_test,(char*)(&xevent))){
+	xevent = temp;
+	goto KEYPRESS;
+      }
+      event = FL_KEYUP;
+      fl_key_vector[keycode/8] &= ~(1 << (keycode%8));
+      // keyup events just get the unshifted keysym:
+      keysym = XKeycodeToKeysym(fl_display, keycode, 0);
+    }
+#  ifdef __sgi
+    // You can plug a microsoft keyboard into an sgi but the extra shift
+    // keys are not translated.  Make them translate like XFree86 does:
+    if (!keysym) switch(keycode) {
+    case 147: keysym = FL_Meta_L; break;
+    case 148: keysym = FL_Meta_R; break;
+    case 149: keysym = FL_Menu; break;
+    }
+#  endif
+#  if BACKSPACE_HACK
+    // Attempt to fix keyboards that send "delete" for the key in the
+    // upper-right corner of the main keyboard.  But it appears that
+    // very few of these remain?
+    static int got_backspace;
+    if (!got_backspace) {
+      if (keysym == FL_Delete) keysym = FL_BackSpace;
+      else if (keysym == FL_BackSpace) got_backspace = 1;
+    }
+#  endif
+    // We have to get rid of the XK_KP_function keys, because they are
+    // not produced on Windoze and thus case statements tend not to check
+    // for them.  There are 15 of these in the range 0xff91 ... 0xff9f
+    if (keysym >= 0xff91 && keysym <= 0xff9f) {
+      // Map keypad keysym to character or keysym depending on
+      // numlock state...
+      unsigned long keysym1 = XKeycodeToKeysym(fl_display, keycode, 1);
+      if ((xevent.xkey.state & Mod2Mask) &&
+          (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))) {
+	// Store ASCII numeric keypad value...
+	keysym = keysym1 | FL_KP;
+	buffer[0] = char(keysym1) & 0x7F;
+	len = 1;
+      } else {
+	// Map keypad to special key...
+	static const unsigned short table[15] = {
+	  FL_F+1, FL_F+2, FL_F+3, FL_F+4,
+	  FL_Home, FL_Left, FL_Up, FL_Right,
+	  FL_Down, FL_Page_Up, FL_Page_Down, FL_End,
+	  0xff0b/*XK_Clear*/, FL_Insert, FL_Delete};
+	keysym = table[keysym-0xff91];
+      }
+    }
+    Fl::e_keysym = int(keysym);
+    set_event_xy();
+    Fl::e_is_click = 0;
+    break;}
+
+  case ButtonPress:
+    Fl::e_keysym = FL_Button + xevent.xbutton.button;
+    set_event_xy();
+    if (xevent.xbutton.button == Button4) {
+      Fl::e_dy = -1; // Up
+      event = FL_MOUSEWHEEL;
+    } else if (xevent.xbutton.button == Button5) {
+      Fl::e_dy = +1; // Down
+      event = FL_MOUSEWHEEL;
+    } else {
+      Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1));
+      event = FL_PUSH;
+      checkdouble();
+    }
+
+    fl_xmousewin = window;
+    in_a_window = true;
+    break;
+
+  case MotionNotify:
+    set_event_xy();
+#  if CONSOLIDATE_MOTION
+    send_motion = fl_xmousewin = window;
+    in_a_window = true;
+    return 0;
+#  else
+    event = FL_MOVE;
+    fl_xmousewin = window;
+    in_a_window = true;
+    break;
+#  endif
+
+  case ButtonRelease:
+    Fl::e_keysym = FL_Button + xevent.xbutton.button;
+    set_event_xy();
+    Fl::e_state &= ~(FL_BUTTON1 << (xevent.xbutton.button-1));
+    if (xevent.xbutton.button == Button4 ||
+        xevent.xbutton.button == Button5) return 0;
+    event = FL_RELEASE;
+
+    fl_xmousewin = window;
+    in_a_window = true;
+    break;
+
+  case EnterNotify:
+    if (xevent.xcrossing.detail == NotifyInferior) break;
+    // XInstallColormap(fl_display, Fl_X::i(window)->colormap);
+    set_event_xy();
+    Fl::e_state = xevent.xcrossing.state << 16;
+    event = FL_ENTER;
+
+    fl_xmousewin = window;
+    in_a_window = true;
+    break;
+
+  case LeaveNotify:
+    if (xevent.xcrossing.detail == NotifyInferior) break;
+    set_event_xy();
+    Fl::e_state = xevent.xcrossing.state << 16;
+    fl_xmousewin = 0;
+    in_a_window = false; // make do_queued_events produce FL_LEAVE event
+    return 0;
+
+  // We cannot rely on the x,y position in the configure notify event.
+  // I now think this is an unavoidable problem with X: it is impossible
+  // for a window manager to prevent the "real" notify event from being
+  // sent when it resizes the contents, even though it can send an
+  // artificial event with the correct position afterwards (and some
+  // window managers do not send this fake event anyway)
+  // So anyway, do a round trip to find the correct x,y:
+  case MapNotify:
+    event = FL_SHOW;
+
+  case ConfigureNotify: {
+    if (window->parent()) break; // ignore child windows
+
+    // figure out where OS really put window
+    XWindowAttributes actual;
+    XGetWindowAttributes(fl_display, fl_xid(window), &actual);
+    Window cr; int X, Y, W = actual.width, H = actual.height;
+    XTranslateCoordinates(fl_display, fl_xid(window), actual.root,
+                          0, 0, &X, &Y, &cr);
+
+    // tell Fl_Window about it and set flag to prevent echoing:
+    resize_bug_fix = window;
+    window->resize(X, Y, W, H);
+    break; // allow add_handler to do something too
+    }
+
+  case ReparentNotify: {
+    int xpos, ypos;
+    Window junk;
+
+    //ReparentNotify gives the new position of the window relative to
+    //the new parent. FLTK cares about the position on the root window.
+    XTranslateCoordinates(fl_display, xevent.xreparent.parent,
+			  XRootWindow(fl_display, fl_screen),
+			  xevent.xreparent.x, xevent.xreparent.y,
+			  &xpos, &ypos, &junk);
+
+    // tell Fl_Window about it and set flag to prevent echoing:
+    resize_bug_fix = window;
+    window->position(xpos, ypos);
+    break;
+    }
+  }
+
+  return Fl::handle(event, window);
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Window::resize(int X,int Y,int W,int H) {
+  int is_a_move = (X != x() || Y != y());
+  int is_a_resize = (W != w() || H != h());
+  int resize_from_program = (this != resize_bug_fix);
+  if (!resize_from_program) resize_bug_fix = 0;
+  if (is_a_move && resize_from_program) set_flag(FL_FORCE_POSITION);
+  else if (!is_a_resize && !is_a_move) return;
+  if (is_a_resize) {
+    Fl_Group::resize(X,Y,W,H);
+    if (shown()) {redraw(); i->wait_for_expose = 1;}
+  } else {
+    x(X); y(Y);
+  }
+
+  if (resize_from_program && is_a_resize && !resizable()) {
+    size_range(w(), h(), w(), h());
+  }
+
+  if (resize_from_program && shown()) {
+    if (is_a_resize) {
+      if (!resizable()) size_range(w(),h(),w(),h());
+      if (is_a_move) {
+	XMoveResizeWindow(fl_display, i->xid, X, Y, W>0 ? W : 1, H>0 ? H : 1);
+      } else {
+	XResizeWindow(fl_display, i->xid, W>0 ? W : 1, H>0 ? H : 1);
+      }
+    } else
+      XMoveWindow(fl_display, i->xid, X, Y);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// A subclass of Fl_Window may call this to associate an X window it
+// creates with the Fl_Window:
+
+void fl_fix_focus(); // in Fl.cxx
+
+Fl_X* Fl_X::set_xid(Fl_Window* win, Window winxid) {
+  Fl_X* xp = new Fl_X;
+  xp->xid = winxid;
+  xp->other_xid = 0;
+  xp->setwindow(win);
+  xp->next = Fl_X::first;
+  xp->region = 0;
+  xp->wait_for_expose = 1;
+  xp->backbuffer_bad = 1;
+  Fl_X::first = xp;
+  if (win->modal()) {Fl::modal_ = win; fl_fix_focus();}
+  return xp;
+}
+
+// More commonly a subclass calls this, because it hides the really
+// ugly parts of X and sets all the stuff for a window that is set
+// normally.  The global variables like fl_show_iconic are so that
+// subclasses of *that* class may change the behavior...
+
+char fl_show_iconic;	// hack for iconize()
+int fl_background_pixel = -1; // hack to speed up bg box drawing
+int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
+
+static const int childEventMask = ExposureMask;
+
+static const int XEventMask =
+ExposureMask|StructureNotifyMask
+|KeyPressMask|KeyReleaseMask|KeymapStateMask|FocusChangeMask
+|ButtonPressMask|ButtonReleaseMask
+|EnterWindowMask|LeaveWindowMask
+|PointerMotionMask;
+
+void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
+{
+  Fl_Group::current(0); // get rid of very common user bug: forgot end()
+
+  int X = win->x();
+  int Y = win->y();
+  int W = win->w();
+  if (W <= 0) W = 1; // X don't like zero...
+  int H = win->h();
+  if (H <= 0) H = 1; // X don't like zero...
+  if (!win->parent() && !Fl::grab()) {
+    // center windows in case window manager does not do anything:
+#ifdef FL_CENTER_WINDOWS
+    if (!(win->flags() & Fl_Window::FL_FORCE_POSITION)) {
+      win->x(X = scr_x+(scr_w-W)/2);
+      win->y(Y = scr_y+(scr_h-H)/2);
+    }
+#endif // FL_CENTER_WINDOWS
+
+    // force the window to be on-screen.  Usually the X window manager
+    // does this, but a few don't, so we do it here for consistency:
+    int scr_x, scr_y, scr_w, scr_h;
+    Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y);
+
+    if (win->border()) {
+      // ensure border is on screen:
+      // (assumme extremely minimal dimensions for this border)
+      const int top = 20;
+      const int left = 1;
+      const int right = 1;
+      const int bottom = 1;
+      if (X+W+right > scr_x+scr_w) X = scr_x+scr_w-right-W;
+      if (X-left < scr_x) X = scr_x+left;
+      if (Y+H+bottom > scr_y+scr_h) Y = scr_y+scr_h-bottom-H;
+      if (Y-top < scr_y) Y = scr_y+top;
+    }
+    // now insure contents are on-screen (more important than border):
+    if (X+W > scr_x+scr_w) X = scr_x+scr_w-W;
+    if (X < scr_x) X = scr_x;
+    if (Y+H > scr_y+scr_h) Y = scr_y+scr_h-H;
+    if (Y < scr_y) Y = scr_y;
+  }
+
+  ulong root = win->parent() ?
+    fl_xid(win->window()) : RootWindow(fl_display, fl_screen);
+
+  XSetWindowAttributes attr;
+  int mask = CWBorderPixel|CWColormap|CWEventMask|CWBitGravity;
+  attr.event_mask = win->parent() ? childEventMask : XEventMask;
+  attr.colormap = colormap;
+  attr.border_pixel = 0;
+  attr.bit_gravity = 0; // StaticGravity;
+  if (win->override()) {
+    attr.override_redirect = 1;
+    attr.save_under = 1;
+    mask |= CWOverrideRedirect | CWSaveUnder;
+  } else attr.override_redirect = 0;
+  if (Fl::grab()) {
+    attr.save_under = 1; mask |= CWSaveUnder;
+    if (!win->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;}
+  }
+  if (fl_background_pixel >= 0) {
+    attr.background_pixel = fl_background_pixel;
+    fl_background_pixel = -1;
+    mask |= CWBackPixel;
+  }
+
+  Fl_X* xp =
+    set_xid(win, XCreateWindow(fl_display,
+			       root,
+			       X, Y, W, H,
+			       0, // borderwidth
+			       visual->depth,
+			       InputOutput,
+			       visual->visual,
+			       mask, &attr));
+  int showit = 1;
+
+  if (!win->parent() && !attr.override_redirect) {
+    // Communicate all kinds 'o junk to the X Window Manager:
+
+    win->label(win->label(), win->iconlabel());
+
+    XChangeProperty(fl_display, xp->xid, WM_PROTOCOLS,
+ 		    XA_ATOM, 32, 0, (uchar*)&WM_DELETE_WINDOW, 1);
+
+    // send size limits and border:
+    xp->sendxjunk();
+
+    // set the class property, which controls the icon used:
+    if (win->xclass()) {
+      char buffer[1024];
+      char *p; const char *q;
+      // truncate on any punctuation, because they break XResource lookup:
+      for (p = buffer, q = win->xclass(); isalnum(*q)||(*q&128);) *p++ = *q++;
+      *p++ = 0;
+      // create the capitalized version:
+      q = buffer;
+      *p = toupper(*q++); if (*p++ == 'X') *p++ = toupper(*q++);
+      while ((*p++ = *q++));
+      XChangeProperty(fl_display, xp->xid, XA_WM_CLASS, XA_STRING, 8, 0,
+		      (unsigned char *)buffer, p-buffer-1);
+    }
+
+    if (win->non_modal() && xp->next && !fl_disable_transient_for) {
+      // find some other window to be "transient for":
+      Fl_Window* wp = xp->next->w;
+      while (wp->parent()) wp = wp->window();
+      XSetTransientForHint(fl_display, xp->xid, fl_xid(wp));
+      if (!wp->visible()) showit = 0; // guess that wm will not show it
+    }
+   
+    // Make sure that borderless windows do not show in the task bar
+    if (!win->border()) {
+      Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0);
+      Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_SKIP_TASKBAR", 0);
+      XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32, 
+          PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1);
+    }
+
+    // Make it receptive to DnD:
+    long version = 4;
+    XChangeProperty(fl_display, xp->xid, fl_XdndAware,
+		    XA_ATOM, sizeof(int)*8, 0, (unsigned char*)&version, 1);
+
+    XWMHints *hints = XAllocWMHints();
+    hints->input = True;
+    hints->flags = InputHint;
+    if (fl_show_iconic) {
+      hints->flags |= StateHint;
+      hints->initial_state = IconicState;
+      fl_show_iconic = 0;
+      showit = 0;
+    }
+    if (win->icon()) {
+      hints->icon_pixmap = (Pixmap)win->icon();
+      hints->flags       |= IconPixmapHint;
+    }
+    XSetWMHints(fl_display, xp->xid, hints);
+    XFree(hints);
+  }
+
+  XMapWindow(fl_display, xp->xid);
+  if (showit) {
+    win->set_visible();
+    int old_event = Fl::e_number;
+    win->handle(Fl::e_number = FL_SHOW); // get child windows to appear
+    Fl::e_number = old_event;
+    win->redraw();
+  }
+}
+
+////////////////////////////////////////////////////////////////
+// Send X window stuff that can be changed over time:
+
+void Fl_X::sendxjunk() {
+  if (w->parent() || w->override()) return; // it's not a window manager window!
+
+  if (!w->size_range_set) { // default size_range based on resizable():
+    if (w->resizable()) {
+      Fl_Widget *o = w->resizable();
+      int minw = o->w(); if (minw > 100) minw = 100;
+      int minh = o->h(); if (minh > 100) minh = 100;
+      w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
+    } else {
+      w->size_range(w->w(), w->h(), w->w(), w->h());
+    }
+    return; // because this recursively called here
+  }
+
+  XSizeHints *hints = XAllocSizeHints();
+  // memset(&hints, 0, sizeof(hints)); jreiser suggestion to fix purify?
+  hints->min_width = w->minw;
+  hints->min_height = w->minh;
+  hints->max_width = w->maxw;
+  hints->max_height = w->maxh;
+  hints->width_inc = w->dw;
+  hints->height_inc = w->dh;
+  hints->win_gravity = StaticGravity;
+
+  // see the file /usr/include/X11/Xm/MwmUtil.h:
+  // fill all fields to avoid bugs in kwm and perhaps other window managers:
+  // 0, MWM_FUNC_ALL, MWM_DECOR_ALL
+  long prop[5] = {0, 1, 1, 0, 0};
+
+  if (hints->min_width != hints->max_width ||
+      hints->min_height != hints->max_height) { // resizable
+    hints->flags = PMinSize|PWinGravity;
+    if (hints->max_width >= hints->min_width ||
+	hints->max_height >= hints->min_height) {
+      hints->flags = PMinSize|PMaxSize|PWinGravity;
+      // unfortunately we can't set just one maximum size.  Guess a
+      // value for the other one.  Some window managers will make the
+      // window fit on screen when maximized, others will put it off screen:
+      if (hints->max_width < hints->min_width) hints->max_width = Fl::w();
+      if (hints->max_height < hints->min_height) hints->max_height = Fl::h();
+    }
+    if (hints->width_inc && hints->height_inc) hints->flags |= PResizeInc;
+    if (w->aspect) {
+      // stupid X!  It could insist that the corner go on the
+      // straight line between min and max...
+      hints->min_aspect.x = hints->max_aspect.x = hints->min_width;
+      hints->min_aspect.y = hints->max_aspect.y = hints->min_height;
+      hints->flags |= PAspect;
+    }
+  } else { // not resizable:
+    hints->flags = PMinSize|PMaxSize|PWinGravity;
+    prop[0] = 1; // MWM_HINTS_FUNCTIONS
+    prop[1] = 1|2|16; // MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE
+  }
+
+  if (w->flags() & Fl_Window::FL_FORCE_POSITION) {
+    hints->flags |= USPosition;
+    hints->x = w->x();
+    hints->y = w->y();
+  }
+
+  if (!w->border()) {
+    prop[0] |= 2; // MWM_HINTS_DECORATIONS
+    prop[2] = 0; // no decorations
+  }
+
+  XSetWMNormalHints(fl_display, xid, hints);
+  XChangeProperty(fl_display, xid,
+		  fl_MOTIF_WM_HINTS, fl_MOTIF_WM_HINTS,
+		  32, 0, (unsigned char *)prop, 5);
+  XFree(hints);
+}
+
+void Fl_Window::size_range_() {
+  size_range_set = 1;
+  if (shown()) i->sendxjunk();
+}
+
+////////////////////////////////////////////////////////////////
+
+// returns pointer to the filename, or null if name ends with '/'
+const char *fl_filename_name(const char *name) {
+  const char *p,*q;
+  if (!name) return (0);
+  for (p=q=name; *p;) if (*p++ == '/') q = p;
+  return q;
+}
+
+void Fl_Window::label(const char *name,const char *iname) {
+  Fl_Widget::label(name);
+  iconlabel_ = iname;
+  if (shown() && !parent()) {
+    if (!name) name = "";
+    XChangeProperty(fl_display, i->xid, XA_WM_NAME,
+		    XA_STRING, 8, 0, (uchar*)name, strlen(name));
+    if (!iname) iname = fl_filename_name(name);
+    XChangeProperty(fl_display, i->xid, XA_WM_ICON_NAME, 
+		    XA_STRING, 8, 0, (uchar*)iname, strlen(iname));
+  }
+}
+
+////////////////////////////////////////////////////////////////
+// Implement the virtual functions for the base Fl_Window class:
+
+// If the box is a filled rectangle, we can make the redisplay *look*
+// faster by using X's background pixel erasing.  We can make it
+// actually *be* faster by drawing the frame only, this is done by
+// setting fl_boxcheat, which is seen by code in fl_drawbox.cxx:
+//
+// On XFree86 (and prehaps all X's) this has a problem if the window
+// is resized while a save-behind window is atop it.  The previous
+// contents are restored to the area, but this assummes the area
+// is cleared to background color.  So this is disabled in this version.
+// Fl_Window *fl_boxcheat;
+static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);}
+
+void Fl_Window::show() {
+  image(Fl::scheme_bg_);
+  if (Fl::scheme_bg_) {
+    labeltype(FL_NORMAL_LABEL);
+    align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  } else {
+    labeltype(FL_NO_LABEL);
+  }
+  if (!shown()) {
+    fl_open_display();
+    if (can_boxcheat(box())) fl_background_pixel = int(fl_xpixel(color()));
+    Fl_X::make_xid(this);
+  } else {
+    XMapRaised(fl_display, i->xid);
+  }
+}
+
+Window fl_window;
+Fl_Window *Fl_Window::current_;
+GC fl_gc;
+
+// make X drawing go into this window (called by subclass flush() impl.)
+void Fl_Window::make_current() {
+  static GC gc;	// the GC used by all X windows
+  if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0);
+  fl_window = i->xid;
+  fl_gc = gc;
+  current_ = this;
+  fl_clip_region(0);
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/allfiles.xbm b/Utilities/FLTK/src/allfiles.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..26373b60b12b5c5e0f48786a1fb71d13edb0dcb9
--- /dev/null
+++ b/Utilities/FLTK/src/allfiles.xbm
@@ -0,0 +1,6 @@
+#define allfiles_width 16
+#define allfiles_height 16
+static unsigned char allfiles_bits[] = {
+   0xfc, 0x3f, 0x04, 0x20, 0x04, 0x20, 0x04, 0x20, 0x84, 0x21, 0xa4, 0x25,
+   0xc4, 0x23, 0xf4, 0x2f, 0xf4, 0x2f, 0xc4, 0x23, 0xa4, 0x25, 0x84, 0x21,
+   0x04, 0x20, 0x04, 0x20, 0x04, 0x20, 0xfc, 0x3f};
diff --git a/Utilities/FLTK/src/cmap.cxx b/Utilities/FLTK/src/cmap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..12f477abf764702e7cb25b462549d018a06783e4
--- /dev/null
+++ b/Utilities/FLTK/src/cmap.cxx
@@ -0,0 +1,179 @@
+//
+// "$Id$"
+//
+// Colormap generation program for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@easysw.com".
+//
+
+// This program produces the contents of "fl_cmap.h" as stdout
+
+// #include <gl/gl.h>
+#include <stdio.h>
+
+// This table is initialized with color values I got by reading the
+// colormap on an IRIX 4.3 machine:
+
+// "full intensity colors" have been turned down some to make white
+// background less intense by default.  The hope is that this will make
+// fltk programs more friendly on color-adjusted screens.  If you want
+// pure colors you should get them out of the colormap.
+
+//#define III 244 // maximum intensity of the basic colors
+
+// that results in errors and unshared colormap entries, so full intensity:
+#define III 255 // maximum intensity of the basic colors
+
+static short cmap[256][3] = {
+// 3-bit colormap:
+  {  0,  0,  0},	// black
+  {III,  0,  0},	// red
+  {  0,III,  0},	// green
+  {III,III,  0},	// yellow
+  {  0,  0,III},	// blue
+  {III,  0,III},	// magenta
+  {  0,III,III},	// cyan
+  {III,III,III},	// white
+// pastel versions of those colors, from SGI's standard color map:
+  { 85, 85, 85},	// 1/3 gray
+  {198,113,113},	// salmon? pale red?
+  {113,198,113},	// pale green
+  {142,142, 56},	// khaki
+  {113,113,198},	// pale blue
+  {142, 56,142},	// purple, orchid, pale magenta
+  { 56,142,142},	// cadet blue, aquamarine, pale cyan
+// The next location is used for FL_SELECTION_COLOR. It formerly was 2/3 gray
+// but this is changed to be the Windows blue color. This allows the default
+// behavior on both X and Windows to match:
+  {  0,  0,128},
+//{170,170,170},	// old 2/3 gray color
+// These next 16 are the FL_FREE_COLOR area. In some versions of fltk
+// these were filled with random colors that a Irix 5.3 machine placed
+// in these locations. Other versions of fltk filled this with the 1/3
+// gray above to discourage their use. This newest version uses colors
+// that NewTek has assigned for their GUI:
+#if 0
+  // The Irix 5.3 colors:
+  { 16, 16, 16},
+  {128, 40,128},
+  {198, 30, 30},
+  { 66, 30, 30},
+  {176,140,140},
+  {  0, 20, 20},
+  { 20, 10, 10},
+  { 40, 20, 20},
+  { 60, 30, 30},
+  {  0, 80, 80},
+  {  0, 40, 40},
+  { 20, 20,  0},
+  { 40, 40,  0},
+  { 80, 80, 10},
+  {150,150, 20},
+  {160, 10, 10},
+#else
+  // The NewTek colors: (from George Yohng)
+  {168,168,152},
+  {232,232,216},
+  {104,104, 88},
+  {152,168,168},
+  {216,232,232},
+  { 88,104,104},
+  {156,156,168},
+  {220,220,232},
+  { 92, 92,104},
+  {156,168,156},
+  {220,232,220},
+  { 92,104, 92},
+  {144,144,144},
+  {192,192,192},
+  { 80, 80, 80},
+  {160,160,160},
+#endif
+// The rest of the colormap is a gray ramp and table, filled in below:
+};
+
+// This is Fl::background from Fl_get_system_colors.cxx, with modifications:
+
+#define FL_GRAY_RAMP 32
+#define FL_NUM_GRAY  24
+#define FL_GRAY 49 // old value is 47
+typedef unsigned char uchar;
+#include <math.h>
+
+void background(uchar r, uchar g, uchar b) {
+  // replace the gray ramp so that color 47 (by default 2/3) is this color
+  if (!r) r = 1; else if (r==255) r = 254;
+  double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+  if (!g) g = 1; else if (g==255) g = 254;
+  double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+  if (!b) b = 1; else if (b==255) b = 254;
+  double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+  for (int i = 0; i < FL_NUM_GRAY; i++) {
+    double gray = i/(FL_NUM_GRAY-1.0);
+    cmap[i+FL_GRAY_RAMP][0] = uchar(pow(gray,powr)*255+.5);
+    cmap[i+FL_GRAY_RAMP][1] = uchar(pow(gray,powg)*255+.5);
+    cmap[i+FL_GRAY_RAMP][2] = uchar(pow(gray,powb)*255+.5);
+  }
+}
+
+int main() {
+  int i,r,g,b;
+#if 0
+  /* Read colormap colors into internal table */
+  long cmwin;
+  noport();
+  cmwin = winopen("CM");
+  for (i=0; i<256; i++)
+    getmcolor(i,&cmap[i][0],&cmap[i][1],&cmap[i][2]);
+  winclose(cmwin);
+#endif
+// overwrite the X allocation area with one color so people are
+// discouraged from using it:
+  //for (i=16; i<32; i++) {cmap[i][0]=cmap[i][1]=cmap[i][2] = 85;}
+
+  // fill in the gray ramp:
+  background(0xc0, 0xc0, 0xc0); // microsoft colors
+  // background(170, 170, 170); // old fltk colors
+  // copy the 1/3 and 2/3 gray to the closest locations in gray ramp:
+  cmap[39][0] = cmap[39][1] = cmap[39][2] = 85;
+  cmap[47][0] = cmap[47][1] = cmap[47][2] = 170;
+
+  // fill in the color cube
+  i = 56;
+  for (b=0; b<5; b++)
+    for (r=0; r<5; r++)
+      for (g=0; g<8; g++) {
+	cmap[i][0] = r*255/4;
+	cmap[i][1] = g*255/7;
+	cmap[i][2] = b*255/4;
+	i++;
+      }
+
+  for (i=0; i<256; i++) {
+    printf("\t0x%02x%02x%02x00",cmap[i][0],cmap[i][1],cmap[i][2]);
+    if (i < 255) printf(",\n");
+  }
+  printf("\n");
+  return 0;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/d1.xbm b/Utilities/FLTK/src/d1.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..a0e67f0290636959b2f88f1a80ea4791101aa5d1
--- /dev/null
+++ b/Utilities/FLTK/src/d1.xbm
@@ -0,0 +1,6 @@
+#define d1_width 16
+#define d1_height 16
+static unsigned char d1_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
+   0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
+   0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/d1_mask.xbm b/Utilities/FLTK/src/d1_mask.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..6b1e14dacab69c6a51f102d151a6634945233486
--- /dev/null
+++ b/Utilities/FLTK/src/d1_mask.xbm
@@ -0,0 +1,6 @@
+#define d1_mask_width 16
+#define d1_mask_height 16
+static unsigned char d1_mask_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
+   0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
+   0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/dump_compose.c b/Utilities/FLTK/src/dump_compose.c
new file mode 100644
index 0000000000000000000000000000000000000000..fe41991cf98530bf042f3c3f9cd488aceda97dcc
--- /dev/null
+++ b/Utilities/FLTK/src/dump_compose.c
@@ -0,0 +1,26 @@
+/* write out the documentation for the compose key */
+
+/* copy the string from Fl_Input.C */
+static const char* const compose_pairs =
+"  ! @ # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "
+"A`A'A^A~A:A*AEC,E`E'E^E:I`I'I^I:D-N~O`O'O^O~O:x O/U`U'U^U:Y'DDss"
+"a`a'a^a~a:a*aec,e`e'e^e:i`i'i^i:d-n~o`o'o^o~o:-:o/u`u'u^u:y'ddy:";
+
+#include <stdio.h>
+
+int main() {
+  int x,y;
+  for (x = 0; x<16; x++) {
+    for (y = 0; y<6; y++) {
+      const char *p = compose_pairs + (16*y+x)*2;
+      if (p[1] == ' ')
+	printf("<td><code>%c&nbsp</code>&nbsp&nbsp&nbsp%c\n",
+	       p[0],(p-compose_pairs)/2+0xA0);
+      else
+	printf("<td><code>%c%c</code>&nbsp&nbsp&nbsp%c\n",
+	       p[0],p[1],(p-compose_pairs)/2+0xA0);
+    }
+    printf("<tr>");
+  }
+  return 0;
+}
diff --git a/Utilities/FLTK/src/ew.xbm b/Utilities/FLTK/src/ew.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..1ff835cd579ff5e0a86707a676ed7d91b271ba10
--- /dev/null
+++ b/Utilities/FLTK/src/ew.xbm
@@ -0,0 +1,8 @@
+#define ew_width 16
+#define ew_height 16
+#define ew_x_hot 8
+#define ew_y_hot 8
+static unsigned char ew_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
+   0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/ew_mask.xbm b/Utilities/FLTK/src/ew_mask.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..49dc1df88190ec88d8104ec14d51dd0ad1117889
--- /dev/null
+++ b/Utilities/FLTK/src/ew_mask.xbm
@@ -0,0 +1,8 @@
+#define ew_mask_width 16
+#define ew_mask_height 16
+#define ew_mask_x_hot 8
+#define ew_mask_y_hot 8
+static unsigned char ew_mask_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
+   0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/fastarrow.h b/Utilities/FLTK/src/fastarrow.h
new file mode 100644
index 0000000000000000000000000000000000000000..e381acdced1354d7741e8efdb44a603e58323996
--- /dev/null
+++ b/Utilities/FLTK/src/fastarrow.h
@@ -0,0 +1,6 @@
+#define fastarrow_width 16
+#define fastarrow_height 16
+static unsigned char fastarrow_bits[] = {
+   0x00, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03,
+   0xe0, 0x07, 0x00, 0x07, 0xe0, 0x00, 0xe0, 0x07, 0xc0, 0x3f, 0xff, 0xff,
+   0xc0, 0x3f, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/filename_absolute.cxx b/Utilities/FLTK/src/filename_absolute.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d4101cfec0e7960c7bfd8e6a5336b8e59d14f0d5
--- /dev/null
+++ b/Utilities/FLTK/src/filename_absolute.cxx
@@ -0,0 +1,197 @@
+//
+// "$Id$"
+//
+// Filename expansion routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/* expand a file name by prepending current directory, deleting . and
+   .. (not really correct for symbolic links) between the prepended
+   current directory.  Use $PWD if it exists.
+   Returns true if any changes were made.
+*/
+
+#include <FL/filename.H>
+#include <stdlib.h>
+#include "flstring.h"
+#include <ctype.h>
+#if defined(WIN32) && !defined(__CYGWIN__)
+# include <direct.h>
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define getcwd _getcwd
+#else
+#  include <unistd.h>
+#  ifdef __EMX__
+#    define getcwd _getcwd2
+#  endif
+#endif
+
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+inline int isdirsep(char c) {return c=='/' || c=='\\';}
+#else
+#define isdirsep(c) ((c)=='/')
+#endif
+
+int fl_filename_absolute(char *to, int tolen, const char *from) {
+  if (isdirsep(*from) || *from == '|'
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+      || from[1]==':'
+#endif
+      ) {
+    strlcpy(to, from, tolen);
+    return 0;
+  }
+
+  char *a;
+  char *temp = new char[tolen];
+  const char *start = from;
+
+  a = getcwd(temp, tolen);
+  if (!a) {
+    strlcpy(to, from, tolen);
+    delete[] temp;
+    return 0;
+  }
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+  for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha
+#else
+  a = temp+strlen(temp);
+#endif
+  if (isdirsep(*(a-1))) a--;
+  /* remove intermediate . and .. names: */
+  while (*start == '.') {
+    if (start[1]=='.' && isdirsep(start[2])) {
+      char *b;
+      for (b = a-1; b >= temp && !isdirsep(*b); b--);
+      if (b < temp) break;
+      a = b;
+      start += 3;
+    } else if (isdirsep(start[1])) {
+      start += 2;
+    } else if (!start[1]) {
+      start ++; // Skip lone "."
+      break;
+    } else
+      break;
+  }
+
+  *a++ = '/';
+  strlcpy(a,start,tolen - (a - temp));
+
+  strlcpy(to, temp, tolen);
+
+  delete[] temp;
+
+  return 1;
+}
+
+/*
+ * 'fl_filename_relative()' - Make a filename relative to the current working directory.
+ */
+
+int					// O - 0 if no change, 1 if changed
+fl_filename_relative(char       *to,	// O - Relative filename
+                     int        tolen,	// I - Size of "to" buffer
+                     const char *from) {// I - Absolute filename
+  char		*newslash;		// Directory separator
+  const char	*slash;			// Directory separator
+  char		cwd[1024];		// Current directory
+
+
+#if defined(WIN32) || defined(__EMX__)
+  if (from[0] == '\0' ||
+      (!isdirsep(*from) && !isalpha(*from) && from[1] != ':' &&
+       !isdirsep(from[2]))) {
+#else
+  if (from[0] == '\0' || !isdirsep(*from)) {
+#endif // WIN32 || __EMX__
+    strlcpy(to, from, tolen);
+    return 0;
+  }
+
+  if (!getcwd(cwd, sizeof(cwd))) {
+    strlcpy(to, from, tolen);
+    return 0;
+  }
+
+#if defined(WIN32) || defined(__EMX__)
+  for (newslash = strchr(cwd, '\\'); newslash; newslash = strchr(newslash + 1, '\\'))
+    *newslash = '/';
+
+  if (!strcasecmp(from, cwd)) {
+    strlcpy(to, ".", tolen);
+    return (1);
+  }
+
+  if (tolower(*from & 255) != tolower(*cwd & 255)) {
+    // Not the same drive...
+    strlcpy(to, from, tolen);
+    return 0;
+  }
+  for (slash = from + 2, newslash = cwd + 2;
+#else
+  if (!strcmp(from, cwd)) {
+    strlcpy(to, ".", tolen);
+    return (1);
+  }
+
+  for (slash = from, newslash = cwd;
+#endif // WIN32 || __EMX__
+       *slash != '\0' && *newslash != '\0';
+       slash ++, newslash ++)
+    if (isdirsep(*slash) && isdirsep(*newslash)) continue;
+#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
+    else if (tolower(*slash & 255) != tolower(*newslash & 255)) break;
+#else
+    else if (*slash != *newslash) break;
+#endif // WIN32 || __EMX__ || __APPLE__
+
+  if (*newslash == '\0' && *slash != '\0' && !isdirsep(*slash))
+    newslash--;
+
+  while (!isdirsep(*slash) && slash > from) slash --;
+
+  if (isdirsep(*slash)) slash ++;
+
+  if (*newslash != '\0')
+    while (!isdirsep(*newslash) && newslash > cwd) newslash --;
+
+  to[0]         = '\0';
+  to[tolen - 1] = '\0';
+
+  while (*newslash != '\0') {
+    if (isdirsep(*newslash)) strlcat(to, "../", tolen);
+
+    newslash ++;
+  }
+
+  strlcat(to, slash, tolen);
+
+  return 1;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/filename_expand.cxx b/Utilities/FLTK/src/filename_expand.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3f040a7e33381dbfe9400bb9c8b1353092c332f5
--- /dev/null
+++ b/Utilities/FLTK/src/filename_expand.cxx
@@ -0,0 +1,110 @@
+//
+// "$Id$"
+//
+// Filename expansion routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/* expand a file name by substuting environment variables and
+   home directories.  Returns true if any changes were made.
+   to & from may be the same buffer.
+*/
+
+#include <FL/filename.H>
+#include <stdlib.h>
+#include "flstring.h"
+#if defined(WIN32) && !defined(__CYGWIN__)
+#else
+# include <unistd.h>
+# include <pwd.h>
+#endif
+
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+static inline int isdirsep(char c) {return c=='/' || c=='\\';}
+#else
+#define isdirsep(c) ((c)=='/')
+#endif
+
+int fl_filename_expand(char *to,int tolen, const char *from) {
+
+  char *temp = new char[tolen];
+  strlcpy(temp,from, tolen);
+  char *start = temp;
+  char *end = temp+strlen(temp);
+
+  int ret = 0;
+
+  for (char *a=temp; a<end; ) {	// for each slash component
+    char *e; for (e=a; e<end && !isdirsep(*e); e++); // find next slash
+    const char *value = 0; // this will point at substitute value
+    switch (*a) {
+    case '~':	// a home directory name
+      if (e <= a+1) {	// current user's directory
+	value = getenv("HOME");
+#ifndef WIN32
+      } else {	// another user's directory
+	struct passwd *pwd;
+	char t = *e; *(char *)e = 0; 
+        pwd = getpwnam(a+1); 
+        *(char *)e = t;
+	    if (pwd) value = pwd->pw_dir;
+#endif
+      }
+      break;
+    case '$':		/* an environment variable */
+      {char t = *e; *(char *)e = 0; value = getenv(a+1); *(char *)e = t;}
+      break;
+    }
+    if (value) {
+      // substitutions that start with slash delete everything before them:
+      if (isdirsep(value[0])) start = a;
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+      // also if it starts with "A:"
+      if (value[0] && value[1]==':') start = a;
+#endif
+      int t = strlen(value); if (isdirsep(value[t-1])) t--;
+      if ((end+1-e+t) >= tolen) end += tolen - (end+1-e+t);
+      memmove(a+t, e, end+1-e);
+      end = a+t+(end-e);
+      *end = '\0';
+      memcpy(a, value, t);
+      ret++;
+    } else {
+      a = e+1;
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+      if (*e == '\\') {*e = '/'; ret++;} // ha ha!
+#endif
+    }
+  }
+
+  strlcpy(to, start, tolen);
+
+  delete[] temp;
+
+  return ret;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/filename_ext.cxx b/Utilities/FLTK/src/filename_ext.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..250085334367869d5de43ddf88ddf7a9784b945e
--- /dev/null
+++ b/Utilities/FLTK/src/filename_ext.cxx
@@ -0,0 +1,47 @@
+//
+// "$Id$"
+//
+// Filename extension routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// returns pointer to the last '.' or to the null if none:
+
+#include <FL/filename.H>
+
+const char *fl_filename_ext(const char *buf) {
+  const char *q = 0;
+  const char *p = buf;
+  for (p=buf; *p; p++) {
+    if (*p == '/') q = 0;
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+    else if (*p == '\\') q = 0;
+#endif
+    else if (*p == '.') q = p;
+  }
+  return q ? q : p;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/filename_isdir.cxx b/Utilities/FLTK/src/filename_isdir.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f1a3d2909526dd80d57ed062f8bd933aa045770b
--- /dev/null
+++ b/Utilities/FLTK/src/filename_isdir.cxx
@@ -0,0 +1,77 @@
+//
+// "$Id$"
+//
+// Directory detection routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Used by fl_file_chooser
+
+#include "flstring.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <FL/filename.H>
+
+
+#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
+static inline int isdirsep(char c) {return c=='/' || c=='\\';}
+#else
+#define isdirsep(c) ((c)=='/')
+#endif
+
+int fl_filename_isdir(const char* n) {
+  struct stat	s;
+
+  // Do a quick optimization for filenames with a trailing slash...
+  if (*n && isdirsep(n[strlen(n) - 1])) return 1;
+
+#ifdef WIN32
+  char		fn[1024];
+  int		length;
+  // This workaround brought to you by the fine folks at Microsoft!
+  // (read lots of sarcasm in that...)
+  length = strlen(n);
+  if (length < (int)(sizeof(fn) - 1)) {
+    if (length < 4 && isalpha(n[0]) && n[1] == ':' &&
+        (isdirsep(n[2]) || !n[2])) {
+      // Always use D:/ for drive letters
+      fn[0] = n[0];
+      strcpy(fn + 1, ":/");
+      n = fn;
+    } else if (length > 0 && isdirsep(n[length - 1])) {
+      // Strip trailing slash from name...
+      length --;
+      memcpy(fn, n, length);
+      fn[length] = '\0';
+      n = fn;
+    }
+  }
+#endif
+
+  return !stat(n, &s) && (s.st_mode&0170000)==0040000;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/filename_list.cxx b/Utilities/FLTK/src/filename_list.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7e16b5ffe332a6beee8c460b33d15cb40d411069
--- /dev/null
+++ b/Utilities/FLTK/src/filename_list.cxx
@@ -0,0 +1,108 @@
+//
+// "$Id$"
+//
+// Filename list routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Wrapper for scandir with const-correct function prototypes.
+
+#include <FL/filename.H>
+#include "flstring.h"
+#include <stdlib.h>
+#include "fltk-config.h"
+
+
+extern "C" {
+#ifndef HAVE_SCANDIR
+  int fl_scandir (const char *dir, dirent ***namelist,
+	          int (*select)(dirent *),
+	          int (*compar)(dirent **, dirent **));
+#  define scandir	fl_scandir
+#endif
+}
+
+int fl_alphasort(struct dirent **a, struct dirent **b) {
+  return strcmp((*a)->d_name, (*b)->d_name);
+}
+
+int fl_casealphasort(struct dirent **a, struct dirent **b) {
+  return strcasecmp((*a)->d_name, (*b)->d_name);
+}
+
+
+int fl_filename_list(const char *d, dirent ***list,
+                     Fl_File_Sort_F *sort) {
+#ifndef HAVE_SCANDIR
+  int n = scandir(d, list, 0, sort);
+#elif defined(__hpux) || defined(__CYGWIN__)
+  // HP-UX, Cygwin define the comparison function like this:
+  int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort);
+#elif defined(__osf__)
+  // OSF, DU 4.0x
+  int n = scandir(d, list, 0, (int(*)(dirent **, dirent **))sort);
+#elif defined(_AIX)
+  // AIX is almost standard...
+  int n = scandir(d, list, 0, (int(*)(void*, void*))sort);
+#elif !defined(__sgi)
+  // The vast majority of UNIX systems want the sort function to have this
+  // prototype, most likely so that it can be passed to qsort without any
+  // changes:
+  int n = scandir(d, list, 0, (int(*)(const void*,const void*))sort);
+#else
+  // This version is when we define our own scandir (WIN32 and perhaps
+  // some Unix systems) and apparently on IRIX:
+  int n = scandir(d, list, 0, sort);
+#endif
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+  // we did this already during fl_scandir/win32
+#else
+  // append a '/' to all filenames that are directories
+  int i, dirlen = strlen(d);
+  char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul
+  // Use memcpy for speed since we already know the length of the string...
+  memcpy(fullname, d, dirlen+1);
+  char *name = fullname + dirlen;
+  if (name!=fullname && name[-1]!='/') *name++ = '/';
+  for (i=0; i<n; i++) {
+    dirent *de = (*list)[i];
+    int len = strlen(de->d_name);
+    if (de->d_name[len-1]=='/' || len>FL_PATH_MAX) continue;
+    // Use memcpy for speed since we already know the length of the string...
+    memcpy(name, de->d_name, len+1);
+    if (fl_filename_isdir(fullname)) {
+      (*list)[i] = de = (dirent*)realloc(de, de->d_name - (char*)de + len + 2);
+      char *dst = de->d_name + len;
+      *dst++ = '/';
+      *dst = 0;
+    }
+  }
+  free(fullname);
+#endif
+  return n;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/filename_match.cxx b/Utilities/FLTK/src/filename_match.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..990ede5c48950b8e186548fdb4114f5ba74aea3c
--- /dev/null
+++ b/Utilities/FLTK/src/filename_match.cxx
@@ -0,0 +1,106 @@
+//
+// "$Id$"
+//
+// Pattern matching routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/* Adapted from Rich Salz. */
+#include <FL/filename.H>
+#include <ctype.h>
+
+int fl_filename_match(const char *s, const char *p) {
+  int matched;
+
+  for (;;) {
+    switch(*p++) {
+
+    case '?' :	// match any single character
+      if (!*s++) return 0;
+      break;
+
+    case '*' :	// match 0-n of any characters
+      if (!*p) return 1; // do trailing * quickly
+      while (!fl_filename_match(s, p)) if (!*s++) return 0;
+      return 1;
+
+    case '[': {	// match one character in set of form [abc-d] or [^a-b]
+      if (!*s) return 0;
+      int reverse = (*p=='^' || *p=='!'); if (reverse) p++;
+      matched = 0;
+      char last = 0;
+      while (*p) {
+	if (*p=='-' && last) {
+	  if (*s <= *++p && *s >= last ) matched = 1;
+	  last = 0;
+	} else {
+	  if (*s == *p) matched = 1;
+	}
+	last = *p++;
+	if (*p==']') break;
+      }
+      if (matched == reverse) return 0;
+      s++; p++;}
+    break;
+
+    case '{' : // {pattern1|pattern2|pattern3}
+    NEXTCASE:
+    if (fl_filename_match(s,p)) return 1;
+    for (matched = 0;;) {
+      switch (*p++) {
+      case '\\': if (*p) p++; break;
+      case '{': matched++; break;
+      case '}': if (!matched--) return 0; break;
+      case '|': case ',': if (matched==0) goto NEXTCASE;
+      case 0: return 0;
+      }
+    }
+    case '|':	// skip rest of |pattern|pattern} when called recursively
+    case ',':
+      for (matched = 0; *p && matched >= 0;) {
+	switch (*p++) {
+	case '\\': if (*p) p++; break;
+	case '{': matched++; break;
+	case '}': matched--; break;
+	}
+      }
+      break;
+    case '}':
+      break;
+
+    case 0:	// end of pattern
+      return !*s;
+
+    case '\\':	// quote next character
+      if (*p) p++;
+    default:
+      if (tolower(*s) != tolower(*(p-1))) return 0;
+      s++;
+      break;
+    }
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/filename_setext.cxx b/Utilities/FLTK/src/filename_setext.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..17ce9877056591441c17b975f85200ab495a39d6
--- /dev/null
+++ b/Utilities/FLTK/src/filename_setext.cxx
@@ -0,0 +1,46 @@
+//
+// "$Id$"
+//
+// Filename extension routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Replace .ext with new extension
+// If no . in name, append new extension
+// If new extension is null, act like it is ""
+
+#include <FL/filename.H>
+#include "flstring.h"
+
+char *fl_filename_setext(char *buf, int buflen, const char *ext) {
+  char *q = (char *)fl_filename_ext(buf);
+  if (ext) {
+    strlcpy(q,ext,buflen - (q - buf));
+  } else *q = 0;
+  return(buf);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_arc.cxx b/Utilities/FLTK/src/fl_arc.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..08cc416bfe44f0c3f2ba2ac457105695c814d205
--- /dev/null
+++ b/Utilities/FLTK/src/fl_arc.cxx
@@ -0,0 +1,86 @@
+//
+// "$Id$"
+//
+// Arc functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Utility for drawing arcs and circles.  They are added to
+// the current fl_begin/fl_vertex/fl_end path.
+// Incremental math implementation:
+
+#include <FL/fl_draw.H>
+#include <FL/math.h>
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...
+#  define hypot _hypot
+#endif // WIN32 && !__CYGWIN__
+
+void fl_arc(double x, double y, double r, double start, double end) {
+
+  // draw start point accurately:
+  
+  double A = start*(M_PI/180);		// Initial angle (radians)
+  double X =  r*cos(A);			// Initial displacement, (X,Y)
+  double Y = -r*sin(A);			//   from center to initial point
+  fl_vertex(x+X,y+Y);			// Insert initial point
+
+  // Maximum arc length to approximate with chord with error <= 0.125
+  
+  double epsilon; {
+    double r1 = hypot(fl_transform_dx(r,0), // Horizontal "radius"
+		      fl_transform_dy(r,0));
+    double r2 = hypot(fl_transform_dx(0,r), // Vertical "radius"
+		      fl_transform_dy(0,r));
+		      
+    if (r1 > r2) r1 = r2;		// r1 = minimum "radius"
+    if (r1 < 2.) r1 = 2.;		// radius for circa 9 chords/circle
+    
+    epsilon = 2*acos(1.0 - 0.125/r1);	// Maximum arc angle
+  }
+  A = end*(M_PI/180) - A;		// Displacement angle (radians)
+  int i = int(ceil(fabs(A)/epsilon));	// Segments in approximation
+  
+  if (i) {
+    epsilon = A/i;			// Arc length for equal-size steps
+    double cos_e = cos(epsilon);	// Rotation coefficients
+    double sin_e = sin(epsilon);
+    do {
+      double Xnew =  cos_e*X + sin_e*Y;
+		Y = -sin_e*X + cos_e*Y;
+      fl_vertex(x + (X=Xnew), y + Y);
+    } while (--i);
+  }
+}
+
+#if 0 // portable version.  X-specific one in fl_vertex.cxx
+void fl_circle(double x,double y,double r) {
+  _fl_arc(x, y, r, r, 0, 360);
+}
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_arci.cxx b/Utilities/FLTK/src/fl_arci.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0ff9368b9ff52c7021bc4cb687ebf2a58dd324af
--- /dev/null
+++ b/Utilities/FLTK/src/fl_arci.cxx
@@ -0,0 +1,119 @@
+//
+// "$Id$"
+//
+// Arc (integer) drawing functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// "integer" circle drawing functions.  These draw the limited
+// circle types provided by X and NT graphics.  The advantage of
+// these is that small ones draw quite nicely (probably due to stored
+// hand-drawn bitmaps of small circles!) and may be implemented by
+// hardware and thus are fast.
+
+// Probably should add fl_chord.
+
+// 3/10/98: created
+
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#ifdef WIN32
+#include <FL/math.h>
+#endif
+#ifdef __APPLE__
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#endif
+
+void fl_arc(int x,int y,int w,int h,double a1,double a2) {
+  if (w <= 0 || h <= 0) return;
+#ifdef WIN32
+  int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
+  int ya = y+h/2-int(h*sin(a1/180.0*M_PI));
+  int xb = x+w/2+int(w*cos(a2/180.0*M_PI));
+  int yb = y+h/2-int(h*sin(a2/180.0*M_PI));
+  Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); 
+#elif defined(__APPLE_QD__)
+  Rect r; r.left=x; r.right=x+w; r.top=y; r.bottom=y+h;
+  a1 = a2-a1; a2 = 450-a2;
+  FrameArc(&r, (short int)a2, (short int)a1);
+#elif defined(__APPLE_QUARTZ__)
+  a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI;
+  float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f;
+  if (w!=h) {
+    CGContextSaveGState(fl_gc);
+    CGContextTranslateCTM(fl_gc, cx, cy);
+    CGContextScaleCTM(fl_gc, w-1.0f, h-1.0f);
+    CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1);
+    CGContextRestoreGState(fl_gc);
+  } else {
+    float r = (w+h)*0.25f-0.5f;
+    CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1);
+  }
+  CGContextStrokePath(fl_gc);
+#else
+  XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64));
+#endif
+}
+
+void fl_pie(int x,int y,int w,int h,double a1,double a2) {
+  if (w <= 0 || h <= 0) return;
+#ifdef WIN32
+  if (a1 == a2) return;
+  int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
+  int ya = y+h/2-int(h*sin(a1/180.0*M_PI));
+  int xb = x+w/2+int(w*cos(a2/180.0*M_PI));
+  int yb = y+h/2-int(h*sin(a2/180.0*M_PI));
+  SelectObject(fl_gc, fl_brush());
+  Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); 
+#elif defined(__APPLE_QD__)
+  Rect r; r.left=x; r.right=x+w; r.top=y; r.bottom=y+h;
+  a1 = a2-a1; a2 = 450-a2;
+  PaintArc(&r, (short int)a2, (short int)a1);
+#elif defined(__APPLE_QUARTZ__)
+  a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI;
+  float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f;
+  if (w!=h) {
+    CGContextSaveGState(fl_gc);
+    CGContextTranslateCTM(fl_gc, cx, cy);
+    CGContextScaleCTM(fl_gc, w, h);
+    CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1);
+    CGContextAddLineToPoint(fl_gc, 0, 0);
+    CGContextClosePath(fl_gc);
+    CGContextRestoreGState(fl_gc);
+  } else {
+    float r = (w+h)*0.25f;
+    CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1);
+    CGContextAddLineToPoint(fl_gc, cx, cy);
+    CGContextClosePath(fl_gc);
+  }
+  CGContextFillPath(fl_gc);
+#else
+  XFillArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64));
+#endif
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_ask.cxx b/Utilities/FLTK/src/fl_ask.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..454ecff777a8c791d198b0318fac70761dddda6a
--- /dev/null
+++ b/Utilities/FLTK/src/fl_ask.cxx
@@ -0,0 +1,357 @@
+//
+// "$Id$"
+//
+// Standard dialog functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Implementation of fl_message, fl_ask, fl_choice, fl_input
+// The three-message fl_show_x functions are for forms compatibility
+// mostly.  In most cases it is easier to get a multi-line message
+// by putting newlines in the message.
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "flstring.h"
+
+#include <FL/Fl.H>
+
+#include <FL/fl_ask.H>
+
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Secret_Input.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+static Fl_Window *message_form;
+static Fl_Box *message;
+static Fl_Box *icon;
+static Fl_Button *button[3];
+static Fl_Input *input;
+static const char *iconlabel = "?";
+Fl_Font fl_message_font_ = FL_HELVETICA;
+uchar fl_message_size_ = 14;
+
+static Fl_Window *makeform() {
+ if (message_form) {
+   message_form->size(410,103);
+   return message_form;
+ }
+ // make sure that the dialog does not become the child of some 
+ // current group
+ Fl_Group *previously_current_group = Fl_Group::current();
+ Fl_Group::current(0);
+ // create a new top level window
+ Fl_Window *w = message_form = new Fl_Window(410,103,"");
+ // w->clear_border();
+ // w->box(FL_UP_BOX);
+ (message = new Fl_Box(60, 25, 340, 20))
+   ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ (input = new Fl_Input(60, 37, 340, 23))->hide();
+ {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50);
+  o->box(FL_THIN_UP_BOX);
+  o->labelfont(FL_TIMES_BOLD);
+  o->labelsize(34);
+  o->color(FL_WHITE);
+  o->labelcolor(FL_BLUE);
+ }
+ button[0] = new Fl_Button(310, 70, 90, 23);
+ button[0]->shortcut("^[");
+ button[0]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ button[1] = new Fl_Return_Button(210, 70, 90, 23);
+ button[1]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ button[2] = new Fl_Button(110, 70, 90, 23);
+ button[2]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ w->resizable(new Fl_Box(60,10,110-60,27));
+ w->end();
+ w->set_modal();
+ Fl_Group::current(previously_current_group);
+ return w;
+}
+
+/*
+ * 'resizeform()' - Resize the form and widgets so that they hold everything
+ *                  that is asked of them...
+ */
+
+void resizeform() {
+  int	i;
+  int	message_w, message_h;
+  int	icon_size;
+  int	button_w[3], button_h[3];
+  int	x, w, h, max_w, max_h;
+
+  fl_font(fl_message_font_, fl_message_size_);
+  message_w = message_h = 0;
+  fl_measure(message->label(), message_w, message_h);
+
+  message_w += 10;
+  message_h += 10;
+  if (message_w < 340)
+    message_w = 340;
+  if (message_h < 30)
+    message_h = 30;
+
+  fl_font(button[0]->labelfont(), button[0]->labelsize());
+
+  memset(button_w, 0, sizeof(button_w));
+  memset(button_h, 0, sizeof(button_h));
+
+  for (max_h = 25, i = 0; i < 3; i ++)
+    if (button[i]->visible())
+    {
+      fl_measure(button[i]->label(), button_w[i], button_h[i]);
+
+      if (i == 1)
+        button_w[1] += 20;
+
+      button_w[i] += 30;
+      button_h[i] += 10;
+
+      if (button_h[i] > max_h)
+        max_h = button_h[i];
+    }
+
+  if (input->visible()) icon_size = message_h + 25;
+  else icon_size = message_h;
+
+  max_w = message_w + 10 + icon_size;
+  w     = button_w[0] + button_w[1] + button_w[2] - 10;
+
+  if (w > max_w)
+    max_w = w;
+
+  message_w = max_w - 10 - icon_size;
+
+  w = max_w + 20;
+  h = max_h + 30 + icon_size;
+
+  message_form->size(w, h);
+  message_form->size_range(w, h, w, h);
+
+  message->resize(20 + icon_size, 10, message_w, message_h);
+  icon->resize(10, 10, icon_size, icon_size);
+  icon->labelsize((uchar)(icon_size - 10));
+  input->resize(20 + icon_size, 10 + message_h, message_w, 25);
+
+  for (x = w, i = 0; i < 3; i ++)
+    if (button_w[i])
+    {
+      x -= button_w[i];
+      button[i]->resize(x, h - 10 - max_h, button_w[i] - 10, max_h);
+
+//      printf("button %d (%s) is %dx%d+%d,%d\n", i, button[i]->label(),
+//             button[i]->w(), button[i]->h(),
+//	     button[i]->x(), button[i]->y());
+    }
+}
+
+static int innards(const char* fmt, va_list ap,
+  const char *b0,
+  const char *b1,
+  const char *b2)
+{
+  makeform();
+  char buffer[1024];
+  if (!strcmp(fmt,"%s")) {
+    message->label(va_arg(ap, const char*));
+  } else {
+    //: matt: MacOS provides two equally named vsnprintf's...
+    ::vsnprintf(buffer, 1024, fmt, ap);
+    message->label(buffer);
+  }
+
+  message->labelfont(fl_message_font_);
+  message->labelsize(fl_message_size_);
+  if (b0) {button[0]->show(); button[0]->label(b0); button[1]->position(210,70);}
+  else {button[0]->hide(); button[1]->position(310,70);}
+  if (b1) {button[1]->show(); button[1]->label(b1);}
+  else button[1]->hide();
+  if (b2) {button[2]->show(); button[2]->label(b2);}
+  else button[2]->hide();
+  const char* prev_icon_label = icon->label();
+  if (!prev_icon_label) icon->label(iconlabel);
+
+  resizeform();
+
+  message_form->hotspot(button[0]);
+  message_form->show();
+  int r;
+  for (;;) {
+    Fl_Widget *o = Fl::readqueue();
+    if (!o) Fl::wait();
+    else if (o == button[0]) {r = 0; break;}
+    else if (o == button[1]) {r = 1; break;}
+    else if (o == button[2]) {r = 2; break;}
+    else if (o == message_form) {r = 0; break;}
+  }
+  message_form->hide();
+  icon->label(prev_icon_label);
+  return r;
+}
+
+// pointers you can use to change FLTK to a foreign language:
+const char* fl_no = "No";
+const char* fl_yes= "Yes";
+const char* fl_ok = "OK";
+const char* fl_cancel= "Cancel";
+const char* fl_close= "Close";
+
+// fltk functions:
+void fl_beep(int type) {
+#ifdef WIN32
+  switch (type) {
+    case FL_BEEP_QUESTION :
+    case FL_BEEP_PASSWORD :
+      MessageBeep(MB_ICONQUESTION);
+      break;
+    case FL_BEEP_MESSAGE :
+      MessageBeep(MB_ICONASTERISK);
+      break;
+    case FL_BEEP_NOTIFICATION :
+      MessageBeep(MB_ICONASTERISK);
+      break;
+    case FL_BEEP_ERROR :
+      MessageBeep(MB_ICONERROR);
+      break;
+    default :
+      MessageBeep(0xFFFFFFFF);
+      break;
+  }
+#elif defined(__APPLE__)
+  switch (type) {
+    case FL_BEEP_DEFAULT :
+    case FL_BEEP_ERROR :
+      SysBeep(30);
+      break;
+    default :
+      break;
+  }
+#else
+  switch (type) {
+    case FL_BEEP_DEFAULT :
+    case FL_BEEP_ERROR :
+      if (!fl_display) fl_open_display();
+
+      XBell(fl_display, 100);
+      break;
+    default :
+      if (!fl_display) fl_open_display();
+
+      XBell(fl_display, 50);
+      break;
+  }
+#endif // WIN32
+}
+
+void fl_message(const char *fmt, ...) {
+  va_list ap;
+
+  fl_beep(FL_BEEP_MESSAGE);
+
+  va_start(ap, fmt);
+  iconlabel = "i";
+  innards(fmt, ap, 0, fl_close, 0);
+  va_end(ap);
+  iconlabel = "?";
+}
+
+void fl_alert(const char *fmt, ...) {
+  va_list ap;
+
+  fl_beep(FL_BEEP_ERROR);
+
+  va_start(ap, fmt);
+  iconlabel = "!";
+  innards(fmt, ap, 0, fl_close, 0);
+  va_end(ap);
+  iconlabel = "?";
+}
+
+int fl_ask(const char *fmt, ...) {
+  va_list ap;
+
+  fl_beep(FL_BEEP_QUESTION);
+
+  va_start(ap, fmt);
+  int r = innards(fmt, ap, fl_no, fl_yes, 0);
+  va_end(ap);
+
+  return r;
+}
+
+int fl_choice(const char*fmt,const char *b0,const char *b1,const char *b2,...){
+  va_list ap;
+
+  fl_beep(FL_BEEP_QUESTION);
+
+  va_start(ap, b2);
+  int r = innards(fmt, ap, b0, b1, b2);
+  va_end(ap);
+  return r;
+}
+
+Fl_Widget *fl_message_icon() {makeform(); return icon;}
+
+static const char* input_innards(const char* fmt, va_list ap,
+				 const char* defstr, uchar type) {
+  makeform();
+  message->position(60,10);
+  input->type(type);
+  input->show();
+  input->value(defstr);
+  input->take_focus();
+
+  int r = innards(fmt, ap, fl_cancel, fl_ok, 0);
+  input->hide();
+  message->position(60,25);
+  return r ? input->value() : 0;
+}
+
+const char* fl_input(const char *fmt, const char *defstr, ...) {
+  fl_beep(FL_BEEP_QUESTION);
+
+  va_list ap;
+  va_start(ap, defstr);
+  const char* r = input_innards(fmt, ap, defstr, FL_NORMAL_INPUT);
+  va_end(ap);
+  return r;
+}
+
+const char *fl_password(const char *fmt, const char *defstr, ...) {
+  fl_beep(FL_BEEP_PASSWORD);
+
+  va_list ap;
+  va_start(ap, defstr);
+  const char* r = input_innards(fmt, ap, defstr, FL_SECRET_INPUT);
+  va_end(ap);
+  return r;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_boxtype.cxx b/Utilities/FLTK/src/fl_boxtype.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..727385369b726642e31f281099503faad6410a2f
--- /dev/null
+++ b/Utilities/FLTK/src/fl_boxtype.cxx
@@ -0,0 +1,311 @@
+//
+// "$Id$"
+//
+// Box drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Box drawing code for the common box types and the table of
+// boxtypes.  Other box types are in seperate files so they are not
+// linked in if not used.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+////////////////////////////////////////////////////////////////
+
+static uchar active_ramp[24] = {
+  FL_GRAY_RAMP+0, FL_GRAY_RAMP+1, FL_GRAY_RAMP+2, FL_GRAY_RAMP+3,
+  FL_GRAY_RAMP+4, FL_GRAY_RAMP+5, FL_GRAY_RAMP+6, FL_GRAY_RAMP+7,
+  FL_GRAY_RAMP+8, FL_GRAY_RAMP+9, FL_GRAY_RAMP+10,FL_GRAY_RAMP+11,
+  FL_GRAY_RAMP+12,FL_GRAY_RAMP+13,FL_GRAY_RAMP+14,FL_GRAY_RAMP+15,
+  FL_GRAY_RAMP+16,FL_GRAY_RAMP+17,FL_GRAY_RAMP+18,FL_GRAY_RAMP+19,
+  FL_GRAY_RAMP+20,FL_GRAY_RAMP+21,FL_GRAY_RAMP+22,FL_GRAY_RAMP+23};
+static uchar inactive_ramp[24] = {
+  43, 43, 44, 44,
+  44, 45, 45, 46,
+  46, 46, 47, 47,
+  48, 48, 48, 49,
+  49, 49, 50, 50,
+  51, 51, 52, 52};
+static int draw_it_active = 1;
+
+int Fl::draw_box_active() { return draw_it_active; }
+
+uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';}
+
+void fl_frame(const char* s, int x, int y, int w, int h) {
+  uchar *g = fl_gray_ramp();
+  if (h > 0 && w > 0) for (;*s;) {
+    // draw top line:
+    fl_color(g[*s++]);
+    fl_xyline(x, y, x+w-1);
+    y++; if (--h <= 0) break;
+    // draw left line:
+    fl_color(g[*s++]);
+    fl_yxline(x, y+h-1, y);
+    x++; if (--w <= 0) break;
+    // draw bottom line:
+    fl_color(g[*s++]);
+    fl_xyline(x, y+h-1, x+w-1);
+    if (--h <= 0) break;
+    // draw right line:
+    fl_color(g[*s++]);
+    fl_yxline(x+w-1, y+h-1, y);
+    if (--w <= 0) break;
+  }
+}
+
+void fl_frame2(const char* s, int x, int y, int w, int h) {
+  uchar *g = fl_gray_ramp();
+  if (h > 0 && w > 0) for (;*s;) {
+    // draw bottom line:
+    fl_color(g[*s++]);
+    fl_xyline(x, y+h-1, x+w-1);
+    if (--h <= 0) break;
+    // draw right line:
+    fl_color(g[*s++]);
+    fl_yxline(x+w-1, y+h-1, y);
+    if (--w <= 0) break;
+    // draw top line:
+    fl_color(g[*s++]);
+    fl_xyline(x, y, x+w-1);
+    y++; if (--h <= 0) break;
+    // draw left line:
+    fl_color(g[*s++]);
+    fl_yxline(x, y+h-1, y);
+    x++; if (--w <= 0) break;
+  }
+}
+
+void fl_no_box(int, int, int, int, Fl_Color) {}
+
+void fl_thin_down_frame(int x, int y, int w, int h, Fl_Color) {
+  fl_frame2("WWHH",x,y,w,h);
+}
+
+void fl_thin_down_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_thin_down_frame(x,y,w,h,c);
+  fl_color(draw_it_active ? c : fl_inactive(c));
+  fl_rectf(x+1, y+1, w-2, h-2);
+}
+
+void fl_thin_up_frame(int x, int y, int w, int h, Fl_Color) {
+  fl_frame2("HHWW",x,y,w,h);
+}
+
+void fl_thin_up_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_thin_up_frame(x,y,w,h,c);
+  fl_color(draw_it_active ? c : fl_inactive(c));
+  fl_rectf(x+1, y+1, w-2, h-2);
+}
+
+void fl_up_frame(int x, int y, int w, int h, Fl_Color) {
+#if BORDER_WIDTH == 1
+  fl_frame2("HHWW",x,y,w,h);
+#else
+#if BORDER_WIDTH == 2
+  fl_frame2("AAWWMMTT",x,y,w,h);
+#else
+  fl_frame("AAAAWWJJUTNN",x,y,w,h);
+#endif
+#endif
+}
+
+#define D1 BORDER_WIDTH
+#define D2 (BORDER_WIDTH+BORDER_WIDTH)
+
+void fl_up_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_up_frame(x,y,w,h,c);
+  fl_color(draw_it_active ? c : fl_inactive(c));
+  fl_rectf(x+D1, y+D1, w-D2, h-D2);
+}
+
+void fl_down_frame(int x, int y, int w, int h, Fl_Color) {
+#if BORDER_WIDTH == 1
+  fl_frame2("WWHH",x,y,w,h);
+#else
+#if BORDER_WIDTH == 2
+  fl_frame2("WWMMPPAA",x,y,w,h);
+#else
+  fl_frame("NNTUJJWWAAAA",x,y,w,h);
+#endif
+#endif
+}
+
+void fl_down_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_down_frame(x,y,w,h,c);
+  fl_color(c); fl_rectf(x+D1, y+D1, w-D2, h-D2);
+}
+
+void fl_engraved_frame(int x, int y, int w, int h, Fl_Color) {
+  fl_frame("HHWWWWHH",x,y,w,h);
+}
+
+void fl_engraved_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_engraved_frame(x,y,w,h,c);
+  fl_color(draw_it_active ? c : fl_inactive(c));
+  fl_rectf(x+2, y+2, w-4, h-4);
+}
+
+void fl_embossed_frame(int x, int y, int w, int h, Fl_Color) {
+  fl_frame("WWHHHHWW",x,y,w,h);
+}
+
+void fl_embossed_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_embossed_frame(x,y,w,h,c);
+  fl_color(draw_it_active ? c : fl_inactive(c));
+  fl_rectf(x+2, y+2, w-4, h-4);
+}
+
+void fl_rectbound(int x, int y, int w, int h, Fl_Color bgcolor) {
+  fl_color(draw_it_active ? FL_BLACK : fl_inactive(FL_BLACK));
+  fl_rect(x, y, w, h);
+  fl_color(draw_it_active ? bgcolor : fl_inactive(bgcolor));
+  fl_rectf(x+1, y+1, w-2, h-2);
+}
+#define fl_border_box fl_rectbound
+
+void fl_border_frame(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(draw_it_active ? c : fl_inactive(c));
+  fl_rect(x, y, w, h);
+}
+
+////////////////////////////////////////////////////////////////
+
+static struct {
+  Fl_Box_Draw_F *f;
+  uchar dx, dy, dw, dh;
+  int set;
+} fl_box_table[256] = {
+// must match list in Enumerations.H!!!
+  {fl_no_box,		0,0,0,0,1},		
+  {fl_rectf,		0,0,0,0,1}, // FL_FLAT_BOX
+  {fl_up_box,		D1,D1,D2,D2,1},
+  {fl_down_box,		D1,D1,D2,D2,1},
+  {fl_up_frame,		D1,D1,D2,D2,1},
+  {fl_down_frame,	D1,D1,D2,D2,1},
+  {fl_thin_up_box,	1,1,2,2,1},
+  {fl_thin_down_box,	1,1,2,2,1},
+  {fl_thin_up_frame,	1,1,2,2,1},
+  {fl_thin_down_frame,	1,1,2,2,1},
+  {fl_engraved_box,	2,2,4,4,1},
+  {fl_embossed_box,	2,2,4,4,1},
+  {fl_engraved_frame,	2,2,4,4,1},
+  {fl_embossed_frame,	2,2,4,4,1},
+  {fl_border_box,	1,1,2,2,1},
+  {fl_border_box,	1,1,5,5,0}, // _FL_SHADOW_BOX,
+  {fl_border_frame,	1,1,2,2,1},
+  {fl_border_frame,	1,1,5,5,0}, // _FL_SHADOW_FRAME,
+  {fl_border_box,	1,1,2,2,0}, // _FL_ROUNDED_BOX,
+  {fl_border_box,	1,1,2,2,0}, // _FL_RSHADOW_BOX,
+  {fl_border_frame,	1,1,2,2,0}, // _FL_ROUNDED_FRAME
+  {fl_rectf,		0,0,0,0,0}, // _FL_RFLAT_BOX,
+  {fl_up_box,		3,3,6,6,0}, // _FL_ROUND_UP_BOX
+  {fl_down_box,		3,3,6,6,0}, // _FL_ROUND_DOWN_BOX,
+  {fl_up_box,		0,0,0,0,0}, // _FL_DIAMOND_UP_BOX
+  {fl_down_box,		0,0,0,0,0}, // _FL_DIAMOND_DOWN_BOX
+  {fl_border_box,	1,1,2,2,0}, // _FL_OVAL_BOX,
+  {fl_border_box,	1,1,2,2,0}, // _FL_OVAL_SHADOW_BOX,
+  {fl_border_frame,	1,1,2,2,0}, // _FL_OVAL_FRAME
+  {fl_rectf,		0,0,0,0,0}, // _FL_OVAL_FLAT_BOX,
+  {fl_up_box,		4,4,8,8,0}, // _FL_PLASTIC_UP_BOX,
+  {fl_down_box,		2,2,4,4,0}, // _FL_PLASTIC_DOWN_BOX,
+  {fl_up_frame,		2,2,4,4,0}, // _FL_PLASTIC_UP_FRAME,
+  {fl_down_frame,	2,2,4,4,0}, // _FL_PLASTIC_DOWN_FRAME,
+  {fl_up_box,		2,2,4,4,0}, // _FL_PLASTIC_THIN_UP_BOX,
+  {fl_down_box,		2,2,4,4,0}, // _FL_PLASTIC_THIN_DOWN_BOX,
+  {fl_up_box,		3,3,6,6,0}, // FL_FREE_BOX+0
+  {fl_down_box,		3,3,6,6,0}, // FL_FREE_BOX+1
+  {fl_up_box,		3,3,6,6,0}, // FL_FREE_BOX+2
+  {fl_down_box,		3,3,6,6,0}, // FL_FREE_BOX+3
+  {fl_up_box,		3,3,6,6,0}, // FL_FREE_BOX+4
+  {fl_down_box,		3,3,6,6,0}, // FL_FREE_BOX+5
+  {fl_up_box,		3,3,6,6,0}, // FL_FREE_BOX+6
+  {fl_down_box,		3,3,6,6,0}, // FL_FREE_BOX+7
+};
+
+int Fl::box_dx(Fl_Boxtype t) {return fl_box_table[t].dx;}
+int Fl::box_dy(Fl_Boxtype t) {return fl_box_table[t].dy;}
+int Fl::box_dw(Fl_Boxtype t) {return fl_box_table[t].dw;}
+int Fl::box_dh(Fl_Boxtype t) {return fl_box_table[t].dh;}
+
+void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) {
+  if (!fl_box_table[t].set) {
+    fl_box_table[t].f   = f;
+    fl_box_table[t].set = 1;
+  }
+}
+
+Fl_Box_Draw_F *Fl::get_boxtype(Fl_Boxtype t) {
+  return fl_box_table[t].f;
+}
+
+void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f,
+		      uchar a, uchar b, uchar c, uchar d) {
+  fl_box_table[t].f   = f;
+  fl_box_table[t].set = 1;
+  fl_box_table[t].dx  = a;
+  fl_box_table[t].dy  = b;
+  fl_box_table[t].dw  = c;
+  fl_box_table[t].dh  = d;
+}
+
+void Fl::set_boxtype(Fl_Boxtype t, Fl_Boxtype f) {
+  fl_box_table[t] = fl_box_table[f];
+}
+
+void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) {
+  if (t && fl_box_table[t].f) fl_box_table[t].f(x,y,w,h,c);
+}
+
+//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.cxx
+
+void Fl_Widget::draw_box() const {
+  int t = box_;
+  if (!t) return;
+//   if (this == fl_boxcheat) {
+//     fl_boxcheat = 0;
+//     if (t == FL_FLAT_BOX) return;
+//     t += 2; // convert box to frame
+//   }
+  draw_box((Fl_Boxtype)t, x_, y_, w_, h_, (Fl_Color)color_);
+}
+
+void Fl_Widget::draw_box(Fl_Boxtype b, Fl_Color c) const {
+  draw_box(b, x_, y_, w_, h_, c);
+}
+
+void Fl_Widget::draw_box(Fl_Boxtype b, int X, int Y, int W, int H, Fl_Color c)
+const {
+  draw_it_active = active_r();
+  fl_box_table[b].f(X, Y, W, H, c);
+  draw_it_active = 1;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_call_main.c b/Utilities/FLTK/src/fl_call_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..81c1baef68f4417eaf63c822dc8f7f6c66ba5263
--- /dev/null
+++ b/Utilities/FLTK/src/fl_call_main.c
@@ -0,0 +1,107 @@
+/*
+ * "$Id$"
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * fl_call_main() calls main() for you Windows people.  Needs to be done in C
+ * because Borland C++ won't let you call main() from C++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+/*
+ * This WinMain() function can be overridden by an application and
+ * is provided for compatibility with programs written for other
+ * operating systems that conform to the ANSI standard entry point
+ * "main()".  This will allow you to build a WIN32 Application
+ * without any special settings.
+ *
+ * Because of problems with the Microsoft Visual C++ header files
+ * and/or compiler, you cannot have a WinMain function in a DLL.
+ * I don't know why.  Thus, this nifty feature is only available
+ * if you link to the static library.
+ *
+ * Currently the debug version of this library will create a
+ * console window for your application so you can put printf()
+ * statements for debugging or informational purposes.  Ultimately
+ * we want to update this to always use the parent's console,
+ * but at present we have not identified a function or API in
+ * Microsoft(r) Windows(r) that allows for it.
+ */
+
+#if defined(WIN32) && !defined(FL_DLL) && !defined (__GNUC__)
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __MWERKS__
+# include <crtl.h>
+#endif
+
+extern int main(int, char *[]);
+
+#ifdef BORLAND5
+# define __argc _argc
+# define __argv _argv
+#endif
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+                             LPSTR lpCmdLine, int nCmdShow) {
+  int rc;
+
+#ifdef _DEBUG
+ /*
+  * If we are using compiling in debug mode, open a console window so
+  * we can see any printf's, etc...
+  *
+  * While we can detect if the program was run from the command-line -
+  * look at the CMDLINE environment variable, it will be "WIN" for
+  * programs started from the GUI - the shell seems to run all WIN32
+  * applications in the background anyways...
+  */
+
+  AllocConsole();
+  freopen("conin$", "r", stdin);
+  freopen("conout$", "w", stdout);
+  freopen("conout$", "w", stderr);
+#endif /* _DEBUG */
+
+  /* Run the standard main entry point function... */
+  rc = main(__argc, __argv);
+
+#ifdef _DEBUG
+  fclose(stdin);
+  fclose(stdout);
+  fclose(stderr);
+#endif /* _DEBUG */
+
+  return rc;
+}
+
+#else
+/* This code to prevent "empty translation unit" or similar warnings... */
+static void dummy(void) {dummy();}
+#endif
+
+/*
+ * End of "$Id$".
+ */
+
diff --git a/Utilities/FLTK/src/fl_cmap.h b/Utilities/FLTK/src/fl_cmap.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b05ee7cf525abc41943d6b50e8f4bad1875fdf1
--- /dev/null
+++ b/Utilities/FLTK/src/fl_cmap.h
@@ -0,0 +1,256 @@
+	0x00000000,
+	0xff000000,
+	0x00ff0000,
+	0xffff0000,
+	0x0000ff00,
+	0xff00ff00,
+	0x00ffff00,
+	0xffffff00,
+	0x55555500,
+	0xc6717100,
+	0x71c67100,
+	0x8e8e3800,
+	0x7171c600,
+	0x8e388e00,
+	0x388e8e00,
+	0x00008000,
+	0xa8a89800,
+	0xe8e8d800,
+	0x68685800,
+	0x98a8a800,
+	0xd8e8e800,
+	0x58686800,
+	0x9c9ca800,
+	0xdcdce800,
+	0x5c5c6800,
+	0x9ca89c00,
+	0xdce8dc00,
+	0x5c685c00,
+	0x90909000,
+	0xc0c0c000,
+	0x50505000,
+	0xa0a0a000,
+	0x00000000,
+	0x0d0d0d00,
+	0x1a1a1a00,
+	0x26262600,
+	0x31313100,
+	0x3d3d3d00,
+	0x48484800,
+	0x55555500,
+	0x5f5f5f00,
+	0x6a6a6a00,
+	0x75757500,
+	0x80808000,
+	0x8a8a8a00,
+	0x95959500,
+	0xa0a0a000,
+	0xaaaaaa00,
+	0xb5b5b500,
+	0xc0c0c000,
+	0xcbcbcb00,
+	0xd5d5d500,
+	0xe0e0e000,
+	0xeaeaea00,
+	0xf5f5f500,
+	0xffffff00,
+	0x00000000,
+	0x00240000,
+	0x00480000,
+	0x006d0000,
+	0x00910000,
+	0x00b60000,
+	0x00da0000,
+	0x00ff0000,
+	0x3f000000,
+	0x3f240000,
+	0x3f480000,
+	0x3f6d0000,
+	0x3f910000,
+	0x3fb60000,
+	0x3fda0000,
+	0x3fff0000,
+	0x7f000000,
+	0x7f240000,
+	0x7f480000,
+	0x7f6d0000,
+	0x7f910000,
+	0x7fb60000,
+	0x7fda0000,
+	0x7fff0000,
+	0xbf000000,
+	0xbf240000,
+	0xbf480000,
+	0xbf6d0000,
+	0xbf910000,
+	0xbfb60000,
+	0xbfda0000,
+	0xbfff0000,
+	0xff000000,
+	0xff240000,
+	0xff480000,
+	0xff6d0000,
+	0xff910000,
+	0xffb60000,
+	0xffda0000,
+	0xffff0000,
+	0x00003f00,
+	0x00243f00,
+	0x00483f00,
+	0x006d3f00,
+	0x00913f00,
+	0x00b63f00,
+	0x00da3f00,
+	0x00ff3f00,
+	0x3f003f00,
+	0x3f243f00,
+	0x3f483f00,
+	0x3f6d3f00,
+	0x3f913f00,
+	0x3fb63f00,
+	0x3fda3f00,
+	0x3fff3f00,
+	0x7f003f00,
+	0x7f243f00,
+	0x7f483f00,
+	0x7f6d3f00,
+	0x7f913f00,
+	0x7fb63f00,
+	0x7fda3f00,
+	0x7fff3f00,
+	0xbf003f00,
+	0xbf243f00,
+	0xbf483f00,
+	0xbf6d3f00,
+	0xbf913f00,
+	0xbfb63f00,
+	0xbfda3f00,
+	0xbfff3f00,
+	0xff003f00,
+	0xff243f00,
+	0xff483f00,
+	0xff6d3f00,
+	0xff913f00,
+	0xffb63f00,
+	0xffda3f00,
+	0xffff3f00,
+	0x00007f00,
+	0x00247f00,
+	0x00487f00,
+	0x006d7f00,
+	0x00917f00,
+	0x00b67f00,
+	0x00da7f00,
+	0x00ff7f00,
+	0x3f007f00,
+	0x3f247f00,
+	0x3f487f00,
+	0x3f6d7f00,
+	0x3f917f00,
+	0x3fb67f00,
+	0x3fda7f00,
+	0x3fff7f00,
+	0x7f007f00,
+	0x7f247f00,
+	0x7f487f00,
+	0x7f6d7f00,
+	0x7f917f00,
+	0x7fb67f00,
+	0x7fda7f00,
+	0x7fff7f00,
+	0xbf007f00,
+	0xbf247f00,
+	0xbf487f00,
+	0xbf6d7f00,
+	0xbf917f00,
+	0xbfb67f00,
+	0xbfda7f00,
+	0xbfff7f00,
+	0xff007f00,
+	0xff247f00,
+	0xff487f00,
+	0xff6d7f00,
+	0xff917f00,
+	0xffb67f00,
+	0xffda7f00,
+	0xffff7f00,
+	0x0000bf00,
+	0x0024bf00,
+	0x0048bf00,
+	0x006dbf00,
+	0x0091bf00,
+	0x00b6bf00,
+	0x00dabf00,
+	0x00ffbf00,
+	0x3f00bf00,
+	0x3f24bf00,
+	0x3f48bf00,
+	0x3f6dbf00,
+	0x3f91bf00,
+	0x3fb6bf00,
+	0x3fdabf00,
+	0x3fffbf00,
+	0x7f00bf00,
+	0x7f24bf00,
+	0x7f48bf00,
+	0x7f6dbf00,
+	0x7f91bf00,
+	0x7fb6bf00,
+	0x7fdabf00,
+	0x7fffbf00,
+	0xbf00bf00,
+	0xbf24bf00,
+	0xbf48bf00,
+	0xbf6dbf00,
+	0xbf91bf00,
+	0xbfb6bf00,
+	0xbfdabf00,
+	0xbfffbf00,
+	0xff00bf00,
+	0xff24bf00,
+	0xff48bf00,
+	0xff6dbf00,
+	0xff91bf00,
+	0xffb6bf00,
+	0xffdabf00,
+	0xffffbf00,
+	0x0000ff00,
+	0x0024ff00,
+	0x0048ff00,
+	0x006dff00,
+	0x0091ff00,
+	0x00b6ff00,
+	0x00daff00,
+	0x00ffff00,
+	0x3f00ff00,
+	0x3f24ff00,
+	0x3f48ff00,
+	0x3f6dff00,
+	0x3f91ff00,
+	0x3fb6ff00,
+	0x3fdaff00,
+	0x3fffff00,
+	0x7f00ff00,
+	0x7f24ff00,
+	0x7f48ff00,
+	0x7f6dff00,
+	0x7f91ff00,
+	0x7fb6ff00,
+	0x7fdaff00,
+	0x7fffff00,
+	0xbf00ff00,
+	0xbf24ff00,
+	0xbf48ff00,
+	0xbf6dff00,
+	0xbf91ff00,
+	0xbfb6ff00,
+	0xbfdaff00,
+	0xbfffff00,
+	0xff00ff00,
+	0xff24ff00,
+	0xff48ff00,
+	0xff6dff00,
+	0xff91ff00,
+	0xffb6ff00,
+	0xffdaff00,
+	0xffffff00
diff --git a/Utilities/FLTK/src/fl_color.cxx b/Utilities/FLTK/src/fl_color.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d2dcefb1c13737ae4d554891d99140452182d42c
--- /dev/null
+++ b/Utilities/FLTK/src/fl_color.cxx
@@ -0,0 +1,389 @@
+//
+// "$Id$"
+//
+// Color functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Implementation of fl_color(i), fl_color(r,g,b).
+
+#ifdef WIN32
+#  include "fl_color_win32.cxx"
+#elif defined(__APPLE__)
+#  include "fl_color_mac.cxx"
+#else
+
+// Also code to look at the X visual and figure out the best way to turn
+// a color into a pixel value.
+
+// SGI compiler seems to have problems with unsigned char arguments
+// being used to index arrays.  So I always copy them to an integer
+// before use.
+
+#  include "Fl_XColor.H"
+#  include <FL/Fl.H>
+#  include <FL/x.H>
+#  include <FL/fl_draw.H>
+
+////////////////////////////////////////////////////////////////
+// figure_out_visual() calculates masks & shifts for generating
+// pixels in true-color visuals:
+
+uchar fl_redmask, fl_greenmask, fl_bluemask;
+int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift;
+static uchar beenhere;
+
+static void figure_out_visual() {
+  beenhere = 1;
+  if (!fl_visual->red_mask || !fl_visual->green_mask || !fl_visual->blue_mask){
+#  if USE_COLORMAP
+    fl_redmask = 0;
+    return;
+#  else
+    Fl::fatal("Requires true color visual");
+#  endif
+  }
+
+  // get the bit masks into a more useful form:
+  int i,j,m;
+
+  for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->red_mask & m) break;
+  for (j = i; m; j++, m<<=1) if (!(fl_visual->red_mask & m)) break;
+  fl_redshift = j-8;
+  fl_redmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
+
+  for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->green_mask & m) break;
+  for (j = i; m; j++, m<<=1) if (!(fl_visual->green_mask & m)) break;
+  fl_greenshift = j-8;
+  fl_greenmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
+
+  for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->blue_mask & m) break;
+  for (j = i; m; j++, m<<=1) if (!(fl_visual->blue_mask & m)) break;
+  fl_blueshift = j-8;
+  fl_bluemask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
+
+  i = fl_redshift;
+  if (fl_greenshift < i) i = fl_greenshift;
+  if (fl_blueshift < i) i = fl_blueshift;
+  if (i < 0) {
+    fl_extrashift = -i;
+    fl_redshift -= i; fl_greenshift -= i; fl_blueshift -= i;
+  } else
+    fl_extrashift = 0;
+
+}
+
+static unsigned fl_cmap[256] = {
+#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
+};
+
+#  if HAVE_OVERLAY
+Fl_XColor fl_xmap[2][256];
+uchar fl_overlay;
+Colormap fl_overlay_colormap;
+XVisualInfo* fl_overlay_visual;
+ulong fl_transparent_pixel;
+#  else
+Fl_XColor fl_xmap[1][256];
+#    define fl_overlay 0
+#  endif
+
+////////////////////////////////////////////////////////////////
+// Get an rgb color.  This is easy for a truecolor visual.  For
+// colormapped it picks the closest color out of the cube in the
+// fltk colormap.  However if this color cube entry has been
+// requested before, you will get the earlier requested color, and
+// even this may be approximated if the X colormap was full.
+
+ulong fl_xpixel(uchar r,uchar g,uchar b) {
+  if (!beenhere) figure_out_visual();
+#  if USE_COLORMAP
+  if (!fl_redmask) {
+    // find closest entry in the colormap:
+    Fl_Color i =
+      fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256);
+    Fl_XColor &xmap = fl_xmap[fl_overlay][i];
+    if (xmap.mapped) return xmap.pixel;
+    // if not black or white, change the entry to be an exact match:
+    if (i != FL_COLOR_CUBE && i != 0xFF)
+      fl_cmap[i] = (r<<24)|(g<<16)|(b<<8);
+    return fl_xpixel(i); // allocate an X color
+  }
+#  endif
+  return
+    (((r&fl_redmask) << fl_redshift)+
+     ((g&fl_greenmask)<<fl_greenshift)+
+     ((b&fl_bluemask)<< fl_blueshift)
+     ) >> fl_extrashift;
+}
+
+void fl_color(uchar r,uchar g,uchar b) {
+  fl_color_ = fl_rgb_color(r, g, b);
+  XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b));
+}
+
+////////////////////////////////////////////////////////////////
+// Get a color out of the the fltk colormap.  Again for truecolor
+// visuals this is easy.  For colormap this actually tries to allocate
+// an X color, and does a least-squares match to find the closest
+// color if X cannot allocate that color.
+
+// calculate what color is actually on the screen for a mask:
+static inline uchar realcolor(uchar color, uchar mask) {
+#  if 0
+  // accurate version if the display has linear gamma, but fl_draw_image
+  // works better with the simpler version on most screens...
+  uchar m = mask;
+  uchar result = color&m;
+  for (;;) {
+    while (m&mask) {m>>=1; color>>=1;}
+    if (!m) break;
+    mask = m;
+    result |= color&m;
+  }
+  return result;
+#  else
+  return (color&mask) | (~mask)&(mask>>1);
+#  endif
+}
+
+ulong fl_xpixel(Fl_Color i) {
+  if (i & 0xffffff00) {
+    return fl_xpixel((i >> 24) & 255, (i >> 16) & 255, (i >> 8) & 255);
+  }
+
+  Fl_XColor &xmap = fl_xmap[fl_overlay][i];
+  if (xmap.mapped) return xmap.pixel;
+
+  if (!beenhere) figure_out_visual();
+
+  uchar r,g,b;
+  {unsigned c = fl_cmap[i]; r=uchar(c>>24); g=uchar(c>>16); b=uchar(c>>8);}
+
+#  if USE_COLORMAP
+  Colormap colormap = fl_colormap;
+#    if HAVE_OVERLAY
+  if (fl_overlay) colormap = fl_overlay_colormap; else
+#    endif
+  if (fl_redmask) {
+#  endif
+    // return color for a truecolor visual:
+    xmap.mapped = 2; // 2 prevents XFreeColor from being called
+    xmap.r = realcolor(r, fl_redmask);
+    xmap.g = realcolor(g, fl_greenmask);
+    xmap.b = realcolor(b, fl_bluemask);
+    return xmap.pixel = 
+      (((r&fl_redmask) << fl_redshift)+
+       ((g&fl_greenmask)<<fl_greenshift)+
+       ((b&fl_bluemask)<< fl_blueshift)
+       ) >> fl_extrashift;
+#  if USE_COLORMAP
+  }
+#    if HAVE_OVERLAY
+  static XColor* ac[2];
+  XColor*& allcolors = ac[fl_overlay];
+  static int nc[2];
+  int& numcolors = nc[fl_overlay];
+#    else
+  static XColor *allcolors;
+  static int numcolors;
+#    endif
+
+  // I don't try to allocate colors with XAllocColor once it fails
+  // with any color.  It is possible that it will work, since a color
+  // may have been freed, but some servers are extremely slow and this
+  // avoids one round trip:
+  if (!numcolors) { // don't try after a failure
+    XColor xcol;
+    xcol.red = r<<8; xcol.green = g<<8; xcol.blue = b<<8;
+    if (XAllocColor(fl_display, colormap, &xcol)) {
+      xmap.mapped = 1;
+      xmap.r = xcol.red>>8;
+      xmap.g = xcol.green>>8;
+      xmap.b = xcol.blue>>8;
+      return xmap.pixel = xcol.pixel;
+    }
+
+    // I only read the colormap once.  Again this is due to the slowness
+    // of round-trips to the X server, even though other programs may alter
+    // the colormap after this and make decisions here wrong.
+#    if HAVE_OVERLAY
+    if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else
+#    endif
+      numcolors = fl_visual->colormap_size;
+    if (!allcolors) allcolors = new XColor[numcolors];
+    for (int p = numcolors; p--;) allcolors[p].pixel = p;
+    XQueryColors(fl_display, colormap, allcolors, numcolors);
+  }
+
+  // find least-squares match:
+  int mindist = 0x7FFFFFFF;
+  unsigned int bestmatch = 0;
+  for (unsigned int n = numcolors; n--;) {
+#    if HAVE_OVERLAY
+    if (fl_overlay && n == fl_transparent_pixel) continue;
+#    endif
+    XColor &a = allcolors[n];
+    int d, t;
+    t = int(r)-int(a.red>>8); d = t*t;
+    t = int(g)-int(a.green>>8); d += t*t;
+    t = int(b)-int(a.blue>>8); d += t*t;
+    if (d <= mindist) {bestmatch = n; mindist = d;}
+  }
+  XColor &p = allcolors[bestmatch];
+
+  // It appears to "work" to not call this XAllocColor, which will
+  // avoid another round-trip to the server.  But then X does not
+  // know that this program "owns" this value, and can (and will)
+  // change it when the program that did allocate it exits:
+  if (XAllocColor(fl_display, colormap, &p)) {
+    xmap.mapped = 1;
+    xmap.pixel = p.pixel;
+  } else {
+    // However, if that XAllocColor fails, I have to give up and
+    // assumme the pixel is ok for the duration of the program.  This
+    // is due to bugs (?) in the Solaris X and some X terminals
+    // where XAllocColor *always* fails when the colormap is full,
+    // even if we ask for a color already in it...
+    xmap.mapped = 2; // 2 prevents XFreeColor from being called
+    xmap.pixel = bestmatch;
+  }
+  xmap.r = p.red>>8;
+  xmap.g = p.green>>8;
+  xmap.b = p.blue>>8;
+  return xmap.pixel;
+#  endif
+}
+
+Fl_Color fl_color_;
+
+void fl_color(Fl_Color i) {
+  if (i & 0xffffff00) {
+    unsigned rgb = (unsigned)i;
+    fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
+  } else {
+    fl_color_ = i;
+    XSetForeground(fl_display, fl_gc, fl_xpixel(i));
+  }
+}
+
+void Fl::free_color(Fl_Color i, int overlay) {
+#  if HAVE_OVERLAY
+#  else
+  if (overlay) return;
+#  endif
+  if (fl_xmap[overlay][i].mapped) {
+#  if USE_COLORMAP
+#    if HAVE_OVERLAY
+    Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap;
+#    else
+    Colormap colormap = fl_colormap;
+#    endif
+    if (fl_xmap[overlay][i].mapped == 1)
+      XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1, 0);
+#  endif
+    fl_xmap[overlay][i].mapped = 0;
+  }
+}
+
+void Fl::set_color(Fl_Color i, unsigned c) {
+  if (fl_cmap[i] != c) {
+    free_color(i,0);
+#  if HAVE_OVERLAY
+    free_color(i,1);
+#  endif
+    fl_cmap[i] = c;
+  }
+}
+
+#endif // end of X-specific code
+
+unsigned Fl::get_color(Fl_Color i) {
+  if (i & 0xffffff00) return (i);
+  else return fl_cmap[i];
+}
+
+void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) {
+  Fl::set_color((Fl_Color)(i & 255),
+	((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8));
+}
+
+void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) {
+  unsigned c;
+
+  if (i & 0xffffff00) c = (unsigned)i;
+  else c = fl_cmap[i];
+
+  red   = uchar(c>>24);
+  green = uchar(c>>16);
+  blue  = uchar(c>>8);
+}
+
+Fl_Color fl_color_average(Fl_Color color1, Fl_Color color2, float weight) {
+  unsigned rgb1;
+  unsigned rgb2;
+  uchar r, g, b;
+
+  if (color1 & 0xffffff00) rgb1 = color1;
+  else rgb1 = fl_cmap[color1 & 255];
+
+  if (color2 & 0xffffff00) rgb2 = color2;
+  else rgb2 = fl_cmap[color2 & 255];
+
+  r = (uchar)(((uchar)(rgb1>>24))*weight + ((uchar)(rgb2>>24))*(1-weight));
+  g = (uchar)(((uchar)(rgb1>>16))*weight + ((uchar)(rgb2>>16))*(1-weight));
+  b = (uchar)(((uchar)(rgb1>>8))*weight + ((uchar)(rgb2>>8))*(1-weight));
+
+  return fl_rgb_color(r, g, b);
+}
+
+Fl_Color fl_inactive(Fl_Color c) {
+  return fl_color_average(c, FL_GRAY, .33f);
+}
+
+Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) {
+  unsigned c1, c2;	// RGB colors
+  int l1, l2;		// Luminosities
+
+
+  // Get the RGB values for each color...
+  if (fg & 0xffffff00) c1 = (unsigned)fg;
+  else c1 = fl_cmap[fg];
+
+  if (bg & 0xffffff00) c2 = (unsigned)bg;
+  else c2 = fl_cmap[bg];
+
+  // Compute the luminosity...
+  l1 = ((c1 >> 24) * 31 + ((c1 >> 16) & 255) * 61 + ((c1 >> 8) & 255) * 8) / 100;
+  l2 = ((c2 >> 24) * 31 + ((c2 >> 16) & 255) * 61 + ((c2 >> 8) & 255) * 8) / 100;
+
+  // Compare and return the contrasting color...
+  if ((l1 - l2) > 127) return fg;
+  else if ((l2 - l1) > 127) return fg;
+  else if (l2 > 127) return FL_BLACK;
+  else return FL_WHITE;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_color_mac.cxx b/Utilities/FLTK/src/fl_color_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a69dc42fe0ced9c97f52f0076d7deded45dba09d
--- /dev/null
+++ b/Utilities/FLTK/src/fl_color_mac.cxx
@@ -0,0 +1,115 @@
+//
+// "$Id$"
+//
+// MacOS color functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// The fltk "colormap".  This allows ui colors to be stored in 8-bit
+// locations, and provides a level of indirection so that global color
+// changes can be made.  Not to be confused with the X colormap, which
+// I try to hide completely.
+
+// matt: Neither Quartz nor Quickdraw support colormaps in this implementation
+// matt: Quartz support done
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+static unsigned fl_cmap[256] = {
+#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
+};
+
+// Translations to mac data structures:
+Fl_XMap fl_xmap[256];
+
+Fl_XMap* fl_current_xmap;
+
+Fl_Color fl_color_;
+
+void fl_color(Fl_Color i) {
+  fl_color_ = i;
+  int index;
+  uchar r, g, b;
+  if (i & 0xFFFFFF00) {
+    // translate rgb colors into color index
+    r = i>>24;
+    g = i>>16;
+    b = i>> 8;
+  } else {
+    // translate index into rgb:
+    index = i;
+    unsigned c = fl_cmap[i];
+    r = c>>24;
+    g = c>>16;
+    b = c>> 8;
+  }
+#ifdef __APPLE_QD__
+  RGBColor rgb; 
+  rgb.red   = (r<<8)|r;
+  rgb.green = (g<<8)|g;
+  rgb.blue  = (b<<8)|b;
+  RGBForeColor(&rgb);
+#elif defined(__APPLE_QUARTZ__)
+  if (!fl_gc) return; // no context yet? We will assign the color later.
+  float fr = r/255.0f;
+  float fg = g/255.0f;
+  float fb = b/255.0f;
+  CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f);
+  CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f);
+#else
+#  error : neither Quickdraw nor Quartz defined
+#endif
+}
+
+void fl_color(uchar r, uchar g, uchar b) {
+  fl_color_ = fl_rgb_color(r, g, b);
+#ifdef __APPLE_QD__
+  RGBColor rgb; 
+  rgb.red   = (r<<8)|r;
+  rgb.green = (g<<8)|g;
+  rgb.blue  = (b<<8)|b;
+  RGBForeColor(&rgb);
+#elif defined(__APPLE_QUARTZ__)
+  float fr = r/255.0f;
+  float fg = g/255.0f;
+  float fb = b/255.0f;
+  CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f);
+  CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f);
+#else
+#  error : neither Quickdraw nor Quartz defined
+#endif
+}
+
+void Fl::set_color(Fl_Color i, unsigned c) {
+  if (fl_cmap[i] != c) {
+    fl_cmap[i] = c;
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_color_win32.cxx b/Utilities/FLTK/src/fl_color_win32.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..faee2335a52b8ffa1830233f11d64e4a0f56d36d
--- /dev/null
+++ b/Utilities/FLTK/src/fl_color_win32.cxx
@@ -0,0 +1,255 @@
+//
+// "$Id$"
+//
+// WIN32 color functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// The fltk "colormap".  This allows ui colors to be stored in 8-bit
+// locations, and provides a level of indirection so that global color
+// changes can be made.  Not to be confused with the X colormap, which
+// I try to hide completely.
+
+// SGI compiler seems to have problems with unsigned char arguments
+// being used to index arrays.  So I always copy them to an integer
+// before use.
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+static unsigned fl_cmap[256] = {
+#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
+};
+
+// Translations to win32 data structures:
+Fl_XMap fl_xmap[256];
+
+Fl_XMap* fl_current_xmap;
+
+HPALETTE fl_palette;
+static HGDIOBJ tmppen=0;
+static HPEN savepen=0;
+
+void fl_cleanup_pens(void) {
+  for (int i=0; i<256; i++) {
+    if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen);
+  }
+}
+
+void fl_save_pen(void) {
+    if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0);
+    savepen = (HPEN)SelectObject(fl_gc, tmppen);
+}
+
+void fl_restore_pen(void) {
+    if (savepen) SelectObject(fl_gc, savepen);
+    DeleteObject(tmppen);
+    tmppen = 0;
+    savepen = 0;
+}
+
+static void clear_xmap(Fl_XMap& xmap) {
+  if (xmap.pen) {
+    HGDIOBJ tmppen = GetStockObject(BLACK_PEN);
+    HGDIOBJ oldpen = SelectObject(fl_gc, tmppen);       // Push out the current pen of the gc
+    if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete
+    DeleteObject((HGDIOBJ)(xmap.pen));
+    xmap.pen = 0;
+    xmap.brush = -1;
+  }
+}
+
+static void set_xmap(Fl_XMap& xmap, COLORREF c) {
+  xmap.rgb = c;
+  if (xmap.pen) {
+      HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one
+      if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen);              // if old one not xmap.pen, need to put it back
+      DeleteObject(xmap.pen);                                         // delete pen
+  }
+  xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb);                        // get a pen into xmap.pen
+  xmap.brush = -1;
+}
+
+Fl_Color fl_color_;
+
+void fl_color(Fl_Color i) {
+  if (i & 0xffffff00) {
+    unsigned rgb = (unsigned)i;
+    fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
+  } else {
+    fl_color_ = i;
+    Fl_XMap &xmap = fl_xmap[i];
+    if (!xmap.pen) {
+#if USE_COLORMAP
+      if (fl_palette) {
+	set_xmap(xmap, PALETTEINDEX(i));
+      } else {
+#endif
+	unsigned c = fl_cmap[i];
+	set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8)));
+#if USE_COLORMAP
+      }
+#endif
+    }
+    fl_current_xmap = &xmap;
+    SelectObject(fl_gc, (HGDIOBJ)(xmap.pen));
+  }
+}
+
+void fl_color(uchar r, uchar g, uchar b) {
+  static Fl_XMap xmap;
+  COLORREF c = RGB(r,g,b);
+  fl_color_ = fl_rgb_color(r, g, b);
+  if (!xmap.pen || c != xmap.rgb) {
+    clear_xmap(xmap);
+    set_xmap(xmap, c);
+  }
+  fl_current_xmap = &xmap;
+  SelectObject(fl_gc, (HGDIOBJ)(xmap.pen));
+}
+
+HBRUSH fl_brush() {
+  return fl_brush_action(0);
+}
+
+HBRUSH fl_brush_action(int action) {
+  Fl_XMap *xmap = fl_current_xmap;
+  // Wonko: we use some statistics to cache only a limited number
+  // of brushes:
+#define FL_N_BRUSH 16
+  static struct Fl_Brush {
+    HBRUSH brush;
+    unsigned short usage;
+    Fl_XMap* backref;
+  } brushes[FL_N_BRUSH];
+
+  if (action) {
+    SelectObject(fl_gc, GetStockObject(BLACK_BRUSH));  // Load stock object
+    for (int i=0; i<FL_N_BRUSH; i++) {
+      if (brushes[i].brush)
+        DeleteObject(brushes[i].brush); // delete all brushes in array
+    }
+    return NULL;
+  }
+
+  int i = xmap->brush; // find the associated brush
+  if (i != -1) { // if the brush was allready allocated
+    if (brushes[i].brush == NULL) goto CREATE_BRUSH;
+    if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic
+      for (int j=0; j<FL_N_BRUSH; j++) {
+	if (brushes[j].usage>16000)
+	  brushes[j].usage -= 16000;
+	else 
+	  brushes[j].usage = 0;
+      }
+    }
+    return brushes[i].brush;
+  } else {
+    int umin = 32000, imin = 0;
+    for (i=0; i<FL_N_BRUSH; i++) {
+      if (brushes[i].brush == NULL) goto CREATE_BRUSH;
+      if (brushes[i].usage<umin) {
+	umin = brushes[i].usage;
+	imin = i;
+      }
+    }
+    i = imin;
+    HGDIOBJ tmpbrush = GetStockObject(BLACK_BRUSH);  // get a stock brush
+    HGDIOBJ oldbrush = SelectObject(fl_gc,tmpbrush); // load in into current context
+    if (oldbrush != brushes[i].brush) SelectObject(fl_gc,oldbrush);  // reload old one
+    DeleteObject(brushes[i].brush);      // delete the one in list
+    brushes[i].brush = NULL;
+    brushes[i].backref->brush = -1;
+  }
+CREATE_BRUSH:
+  brushes[i].brush = CreateSolidBrush(xmap->rgb);
+  brushes[i].usage = 0;
+  brushes[i].backref = xmap;
+  xmap->brush = i;
+  return brushes[i].brush;
+}
+
+void Fl::free_color(Fl_Color i, int overlay) {
+  if (overlay) return; // do something about GL overlay?
+  clear_xmap(fl_xmap[i]);
+}
+
+void Fl::set_color(Fl_Color i, unsigned c) {
+  if (fl_cmap[i] != c) {
+    clear_xmap(fl_xmap[i]);
+    fl_cmap[i] = c;
+  }
+}
+
+#if USE_COLORMAP
+
+// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary
+// Thanks to Michael Sweet @ Easy Software Products for this
+
+HPALETTE
+fl_select_palette(void)
+{
+  static char beenhere;
+  if (!beenhere) {
+    beenhere = 1;
+
+    //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL;
+    int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE);
+    if (nColors <= 0 || nColors > 256) return NULL;
+    // this will try to work on < 256 color screens, but will probably
+    // come out quite badly.
+
+    // I lamely try to get this variable-sized object allocated on stack:
+    ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1];
+    LOGPALETTE *pPal = (LOGPALETTE*)foo;
+
+    pPal->palVersion    = 0x300;
+    pPal->palNumEntries = nColors;
+
+    // Build 256 colors from the standard FLTK colormap...
+
+    for (int i = 0; i < nColors; i ++) {
+      pPal->palPalEntry[i].peRed   = (fl_cmap[i] >> 24) & 255;
+      pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255;
+      pPal->palPalEntry[i].peBlue  = (fl_cmap[i] >>  8) & 255;
+      pPal->palPalEntry[i].peFlags = 0;
+    };
+
+    // Create the palette:
+    fl_palette = CreatePalette(pPal);
+  }
+  if (fl_palette) {
+    SelectPalette(fl_gc, fl_palette, FALSE);
+    RealizePalette(fl_gc);
+  }
+  return fl_palette;
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_cursor.cxx b/Utilities/FLTK/src/fl_cursor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..651c098d568aa7356a0b9025ed5f8311a9451c46
--- /dev/null
+++ b/Utilities/FLTK/src/fl_cursor.cxx
@@ -0,0 +1,326 @@
+//
+// "$Id$"
+//
+// Mouse cursor support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Change the current cursor.
+// Under X the cursor is attached to the X window.  I tried to hide
+// this and pretend that changing the cursor is a drawing function.
+// This avoids a field in the Fl_Window, and I suspect is more
+// portable to other systems.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#if !defined(WIN32) && !defined(__APPLE__)
+#  include <X11/cursorfont.h>
+#endif
+#include <FL/fl_draw.H>
+
+void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
+  if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg);
+}
+
+void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
+//  if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW;
+
+  cursor_default = c;
+  cursor_fg      = fg;
+  cursor_bg      = bg;
+
+  cursor(c, fg, bg);
+}
+
+#ifdef WIN32
+
+#  ifndef IDC_HAND
+#    define IDC_HAND	MAKEINTRESOURCE(32649)
+#  endif // !IDC_HAND
+
+void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) {
+  if (!shown()) return;
+  // the cursor must be set for the top level window, not for subwindows
+  Fl_Window *w = window(), *toplevel = this;
+  while (w) { toplevel = w; w = w->window(); }
+  if (toplevel != this) { toplevel->cursor(c, c1, c2); return; }
+  // now set the actual cursor
+  if (c == FL_CURSOR_DEFAULT) {
+    c = cursor_default;
+  }
+  if (c > FL_CURSOR_NESW) {
+    i->cursor = 0;
+  } else if (c == FL_CURSOR_DEFAULT) {
+    i->cursor = fl_default_cursor;
+  } else {
+    LPSTR n;
+    switch (c) {
+    case FL_CURSOR_ARROW:	n = IDC_ARROW; break;
+    case FL_CURSOR_CROSS:	n = IDC_CROSS; break;
+    case FL_CURSOR_WAIT:	n = IDC_WAIT; break;
+    case FL_CURSOR_INSERT:	n = IDC_IBEAM; break;
+    case FL_CURSOR_HELP:	n = IDC_HELP; break;
+    case FL_CURSOR_HAND: {
+          OSVERSIONINFO osvi;
+
+          // Get the OS version: Windows 98 and 2000 have a standard
+	  // hand cursor.
+          memset(&osvi, 0, sizeof(OSVERSIONINFO));
+          osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+          GetVersionEx(&osvi);
+
+          if (osvi.dwMajorVersion > 4 ||
+  	      (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 &&
+  	       osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) n = IDC_HAND;
+          else n = IDC_UPARROW;
+	} break;
+    case FL_CURSOR_MOVE:	n = IDC_SIZEALL; break;
+    case FL_CURSOR_N:
+    case FL_CURSOR_S:
+    case FL_CURSOR_NS:		n = IDC_SIZENS; break;
+    case FL_CURSOR_NE:
+    case FL_CURSOR_SW:
+    case FL_CURSOR_NESW:	n = IDC_SIZENESW; break;
+    case FL_CURSOR_E:
+    case FL_CURSOR_W:
+    case FL_CURSOR_WE:		n = IDC_SIZEWE; break;
+    case FL_CURSOR_SE:
+    case FL_CURSOR_NW:
+    case FL_CURSOR_NWSE:	n = IDC_SIZENWSE; break;
+    default:			n = IDC_NO; break;
+    }
+    i->cursor = LoadCursor(NULL, n);
+  }
+  SetCursor(i->cursor);
+}
+
+#elif defined(__APPLE__)
+
+// warning: this function is only implemented in Quickdraw. The function
+//          below may not work If FLTK is compiled with Quartz enabled
+
+static Cursor crsrHAND =
+{
+  { 0x0600, 0x0900, 0x0900, 0x0900, 0x09C0, 0x0938, 0x6926, 0x9805,
+    0x8801, 0x4801, 0x2002, 0x2002, 0x1004, 0x0804, 0x0408, 0x0408 },
+  { 0x0600, 0x0F00, 0x0F00, 0x0F00, 0x0FC0, 0x0FF8, 0x6FFE, 0xFFFF,
+    0xFFFF, 0x7FFF, 0x3FFE, 0x3FFE, 0x1FFC, 0x0FFC, 0x07F8, 0x07F8 },
+  { 1, 5 } // Hotspot: ( y, x )
+}, *crsrHANDptr = &crsrHAND;
+static Cursor crsrHELP =
+{
+  { 0x0000, 0x4000, 0x6000, 0x7000, 0x783C, 0x7C7E, 0x7E66, 0x7F06,
+    0x7F8C, 0x7C18, 0x6C18, 0x4600, 0x0618, 0x0318, 0x0300, 0x0000 },
+  { 0xC000, 0xE000, 0xF000, 0xF83C, 0xFC7E, 0xFEFF, 0xFFFF, 0xFFFF,
+    0xFFFE, 0xFFFC, 0xFE3C, 0xEF3C, 0xCF3C, 0x07BC, 0x0798, 0x0380 },
+  { 1, 1 }
+}, *crsrHELPptr = &crsrHELP;
+static Cursor crsrMOVE =
+{
+  { 0x0000, 0x0180, 0x03C0, 0x07E0, 0x07E0, 0x1998, 0x399C, 0x7FFE,
+    0x7FFE, 0x399C, 0x1998, 0x07E0, 0x07E0, 0x03C0, 0x0180, 0x0000 },
+  { 0x0180, 0x03C0, 0x07E0, 0x0FF0, 0x1FF8, 0x3FFC, 0x7FFE, 0xFFFF,
+    0xFFFF, 0x7FFE, 0x3FFC, 0x1FF8, 0x0FF0, 0x07E0, 0x03C0, 0x0180 },
+  { 8, 8 }
+}, *crsrMOVEptr = &crsrMOVE;
+static Cursor crsrNS =
+{
+  { 0x0000, 0x0180, 0x03C0, 0x07E0, 0x0FF0, 0x0180, 0x0180, 0x0180,
+    0x0180, 0x0180, 0x0180, 0x0FF0, 0x07E0, 0x03C0, 0x0180, 0x0000 },
+  { 0x0180, 0x03C0, 0x07E0, 0x0FF0, 0x1FF8, 0x1FF8, 0x03C0, 0x03C0,
+    0x03C0, 0x03C0, 0x1FF8, 0x1FF8, 0x0FF0, 0x07E0, 0x03C0, 0x0180 },
+  { 8, 8 }
+}, *crsrNSptr = &crsrNS;
+static Cursor crsrWE =
+{
+  { 0x0000, 0x0000, 0x0000, 0x0000, 0x0810, 0x1818, 0x381C, 0x7FFE,
+    0x7FFE, 0x381C, 0x1818, 0x0810, 0x0000, 0x0000, 0x0000, 0x0000 },
+  { 0x0000, 0x0000, 0x0000, 0x0C30, 0x1C38, 0x3C3C, 0x7FFE, 0xFFFF,
+    0xFFFF, 0x7FFE, 0x3C3C, 0x1C38, 0x0C30, 0x0000, 0x0000, 0x0000 },
+  { 8, 8 }
+}, *crsrWEptr = &crsrWE;
+static Cursor crsrNWSE =
+{
+  { 0x0000, 0x7E00, 0x7C00, 0x7800, 0x7C00, 0x6E00, 0x4710, 0x03B0,
+    0x01F0, 0x00F0, 0x01F0, 0x03F0, 0x0000, 0x0000, 0x0000, 0x0000 },
+  { 0xFF00, 0xFF00, 0xFE00, 0xFC00, 0xFE00, 0xFF18, 0xEFB8, 0xC7F8,
+    0x03F8, 0x01F8, 0x03F8, 0x07F8, 0x07F8, 0x0000, 0x0000, 0x0000 },
+  { 8, 8 }
+}, *crsrNWSEptr = &crsrNWSE;
+static Cursor crsrNESW =
+{
+  { 0x0000, 0x03F0, 0x01F0, 0x00F0, 0x01F0, 0x03B0, 0x4710, 0x6E00,
+    0x7C00, 0x7800, 0x7C00, 0x7E00, 0x0000, 0x0000, 0x0000, 0x0000 },
+  { 0x07F8, 0x07F8, 0x03F8, 0x01F8, 0x03F8, 0xC7F8, 0xEFB8, 0xFF18,
+    0xFE00, 0xFC00, 0xFE00, 0xFF00, 0xFF00, 0x0000, 0x0000, 0x0000 },
+  { 8, 8 }
+}, *crsrNESWptr = &crsrNESW;
+static Cursor crsrNONE =
+{
+  { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+  { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+  { 0, 0 }
+}, *crsrNONEptr = &crsrNONE;
+static Cursor crsrARROW =
+{
+  { 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00,
+    0x7F80, 0x7C00, 0x6C00, 0x4600, 0x0600, 0x0300, 0x0300, 0x0000 },
+  { 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80,
+    0xFFC0, 0xFFC0, 0xFE00, 0xEF00, 0xCF00, 0x0780, 0x0780, 0x0380 },
+  { 1, 1 }
+}, *crsrARROWptr = &crsrARROW;
+
+
+void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
+  if (!shown()) return;
+  if (c == FL_CURSOR_DEFAULT) {
+    c = cursor_default;
+  }
+  switch (c) {
+  case FL_CURSOR_CROSS:     i->cursor = GetCursor( crossCursor ); break;
+  case FL_CURSOR_WAIT:      i->cursor = GetCursor( watchCursor ); break;
+  case FL_CURSOR_INSERT:    i->cursor = GetCursor( iBeamCursor ); break;
+  case FL_CURSOR_N:
+  case FL_CURSOR_S:
+  case FL_CURSOR_NS:        i->cursor = &crsrNSptr; break;
+  case FL_CURSOR_HELP:	i->cursor = &crsrHELPptr; break;
+  case FL_CURSOR_HAND:	i->cursor = &crsrHANDptr; break;
+  case FL_CURSOR_MOVE:	i->cursor = &crsrMOVEptr; break;
+  case FL_CURSOR_NE:
+  case FL_CURSOR_SW:
+  case FL_CURSOR_NESW:	i->cursor = &crsrNESWptr; break;
+  case FL_CURSOR_E:
+  case FL_CURSOR_W:
+  case FL_CURSOR_WE:	i->cursor = &crsrWEptr; break;
+  case FL_CURSOR_SE:
+  case FL_CURSOR_NW:
+  case FL_CURSOR_NWSE:	i->cursor = &crsrNWSEptr; break;
+  case FL_CURSOR_NONE:	i->cursor = &crsrNONEptr; break;
+  case FL_CURSOR_ARROW:   	i->cursor = &crsrARROWptr; break;
+  case FL_CURSOR_DEFAULT:
+  default:
+    i->cursor = fl_default_cursor; break;
+  }
+  SetCursor( *i->cursor );
+}
+
+#else
+
+// I like the MSWindows resize cursors, so I duplicate them here:
+
+#define CURSORSIZE 16
+#define HOTXY 7
+static struct TableEntry {
+  uchar bits[CURSORSIZE*CURSORSIZE/8];
+  uchar mask[CURSORSIZE*CURSORSIZE/8];
+  Cursor cursor;
+} table[] = {
+  {{	// FL_CURSOR_NS
+   0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
+   0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+   0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00},
+   {
+   0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
+   0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
+   0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}},
+  {{	// FL_CURSOR_EW
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
+   0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+   {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
+   0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+  {{	// FL_CURSOR_NWSE
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
+   0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
+   0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+   {
+   0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
+   0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
+   0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}},
+  {{	// FL_CURSOR_NESW
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e,
+   0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00,
+   0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+   {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f,
+   0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00,
+   0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}},
+  {{0}, {0}} // FL_CURSOR_NONE & unknown
+};
+
+void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
+  if (!shown()) return;
+  Cursor xc;
+  int deleteit = 0;
+  if (c == FL_CURSOR_DEFAULT) {
+    c  = cursor_default;
+    fg = cursor_fg;
+    bg = cursor_bg;
+  }
+
+  if (!c) {
+    xc = None;
+  } else {
+    if (c >= FL_CURSOR_NS) {
+      TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS);
+      if (!(q->cursor)) {
+	XColor dummy = { 0 };
+	Pixmap p = XCreateBitmapFromData(fl_display,
+	  RootWindow(fl_display, fl_screen), (const char*)(q->bits),
+	  CURSORSIZE, CURSORSIZE);
+	Pixmap m = XCreateBitmapFromData(fl_display,
+	  RootWindow(fl_display, fl_screen), (const char*)(q->mask),
+	  CURSORSIZE, CURSORSIZE);
+	q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy,
+					HOTXY, HOTXY);
+	XFreePixmap(fl_display, m);
+	XFreePixmap(fl_display, p);
+      }
+      xc = q->cursor;
+    } else {
+      xc = XCreateFontCursor(fl_display, (c-1)*2);
+      deleteit = 1;
+    }
+    XColor fgc;
+    uchar r,g,b;
+    Fl::get_color(fg,r,g,b);
+    fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8;
+    XColor bgc;
+    Fl::get_color(bg,r,g,b);
+    bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8;
+    XRecolorCursor(fl_display, xc, &fgc, &bgc);
+  }
+  XDefineCursor(fl_display, fl_xid(this), xc);
+  if (deleteit) XFreeCursor(fl_display, xc);
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_curve.cxx b/Utilities/FLTK/src/fl_curve.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e97579aa0a9b1162a01d23c576234551537c6499
--- /dev/null
+++ b/Utilities/FLTK/src/fl_curve.cxx
@@ -0,0 +1,106 @@
+//
+// "$Id$"
+//
+// Bezier curve functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Utility for drawing Bezier curves, adding the points to
+// the current fl_begin/fl_vertex/fl_end path.
+// Incremental math implementation:
+// I very much doubt this is optimal!  From Foley/vanDam page 511.
+// If anybody has a better algorithim, please send it!
+
+#include <FL/fl_draw.H>
+#include <math.h>
+
+void fl_curve(double X0, double Y0,
+	      double X1, double Y1,
+	      double X2, double Y2,
+	      double X3, double Y3) {
+
+  double x = fl_transform_x(X0,Y0);
+  double y = fl_transform_y(X0,Y0);
+
+  // draw point 0:
+  fl_transformed_vertex(x,y);
+
+  double x1 = fl_transform_x(X1,Y1);
+  double yy1 = fl_transform_y(X1,Y1);
+  double x2 = fl_transform_x(X2,Y2);
+  double y2 = fl_transform_y(X2,Y2);
+  double x3 = fl_transform_x(X3,Y3);
+  double y3 = fl_transform_y(X3,Y3);
+
+  // find the area:
+  double a = fabs((x-x2)*(y3-yy1)-(y-y2)*(x3-x1));
+  double b = fabs((x-x3)*(y2-yy1)-(y-y3)*(x2-x1));
+  if (b > a) a = b;
+
+  // use that to guess at the number of segments:
+  int n = int(sqrt(a)/4);
+  if (n > 1) {
+    if (n > 100) n = 100; // make huge curves not hang forever
+
+    double e = 1.0/n;
+
+    // calculate the coefficients of 3rd order equation:
+    double xa = (x3-3*x2+3*x1-x);
+    double xb = 3*(x2-2*x1+x);
+    double xc = 3*(x1-x);
+    // calculate the forward differences:
+    double dx1 = ((xa*e+xb)*e+xc)*e;
+    double dx3 = 6*xa*e*e*e;
+    double dx2 = dx3 + 2*xb*e*e;
+
+    // calculate the coefficients of 3rd order equation:
+    double ya = (y3-3*y2+3*yy1-y);
+    double yb = 3*(y2-2*yy1+y);
+    double yc = 3*(yy1-y);
+    // calculate the forward differences:
+    double dy1 = ((ya*e+yb)*e+yc)*e;
+    double dy3 = 6*ya*e*e*e;
+    double dy2 = dy3 + 2*yb*e*e;
+
+    // draw points 1 .. n-2:
+    for (int m=2; m<n; m++) {
+      x += dx1;
+      dx1 += dx2;
+      dx2 += dx3;
+      y += dy1;
+      dy1 += dy2;
+      dy2 += dy3;
+      fl_transformed_vertex(x,y);
+    }
+
+    // draw point n-1:
+    fl_transformed_vertex(x+dx1, y+dy1);
+  }
+
+  // draw point n:
+  fl_transformed_vertex(x3,y3);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_diamond_box.cxx b/Utilities/FLTK/src/fl_diamond_box.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..830a8beb70c41e33c6aea7216f4acd68e17a3c28
--- /dev/null
+++ b/Utilities/FLTK/src/fl_diamond_box.cxx
@@ -0,0 +1,80 @@
+//
+// "$Id$"
+//
+// Diamond box code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Box drawing code for an obscure box type.
+// These box types are in seperate files so they are not linked
+// in if not used.
+
+// The diamond box draws best if the area is square!
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+extern uchar* fl_gray_ramp();
+
+static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) {
+  w &= -2;
+  h &= -2;
+  int x1 = x+w/2;
+  int y1 = y+h/2;
+  fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
+  uchar *g = fl_gray_ramp();
+  fl_color(g['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
+  fl_color(g['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
+  fl_color(g['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1);
+  fl_color(g['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1);
+  fl_color(g['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
+  fl_color(g['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
+  fl_color(g['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h);
+}
+
+static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) {
+  w &= -2;
+  h &= -2;
+  int x1 = x+w/2;
+  int y1 = y+h/2;
+  uchar *g = fl_gray_ramp();
+  fl_color(g['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
+  fl_color(g['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
+  fl_color(g['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
+  fl_color(g['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
+  fl_color(g['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
+  fl_color(g['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
+  fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
+  fl_color(g['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype fl_define_FL_DIAMOND_BOX() {
+  fl_internal_boxtype(_FL_DIAMOND_DOWN_BOX, fl_diamond_down_box);
+  fl_internal_boxtype(_FL_DIAMOND_UP_BOX,fl_diamond_up_box);
+  return _FL_DIAMOND_UP_BOX;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_dnd.cxx b/Utilities/FLTK/src/fl_dnd.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1870bd7b363a45ae66f237d9970518adecd5a02b
--- /dev/null
+++ b/Utilities/FLTK/src/fl_dnd.cxx
@@ -0,0 +1,38 @@
+//
+// "$Id$"
+//
+// Drag & Drop code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#ifdef WIN32
+#  include "fl_dnd_win32.cxx"
+#elif defined(__APPLE__)
+#  include "fl_dnd_mac.cxx"
+#else
+#  include "fl_dnd_x.cxx"
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_dnd_mac.cxx b/Utilities/FLTK/src/fl_dnd_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4f805e842accd70b5212c9f30d78682724eb5189
--- /dev/null
+++ b/Utilities/FLTK/src/fl_dnd_mac.cxx
@@ -0,0 +1,91 @@
+//
+// "$Id$"
+//
+// Drag & Drop code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org
+
+// This file contains win32-specific code for fltk which is always linked
+// in.  Search other files for "WIN32" or filenames ending in _win32.cxx
+// for other system-specific code.
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+
+// warning: this function is only implemented in Quickdraw. The function
+//          below may not work If FLTK is compiled with Quartz enabled
+
+extern EventRef fl_os_event;
+extern char *fl_selection_buffer;
+extern int fl_selection_length;
+
+
+/**
+ * drag and drop whatever is in the cut-copy-paste buffer
+ * - create a selection first using: 
+ *     Fl::copy(const char *stuff, int len, 0)
+ */
+int Fl::dnd()
+{
+  OSErr result;
+  DragReference dragRef;
+  result = NewDrag( &dragRef );
+  if ( result != noErr ) return false;
+  
+  result = AddDragItemFlavor( dragRef, 1, 'TEXT', fl_selection_buffer, fl_selection_length, 0 );
+  if ( result != noErr ) { DisposeDrag( dragRef ); return false; }
+  
+  Point mp;
+  GetMouse(&mp);
+  LocalToGlobal( &mp );
+  RgnHandle region = NewRgn();
+  SetRectRgn( region, mp.h-10, mp.v-10, mp.h+10, mp.v+10 );
+  RgnHandle r2 = NewRgn();
+  SetRectRgn( r2, mp.h-8, mp.v-8, mp.h+8, mp.v+8 );
+  DiffRgn( region, r2, region );
+  DisposeRgn( r2 );
+
+  EventRecord event;
+  ConvertEventRefToEventRecord( fl_os_event, &event );
+  result = TrackDrag( dragRef, &event, region );
+
+  Fl_Widget *w = Fl::pushed();
+  if ( w )
+  {
+    int old_event = Fl::e_number;
+    w->handle(Fl::e_number = FL_RELEASE);
+    Fl::e_number = old_event;
+    Fl::pushed( 0 );
+  }
+
+  if ( result != noErr ) { DisposeRgn( region ); DisposeDrag( dragRef ); return false; }
+  
+  DisposeRgn( region );
+  DisposeDrag( dragRef );
+  return true;
+}
+  
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_dnd_win32.cxx b/Utilities/FLTK/src/fl_dnd_win32.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1475a6775e4250b43a5ec27ebdb8f48294daa17b
--- /dev/null
+++ b/Utilities/FLTK/src/fl_dnd_win32.cxx
@@ -0,0 +1,404 @@
+//
+// "$Id$"
+//
+// Drag & Drop code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org
+
+// This file contains win32-specific code for fltk which is always linked
+// in.  Search other files for "WIN32" or filenames ending in _win32.cxx
+// for other system-specific code.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include "flstring.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <time.h>
+#if defined(__CYGWIN__)
+#include <sys/time.h>
+#include <unistd.h>
+#else
+#include <winsock.h>
+#endif
+
+extern char *fl_selection_buffer[2];
+extern int fl_selection_length[2];
+extern int fl_selection_buffer_length[2];
+extern char fl_i_own_selection[2];
+
+Fl_Window *fl_dnd_target_window = 0;
+
+// All of the following code requires GCC 3.x or a non-GNU compiler...
+#if !defined(__GNUC__) || __GNUC__ >= 3
+
+#include <ole2.h>
+#include <shellapi.h>
+
+/**
+ * subclass the IDropTarget to receive data from DnD operations
+ */
+class FLDropTarget : public IDropTarget
+{
+  DWORD m_cRefCount;
+  DWORD lastEffect;
+  int px, py;
+public:
+  FLDropTarget() : m_cRefCount(0) { } // initialize
+  HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) {
+    if (IID_IUnknown==riid || IID_IDropTarget==riid)
+    {
+      *ppvObject=this;
+      ((LPUNKNOWN)*ppvObject)->AddRef();
+      return S_OK;
+    }
+    *ppvObject = NULL;
+    return E_NOINTERFACE;
+  }
+  ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; }
+  ULONG STDMETHODCALLTYPE Release() {
+    long nTemp;
+    nTemp = --m_cRefCount;
+    if(nTemp==0)
+      delete this;
+    return nTemp;
+  }
+  HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD /*grfKeyState*/, POINTL pt, DWORD *pdwEffect) {
+    if( !pDataObj ) return E_INVALIDARG;
+    // set e_modifiers here from grfKeyState, set e_x and e_root_x
+    // check if FLTK handles this drag and return if it can't (i.e. BMP drag without filename)
+    POINT ppt; 
+    Fl::e_x_root = ppt.x = pt.x; 
+    Fl::e_y_root = ppt.y = pt.y;
+    HWND hWnd = WindowFromPoint( ppt );
+    Fl_Window *target = fl_find( hWnd );
+    if (target) {
+      Fl::e_x = Fl::e_x_root-target->x();
+      Fl::e_y = Fl::e_y_root-target->y();
+    }
+    fl_dnd_target_window = target;
+    px = pt.x; py = pt.y;
+    if (fillCurrentDragData(pDataObj)) {
+      // FLTK has no mechanism yet for the different drop effects, so we allow move and copy
+      if ( target && Fl::handle( FL_DND_ENTER, target ) )
+        *pdwEffect = DROPEFFECT_MOVE|DROPEFFECT_COPY; //|DROPEFFECT_LINK;
+      else
+        *pdwEffect = DROPEFFECT_NONE;
+    } else {
+      *pdwEffect = DROPEFFECT_NONE;
+    }
+    lastEffect = *pdwEffect;
+    return S_OK;
+  }
+  HRESULT STDMETHODCALLTYPE DragOver( DWORD /*grfKeyState*/, POINTL pt, DWORD *pdwEffect) {
+    if ( px==pt.x && py==pt.y ) 
+    {
+      *pdwEffect = lastEffect;
+      return S_OK;
+    }
+    if ( !fl_dnd_target_window )
+    {
+      *pdwEffect = lastEffect = DROPEFFECT_NONE;
+      return S_OK;
+    }
+    // set e_modifiers here from grfKeyState, set e_x and e_root_x
+    Fl::e_x_root = pt.x; 
+    Fl::e_y_root = pt.y;
+    if (fl_dnd_target_window) {
+      Fl::e_x = Fl::e_x_root-fl_dnd_target_window->x();
+      Fl::e_y = Fl::e_y_root-fl_dnd_target_window->y();
+    }
+    if (fillCurrentDragData(0)) {
+      // Fl_Group will change DND_DRAG into DND_ENTER and DND_LEAVE if needed
+      if ( Fl::handle( FL_DND_DRAG, fl_dnd_target_window ) )
+        *pdwEffect = DROPEFFECT_MOVE|DROPEFFECT_COPY; //|DROPEFFECT_LINK;
+      else 
+        *pdwEffect = DROPEFFECT_NONE;
+    } else {
+      *pdwEffect = DROPEFFECT_NONE;
+    }
+    px = pt.x; py = pt.y;
+    lastEffect = *pdwEffect;
+    return S_OK;
+  }
+  HRESULT STDMETHODCALLTYPE DragLeave() {
+    if ( fl_dnd_target_window && fillCurrentDragData(0))
+    {
+      Fl::handle( FL_DND_LEAVE, fl_dnd_target_window );
+      fl_dnd_target_window = 0;
+      clearCurrentDragData();
+    }
+    return S_OK;
+  }
+  HRESULT STDMETHODCALLTYPE Drop( IDataObject *data, DWORD /*grfKeyState*/, POINTL pt, DWORD* /*pdwEffect*/) {
+    if ( !fl_dnd_target_window )
+      return S_OK;
+    Fl_Window *target = fl_dnd_target_window;
+    fl_dnd_target_window = 0;
+    Fl::e_x_root = pt.x; 
+    Fl::e_y_root = pt.y;
+    if (target) {
+      Fl::e_x = Fl::e_x_root-target->x();
+      Fl::e_y = Fl::e_y_root-target->y();
+    }
+    // tell FLTK that the user released an object on this widget
+    if ( !Fl::handle( FL_DND_RELEASE, target ) )
+      return S_OK;
+    
+    Fl_Widget *w = target;
+    while (w->parent()) w = w->window();
+    HWND hwnd = fl_xid( (Fl_Window*)w );
+    if (fillCurrentDragData(data)) {
+      int old_event = Fl::e_number;
+      Fl::belowmouse()->handle(Fl::e_number = FL_PASTE); // e_text will be invalid after this call
+      Fl::e_number = old_event;
+      SetForegroundWindow( hwnd );
+      clearCurrentDragData();
+      return S_OK;
+    }
+    return S_OK;
+  }
+private:
+
+  static IDataObject *currDragRef;
+  static char *currDragData;
+  static int currDragSize; 
+  static char currDragResult;
+
+  static void clearCurrentDragData() {
+    currDragRef = 0;
+    if (currDragData) free(currDragData);
+    currDragData = 0;
+    currDragSize = 0;
+    currDragResult = 0;
+  }
+  static char fillCurrentDragData(IDataObject *data) {
+    // shortcut through this whole procedure if there is no fresh data
+    if (!data) 
+      return currDragResult;
+    // shortcut through this whole procedure if this is still the same drag event
+    // (* this is safe, because 'currDragRef' is cleared on Leave and Drop events)
+    if (data==currDragRef)
+      return currDragResult;
+
+    // clear currDrag* for a new drag event
+    clearCurrentDragData();
+
+    // fill currDrag* with ASCII data, if available
+    FORMATETC fmt = { 0 };
+    STGMEDIUM medium = { 0 };
+    fmt.tymed = TYMED_HGLOBAL;
+    fmt.dwAspect = DVASPECT_CONTENT;
+    fmt.lindex = -1;
+    fmt.cfFormat = CF_TEXT;
+    // if it is ASCII text, return a copy of it
+    if ( data->GetData( &fmt, &medium )==S_OK )
+    {
+      void *stuff = GlobalLock( medium.hGlobal );
+      Fl::e_length = strlen((char*)stuff);
+      Fl::e_text = strdup((char*)stuff);
+      GlobalUnlock( medium.hGlobal );
+      ReleaseStgMedium( &medium );
+      currDragResult = 1;
+      return currDragResult;
+    }
+    // else fill currDrag* with filenames, if possible
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.tymed = TYMED_HGLOBAL;
+    fmt.dwAspect = DVASPECT_CONTENT;
+    fmt.lindex = -1;
+    fmt.cfFormat = CF_HDROP;
+    // if it is a pathname list, send an FL_PASTE with a \n seperated list of filepaths
+    if ( data->GetData( &fmt, &medium )==S_OK )
+    {
+      HDROP hdrop = (HDROP)medium.hGlobal;
+      int i, n, nn = 0, nf = DragQueryFile( hdrop, (UINT)-1, 0, 0 );
+      for ( i=0; i<nf; i++ ) nn += DragQueryFile( hdrop, i, 0, 0 );
+      nn += nf;
+      Fl::e_length = nn-1;
+      char *dst = Fl::e_text = (char*)malloc(nn+1);
+      for ( i=0; i<nf; i++ ) {
+	n = DragQueryFile( hdrop, i, dst, nn );
+	dst += n;
+	if ( i<nf-1 ) *dst++ = '\n';
+      }
+      *dst = 0;
+      ReleaseStgMedium( &medium );
+      currDragResult = 1;
+      return currDragResult;
+    }
+    currDragResult = 0;
+    return currDragResult;
+  }
+} flDropTarget;
+
+IDropTarget *flIDropTarget = &flDropTarget;
+
+IDataObject *FLDropTarget::currDragRef = 0;
+char *FLDropTarget::currDragData = 0;
+int FLDropTarget::currDragSize = 0; 
+char FLDropTarget::currDragResult = 0;
+
+/**
+ * this class is needed to allow FLTK apps to be a DnD source
+ */
+class FLDropSource : public IDropSource
+{
+  DWORD m_cRefCount;
+public:
+  FLDropSource() { m_cRefCount = 0; }
+  HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) {
+    if (IID_IUnknown==riid || IID_IDropSource==riid)
+    {
+      *ppvObject=this;
+      ((LPUNKNOWN)*ppvObject)->AddRef();
+      return S_OK;
+    }
+    *ppvObject = NULL;
+    return E_NOINTERFACE;
+  }
+  ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; }
+  ULONG STDMETHODCALLTYPE Release() {
+    long nTemp;
+    nTemp = --m_cRefCount;
+    if(nTemp==0)
+      delete this;
+    return nTemp;
+  }
+  STDMETHODIMP GiveFeedback( ulong ) { return DRAGDROP_S_USEDEFAULTCURSORS; }
+  STDMETHODIMP QueryContinueDrag( BOOL esc, DWORD keyState ) { 
+    if ( esc ) 
+      return DRAGDROP_S_CANCEL;
+    if ( !(keyState & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) ) 
+      return DRAGDROP_S_DROP;
+    return S_OK;
+  }
+};
+
+/**
+ * this is the actual object that FLTK can drop somewhere
+ * - the implementation is minimal, but it should work with all decent Win32 drop targets
+ */
+class FLDataObject : public IDataObject
+{
+  DWORD m_cRefCount;
+public:
+  FLDataObject() { m_cRefCount = 1; }
+  HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) {
+    if (IID_IUnknown==riid || IID_IDataObject==riid)
+    {
+      *ppvObject=this;
+      ((LPUNKNOWN)*ppvObject)->AddRef();
+      return S_OK;
+    }
+    *ppvObject = NULL;
+    return E_NOINTERFACE;
+  }
+  ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; }
+  ULONG STDMETHODCALLTYPE Release() {
+    long nTemp;
+    nTemp = --m_cRefCount;
+    if(nTemp==0)
+      delete this;
+    return nTemp;
+  }
+  // GetData currently allows ASCII text through Global Memory only
+  HRESULT STDMETHODCALLTYPE GetData( FORMATETC *pformatetcIn, STGMEDIUM *pmedium ) {
+    if ((pformatetcIn->dwAspect & DVASPECT_CONTENT) &&
+        (pformatetcIn->tymed & TYMED_HGLOBAL) &&
+        (pformatetcIn->cfFormat == CF_TEXT))
+    {
+      HGLOBAL gh = GlobalAlloc( GHND, fl_selection_length[0]+1 );
+      char *pMem = (char*)GlobalLock( gh );
+      memmove( pMem, fl_selection_buffer[0], fl_selection_length[0] );
+      pMem[ fl_selection_length[0] ] = 0;      
+      pmedium->tymed	      = TYMED_HGLOBAL;
+      pmedium->hGlobal	      = gh;
+      pmedium->pUnkForRelease = NULL;
+      GlobalUnlock( gh );
+      return S_OK;
+    }
+    return DV_E_FORMATETC;
+  }
+  HRESULT STDMETHODCALLTYPE QueryGetData( FORMATETC *pformatetc )
+  {
+    if ((pformatetc->dwAspect & DVASPECT_CONTENT) &&
+        (pformatetc->tymed & TYMED_HGLOBAL) &&
+        (pformatetc->cfFormat == CF_TEXT))
+      return S_OK;
+    return DV_E_FORMATETC;	
+  }  
+  // all the following methods are not really needed for a DnD object
+  HRESULT STDMETHODCALLTYPE GetDataHere( FORMATETC* /*pformatetcIn*/, STGMEDIUM* /*pmedium*/) { return E_NOTIMPL; }
+  HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc( FORMATETC* /*in*/, FORMATETC* /*out*/) { return E_NOTIMPL; }
+  HRESULT STDMETHODCALLTYPE SetData( FORMATETC* /*pformatetc*/, STGMEDIUM* /*pmedium*/, BOOL /*fRelease*/) { return E_NOTIMPL; }
+  HRESULT STDMETHODCALLTYPE EnumFormatEtc( DWORD /*dir*/, IEnumFORMATETC** /*ppenumFormatEtc*/) { return E_NOTIMPL; }
+  HRESULT STDMETHODCALLTYPE DAdvise( FORMATETC* /*pformatetc*/, DWORD /*advf*/,
+      IAdviseSink* /*pAdvSink*/, DWORD* /*pdwConnection*/) { return E_NOTIMPL; }
+  HRESULT STDMETHODCALLTYPE DUnadvise( DWORD /*dwConnection*/) { return E_NOTIMPL; }
+  HRESULT STDMETHODCALLTYPE EnumDAdvise( IEnumSTATDATA** /*ppenumAdvise*/) { return E_NOTIMPL; }
+};
+
+
+/**
+ * drag and drop whatever is in the cut-copy-paste buffer
+ * - create a selection first using: 
+ *     Fl::copy(const char *stuff, int len, 0)
+ */
+int Fl::dnd()
+{
+  DWORD dropEffect;
+  ReleaseCapture();
+
+  FLDataObject *fdo = new FLDataObject;
+  fdo->AddRef();
+  FLDropSource *fds = new FLDropSource;
+  fds->AddRef();
+
+  HRESULT ret = DoDragDrop( fdo, fds, DROPEFFECT_MOVE|DROPEFFECT_LINK|DROPEFFECT_COPY, &dropEffect );
+
+  fdo->Release();
+  fds->Release();
+
+  Fl_Widget *w = Fl::pushed();
+  if ( w )
+  {
+    int old_event = Fl::e_number;
+    w->handle(Fl::e_number = FL_RELEASE);
+    Fl::e_number = old_event;
+    Fl::pushed( 0 );
+  }
+  if ( ret==DRAGDROP_S_DROP ) return 1; // or DD_S_CANCEL
+  return 0;
+}
+#else
+int Fl::dnd()
+{
+  // Always indicate DnD failed when using GCC < 3...
+  return 1;
+}
+#endif // !__GNUC__ || __GNUC__ >= 3
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_dnd_x.cxx b/Utilities/FLTK/src/fl_dnd_x.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fa0c43a5f9855510bcc5abf3b1fd4026e06cf940
--- /dev/null
+++ b/Utilities/FLTK/src/fl_dnd_x.cxx
@@ -0,0 +1,201 @@
+//
+// "$Id$"
+//
+// Drag & Drop code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2006 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#include "flstring.h"
+
+
+extern Atom fl_XdndAware;
+extern Atom fl_XdndSelection;
+extern Atom fl_XdndEnter;
+extern Atom fl_XdndTypeList;
+extern Atom fl_XdndPosition;
+extern Atom fl_XdndLeave;
+extern Atom fl_XdndDrop;
+extern Atom fl_XdndStatus;
+extern Atom fl_XdndActionCopy;
+extern Atom fl_XdndFinished;
+//extern Atom fl_XdndProxy;
+extern Atom fl_XdndURIList;
+
+extern char fl_i_own_selection[2];
+extern char *fl_selection_buffer[2];
+
+extern void fl_sendClientMessage(Window window, Atom message,
+                                 unsigned long d0,
+                                 unsigned long d1=0,
+                                 unsigned long d2=0,
+                                 unsigned long d3=0,
+                                 unsigned long d4=0);
+
+// return version # of Xdnd this window supports.  Also change the
+// window to the proxy if it uses a proxy:
+static int dnd_aware(Window& window) {
+  Atom actual; int format; unsigned long count, remaining;
+  unsigned char *data = 0;
+  XGetWindowProperty(fl_display, window, fl_XdndAware,
+		     0, 4, False, XA_ATOM,
+		     &actual, &format,
+		     &count, &remaining, &data);
+  if (actual == XA_ATOM && format==32 && count && data)
+    return int(*(Atom*)data);
+  return 0;
+}
+
+static int grabfunc(int event) {
+  if (event == FL_RELEASE) Fl::pushed(0);
+  return 0;
+}
+
+extern int (*fl_local_grab)(int); // in Fl.cxx
+
+// send an event to an fltk window belonging to this program:
+static int local_handle(int event, Fl_Window* window) {
+  fl_local_grab = 0;
+  Fl::e_x = Fl::e_x_root-window->x();
+  Fl::e_y = Fl::e_y_root-window->y();
+  int ret = Fl::handle(event,window);
+  fl_local_grab = grabfunc;
+  return ret;
+}
+
+int Fl::dnd() {
+  Fl_Window *source_fl_win = Fl::first_window();
+  Fl::first_window()->cursor((Fl_Cursor)21);
+  Window source_window = fl_xid(Fl::first_window());
+  fl_local_grab = grabfunc;
+  Window target_window = 0;
+  Fl_Window* local_window = 0;
+  int dndversion = 4; int dest_x, dest_y;
+  XSetSelectionOwner(fl_display, fl_XdndSelection, fl_message_window, fl_event_time);
+
+  while (Fl::pushed()) {
+
+    // figure out what window we are pointing at:
+    Window new_window = 0; int new_version = 0;
+    Fl_Window* new_local_window = 0;
+    for (Window child = RootWindow(fl_display, fl_screen);;) {
+      Window root; unsigned int junk3;
+      XQueryPointer(fl_display, child, &root, &child,
+		    &e_x_root, &e_y_root, &dest_x, &dest_y, &junk3);
+      if (!child) {
+	if (!new_window && (new_version = dnd_aware(root))) new_window = root;
+	break;
+      }
+      new_window = child;
+      if ((new_local_window = fl_find(child))) break;
+      if ((new_version = dnd_aware(new_window))) break;
+    }
+
+    if (new_window != target_window) {
+      if (local_window) {
+	local_handle(FL_DND_LEAVE, local_window);
+      } else if (dndversion) {
+	fl_sendClientMessage(target_window, fl_XdndLeave, source_window);
+      }
+      dndversion = new_version;
+      target_window = new_window;
+      local_window = new_local_window;
+      if (local_window) {
+	local_handle(FL_DND_ENTER, local_window);
+      } else if (dndversion) {
+        // Send an X-DND message to the target window.  In order to
+	// support dragging of files/URLs as well as arbitrary text,
+	// we look at the selection buffer - if the buffer starts
+	// with a common URI scheme, does not contain spaces, and
+	// contains at least one CR LF, then we flag the data as
+	// both a URI list (MIME media type "text/uri-list") and
+	// plain text.  Otherwise, we just say it is plain text.
+        if ((!strncmp(fl_selection_buffer[0], "file:///", 8) ||
+	     !strncmp(fl_selection_buffer[0], "ftp://", 6) ||
+	     !strncmp(fl_selection_buffer[0], "http://", 7) ||
+	     !strncmp(fl_selection_buffer[0], "https://", 8) ||
+	     !strncmp(fl_selection_buffer[0], "ipp://", 6) ||
+	     !strncmp(fl_selection_buffer[0], "ldap:", 5) ||
+	     !strncmp(fl_selection_buffer[0], "mailto:", 7) ||
+	     !strncmp(fl_selection_buffer[0], "news:", 5) ||
+	     !strncmp(fl_selection_buffer[0], "smb://", 6)) &&
+	    !strchr(fl_selection_buffer[0], ' ') &&
+	    strstr(fl_selection_buffer[0], "\r\n")) {
+	  // Send file/URI list...
+	  fl_sendClientMessage(target_window, fl_XdndEnter, source_window,
+			       dndversion<<24, fl_XdndURIList, XA_STRING, 0);
+        } else {
+	  // Send plain text...
+	  fl_sendClientMessage(target_window, fl_XdndEnter, source_window,
+			       dndversion<<24, XA_STRING, 0, 0);
+	}
+      }
+    }
+    if (local_window) {
+      local_handle(FL_DND_DRAG, local_window);
+    } else if (dndversion) {
+      fl_sendClientMessage(target_window, fl_XdndPosition, source_window,
+			   0, (e_x_root<<16)|e_y_root, fl_event_time,
+			   fl_XdndActionCopy);
+    }
+    Fl::wait();
+  }
+
+  if (local_window) {
+    fl_i_own_selection[0] = 1;
+    if (local_handle(FL_DND_RELEASE, local_window)) paste(*belowmouse(), 0);
+  } else if (dndversion) {
+    fl_sendClientMessage(target_window, fl_XdndDrop, source_window,
+			 0, fl_event_time);
+  } else if (target_window) {
+    // fake a drop by clicking the middle mouse button:
+    XButtonEvent msg;
+    msg.type = ButtonPress;
+    msg.window = target_window;
+    msg.root = RootWindow(fl_display, fl_screen);
+    msg.subwindow = 0;
+    msg.time = fl_event_time+1;
+    msg.x = dest_x;
+    msg.y = dest_y;
+    msg.x_root = Fl::e_x_root;
+    msg.y_root = Fl::e_y_root;
+    msg.state = 0x0;
+    msg.button = Button2;
+    XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg);
+    msg.time++;
+    msg.state = 0x200;
+    msg.type = ButtonRelease;
+    XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg);
+  }
+
+  fl_local_grab = 0;
+  source_fl_win->cursor(FL_CURSOR_DEFAULT);
+  return 1;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_draw.cxx b/Utilities/FLTK/src/fl_draw.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..637744c4fd0b323274692f3da8848e1ce3e105b7
--- /dev/null
+++ b/Utilities/FLTK/src/fl_draw.cxx
@@ -0,0 +1,332 @@
+//
+// "$Id$"
+//
+// Label drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Implementation of fl_draw(const char*,int,int,int,int,Fl_Align)
+// Used to draw all the labels and text, this routine:
+// Word wraps the labels to fit into their bounding box.
+// Breaks them into lines at the newlines.
+// Expands all unprintable characters to ^X or \nnn notation
+// Aligns them against the inside of the box.
+
+#define min(a,b) ((a)<(b)?(a):(b))
+#include <FL/fl_draw.H>
+#include <FL/Fl_Image.H>
+
+#include "flstring.h"
+#include <ctype.h>
+#include <math.h>
+
+#define MAXBUF 1024
+
+char fl_draw_shortcut;	// set by fl_labeltypes.cxx
+
+static char* underline_at;
+
+// Copy p to buf, replacing unprintable characters with ^X and \nnn
+// Stop at a newline or if MAXBUF characters written to buffer.
+// Also word-wrap if width exceeds maxw.
+// Returns a pointer to the start of the next line of caharcters.
+// Sets n to the number of characters put into the buffer.
+// Sets width to the width of the string in the current font.
+
+static const char*
+expand(const char* from, char* buf, double maxw, int& n, double &width,
+       int wrap, int draw_symbols) {
+  char* o = buf;
+  char* e = buf+(MAXBUF-4);
+  underline_at = 0;
+  char* word_end = o;
+  const char* word_start = from;
+  double w = 0;
+
+  const char* p = from;
+  for (;; p++) {
+
+    int c = *p & 255;
+
+    if (!c || c == ' ' || c == '\n') {
+      // test for word-wrap:
+      if (word_start < p && wrap) {
+	double newwidth = w + fl_width(word_end, o-word_end);
+	if (word_end > buf && newwidth > maxw) { // break before this word
+	  o = word_end;
+	  p = word_start;
+	  break;
+	}
+	word_end = o;
+	w = newwidth;
+      }
+      if (!c) break;
+      else if (c == '\n') {p++; break;}
+      word_start = p+1;
+    }
+
+    if (o > e) break; // don't overflow buffer
+
+    if (c == '\t') {
+      for (c = (o-buf)%8; c<8 && o<e; c++) *o++ = ' ';
+    } else if (c == '&' && fl_draw_shortcut && *(p+1)) {
+      if (*(p+1) == '&') {p++; *o++ = '&';}
+      else if (fl_draw_shortcut != 2) underline_at = o;
+    } else if (c < ' ' || c == 127) { // ^X
+      *o++ = '^';
+      *o++ = c ^ 0x40;
+    } else if (c == 0xA0) { // non-breaking space
+      *o++ = ' ';
+    } else if (c == '@' && draw_symbols) { // Symbol???
+      if (p[1] && p[1] != '@')  break;
+      *o++ = c;
+      if (p[1]) p++;
+    } else {
+      *o++ = c;
+    }
+  }
+
+  width = w + fl_width(word_end, o-word_end);
+  *o = 0;
+  n = o-buf;
+  return p;
+}
+
+void fl_draw(
+    const char* str,	// the (multi-line) string
+    int x, int y, int w, int h,	// bounding box
+    Fl_Align align,
+    void (*callthis)(const char*,int,int,int),
+    Fl_Image* img, int draw_symbols) {
+  const char* p;
+  const char* e;
+  char buf[MAXBUF];
+  int buflen;
+  char symbol[2][255], *symptr;
+  int symwidth[2], symoffset, symtotal;
+
+  // count how many lines and put the last one into the buffer:
+  int lines;
+  double width;
+
+  symbol[0][0] = '\0';
+  symwidth[0]  = 0;
+
+  symbol[1][0] = '\0';
+  symwidth[1]  = 0;
+
+  if (draw_symbols) {
+    if (str && str[0] == '@' && str[1] && str[1] != '@') {
+      // Start with a symbol...
+      for (symptr = symbol[0];
+           *str && !isspace(*str) && symptr < (symbol[0] + sizeof(symbol[0]) - 1);
+           *symptr++ = *str++);
+      *symptr = '\0';
+      if (isspace(*str)) str++;
+      symwidth[0] = min(w,h);
+    }
+
+    if (str && (p = strrchr(str, '@')) != NULL && p > (str + 1) && p[-1] != '@') {
+      strlcpy(symbol[1], p, sizeof(symbol[1]));
+      symwidth[1] = min(w,h);
+    }
+  }
+
+  symtotal = symwidth[0] + symwidth[1];
+
+  if (str) {
+    for (p = str, lines=0; p;) {
+      e = expand(p, buf, w - symtotal, buflen, width, align&FL_ALIGN_WRAP,
+                 draw_symbols);
+      lines++;
+      if (!*e || (*e == '@' && e[1] != '@' && draw_symbols)) break;
+      p = e;
+    }
+  } else lines = 0;
+
+  if ((symwidth[0] || symwidth[1]) && lines) {
+    if (symwidth[0]) symwidth[0] = lines * fl_height();
+    if (symwidth[1]) symwidth[1] = lines * fl_height();
+  }
+
+  symtotal = symwidth[0] + symwidth[1];
+  
+  // figure out vertical position of the first line:
+  int xpos;
+  int ypos;
+  int height = fl_height();
+  int imgh = img ? img->h() : 0;
+
+  symoffset = 0;
+
+  if (align & FL_ALIGN_BOTTOM) ypos = y+h-(lines-1)*height-imgh;
+  else if (align & FL_ALIGN_TOP) ypos = y+height;
+  else ypos = y+(h-lines*height-imgh)/2+height;
+
+  // draw the image unless the "text over image" alignment flag is set...
+  if (img && !(align & FL_ALIGN_TEXT_OVER_IMAGE)) {
+    if (img->w() > symoffset) symoffset = img->w();
+
+    if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0];
+    else if (align & FL_ALIGN_RIGHT) xpos = x + w - img->w() - symwidth[1];
+    else xpos = x + (w - img->w() - symtotal) / 2 + symwidth[0];
+
+    img->draw(xpos, ypos - height);
+    ypos += img->h();
+  }
+
+  // now draw all the lines:
+  if (str) {
+    int desc = fl_descent();
+    for (p=str; ; ypos += height) {
+      if (lines>1) e = expand(p, buf, w - symtotal, buflen, width,
+                              align&FL_ALIGN_WRAP, draw_symbols);
+      else e = "";
+
+      if (width > symoffset) symoffset = (int)(width + 0.5);
+
+      if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0];
+      else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1];
+      else xpos = x + (w - (int)(width + .5) - symtotal) / 2 + symwidth[0];
+
+      callthis(buf,buflen,xpos,ypos-desc);
+
+      if (underline_at && underline_at >= buf && underline_at < (buf + buflen))
+	callthis("_",1,xpos+int(fl_width(buf,underline_at-buf)),ypos-desc);
+
+      if (!*e || (*e == '@' && e[1] != '@')) break;
+      p = e;
+    }
+  }
+
+  // draw the image if the "text over image" alignment flag is set...
+  if (img && (align & FL_ALIGN_TEXT_OVER_IMAGE)) {
+    if (img->w() > symoffset) symoffset = img->w();
+
+    if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0];
+    else if (align & FL_ALIGN_RIGHT) xpos = x + w - img->w() - symwidth[1];
+    else xpos = x + (w - img->w() - symtotal) / 2 + symwidth[0];
+
+    img->draw(xpos, ypos);
+  }
+
+  // draw the symbols, if any...
+  if (symwidth[0]) {
+    // draw to the left
+    if (align & FL_ALIGN_LEFT) xpos = x;
+    else if (align & FL_ALIGN_RIGHT) xpos = x + w - symtotal - symoffset;
+    else xpos = x + (w - symoffset - symtotal) / 2;
+
+    if (align & FL_ALIGN_BOTTOM) ypos = y + h - symwidth[0];
+    else if (align & FL_ALIGN_TOP) ypos = y;
+    else ypos = y + (h - symwidth[0]) / 2;
+
+    fl_draw_symbol(symbol[0], xpos, ypos, symwidth[0], symwidth[0], fl_color());
+  }
+
+  if (symwidth[1]) {
+    // draw to the right
+    if (align & FL_ALIGN_LEFT) xpos = x + symoffset + symwidth[0];
+    else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1];
+    else xpos = x + (w - symoffset - symtotal) / 2 + symoffset + symwidth[0];
+
+    if (align & FL_ALIGN_BOTTOM) ypos = y + h - symwidth[1];
+    else if (align & FL_ALIGN_TOP) ypos = y;
+    else ypos = y + (h - symwidth[1]) / 2;
+
+    fl_draw_symbol(symbol[1], xpos, ypos, symwidth[1], symwidth[1], fl_color());
+  }
+}
+
+void fl_draw(
+  const char* str,	// the (multi-line) string
+  int x, int y, int w, int h,	// bounding box
+  Fl_Align align,
+  Fl_Image* img,
+  int draw_symbols) {
+  if ((!str || !*str) && !img) return;
+  if (w && h && !fl_not_clipped(x, y, w, h) && (align & FL_ALIGN_INSIDE)) return;
+  if (align & FL_ALIGN_CLIP) fl_clip(x, y, w, h);
+  fl_draw(str, x, y, w, h, align, fl_draw, img, draw_symbols);
+  if (align & FL_ALIGN_CLIP) fl_pop_clip();
+}
+
+void fl_measure(const char* str, int& w, int& h, int draw_symbols) {
+  if (!str || !*str) {w = 0; h = 0; return;}
+  h = fl_height();
+  const char* p;
+  const char* e;
+  char buf[MAXBUF];
+  int buflen;
+  int lines;
+  double width;
+  int W = 0;
+  char symbol[2][255], *symptr;
+  int symwidth[2], symtotal;
+
+  // count how many lines and put the last one into the buffer:
+  symbol[0][0] = '\0';
+  symwidth[0]  = 0;
+
+  symbol[1][0] = '\0';
+  symwidth[1]  = 0;
+
+  if (str && str[0] == '@' && str[1] && str[1] != '@') {
+    // Start with a symbol...
+    for (symptr = symbol[0];
+         *str && !isspace(*str) && symptr < (symbol[0] + sizeof(symbol[0]) - 1);
+         *symptr++ = *str++);
+    *symptr = '\0';
+    if (isspace(*str)) str++;
+    symwidth[0] = h;
+  }
+
+  if (str && (p = strrchr(str, '@')) != NULL && p > (str + 1)) {
+    strlcpy(symbol[1], p, sizeof(symbol[1]));
+    symwidth[1] = h;
+  }
+
+  symtotal = symwidth[0] + symwidth[1];
+  
+  for (p = str, lines=0; p;) {
+    e = expand(p, buf, w - symtotal, buflen, width, w != 0, draw_symbols);
+    if ((int)ceil(width) > W) W = (int)ceil(width);
+    lines++;
+    if (!*e || (*e == '@' && draw_symbols)) break;
+    p = e;
+  }
+
+  if ((symwidth[0] || symwidth[1]) && lines) {
+    if (symwidth[0]) symwidth[0] = lines * fl_height();
+    if (symwidth[1]) symwidth[1] = lines * fl_height();
+  }
+
+  symtotal = symwidth[0] + symwidth[1];
+  
+  w = W + symtotal;
+  h = lines*h;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_draw_image.cxx b/Utilities/FLTK/src/fl_draw_image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a5cba970f5ebd306b8d497d48ab308b896dff823
--- /dev/null
+++ b/Utilities/FLTK/src/fl_draw_image.cxx
@@ -0,0 +1,578 @@
+//
+// "$Id$"
+//
+// Image drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// I hope a simple and portable method of drawing color and monochrome
+// images.  To keep this simple, only a single storage type is
+// supported: 8 bit unsigned data, byte order RGB, and pixels are
+// stored packed into rows with the origin at the top-left.  It is
+// possible to alter the size of pixels with the "delta" argument, to
+// add alpha or other information per pixel.  It is also possible to
+// change the origin and direction of the image data by messing with
+// the "delta" and "linedelta", making them negative, though this may
+// defeat some of the shortcuts in translating the image for X.
+
+#include "fltk-config.h"
+
+#ifdef WIN32
+#  include "fl_draw_image_win32.cxx"
+#elif defined(__APPLE__)
+#  include "fl_draw_image_mac.cxx"
+#else
+
+// A list of assumptions made about the X display:
+
+// bits_per_pixel must be one of 8, 16, 24, 32.
+
+// scanline_pad must be a power of 2 and greater or equal to 8.
+
+// PsuedoColor visuals must have 8 bits_per_pixel (although the depth
+// may be less than 8).  This is the only limitation that affects any
+// modern X displays, you can't use 12 or 16 bit colormaps.
+
+// The mask bits in TrueColor visuals for each color are
+// contiguous and have at least one bit of each color.  This
+// is not checked for.
+
+// For 24 and 32 bit visuals there must be at least 8 bits of each color.
+
+////////////////////////////////////////////////////////////////
+
+#  include <FL/Fl.H>
+#  include <FL/fl_draw.H>
+#  include <FL/x.H>
+#  include "Fl_XColor.H"
+#  include "flstring.h"
+
+static XImage xi;	// template used to pass info to X
+static int bytes_per_pixel;
+static int scanline_add;
+static int scanline_mask;
+
+static void (*converter)(const uchar *from, uchar *to, int w, int delta);
+static void (*mono_converter)(const uchar *from, uchar *to, int w, int delta);
+
+static int dir;		// direction-alternator
+static int ri,gi,bi;	// saved error-diffusion value
+
+#  if USE_COLORMAP
+////////////////////////////////////////////////////////////////
+// 8-bit converter with error diffusion
+
+static void color8_converter(const uchar *from, uchar *to, int w, int delta) {
+  int r=ri, g=gi, b=bi;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    to = to+(w-1);
+    d = -delta;
+    td = -1;
+  } else {
+    dir = 1;
+    d = delta;
+    td = 1;
+  }
+  for (; w--; from += d, to += td) {
+    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
+    g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;
+    b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;
+    Fl_Color i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256);
+    Fl_XColor& xmap = fl_xmap[0][i];
+    if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);}
+    r -= xmap.r;
+    g -= xmap.g;
+    b -= xmap.b;
+    *to = uchar(xmap.pixel);
+  }
+  ri = r; gi = g; bi = b;
+}
+
+static void mono8_converter(const uchar *from, uchar *to, int w, int delta) {
+  int r=ri, g=gi, b=bi;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    to = to+(w-1);
+    d = -delta;
+    td = -1;
+  } else {
+    dir = 1;
+    d = delta;
+    td = 1;
+  }
+  for (; w--; from += d, to += td) {
+    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
+    g += from[0]; if (g < 0) g = 0; else if (g>255) g = 255;
+    b += from[0]; if (b < 0) b = 0; else if (b>255) b = 255;
+    Fl_Color i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256);
+    Fl_XColor& xmap = fl_xmap[0][i];
+    if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);}
+    r -= xmap.r;
+    g -= xmap.g;
+    b -= xmap.b;
+    *to = uchar(xmap.pixel);
+  }
+  ri = r; gi = g; bi = b;
+}
+
+#  endif
+
+////////////////////////////////////////////////////////////////
+// 16 bit TrueColor converters with error diffusion
+// Cray computers have no 16-bit type, so we use character pointers
+// (which may be slow)
+
+#  ifdef U16
+#    define OUTTYPE U16
+#    define OUTSIZE 1
+#    define OUTASSIGN(v) *t = v
+#  else
+#    define OUTTYPE uchar
+#    define OUTSIZE 2
+#    define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt)
+#  endif
+
+static void color16_converter(const uchar *from, uchar *to, int w, int delta) {
+  OUTTYPE *t = (OUTTYPE *)to;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    t = t+(w-1)*OUTSIZE;
+    d = -delta;
+    td = -OUTSIZE;
+  } else {
+    dir = 1;
+    d = delta;
+    td = OUTSIZE;
+  }
+  int r=ri, g=gi, b=bi;
+  for (; w--; from += d, t += td) {
+    r = (r&~fl_redmask)  +from[0]; if (r>255) r = 255;
+    g = (g&~fl_greenmask)+from[1]; if (g>255) g = 255;
+    b = (b&~fl_bluemask) +from[2]; if (b>255) b = 255;
+    OUTASSIGN((
+      ((r&fl_redmask)<<fl_redshift)+
+      ((g&fl_greenmask)<<fl_greenshift)+
+      ((b&fl_bluemask)<<fl_blueshift)
+      ) >> fl_extrashift);
+  }
+  ri = r; gi = g; bi = b;
+}
+
+static void mono16_converter(const uchar *from,uchar *to,int w, int delta) {
+  OUTTYPE *t = (OUTTYPE *)to;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    t = t+(w-1)*OUTSIZE;
+    d = -delta;
+    td = -OUTSIZE;
+  } else {
+    dir = 1;
+    d = delta;
+    td = OUTSIZE;
+  }
+  uchar mask = fl_redmask & fl_greenmask & fl_bluemask;
+  int r=ri;
+  for (; w--; from += d, t += td) {
+    r = (r&~mask) + *from; if (r > 255) r = 255;
+    uchar m = r&mask;
+    OUTASSIGN((
+      (m<<fl_redshift)+
+      (m<<fl_greenshift)+
+      (m<<fl_blueshift)
+      ) >> fl_extrashift);
+  }
+  ri = r;
+}
+
+// special-case the 5r6g5b layout used by XFree86:
+
+static void c565_converter(const uchar *from, uchar *to, int w, int delta) {
+  OUTTYPE *t = (OUTTYPE *)to;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    t = t+(w-1)*OUTSIZE;
+    d = -delta;
+    td = -OUTSIZE;
+  } else {
+    dir = 1;
+    d = delta;
+    td = OUTSIZE;
+  }
+  int r=ri, g=gi, b=bi;
+  for (; w--; from += d, t += td) {
+    r = (r&7)+from[0]; if (r>255) r = 255;
+    g = (g&3)+from[1]; if (g>255) g = 255;
+    b = (b&7)+from[2]; if (b>255) b = 255;
+    OUTASSIGN(((r&0xf8)<<8) + ((g&0xfc)<<3) + (b>>3));
+  }
+  ri = r; gi = g; bi = b;
+}
+
+static void m565_converter(const uchar *from,uchar *to,int w, int delta) {
+  OUTTYPE *t = (OUTTYPE *)to;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    t = t+(w-1)*OUTSIZE;
+    d = -delta;
+    td = -OUTSIZE;
+  } else {
+    dir = 1;
+    d = delta;
+    td = OUTSIZE;
+  }
+  int r=ri;
+  for (; w--; from += d, t += td) {
+    r = (r&7) + *from; if (r > 255) r = 255;
+    OUTASSIGN((r>>3) * 0x841);
+  }
+  ri = r;
+}
+
+////////////////////////////////////////////////////////////////
+// 24bit TrueColor converters:
+
+static void rgb_converter(const uchar *from, uchar *to, int w, int delta) {
+  int d = delta-3;
+  for (; w--; from += d) {
+    *to++ = *from++;
+    *to++ = *from++;
+    *to++ = *from++;
+  }
+}
+
+static void bgr_converter(const uchar *from, uchar *to, int w, int delta) {
+  for (; w--; from += delta) {
+    uchar r = from[0];
+    uchar g = from[1];
+    *to++ = from[2];
+    *to++ = g;
+    *to++ = r;
+  }
+}
+
+static void rrr_converter(const uchar *from, uchar *to, int w, int delta) {
+  for (; w--; from += delta) {
+    *to++ = *from;
+    *to++ = *from;
+    *to++ = *from;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+// 32bit TrueColor converters on a 32 or 64-bit machine:
+
+#  ifdef U64
+#    define STORETYPE U64
+#    if WORDS_BIGENDIAN
+#      define INNARDS32(f) \
+  U64 *t = (U64*)to; \
+  int w1 = (w+1)/2; \
+  for (; w1--; from += delta) {U64 i = f; from += delta; *t++ = (i<<32)|(f);}
+#    else
+#      define INNARDS32(f) \
+  U64 *t = (U64*)to; \
+  int w1 = (w+1)/2; \
+  for (; w1--; from += delta) {U64 i=f; from+= delta; *t++ = ((U64)(f)<<32)|i;}
+#    endif
+#  else
+#    define STORETYPE U32
+#    define INNARDS32(f) \
+  U32 *t = (U32*)to; for (; w--; from += delta) *t++ = f
+#  endif
+
+static void rgbx_converter(const uchar *from, uchar *to, int w, int delta) {
+  INNARDS32((unsigned(from[0])<<24)+(from[1]<<16)+(from[2]<<8));
+}
+
+static void xbgr_converter(const uchar *from, uchar *to, int w, int delta) {
+  INNARDS32((from[0])+(from[1]<<8)+(from[2]<<16));
+}
+
+static void xrgb_converter(const uchar *from, uchar *to, int w, int delta) {
+  INNARDS32((from[0]<<16)+(from[1]<<8)+(from[2]));
+}
+
+static void bgrx_converter(const uchar *from, uchar *to, int w, int delta) {
+  INNARDS32((from[0]<<8)+(from[1]<<16)+(unsigned(from[2])<<24));
+}
+
+static void rrrx_converter(const uchar *from, uchar *to, int w, int delta) {
+  INNARDS32(unsigned(*from) * 0x1010100U);
+}
+
+static void xrrr_converter(const uchar *from, uchar *to, int w, int delta) {
+  INNARDS32(*from * 0x10101U);
+}
+
+static void
+color32_converter(const uchar *from, uchar *to, int w, int delta) {
+  INNARDS32(
+    (from[0]<<fl_redshift)+(from[1]<<fl_greenshift)+(from[2]<<fl_blueshift));
+}
+
+static void
+mono32_converter(const uchar *from,uchar *to,int w, int delta) {
+  INNARDS32(
+    (*from << fl_redshift)+(*from << fl_greenshift)+(*from << fl_blueshift));
+}
+
+////////////////////////////////////////////////////////////////
+
+static void figure_out_visual() {
+
+  fl_xpixel(FL_BLACK); // setup fl_redmask, etc, in fl_color.cxx
+  fl_xpixel(FL_WHITE); // also make sure white is allocated
+
+  static XPixmapFormatValues *pfvlist;
+  static int FL_NUM_pfv;
+  if (!pfvlist) pfvlist = XListPixmapFormats(fl_display,&FL_NUM_pfv);
+  XPixmapFormatValues *pfv;
+  for (pfv = pfvlist; pfv < pfvlist+FL_NUM_pfv; pfv++)
+    if (pfv->depth == fl_visual->depth) break;
+  xi.format = ZPixmap;
+  xi.byte_order = ImageByteOrder(fl_display);
+//i.bitmap_unit = 8;
+//i.bitmap_bit_order = MSBFirst;
+//i.bitmap_pad = 8;
+  xi.depth = fl_visual->depth;
+  xi.bits_per_pixel = pfv->bits_per_pixel;
+
+  if (xi.bits_per_pixel & 7) bytes_per_pixel = 0; // produce fatal error
+  else bytes_per_pixel = xi.bits_per_pixel/8;
+
+  unsigned int n = pfv->scanline_pad/8;
+  if (pfv->scanline_pad & 7 || (n&(n-1)))
+    Fl::fatal("Can't do scanline_pad of %d",pfv->scanline_pad);
+  if (n < sizeof(STORETYPE)) n = sizeof(STORETYPE);
+  scanline_add = n-1;
+  scanline_mask = -n;
+
+#  if USE_COLORMAP
+  if (bytes_per_pixel == 1) {
+    converter = color8_converter;
+    mono_converter = mono8_converter;
+    return;
+  }
+  if (!fl_visual->red_mask)
+    Fl::fatal("Can't do %d bits_per_pixel colormap",xi.bits_per_pixel);
+#  endif
+
+  // otherwise it is a TrueColor visual:
+
+  int rs = fl_redshift;
+  int gs = fl_greenshift;
+  int bs = fl_blueshift;
+
+  switch (bytes_per_pixel) {
+
+  case 2:
+    // All 16-bit TrueColor visuals are supported on any machine with
+    // 24 or more bits per integer.
+#  ifdef U16
+    xi.byte_order = WORDS_BIGENDIAN;
+#  else
+    xi.byte_order = 1;
+#  endif
+    if (rs == 11 && gs == 6 && bs == 0 && fl_extrashift == 3) {
+      converter = c565_converter;
+      mono_converter = m565_converter;
+    } else {
+      converter = color16_converter;
+      mono_converter = mono16_converter;
+    }
+    break;
+
+  case 3:
+    if (xi.byte_order) {rs = 16-rs; gs = 16-gs; bs = 16-bs;}
+    if (rs == 0 && gs == 8 && bs == 16) {
+      converter = rgb_converter;
+      mono_converter = rrr_converter;
+    } else if (rs == 16 && gs == 8 && bs == 0) {
+      converter = bgr_converter;
+      mono_converter = rrr_converter;
+    } else {
+      Fl::fatal("Can't do arbitrary 24bit color");
+    }
+    break;
+
+  case 4:
+    if ((xi.byte_order!=0) != WORDS_BIGENDIAN)
+      {rs = 24-rs; gs = 24-gs; bs = 24-bs;}
+    if (rs == 0 && gs == 8 && bs == 16) {
+      converter = xbgr_converter;
+      mono_converter = xrrr_converter;
+    } else if (rs == 24 && gs == 16 && bs == 8) {
+      converter = rgbx_converter;
+      mono_converter = rrrx_converter;
+    } else if (rs == 8 && gs == 16 && bs == 24) {
+      converter = bgrx_converter;
+      mono_converter = rrrx_converter;
+    } else if (rs == 16 && gs == 8 && bs == 0) {
+      converter = xrgb_converter;
+      mono_converter = xrrr_converter;
+    } else {
+      xi.byte_order = WORDS_BIGENDIAN;
+      converter = color32_converter;
+      mono_converter = mono32_converter;
+    }
+    break;
+
+  default:
+    Fl::fatal("Can't do %d bits_per_pixel",xi.bits_per_pixel);
+  }
+
+}
+
+#  define MAXBUFFER 0x40000 // 256k
+
+static void innards(const uchar *buf, int X, int Y, int W, int H,
+		    int delta, int linedelta, int mono,
+		    Fl_Draw_Image_Cb cb, void* userdata)
+{
+  if (!linedelta) linedelta = W*delta;
+
+  int dx, dy, w, h;
+  fl_clip_box(X,Y,W,H,dx,dy,w,h);
+  if (w<=0 || h<=0) return;
+  dx -= X;
+  dy -= Y;
+
+  if (!bytes_per_pixel) figure_out_visual();
+  xi.width = w;
+  xi.height = h;
+
+  void (*conv)(const uchar *from, uchar *to, int w, int delta) = converter;
+  if (mono) conv = mono_converter;
+
+  // See if the data is already in the right format.  Unfortunately
+  // some 32-bit x servers (XFree86) care about the unknown 8 bits
+  // and they must be zero.  I can't confirm this for user-supplied
+  // data, so the 32-bit shortcut is disabled...
+  // This can set bytes_per_line negative if image is bottom-to-top
+  // I tested it on Linux, but it may fail on other Xlib implementations:
+  if (buf && (
+#  if 0	// set this to 1 to allow 32-bit shortcut
+      delta == 4 &&
+#    if WORDS_BIGENDIAN
+      conv == rgbx_converter
+#    else
+      conv == xbgr_converter
+#    endif
+      ||
+#  endif
+      conv == rgb_converter && delta==3
+      ) && !(linedelta&scanline_add)) {
+    xi.data = (char *)(buf+delta*dx+linedelta*dy);
+    xi.bytes_per_line = linedelta;
+
+  } else {
+    int linesize = ((w*bytes_per_pixel+scanline_add)&scanline_mask)/sizeof(STORETYPE);
+    int blocking = h;
+    static STORETYPE *buffer;	// our storage, always word aligned
+    static long buffer_size;
+    {int size = linesize*h;
+    if (size > MAXBUFFER) {
+      size = MAXBUFFER;
+      blocking = MAXBUFFER/linesize;
+    }
+    if (size > buffer_size) {
+      delete[] buffer;
+      buffer_size = size;
+      buffer = new STORETYPE[size];
+    }}
+    xi.data = (char *)buffer;
+    xi.bytes_per_line = linesize*sizeof(STORETYPE);
+    if (buf) {
+      buf += delta*dx+linedelta*dy;
+      for (int j=0; j<h; ) {
+	STORETYPE *to = buffer;
+	int k;
+	for (k = 0; j<h && k<blocking; k++, j++) {
+	  conv(buf, (uchar*)to, w, delta);
+	  buf += linedelta;
+	  to += linesize;
+	}
+	XPutImage(fl_display,fl_window,fl_gc, &xi, 0, 0, X+dx, Y+dy+j-k, w, k);
+      }
+    } else {
+      STORETYPE* linebuf = new STORETYPE[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)];
+      for (int j=0; j<h; ) {
+	STORETYPE *to = buffer;
+	int k;
+	for (k = 0; j<h && k<blocking; k++, j++) {
+	  cb(userdata, dx, dy+j, w, (uchar*)linebuf);
+	  conv((uchar*)linebuf, (uchar*)to, w, delta);
+	  to += linesize;
+	}
+	XPutImage(fl_display,fl_window,fl_gc, &xi, 0, 0, X+dx, Y+dy+j-k, w, k);
+      }
+
+      delete[] linebuf;
+    }
+  }
+}
+
+void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+  innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
+}
+void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+		   int x, int y, int w, int h,int d) {
+  innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
+}
+void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+  innards(buf,x,y,w,h,d,l,1,0,0);
+}
+void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+		   int x, int y, int w, int h,int d) {
+  innards(0,x,y,w,h,d,0,1,cb,data);
+}
+
+void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
+  if (fl_visual->depth > 16) {
+    fl_color(r,g,b);
+    fl_rectf(x,y,w,h);
+  } else {
+    uchar c[3];
+    c[0] = r; c[1] = g; c[2] = b;
+    innards(c,x,y,w,h,0,0,0,0,0);
+  }
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_draw_image_mac.cxx b/Utilities/FLTK/src/fl_draw_image_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d165b87f93ff28f7a7be7a48fc77c826854abfe0
--- /dev/null
+++ b/Utilities/FLTK/src/fl_draw_image_mac.cxx
@@ -0,0 +1,271 @@
+//
+// "$Id$"
+//
+// MacOS image drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+////////////////////////////////////////////////////////////////
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+#define MAXBUFFER 0x40000 // 256k
+
+/**
+ * draw an image based on the input parameters
+ *
+ * buf:       image source data
+ * X, Y:      position (in buffer?!)
+ * W, H:      size of picture (in pixel?)
+ * delta:     distance from pixel to pixel in buf in bytes
+ * linedelta: distance from line to line in buf in bytes
+ * mono:      if set, pixel is one byte - if zero, pixel is 3 byte
+ * cb:        callback to copy image data into (RGB?) buffer
+ *   buf:       pointer to first byte in image source
+ *   x, y:      position in buffer
+ *   w:         width (in bytes?)
+ *   dst:       destination buffer
+ * userdata:  ?
+ */
+static void innards(const uchar *buf, int X, int Y, int W, int H,
+		    int delta, int linedelta, int mono,
+		    Fl_Draw_Image_Cb cb, void* userdata)
+{
+  if (!linedelta) linedelta = W*delta;
+
+#ifdef __APPLE_QD__
+  // theoretically, if the current GPort permits, we could write
+  // directly into it, avoiding the temporary GWorld. For now I
+  // will go the safe way... .
+  char direct = 0;
+  GWorldPtr gw;
+  Rect bounds;
+  bounds.left=0; bounds.right=W; bounds.top=0; bounds.bottom=H;
+  QDErr err = NewGWorld( &gw, 32, &bounds, 0L, 0L, useTempMem );
+  if (err==noErr && gw) {
+    PixMapHandle pm = GetGWorldPixMap( gw );
+    if ( pm ) {
+      LockPixels( pm );
+      if ( *pm ) {
+        uchar *base = (uchar*)GetPixBaseAddr( pm );
+        if ( base ) {
+          PixMapPtr pmp = *pm;
+          // make absolutely sure that we can use a direct memory write to
+          // create the pixmap!
+          if ( pmp->pixelType == 16 || pmp->pixelSize == 32 || pmp->cmpCount == 3 || pmp->cmpSize == 8 ) {
+            int rowBytes = pmp->rowBytes & 0x3fff;
+            if ( cb )
+            {
+              uchar *tmpBuf = new uchar[ W*delta ];
+              if ( mono ) delta -= 1; else delta -= 3; 
+              for ( int i=0; i<H; i++ )
+              {
+                uchar *src = tmpBuf;
+                uchar *dst = base + i*rowBytes;
+                cb( userdata, 0, i, W, tmpBuf );
+                if ( mono ) {
+                  for ( int j=0; j<W; j++ )
+                    { uchar c = *src++; *dst++ = 0; *dst++ = c; *dst++ = c; *dst++ = c; src += delta; }
+                } else {
+                  for ( int j=0; j<W; j++ )
+                    { *dst++ = 0; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; src += delta; }
+                }
+              }
+              delete[] tmpBuf;
+            }
+            else
+            {
+              if ( mono ) delta -= 1; else delta -= 3; 
+              for ( int i=0; i<H; i++ )
+              {
+                const uchar *src = buf+i*linedelta;
+                uchar *dst = base + i*rowBytes;
+                if ( mono ) {
+                  for ( int j=0; j<W; j++ )
+                    { uchar c = *src++; *dst++ = 0; *dst++ = c; *dst++ = c; *dst++ = c; src += delta; }
+                } else {
+                  for ( int j=0; j<W; j++ )
+                    { *dst++ = 0; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; src += delta; }
+                }
+              }
+            }
+          
+            fl_copy_offscreen( X, Y, W, H, gw, 0, 0 );
+            direct = 1;
+          }
+        }
+      }
+
+      UnlockPixels( pm );
+    }
+
+    DisposeGWorld( gw );
+  }
+
+  // great. We were able to write the pixels directly into memory, so we can return now.
+  if ( direct )
+    return;
+
+  // following the very save (and very slow) way to write the image into the give port
+  if ( cb )
+  {
+    uchar *tmpBuf = new uchar[ W*3 ];
+    for ( int i=0; i<H; i++ )
+    {
+      uchar *src = tmpBuf;
+      cb( userdata, 0, i, W, tmpBuf );
+      for ( int j=0; j<W; j++ )
+      {
+        if ( mono )          
+          { fl_color( src[0], src[0], src[0] ); src++; }
+        else
+          { fl_color( src[0], src[1], src[2] ); src+=3; }
+        MoveTo( X+j, Y+i );
+        Line( 0, 0 );
+      }
+    }
+    delete[] tmpBuf;
+  }
+  else
+  {
+    for ( int i=0; i<H; i++ )
+    {
+      const uchar *src = buf+i*linedelta;
+      for ( int j=0; j<W; j++ )
+      {
+        if ( mono )          
+          fl_color( src[0], src[0], src[0] );
+        else
+          fl_color( src[0], src[1], src[2] );
+        MoveTo( X+j, Y+i );
+        Line( 0, 0 );
+        src += delta;
+      }
+    }
+  }
+#elif defined(__APPLE_QUARTZ__)
+  const void *array = buf;
+  uchar *tmpBuf = 0;
+  if (cb) {
+    tmpBuf = new uchar[ H*W*delta ];
+    for (int i=0; i<H; i++) {
+      cb(userdata, 0, i, W, tmpBuf+i*W*delta);
+    }
+    array = (void*)tmpBuf;
+    linedelta = W;
+  }
+  // create an image context
+  CGColorSpaceRef   lut = CGColorSpaceCreateDeviceRGB();
+  CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H*delta, 0L);
+  CGImageRef        img = CGImageCreate( W, H, 8, 8*delta, linedelta*delta,
+                            lut, delta&1?kCGImageAlphaNone:kCGImageAlphaNoneSkipLast,
+                            src, 0L, false, kCGRenderingIntentDefault);
+  // draw the image into the destination context
+  if (img) {
+    CGRect rect = { X, Y, W, H };
+    Fl_X::q_begin_image(rect, 0, 0, W, H);
+    CGContextDrawImage(fl_gc, rect, img);
+    Fl_X::q_end_image();
+    // release all allocated resources
+    CGImageRelease(img);
+  }
+  CGColorSpaceRelease(lut);
+  CGDataProviderRelease(src);
+  if (cb) {
+    delete[] tmpBuf;
+  }
+  if (img) return; // else fall through to slow mode
+  // following the very save (and very slow) way to write the image into the give port
+  CGContextSetShouldAntialias(fl_gc, false);
+  if ( cb )
+  {
+    uchar *tmpBuf = new uchar[ W*4 ];
+    for ( int i=0; i<H; i++ )
+    {
+      uchar *src = tmpBuf;
+      cb( userdata, 0, i, W, tmpBuf );
+      for ( int j=0; j<W; j++ )
+      {
+        if ( mono )
+          { fl_color( src[0], src[0], src[0] ); }
+        else
+          { fl_color( src[0], src[1], src[2] ); }
+        CGContextMoveToPoint(fl_gc, X+j, Y+i);
+        CGContextAddLineToPoint(fl_gc, X+j, Y+i);
+        CGContextStrokePath(fl_gc);
+        src+=delta;
+      }
+    }
+    delete[] tmpBuf;
+  }
+  else
+  {
+    for ( int i=0; i<H; i++ )
+    {
+      const uchar *src = buf+i*linedelta;
+      for ( int j=0; j<W; j++ )
+      {
+        if ( mono )
+          fl_color( src[0], src[0], src[0] );
+        else
+          fl_color( src[0], src[1], src[2] );
+        CGContextMoveToPoint(fl_gc, X+j, Y+i);
+        CGContextAddLineToPoint(fl_gc, X+j, Y+i);
+        CGContextStrokePath(fl_gc);
+        src += delta;
+      }
+    }
+  }
+  CGContextSetShouldAntialias(fl_gc, true);
+#else
+# error : you must defined __APPLE_QD__ or __APPLE_QUARTZ__
+#endif
+}
+
+void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+  innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
+}
+void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+		   int x, int y, int w, int h,int d) {
+  innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
+}
+void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+  innards(buf,x,y,w,h,d,l,1,0,0);
+}
+void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+		   int x, int y, int w, int h,int d) {
+  innards(0,x,y,w,h,d,0,1,cb,data);
+}
+
+void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
+  fl_color(r,g,b);
+  fl_rectf(x,y,w,h);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_draw_image_win32.cxx b/Utilities/FLTK/src/fl_draw_image_win32.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5ee8ed0d3c9e8b090d48c09ed0c7065a22f3bc24
--- /dev/null
+++ b/Utilities/FLTK/src/fl_draw_image_win32.cxx
@@ -0,0 +1,265 @@
+//
+// "$Id$"
+//
+// WIN32 image drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// I hope a simple and portable method of drawing color and monochrome
+// images.  To keep this simple, only a single storage type is
+// supported: 8 bit unsigned data, byte order RGB, and pixels are
+// stored packed into rows with the origin at the top-left.  It is
+// possible to alter the size of pixels with the "delta" argument, to
+// add alpha or other information per pixel.  It is also possible to
+// change the origin and direction of the image data by messing with
+// the "delta" and "linedelta", making them negative, though this may
+// defeat some of the shortcuts in translating the image for X.
+
+// Unbelievably (since it conflicts with how most PC software works)
+// Micro$oft picked a bottom-up and BGR storage format for their
+// DIB images.  I'm pretty certain there is a way around this, but
+// I can't find any other than the brute-force method of drawing
+// each line as a seperate image.  This may also need to be done
+// if the delta is any amount other than 1, 3, or 4.
+
+////////////////////////////////////////////////////////////////
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+#define MAXBUFFER 0x40000 // 256k
+
+#if USE_COLORMAP
+
+// error-diffusion dither into the FLTK colormap
+static void dither(uchar* to, const uchar* from, int w, int delta) {
+  static int ri, gi, bi, dir;
+  int r=ri, g=gi, b=bi;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    to = to+(w-1);
+    d = -delta;
+    td = -1;
+  } else {
+    dir = 1;
+    d = delta;
+    td = 1;
+  }
+  for (; w--; from += d, to += td) {
+    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
+    int rr = r*FL_NUM_RED/256;
+    r -= rr*255/(FL_NUM_RED-1);
+    g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;
+    int gg = g*FL_NUM_GREEN/256;
+    g -= gg*255/(FL_NUM_GREEN-1);
+    b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;
+    int bb = b*FL_NUM_BLUE/256;
+    b -= bb*255/(FL_NUM_BLUE-1);
+    *to = uchar(FL_COLOR_CUBE+(bb*FL_NUM_RED+rr)*FL_NUM_GREEN+gg);
+  }
+  ri = r; gi = g; bi = b;
+}
+
+// error-diffusion dither into the FLTK colormap
+static void monodither(uchar* to, const uchar* from, int w, int delta) {
+  static int ri,dir;
+  int r=ri;
+  int d, td;
+  if (dir) {
+    dir = 0;
+    from = from+(w-1)*delta;
+    to = to+(w-1);
+    d = -delta;
+    td = -1;
+  } else {
+    dir = 1;
+    d = delta;
+    td = 1;
+  }
+  for (; w--; from += d, to += td) {
+    r += *from; if (r < 0) r = 0; else if (r>255) r = 255;
+    int rr = r*FL_NUM_GRAY/256;
+    r -= rr*255/(FL_NUM_GRAY-1);
+    *to = uchar(FL_GRAY_RAMP+rr);
+  }
+  ri = r;
+}
+
+#endif // USE_COLORMAP
+
+static void innards(const uchar *buf, int X, int Y, int W, int H,
+		    int delta, int linedelta, int mono,
+		    Fl_Draw_Image_Cb cb, void* userdata)
+{
+#if USE_COLORMAP
+  char indexed = (fl_palette != 0);
+#endif
+
+  if (!linedelta) linedelta = W*delta;
+
+  int x, y, w, h;
+  fl_clip_box(X,Y,W,H,x,y,w,h);
+  if (w<=0 || h<=0) return;
+  if (buf) buf += (x-X)*delta + (y-Y)*linedelta;
+
+  static U32 bmibuffer[256+12];
+  BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer);
+  if (!bmi.bmiHeader.biSize) {
+    bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type?
+    bmi.bmiHeader.biPlanes = 1;
+    bmi.bmiHeader.biCompression = BI_RGB;
+    bmi.bmiHeader.biXPelsPerMeter = 0;
+    bmi.bmiHeader.biYPelsPerMeter = 0;
+    bmi.bmiHeader.biClrUsed = 0;
+    bmi.bmiHeader.biClrImportant = 0;
+  }
+#if USE_COLORMAP
+  if (indexed) {
+    for (short i=0; i<256; i++) {
+      *((short*)(bmi.bmiColors)+i) = i;
+    }
+  } else
+#endif
+  if (mono) {
+    for (int i=0; i<256; i++) {
+      bmi.bmiColors[i].rgbBlue = (uchar)i;
+      bmi.bmiColors[i].rgbGreen = (uchar)i;
+      bmi.bmiColors[i].rgbRed = (uchar)i;
+      bmi.bmiColors[i].rgbReserved = (uchar)i;
+    }
+  }
+  bmi.bmiHeader.biWidth = w;
+#if USE_COLORMAP
+  bmi.bmiHeader.biBitCount = mono|indexed ? 8 : 24;
+  int pixelsize = mono|indexed ? 1 : 3;
+#else
+  bmi.bmiHeader.biBitCount = mono ? 8 : 24;
+  int pixelsize = mono ? 1 : 3;
+#endif
+  int linesize = (pixelsize*w+3)&~3;
+  
+  static U32* buffer;
+  int blocking = h;
+  {int size = linesize*h;
+  if (size > MAXBUFFER) {
+    size = MAXBUFFER;
+    blocking = MAXBUFFER/linesize;
+  }
+  static long buffer_size;
+  if (size > buffer_size) {
+    delete[] buffer;
+    buffer_size = size;
+    buffer = new U32[(size+3)/4];
+  }}
+  bmi.bmiHeader.biHeight = blocking;
+  static U32* line_buffer;
+  if (!buf) {
+    int size = W*delta;
+    static int line_buf_size;
+    if (size > line_buf_size) {
+      delete[] line_buffer;
+      line_buf_size = size;
+      line_buffer = new U32[(size+3)/4];
+    }
+  }
+  for (int j=0; j<h; ) {
+    int k;
+    for (k = 0; j<h && k<blocking; k++, j++) {
+      const uchar* from;
+      if (!buf) { // run the converter:
+	cb(userdata, x-X, y-Y+j, w, (uchar*)line_buffer);
+	from = (uchar*)line_buffer;
+      } else {
+	from = buf;
+	buf += linedelta;
+      }
+      uchar *to = (uchar*)buffer+(blocking-k-1)*linesize;
+#if USE_COLORMAP
+      if (indexed) {
+	if (mono)
+	  monodither(to, from, w, delta);
+	else 
+	  dither(to, from, w, delta);
+	to += w;
+      } else
+#endif
+      if (mono) {
+	for (int i=w; i--; from += delta) *to++ = *from;
+      } else {
+	for (int i=w; i--; from += delta, to += 3) {
+	  uchar r = from[0];
+	  to[0] = from[2];
+	  to[1] = from[1];
+	  to[2] = r;
+        }
+      }
+    }
+    SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k,
+		      (LPSTR)((uchar*)buffer+(blocking-k)*linesize),
+		      &bmi,
+#if USE_COLORMAP
+		      indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS
+#else
+		      DIB_RGB_COLORS
+#endif
+		      );
+  }
+}
+
+void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+  innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
+}
+void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+		   int x, int y, int w, int h,int d) {
+  innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
+}
+void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+  innards(buf,x,y,w,h,d,l,1,0,0);
+}
+void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+		   int x, int y, int w, int h,int d) {
+  innards(0,x,y,w,h,d,0,1,cb,data);
+}
+
+void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
+#if USE_COLORMAP
+  // use the error diffusion dithering code to produce a much nicer block:
+  if (fl_palette) {
+    uchar c[3];
+    c[0] = r; c[1] = g; c[2] = b;
+    innards(c,x,y,w,h,0,0,0,0,0);
+    return;
+  }
+#endif
+  fl_color(r,g,b);
+  fl_rectf(x,y,w,h);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_draw_pixmap.cxx b/Utilities/FLTK/src/fl_draw_pixmap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9aebb3554d1ab51bc6275a0295ce574736a7543e
--- /dev/null
+++ b/Utilities/FLTK/src/fl_draw_pixmap.cxx
@@ -0,0 +1,343 @@
+//
+// "$Id$"
+//
+// Pixmap drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Implemented without using the xpm library (which I can't use because
+// it interferes with the color cube used by fl_draw_image).
+// Current implementation is cheap and slow, and works best on a full-color
+// display.  Transparency is not handled, and colors are dithered to
+// the color cube.  Color index is achieved by adding the id
+// characters together!  Also mallocs a lot of temporary memory!
+// Notice that there is no pixmap file interface.  This is on purpose,
+// as I want to discourage programs that require support files to work.
+// All data needed by a program ui should be compiled in!!!
+
+#include "fltk-config.h"
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <stdio.h>
+#include "flstring.h"
+
+static int ncolors, chars_per_pixel;
+
+int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h) {
+  return fl_measure_pixmap((const char*const*)data,w,h);
+}
+
+int fl_measure_pixmap(const char * const *data, int &w, int &h) {
+  int i = sscanf(data[0],"%d%d%d%d",&w,&h,&ncolors,&chars_per_pixel);
+  if (i<4 || w<=0 || h<=0 ||
+      chars_per_pixel!=1 && chars_per_pixel!=2) return w=0;
+  return 1;
+}
+
+#ifdef U64
+
+// The callback from fl_draw_image to get a row of data passes this:
+struct pixmap_data {
+  int w, h;
+  const uchar*const* data;
+  union {
+    U64 colors[256];
+    U64* byte1[256];
+  };
+};
+
+// callback for 1 byte per pixel:
+static void cb1(void*v, int x, int y, int w, uchar* buf) {
+  pixmap_data& d = *(pixmap_data*)v;
+  const uchar* p = d.data[y]+x;
+  U64* q = (U64*)buf;
+  for (int X=w; X>0; X-=2, p += 2) {
+    if (X>1) {
+#  if WORDS_BIGENDIAN
+      *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]];
+#  else
+      *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]];
+#  endif
+    } else {
+#  if WORDS_BIGENDIAN
+      *q++ = d.colors[p[0]]<<32;
+#  else
+      *q++ = d.colors[p[0]];
+#  endif
+    }
+  }
+}
+
+// callback for 2 bytes per pixel:
+static void cb2(void*v, int x, int y, int w, uchar* buf) {
+  pixmap_data& d = *(pixmap_data*)v;
+  const uchar* p = d.data[y]+2*x;
+  U64* q = (U64*)buf;
+  for (int X=w; X>0; X-=2) {
+    U64* colors = d.byte1[*p++];
+    int index = *p++;
+    if (X>1) {
+      U64* colors1 = d.byte1[*p++];
+      int index1 = *p++;
+#  if WORDS_BIGENDIAN
+      *q++ = (colors[index]<<32) | colors1[index1];
+#  else
+      *q++ = (colors1[index1]<<32) | colors[index];
+#  endif
+    } else {
+#  if WORDS_BIGENDIAN
+      *q++ = colors[index]<<32;
+#  else
+      *q++ = colors[index];
+#  endif
+    }
+  }
+}
+
+#else // U32
+
+// The callback from fl_draw_image to get a row of data passes this:
+struct pixmap_data {
+  int w, h;
+  const uchar*const* data;
+  union {
+    U32 colors[256];
+    U32* byte1[256];
+  };
+};
+
+#  ifndef __APPLE_QUARTZ__
+
+// callback for 1 byte per pixel:
+static void cb1(void*v, int x, int y, int w, uchar* buf) {
+  pixmap_data& d = *(pixmap_data*)v;
+  const uchar* p = d.data[y]+x;
+  U32* q = (U32*)buf;
+  for (int X=w; X--;) *q++ = d.colors[*p++];
+}
+
+// callback for 2 bytes per pixel:
+static void cb2(void*v, int x, int y, int w, uchar* buf) {
+  pixmap_data& d = *(pixmap_data*)v;
+  const uchar* p = d.data[y]+2*x;
+  U32* q = (U32*)buf;
+  for (int X=w; X--;) {
+    U32* colors = d.byte1[*p++];
+    *q++ = colors[*p++];
+  }
+}
+
+#  endif  // !__APPLE_QUARTZ__
+
+#endif // U64 else U32
+
+uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here
+
+int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) {
+  return fl_draw_pixmap((const char*const*)data,x,y,bg);
+}
+
+int fl_draw_pixmap(const char*const* di, int x, int y, Fl_Color bg) {
+  pixmap_data d;
+  if (!fl_measure_pixmap(di, d.w, d.h)) return 0;
+  const uchar*const* data = (const uchar*const*)(di+1);
+  int transparent_index = -1;
+
+  if (ncolors < 0) {	// FLTK (non standard) compressed colormap
+    ncolors = -ncolors;
+    const uchar *p = *data++;
+    // if first color is ' ' it is transparent (put it later to make
+    // it not be transparent):
+    if (*p == ' ') {
+      uchar* c = (uchar*)&d.colors[(int)' '];
+#ifdef U64
+      *(U64*)c = 0;
+#  if WORDS_BIGENDIAN
+      c += 4;
+#  endif
+#endif
+      transparent_index = ' ';
+      Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
+      p += 4;
+      ncolors--;
+    }
+    // read all the rest of the colors:
+    for (int i=0; i < ncolors; i++) {
+      uchar* c = (uchar*)&d.colors[*p++];
+#ifdef U64
+      *(U64*)c = 0;
+#  if WORDS_BIGENDIAN
+      c += 4;
+#  endif
+#endif
+      *c++ = *p++;
+      *c++ = *p++;
+      *c++ = *p++;
+#ifdef __APPLE_QUARTZ__
+      *c = 255;
+#else
+      *c = 0;
+#endif
+    }
+  } else {	// normal XPM colormap with names
+    if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1));
+    for (int i=0; i<ncolors; i++) {
+      const uchar *p = *data++;
+      // the first 1 or 2 characters are the color index:
+      int ind = *p++;
+      uchar* c;
+      if (chars_per_pixel>1) {
+#ifdef U64
+	U64* colors = d.byte1[ind];
+	if (!colors) colors = d.byte1[ind] = new U64[256];
+#else
+	U32* colors = d.byte1[ind];
+	if (!colors) colors = d.byte1[ind] = new U32[256];
+#endif
+	c = (uchar*)&colors[*p];
+	ind = (ind<<8)|*p++;
+      } else {
+	c = (uchar *)&d.colors[ind];
+      }
+      // look for "c word", or last word if none:
+      const uchar *previous_word = p;
+      for (;;) {
+	while (*p && isspace(*p)) p++;
+	uchar what = *p++;
+	while (*p && !isspace(*p)) p++;
+	while (*p && isspace(*p)) p++;
+	if (!*p) {p = previous_word; break;}
+	if (what == 'c') break;
+	previous_word = p;
+	while (*p && !isspace(*p)) p++;
+      }
+#ifdef U64
+      *(U64*)c = 0;
+#  if WORDS_BIGENDIAN
+      c += 4;
+#  endif
+#endif
+#ifdef __APPLE_QUARTZ__
+      c[3] = 255;
+#endif
+      if (!fl_parse_color((const char*)p, c[0], c[1], c[2])) {
+        // assume "None" or "#transparent" for any errors
+	// "bg" should be transparent...
+	Fl::get_color(bg, c[0], c[1], c[2]);
+#ifdef __APPLE_QUARTZ__
+        c[3] = 0;
+#endif
+	transparent_index = ind;
+      }
+    }
+  }
+  d.data = data;
+
+#ifndef __APPLE_QUARTZ__
+
+  // build the mask bitmap used by Fl_Pixmap:
+  if (fl_mask_bitmap && transparent_index >= 0) {
+    int W = (d.w+7)/8;
+    uchar* bitmap = new uchar[W * d.h];
+    *fl_mask_bitmap = bitmap;
+    for (int Y = 0; Y < d.h; Y++) {
+      const uchar* p = data[Y];
+      if (chars_per_pixel <= 1) {
+	int dw = d.w;
+	for (int X = 0; X < W; X++) {
+	  uchar b = (dw-->0 && *p++ != transparent_index);
+	  if (dw-->0 && *p++ != transparent_index) b |= 2;
+	  if (dw-->0 && *p++ != transparent_index) b |= 4;
+	  if (dw-->0 && *p++ != transparent_index) b |= 8;
+	  if (dw-->0 && *p++ != transparent_index) b |= 16;
+	  if (dw-->0 && *p++ != transparent_index) b |= 32;
+	  if (dw-->0 && *p++ != transparent_index) b |= 64;
+	  if (dw-->0 && *p++ != transparent_index) b |= 128;
+	  *bitmap++ = b;
+	}
+      } else {
+        uchar b = 0, bit = 1;
+	for (int X = 0; X < d.w; X++) {
+	  int ind = *p++;
+	  ind = (ind<<8) | (*p++);
+	  if (ind != transparent_index) b |= bit;
+
+          if (bit < 128) bit <<= 1;
+	  else {
+	    *bitmap++ = b;
+	    b = 0;
+	    bit = 1;
+	  }
+	}
+
+        if (bit > 1) *bitmap++ = b;
+      }
+    }
+  }
+
+  fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
+
+#else // __APPLE_QUARTZ__
+
+  bool transparent = (transparent_index>=0);
+  transparent = true;
+  U32 *array = new U32[d.w * d.h], *q = array;
+  for (int Y = 0; Y < d.h; Y++) {
+    const uchar* p = data[Y];
+    if (chars_per_pixel <= 1) {
+      for (int X = 0; X < d.w; X++) {
+        *q++ = d.colors[*p++];
+      }
+    } else {
+      for (int X = 0; X < d.w; X++) {
+        U32* colors = d.byte1[*p++];
+        *q++ = colors[*p++];
+      }
+    }
+  }
+  CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+  CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L);
+  CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w,
+        lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast,
+        src, 0L, false, kCGRenderingIntentDefault);
+  CGColorSpaceRelease(lut);
+  CGDataProviderRelease(src);
+  CGRect rect = { x, y, d.w, d.h };
+  Fl_X::q_begin_image(rect, x, y, d.w, d.h);
+  CGContextDrawImage(fl_gc, rect, img);
+  Fl_X::q_end_image();
+  CGContextFlush(fl_gc);
+  CGImageRelease(img);
+  delete array;
+
+#endif // !__APPLE_QUARTZ__
+
+  if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i];
+  return 1;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_engraved_label.cxx b/Utilities/FLTK/src/fl_engraved_label.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7ec602efcaff2bf4b0deb6b6d41955c4d9443e45
--- /dev/null
+++ b/Utilities/FLTK/src/fl_engraved_label.cxx
@@ -0,0 +1,93 @@
+//
+// "$Id$"
+//
+// Engraved label drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Drawing code for XForms style engraved & embossed labels
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+
+// data[] is dx, dy, color triples
+
+static void innards(
+    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align,
+    int data[][3], int n)
+{
+  Fl_Align a1 = align;
+  if (a1 & FL_ALIGN_CLIP) {
+    fl_clip(X, Y, W, H); a1 = (Fl_Align)(a1&~FL_ALIGN_CLIP);}
+  fl_font((Fl_Font)o->font, o->size);
+  for (int i = 0; i < n; i++) {
+    fl_color((Fl_Color)(i < n-1 ? data[i][2] : o->color));
+    fl_draw(o->value, X+data[i][0], Y+data[i][1], W, H, a1);
+  }
+  if (align & FL_ALIGN_CLIP) fl_pop_clip();
+}
+
+static void fl_shadow_label(
+    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+  static int data[2][3] = {{2,2,FL_DARK3},{0,0,0}};
+  innards(o, X, Y, W, H, align, data, 2);
+}
+
+static void fl_engraved_label(
+    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+  static int data[7][3] = {
+    {1,0,FL_LIGHT3},{1,1,FL_LIGHT3},{0,1,FL_LIGHT3},
+    {-1,0,FL_DARK3},{-1,-1,FL_DARK3},{0,-1,FL_DARK3},
+    {0,0,0}};
+  innards(o, X, Y, W, H, align, data, 7);
+}
+
+static void fl_embossed_label(
+    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+  static int data[7][3] = {
+    {-1,0,FL_LIGHT3},{-1,-1,FL_LIGHT3},{0,-1,FL_LIGHT3},
+    {1,0,FL_DARK3},{1,1,FL_DARK3},{0,1,FL_DARK3},
+    {0,0,0}};
+  innards(o, X, Y, W, H, align, data, 7);
+}
+
+Fl_Labeltype fl_define_FL_SHADOW_LABEL() {
+  Fl::set_labeltype(_FL_SHADOW_LABEL, fl_shadow_label, 0);
+  return _FL_SHADOW_LABEL;
+}
+Fl_Labeltype fl_define_FL_ENGRAVED_LABEL() {
+  Fl::set_labeltype(_FL_ENGRAVED_LABEL, fl_engraved_label, 0);
+  return _FL_ENGRAVED_LABEL;
+}
+Fl_Labeltype fl_define_FL_EMBOSSED_LABEL() {
+  Fl::set_labeltype(_FL_EMBOSSED_LABEL, fl_embossed_label, 0);
+  return _FL_EMBOSSED_LABEL;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_file_dir.cxx b/Utilities/FLTK/src/fl_file_dir.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b03759d5b45700e38dffba50263a931a643b7aa4
--- /dev/null
+++ b/Utilities/FLTK/src/fl_file_dir.cxx
@@ -0,0 +1,160 @@
+//
+// "$Id$"
+//
+// File chooser widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include "flstring.h"
+#include <FL/filename.H>
+#include <FL/Fl_File_Chooser.H>
+#include <FL/fl_ask.H>
+
+
+static Fl_File_Chooser	*fc = (Fl_File_Chooser *)0;
+static void		(*current_callback)(const char*) = 0;
+static const char	*current_label = fl_ok;
+
+
+// Do a file chooser callback...
+static void callback(Fl_File_Chooser *, void*) {
+  if (current_callback && fc->value())
+    (*current_callback)(fc->value());
+}
+
+
+// Set the file chooser callback
+void fl_file_chooser_callback(void (*cb)(const char*)) {
+  current_callback = cb;
+}
+
+
+// Set the "OK" button label
+void fl_file_chooser_ok_label(const char *l) {
+  if (l) current_label = l;
+  else current_label = fl_ok;
+}
+
+
+//
+// 'fl_file_chooser()' - Show a file chooser dialog and get a filename.
+//
+
+char *					// O - Filename or NULL
+fl_file_chooser(const char *message,	// I - Message in titlebar
+                const char *pat,	// I - Filename pattern
+		const char *fname,	// I - Initial filename selection
+		int        relative) {	// I - 0 for absolute path
+  static char	retname[1024];		// Returned filename
+
+  if (!fc) {
+    if (!fname || !*fname) fname = ".";
+
+    fc = new Fl_File_Chooser(fname, pat, Fl_File_Chooser::CREATE, message);
+    fc->callback(callback, 0);
+  } else {
+    fc->type(Fl_File_Chooser::CREATE);
+    fc->filter(pat);
+    fc->label(message);
+
+    if (!fname || !*fname) {
+      if (fc->filter() != pat && (!pat || !fc->filter() ||
+          strcmp(pat, fc->filter())) && fc->value()) {
+	// if pattern is different, remove name but leave old directory:
+	strlcpy(retname, fc->value(), sizeof(retname));
+
+	char *p = strrchr(retname, '/');
+
+        if (p) {
+	  // If the filename is "/foo", then the directory will be "/", not
+	  // ""...
+	  if (p == retname)
+	    retname[1] = '\0';
+	  else
+	    *p = '\0';
+	}
+
+	// Set the directory...
+	fc->directory(retname);
+      }
+    }
+    else
+      fc->value(fname);
+  }
+
+  fc->ok_label(current_label);
+  fc->show();
+
+  while (fc->shown())
+    Fl::wait();
+
+  if (fc->value() && relative) {
+    fl_filename_relative(retname, sizeof(retname), fc->value());
+
+    return retname;
+  } else if (fc->value()) return (char *)fc->value();
+  else return 0;
+}
+
+
+//
+// 'fl_dir_chooser()' - Show a file chooser dialog and get a directory.
+//
+
+char *					// O - Directory or NULL
+fl_dir_chooser(const char *message,	// I - Message for titlebar
+               const char *fname,	// I - Initial directory name
+	       int        relative)	// I - 0 for absolute
+{
+  static char	retname[1024];		// Returned directory name
+
+  if (!fc) {
+    if (!fname || !*fname) fname = ".";
+
+    fc = new Fl_File_Chooser(fname, "*", Fl_File_Chooser::CREATE |
+                                         Fl_File_Chooser::DIRECTORY, message);
+    fc->callback(callback, 0);
+  } else {
+    fc->type(Fl_File_Chooser::CREATE | Fl_File_Chooser::DIRECTORY);
+    fc->filter("*");
+    if (fname && *fname) fc->value(fname);
+    fc->label(message);
+  }
+
+  fc->show();
+
+  while (fc->shown())
+    Fl::wait();
+
+  if (fc->value() && relative) {
+    fl_filename_relative(retname, sizeof(retname), fc->value());
+
+    return retname;
+  } else if (fc->value()) return (char *)fc->value();
+  else return 0;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_font.cxx b/Utilities/FLTK/src/fl_font.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7dd3576fec7974c7f00b5a3527d6f5f16445f624
--- /dev/null
+++ b/Utilities/FLTK/src/fl_font.cxx
@@ -0,0 +1,60 @@
+//
+// "$Id$"
+//
+// Font selection code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Select fonts from the FLTK font table.
+#include "flstring.h"
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include "Fl_Font.H"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef WIN32
+#  include "fl_font_win32.cxx"
+#elif defined(__APPLE__)
+#  include "fl_font_mac.cxx"
+#elif USE_XFT
+#  include "fl_font_xft.cxx"
+#else
+#  include "fl_font_x.cxx"
+#endif // WIN32
+
+
+double fl_width(const char* c) {
+  if (c) return fl_width(c, strlen(c));
+  else return 0.0f;
+}
+
+void fl_draw(const char* str, int x, int y) {
+  fl_draw(str, strlen(str), x, y);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_font_mac.cxx b/Utilities/FLTK/src/fl_font_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4dd71f560e6514a0cd8e9f7537a14335cbe1d866
--- /dev/null
+++ b/Utilities/FLTK/src/fl_font_mac.cxx
@@ -0,0 +1,307 @@
+//
+// "$Id$"
+//
+// MacOS font selection routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+//: MeasureText, FontMetrics, WidthTabHandle, GetSysFont, SysFontSize
+//: TextSize, TextFont
+//: GetFNum (theName: Str255; VAR familyID: Integer);
+//: FUNCTION FMSwapFont (inRec: FMInput): FMOutPtr;
+//: SetFractEnable
+
+Fl_FontSize::Fl_FontSize(const char* name, int Size) {
+  next = 0;
+#  if HAVE_GL
+  listbase = 0;
+#  endif
+#ifdef __APPLE_QD__
+  knowMetrics = 0;
+  switch (*name++) {
+  case 'I': face = italic; break;
+  case 'P': face = italic | bold; break;
+  case 'B': face = bold; break;
+  default: face = 0; break;
+  }
+  unsigned char fn[80]; 
+  fn[0] = strlen(name); strcpy((char*)(fn+1), name);
+  GetFNum(fn, &font);
+  size = Size;
+  FMInput fIn = { font, size, face, 0, 0, { 1, 1}, { 1, 1} };
+  FMOutput *fOut = FMSwapFont(&fIn);
+  ascent = fOut->ascent;	//: the following three lines give only temporary aproimations
+  descent = fOut->descent;
+  for (int i=0; i<256; i++) width[i] = fOut->widMax;
+  minsize = maxsize = size;
+#elif defined(__APPLE_QUARTZ__)
+  q_name = strdup(name);
+  size = Size;
+  ascent = Size*3/4;
+  descent = Size-ascent;
+  q_width = Size*2/3;
+  minsize = maxsize = Size;
+  // Using ATS to get the genral Glyph size information
+  CFStringRef cfname = CFStringCreateWithCString(0L, q_name, kCFStringEncodingASCII);
+  ATSFontRef font = ATSFontFindFromName(cfname, kATSOptionFlagsDefault);
+  if (font) {
+    ATSFontMetrics m = { 0 };
+    ATSFontGetHorizontalMetrics(font, kATSOptionFlagsDefault, &m);
+    if (m.avgAdvanceWidth) q_width = int(m.avgAdvanceWidth*size);
+    // playing with the offsets a little to make standard sizes fit
+    if (m.ascent) ascent  = int(m.ascent*size-0.5f);
+    if (m.descent) descent = -int(m.descent*size-1.5f);
+  }
+  CFRelease(cfname);
+#endif
+}
+
+Fl_FontSize* fl_fontsize = 0L;
+
+Fl_FontSize::~Fl_FontSize() {
+/*
+#if HAVE_GL
+ // ++ todo: remove OpenGL font alocations
+// Delete list created by gl_draw().  This is not done by this code
+// as it will link in GL unnecessarily.  There should be some kind
+// of "free" routine pointer, or a subclass?
+// if (listbase) {
+//  int base = font->min_char_or_byte2;
+//  int size = font->max_char_or_byte2-base+1;
+//  int base = 0; int size = 256;
+//  glDeleteLists(listbase+base,size);
+// }
+#endif
+  */
+  if (this == fl_fontsize) fl_fontsize = 0;
+#ifdef __APPLE_QUARTZ__
+  free(q_name);
+#endif
+}
+
+////////////////////////////////////////////////////////////////
+
+static Fl_Fontdesc built_in_table[] = {
+#ifdef __APPLE_QD__
+{" Arial"},
+{"BArial"},
+{"IArial"},
+{"PArial"},
+{" Courier New"},
+{"BCourier New"},
+{"ICourier New"},
+{"PCourier New"},
+{" Times New Roman"},
+{"BTimes New Roman"},
+{"ITimes New Roman"},
+{"PTimes New Roman"},
+{" Symbol"},
+{" Chicago"},
+{"BChicago"},
+{" Webdings"},
+#elif defined(__APPLE_QUARTZ__)
+{"Arial"},
+{"Arial Bold"},
+{"Arial Italic"},
+{"Arial Bold Italic"},
+{"Courier New"},
+{"Courier New Bold"},
+{"Courier New Italic"},
+{"Courier New Bold Italic"},
+{"Times New Roman"},
+{"Times New Roman Bold"},
+{"Times New Roman Italic"},
+{"Times New Roman Bold Italic"},
+{"Symbol"},
+{"Monaco"},
+{"Andale Mono"}, // there is no bold Monaco font on standard Mac
+{"Webdings"},
+#endif
+};
+
+Fl_Fontdesc* fl_fonts = built_in_table;
+
+void fl_font(Fl_FontSize* s) {
+  fl_fontsize = s;
+#ifdef __APPLE_QD__
+  if (fl_window) SetPort( GetWindowPort(fl_window) );
+  TextFont(fl_fontsize->font);	//: select font into current QuickDraw GC
+  TextFace(fl_fontsize->face);
+  TextSize(fl_fontsize->size);
+  if (!fl_fontsize->knowMetrics) {	//: get the true metrics for the currnet GC 
+                                        //: (fails on multiple monitors with different dpi's!)
+    FontInfo fi; GetFontInfo(&fi);
+    fl_fontsize->ascent = fi.ascent;
+    fl_fontsize->descent = fi.descent;
+    FMetricRec mr; FontMetrics(&mr);
+    short *f = (short*)*mr.wTabHandle; //: get the char size table
+    for (int i=0; i<256; i++) fl_fontsize->width[i] = f[2*i];
+    fl_fontsize->knowMetrics = 1;
+  }
+#elif defined(__APPLE_QUARTZ__)
+  if (!s) return;
+  if (!fl_gc) return; // no worries, we will assign the font to the context later
+  CGContextSelectFont(fl_gc, s->q_name, (float)s->size, kCGEncodingMacRoman);
+#else
+# error : need to defined either Quartz or Quickdraw
+#endif
+}
+
+static Fl_FontSize* find(int fnum, int size) {
+  Fl_Fontdesc* s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // use 0 if fnum undefined
+  Fl_FontSize* f;
+  for (f = s->first; f; f = f->next)
+    if (f->minsize <= size && f->maxsize >= size) return f;
+  f = new Fl_FontSize(s->name, size);
+  f->next = s->first;
+  s->first = f;
+  return f;
+}
+
+////////////////////////////////////////////////////////////////
+// Public interface:
+
+int fl_font_ = 0;
+int fl_size_ = 0;
+
+void fl_font(int fnum, int size) {
+  fl_font_ = fnum;
+  fl_size_ = size;
+  fl_font(find(fnum, size));
+}
+
+int fl_height() {
+  if (fl_fontsize) return fl_fontsize->ascent+fl_fontsize->descent;
+  else return -1;
+}
+
+int fl_descent() {
+  if (fl_fontsize) return fl_fontsize->descent;
+  else return -1;
+}
+
+// MRS: The default character set is MacRoman, which is different from
+//      ISO-8859-1; in FLTK 2.0 we'll use UTF-8 with Quartz...
+
+static uchar macroman_lut[256] = {
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+  96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+  112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+  144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+  202, 193, 162, 163, 164, 180, 166, 164, 172, 169, 187, 199, 194, 173, 168, 248,
+  161, 177, 178, 179, 171, 181, 166, 225, 252, 185, 188, 200, 188, 189, 190, 192,
+  203, 231, 229, 204, 128, 129, 174, 130, 233, 131, 230, 232, 237, 234, 235, 236,
+  208, 132, 241, 238, 239, 205, 133, 215, 175, 244, 242, 243, 134, 221, 222, 167,
+  136, 135, 137, 139, 138, 140, 190, 141, 143, 142, 144, 145, 147, 146, 148, 149,
+  240, 150, 152, 151, 153, 155, 154, 214, 191, 157, 156, 158, 159, 253, 254, 216
+};
+
+static char *iso_buf = 0;
+static int n_iso_buf = 0;
+
+// this function must be available for OpenGL character drawing as well
+const char *fl_iso2macRoman(const char *s, int n) {
+  // do not do a text lookup for 'Symbol' or 'WebDings'. This fails
+  // if the user assigns a new font to these numbers though.
+  if (fl_font_ == 12 || fl_font_ == 15)
+    return s;
+  if (n>n_iso_buf) {
+    if (iso_buf) free(iso_buf);
+    iso_buf = (char*)malloc(n+500);
+    n_iso_buf = n;
+  }
+  uchar *src = (uchar*)s;
+  uchar *dst = (uchar*)iso_buf;
+  for (;n--;) {
+    *dst++ = macroman_lut[*src++];
+  }
+  return iso_buf;
+}
+
+double fl_width(const char* c, int n) {
+  const char *txt = fl_iso2macRoman(c, n);
+#ifdef __APPLE_QD__
+  return (double)TextWidth( txt, 0, n );
+#else
+  if (!fl_gc) {
+    Fl_Window *w = Fl::first_window();
+    if (w) w->make_current();
+    if (!fl_gc) return -1;
+  }
+  // according to the Apple developer docs, this is the correct way to
+  // find the length of a rendered text...
+  CGContextSetTextPosition(fl_gc, 0, 0);
+  CGContextSetTextDrawingMode(fl_gc, kCGTextInvisible);
+  CGContextShowText(fl_gc, txt, n);
+  CGContextSetTextDrawingMode(fl_gc, kCGTextFill);
+  CGPoint p = CGContextGetTextPosition(fl_gc);
+  return p.x;
+#endif
+}
+
+double fl_width(uchar c) {
+#ifdef __APPLE_QD__
+  return (double)TextWidth((const char*)(macroman_lut + c), 0, 1 );
+#else
+  return fl_width((const char*)(&c), 1);
+#endif
+}
+
+void fl_draw(const char *str, int n, float x, float y);
+
+void fl_draw(const char* str, int n, int x, int y) {
+#ifdef __APPLE_QD__
+  const char *txt = fl_iso2macRoman(str, n);
+  MoveTo(x, y);
+  DrawText((const char *)txt, 0, n);
+#elif defined(__APPLE_QUARTZ__)
+  fl_draw(str, n, (float)x, (float)y);
+#else
+#  error : neither Quartz no Quickdraw chosen
+#endif
+}
+
+void fl_draw(const char *str, int n, float x, float y) {
+#ifdef __APPLE_QD__
+  fl_draw(str, n, (int)x, (int)y);
+#elif defined(__APPLE_QUARTZ__)
+  const char *txt = fl_iso2macRoman(str, n);
+  CGContextShowTextAtPoint(fl_gc, x, y, txt, n);
+#else
+#  error : neither Quartz no Quickdraw chosen
+#endif
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_font_win32.cxx b/Utilities/FLTK/src/fl_font_win32.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..13b361e830ba21f6b8451705974a879a7808058d
--- /dev/null
+++ b/Utilities/FLTK/src/fl_font_win32.cxx
@@ -0,0 +1,169 @@
+//
+// "$Id$"
+//
+// WIN32 font selection routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+Fl_FontSize::Fl_FontSize(const char* name, int size) {
+  int weight = FW_NORMAL;
+  int italic = 0;
+  switch (*name++) {
+  case 'I': italic = 1; break;
+  case 'P': italic = 1;
+  case 'B': weight = FW_BOLD; break;
+  case ' ': break;
+  default: name--;
+  }
+  fid = CreateFont(
+    -size, // negative makes it use "char size"
+    0,	            // logical average character width 
+    0,	            // angle of escapement 
+    0,	            // base-line orientation angle 
+    weight,
+    italic,
+    FALSE,	        // underline attribute flag 
+    FALSE,	        // strikeout attribute flag 
+    DEFAULT_CHARSET,    // character set identifier 
+    OUT_DEFAULT_PRECIS,	// output precision 
+    CLIP_DEFAULT_PRECIS,// clipping precision 
+    DEFAULT_QUALITY,	// output quality 
+    DEFAULT_PITCH,	// pitch and family 
+    name	        // pointer to typeface name string 
+    );
+  if (!fl_gc) fl_GetDC(0);
+  SelectObject(fl_gc, fid);
+  GetTextMetrics(fl_gc, &metr);
+//  BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar);
+// ...would be the right call, but is not implemented into Window95! (WinNT?)
+  GetCharWidth(fl_gc, 0, 255, width);
+#if HAVE_GL
+  listbase = 0;
+#endif
+  minsize = maxsize = size;
+}
+
+Fl_FontSize* fl_fontsize;
+
+Fl_FontSize::~Fl_FontSize() {
+#if HAVE_GL
+// Delete list created by gl_draw().  This is not done by this code
+// as it will link in GL unnecessarily.  There should be some kind
+// of "free" routine pointer, or a subclass?
+// if (listbase) {
+//  int base = font->min_char_or_byte2;
+//  int size = font->max_char_or_byte2-base+1;
+//  int base = 0; int size = 256;
+//  glDeleteLists(listbase+base,size);
+// }
+#endif
+  if (this == fl_fontsize) fl_fontsize = 0;
+  DeleteObject(fid);
+}
+
+////////////////////////////////////////////////////////////////
+
+// WARNING: if you add to this table, you must redefine FL_FREE_FONT
+// in Enumerations.H & recompile!!
+static Fl_Fontdesc built_in_table[] = {
+{" Arial"},
+{"BArial"},
+{"IArial"},
+{"PArial"},
+{" Courier New"},
+{"BCourier New"},
+{"ICourier New"},
+{"PCourier New"},
+{" Times New Roman"},
+{"BTimes New Roman"},
+{"ITimes New Roman"},
+{"PTimes New Roman"},
+{" Symbol"},
+{" Terminal"},
+{"BTerminal"},
+{" Wingdings"},
+};
+
+Fl_Fontdesc* fl_fonts = built_in_table;
+
+static Fl_FontSize* find(int fnum, int size) {
+  Fl_Fontdesc* s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // use 0 if fnum undefined
+  Fl_FontSize* f;
+  for (f = s->first; f; f = f->next)
+    if (f->minsize <= size && f->maxsize >= size) return f;
+  f = new Fl_FontSize(s->name, size);
+  f->next = s->first;
+  s->first = f;
+  return f;
+}
+
+////////////////////////////////////////////////////////////////
+// Public interface:
+
+int fl_font_ = 0;
+int fl_size_ = 0;
+//static HDC font_gc;
+
+void fl_font(int fnum, int size) {
+  if (fnum == fl_font_ && size == fl_size_) return;
+  fl_font_ = fnum; fl_size_ = size;
+  fl_fontsize = find(fnum, size);
+}
+
+int fl_height() {
+  if (fl_fontsize) return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent);
+  else return -1;
+}
+
+int fl_descent() {
+  if (fl_fontsize) return fl_fontsize->metr.tmDescent;
+  else return -1;
+}
+
+double fl_width(const char* c, int n) {
+  if (!fl_fontsize) return -1.0;
+  double w = 0.0;
+  while (n--) w += fl_fontsize->width[uchar(*c++)];
+  return w;
+}
+
+double fl_width(uchar c) {
+  if (fl_fontsize) return fl_fontsize->width[c];
+  else return -1.0;
+}
+
+void fl_draw(const char* str, int n, int x, int y) {
+  COLORREF oldColor = SetTextColor(fl_gc, fl_RGB());
+  if (fl_fontsize) SelectObject(fl_gc, fl_fontsize->fid);
+  TextOut(fl_gc, x, y, str, n);
+  SetTextColor(fl_gc, oldColor);
+}
+
+void fl_draw(const char* str, int n, float x, float y) {
+  fl_draw(str, n, (int)x, (int)y);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_font_x.cxx b/Utilities/FLTK/src/fl_font_x.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6540cc275f9d7fbc38038e8d0bb5a7f3040dc852
--- /dev/null
+++ b/Utilities/FLTK/src/fl_font_x.cxx
@@ -0,0 +1,264 @@
+//
+// "$Id$"
+//
+// Standard X11 font selection code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+Fl_FontSize::Fl_FontSize(const char* name) {
+  font = XLoadQueryFont(fl_display, name);
+  if (!font) {
+    Fl::warning("bad font: %s", name);
+    font = XLoadQueryFont(fl_display, "fixed"); // if fixed fails we crash
+  }
+#  if HAVE_GL
+  listbase = 0;
+#  endif
+}
+
+Fl_FontSize* fl_fontsize;
+
+Fl_FontSize::~Fl_FontSize() {
+#  if HAVE_GL
+// Delete list created by gl_draw().  This is not done by this code
+// as it will link in GL unnecessarily.  There should be some kind
+// of "free" routine pointer, or a subclass?
+// if (listbase) {
+//  int base = font->min_char_or_byte2;
+//  int size = font->max_char_or_byte2-base+1;
+//  int base = 0; int size = 256;
+//  glDeleteLists(listbase+base,size);
+// }
+#  endif
+  if (this == fl_fontsize) fl_fontsize = 0;
+  XFreeFont(fl_display, font);
+}
+
+////////////////////////////////////////////////////////////////
+
+// WARNING: if you add to this table, you must redefine FL_FREE_FONT
+// in Enumerations.H & recompile!!
+static Fl_Fontdesc built_in_table[] = {
+{"-*-helvetica-medium-r-normal--*"},
+{"-*-helvetica-bold-r-normal--*"},
+{"-*-helvetica-medium-o-normal--*"},
+{"-*-helvetica-bold-o-normal--*"},
+{"-*-courier-medium-r-normal--*"},
+{"-*-courier-bold-r-normal--*"},
+{"-*-courier-medium-o-normal--*"},
+{"-*-courier-bold-o-normal--*"},
+{"-*-times-medium-r-normal--*"},
+{"-*-times-bold-r-normal--*"},
+{"-*-times-medium-i-normal--*"},
+{"-*-times-bold-i-normal--*"},
+{"-*-symbol-*"},
+{"-*-lucidatypewriter-medium-r-normal-sans-*"},
+{"-*-lucidatypewriter-bold-r-normal-sans-*"},
+{"-*-*zapf dingbats-*"}
+};
+
+Fl_Fontdesc* fl_fonts = built_in_table;
+
+#define MAXSIZE 32767
+
+// return dash number N, or pointer to ending null if none:
+const char* fl_font_word(const char* p, int n) {
+  while (*p) {if (*p=='-') {if (!--n) break;} p++;}
+  return p;
+}
+
+// return a pointer to a number we think is "point size":
+char* fl_find_fontsize(char* name) {
+  char* c = name;
+  // for standard x font names, try after 7th dash:
+  if (*c == '-') {
+    c = (char*)fl_font_word(c,7);
+    if (*c++ && isdigit(*c)) return c;
+    return 0; // malformed x font name?
+  }
+  char* r = 0;
+  // find last set of digits:
+  for (c++;* c; c++)
+    if (isdigit(*c) && !isdigit(*(c-1))) r = c;
+  return r;
+}
+
+const char* fl_encoding = "iso8859-1";
+
+// return true if this matches fl_encoding:
+int fl_correct_encoding(const char* name) {
+  if (*name != '-') return 0;
+  const char* c = fl_font_word(name,13);
+  return (*c++ && !strcmp(c,fl_encoding));
+}
+
+// locate or create an Fl_FontSize for a given Fl_Fontdesc and size:
+static Fl_FontSize* find(int fnum, int size) {
+  Fl_Fontdesc* s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // use font 0 if still undefined
+  Fl_FontSize* f;
+  for (f = s->first; f; f = f->next)
+    if (f->minsize <= size && f->maxsize >= size) return f;
+  fl_open_display();
+  if (!s->xlist) {
+    s->xlist = XListFonts(fl_display, s->name, 100, &(s->n));
+    if (!s->xlist) {	// use fixed if no matching font...
+      s->first = new Fl_FontSize("fixed");
+      s->first->minsize = 0;
+      s->first->maxsize = 32767;
+      return s->first;
+    }
+  }
+  // search for largest <= font size:
+  char* name = s->xlist[0]; int ptsize = 0;	// best one found so far
+  int matchedlength = 32767;
+  char namebuffer[1024];	// holds scalable font name
+  int found_encoding = 0;
+  int m = s->n; if (m<0) m = -m;
+  for (int n=0; n < m; n++) {
+
+    char* thisname = s->xlist[n];
+    if (fl_correct_encoding(thisname)) {
+      if (!found_encoding) ptsize = 0; // force it to choose this
+      found_encoding = 1;
+    } else {
+      if (found_encoding) continue;
+    }
+    char* c = fl_find_fontsize(thisname);
+    int thissize = c ? atoi(c) : MAXSIZE;
+    int thislength = strlen(thisname);
+    if (thissize == size && thislength < matchedlength) {
+      // exact match, use it:
+      name = thisname;
+      ptsize = size;
+      matchedlength = thislength;
+    } else if (!thissize && ptsize!=size) {
+      // whoa!  A scalable font!  Use unless exact match found:
+      int l = c-thisname;
+      memcpy(namebuffer,thisname,l);
+      l += sprintf(namebuffer+l,"%d",size);
+      while (*c == '0') c++;
+      strcpy(namebuffer+l,c);
+      name = namebuffer;
+      ptsize = size;
+    } else if (!ptsize ||	// no fonts yet
+	       thissize < ptsize && ptsize > size || // current font too big
+	       thissize > ptsize && thissize <= size // current too small
+      ) {
+      name = thisname; ptsize = thissize;
+      matchedlength = thislength;
+    }
+  }
+
+  if (ptsize != size) { // see if we already found this unscalable font:
+    for (f = s->first; f; f = f->next) {
+      if (f->minsize <= ptsize && f->maxsize >= ptsize) {
+	if (f->minsize > size) f->minsize = size;
+	if (f->maxsize < size) f->maxsize = size;
+	return f;
+      }
+    }
+  }
+
+  // okay, we definately have some name, make the font:
+  f = new Fl_FontSize(name);
+  if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;}
+  else {f->minsize = size; f->maxsize = ptsize;}
+  f->next = s->first;
+  s->first = f;
+  return f;
+
+}
+
+////////////////////////////////////////////////////////////////
+// Public interface:
+
+int fl_font_ = 0;
+int fl_size_ = 0;
+XFontStruct* fl_xfont = 0;
+static GC font_gc;
+
+void fl_font(int fnum, int size) {
+  if (fnum == fl_font_ && size == fl_size_) return;
+  fl_font_ = fnum; fl_size_ = size;
+  Fl_FontSize* f = find(fnum, size);
+  if (f != fl_fontsize) {
+    fl_fontsize = f;
+    fl_xfont = f->font;
+    font_gc = 0;
+  }
+}
+
+int fl_height() {
+  if (fl_xfont) return (fl_xfont->ascent + fl_xfont->descent);
+  else return -1;
+}
+
+int fl_descent() {
+  if (fl_xfont) return fl_xfont->descent;
+  else return -1;
+}
+
+double fl_width(const char* c, int n) {
+  if (!fl_xfont) return -1.0;
+  XCharStruct* p = fl_xfont->per_char;
+  if (!p) return n*fl_xfont->min_bounds.width;
+  int a = fl_xfont->min_char_or_byte2;
+  int b = fl_xfont->max_char_or_byte2 - a;
+  int w = 0;
+  while (n--) {
+    int x = *(uchar*)c++ - a;
+    if (x >= 0 && x <= b) w += p[x].width;
+    else w += fl_xfont->min_bounds.width;
+  }
+  return w;
+}
+
+double fl_width(uchar c) {
+  if (!fl_xfont) return -1;
+  XCharStruct* p = fl_xfont->per_char;
+  if (p) {
+    int a = fl_xfont->min_char_or_byte2;
+    int b = fl_xfont->max_char_or_byte2 - a;
+    int x = c-a;
+    if (x >= 0 && x <= b) return p[x].width;
+  }
+  return fl_xfont->min_bounds.width;
+}
+
+void fl_draw(const char* str, int n, int x, int y) {
+  if (font_gc != fl_gc) {
+    if (!fl_xfont) fl_font(FL_HELVETICA, 14);
+    font_gc = fl_gc;
+    XSetFont(fl_display, fl_gc, fl_xfont->fid);
+  }
+  XDrawString(fl_display, fl_window, fl_gc, x, y, str, n);
+}
+  
+void fl_draw(const char* str, int n, float x, float y) {
+  fl_draw(str, n, (int)x, (int)y);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_font_xft.cxx b/Utilities/FLTK/src/fl_font_xft.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d608896bc0b1dd12f3a1a180226bf6cf106be2f0
--- /dev/null
+++ b/Utilities/FLTK/src/fl_font_xft.cxx
@@ -0,0 +1,265 @@
+//
+// "$Id$"
+//
+// Xft font code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2001-2005 Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//
+// Draw fonts using Keith Packard's Xft library to provide anti-
+// aliased text. Yow!
+//
+// Many thanks to Carl for making the original version of this.
+//
+// This font code only requires libXft to work.  Contrary to popular
+// belief there is no need to have FreeType, or the Xrender extension
+// available to use this code.  You will just get normal Xlib fonts
+// (Xft calls them "core" fonts) The Xft algorithms for choosing
+// these is about as good as the FLTK ones (I hope to fix it so it is
+// exactly as good...), plus it can cache it's results and share them
+// between programs, so using this should be a win in all cases. Also
+// it should be obvious by comparing this file and fl_font_x.cxx that
+// it is a lot easier to program with Xft than with Xlib.
+//
+// Also, Xft supports UTF-8 text rendering directly, which will allow
+// us to support UTF-8 on all platforms more easily.
+//
+// To actually get antialiasing you need the following:
+//
+//     1. You have XFree86 4
+//     2. You have the XRender extension
+//     3. Your X device driver supports the render extension
+//     4. You have libXft
+//     5. Your libXft has FreeType2 support compiled in
+//     6. You have the FreeType2 library
+//
+// Distributions that have XFree86 4.0.3 or later should have all of this...
+//
+// Unlike some other Xft packages, I tried to keep this simple and not
+// to work around the current problems in Xft by making the "patterns"
+// complicated. I belive doing this defeats our ability to improve Xft
+// itself. You should edit the ~/.xftconfig file to "fix" things, there
+// are several web pages of information on how to do this.
+//
+
+#include <X11/Xft/Xft.h>
+
+// The predefined fonts that FLTK has:
+static Fl_Fontdesc built_in_table[] = {
+{" sans"},
+{"Bsans"},
+{"Isans"},
+{"Psans"},
+{" mono"},
+{"Bmono"},
+{"Imono"},
+{"Pmono"},
+{" serif"},
+{"Bserif"},
+{"Iserif"},
+{"Pserif"},
+{" symbol"},
+{" screen"},
+{"Bscreen"},
+{" dingbats"},
+};
+
+Fl_Fontdesc* fl_fonts = built_in_table;
+
+#define current_font (fl_fontsize->font)
+
+int fl_font_ = 0;
+int fl_size_ = 0;
+XFontStruct* fl_xfont = 0;
+const char* fl_encoding_ = "iso8859-1";
+Fl_FontSize* fl_fontsize = 0;
+
+void fl_font(int fnum, int size) {
+  if (fnum == fl_font_ && size == fl_size_ &&
+      !strcasecmp(fl_fontsize->encoding, fl_encoding_))
+    return;
+  fl_font_ = fnum; fl_size_ = size;
+  Fl_Fontdesc *font = fl_fonts + fnum;
+  Fl_FontSize* f;
+  // search the fontsizes we have generated already
+  for (f = font->first; f; f = f->next) {
+    if (f->size == size && !strcasecmp(f->encoding, fl_encoding_))
+      break;
+  }
+  if (!f) {
+    f = new Fl_FontSize(font->name);
+    f->next = font->first;
+    font->first = f;
+  }
+  fl_fontsize = f;
+#if XFT_MAJOR < 2
+  fl_xfont    = f->font->u.core.font;
+#endif // XFT_MAJOR < 2
+}
+
+static XftFont* fontopen(const char* name, bool core) {
+  fl_open_display();
+  int slant = XFT_SLANT_ROMAN;
+  int weight = XFT_WEIGHT_MEDIUM;
+  // may be efficient, but this is non-obvious
+  switch (*name++) {
+  case 'I': slant = XFT_SLANT_ITALIC; break;
+  case 'P': slant = XFT_SLANT_ITALIC;
+  case 'B': weight = XFT_WEIGHT_BOLD; break;
+  case ' ': break;
+  default: name--;
+  }
+  // this call is extremely slow...
+  return XftFontOpen(fl_display, fl_screen,
+		     XFT_FAMILY, XftTypeString, name,
+		     XFT_WEIGHT, XftTypeInteger, weight,
+		     XFT_SLANT, XftTypeInteger, slant,
+		     XFT_ENCODING, XftTypeString, fl_encoding_,
+		     XFT_PIXEL_SIZE, XftTypeDouble, (double)fl_size_,
+		     core ? XFT_CORE : 0, XftTypeBool, true,
+		     XFT_RENDER, XftTypeBool, false,
+		     0);
+}
+
+Fl_FontSize::Fl_FontSize(const char* name) {
+  encoding = fl_encoding_;
+  size = fl_size_;
+#if HAVE_GL
+  listbase = 0;
+#endif // HAVE_GL
+  font = fontopen(name, false);
+}
+
+Fl_FontSize::~Fl_FontSize() {
+  if (this == fl_fontsize) fl_fontsize = 0;
+//  XftFontClose(fl_display, font);
+}
+
+int fl_height() {
+  if (current_font) return current_font->ascent + current_font->descent;
+  else return -1;
+}
+
+int fl_descent() {
+  if (current_font) return current_font->descent;
+  else return -1;
+}
+
+double fl_width(const char *str, int n) {
+  if (!current_font) return -1.0;
+  XGlyphInfo i;
+  XftTextExtents8(fl_display, current_font, (XftChar8 *)str, n, &i);
+  return i.xOff;
+}
+
+double fl_width(uchar c) {
+  return fl_width((const char *)(&c), 1);
+}
+
+#if HAVE_GL
+// This call is used by opengl to get a bitmapped font.
+XFontStruct* fl_xxfont() {
+#  if XFT_MAJOR > 1
+  // kludge!
+  static XFontStruct* fixed = 0;
+  if (!fixed) fixed = XLoadQueryFont(fl_display, "fixed");
+  return fixed;
+#  else
+  if (current_font->core) return current_font->u.core.font;
+  static XftFont* xftfont;
+  if (xftfont) XftFontClose (fl_display, xftfont);
+  xftfont = fontopen(fl_fonts[fl_font_].name, true);
+  return xftfont->u.core.font;
+#  endif // XFT_MAJOR > 1
+}
+#endif // HAVE_GL
+
+#if USE_OVERLAY
+// Currently Xft does not work with colormapped visuals, so this probably
+// does not work unless you have a true-color overlay.
+extern bool fl_overlay;
+extern Colormap fl_overlay_colormap;
+extern XVisualInfo* fl_overlay_visual;
+#endif
+
+// For some reason Xft produces errors if you destroy a window whose id
+// still exists in an XftDraw structure. It would be nice if this is not
+// true, a lot of junk is needed to try to stop this:
+
+static XftDraw* draw;
+static Window draw_window;
+#if USE_OVERLAY
+static XftDraw* draw_overlay;
+static Window draw_overlay_window;
+#endif
+
+void fl_destroy_xft_draw(Window id) {
+  if (id == draw_window)
+    XftDrawChange(draw, draw_window = fl_message_window);
+#if USE_OVERLAY
+  if (id == draw_overlay_window)
+    XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window);
+#endif
+}
+
+void fl_draw(const char *str, int n, int x, int y) {
+#if USE_OVERLAY
+  XftDraw*& draw = fl_overlay ? draw_overlay : ::draw;
+  if (fl_overlay) {
+    if (!draw) 
+      draw = XftDrawCreate(fl_display, draw_overlay_window = fl_window,
+			   fl_overlay_visual->visual, fl_overlay_colormap);
+    else //if (draw_overlay_window != fl_window)
+      XftDrawChange(draw, draw_overlay_window = fl_window);
+  } else
+#endif
+  if (!draw)
+    draw = XftDrawCreate(fl_display, draw_window = fl_window,
+			 fl_visual->visual, fl_colormap);
+  else //if (draw_window != fl_window)
+    XftDrawChange(draw, draw_window = fl_window);
+
+  Region region = fl_clip_region();
+  if (region && XEmptyRegion(region)) return;
+  XftDrawSetClip(draw, region);
+
+  // Use fltk's color allocator, copy the results to match what
+  // XftCollorAllocValue returns:
+  XftColor color;
+  color.pixel = fl_xpixel(fl_color_);
+  uchar r,g,b; Fl::get_color(fl_color_, r,g,b);
+  color.color.red   = ((int)r)*0x101;
+  color.color.green = ((int)g)*0x101;
+  color.color.blue  = ((int)b)*0x101;
+  color.color.alpha = 0xffff;
+
+  XftDrawString8(draw, &color, current_font, x, y, (XftChar8 *)str, n);
+}
+
+void fl_draw(const char* str, int n, float x, float y) {
+  fl_draw(str, n, (int)x, (int)y);
+}
+
+//
+// End of "$Id$"
+//
diff --git a/Utilities/FLTK/src/fl_images_core.cxx b/Utilities/FLTK/src/fl_images_core.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..96d374c125fb48c1fe3c124340c66e5801285c53
--- /dev/null
+++ b/Utilities/FLTK/src/fl_images_core.cxx
@@ -0,0 +1,103 @@
+//
+// "$Id$"
+//
+// FLTK images library core.
+//
+// Copyright 1997-2005 by Easy Software Products.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// Contents:
+//
+//   fl_register_images() - Register the image formats.
+//   fl_check_images()    - Check for a supported image format.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl_Shared_Image.H>
+#include <FL/Fl_BMP_Image.H>
+#include <FL/Fl_GIF_Image.H>
+#include <FL/Fl_JPEG_Image.H>
+#include <FL/Fl_PNG_Image.H>
+#include <FL/Fl_PNM_Image.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+
+//
+// Define a simple global image registration function that registers
+// the extra image formats that aren't part of the core FLTK library.
+//
+
+static Fl_Image	*fl_check_images(const char *name, uchar *header, int headerlen);
+
+
+//
+// 'fl_register_images()' - Register the image formats.
+//
+
+void fl_register_images() {
+  Fl_Shared_Image::add_handler(fl_check_images);
+}
+
+
+//
+// 'fl_check_images()' - Check for a supported image format.
+//
+
+Fl_Image *					// O - Image, if found
+fl_check_images(const char *name,		// I - Filename
+                uchar      *header,		// I - Header data from file
+		int        headerlen) {		// I - Amount of data
+  if (memcmp(header, "GIF87a", 6) == 0 ||
+      memcmp(header, "GIF89a", 6) == 0)	// GIF file
+    return new Fl_GIF_Image(name);
+
+  if (memcmp(header, "BM", 2) == 0)	// BMP file
+    return new Fl_BMP_Image(name);
+
+  if (header[0] == 'P' && header[1] >= '1' && header[1] <= '7')
+					// Portable anymap
+    return new Fl_PNM_Image(name);
+
+#ifdef HAVE_LIBPNG
+  if (memcmp(header, "\211PNG", 4) == 0)// PNG file
+    return new Fl_PNG_Image(name);
+#endif // HAVE_LIBPNG
+
+#ifdef HAVE_LIBJPEG
+  if (memcmp(header, "\377\330\377", 3) == 0 &&
+					// Start-of-Image
+      header[3] >= 0xe0 && header[3] <= 0xef)
+	   				// APPn for JPEG file
+    return new Fl_JPEG_Image(name);
+#endif // HAVE_LIBJPEG
+
+  return 0;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_labeltype.cxx b/Utilities/FLTK/src/fl_labeltype.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c73f40a9fbcc2145f3b1d2ca0c6c17073d556ba2
--- /dev/null
+++ b/Utilities/FLTK/src/fl_labeltype.cxx
@@ -0,0 +1,133 @@
+//
+// "$Id$"
+//
+// Label drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Drawing code for the (one) common label types.
+// Other label types (symbols) are in their own source files
+// to avoid linking if not used.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Group.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Image.H>
+
+void
+fl_no_label(const Fl_Label*,int,int,int,int,Fl_Align) {}
+
+void
+fl_normal_label(const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+  fl_font(o->font, o->size);
+  fl_color((Fl_Color)o->color);
+  fl_draw(o->value, X, Y, W, H, align, o->image);
+}
+
+void
+fl_normal_measure(const Fl_Label* o, int& W, int& H) {
+  fl_font(o->font, o->size);
+  fl_measure(o->value, W, H);
+  if (o->image) {
+    if (o->image->w() > W) W = o->image->w();
+    H += o->image->h();
+  }
+}
+
+#define MAX_LABELTYPE 16
+
+static Fl_Label_Draw_F* table[MAX_LABELTYPE] = {
+  fl_normal_label,
+  fl_no_label,
+  fl_normal_label,	// _FL_SHADOW_LABEL,
+  fl_normal_label,	// _FL_ENGRAVED_LABEL,
+  fl_normal_label,	// _FL_EMBOSSED_LABEL,
+  fl_no_label,		// _FL_MULTI_LABEL,
+  fl_no_label,		// _FL_ICON_LABEL,
+  // FL_FREE_LABELTYPE+n:
+  fl_no_label, fl_no_label, fl_no_label,
+  fl_no_label, fl_no_label, fl_no_label,
+  fl_no_label, fl_no_label, fl_no_label
+};
+
+static Fl_Label_Measure_F* measure[MAX_LABELTYPE];
+
+void Fl::set_labeltype(Fl_Labeltype t,Fl_Label_Draw_F* f,Fl_Label_Measure_F*m) 
+{
+  table[t] = f; measure[t] = m;
+}
+
+////////////////////////////////////////////////////////////////
+
+// draw label with arbitrary alignment in arbitrary box:
+void Fl_Label::draw(int X, int Y, int W, int H, Fl_Align align) const {
+  if (!value && !image) return;
+  table[type](this, X, Y, W, H, align);
+}
+
+void Fl_Label::measure(int& W, int& H) const {
+  if (!value && !image) {
+    W = H = 0;
+    return;
+  }
+
+  Fl_Label_Measure_F* f = ::measure[type]; if (!f) f = fl_normal_measure;
+  f(this, W, H);
+}
+
+// The normal call for a draw() method:
+void Fl_Widget::draw_label() const {
+  int X = x_+Fl::box_dx(box());
+  int W = w_-Fl::box_dw(box());
+  if (W > 11 && align()&(FL_ALIGN_LEFT|FL_ALIGN_RIGHT)) {X += 3; W -= 6;}
+  draw_label(X, y_+Fl::box_dy(box()), W, h_-Fl::box_dh(box()));
+}
+
+// draw() can use this instead to change the bounding box:
+void Fl_Widget::draw_label(int X, int Y, int W, int H) const {
+  // quit if we are not drawing a label inside the widget:
+  if ((align()&15) && !(align() & FL_ALIGN_INSIDE)) return;
+  draw_label(X,Y,W,H,align());
+}
+
+// Anybody can call this to force the label to draw anywhere:
+void Fl_Widget::draw_label(int X, int Y, int W, int H, Fl_Align a) const {
+  if (flags()&SHORTCUT_LABEL) fl_draw_shortcut = 1;
+  Fl_Label l1 = label_;
+  if (!active_r()) {
+    l1.color = fl_inactive((Fl_Color)l1.color);
+    if (l1.deimage) l1.image = l1.deimage;
+  }
+  l1.draw(X,Y,W,H,a);
+  fl_draw_shortcut = 0;
+}
+
+// include these vars here so they can be referenced without including
+// Fl_Input_ code:
+#include <FL/Fl_Input_.H>
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_line_style.cxx b/Utilities/FLTK/src/fl_line_style.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a0be2894da3b194223214b421b28c4e2ac3ffc4b
--- /dev/null
+++ b/Utilities/FLTK/src/fl_line_style.cxx
@@ -0,0 +1,165 @@
+//
+// "$Id$"
+//
+// Line style code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include "flstring.h"
+#include <stdio.h>
+
+#ifdef __APPLE_QUARTZ__
+float fl_quartz_line_width_ = 1.0f;
+static enum CGLineCap fl_quartz_line_cap_ = kCGLineCapButt;
+static enum CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter;
+static float *fl_quartz_line_pattern = 0;
+static int fl_quartz_line_pattern_size = 0;
+void fl_quartz_restore_line_style_() {
+  CGContextSetLineWidth(fl_gc, fl_quartz_line_width_);
+  CGContextSetLineCap(fl_gc, fl_quartz_line_cap_);
+  CGContextSetLineJoin(fl_gc, fl_quartz_line_join_);
+  CGContextSetLineDash(fl_gc, 0, fl_quartz_line_pattern, fl_quartz_line_pattern_size);
+}
+#endif
+
+void fl_line_style(int style, int width, char* dashes) {
+#ifdef WIN32
+  // According to Bill, the "default" cap and join should be the
+  // "fastest" mode supported for the platform.  I don't know why
+  // they should be different (same graphics cards, etc., right?) MRS
+  static DWORD Cap[4]= {PS_ENDCAP_FLAT, PS_ENDCAP_FLAT, PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE};
+  static DWORD Join[4]={PS_JOIN_ROUND, PS_JOIN_MITER, PS_JOIN_ROUND, PS_JOIN_BEVEL};
+  int s1 = PS_GEOMETRIC | Cap[(style>>8)&3] | Join[(style>>12)&3];
+  DWORD a[16]; int n = 0;
+  if (dashes && dashes[0]) {
+    s1 |= PS_USERSTYLE;
+    for (n = 0; n < 16 && *dashes; n++) a[n] = *dashes++;
+  } else {
+    s1 |= style & 0xff; // allow them to pass any low 8 bits for style
+  }
+  if ((style || n) && !width) width = 1; // fix cards that do nothing for 0?
+  LOGBRUSH penbrush = {BS_SOLID,fl_RGB(),0}; // can this be fl_brush()?
+  HPEN newpen = ExtCreatePen(s1, width, &penbrush, n, n ? a : 0);
+  if (!newpen) {
+    Fl::error("fl_line_style(): Could not create GDI pen object.");
+    return;
+  }
+  HPEN oldpen = (HPEN)SelectObject(fl_gc, newpen);
+  DeleteObject(oldpen);
+  DeleteObject(fl_current_xmap->pen);
+  fl_current_xmap->pen = newpen;
+#elif defined(__APPLE_QD__)
+  // QuickDraw supports pen size and pattern, but no arbitrary line styles.
+  static Pattern	styles[] = {
+    { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } },	// FL_SOLID
+    { { 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f } },	// FL_DASH
+    { { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 } }	// FL_DOT
+  };
+
+  if (!width) width = 1;
+  PenSize(width, width);
+
+  style &= 0xff;
+  if (style > 2) style = 2;
+  PenPat(styles + style);
+#elif defined(__APPLE_QUARTZ__)
+  static enum CGLineCap Cap[4] = { kCGLineCapButt, kCGLineCapButt, 
+                                   kCGLineCapRound, kCGLineCapSquare };
+  static enum CGLineJoin Join[4] = { kCGLineJoinMiter, kCGLineJoinMiter, 
+                                    kCGLineJoinRound, kCGLineJoinBevel };
+  if (width<1) width = 1;
+  fl_quartz_line_width_ = (float)width; 
+  fl_quartz_line_cap_ = Cap[(style>>8)&3];
+  fl_quartz_line_join_ = Join[(style>>12)&3];
+  char *d = dashes; 
+  static float pattern[16];
+  if (d && *d) {
+    float *p = pattern;
+    while (*d) { *p++ = (float)*d++; }
+    fl_quartz_line_pattern = pattern;
+    fl_quartz_line_pattern_size = d-dashes;
+  } else if (style & 0xff) {
+    char dash, dot, gap;
+    // adjust lengths to account for cap:
+    if (style & 0x200) {
+      dash = char(2*width);
+      dot = 1; 
+      gap = char(2*width-1);
+    } else {
+      dash = char(3*width);
+      dot = gap = char(width);
+    }
+    float *p = pattern;
+    switch (style & 0xff) {
+    case FL_DASH:       *p++ = dash; *p++ = gap; break;
+    case FL_DOT:        *p++ = dot; *p++ = gap; break;
+    case FL_DASHDOT:    *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break;
+    case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break;
+    }
+    fl_quartz_line_pattern_size = p-pattern;
+    fl_quartz_line_pattern = pattern;
+  } else {
+    fl_quartz_line_pattern = 0; fl_quartz_line_pattern_size = 0;
+  }
+  fl_quartz_restore_line_style_();
+#else
+  int ndashes = dashes ? strlen(dashes) : 0;
+  // emulate the WIN32 dash patterns on X
+  char buf[7];
+  if (!ndashes && (style&0xff)) {
+    int w = width ? width : 1;
+    char dash, dot, gap;
+    // adjust lengths to account for cap:
+    if (style & 0x200) {
+      dash = char(2*w);
+      dot = 1; // unfortunately 0 does not work
+      gap = char(2*w-1);
+    } else {
+      dash = char(3*w);
+      dot = gap = char(w);
+    }
+    char* p = dashes = buf;
+    switch (style & 0xff) {
+    case FL_DASH:	*p++ = dash; *p++ = gap; break;
+    case FL_DOT:	*p++ = dot; *p++ = gap; break;
+    case FL_DASHDOT:	*p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break;
+    case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break;
+    }
+    ndashes = p-buf;
+  }
+  static int Cap[4] = {CapButt, CapButt, CapRound, CapProjecting};
+  static int Join[4] = {JoinMiter, JoinMiter, JoinRound, JoinBevel};
+  XSetLineAttributes(fl_display, fl_gc, width, 
+		     ndashes ? LineOnOffDash : LineSolid,
+		     Cap[(style>>8)&3], Join[(style>>12)&3]);
+  if (ndashes) XSetDashes(fl_display, fl_gc, 0, dashes, ndashes);
+#endif
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_oval_box.cxx b/Utilities/FLTK/src/fl_oval_box.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3d5ad009e01f6d4ddfc55fc1833a0049116a5f1c
--- /dev/null
+++ b/Utilities/FLTK/src/fl_oval_box.cxx
@@ -0,0 +1,66 @@
+//
+// "$Id$"
+//
+// Oval box drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+
+// Less-used box types are in seperate files so they are not linked
+// in if not used.
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+static void fl_oval_flat_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(c);
+  fl_pie(x, y, w, h, 0, 360);
+}
+
+static void fl_oval_frame(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(c);
+  fl_arc(x, y, w, h, 0, 360);
+}
+
+static void fl_oval_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_oval_flat_box(x,y,w,h,c);
+  fl_oval_frame(x,y,w,h,FL_BLACK);
+}
+
+static void fl_oval_shadow_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_oval_flat_box(x+3,y+3,w,h,FL_DARK3);
+  fl_oval_box(x,y,w,h,c);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype fl_define_FL_OVAL_BOX() {
+  fl_internal_boxtype(_FL_OSHADOW_BOX,fl_oval_shadow_box);
+  fl_internal_boxtype(_FL_OVAL_FRAME,fl_oval_frame);
+  fl_internal_boxtype(_FL_OFLAT_BOX,fl_oval_flat_box);
+  fl_internal_boxtype(_FL_OVAL_BOX,fl_oval_box);
+  return _FL_OVAL_BOX;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_overlay.cxx b/Utilities/FLTK/src/fl_overlay.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6e740add3c8d426bbc3a6f626a03533c00db8057
--- /dev/null
+++ b/Utilities/FLTK/src/fl_overlay.cxx
@@ -0,0 +1,81 @@
+//
+// "$Id$"
+//
+// Overlay support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Extremely limited "overlay" support.  You can use this to drag out
+// a rectangle in response to mouse events.  It is your responsibility
+// to erase the overlay before drawing anything that might intersect
+// it.
+
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#ifdef __APPLE__
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#endif
+
+static int px,py,pw,ph;
+
+static void draw_current_rect() {
+#ifdef WIN32
+  int old = SetROP2(fl_gc, R2_NOT);
+  fl_rect(px, py, pw, ph);
+  SetROP2(fl_gc, old);
+#elif defined(__APPLE_QD__)
+  PenMode( patXor );
+  fl_rect(px, py, pw, ph);
+  PenMode( patCopy );
+#elif defined(__APPLE_QUARTZ__)
+  // warning: Quartz does not support xor drawing
+  // Use the Fl_Overlay_Window instead.
+  fl_rect(px, py, pw, ph);
+#else
+  XSetFunction(fl_display, fl_gc, GXxor);
+  XSetForeground(fl_display, fl_gc, 0xffffffff);
+  XDrawRectangle(fl_display, fl_window, fl_gc, px, py, pw, ph);
+  XSetFunction(fl_display, fl_gc, GXcopy);
+#endif
+}
+
+void fl_overlay_clear() {
+  if (pw > 0) {draw_current_rect(); pw = 0;}
+}
+
+void fl_overlay_rect(int x, int y, int w, int h) {
+  if (w < 0) {x += w; w = -w;} else if (!w) w = 1;
+  if (h < 0) {y += h; h = -h;} else if (!h) h = 1;
+  if (pw > 0) {
+    if (x==px && y==py && w==pw && h==ph) return;
+    draw_current_rect();
+  }
+  px = x; py = y; pw = w; ph = h;
+  draw_current_rect();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_overlay_visual.cxx b/Utilities/FLTK/src/fl_overlay_visual.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b94d130762ce456c2626a5ccf16d09b69689b4e6
--- /dev/null
+++ b/Utilities/FLTK/src/fl_overlay_visual.cxx
@@ -0,0 +1,107 @@
+//
+// "$Id$"
+//
+// X overlay support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Return an overlay visual, if any.  Also allocate a colormap and
+// record the depth for fl_color() to use.
+// Another disgusting X interface, based on code extracted and
+// purified with great difficulty from XLayerUtil.cxx:
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#if HAVE_OVERLAY
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+// SERVER_OVERLAY_VISUALS property element:
+struct OverlayInfo {
+  long overlay_visual;
+  long transparent_type;
+  long value;
+  long layer;
+};
+
+extern Colormap fl_overlay_colormap;
+extern XVisualInfo* fl_overlay_visual;
+extern ulong fl_transparent_pixel;
+
+XVisualInfo *fl_find_overlay_visual() {
+  static char beenhere;
+  if (beenhere) return fl_overlay_visual;
+  beenhere = 1;
+
+  fl_open_display();
+  Atom overlayVisualsAtom =
+    XInternAtom(fl_display,"SERVER_OVERLAY_VISUALS",1);
+  if (!overlayVisualsAtom) return 0;
+  OverlayInfo *overlayInfo;
+  ulong sizeData, bytesLeft;
+  Atom actualType;
+  int actualFormat;
+  if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
+			 overlayVisualsAtom, 0L, 10000L, False,
+			 overlayVisualsAtom, &actualType, &actualFormat,
+			 &sizeData, &bytesLeft,
+			 (unsigned char **) &overlayInfo)) return 0;
+
+  if (actualType == overlayVisualsAtom && actualFormat == 32) {
+    int n = int(sizeData/4);
+    XVisualInfo* v = 0;
+    // find the greatest depth that has a transparent pixel:
+    for (int i = 0; i < n; i++) {
+      if (overlayInfo[i].transparent_type != 1) continue;
+      if (overlayInfo[i].layer <= 0) continue;
+      XVisualInfo templt;
+      templt.visualid = overlayInfo[i].overlay_visual;
+      int num;
+      XVisualInfo *v1=XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
+      if (v1->screen == fl_screen && v1->c_class == PseudoColor
+	  && (!v || v1->depth > v->depth && v1->depth <= 8)) {
+	if (v) XFree((char*)v);
+	v = v1;
+	fl_transparent_pixel = overlayInfo[i].value;
+      } else {
+	XFree((char*)v1);
+      }
+    }
+    if (v) {
+      fl_overlay_visual = v;
+      fl_overlay_colormap = 
+	XCreateColormap(fl_display, RootWindow(fl_display, fl_screen),
+			v->visual, AllocNone);
+    }
+  }
+  XFree((char*)overlayInfo);
+  //printf("overlay visual %ld selected\n", fl_overlay_visual->visualid);
+  return fl_overlay_visual;
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_plastic.cxx b/Utilities/FLTK/src/fl_plastic.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..86216e3cc8d9a6ba879ff3f3c7e2de3f90685d6f
--- /dev/null
+++ b/Utilities/FLTK/src/fl_plastic.cxx
@@ -0,0 +1,381 @@
+//
+// "$Id$"
+//
+// "Plastic" drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// These box types provide a cross between Aqua and KDE buttons; kindof
+// like translucent plastic buttons...
+//
+// Copyright 2001-2005 by Michael Sweet.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Box drawing code for an obscure box type.
+// These box types are in seperate files so they are not linked
+// in if not used.
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include "flstring.h"
+
+//
+// Uncomment the following line to restore the old plastic box type
+// appearance.
+//
+
+//#define USE_OLD_PLASTIC_BOX
+#define USE_OLD_PLASTIC_COLOR
+
+extern uchar *fl_gray_ramp();
+
+inline Fl_Color shade_color(uchar gc, Fl_Color bc) {
+#ifdef USE_OLD_PLASTIC_COLOR
+  return fl_color_average((Fl_Color)gc, bc, 0.75f);
+#else
+  unsigned	grgb = Fl::get_color((Fl_Color)gc),
+		brgb = Fl::get_color(bc);
+  int		red, green, blue, gray;
+
+
+  gray  = ((grgb >> 24) & 255);
+  red   = gray * ((brgb >> 24) & 255) / 255 + gray * gray / 510;
+  gray  = ((grgb >> 16) & 255);
+  green = gray * ((brgb >> 16) & 255) / 255 + gray * gray / 510;
+  gray  = ((grgb >> 8) & 255);
+  blue  = gray * ((brgb >> 8) & 255) / 255 + gray * gray / 510;
+
+  if (red > 255)
+    red = 255;
+
+  if (green > 255)
+    green = 255;
+
+  if (blue > 255)
+    blue = 255;
+
+  if (Fl::draw_box_active())
+    return fl_rgb_color(red, green, blue);
+  else
+    return fl_color_average(FL_GRAY, fl_rgb_color(red, green, blue), 0.75f);
+#endif // USE_OLD_PLASTIC_COLOR
+}
+
+
+static void frame_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
+  uchar *g = fl_gray_ramp();
+  int b = strlen(c) / 4 + 1;
+
+  for (x += b, y += b, w -= 2 * b, h -= 2 * b; b > 1; b --)
+  {
+    // Draw lines around the perimeter of the button, 4 colors per
+    // circuit.
+    fl_color(shade_color(g[*c++], bc));
+    fl_line(x, y + h + b, x + w - 1, y + h + b, x + w + b - 1, y + h);
+    fl_color(shade_color(g[*c++], bc));
+    fl_line(x + w + b - 1, y + h, x + w + b - 1, y, x + w - 1, y - b);
+    fl_color(shade_color(g[*c++], bc));
+    fl_line(x + w - 1, y - b, x, y - b, x - b, y);
+    fl_color(shade_color(g[*c++], bc));
+    fl_line(x - b, y, x - b, y + h, x, y + h + b);
+  }
+}
+
+
+static void frame_round(int x, int y, int w, int h, const char *c, Fl_Color bc) {
+  uchar *g = fl_gray_ramp();
+  int b = strlen(c) / 4 + 1;
+
+  if (w==h) {
+    for (; b > 1; b --, x ++, y ++, w -= 2, h -= 2)
+    {
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, w, h, 45.0, 135.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, w, h, 315.0, 405.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, w, h, 225.0, 315.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, w, h, 135.0, 225.0);
+    }
+  } else if (w>h) {
+    int d = h/2;
+    for (; b > 1; d--, b --, x ++, y ++, w -= 2, h -= 2)
+    {
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, h, h, 90.0, 135.0);
+      fl_xyline(x+d, y, x+w-d);
+      fl_arc(x+w-h, y, h, h, 45.0, 90.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x+w-h, y, h, h, 315.0, 405.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x+w-h, y, h, h, 270.0, 315.0);
+      fl_xyline(x+d, y+h-1, x+w-d);
+      fl_arc(x, y, h, h, 225.0, 270.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, h, h, 135.0, 225.0);
+    }
+  } else if (w<h) {
+    int d = w/2;
+    for (; b > 1; d--, b --, x ++, y ++, w -= 2, h -= 2)
+    {
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, w, w, 45.0, 135.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y, w, w, 0.0, 45.0);
+      fl_yxline(x+w-1, y+d, y+h-d);
+      fl_arc(x, y+h-w, w, w, 315.0, 360.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y+h-w, w, w, 225.0, 315.0);
+      fl_color(shade_color(g[*c++], bc));
+      fl_arc(x, y+h-w, w, w, 180.0, 225.0);
+      fl_yxline(x, y+d, y+h-d);
+      fl_arc(x, y, w, w, 135.0, 180.0);
+    }
+  }
+}
+
+
+static void shade_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
+  uchar		*g = fl_gray_ramp();
+  int		i, j;
+  int		clen = strlen(c) - 1;
+  int		chalf = clen / 2;
+  int		cstep = 1;
+
+  if (h < (w * 2)) {
+    // Horizontal shading...
+    if (clen >= h) cstep = 2;
+
+    for (i = 0, j = 0; j < chalf; i ++, j += cstep) {
+      // Draw the top line and points...
+      fl_color(shade_color(g[c[i]], bc));
+      fl_xyline(x + 1, y + i, x + w - 2);
+
+      fl_color(shade_color(g[c[i] - 2], bc));
+      fl_point(x, y + i + 1);
+      fl_point(x + w - 1, y + i + 1);
+
+      // Draw the bottom line and points...
+      fl_color(shade_color(g[c[clen - i]], bc));
+      fl_xyline(x + 1, y + h - i, x + w - 2);
+
+      fl_color(shade_color(g[c[clen - i] - 2], bc));
+      fl_point(x, y + h - i);
+      fl_point(x + w - 1, y + h - i);
+    }
+
+    // Draw the interior and sides...
+    i = chalf / cstep;
+
+    fl_color(shade_color(g[c[chalf]], bc));
+    fl_rectf(x + 1, y + i, w - 2, h - 2 * i + 1);
+
+    fl_color(shade_color(g[c[chalf] - 2], bc));
+    fl_yxline(x, y + i, y + h - i);
+    fl_yxline(x + w - 1, y + i, y + h - i);
+  } else {
+    // Vertical shading...
+    if (clen >= w) cstep = 2;
+
+    for (i = 0, j = 0; j < chalf; i ++, j += cstep) {
+      // Draw the left line and points...
+      fl_color(shade_color(g[c[i]], bc));
+      fl_yxline(x + i, y + 1, y + h - 1);
+
+      fl_color(shade_color(g[c[i] - 2], bc));
+      fl_point(x + i + 1, y);
+      fl_point(x + i + 1, y + h);
+
+      // Draw the right line and points...
+      fl_color(shade_color(g[c[clen - i]], bc));
+      fl_yxline(x + w - 1 - i, y + 1, y + h - 1);
+
+      fl_color(shade_color(g[c[clen - i] - 2], bc));
+      fl_point(x + w - 2 - i, y);
+      fl_point(x + w - 2 - i, y + h);
+    }
+
+    // Draw the interior, top, and bottom...
+    i = chalf / cstep;
+
+    fl_color(shade_color(g[c[chalf]], bc));
+    fl_rectf(x + i, y + 1, w - 2 * i, h - 1);
+
+    fl_color(shade_color(g[c[chalf] - 2], bc));
+    fl_xyline(x + i, y, x + w - i);
+    fl_xyline(x + i, y + h, x + w - i);
+  }
+}
+
+static void shade_round(int x, int y, int w, int h, const char *c, Fl_Color bc) {
+  uchar		*g = fl_gray_ramp();
+  int		i;
+  int		clen = strlen(c) - 1;
+  int		chalf = clen / 2;
+
+  if (w>h) {
+    int d = h/2;
+    const int na = 8;
+    for (i=0; i<chalf; i++, d--, x++, y++, w-=2, h-=2)
+    {
+      fl_color(shade_color(g[c[i]], bc));
+      fl_pie(x, y, h, h, 90.0, 135.0+i*na);
+      fl_xyline(x+d, y, x+w-d);
+      fl_pie(x+w-h, y, h, h, 45.0+i*na, 90.0);
+      fl_color(shade_color(g[c[i] - 2], bc));
+      fl_pie(x+w-h, y, h, h, 315.0+i*na, 405.0+i*na);
+      fl_color(shade_color(g[c[clen - i]], bc));
+      fl_pie(x+w-h, y, h, h, 270.0, 315.0+i*na);
+      fl_xyline(x+d, y+h-1, x+w-d);
+      fl_pie(x, y, h, h, 225.0+i*na, 270.0);
+      fl_color(shade_color(g[c[clen - i] - 2], bc));
+      fl_pie(x, y, h, h, 135.0+i*na, 225.0+i*na);
+    }
+    fl_color(shade_color(g[c[chalf]], bc));
+    fl_rectf(x+d, y, w-h+1, h+1);
+    fl_pie(x, y, h, h, 90.0, 270.0);
+    fl_pie(x+w-h, y, h, h, 270.0, 90.0);
+  } else {
+    int d = w/2;
+    const int na = 8;
+    for (i=0; i<chalf; i++, d--, x++, y++, w-=2, h-=2)
+    {
+      fl_color(shade_color(g[c[i]], bc));
+      fl_pie(x, y, w, w, 45.0+i*na, 135.0+i*na);
+      fl_color(shade_color(g[c[i] - 2], bc));
+      fl_pie(x, y, w, w, 0.0, 45.0+i*na);
+      fl_yxline(x+w-1, y+d, y+h-d);
+      fl_pie(x, y+h-w, w, w, 315.0+i*na, 360.0);
+      fl_color(shade_color(g[c[clen - i]], bc));
+      fl_pie(x, y+h-w, w, w, 225.0+i*na, 315.0+i*na);
+      fl_color(shade_color(g[c[clen - i] - 2], bc));
+      fl_pie(x, y+h-w, w, w, 180.0, 225.0+i*na);
+      fl_yxline(x, y+d, y+h-d);
+      fl_pie(x, y, w, w, 135.0+i*na, 180.0);
+    }
+    fl_color(shade_color(g[c[chalf]], bc));
+    fl_rectf(x, y+d, w+1, h-w+1);
+    fl_pie(x, y, w, w, 0.0, 180.0);
+    fl_pie(x, y+h-w, w, w, 180.0, 360.0);
+  }
+}
+
+
+static void up_frame(int x, int y, int w, int h, Fl_Color c) {
+  frame_rect(x, y, w, h - 1, "KLDIIJLM", c);
+}
+
+
+static void narrow_thin_box(int x, int y, int w, int h, Fl_Color c) {
+  if (h<=0 || w<=0) return;
+  uchar *g = fl_gray_ramp();
+  fl_color(shade_color(g['R'], c));
+  fl_rectf(x+1, y+1, w-2, h-2);
+  fl_color(shade_color(g['I'], c));
+  if (w > 1) {
+    fl_xyline(x+1, y, x+w-2);
+    fl_xyline(x+1, y+h-1, x+w-2);
+  }
+  if (h > 1) {
+    fl_yxline(x, y+1, y+h-2);
+    fl_yxline(x+w-1, y+1, y+h-2);
+  }
+}
+
+
+static void thin_up_box(int x, int y, int w, int h, Fl_Color c) {
+#ifdef USE_OLD_PLASTIC_BOX
+  shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c);
+  up_frame(x, y, w, h, c);
+#else
+  if (w > 4 && h > 4) {
+    shade_rect(x + 1, y + 1, w - 2, h - 3, "RQOQSUWQ", c);
+    frame_rect(x, y, w, h - 1, "IJLM", c);
+  } else {
+    narrow_thin_box(x, y, w, h, c);
+  }
+#endif // USE_OLD_PLASTIC_BOX
+}
+
+
+static void up_box(int x, int y, int w, int h, Fl_Color c) {
+#ifdef USE_OLD_PLASTIC_BOX
+  shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c);
+  up_frame(x, y, w, h, c);
+#else
+  if (w > 8 && h > 8) {
+    shade_rect(x + 1, y + 1, w - 2, h - 3, "RVQNOPQRSTUVWVQ", c);
+    frame_rect(x, y, w, h - 1, "IJLM", c);
+  } else {
+    thin_up_box(x, y, w, h, c);
+  }
+#endif // USE_OLD_PLASTIC_BOX
+}
+
+
+static void up_round(int x, int y, int w, int h, Fl_Color c) {
+  shade_round(x, y, w, h, "RVQNOPQRSTUVWVQ", c);
+  frame_round(x, y, w, h, "IJLM", c);
+}
+
+
+static void down_frame(int x, int y, int w, int h, Fl_Color c) {
+  frame_rect(x, y, w, h - 1, "LLLLTTRR", c);
+}
+
+
+static void down_box(int x, int y, int w, int h, Fl_Color c) {
+  if (w > 6 && h > 6) {
+    shade_rect(x + 2, y + 2, w - 4, h - 5, "STUVWWWVT", c);
+    down_frame(x, y, w, h, c);
+  }
+  else {
+    narrow_thin_box(x, y, w, h, c);
+  }
+}
+
+
+static void down_round(int x, int y, int w, int h, Fl_Color c) {
+  shade_round(x, y, w, h, "STUVWWWVT", c);
+  frame_round(x, y, w, h, "IJLM", c);
+}
+
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+
+
+Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX() {
+  fl_internal_boxtype(_FL_PLASTIC_UP_BOX, up_box);
+  fl_internal_boxtype(_FL_PLASTIC_DOWN_BOX, down_box);
+  fl_internal_boxtype(_FL_PLASTIC_UP_FRAME, up_frame);
+  fl_internal_boxtype(_FL_PLASTIC_DOWN_FRAME, down_frame);
+  fl_internal_boxtype(_FL_PLASTIC_THIN_UP_BOX, thin_up_box);
+  fl_internal_boxtype(_FL_PLASTIC_THIN_DOWN_BOX, down_box);
+  fl_internal_boxtype(_FL_PLASTIC_ROUND_UP_BOX, up_round);
+  fl_internal_boxtype(_FL_PLASTIC_ROUND_DOWN_BOX, down_round);
+
+  return _FL_PLASTIC_UP_BOX;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_read_image.cxx b/Utilities/FLTK/src/fl_read_image.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f0370a9c6359198a0d3c8e36978fca67fe13eafd
--- /dev/null
+++ b/Utilities/FLTK/src/fl_read_image.cxx
@@ -0,0 +1,425 @@
+//
+// "$Id$"
+//
+// X11 image reading routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include "flstring.h"
+
+#ifdef DEBUG
+#  include <stdio.h>
+#endif // DEBUG
+
+#ifdef WIN32
+#  include "fl_read_image_win32.cxx"
+#elif defined(__APPLE__)
+#  include "fl_read_image_mac.cxx"
+#else
+#  include <X11/Xutil.h>
+#  ifdef __sgi
+#    include <X11/extensions/readdisplay.h>
+#  endif // __sgi
+
+// Defined in fl_color.cxx
+extern uchar fl_redmask, fl_greenmask, fl_bluemask;
+extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift;
+
+//
+// 'fl_read_image()' - Read an image from the current window.
+//
+
+uchar *				// O - Pixel buffer or NULL if failed
+fl_read_image(uchar *p,		// I - Pixel buffer or NULL to allocate
+              int   X,		// I - Left position
+	      int   Y,		// I - Top position
+	      int   w,		// I - Width of area to read
+	      int   h,		// I - Height of area to read
+	      int   alpha) {	// I - Alpha value for image (0 for none)
+  XImage	*image;		// Captured image
+  int		i, maxindex;	// Looping vars
+  int           x, y;		// Current X & Y in image
+  int		d;		// Depth of image
+  unsigned char *line,		// Array to hold image row
+		*line_ptr;	// Pointer to current line image
+  unsigned char	*pixel;		// Current color value
+  XColor	colors[4096];	// Colors from the colormap...
+  unsigned char	cvals[4096][3];	// Color values from the colormap...
+  unsigned	index_mask,
+		index_shift,
+		red_mask,
+		red_shift,
+		green_mask,
+		green_shift,
+		blue_mask,
+		blue_shift;
+
+
+  //
+  // Under X11 we have the option of the XGetImage() interface or SGI's
+  // ReadDisplay extension which does all of the really hard work for
+  // us...
+  //
+
+#  ifdef __sgi
+  if (XReadDisplayQueryExtension(fl_display, &i, &i)) {
+    image = XReadDisplay(fl_display, fl_window, X, Y, w, h, 0, NULL);
+  } else
+#  else
+  image = 0;
+#  endif // __sgi
+
+  if (!image) {
+    image = XGetImage(fl_display, fl_window, X, Y, w, h, AllPlanes, ZPixmap);
+  }
+
+  if (!image) return 0;
+
+#ifdef DEBUG
+  printf("width            = %d\n", image->width);
+  printf("height           = %d\n", image->height);
+  printf("xoffset          = %d\n", image->xoffset);
+  printf("format           = %d\n", image->format);
+  printf("data             = %p\n", image->data);
+  printf("byte_order       = %d\n", image->byte_order);
+  printf("bitmap_unit      = %d\n", image->bitmap_unit);
+  printf("bitmap_bit_order = %d\n", image->bitmap_bit_order);
+  printf("bitmap_pad       = %d\n", image->bitmap_pad);
+  printf("depth            = %d\n", image->depth);
+  printf("bytes_per_line   = %d\n", image->bytes_per_line);
+  printf("bits_per_pixel   = %d\n", image->bits_per_pixel);
+  printf("red_mask         = %08x\n", image->red_mask);
+  printf("green_mask       = %08x\n", image->green_mask);
+  printf("blue_mask        = %08x\n", image->blue_mask);
+  printf("map_entries      = %d\n", fl_visual->visual->map_entries);
+#endif // DEBUG
+
+  d = alpha ? 4 : 3;
+
+  // Allocate the image data array as needed...
+  if (!p) p = new uchar[w * h * d];
+
+  // Initialize the default colors/alpha in the whole image...
+  memset(p, alpha, w * h * d);
+
+  // Check that we have valid mask/shift values...
+  if (!image->red_mask && image->bits_per_pixel > 12) {
+    // Greater than 12 bits must be TrueColor...
+    image->red_mask   = fl_visual->visual->red_mask;
+    image->green_mask = fl_visual->visual->green_mask;
+    image->blue_mask  = fl_visual->visual->blue_mask;
+
+#ifdef DEBUG
+    puts("\n---- UPDATED ----");
+    printf("fl_redmask       = %08x\n", fl_redmask);
+    printf("fl_redshift      = %d\n", fl_redshift);
+    printf("fl_greenmask     = %08x\n", fl_greenmask);
+    printf("fl_greenshift    = %d\n", fl_greenshift);
+    printf("fl_bluemask      = %08x\n", fl_bluemask);
+    printf("fl_blueshift     = %d\n", fl_blueshift);
+    printf("red_mask         = %08x\n", image->red_mask);
+    printf("green_mask       = %08x\n", image->green_mask);
+    printf("blue_mask        = %08x\n", image->blue_mask);
+#endif // DEBUG
+  }
+
+  // Check if we have colormap image...
+  if (!image->red_mask) {
+    // Get the colormap entries for this window...
+    maxindex = fl_visual->visual->map_entries;
+
+    for (i = 0; i < maxindex; i ++) colors[i].pixel = i;
+
+    XQueryColors(fl_display, fl_colormap, colors, maxindex);
+
+    for (i = 0; i < maxindex; i ++) {
+      cvals[i][0] = colors[i].red >> 8;
+      cvals[i][1] = colors[i].green >> 8;
+      cvals[i][2] = colors[i].blue >> 8;
+    }
+
+    // Read the pixels and output an RGB image...
+    for (y = 0; y < image->height; y ++) {
+      pixel = (unsigned char *)(image->data + y * image->bytes_per_line);
+      line  = p + y * w * d;
+
+      switch (image->bits_per_pixel) {
+        case 1 :
+	  for (x = image->width, line_ptr = line, index_mask = 128;
+	       x > 0;
+	       x --, line_ptr += d) {
+	    if (*pixel & index_mask) {
+	      line_ptr[0] = cvals[1][0];
+	      line_ptr[1] = cvals[1][1];
+	      line_ptr[2] = cvals[1][2];
+            } else {
+	      line_ptr[0] = cvals[0][0];
+	      line_ptr[1] = cvals[0][1];
+	      line_ptr[2] = cvals[0][2];
+            }
+
+            if (index_mask > 1) {
+	      index_mask >>= 1;
+	    } else {
+              index_mask = 128;
+              pixel ++;
+            }
+	  }
+          break;
+
+        case 2 :
+	  for (x = image->width, line_ptr = line, index_shift = 6;
+	       x > 0;
+	       x --, line_ptr += d) {
+	    i = (*pixel >> index_shift) & 3;
+
+	    line_ptr[0] = cvals[i][0];
+	    line_ptr[1] = cvals[i][1];
+	    line_ptr[2] = cvals[i][2];
+
+            if (index_shift > 0) {
+              index_mask >>= 2;
+              index_shift -= 2;
+            } else {
+              index_mask  = 192;
+              index_shift = 6;
+              pixel ++;
+            }
+	  }
+          break;
+
+        case 4 :
+	  for (x = image->width, line_ptr = line, index_shift = 4;
+	       x > 0;
+	       x --, line_ptr += d) {
+	    if (index_shift == 4) i = (*pixel >> 4) & 15;
+	    else i = *pixel & 15;
+
+	    line_ptr[0] = cvals[i][0];
+	    line_ptr[1] = cvals[i][1];
+	    line_ptr[2] = cvals[i][2];
+
+            if (index_shift > 0) {
+              index_shift = 0;
+	    } else {
+              index_shift = 4;
+              pixel ++;
+            }
+	  }
+          break;
+
+        case 8 :
+	  for (x = image->width, line_ptr = line;
+	       x > 0;
+	       x --, line_ptr += d, pixel ++) {
+	    line_ptr[0] = cvals[*pixel][0];
+	    line_ptr[1] = cvals[*pixel][1];
+	    line_ptr[2] = cvals[*pixel][2];
+	  }
+          break;
+
+        case 12 :
+	  for (x = image->width, line_ptr = line, index_shift = 0;
+	       x > 0;
+	       x --, line_ptr += d) {
+	    if (index_shift == 0) {
+	      i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095;
+	    } else {
+	      i = ((pixel[1] << 8) | pixel[2]) & 4095;
+	    }
+
+	    line_ptr[0] = cvals[i][0];
+	    line_ptr[1] = cvals[i][1];
+	    line_ptr[2] = cvals[i][2];
+
+            if (index_shift == 0) {
+              index_shift = 4;
+            } else {
+              index_shift = 0;
+              pixel += 3;
+            }
+	  }
+          break;
+      }
+    }
+  } else {
+    // RGB(A) image, so figure out the shifts & masks...
+    red_mask  = image->red_mask;
+    red_shift = 0;
+
+    while ((red_mask & 1) == 0) {
+      red_mask >>= 1;
+      red_shift ++;
+    }
+
+    green_mask  = image->green_mask;
+    green_shift = 0;
+
+    while ((green_mask & 1) == 0) {
+      green_mask >>= 1;
+      green_shift ++;
+    }
+
+    blue_mask  = image->blue_mask;
+    blue_shift = 0;
+
+    while ((blue_mask & 1) == 0) {
+      blue_mask >>= 1;
+      blue_shift ++;
+    }
+
+    // Read the pixels and output an RGB image...
+    for (y = 0; y < image->height; y ++) {
+      pixel = (unsigned char *)(image->data + y * image->bytes_per_line);
+      line  = p + y * w * d;
+
+      switch (image->bits_per_pixel) {
+        case 8 :
+	  for (x = image->width, line_ptr = line;
+	       x > 0;
+	       x --, line_ptr += d, pixel ++) {
+	    i = *pixel;
+
+	    line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	    line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	    line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+	  }
+          break;
+
+        case 12 :
+	  for (x = image->width, line_ptr = line, index_shift = 0;
+	       x > 0;
+	       x --, line_ptr += d) {
+	    if (index_shift == 0) {
+	      i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095;
+	    } else {
+	      i = ((pixel[1] << 8) | pixel[2]) & 4095;
+            }
+
+	    line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	    line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	    line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+
+            if (index_shift == 0) {
+              index_shift = 4;
+            } else {
+              index_shift = 0;
+              pixel += 3;
+            }
+	  }
+          break;
+
+        case 16 :
+          if (image->byte_order == LSBFirst) {
+            // Little-endian...
+	    for (x = image->width, line_ptr = line;
+	         x > 0;
+	         x --, line_ptr += d, pixel += 2) {
+	      i = (pixel[1] << 8) | pixel[0];
+
+	      line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	      line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	      line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+	    }
+	  } else {
+            // Big-endian...
+	    for (x = image->width, line_ptr = line;
+	         x > 0;
+	         x --, line_ptr += d, pixel += 2) {
+	      i = (pixel[0] << 8) | pixel[1];
+
+	      line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	      line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	      line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+	    }
+	  }
+          break;
+
+        case 24 :
+          if (image->byte_order == LSBFirst) {
+            // Little-endian...
+	    for (x = image->width, line_ptr = line;
+	         x > 0;
+	         x --, line_ptr += d, pixel += 3) {
+	      i = (((pixel[2] << 8) | pixel[1]) << 8) | pixel[0];
+
+	      line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	      line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	      line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+	    }
+	  } else {
+            // Big-endian...
+	    for (x = image->width, line_ptr = line;
+	         x > 0;
+	         x --, line_ptr += d, pixel += 3) {
+	      i = (((pixel[0] << 8) | pixel[1]) << 8) | pixel[2];
+
+	      line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	      line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	      line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+	    }
+	  }
+          break;
+
+        case 32 :
+          if (image->byte_order == LSBFirst) {
+            // Little-endian...
+	    for (x = image->width, line_ptr = line;
+	         x > 0;
+	         x --, line_ptr += d, pixel += 4) {
+	      i = (((((pixel[3] << 8) | pixel[2]) << 8) | pixel[1]) << 8) | pixel[0];
+
+	      line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	      line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	      line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+	    }
+	  } else {
+            // Big-endian...
+	    for (x = image->width, line_ptr = line;
+	         x > 0;
+	         x --, line_ptr += d, pixel += 4) {
+	      i = (((((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]) << 8) | pixel[3];
+
+	      line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask;
+	      line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask;
+	      line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask;
+	    }
+	  }
+          break;
+      }
+    }
+  }
+
+  // Destroy the X image we've read and return the RGB(A) image...
+  XDestroyImage(image);
+
+  return p;
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_read_image_mac.cxx b/Utilities/FLTK/src/fl_read_image_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0488fedd6bb3afd7cac2a053f81fa8cc9c625673
--- /dev/null
+++ b/Utilities/FLTK/src/fl_read_image_mac.cxx
@@ -0,0 +1,129 @@
+//
+// "$Id$"
+//
+// WIN32 image reading routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+// warning: this function is only implemented in Quickdraw. The function
+//          below may not work If FLTK is compiled with Quartz enabled
+
+//
+// 'fl_read_image()' - Read an image from the current window.
+//
+
+uchar *				// O - Pixel buffer or NULL if failed
+fl_read_image(uchar *p,		// I - Pixel buffer or NULL to allocate
+              int   x,		// I - Left position
+	      int   y,		// I - Top position
+	      int   w,		// I - Width of area to read
+	      int   h,		// I - Height of area to read
+	      int   alpha) {	// I - Alpha value for image (0 for none)
+  Rect		src,		// Source rectangle
+		dst;		// Destination rectangle
+  Fl_Offscreen	osbuffer;	// Temporary off-screen buffer for copy
+  GrafPtr	srcPort;	// Source port
+  RGBColor	rgb;		// RGB colors for copy mask...
+  PixMapHandle	pm;		// Pixmap handle for off-screen buffer
+  uchar		*base,		// Base address of off-screen buffer
+		*psrc,		// Pointer into off-screen buffer
+		*pdst;		// Pointer into pixel buffer
+  int           idx, idy;	// Current X & Y in image
+  int		d;		// Depth of image
+  int		rowBytes;	// Number of bytes per row...
+
+
+  // Get an off-screen buffer for copying the image...
+  osbuffer = fl_create_offscreen(w,h);
+
+  if (!osbuffer) return 0;
+
+  // Set the source and destination rectangles...
+  src.top    = y;
+  src.left   = x;
+  src.bottom = y + h;
+  src.right  = x + w;
+
+  dst.top    = 0;
+  dst.left   = 0;
+  dst.bottom = h;
+  dst.right  = w;
+
+  // Get the source port...
+  GetPort(&srcPort);
+
+  // Set the RGB copy mask via the foreground/background colors...
+  rgb.red   = 0xffff;
+  rgb.green = 0xffff;
+  rgb.blue  = 0xffff;
+  RGBBackColor(&rgb);
+
+  rgb.red   = 0x0000;
+  rgb.green = 0x0000;
+  rgb.blue  = 0x0000;
+  RGBForeColor(&rgb);
+
+  // Copy the screen image to the off-screen buffer...
+  CopyBits(GetPortBitMapForCopyBits(srcPort),
+           GetPortBitMapForCopyBits(osbuffer), &src, &dst, srcCopy, 0L);
+
+  // Allocate the image data array as needed...
+  d = alpha ? 4 : 3;
+
+  if (!p) p = new uchar[w * h * d];
+
+  // Initialize the default colors/alpha in the whole image...
+  memset(p, alpha, w * h * d);
+
+  // Set the correct port for the off-screen buffer and lock the buffer
+  SetGWorld(osbuffer, 0);
+
+  pm = GetGWorldPixMap(osbuffer);
+  LockPixels(pm);
+
+  base     = (uchar *)GetPixBaseAddr(pm);
+  rowBytes = (*pm)->rowBytes & 0x3fff;
+
+  // Copy the image from the off-screen buffer to the memory buffer.
+  for (idy = 0, pdst = p; idy < h; idy ++)
+    for (idx = 0, psrc = base + idy * rowBytes + 1; idx < w; idx ++, psrc += 4, pdst += d) {
+      pdst[0] = psrc[0];
+      pdst[1] = psrc[1];
+      pdst[2] = psrc[2];
+    }
+
+  // Unlock and delete the off-screen buffer, then return...
+  UnlockPixels(pm);
+  fl_delete_offscreen(osbuffer);
+
+  SetPort(srcPort);
+  return p;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_read_image_win32.cxx b/Utilities/FLTK/src/fl_read_image_win32.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b218d598f9aa2ff70839434f715ef7fe91c02b72
--- /dev/null
+++ b/Utilities/FLTK/src/fl_read_image_win32.cxx
@@ -0,0 +1,72 @@
+//
+// "$Id$"
+//
+// WIN32 image reading routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//
+// 'fl_read_image()' - Read an image from the current window.
+//
+
+uchar *				// O - Pixel buffer or NULL if failed
+fl_read_image(uchar *p,		// I - Pixel buffer or NULL to allocate
+              int   X,		// I - Left position
+	      int   Y,		// I - Top position
+	      int   w,		// I - Width of area to read
+	      int   h,		// I - Height of area to read
+	      int   alpha) {	// I - Alpha value for image (0 for none)
+  int	x, y;			// Looping vars
+  int	d;			// Depth of image
+  uchar	*ptr;			// Pointer in image data
+
+
+  // Allocate the image data array as needed...
+  d = alpha ? 4 : 3;
+
+  if (!p) p = new uchar[w * h * d];
+
+  // Initialize the default colors/alpha in the whole image...
+  memset(p, alpha, w * h * d);
+
+  // Grab all of the pixels in the image, one at a time...
+  // MRS: there has to be a better way than this!
+  for (y = 0, ptr = p; y < h; y ++) {
+    for (x = 0; x < w; x ++, ptr += d) {
+      COLORREF c = GetPixel(fl_gc, X + x, Y + y);
+
+      ptr[0] = c;
+      c >>= 8;
+      ptr[1] = c;
+      c >>= 8;
+      ptr[2] = c;
+    }
+  }
+
+  return p;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_rect.cxx b/Utilities/FLTK/src/fl_rect.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..75a08b0b79fa5897eb47e10dc8698faadc0b6384
--- /dev/null
+++ b/Utilities/FLTK/src/fl_rect.cxx
@@ -0,0 +1,677 @@
+//
+// "$Id$"
+//
+// Rectangle drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// These routines from fl_draw.H are used by the standard boxtypes
+// and thus are always linked into an fltk program.
+// Also all fl_clip routines, since they are always linked in so
+// that minimal update works.
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+#ifdef __APPLE_QUARTZ__
+extern float fl_quartz_line_width_;
+#endif
+
+void fl_rect(int x, int y, int w, int h) {
+  if (w<=0 || h<=0) return;
+#ifdef WIN32
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x+w-1, y);
+  LineTo(fl_gc, x+w-1, y+h-1);
+  LineTo(fl_gc, x, y+h-1);
+  LineTo(fl_gc, x, y);
+#elif defined(__APPLE_QD__)
+  Rect rect;
+  SetRect(&rect, x, y, x+w, y+h);
+  FrameRect(&rect);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGRect rect = CGRectMake(x, y, w-1, h-1);
+  CGContextStrokeRect(fl_gc, rect);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
+#endif
+}
+
+void fl_rectf(int x, int y, int w, int h) {
+  if (w<=0 || h<=0) return;
+#ifdef WIN32
+  RECT rect;
+  rect.left = x; rect.top = y;  
+  rect.right = x + w; rect.bottom = y + h;
+  FillRect(fl_gc, &rect, fl_brush());
+#elif defined(__APPLE_QD__)
+  Rect rect;
+  SetRect(&rect, x, y, x+w, y+h);
+  PaintRect(&rect);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGRect rect = CGRectMake(x, y, w-1, h-1);
+  CGContextFillRect(fl_gc, rect);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
+#endif
+}
+
+void fl_xyline(int x, int y, int x1) {
+#ifdef WIN32
+  MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); LineTo(x1, y);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y);
+#endif
+}
+
+void fl_xyline(int x, int y, int x1, int y2) {
+#ifdef WIN32
+  if (y2 < y) y2--;
+  else y2++;
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x1, y);
+  LineTo(fl_gc, x1, y2);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x1, y);
+  LineTo(x1, y2);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y);
+  CGContextAddLineToPoint(fl_gc, x1, y2);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XPoint p[3];
+  p[0].x = x;  p[0].y = p[1].y = y;
+  p[1].x = p[2].x = x1; p[2].y = y2;
+  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
+#endif
+}
+
+void fl_xyline(int x, int y, int x1, int y2, int x3) {
+#ifdef WIN32
+  if(x3 < x1) x3--;
+  else x3++;
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x1, y);
+  LineTo(fl_gc, x1, y2);
+  LineTo(fl_gc, x3, y2);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x1, y);
+  LineTo(x1, y2);
+  LineTo(x3, y2);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y);
+  CGContextAddLineToPoint(fl_gc, x1, y2);
+  CGContextAddLineToPoint(fl_gc, x3, y2);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XPoint p[4];
+  p[0].x = x;  p[0].y = p[1].y = y;
+  p[1].x = p[2].x = x1; p[2].y = p[3].y = y2;
+  p[3].x = x3;
+  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_yxline(int x, int y, int y1) {
+#ifdef WIN32
+  if (y1 < y) y1--;
+  else y1++;
+  MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); LineTo(x, y1);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x, y1);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1);
+#endif
+}
+
+void fl_yxline(int x, int y, int y1, int x2) {
+#ifdef WIN32
+  if (x2 > x) x2++;
+  else x2--;
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x, y1);
+  LineTo(fl_gc, x2, y1);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x, y1);
+  LineTo(x2, y1);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y1);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XPoint p[3];
+  p[0].x = p[1].x = x;  p[0].y = y;
+  p[1].y = p[2].y = y1; p[2].x = x2;
+  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
+#endif
+}
+
+void fl_yxline(int x, int y, int y1, int x2, int y3) {
+#ifdef WIN32
+  if(y3<y1) y3--;
+  else y3++;
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x, y1);
+  LineTo(fl_gc, x2, y1);
+  LineTo(fl_gc, x2, y3);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x, y1);
+  LineTo(x2, y1);
+  LineTo(x2, y3);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y3);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XPoint p[4];
+  p[0].x = p[1].x = x;  p[0].y = y;
+  p[1].y = p[2].y = y1; p[2].x = p[3].x = x2;
+  p[3].y = y3;
+  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_line(int x, int y, int x1, int y1) {
+#ifdef WIN32
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x1, y1);
+  // Draw the last point *again* because the GDI line drawing
+  // functions will not draw the last point ("it's a feature!"...)
+  SetPixel(fl_gc, x1, y1, fl_RGB());
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x1, y1);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y1);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1);
+#endif
+}
+
+void fl_line(int x, int y, int x1, int y1, int x2, int y2) {
+#ifdef WIN32
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x1, y1);
+  LineTo(fl_gc, x2, y2);
+  // Draw the last point *again* because the GDI line drawing
+  // functions will not draw the last point ("it's a feature!"...)
+  SetPixel(fl_gc, x2, y2, fl_RGB());
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x1, y1);
+  LineTo(x2, y2);
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y2);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XPoint p[3];
+  p[0].x = x;  p[0].y = y;
+  p[1].x = x1; p[1].y = y1;
+  p[2].x = x2; p[2].y = y2;
+  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
+#endif
+}
+
+void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {
+#ifdef WIN32
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x1, y1);
+  LineTo(fl_gc, x2, y2);
+  LineTo(fl_gc, x, y);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x1, y1);
+  LineTo(x2, y2);
+  LineTo(x, y);
+#elif defined(__APPLE_QUARTZ__)
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y2);
+  CGContextClosePath(fl_gc);
+  CGContextStrokePath(fl_gc);
+#else
+  XPoint p[4];
+  p[0].x = x;  p[0].y = y;
+  p[1].x = x1; p[1].y = y1;
+  p[2].x = x2; p[2].y = y2;
+  p[3].x = x;  p[3].y = y;
+  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+#ifdef WIN32
+  MoveToEx(fl_gc, x, y, 0L); 
+  LineTo(fl_gc, x1, y1);
+  LineTo(fl_gc, x2, y2);
+  LineTo(fl_gc, x3, y3);
+  LineTo(fl_gc, x, y);
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); 
+  LineTo(x1, y1);
+  LineTo(x2, y2);
+  LineTo(x3, y3);
+  LineTo(x, y);
+#elif defined(__APPLE_QUARTZ__)
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y2);
+  CGContextAddLineToPoint(fl_gc, x3, y3);
+  CGContextClosePath(fl_gc);
+  CGContextStrokePath(fl_gc);
+#else
+  XPoint p[5];
+  p[0].x = x;  p[0].y = y;
+  p[1].x = x1; p[1].y = y1;
+  p[2].x = x2; p[2].y = y2;
+  p[3].x = x3; p[3].y = y3;
+  p[4].x = x;  p[4].y = y;
+  XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
+#endif
+}
+
+void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {
+  XPoint p[4];
+  p[0].x = x;  p[0].y = y;
+  p[1].x = x1; p[1].y = y1;
+  p[2].x = x2; p[2].y = y2;
+#ifdef WIN32
+  SelectObject(fl_gc, fl_brush());
+  Polygon(fl_gc, p, 3);
+#elif defined(__APPLE_QD__)
+  PolyHandle poly = OpenPoly();
+  MoveTo(x, y);
+  LineTo(x1, y1);
+  LineTo(x2, y2);
+  LineTo(x, y);
+  ClosePoly();
+  PaintPoly(poly);
+  FramePoly(poly);
+  KillPoly(poly);
+#elif defined(__APPLE_QUARTZ__)
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y2);
+  CGContextClosePath(fl_gc);
+  CGContextFillPath(fl_gc);
+#else
+  p[3].x = x;  p[3].y = y;
+  XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0);
+  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+  XPoint p[5];
+  p[0].x = x;  p[0].y = y;
+  p[1].x = x1; p[1].y = y1;
+  p[2].x = x2; p[2].y = y2;
+  p[3].x = x3; p[3].y = y3;
+#ifdef WIN32
+  SelectObject(fl_gc, fl_brush());
+  Polygon(fl_gc, p, 4);
+#elif defined(__APPLE_QD__)
+  PolyHandle poly = OpenPoly();
+  MoveTo(x, y);
+  LineTo(x1, y1);
+  LineTo(x2, y2);
+  LineTo(x3, y3);
+  LineTo(x, y);
+  ClosePoly();
+  PaintPoly(poly);
+  FramePoly(poly);
+  KillPoly(poly);
+#elif defined(__APPLE_QUARTZ__)
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x1, y1);
+  CGContextAddLineToPoint(fl_gc, x2, y2);
+  CGContextAddLineToPoint(fl_gc, x3, y3);
+  CGContextClosePath(fl_gc);
+  CGContextFillPath(fl_gc);
+#else
+  p[4].x = x;  p[4].y = y;
+  XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0);
+  XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
+#endif
+}
+
+void fl_point(int x, int y) {
+#ifdef WIN32
+  SetPixel(fl_gc, x, y, fl_RGB());
+#elif defined(__APPLE_QD__)
+  MoveTo(x, y); Line(0, 0); 
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  CGContextMoveToPoint(fl_gc, x, y);
+  CGContextAddLineToPoint(fl_gc, x, y);
+  CGContextStrokePath(fl_gc);
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
+#else
+  XDrawPoint(fl_display, fl_window, fl_gc, x, y);
+#endif
+}
+
+////////////////////////////////////////////////////////////////
+
+#define STACK_SIZE 10
+#define STACK_MAX (STACK_SIZE - 1)
+static Fl_Region rstack[STACK_SIZE];
+static int rstackptr=0;
+int fl_clip_state_number=0; // used by gl_begin.cxx to update GL clip
+
+#if !defined(WIN32) && !defined(__APPLE__)
+// Missing X call: (is this the fastest way to init a 1-rectangle region?)
+// MSWindows equivalent exists, implemented inline in win32.H
+Fl_Region XRectangleRegion(int x, int y, int w, int h) {
+  XRectangle R;
+  R.x = x; R.y = y; R.width = w; R.height = h;
+  Fl_Region r = XCreateRegion();
+  XUnionRectWithRegion(&R, r, r);
+  return r;
+}
+#endif
+
+#ifdef __APPLE_QD__
+extern Fl_Region fl_window_region;
+#elif defined(__APPLE_QUARTZ__)
+// warning: the Quartz implementation currently uses Quickdraw calls to achieve
+//          clipping. A future version should instead use 'CGContectClipToRect'
+//          and friends.
+extern Fl_Region fl_window_region;
+#endif
+
+// undo any clobbering of clip done by your program:
+void fl_restore_clip() {
+  fl_clip_state_number++;
+  Fl_Region r = rstack[rstackptr];
+#ifdef WIN32
+  SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared
+#elif defined(__APPLE_QD__)
+# if 1
+  // This code is required to allow true subwindows to work on Mac.
+  // During regular operation however, this seems overkill.
+  // See also: Fl_Window::make_current()
+  if ( fl_window ) {
+    GrafPtr port = GetWindowPort( fl_window );
+    if ( port ) { // port will be NULL if we are using a GWorld (and fl_window_region is invalid)
+      RgnHandle portClip = NewRgn();
+      CopyRgn( fl_window_region, portClip ); // changed
+      if ( r ) 
+        SectRgn( portClip, r, portClip );
+      SetPortClipRegion( port, portClip );
+      DisposeRgn( portClip );
+    }
+  } else {
+    if (r) 
+      SetClip(r);
+    else {
+      Rect rect; rect.left=0; rect.top=0; rect.right=0x7fff; rect.bottom=0x7fff;
+      ClipRect(&rect);
+    }
+  }
+# else
+  if (r) SetClip(r);
+  else {
+    Rect rect; rect.left=0; rect.top=0; rect.right=0x7fff; rect.bottom=0x7fff;
+    ClipRect(&rect);
+  }
+# endif
+#elif defined(__APPLE_QUARTZ__)
+  if ( fl_window )
+  {
+    GrafPtr port = GetWindowPort( fl_window );
+    if ( port ) { 
+      RgnHandle portClip = NewRgn();
+      CopyRgn( fl_window_region, portClip ); // changed
+      if ( r )
+        SectRgn( portClip, r, portClip );
+      Rect portRect; GetPortBounds(port, &portRect);
+      Fl_X::q_clear_clipping();
+      ClipCGContextToRegion(fl_gc, &portRect, portClip );
+      Fl_X::q_fill_context();
+      DisposeRgn( portClip );
+    }
+  }
+#else
+  if (r) XSetRegion(fl_display, fl_gc, r);
+  else XSetClipMask(fl_display, fl_gc, 0);
+#endif
+}
+
+// Replace the top of the clip stack:
+void fl_clip_region(Fl_Region r) {
+  Fl_Region oldr = rstack[rstackptr];
+  if (oldr) XDestroyRegion(oldr);
+  rstack[rstackptr] = r;
+  fl_restore_clip();
+}
+
+// Return the current clip region...
+Fl_Region fl_clip_region() {
+  return rstack[rstackptr];
+}
+
+// Intersect & push a new clip rectangle:
+void fl_push_clip(int x, int y, int w, int h) {
+  Fl_Region r;
+  if (w > 0 && h > 0) {
+    r = XRectangleRegion(x,y,w,h);
+    Fl_Region current = rstack[rstackptr];
+    if (current) {
+#ifdef WIN32
+      CombineRgn(r,r,current,RGN_AND);
+#elif defined(__APPLE_QD__)
+      SectRgn(r, current, r); 
+#elif defined(__APPLE_QUARTZ__)
+      SectRgn(r, current, r);
+#else
+      Fl_Region temp = XCreateRegion();
+      XIntersectRegion(current, r, temp);
+      XDestroyRegion(r);
+      r = temp;
+#endif
+    }
+  } else { // make empty clip region:
+#ifdef WIN32
+    r = CreateRectRgn(0,0,0,0);
+#elif defined(__APPLE_QD__)
+    r = NewRgn(); 
+    SetEmptyRgn(r);
+#elif defined(__APPLE_QUARTZ__)
+    r = NewRgn();
+    SetEmptyRgn(r);
+#else
+    r = XCreateRegion();
+#endif
+  }
+  if (rstackptr < STACK_MAX) rstack[++rstackptr] = r;
+  else Fl::warning("fl_push_clip: clip stack overflow!\n");
+  fl_restore_clip();
+}
+
+// make there be no clip (used by fl_begin_offscreen() only!)
+void fl_push_no_clip() {
+  if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0;
+  else Fl::warning("fl_push_no_clip: clip stack overflow!\n");
+  fl_restore_clip();
+}
+
+// pop back to previous clip:
+void fl_pop_clip() {
+  if (rstackptr > 0) {
+    Fl_Region oldr = rstack[rstackptr--];
+    if (oldr) XDestroyRegion(oldr);
+  } else Fl::warning("fl_pop_clip: clip stack underflow!\n");
+  fl_restore_clip();
+}
+
+// does this rectangle intersect current clip?
+int fl_not_clipped(int x, int y, int w, int h) {
+  if (x+w <= 0 || y+h <= 0) return 0;
+  Fl_Region r = rstack[rstackptr];
+#ifdef WIN32
+  if (!r) return 1;
+  RECT rect;
+  rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
+  return RectInRegion(r,&rect);
+#elif defined(__APPLE_QD__)
+  if (!r) return 1;
+  Rect rect;
+  rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
+  return RectInRgn(&rect, r);
+#elif defined(__APPLE_QUARTZ__)
+  if (!r) return 1;
+  Rect rect;
+  rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
+  return RectInRgn(&rect, r);
+#else
+  return r ? XRectInRegion(r, x, y, w, h) : 1;
+#endif
+}
+
+// return rectangle surrounding intersection of this rectangle and clip:
+int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
+  X = x; Y = y; W = w; H = h;
+  Fl_Region r = rstack[rstackptr];
+  if (!r) return 0;
+#ifdef WIN32
+// The win32 API makes no distinction between partial and complete
+// intersection, so we have to check for partial intersection ourselves.
+// However, given that the regions may be composite, we have to do
+// some voodoo stuff...
+  Fl_Region rr = XRectangleRegion(x,y,w,h);
+  Fl_Region temp = CreateRectRgn(0,0,0,0);
+  int ret;
+  if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint
+    W = H = 0;
+    ret = 2;
+  } else if (EqualRgn(temp, rr)) { // complete
+    ret = 0;
+  } else {	// parital intersection
+    RECT rect;
+    GetRgnBox(temp, &rect);
+    X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
+    ret = 1;
+  }
+  DeleteObject(temp);
+  DeleteObject(rr);
+  return ret;
+#elif defined(__APPLE_QD__)
+  RgnHandle rr = NewRgn();
+  SetRectRgn( rr, x, y, x+w, y+h );
+  SectRgn( r, rr, rr );
+  Rect rp; GetRegionBounds(rr, &rp);
+  X = rp.left;
+  Y = rp.top;
+  W = rp.right - X;
+  H = rp.bottom - Y;
+  DisposeRgn( rr );
+  if ( H==0 ) return 2;
+  if ( h==H && w==W ) return 0;
+  return 0;
+#elif defined(__APPLE_QUARTZ__)
+  RgnHandle rr = NewRgn();
+  SetRectRgn( rr, x, y, x+w, y+h );
+  SectRgn( r, rr, rr );
+  Rect rp; GetRegionBounds(rr, &rp);
+  X = rp.left;
+  Y = rp.top;
+  W = rp.right - X;
+  H = rp.bottom - Y;
+  DisposeRgn( rr );
+  if ( H==0 ) return 2;
+  if ( h==H && w==W ) return 0;
+  return 0;
+#else
+  switch (XRectInRegion(r, x, y, w, h)) {
+  case 0: // completely outside
+    W = H = 0;
+    return 2;
+  case 1: // completely inside:
+    return 0;
+  default: // partial:
+    break;
+  }
+  Fl_Region rr = XRectangleRegion(x,y,w,h);
+  Fl_Region temp = XCreateRegion();
+  XIntersectRegion(r, rr, temp);
+  XRectangle rect;
+  XClipBox(temp, &rect);
+  X = rect.x; Y = rect.y; W = rect.width; H = rect.height;
+  XDestroyRegion(temp);
+  XDestroyRegion(rr);
+  return 1;
+#endif
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_round_box.cxx b/Utilities/FLTK/src/fl_round_box.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e8b085e6b721512187c8d416f86751397a4c9726
--- /dev/null
+++ b/Utilities/FLTK/src/fl_round_box.cxx
@@ -0,0 +1,122 @@
+//
+// "$Id$"
+//
+// Round box drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Box drawing code for an obscure box type.
+// These box types are in seperate files so they are not linked
+// in if not used.
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+// A compiler from a certain very large software company will not compile
+// the function pointer assignment due to the name conflict with fl_arc.
+// This function is to fix that:
+void fl_arc_i(int x,int y,int w,int h,double a1,double a2) {
+  fl_arc(x,y,w,h,a1,a2);
+}
+
+enum {UPPER_LEFT, LOWER_RIGHT, CLOSED, FILL};
+
+static void draw(int which, int x,int y,int w,int h, int inset, uchar color)
+{
+  if (inset*2 >= w) inset = (w-1)/2;
+  if (inset*2 >= h) inset = (h-1)/2;
+  x += inset;
+  y += inset;
+  w -= 2*inset;
+  h -= 2*inset;
+  int d = w <= h ? w : h;
+  if (d <= 1) return;
+  fl_color((Fl_Color)color);
+  void (*f)(int,int,int,int,double,double);
+  f = (which==FILL) ? fl_pie : fl_arc_i;
+  if (which >= CLOSED) {
+    f(x+w-d, y, d, d, w<=h ? 0 : -90, w<=h ? 180 : 90);
+    f(x, y+h-d, d, d, w<=h ? 180 : 90, w<=h ? 360 : 270);
+  } else if (which == UPPER_LEFT) {
+    f(x+w-d, y, d, d, 45, w<=h ? 180 : 90);
+    f(x, y+h-d, d, d, w<=h ? 180 : 90, 225);
+  } else { // LOWER_RIGHT
+    f(x, y+h-d, d, d, 225, w<=h ? 360 : 270);
+    f(x+w-d, y, d, d, w<=h ? 360 : 270, 360+45);
+  }
+  if (which == FILL) {
+    if (w < h)
+      fl_rectf(x, y+d/2, w, h-(d&-2));
+    else if (w > h)
+      fl_rectf(x+d/2, y, w-(d&-2), h);
+  } else {
+    if (w < h) {
+      if (which != UPPER_LEFT) fl_yxline(x+w-1, y+d/2-1, y+h-d/2+1);
+      if (which != LOWER_RIGHT) fl_yxline(x, y+d/2-1, y+h-d/2+1);
+    } else if (w > h) {
+      if (which != UPPER_LEFT) fl_xyline(x+d/2-1, y+h-1, x+w-d/2+1);
+      if (which != LOWER_RIGHT) fl_xyline(x+d/2-1, y, x+w-d/2+1);
+    }
+  }
+}
+
+extern uchar* fl_gray_ramp();
+
+void fl_round_down_box(int x, int y, int w, int h, Fl_Color bgcolor) {
+  uchar *g = fl_gray_ramp();
+  draw(FILL,	    x,   y, w,   h, 2, bgcolor);
+  draw(UPPER_LEFT,  x+1, y, w-2, h, 0, g['N']);
+  draw(UPPER_LEFT,  x+1, y, w-2, h, 1, g['H']);
+  draw(UPPER_LEFT,  x,   y, w,   h, 0, g['N']);
+  draw(UPPER_LEFT,  x,   y, w,   h, 1, g['H']);
+  draw(LOWER_RIGHT, x,   y, w,   h, 0, g['S']);
+  draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['U']);
+  draw(LOWER_RIGHT, x,   y, w,   h, 1, g['U']);
+  draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['W']);
+  draw(CLOSED,	    x,   y, w,   h, 2, g['A']);
+}
+
+void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) {
+  uchar *g = fl_gray_ramp();
+  draw(FILL,	    x,   y, w,   h, 2, bgcolor);
+  draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['H']);
+  draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['N']);
+  draw(LOWER_RIGHT, x,   y, w,   h, 1, g['H']);
+  draw(LOWER_RIGHT, x,   y, w,   h, 2, g['N']);
+  draw(UPPER_LEFT,  x,   y, w,   h, 2, g['U']);
+  draw(UPPER_LEFT,  x+1, y, w-2, h, 1, g['S']);
+  draw(UPPER_LEFT,  x,   y, w,   h, 1, g['W']);
+  draw(UPPER_LEFT,  x+1, y, w-2, h, 0, g['U']);
+  draw(CLOSED,	    x,   y, w,   h, 0, g['A']);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype fl_define_FL_ROUND_UP_BOX() {
+  fl_internal_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box);
+  fl_internal_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box);
+  return _FL_ROUND_UP_BOX;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_rounded_box.cxx b/Utilities/FLTK/src/fl_rounded_box.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bffaf29a0bd78aacfcc39f1c03c16da676f95339
--- /dev/null
+++ b/Utilities/FLTK/src/fl_rounded_box.cxx
@@ -0,0 +1,99 @@
+//
+// "$Id$"
+//
+// Rounded box drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+#define RN	5
+#define RS	15
+#define BW	3
+
+static double offset[RN] = { 0.0, 0.07612, 0.29289, 0.61732, 1.0};
+
+static void rbox(int fill, int x, int y, int w, int h) {
+  int i;
+  int rsx ,rsy, rs;
+  rsx = w*2/5; rsy = h*2/5;
+  if (rsx > rsy) rs = rsy; else  rs = rsx;
+  if (rs > RS) rs = RS;
+  rsx = rs; rsy = rs;
+
+  if (fill) fl_begin_polygon(); else fl_begin_loop();
+  for (i=0; i<RN; i++)
+    fl_vertex(x + offset[RN-i-1]*rsx, y + offset[i] * rsy);
+  for (i=0; i<RN; i++)
+    fl_vertex(x + offset[i]*rsx, y + h-1 - offset[RN-i-1] * rsy);
+  for (i=0; i<RN; i++)
+    fl_vertex(x + w-1 - offset[RN-i-1]*rsx, y + h-1 - offset[i] * rsy);
+  for (i=0; i<RN; i++)
+    fl_vertex(x + w-1 - offset[i]*rsx, y + offset[RN-i-1] * rsy);
+  if (fill) fl_end_polygon(); else fl_end_loop();
+}
+
+static void fl_rflat_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(c); rbox(1, x, y, w, h); rbox(0, x, y, w, h);
+}
+
+static void fl_rounded_frame(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(c); rbox(0, x, y, w, h);
+}
+
+static void fl_rounded_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(c); rbox(1, x, y, w, h);
+  fl_color(FL_BLACK); rbox(0, x, y, w, h);
+}
+
+static void fl_rshadow_box(int x, int y, int w, int h, Fl_Color c) {
+  // draw shadow:
+  fl_color(FL_DARK3);
+  rbox(1, x+BW, y+BW, w, h);
+  rbox(0, x+BW, y+BW, w, h);
+  // draw the box:
+  fl_rounded_box(x, y, w, h, c);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+
+Fl_Boxtype fl_define_FL_ROUNDED_BOX() {
+  fl_internal_boxtype(_FL_ROUNDED_FRAME, fl_rounded_frame);
+  fl_internal_boxtype(_FL_ROUNDED_BOX, fl_rounded_box);
+  return _FL_ROUNDED_BOX;
+}
+
+Fl_Boxtype fl_define_FL_RFLAT_BOX() {
+  fl_internal_boxtype(_FL_RFLAT_BOX, fl_rflat_box);
+  return _FL_RFLAT_BOX;
+}
+
+Fl_Boxtype fl_define_FL_RSHADOW_BOX() {
+  fl_internal_boxtype(_FL_RSHADOW_BOX, fl_rshadow_box);
+  return _FL_RSHADOW_BOX;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_scroll_area.cxx b/Utilities/FLTK/src/fl_scroll_area.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ec327565919a190743f07b51911a8fd226f9f62a
--- /dev/null
+++ b/Utilities/FLTK/src/fl_scroll_area.cxx
@@ -0,0 +1,143 @@
+//
+// "$Id$"
+//
+// Scrolling routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Drawing function to move the contents of a rectangle.  This is passed
+// a "callback" which is called to draw rectangular areas that are moved
+// into the drawing area.
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+
+// scroll a rectangle and redraw the newly exposed portions:
+void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
+	       void (*draw_area)(void*, int,int,int,int), void* data)
+{
+  if (!dx && !dy) return;
+  if (dx <= -W || dx >= W || dy <= -H || dy >= H) {
+    // no intersection of old an new scroll
+    draw_area(data,X,Y,W,H);
+    return;
+  }
+  int src_x, src_w, dest_x, clip_x, clip_w;
+  if (dx > 0) {
+    src_x = X;
+    dest_x = X+dx;
+    src_w = W-dx;
+    clip_x = X;
+    clip_w = dx;
+  } else {
+    src_x = X-dx;
+    dest_x = X;
+    src_w = W+dx;
+    clip_x = X+src_w;
+    clip_w = W-src_w;
+  }
+  int src_y, src_h, dest_y, clip_y, clip_h;
+  if (dy > 0) {
+    src_y = Y;
+    dest_y = Y+dy;
+    src_h = H-dy;
+    clip_y = Y;
+    clip_h = dy;
+  } else {
+    src_y = Y-dy;
+    dest_y = Y;
+    src_h = H+dy;
+    clip_y = Y+src_h;
+    clip_h = H-src_h;
+  }
+#ifdef WIN32
+  BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY);
+  // NYI: need to redraw areas that the source of BitBlt was bad due to
+  // overlapped windows, probably similar to X version:
+  // MRS: basic code needs to redraw parts that scrolled from off-screen...
+  int temp, limit;
+  int wx, wy;
+
+  // Compute the X position of the current window;
+  // this only works when scrolling in response to
+  // a user event; Fl_Window::x/y_root() do not work
+  // on WIN32...
+  wx = Fl::event_x_root() - Fl::event_x();
+  wy = Fl::event_y_root() - Fl::event_y();
+
+  temp = wx + src_x;
+  if (temp < Fl::x()) {
+    draw_area(data, dest_x, dest_y, Fl::x() - temp, src_h);
+  }
+  temp  = wx + src_x + src_w;
+  limit = Fl::x() + Fl::w();
+  if (temp > limit) {
+    draw_area(data, dest_x + src_w - temp + limit, dest_y, temp - limit, src_h);
+  }
+
+  temp = wy + src_y;
+  if (temp < Fl::y()) {
+    draw_area(data, dest_x, dest_y, src_w, Fl::y() - temp);
+  }
+  temp  = wy + src_y + src_h;
+  limit = Fl::y() + Fl::h();
+  if (temp > limit) {
+    draw_area(data, dest_x, dest_y + src_h - temp + limit, src_w, temp - limit);
+  }
+#elif defined(__APPLE_QD__)
+  Rect src = { src_y, src_x, src_y+src_h, src_x+src_w };
+  Rect dst = { dest_y, dest_x, dest_y+src_h, dest_x+src_w };
+  static RGBColor bg = { 0xffff, 0xffff, 0xffff }; RGBBackColor( &bg );
+  static RGBColor fg = { 0x0000, 0x0000, 0x0000 }; RGBForeColor( &fg );
+  CopyBits( GetPortBitMapForCopyBits( GetWindowPort(fl_window) ),
+            GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), &src, &dst, srcCopy, 0L);
+#elif defined(__APPLE_QUARTZ__)
+  // warning: there does not seem to be an equivalent to this function in Quartz
+  Rect src = { src_y, src_x, src_y+src_h, src_x+src_w };
+  Rect dst = { dest_y, dest_x, dest_y+src_h, dest_x+src_w };
+  static RGBColor bg = { 0xffff, 0xffff, 0xffff }; RGBBackColor( &bg );
+  static RGBColor fg = { 0x0000, 0x0000, 0x0000 }; RGBForeColor( &fg );
+  CopyBits( GetPortBitMapForCopyBits( GetWindowPort(fl_window) ),
+            GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), &src, &dst, srcCopy, 0L);
+#else
+  XCopyArea(fl_display, fl_window, fl_window, fl_gc,
+	    src_x, src_y, src_w, src_h, dest_x, dest_y);
+  // we have to sync the display and get the GraphicsExpose events! (sigh)
+  for (;;) {
+    XEvent e; XWindowEvent(fl_display, fl_window, ExposureMask, &e);
+    if (e.type == NoExpose) break;
+    // otherwise assumme it is a GraphicsExpose event:
+    draw_area(data, e.xexpose.x, e.xexpose.y,
+	      e.xexpose.width, e.xexpose.height);
+    if (!e.xgraphicsexpose.count) break;
+  }
+#endif
+  if (dx) draw_area(data, clip_x, dest_y, clip_w, src_h);
+  if (dy) draw_area(data, X, clip_y, W, clip_h);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_set_font.cxx b/Utilities/FLTK/src/fl_set_font.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4cabe5e4c9c8a9a74ebbed28c4cda9e1da32f20e
--- /dev/null
+++ b/Utilities/FLTK/src/fl_set_font.cxx
@@ -0,0 +1,88 @@
+//
+// "$Id$"
+//
+// Font utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Add a font to the internal table.
+// Also see fl_set_fonts.cxx which adds all possible fonts.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include "flstring.h"
+#include "Fl_Font.H"
+#include <stdlib.h>
+
+static int table_size;
+
+void Fl::set_font(Fl_Font fnum, const char* name) {
+  while (fnum >= table_size) {
+    int i = table_size;
+    if (!i) {	// don't realloc the built-in table
+      table_size = 2*FL_FREE_FONT;
+      i = FL_FREE_FONT;
+      Fl_Fontdesc* t = (Fl_Fontdesc*)malloc(table_size*sizeof(Fl_Fontdesc));
+      memcpy(t, fl_fonts, FL_FREE_FONT*sizeof(Fl_Fontdesc));
+      fl_fonts = t;
+    } else {
+      table_size = 2*table_size;
+      fl_fonts=(Fl_Fontdesc*)realloc(fl_fonts, table_size*sizeof(Fl_Fontdesc));
+    }
+    for (; i < table_size; i++) {
+      fl_fonts[i].fontname[0] = 0;
+      fl_fonts[i].name = 0;
+#if !defined(WIN32) && !defined(__APPLE__)
+      fl_fonts[i].xlist = 0;
+      fl_fonts[i].n = 0;
+#endif // !WIN32 && !__APPLE__
+    }
+  }
+  Fl_Fontdesc* s = fl_fonts+fnum;
+  if (s->name) {
+    if (!strcmp(s->name, name)) {s->name = name; return;}
+#if !defined(WIN32) && !defined(__APPLE__)
+    if (s->xlist && s->n >= 0) XFreeFontNames(s->xlist);
+#endif
+    for (Fl_FontSize* f = s->first; f;) {
+      Fl_FontSize* n = f->next; delete f; f = n;
+    }
+    s->first = 0;
+  }
+  s->name = name;
+  s->fontname[0] = 0;
+#if !defined(WIN32) && !defined(__APPLE__)
+  s->xlist = 0;
+#endif
+  s->first = 0;
+}
+
+void Fl::set_font(Fl_Font fnum, Fl_Font from) {
+  Fl::set_font(fnum, get_font(from));
+}
+
+const char* Fl::get_font(Fl_Font fnum) {return fl_fonts[fnum].name;}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_set_fonts.cxx b/Utilities/FLTK/src/fl_set_fonts.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2b407bdba84bfb78a6fdc6c52bf0bc5d0fe07680
--- /dev/null
+++ b/Utilities/FLTK/src/fl_set_fonts.cxx
@@ -0,0 +1,46 @@
+//
+// "$Id$"
+//
+// More font utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include "Fl_Font.H"
+#include "flstring.h"
+#include <stdlib.h>
+
+#ifdef WIN32
+#  include "fl_set_fonts_win32.cxx"
+#elif defined(__APPLE__)
+#  include "fl_set_fonts_mac.cxx"
+#elif USE_XFT
+#  include "fl_set_fonts_xft.cxx"
+#else
+#  include "fl_set_fonts_x.cxx"
+#endif // WIN32
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_set_fonts_mac.cxx b/Utilities/FLTK/src/fl_set_fonts_mac.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1195a5f770c5fc0e32abc7d7861f8347c538354c
--- /dev/null
+++ b/Utilities/FLTK/src/fl_set_fonts_mac.cxx
@@ -0,0 +1,214 @@
+//
+// "$Id$"
+//
+// MacOS font utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server.  It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+// Bug: older versions calculated the value for *ap as a side effect of
+// making the name, and then forgot about it. To avoid having to change
+// the header files I decided to store this value in the last character
+// of the font name array.
+#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+
+// turn a stored font name into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+#ifdef __APPLE_QD__
+  Fl_Fontdesc *f = fl_fonts + fnum;
+  if (!f->fontname[0]) {
+    const char* p = f->name;
+    if (!p || !*p) {if (ap) *ap = 0; return "";}
+    int type;
+    switch (*p) {
+    case 'B': type = FL_BOLD; break;
+    case 'I': type = FL_ITALIC; break;
+    case 'P': type = FL_BOLD | FL_ITALIC; break;
+    default:  type = 0; break;
+    }
+    strlcpy(f->fontname, p+1, ENDOFBUFFER);
+    if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
+    if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
+    f->fontname[ENDOFBUFFER] = (char)type;
+  }
+  if (ap) *ap = f->fontname[ENDOFBUFFER];
+  return f->fontname;
+#elif defined(__APPLE_QUARTZ__)
+  Fl_Fontdesc *f = fl_fonts + fnum;
+  if (!f->fontname[0]) {
+    const char* p = f->name;
+    if (!p || !*p) {if (ap) *ap = 0; return "";}
+    strlcpy(f->fontname, p, ENDOFBUFFER);
+    int type = 0;
+    if (strstr(f->name, "Bold")) type |= FL_BOLD;
+    if (strstr(f->name, "Italic")) type |= FL_ITALIC;
+    f->fontname[ENDOFBUFFER] = (char)type;
+  }
+  if (ap) *ap = f->fontname[ENDOFBUFFER];
+  return f->fontname;
+#endif
+}
+
+static int fl_free_font = FL_FREE_FONT;
+
+Fl_Font Fl::set_fonts(const char* xstarname) {
+#pragma unused ( xstarname )
+#ifdef __APPLE_QD__
+  if (fl_free_font != FL_FREE_FONT) 
+    return (Fl_Font)fl_free_font;
+  static char styleLU[] = " BIP";
+  FMFontFamilyInstanceIterator ffiIterator;
+  FMFontFamilyIterator ffIterator;
+  FMFontFamily family;
+  FMFont font;
+  FMFontStyle style; // bits 0..6: bold, italic underline, outline, shadow, condens, extended (FLTK supports 0 and 1 )
+  FMFontSize size;
+  //FMFilter filter; // do we need to set a specific (or multiple) filter(s) to get ALL fonts?
+  
+  Str255 buf;
+  //filter.format = kFMCurrentFilterFormat;
+  //filter.selector = kFMGenerationFilterSelector;
+  //filter.filter.generationFilter = 
+  FMCreateFontFamilyIterator( NULL, NULL, kFMUseGlobalScopeOption, &ffIterator );
+  OSStatus listFamilies, listInstances;
+  for (;;)
+  {
+    listFamilies = FMGetNextFontFamily( &ffIterator, &family );
+    if ( listFamilies != 0 ) break;
+    FMGetFontFamilyName( family, buf );
+    buf[ buf[0]+1 ] = 0;
+    //printf( "Font Family: %s\n", buf+1 );
+    int i;
+    for (i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts
+      if (!strcmp(Fl::get_font_name((Fl_Font)i),(char*)buf+1)) break;
+    if ( i < FL_FREE_FONT ) continue;
+    FMCreateFontFamilyInstanceIterator( family, &ffiIterator );
+    char pStyle = 0, nStyle;
+    for (;;)
+    {
+      listInstances = FMGetNextFontFamilyInstance( &ffiIterator, &font, &style, &size );
+      if ( listInstances != 0 ) break;
+      // printf(" %d %d %d\n", font, style, size );
+      nStyle = styleLU[style&0x03];
+      if ( ( pStyle & ( 1<<(style&0x03) ) ) == 0 )
+      {
+        buf[0] = nStyle;
+        Fl::set_font((Fl_Font)(fl_free_font++), strdup((char*)buf));
+        pStyle |= ( 1<<(style&0x03) );
+      }
+    }
+    FMDisposeFontFamilyInstanceIterator( &ffiIterator );
+  }
+  FMDisposeFontFamilyIterator( &ffIterator );
+  return (Fl_Font)fl_free_font;
+#elif defined(__APPLE_QUARTZ__)
+  ATSFontIterator it;
+  ATSFontIteratorCreate(kATSFontContextGlobal, 0L, 0L, kATSOptionFlagsRestrictedScope, &it);  
+  for (;;) {
+    ATSFontRef font;
+    CFStringRef fname = 0;
+    OSStatus err = ATSFontIteratorNext(it, &font);
+    if (err!=noErr) break;
+    ATSFontGetName(font, kATSOptionFlagsDefault, &fname);
+    char buf[1024];
+    CFStringGetCString(fname, buf, 1024, kCFStringEncodingASCII);
+    int i;
+    for (i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts
+      if (!strcmp(Fl::get_font_name((Fl_Font)i),buf)) break;
+    if ( i < FL_FREE_FONT ) continue;
+    Fl::set_font((Fl_Font)(fl_free_font++), strdup((char*)buf));
+  }
+  ATSFontIteratorRelease(&it);
+  return (Fl_Font)fl_free_font;
+#endif
+}
+
+static int array[128];
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+  Fl_Fontdesc *s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
+  int cnt = 0;
+
+#ifdef __APPLE_QD__
+  Str255 name;
+  int len = strlen( s->name );
+  memcpy(((char*)name)+1, s->name+1, len );
+  name[0] = len-1;
+  FMFontFamily family = FMGetFontFamilyFromName( name );
+  if ( family == kInvalidFontFamily ) return 0;
+
+  sizep = array;
+  FMFont font;
+  FMFontStyle style, fStyle;
+  switch ( s->name[0] ) {
+    default :
+      fStyle=0;
+      break;
+    case 'B' : 
+      fStyle=1;
+      break;
+    case 'I' : 
+      fStyle=2;
+      break;
+    case 'P' :
+      fStyle=3;
+      break;
+  }
+  FMFontSize size, pSize = -1;
+  FMFontFamilyInstanceIterator ffiIterator;
+  FMCreateFontFamilyInstanceIterator( family, &ffiIterator );
+  OSStatus listInstances;
+  for (;;)
+  {
+    listInstances = FMGetNextFontFamilyInstance( &ffiIterator, &font, &style, &size );
+    if ( listInstances != 0 ) break;
+    if ( style==fStyle )
+    {
+      if ( size>pSize ) 
+      {
+        array[ cnt++ ] = size;
+        pSize = size;
+      }
+    }
+  }
+  FMDisposeFontFamilyInstanceIterator( &ffiIterator );
+#elif defined(__APPLE_QUARTZ__)
+  // ATS supports all font size 
+  array[0] = 0;
+  sizep = array;
+  cnt = 1;
+#endif
+
+  return cnt;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_set_fonts_win32.cxx b/Utilities/FLTK/src/fl_set_fonts_win32.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..449bb6314a0c91bf7532c6eeeb92251cde3283e1
--- /dev/null
+++ b/Utilities/FLTK/src/fl_set_fonts_win32.cxx
@@ -0,0 +1,149 @@
+//
+// "$Id$"
+//
+// WIN32 font utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this7 library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This function fills in the FLTK font table with all the fonts that
+// are found on the X server.  It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+// Bug: older versions calculated the value for *ap as a side effect of
+// making the name, and then forgot about it. To avoid having to change
+// the header files I decided to store this value in the last character
+// of the font name array.
+#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+
+// turn a stored font name into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+  Fl_Fontdesc *f = fl_fonts + fnum;
+  if (!f->fontname[0]) {
+    const char* p = f->name;
+    if (!p || !*p) {if (ap) *ap = 0; return "";}
+    int type;
+    switch (*p) {
+    case 'B': type = FL_BOLD; break;
+    case 'I': type = FL_ITALIC; break;
+    case 'P': type = FL_BOLD | FL_ITALIC; break;
+    default:  type = 0; break;
+    }
+    strlcpy(f->fontname, p+1, ENDOFBUFFER);
+    if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
+    if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
+    f->fontname[ENDOFBUFFER] = (char)type;
+  }
+  if (ap) *ap = f->fontname[ENDOFBUFFER];
+  return f->fontname;
+}
+
+static int fl_free_font = FL_FREE_FONT;
+
+static int CALLBACK
+enumcb(CONST LOGFONT    *lpelf,
+       CONST TEXTMETRIC * /*lpntm*/,
+       DWORD            /*FontType*/,
+       LPARAM           p) {
+  if (!p && lpelf->lfCharSet != ANSI_CHARSET) return 1;
+  const char *n = lpelf->lfFaceName;
+  for (int i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts
+    if (!strcmp(Fl::get_font_name((Fl_Font)i),n)) return 1;
+  char buffer[LF_FACESIZE + 1];
+  strcpy(buffer+1, n);
+  buffer[0] = ' '; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+  if (lpelf->lfWeight <= 400)
+    buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+  buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+  if (lpelf->lfWeight <= 400)
+    buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+  return 1;
+}
+
+Fl_Font Fl::set_fonts(const char* xstarname) {
+  if (fl_free_font == FL_FREE_FONT) {// if not already been called
+    if (!fl_gc) fl_GetDC(0);
+    EnumFontFamilies(fl_gc, NULL, (FONTENUMPROC)enumcb, xstarname != 0);
+  }
+  return (Fl_Font)fl_free_font;
+}
+
+
+static int nbSize;
+static int cyPerInch;
+static int sizes[128];
+
+static int CALLBACK
+EnumSizeCb(CONST LOGFONT    * /*lpelf*/,
+           CONST TEXTMETRIC *lpntm,
+	   DWORD            fontType,
+	   LPARAM           /*p*/) {
+  if ((fontType & RASTER_FONTTYPE) == 0) {
+    sizes[0] = 0;
+    nbSize = 1;
+
+    // Scalable font
+    return 0;
+  }
+
+  int add = lpntm->tmHeight - lpntm->tmInternalLeading;
+  add = MulDiv(add, 72, cyPerInch);
+
+  int start = 0;
+  while ((start < nbSize) && (sizes[start] < add)) {
+    start++;
+  }
+
+  if ((start < nbSize) && (sizes[start] == add)) {
+    return 1;
+  }
+
+  for (int i=nbSize; i>start; i--) sizes[i] = sizes[i - 1];
+
+  sizes[start] = add;
+  nbSize++;
+
+  // Stop enum if buffer overflow
+  return nbSize < 128;
+}
+
+
+int
+Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+  nbSize = 0;
+  Fl_Fontdesc *s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
+
+  if (!fl_gc) fl_GetDC(0);
+  cyPerInch = GetDeviceCaps(fl_gc, LOGPIXELSY);
+  if (cyPerInch < 1) cyPerInch = 1;
+  EnumFontFamilies(fl_gc, s->name+1, (FONTENUMPROC)EnumSizeCb, 0);
+
+  sizep = sizes;
+  return nbSize;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_set_fonts_x.cxx b/Utilities/FLTK/src/fl_set_fonts_x.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9c785167c21ebcdefcaf4d1f49a8735e090d034b
--- /dev/null
+++ b/Utilities/FLTK/src/fl_set_fonts_x.cxx
@@ -0,0 +1,350 @@
+//
+// "$Id$"
+//
+// X11 font utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server.  It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+// Standard X fonts are matched by a pattern that is always of
+// this form, and this pattern is put in the table:
+// "-*-family-weight-slant-width1-style-*-registry-encoding"
+
+// Non-standard font names (those not starting with '-') are matched
+// by a pattern of the form "prefix*suffix", where the '*' is where
+// fltk thinks the point size is, or by the actual font name if no
+// point size is found.
+
+// Fltk knows how to pull an "attribute" out of a font name, such as
+// bold or italic, by matching known x font field values.  All words
+// that don't match a known attribute are combined into the "name"
+// of the font.  Names are compared before attributes for sorting, this
+// makes the bold and plain version of a font come out next to each
+// other despite the poor X font naming scheme.
+
+// By default fl_set_fonts() only does iso8859-1 encoded fonts.  You can
+// do all normal X fonts by passing "-*" or every possible font with "*".
+
+// Fl::set_font will take strings other than the ones this stores
+// and can identify any font on X that way.  You may want to write your
+// own system of font management and not use this code.
+
+// turn word N of a X font name into either some attribute bits
+// (right now 0, FL_BOLD, or FL_ITALIC), or into -1 indicating that
+// the word should be put into the name:
+
+static int attribute(int n, const char *p) {
+  // don't put blank things into name:
+  if (!*p || *p=='-' || *p=='*') return 0;
+  if (n == 3) { // weight
+    if (!strncmp(p,"normal",6) ||
+	!strncmp(p,"light",5) ||
+	!strncmp(p,"medium",6) ||
+	!strncmp(p,"book",4)) return 0;
+    if (!strncmp(p,"bold",4) || !strncmp(p,"demi",4)) return FL_BOLD;
+  } else if (n == 4) { // slant
+    if (*p == 'r') return 0;
+    if (*p == 'i' || *p == 'o') return FL_ITALIC;
+  } else if (n == 5) { // sWidth
+    if (!strncmp(p,"normal",6)) return 0;
+  }
+  return -1;
+}
+
+// return non-zero if the registry-encoding should be used:
+extern const char* fl_encoding;
+static int use_registry(const char *p) {
+  return *p && *p!='*' && strcmp(p,fl_encoding);
+}
+
+// Bug: older versions calculated the value for *ap as a side effect of
+// making the name, and then forgot about it. To avoid having to change
+// the header files I decided to store this value in the last character
+// of the font name array.
+#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+
+// turn a stored (with *'s) X font name into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+  Fl_Fontdesc *f = fl_fonts + fnum;
+  if (!f->fontname[0]) {
+    int type = 0;
+    const char* p = f->name;
+    if (!p) {
+      if (ap) *ap = 0;
+      return "";
+    }
+    char *o = f->fontname;
+
+    if (*p != '-') { // non-standard font, just replace * with spaces:
+      if (strstr(p,"bold")) type = FL_BOLD;
+      if (strstr(p,"ital")) type |= FL_ITALIC;
+      for (;*p; p++) {
+	if (*p == '*' || *p == ' ' || *p == '-') {
+	  do p++; while (*p == '*' || *p == ' ' || *p == '-');
+	  if (!*p) break;
+	  if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = ' ';
+	}
+	if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = *p;
+      }
+      *o = 0;
+
+    } else { // standard dash-seperated font:
+
+      // get the family:
+      const char *x = fl_font_word(p,2); if (*x) x++; if (*x=='*') x++;
+      if (!*x) {
+	if (ap) *ap = 0;
+	return p;
+      }
+      const char *e = fl_font_word(x,1);
+      if ((e - x) < (int)(ENDOFBUFFER - 1)) {
+	// MRS: we want strncpy here, not strlcpy...
+	strncpy(o,x,e-x);
+	o += e-x;
+      } else {
+	strlcpy(f->fontname, x, ENDOFBUFFER);
+	o = f->fontname+ENDOFBUFFER-1;
+      }
+
+      // collect all the attribute words:
+      for (int n = 3; n <= 6; n++) {
+	// get the next word:
+	if (*e) e++; x = e; e = fl_font_word(x,1);
+	int t = attribute(n,x);
+	if (t < 0) {
+	  if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = ' ';
+	  if ((e - x) < (int)(ENDOFBUFFER - (o - f->fontname) - 1)) {
+	    // MRS: we want strncpy here, not strlcpy...
+	    strncpy(o,x,e-x);
+	    o += e-x;
+	  } else {
+	    strlcpy(o,x, ENDOFBUFFER - (o - f->fontname) - 1);
+	    o = f->fontname+ENDOFBUFFER-1;
+	  }
+	} else type |= t;
+      }
+
+      // skip over the '*' for the size and get the registry-encoding:
+      x = fl_font_word(e,2);
+      if (*x) {x++; *o++ = '('; while (*x) *o++ = *x++; *o++ = ')';}
+
+      *o = 0;
+      if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
+      if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
+    }
+    f->fontname[ENDOFBUFFER] = (char)type;
+  }
+  if (ap) *ap = f->fontname[ENDOFBUFFER];
+  return f->fontname;
+}
+
+extern "C" {
+// sort raw (non-'*') X font names into perfect order:
+
+static int ultrasort(const void *aa, const void *bb) {
+  const char *a = *(char **)aa;
+  const char *b = *(char **)bb;
+
+  // sort all non x-fonts at the end:
+  if (*a != '-') {
+    if (*b == '-') return 1;
+    // 2 non-x fonts are matched by "numeric sort"
+    int ret = 0;
+    for (;;) {
+      if (isdigit(*a) && isdigit(*b)) {
+	int na = strtol(a, (char **)&a, 10);
+	int nb = strtol(b, (char **)&b, 10);
+	if (!ret) ret = na-nb;
+      } else if (*a != *b) {
+	return (*a-*b);
+      } else if (!*a) {
+	return ret;
+      } else {
+	a++; b++;
+      }
+    }
+  } else {
+    if (*b != '-') return -1;
+  }
+
+  // skip the foundry (assumme equal):
+  for (a++; *a && *a++!='-';);
+  for (b++; *b && *b++!='-';);
+
+  // compare the family and all the attribute words:
+  int atype = 0;
+  int btype = 0;
+  for (int n = 2; n <= 6; n++) {
+    int at = attribute(n,a);
+    int bt = attribute(n,b);
+    if (at < 0) {
+      if (bt >= 0) return 1;
+      for (;;) {if (*a!=*b) return *a-*b; b++; if (!*a || *a++=='-') break;}
+    } else {
+      if (bt < 0) return -1;
+      a = fl_font_word(a,1); if (*a) a++;
+      b = fl_font_word(b,1); if (*b) b++;
+      atype |= at; btype |= bt;
+    }
+  }
+
+  // remember the pixel size:
+  int asize = atoi(a);
+  int bsize = atoi(b);
+
+  // compare the registry/encoding:
+  a = fl_font_word(a,6); if (*a) a++;
+  b = fl_font_word(b,6); if (*b) b++;
+  if (use_registry(a)) {
+    if (!use_registry(b)) return 1;
+    int r = strcmp(a,b); if (r) return r;
+  } else {
+    if (use_registry(b)) return -1;
+  }
+
+  if (atype != btype) return atype-btype;
+  if (asize != bsize) return asize-bsize;
+
+  // something wrong, just do a string compare...
+  return strcmp(*(char**)aa, *(char**)bb);
+}
+}
+
+// converts a X font name to a standard starname, returns point size:
+static int to_canonical(char *to, const char *from, size_t tolen) {
+  char* c = fl_find_fontsize((char*)from);
+  if (!c) return -1; // no point size found...
+  const char* endptr;
+  int size = strtol(c,(char**)&endptr,10);
+  if (from[0] == '-') {
+    // replace the "foundry" with -*-:
+    *to++ = '-'; *to++ = '*';
+    for (from++; *from && *from != '-'; from++);
+    // skip to the registry-encoding:
+    endptr = (char*)fl_font_word(endptr,6);
+    if (*endptr && !use_registry(endptr+1)) endptr = "";
+  }
+  int n = c-from;
+  // MRS: we want strncpy here, not strlcpy...
+  if (n > (int)(tolen - 1)) return -1;
+  strncpy(to,from,n);
+  to[n++] = '*';
+  strlcpy(to+n,endptr, tolen - n);
+  return size;
+}
+
+static int fl_free_font = FL_FREE_FONT;
+
+Fl_Font Fl::set_fonts(const char* xstarname) {
+  if (fl_free_font > FL_FREE_FONT) // already been here
+    return (Fl_Font)fl_free_font;
+  fl_open_display();
+  int xlistsize;
+  char buf[20];
+  if (!xstarname) {
+    strcpy(buf,"-*-"); strcpy(buf+3,fl_encoding);
+    xstarname = buf;
+  }
+  char **xlist = XListFonts(fl_display, xstarname, 10000, &xlistsize);
+  if (!xlist) return (Fl_Font)fl_free_font;
+  qsort(xlist, xlistsize, sizeof(*xlist), ultrasort);
+  int used_xlist = 0;
+  for (int i=0; i<xlistsize;) {
+    int first_xlist = i;
+    const char *p = xlist[i++];
+    char canon[1024];
+    int size = to_canonical(canon, p, sizeof(canon));
+    if (size >= 0) {
+      for (;;) { // find all matching fonts:
+	if (i >= xlistsize) break;
+	const char *q = xlist[i];
+	char this_canon[1024];
+	if (to_canonical(this_canon, q, sizeof(this_canon)) < 0) break;
+	if (strcmp(canon, this_canon)) break;
+	i++;
+      }
+      /*if (*p=='-' || i > first_xlist+1)*/ p = canon;
+    }
+    int j;
+    for (j = 0;; j++) {
+      if (j < FL_FREE_FONT) {
+	// see if it is one of our built-in fonts:
+	// if so, set the list of x fonts, since we have it anyway
+	if (fl_fonts[j].name && !strcmp(fl_fonts[j].name, p)) break;
+      } else {
+	j = fl_free_font++;
+	if (p == canon) p = strdup(p); else used_xlist = 1;
+	Fl::set_font((Fl_Font)j, p);
+	break;
+      }
+    }
+    if (!fl_fonts[j].xlist) {
+      fl_fonts[j].xlist = xlist+first_xlist;
+      fl_fonts[j].n = -(i-first_xlist);
+      used_xlist = 1;
+    }
+  }
+  if (!used_xlist) XFreeFontNames(xlist);
+  return (Fl_Font)fl_free_font;
+}
+
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+  Fl_Fontdesc *s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
+  if (!s->xlist) {
+    fl_open_display();
+    s->xlist = XListFonts(fl_display, s->name, 100, &(s->n));
+    if (!s->xlist) return 0;
+  }
+  int listsize = s->n; if (listsize<0) listsize = -listsize;
+  static int sizes[128];
+  int numsizes = 0;
+  for (int i = 0; i < listsize; i++) {
+    char *q = s->xlist[i];
+    char *d = fl_find_fontsize(q);
+    if (!d) continue;
+    int s = strtol(d,0,10);
+    if (!numsizes || sizes[numsizes-1] < s) {
+      sizes[numsizes++] = s;
+    } else {
+      // insert-sort the new size into list:
+      int n;
+      for (n = numsizes-1; n > 0; n--) if (sizes[n-1] < s) break;
+      if (sizes[n] != s) {
+	for (int m = numsizes; m > n; m--) sizes[m] = sizes[m-1];
+	sizes[n] = s;
+	numsizes++;
+      }
+    }
+  }
+  sizep = sizes;
+  return numsizes;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_set_fonts_xft.cxx b/Utilities/FLTK/src/fl_set_fonts_xft.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a6cf89cf17e513f89d14bf4a6e2d735b64727dfe
--- /dev/null
+++ b/Utilities/FLTK/src/fl_set_fonts_xft.cxx
@@ -0,0 +1,361 @@
+//
+// "$Id$"
+//
+// More font utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <X11/Xft/Xft.h>
+
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server.  It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+// Bug: older versions calculated the value for *ap as a side effect of
+// making the name, and then forgot about it. To avoid having to change
+// the header files I decided to store this value in the last character
+// of the font name array.
+#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+
+// turn a stored font name into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+  Fl_Fontdesc *f = fl_fonts + fnum;
+  if (!f->fontname[0]) {
+    const char* p = f->name;
+    int type;
+    switch (p[0]) {
+    case 'B': type = FL_BOLD; break;
+    case 'I': type = FL_ITALIC; break;
+    case 'P': type = FL_BOLD | FL_ITALIC; break;
+    default:  type = 0; break;
+    }
+  
+  // NOTE: This can cause duplications in fonts that already have Bold or Italic in 
+  // their "name". Maybe we need to find a cleverer way?
+    strlcpy(f->fontname, p+1, ENDOFBUFFER);
+    if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
+    if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
+    f->fontname[ENDOFBUFFER] = (char)type;
+  }
+  if (ap) *ap = f->fontname[ENDOFBUFFER];
+  return f->fontname;
+}
+
+///////////////////////////////////////////////////////////
+#define LOCAL_RAW_NAME_MAX 256
+
+extern "C" {
+// sort returned fontconfig font names
+static int name_sort(const void *aa, const void *bb) {
+  // What should we do here? Just do a string compare for now...
+  // NOTE: This yeilds some oddities - in particular a Blah Bold font will be 
+  // listed before Blah...
+  // Also - the fontconfig listing returns some faces that are effectively duplicates
+  // as far as fltk is concerned, e.g. where there are ko or ja variants that we 
+  // can't distinguish (since we are not yet fully UTF-*) - should we strip them here?
+  return strcasecmp(*(char**)aa, *(char**)bb);
+} // end of name_sort
+} // end of extern C section
+
+
+// Read the "pretty" name we have derived from fontconfig then convert
+// it into the format fltk uses internally for Xft names...
+// This is just a mess - I should have tokenised the strings and gone from there,
+// but I really thought this would be easier!
+static void make_raw_name(char *raw, char *pretty)
+{
+  // Input name will be "Some Name:style = Bold Italic" or whatever
+  // The plan is this:
+  // - the first char in the "raw" name becomes either I, B, P or " " for
+  //   italic, bold, bold italic or normal - this seems to be the fltk way...
+
+  char *style = strchr(pretty, ':');
+  char *last = style + strlen(style) - 2;
+
+  if (style)
+  {
+    *style = 0; // Terminate "name" string
+    style ++;   // point to start of style section
+  }
+  raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text
+  strncat(raw, pretty, LOCAL_RAW_NAME_MAX);
+  // At this point, the name is "marked" as regular...
+  if (style)
+  {
+#define PLAIN   0
+#define BOLD    1
+#define ITALIC  2
+#define BITALIC (BOLD | ITALIC)
+    int mods = PLAIN;
+    // Now try and parse the style string - look for the "=" sign
+    style = strchr(style, '=');
+    while ((style) && (style < last))
+    {
+      int type;
+      while ((*style == '=') || (*style == ' ') || (*style == '\t'))
+      {
+        style++; // Start of Style string
+        if ((style >= last) || (*style == 0)) continue;
+      }
+      type = toupper(style[0]);
+      switch (type)
+      {
+      // Things we might see: Regular Normal Bold Italic Oblique (??what??) Medium
+      // Roman Light Demi Sans SemiCondensed SuperBold Book... etc...
+      // Things we actually care about: Bold Italic Oblique SuperBold - Others???
+      case 'I':
+        if (strncasecmp(style, "Italic", 6) == 0)
+        {
+          mods |= ITALIC;
+        }
+        goto NEXT_STYLE;
+        
+      case 'B':
+        if (strncasecmp(style, "Bold", 4) == 0)
+        {
+          mods |= BOLD;
+        }
+        goto NEXT_STYLE;
+        
+      case 'O':
+        if (strncasecmp(style, "Oblique", 7) == 0)
+        {
+          mods |= ITALIC;
+        }
+        goto NEXT_STYLE;
+          
+      case 's':
+        if (strncasecmp(style, "SuperBold", 9) == 0)
+        {
+          mods |= BOLD;
+        }
+        goto NEXT_STYLE;
+          
+      default: // find the next gap
+        goto NEXT_STYLE;
+      } // switch end
+NEXT_STYLE:
+      while ((*style != ' ') && (*style != '\t'))
+      {
+        style++;
+        if ((style >= last) || (*style == 0)) goto STYLE_DONE;
+      }
+    }
+STYLE_DONE:
+    // Set the "modifier" character in the raw string
+    switch(mods)
+    {
+    case BOLD: raw[0] = 'B';
+      break;
+    case ITALIC: raw[0] = 'I';
+      break;
+    case BITALIC: raw[0] = 'P';
+      break;
+    default: raw[0] = ' ';
+      break;
+    }
+  }
+} // make_raw_name
+
+///////////////////////////////////////////////////////////
+
+static int fl_free_font = FL_FREE_FONT;
+
+// Uses the fontconfig lib to construct a list of all installed fonts.
+// I tried using XftListFonts for this, but the API is tricky - and when I looked
+// at the XftList* code, it calls the Fc* functions anyway... so...
+// Also, for now I'm ignoring the "pattern_name" and just getting everything...
+// AND I don't try and skip the fonts we've already loaded in the defaults.
+// Blimey! What a hack!
+Fl_Font Fl::set_fonts(const char* pattern_name)
+{
+  FcFontSet  *fnt_set;     // Will hold the list of fonts we find
+  FcPattern   *fnt_pattern; // Holds the generic "match all names" pattern
+  FcObjectSet *fnt_obj_set = 0; // Holds the generic "match all objects" 
+  
+  int j; // loop iterator variable
+  int font_count; // Total number of fonts found to process
+  char **full_list; // The list of font names we build
+
+  if (fl_free_font > FL_FREE_FONT) // already been here
+    return (Fl_Font)fl_free_font;
+  
+  fl_open_display(); // Just in case...
+    
+  // Make sure fontconfig is ready... is this necessary? The docs say it is
+  // safe to call it multiple times, so just go for it anyway!
+  if (!FcInit ()) 
+  {
+    // What to do? Just return defaults...
+    return FL_FREE_FONT;
+  }
+
+  // Create a search pattern that will match every font name - I think this does the
+  // Right Thing... but am not certain...
+  // This could possibly be "enhanced" to pay attention to the requested "pattern_name"?
+  fnt_pattern = FcPatternCreate ();
+  fnt_obj_set = FcObjectSetBuild (FC_FAMILY, FC_STYLE, 0);
+    
+  // Hopefully, this is a set of all the fonts...
+  fnt_set = FcFontList (0, fnt_pattern, fnt_obj_set);
+  
+  // We don't need the fnt_pattern any more, release it
+  FcPatternDestroy (fnt_pattern);
+
+  // Now, if we got any fonts, iterate through them...
+  if (fnt_set)
+  {
+    char *stop;
+    char *start;
+    char *first;
+    
+    font_count = fnt_set->nfont; // How many fonts?
+    
+    // Allocate array of char*'s to hold the name strings
+    full_list = (char **)malloc(sizeof(char *) * font_count);
+    
+    // iterate through all the font patterns and get the names out...
+      for (j = 0; j < font_count; j++)
+      {
+      // NOTE: FcChar8 is a typedef of "unsigned char"...
+      FcChar8 *font; // String to hold the font's name
+            
+      // Convert from fontconfig internal pattern to human readable name
+      // NOTE: This WILL malloc storage, so we need to free it later...
+      font = FcNameUnparse (fnt_set->fonts[j]);
+            
+      // The returned strings look like this...
+      // Century Schoolbook:style=Bold Italic,fed kursiv,Fett Kursiv,...
+      // So the bit we want is up to the first comma - BUT some strings have
+      // more than one name, separated by, guess what?, a comma...
+      stop = start = first = 0;
+      stop = strchr((const char *)font, ',');
+      start = strchr((const char *)font, ':');
+      if ((stop) && (start) && (stop < start))
+      {
+        first = stop + 1; // discard first version of name
+        // find first comma *after* the end of the name
+        stop = strchr((const char *)start, ',');
+      }
+      else
+      {
+        first = (char *)font; // name is just what was returned
+      }
+      // Truncate the name after the (english) modifiers description
+      if (stop)
+      {
+        *stop = 0; // Terminate the string at the first comma, if there is one
+      }
+
+      // Copy the font description into our list
+      if (first == (char *)font)
+      { // The listed name is still OK
+        full_list[j] = (char *)font;
+      }
+      else
+      { // The listed name has been modified
+        full_list[j] = strdup(first);
+        // Free the font name storage
+        free (font);
+      }
+      // replace "style=Regular" so strcmp sorts it first
+      if (start) {
+        char *reg = strstr(full_list[j], "=Regular");
+        if (reg) reg[1]='.';
+      }
+    }
+        
+    // Release the fnt_set - we don't need it any more
+    FcFontSetDestroy (fnt_set);
+        
+    // Sort the list into alphabetic order
+    qsort(full_list, font_count, sizeof(*full_list), name_sort);
+    
+    // Now let us add the names we got to fltk's font list...
+    for (j = 0; j < font_count; j++)
+    {
+      if (full_list[j])
+      {
+        char xft_name[LOCAL_RAW_NAME_MAX];
+        char *stored_name;
+        // Parse the strings into FLTK-XFT style..
+        make_raw_name(xft_name, full_list[j]);
+        // NOTE: This just adds on AFTER the default fonts - no attempt is made
+        // to identify already loaded fonts. Is this bad?
+        stored_name = strdup(xft_name);
+        Fl::set_font((Fl_Font)(j + FL_FREE_FONT), stored_name);
+        fl_free_font ++;
+        
+        free(full_list[j]); // release that name from our internal array
+      }
+    }
+    // Now we are done with the list, release it fully
+    free (full_list);
+  }
+  return (Fl_Font)fl_free_font;
+} // ::set_fonts
+////////////////////////////////////////////////////////////////
+
+
+extern "C" {
+static int int_sort(const void *aa, const void *bb) {
+  return (*(int*)aa)-(*(int*)bb);
+}
+}
+
+////////////////////////////////////////////////////////////////
+
+// Return all the point sizes supported by this font:
+// Suprisingly enough Xft works exactly like fltk does and returns
+// the same list. Except there is no way to tell if the font is scalable.
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+  Fl_Fontdesc *s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
+
+  fl_open_display();
+  XftFontSet* fs = XftListFonts(fl_display, fl_screen,
+        XFT_FAMILY, XftTypeString, s->name+1, 0,
+        XFT_PIXEL_SIZE, 0);
+  static int* array = 0;
+  static int array_size = 0;
+  if (fs->nfont >= array_size) {
+    delete[] array;
+    array = new int[array_size = fs->nfont+1];
+  }
+  array[0] = 0; int j = 1; // claim all fonts are scalable
+  for (int i = 0; i < fs->nfont; i++) {
+    double v;
+    if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) {
+      array[j++] = int(v);
+    }
+  }
+  qsort(array+1, j-1, sizeof(int), int_sort);
+  XftFontSetDestroy(fs);
+  sizep = array;
+  return j;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_shadow_box.cxx b/Utilities/FLTK/src/fl_shadow_box.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..691c72971c547db511b3825b16ff22735e240e42
--- /dev/null
+++ b/Utilities/FLTK/src/fl_shadow_box.cxx
@@ -0,0 +1,56 @@
+//
+// "$Id$"
+//
+// Shadow box drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+#define BW 3
+
+static void fl_shadow_frame(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(FL_DARK3);
+  fl_rectf(x+BW, y+h-BW,  w - BW, BW);
+  fl_rectf(x+w-BW,  y+BW, BW,  h - BW);
+  fl_color(c);
+  fl_rect(x,y,w-BW,h-BW);
+}
+
+static void fl_shadow_box(int x, int y, int w, int h, Fl_Color c) {
+  fl_color(c);
+  fl_rectf(x+1,y+1,w-2-BW,h-2-BW);
+  fl_shadow_frame(x,y,w,h,FL_GRAY0);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype fl_define_FL_SHADOW_BOX() {
+  fl_internal_boxtype(_FL_SHADOW_FRAME, fl_shadow_frame);
+  fl_internal_boxtype(_FL_SHADOW_BOX, fl_shadow_box);
+  return _FL_SHADOW_BOX;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_shortcut.cxx b/Utilities/FLTK/src/fl_shortcut.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..69e11ede5a5bb6790d3f319bc521a67c79c6ecbe
--- /dev/null
+++ b/Utilities/FLTK/src/fl_shortcut.cxx
@@ -0,0 +1,221 @@
+//
+// "$Id$"
+//
+// Shortcut support routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Code to test and parse fltk shortcut numbers.
+//
+// A shortcut is a keysym or'd with shift flags.  In the simplest
+// sense a shortcut is matched if the shift state is exactly as
+// given and the key returning that keysym is pressed.
+//
+// To make it easier to match some things it is more complex:
+//
+// Only FL_META, FL_ALT, FL_SHIFT, and FL_CTRL must be "off".  A
+// zero in the other shift flags indicates "dont care".
+//
+// It also checks against the first character of Fl::event_text(),
+// and zero for FL_SHIFT means "don't care".
+// This allows punctuation shortcuts like "#" to work (rather than
+// calling it "shift+3")
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Button.H>
+#include <FL/fl_draw.H>
+#include <ctype.h>
+#include "flstring.h"
+#if !defined(WIN32) && !defined(__APPLE__)
+#include <FL/x.H>
+#endif
+
+int Fl::test_shortcut(int shortcut) {
+  if (!shortcut) return 0;
+
+  int v = shortcut & 0xffff;
+  if (v > 32 && v < 0x7f || v > 0xa0 && v <= 0xff) {
+    if (isupper(v)) {
+      shortcut |= FL_SHIFT;
+    }
+  }
+
+  int shift = Fl::event_state();
+  // see if any required shift flags are off:
+  if ((shortcut&shift) != (shortcut&0x7fff0000)) return 0;
+  // record shift flags that are wrong:
+  int mismatch = (shortcut^shift)&0x7fff0000;
+  // these three must always be correct:
+  if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0;
+
+  int key = shortcut & 0xffff;
+
+  // if shift is also correct, check for exactly equal keysyms:
+  if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1;
+
+  // try matching ascii, ignore shift:
+  if (key == event_text()[0]) return 1;
+
+  // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'):
+  if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F
+      && event_text()[0]==(key^0x40)) return 1;
+  return 0;
+}
+
+#if defined(WIN32) || defined(__APPLE__) // if not X
+// This table must be in numeric order by fltk (X) keysym number:
+struct Keyname {int key; const char* name;};
+static Keyname table[] = {
+  {' ', "Space"},
+  {FL_BackSpace, "Backspace"},
+  {FL_Tab,	"Tab"},
+  {0xff0b/*XK_Clear*/, "Clear"},
+  {FL_Enter,	"Enter"}, // X says "Enter"
+  {FL_Pause,	"Pause"},
+  {FL_Scroll_Lock, "Scroll_Lock"},
+  {FL_Escape,	"Escape"},
+  {FL_Home,	"Home"},
+  {FL_Left,	"Left"},
+  {FL_Up,	"Up"},
+  {FL_Right,	"Right"},
+  {FL_Down,	"Down"},
+  {FL_Page_Up,	"Page_Up"}, // X says "Prior"
+  {FL_Page_Down,"Page_Down"}, // X says "Next"
+  {FL_End,	"End"},
+  {FL_Print,	"Print"},
+  {FL_Insert,	"Insert"},
+  {FL_Menu,	"Menu"},
+  {FL_Num_Lock,	"Num_Lock"},
+  {FL_KP_Enter,	"KP_Enter"},
+  {FL_Shift_L,	"Shift_L"},
+  {FL_Shift_R,	"Shift_R"},
+  {FL_Control_L,"Control_L"},
+  {FL_Control_R,"Control_R"},
+  {FL_Caps_Lock,"Caps_Lock"},
+  {FL_Meta_L,	"Meta_L"},
+  {FL_Meta_R,	"Meta_R"},
+  {FL_Alt_L,	"Alt_L"},
+  {FL_Alt_R,	"Alt_R"},
+  {FL_Delete,	"Delete"}
+};
+#endif
+
+const char * fl_shortcut_label(int shortcut) {
+  static char buf[20];
+  char *p = buf;
+  if (!shortcut) {*p = 0; return buf;}
+  // fix upper case shortcuts
+  int v = shortcut & 0xffff;
+  if (v > 32 && v < 0x7f || v > 0xa0 && v <= 0xff) {
+    if (isupper(v)) {
+      shortcut |= FL_SHIFT;
+    }
+  }
+#ifdef __APPLE__
+  // \todo Mac :  we might want to change the symbols for Mac users - consider drawing Apple Symbols... .
+  if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;} //: Mac hollow up arrow
+  if (shortcut & FL_META)  {strcpy(p,"Cmd+"); p += 4;}  //: Mac 'Apple' key
+  if (shortcut & FL_ALT)   {strcpy(p,"Option+"); p += 7;}   //: Mac 'Alt/Option' or fancy switch symbol
+  if (shortcut & FL_CTRL)  {strcpy(p,"Ctrl+"); p += 5;}  //: Mac ctrl key
+#else
+  if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;}
+  if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;}
+  if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;}
+  if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;}
+#endif // __APPLE__
+  int key = shortcut & 0xFFFF;
+#if defined(WIN32) || defined(__APPLE__) // if not X
+  if (key >= FL_F && key <= FL_F_Last) {
+    *p++ = 'F';
+    if (key > FL_F+9) *p++ = (key-FL_F)/10+'0';
+    *p++ = (key-FL_F)%10 + '0';
+  } else {
+    // binary search the table for a match:
+    int a = 0;
+    int b = sizeof(table)/sizeof(*table);
+    while (a < b) {
+      int c = (a+b)/2;
+      if (table[c].key == key) {
+	if (p > buf) {strcpy(p,table[c].name); return buf;}
+	return table[c].name;
+      }
+      if (table[c].key < key) a = c+1;
+      else b = c;
+    }
+    if (key >= FL_KP && key <= FL_KP_Last) {
+      // mark keypad keys with KP_ prefix
+      strcpy(p,"KP_"); p += 3;
+      *p++ = uchar(key & 127);
+    } else {
+      // if none found, use the keystroke as a match:
+      *p++ = uchar(toupper(key & 255));
+    }
+  }
+  *p = 0;
+  return buf;
+#else
+  const char* q;
+  if (key == FL_Enter || key == '\r') q="Enter";  // don't use Xlib's "Return":
+  else if (key > 32 && key < 0x100) q = 0;
+  else q = XKeysymToString(key);
+  if (!q) {*p++ = uchar(toupper(key & 255)); *p = 0; return buf;}
+  if (p > buf) {strcpy(p,q); return buf;} else return q;
+#endif
+}
+
+// Emulation of XForms named shortcuts
+#include <stdlib.h>
+int fl_old_shortcut(const char* s) {
+  if (!s || !*s) return 0;
+  int n = 0;
+  if (*s == '#') {n |= FL_ALT; s++;}
+  if (*s == '+') {n |= FL_SHIFT; s++;}
+  if (*s == '^') {n |= FL_CTRL; s++;}
+  if (*s && s[1]) return n | (int)strtol(s,0,0); // allow 0xf00 to get any key
+  return n | *s;
+}
+
+// Tests for &x shortcuts in button labels:
+
+int Fl_Widget::test_shortcut(const char *l) {
+  char c = Fl::event_text()[0];
+  if (!c || !l) return 0;
+  for (;;) {
+    if (!*l) return 0;
+    if (*l++ == '&' && *l) {
+      if (*l == '&') l++;
+      else if (*l == c) return 1;
+      else return 0;
+    }
+  }
+}
+
+int Fl_Widget::test_shortcut() {
+  if (!(flags()&SHORTCUT_LABEL)) return 0;
+  return test_shortcut(label());
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_show_colormap.cxx b/Utilities/FLTK/src/fl_show_colormap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6d52022a75b6574a5e76fb10b0d2bf9f3d9515a2
--- /dev/null
+++ b/Utilities/FLTK/src/fl_show_colormap.cxx
@@ -0,0 +1,162 @@
+//
+// "$Id$"
+//
+// Colormap color selection dialog for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Select a color from the colormap.
+// Pretty much unchanged from Forms.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Single_Window.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_show_colormap.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#define BOXSIZE 14
+#define BORDER 4
+
+class ColorMenu : public Fl_Window {
+  Fl_Color initial;
+  Fl_Color which, previous;
+  int done;
+  void drawbox(Fl_Color);
+  void draw();
+  int handle(int);
+public:
+  ColorMenu(Fl_Color oldcol);
+  Fl_Color run();
+};
+
+ColorMenu::ColorMenu(Fl_Color oldcol) :
+  Fl_Window(BOXSIZE*8+1+2*BORDER, BOXSIZE*32+1+2*BORDER) {
+  clear_border();
+  set_modal();
+  initial = which = oldcol;
+}
+
+void ColorMenu::drawbox(Fl_Color c) {
+  if (c < 0 || c > 255) return;
+  int X = (c%8)*BOXSIZE+BORDER;
+  int Y = (c/8)*BOXSIZE+BORDER;
+#if BORDER_WIDTH < 3
+  if (c == which) fl_draw_box(FL_DOWN_BOX, X+1, Y+1, BOXSIZE-1, BOXSIZE-1, c);
+  else fl_draw_box(FL_BORDER_BOX, X, Y, BOXSIZE+1, BOXSIZE+1, c);
+#else
+  fl_draw_box(c == which ? FL_DOWN_BOX : FL_BORDER_BOX,
+	      X, Y, BOXSIZE+1, BOXSIZE+1, c);
+#endif
+}
+
+void ColorMenu::draw() {
+  if (damage() != FL_DAMAGE_CHILD) {
+    fl_draw_box(FL_UP_BOX,0,0,w(),h(),color());
+    for (int c = 0; c < 256; c++) drawbox((Fl_Color)c);
+  } else {
+    drawbox(previous);
+    drawbox(which);
+  }
+  previous = which;
+}
+
+int ColorMenu::handle(int e) {
+  int c = which;
+  switch (e) {
+  case FL_PUSH:
+  case FL_DRAG: {
+    int X = (Fl::event_x_root() - x() - BORDER);
+    if (X >= 0) X = X/BOXSIZE;
+    int Y = (Fl::event_y_root() - y() - BORDER);
+    if (Y >= 0) Y = Y/BOXSIZE;
+    if (X >= 0 && X < 8 && Y >= 0 && Y < 32)
+      c = 8*Y + X;
+    else
+      c = initial;
+    } break;
+  case FL_RELEASE:
+    done = 1;
+    return 1;
+  case FL_KEYBOARD:
+    switch (Fl::event_key()) {
+    case FL_Up: if (c > 7) c -= 8; break;
+    case FL_Down: if (c < 256-8) c += 8; break;
+    case FL_Left: if (c > 0) c--; break;
+    case FL_Right: if (c < 255) c++; break;
+    case FL_Escape: which = initial; done = 1; return 1;
+    case FL_KP_Enter:
+    case FL_Enter: done = 1; return 1;
+    default: return 0;
+    }
+    break;
+  default:
+    return 0;
+  }
+  if (c != which) {
+    which = (Fl_Color)c; damage(FL_DAMAGE_CHILD);
+    int bx = (c%8)*BOXSIZE+BORDER;
+    int by = (c/8)*BOXSIZE+BORDER;
+    int px = x();
+    int py = y();
+    int scr_x, scr_y, scr_w, scr_h;
+    Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+    if (px < scr_x) px = scr_x;
+    if (px+bx+BOXSIZE+BORDER >= scr_x+scr_w) px = scr_x+scr_w-bx-BOXSIZE-BORDER;
+    if (py < scr_y) py = scr_y;
+    if (py+by+BOXSIZE+BORDER >= scr_y+scr_h) py = scr_y+scr_h-by-BOXSIZE-BORDER;
+    if (px+bx < BORDER) px = BORDER-bx;
+    if (py+by < BORDER) py = BORDER-by;
+    position(px,py);
+  }
+  return 1;
+}
+
+extern char fl_override_redirect; // hack for menus
+
+#ifdef _MSC_VER
+#pragma optimize("a",off) // needed to get the done check to work
+#endif
+Fl_Color ColorMenu::run() {
+  if (which < 0 || which > 255) {
+    position(Fl::event_x_root()-w()/2, Fl::event_y_root()-y()/2);
+  } else {
+    position(Fl::event_x_root()-(initial%8)*BOXSIZE-BOXSIZE/2-BORDER,
+	     Fl::event_y_root()-(initial/8)*BOXSIZE-BOXSIZE/2-BORDER);
+  }
+  show();
+  Fl::grab(*this);
+  done = 0;
+  while (!done) Fl::wait();
+  Fl::release();
+  return which;
+}
+
+Fl_Color fl_show_colormap(Fl_Color oldcol) {
+  ColorMenu m(oldcol);
+  return m.run();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_symbols.cxx b/Utilities/FLTK/src/fl_symbols.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e25fea6157f766032010d84706e7d8452dcd89e2
--- /dev/null
+++ b/Utilities/FLTK/src/fl_symbols.cxx
@@ -0,0 +1,700 @@
+//
+// "$Id$"
+//
+// Symbol drawing code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// These are small graphics drawn by the normal label-drawing
+// code when the string starts with an '@' sign.
+
+// Adapted from original code written by:
+
+// Written by Mark Overmars
+// Version 2.1 a
+// Date: Oct  2, 1992
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/math.h>
+#include "flstring.h"
+
+typedef struct {
+  const char *name;
+  void (*drawit)(Fl_Color);
+  char scalable;
+  char notempty;
+} SYMBOL;
+
+#define MAXSYMBOL       211
+   /* Maximal number of symbols in table. Only half of them are
+      used. Should be prime. */
+
+static SYMBOL symbols[MAXSYMBOL];      /* The symbols */
+static int symbnumb = -1;              /* Their number */
+
+static int find(const char *name) {
+// returns hash entry if it exists, or first empty slot:
+  int pos = name[0] ? (
+    name[1] ? (
+      name[2] ? 71*name[0]+31*name[1]+name[2] : 31*name[0]+name[1]
+    ) :
+      name[0]
+  ) : 0;
+  pos %= MAXSYMBOL;
+  int hh2 = name[0] ? (
+    (name[1]) ? 51*name[0]+3*name[1] : 3*name[0]
+    ) : 1;
+  hh2 %= MAXSYMBOL; if (!hh2) hh2 = 1;
+  for (;;) {
+    if (!symbols[pos].notempty) return pos;
+    if (!strcmp(symbols[pos].name,name)) return pos;
+    pos = (pos + hh2) % MAXSYMBOL;
+  }
+}
+
+static void fl_init_symbols(void);
+
+/**************** The routines seen by the user *************************/
+
+int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable)
+/* Adds a symbol to the system. Returns whether correct. */
+{
+  fl_init_symbols();
+  int pos;
+  if (symbnumb > MAXSYMBOL / 2) return 0;	// table is full
+  pos = find(name);
+  symbols[pos].name = name;
+  symbols[pos].drawit = drawit;
+  symbols[pos].notempty = 1;
+  symbols[pos].scalable = scalable;
+  symbnumb++;
+  return 1;
+}
+
+int fl_return_arrow(int x,int y,int w,int h);
+
+// provided for back compatability:
+int fl_draw_symbol(const char *label,int x,int y,int w,int h,Fl_Color col) {  
+  const char *p = label;
+  if (*p++ != '@') return 0;
+  fl_init_symbols();
+  int equalscale = 0;
+  if (*p == '#') {equalscale = 1; p++;}
+  if (*p == '-' && p[1]>='1' && p[1]<='9') {
+    int n = p[1]-'0';
+    x += n; y += n; w -= 2*n; h -= 2*n;
+    p += 2;
+  } else if (*p == '+' && p[1]>='1' && p[1]<='9') {
+    int n = p[1]-'0';
+    x -= n; y -= n; w += 2*n; h += 2*n;
+    p += 2;
+  }
+  if (w < 10) {x -= (10-w)/2; w = 10;}
+  if (h < 10) {y -= (10-h)/2; h = 10;}
+  w = (w-1)|1; h = (h-1)|1;
+  char flip_x = 0, flip_y = 0;
+  if (*p=='$') {
+    flip_x = 1;
+    p++;
+  }
+  if (*p=='%') {
+    flip_y = 1;
+    p++;
+  }
+  int rotangle;
+  switch (*p++) {
+  case '0':
+    rotangle = 1000*(p[1]-'0') + 100*(p[2]-'0') + 10*(p[3]-'0');
+    p += 4;
+    break;
+  case '1': rotangle = 2250; break;
+  case '2': rotangle = 2700; break;
+  case '3': rotangle = 3150; break;
+  case '4': rotangle = 1800; break;
+  case '5':
+  case '6': rotangle = 0; break;
+  case '7': rotangle = 1350; break;
+  case '8': rotangle =  900; break;
+  case '9': rotangle =  450; break;
+  default: rotangle = 0; p--; break;
+  }
+  int pos = find(p);
+  if (!symbols[pos].notempty) return 0;
+  if (symbols[pos].scalable == 3) { // kludge to detect return arrow
+    fl_return_arrow(x,y,w,h);
+    return 1;
+  }
+  fl_push_matrix();
+  fl_translate(x+w/2,y+h/2);
+  if (symbols[pos].scalable) {
+    if (equalscale) {if (w<h) h = w; else w = h;}
+    fl_scale(0.5*w, 0.5*h);
+    fl_rotate(rotangle/10.0);
+    if (flip_x) fl_scale(-1.0, 1.0);
+    if (flip_y) fl_scale(1.0, -1.0);
+  }
+  (symbols[pos].drawit)(col);
+  fl_pop_matrix();
+  return 1;
+}
+
+/******************** THE DEFAULT SYMBOLS ****************************/
+
+/* Some help stuff */
+
+#define BP fl_begin_polygon()
+#define EP fl_end_polygon()
+#define BCP fl_begin_complex_polygon()
+#define ECP fl_end_complex_polygon()
+#define BL fl_begin_line()
+#define EL fl_end_line()
+#define BC fl_begin_loop()
+#define EC fl_end_loop()
+#define vv(x,y) fl_vertex(x,y)
+
+//for the outline color
+static void set_outline_color(Fl_Color c) {
+  fl_color(fl_darker(c));
+}
+
+static void rectangle(double x,double y,double x2,double y2,Fl_Color col) {
+  fl_color(col);
+  BP; vv(x,y); vv(x2,y); vv(x2,y2); vv(x,y2); EP;
+  set_outline_color(col);
+  BC; vv(x,y); vv(x2,y); vv(x2,y2); vv(x,y2); EC;
+}
+
+/* The drawing routines */
+
+static void draw_fltk(Fl_Color col) 
+{
+  fl_color(col);
+  // F fill
+  BCP; vv(-2.0, -0.5); vv(-1.0, -0.5); vv(-1.0, -0.3); vv(-1.8, -0.3);
+  vv(-1.8, -0.1); vv(-1.2, -0.1); vv(-1.2, 0.1); vv(-1.8, 0.1);
+  vv(-1.8, 0.5); vv(-2.0, 0.5); ECP;
+  // L fill
+  BCP; vv(-1.0, -0.5); vv(-0.8, -0.5); vv(-0.8, 0.3); vv(0.0, 0.3);
+  vv(0.0, 0.5); vv(-1.0, 0.5); ECP;
+  // T outline
+  BCP; vv(-0.1, -0.5); vv(1.1, -0.5); vv(1.1, -0.3); vv(0.6, -0.3);
+  vv(0.6, 0.5); vv(0.4, 0.5); vv(0.4, -0.3); vv(-0.1, -0.3); ECP;
+  // K outline
+  BCP; vv(1.1, -0.5); vv(1.3, -0.5); vv(1.3, -0.15); vv(1.70, -0.5);
+  vv(2.0, -0.5); vv(1.43, 0.0); vv(2.0, 0.5); vv(1.70, 0.5);
+  vv(1.3, 0.15); vv(1.3, 0.5); vv(1.1, 0.5); ECP;
+  set_outline_color(col);
+  // F outline
+  BC; vv(-2.0, -0.5); vv(-1.0, -0.5); vv(-1.0, -0.3); vv(-1.8, -0.3);
+  vv(-1.8, -0.1); vv(-1.2, -0.1); vv(-1.2, 0.1); vv(-1.8, 0.1);
+  vv(-1.8, 0.5); vv(-2.0, 0.5); EC;
+  // L outline
+  BC; vv(-1.0, -0.5); vv(-0.8, -0.5); vv(-0.8, 0.3); vv(0.0, 0.3);
+  vv(0.0, 0.5); vv(-1.0, 0.5); EC;
+  // T outline
+  BC; vv(-0.1, -0.5); vv(1.1, -0.5); vv(1.1, -0.3); vv(0.6, -0.3);
+  vv(0.6, 0.5); vv(0.4, 0.5); vv(0.4, -0.3); vv(-0.1, -0.3); EC;
+  // K outline
+  BC; vv(1.1, -0.5); vv(1.3, -0.5); vv(1.3, -0.15); vv(1.70, -0.5);
+  vv(2.0, -0.5); vv(1.43, 0.0); vv(2.0, 0.5); vv(1.70, 0.5);
+  vv(1.3, 0.15); vv(1.3, 0.5); vv(1.1, 0.5); EC;
+}
+
+static void draw_search(Fl_Color col) 
+{
+  fl_color(col);
+  BP; vv(-.4, .13); vv(-1.0, .73); vv(-.73, 1.0); vv(-.13, .4); EP;
+  set_outline_color(col);
+  fl_line_style(FL_SOLID, 3, 0);
+  BC; fl_circle(.2, -.2, .6); EC;
+  fl_line_style(FL_SOLID, 1, 0);
+  BC; vv(-.4, .13); vv(-1.0, .73); vv(-.73, 1.0); vv(-.13, .4); EC;
+}
+
+static void draw_arrow1(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,-0.4); EP;
+  BP; vv(0.0,0.8); vv(0.8,0.0); vv(0.0,-0.8); vv(0.0,-0.4); vv(0.0,0.4); EP;
+  set_outline_color(col);
+  BC; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,0.8); vv(0.8,0.0);
+      vv(0.0,-0.8); vv(0.0,-0.4); EC;
+}
+
+static void draw_arrow1bar(Fl_Color col)
+{
+  draw_arrow1(col);
+  rectangle(.6,-.8,.9,.8,col);
+}
+
+static void draw_arrow2(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(-0.3,0.8); vv(0.50,0.0); vv(-0.3,-0.8); EP;
+  set_outline_color(col);
+  BC; vv(-0.3,0.8); vv(0.50,0.0); vv(-0.3,-0.8); EC;
+}
+
+static void draw_arrow3(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EP;
+  BP; vv(-0.7,0.8); vv(0.1,0.0); vv(-0.7,-0.8); EP;
+  set_outline_color(col);
+  BC; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EC;
+  BC; vv(-0.7,0.8); vv(0.1,0.0); vv(-0.7,-0.8); EC;
+}
+
+static void draw_arrowbar(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EP;
+  BP; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EP;
+  set_outline_color(col);
+  BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
+  BC; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EC;
+}
+
+static void draw_arrowbox(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EP;
+  BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
+  set_outline_color(col);
+  BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
+  BC; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EC;
+}
+
+static void draw_bararrow(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EP;
+  BP; vv(-0.5,0.8); vv(-0.1,0.8); vv(-0.1,-0.8); vv(-0.5,-0.8); EP;
+  set_outline_color(col);
+  BC; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EC;
+  BC; vv(-0.5,0.8); vv(-0.1,0.8); vv(-0.1,-0.8); vv(-0.5,-0.8); EC;
+}
+
+static void draw_doublebar(Fl_Color col) { 
+  rectangle(-0.6,-0.8,-.1,.8,col);
+  rectangle(.1,-0.8,.6,.8,col); 
+}
+
+static void draw_arrow01(Fl_Color col)
+  { fl_rotate(180); draw_arrow1(col); }
+
+static void draw_arrow02(Fl_Color col)
+  { fl_rotate(180); draw_arrow2(col); }
+
+static void draw_arrow03(Fl_Color col)
+  { fl_rotate(180); draw_arrow3(col); }
+
+static void draw_0arrowbar(Fl_Color col)
+  { fl_rotate(180); draw_arrowbar(col); }
+
+static void draw_0arrowbox(Fl_Color col)
+  { fl_rotate(180); draw_arrowbox(col); }
+
+static void draw_0bararrow(Fl_Color col)
+  { fl_rotate(180); draw_bararrow(col); }
+
+static void draw_doublearrow(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(-0.35,-0.4); vv(-0.35,0.4); vv(0.35,0.4); vv(0.35,-0.4); EP;
+  BP; vv(0.15,0.8); vv(0.95,0.0); vv(0.15,-0.8); EP;
+  BP; vv(-0.15,0.8); vv(-0.95,0.0); vv(-0.15,-0.8); EP;
+  set_outline_color(col);
+  BC; vv(-0.15,0.4); vv(0.15,0.4); vv(0.15,0.8); vv(0.95,0.0);
+      vv(0.15,-0.8); vv(0.15,-0.4); vv(-0.15,-0.4); vv(-0.15,-0.8);
+      vv(-0.95,0.0); vv(-0.15,0.8); EC;
+}
+
+static void draw_arrow(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EP;
+  BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
+  set_outline_color(col);
+  BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
+  BC; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EC;
+}
+
+static void draw_square(Fl_Color col)
+  { rectangle(-1,-1,1,1,col); }
+
+static void draw_circle(Fl_Color col) {
+  fl_color(col); BP; fl_circle(0,0,1); EP;
+  set_outline_color(col);
+  BC; fl_circle(0,0,1); EC;
+}
+
+static void draw_line(Fl_Color col)
+  { fl_color(col); BL; vv(-1.0,0.0); vv(1.0,0.0); EL; }
+
+static void draw_plus(Fl_Color col)
+{
+  fl_color(col);
+  BP; vv(-0.9,-0.15); vv(-0.9,0.15); vv(0.9,0.15); vv(0.9,-0.15); EP;
+  BP; vv(-0.15,-0.9); vv(-0.15,0.9); vv(0.15,0.9); vv(0.15,-0.9); EP;
+  set_outline_color(col);
+  BC;
+  vv(-0.9,-0.15); vv(-0.9,0.15); vv(-0.15,0.15); vv(-0.15,0.9);
+  vv(0.15,0.9); vv(0.15,0.15); vv(0.9,0.15); vv(0.9,-0.15);
+  vv(0.15,-0.15); vv(0.15,-0.9); vv(-0.15,-0.9); vv(-0.15,-0.15);
+  EC;
+}
+
+static void draw_uparrow(Fl_Color) {
+  fl_color(FL_LIGHT3);
+  BL; vv(-.8,.8); vv(-.8,-.8); vv(.8,0); EL;
+  fl_color(FL_DARK3);
+  BL; vv(-.8,.8); vv(.8, 0); EL;
+}
+
+static void draw_downarrow(Fl_Color) {
+  fl_color(FL_DARK3);
+  BL; vv(-.8,.8); vv(-.8,-.8); vv(.8,0); EL;
+  fl_color(FL_LIGHT3);
+  BL; vv(-.8,.8); vv(.8, 0); EL;
+}
+
+static void draw_menu(Fl_Color col)
+{
+  rectangle(-0.65, 0.85, 0.65, -0.25, col);
+  rectangle(-0.65, -0.6, 0.65, -1.0, col);
+}
+
+// Standard UI icons...
+static void draw_filenew(Fl_Color c) {
+  fl_color(c);
+  BCP;
+    vv(-0.7, -1.0);
+    vv(0.1, -1.0);
+    vv(0.1, -0.4);
+    vv(0.7, -0.4);
+    vv(0.7, 1.0);
+    vv(-0.7, 1.0);
+  ECP;
+
+  fl_color(fl_lighter(c));
+  BP;
+    vv(0.1, -1.0);
+    vv(0.1, -0.4);
+    vv(0.7, -0.4);
+  EP;
+
+  fl_color(fl_darker(c));
+  BC;
+    vv(-0.7, -1.0);
+    vv(0.1, -1.0);
+    vv(0.1, -0.4);
+    vv(0.7, -0.4);
+    vv(0.7, 1.0);
+    vv(-0.7, 1.0);
+  EC;
+
+  BL;
+    vv(0.1, -1.0);
+    vv(0.7, -0.4);
+  EL;
+}
+
+static void draw_fileopen(Fl_Color c) {
+  fl_color(c);
+  BP;
+    vv(-1.0, -0.7);
+    vv(-0.9, -0.8);
+    vv(-0.4, -0.8);
+    vv(-0.3, -0.7);
+    vv(0.6, -0.7);
+    vv(0.6, 0.7);
+    vv(-1.0, 0.7);
+  EP;
+
+  fl_color(fl_darker(c));
+  BC;
+    vv(-1.0, -0.7);
+    vv(-0.9, -0.8);
+    vv(-0.4, -0.8);
+    vv(-0.3, -0.7);
+    vv(0.6, -0.7);
+    vv(0.6, 0.7);
+    vv(-1.0, 0.7);
+  EC;
+
+  fl_color(fl_lighter(c));
+  BP;
+    vv(-1.0, 0.7);
+    vv(-0.6, -0.3);
+    vv(1.0, -0.3);
+    vv(0.6, 0.7);
+  EP;
+
+  fl_color(fl_darker(c));
+  BC;
+    vv(-1.0, 0.7);
+    vv(-0.6, -0.3);
+    vv(1.0, -0.3);
+    vv(0.6, 0.7);
+  EC;
+}
+
+static void draw_filesave(Fl_Color c) {
+  fl_color(c);
+  BP;
+    vv(-0.9, -1.0);
+    vv(0.9, -1.0);
+    vv(1.0, -0.9);
+    vv(1.0, 0.9);
+    vv(0.9, 1.0);
+    vv(-0.9, 1.0);
+    vv(-1.0, 0.9);
+    vv(-1.0, -0.9);
+  EP;
+
+  fl_color(fl_lighter(c));
+  BP;
+    vv(-0.7, -1.0);
+    vv(0.7, -1.0);
+    vv(0.7, -0.4);
+    vv(-0.7, -0.4);
+  EP;
+
+  BP;
+    vv(-0.7, 0.0);
+    vv(0.7, 0.0);
+    vv(0.7, 1.0);
+    vv(-0.7, 1.0);
+  EP;
+
+  fl_color(c);
+  BP;
+    vv(-0.5, -0.9);
+    vv(-0.3, -0.9);
+    vv(-0.3, -0.5);
+    vv(-0.5, -0.5);
+  EP;
+
+  fl_color(fl_darker(c));
+  BC;
+    vv(-0.9, -1.0);
+    vv(0.9, -1.0);
+    vv(1.0, -0.9);
+    vv(1.0, 0.9);
+    vv(0.9, 1.0);
+    vv(-0.9, 1.0);
+    vv(-1.0, 0.9);
+    vv(-1.0, -0.9);
+  EC;
+}
+
+static void draw_filesaveas(Fl_Color c) {
+  draw_filesave(c);
+
+  fl_color(fl_color_average(c, FL_WHITE, 0.25f));
+  BP;
+    vv(0.6, -0.8);
+    vv(1.0, -0.4);
+    vv(0.0, 0.6);
+    vv(-0.4, 0.6);
+    vv(-0.4, 0.2);
+  EP;
+
+  fl_color(fl_darker(c));
+  BC;
+    vv(0.6, -0.8);
+    vv(1.0, -0.4);
+    vv(0.0, 0.6);
+    vv(-0.4, 0.6);
+    vv(-0.4, 0.2);
+  EC;
+
+  BP;
+    vv(-0.1, 0.6);
+    vv(-0.4, 0.6);
+    vv(-0.4, 0.3);
+  EP;
+}
+
+static void draw_fileprint(Fl_Color c) {
+  fl_color(c);
+  BP;
+    vv(-0.8, 0.0);
+    vv(0.8, 0.0);
+    vv(1.0, 0.2);
+    vv(1.0, 1.0);
+    vv(-1.0, 1.0);
+    vv(-1.0, 0.2);
+  EP;
+
+  fl_color(fl_color_average(c, FL_WHITE, 0.25f));
+  BP;
+    vv(-0.6, 0.0);
+    vv(-0.6, -1.0);
+    vv(0.6, -1.0);
+    vv(0.6, 0.0);
+  EP;
+
+  fl_color(fl_lighter(c));
+  BP;
+    vv(-0.6, 0.6);
+    vv(0.6, 0.6);
+    vv(0.6, 1.0);
+    vv(-0.6, 1.0);
+  EP;
+
+  fl_color(fl_darker(c));
+  BC;
+    vv(-0.8, 0.0);
+    vv(-0.6, 0.0);
+    vv(-0.6, -1.0);
+    vv(0.6, -1.0);
+    vv(0.6, 0.0);
+    vv(0.8, 0.0);
+    vv(1.0, 0.2);
+    vv(1.0, 1.0);
+    vv(-1.0, 1.0);
+    vv(-1.0, 0.2);
+  EC;
+
+  BC;
+    vv(-0.6, 0.6);
+    vv(0.6, 0.6);
+    vv(0.6, 1.0);
+    vv(-0.6, 1.0);
+  EC;
+}
+
+static void draw_round_arrow(Fl_Color c, float da=5.0) {
+  double a, r, dr1=0.005, dr2=0.015;
+  int i, j;
+  for (j=0; j<2; j++) {
+    if (j&1) {
+      fl_color(c);
+      set_outline_color(c);
+      BC;
+    } else {
+      fl_color(c);
+      BCP;
+    }
+    vv(-0.1, 0.0);
+    vv(-1.0, 0.0);
+    vv(-1.0, 0.9);
+    for (i=27, a=140.0, r=1.0; i>0; i--, a-=da, r-=dr1) {
+      double ar = a/180.0 * M_PI;
+      vv(cos(ar)*r, sin(ar)*r);
+    }
+    for (i=27; i>=0; a+=da, i--, r-=dr2) {
+      double ar = a/180.0 * M_PI;
+      vv(cos(ar)*r, sin(ar)*r);
+    }
+    if (j&1) {
+      EC;
+    } else {
+      ECP;
+    }
+  }
+}
+
+static void draw_refresh(Fl_Color c) {
+  draw_round_arrow(c);
+  fl_rotate(180.0);
+  draw_round_arrow(c);
+  fl_rotate(-180.0);
+}
+
+static void draw_reload(Fl_Color c) {
+  fl_rotate(-135.0);
+  draw_round_arrow(c, 10);
+  fl_rotate(135.0);
+}
+
+static void draw_undo(Fl_Color c) {
+  fl_translate(0.0, 0.2);
+  fl_scale(1.0, -1.0);
+  draw_round_arrow(c, 6);
+  fl_scale(1.0, -1.0);
+  fl_translate(0.0, -0.2);
+}
+
+static void draw_redo(Fl_Color c) {
+  fl_scale(-1.0, 1.0);
+  draw_undo(c);
+  fl_scale(-1.0, 1.0);
+}
+
+static void fl_init_symbols(void) {
+  static char beenhere;
+  if (beenhere) return;
+  beenhere = 1;
+  symbnumb = 0;
+
+  fl_add_symbol("",		draw_arrow1,		1);
+  fl_add_symbol("->",		draw_arrow1,		1);
+  fl_add_symbol(">",		draw_arrow2,		1);
+  fl_add_symbol(">>",		draw_arrow3,		1);
+  fl_add_symbol(">|",		draw_arrowbar,		1);
+  fl_add_symbol(">[]",		draw_arrowbox,		1);
+  fl_add_symbol("|>",		draw_bararrow,		1);
+  fl_add_symbol("<-",		draw_arrow01,		1);
+  fl_add_symbol("<",		draw_arrow02,		1);
+  fl_add_symbol("<<",		draw_arrow03,		1);
+  fl_add_symbol("|<",		draw_0arrowbar,		1);
+  fl_add_symbol("[]<",		draw_0arrowbox,		1);
+  fl_add_symbol("<|",		draw_0bararrow,		1);
+  fl_add_symbol("<->",		draw_doublearrow,	1);
+  fl_add_symbol("-->",		draw_arrow,		1);
+  fl_add_symbol("+",		draw_plus,		1);
+  fl_add_symbol("->|",		draw_arrow1bar,		1);
+  fl_add_symbol("arrow",	draw_arrow,		1);
+  fl_add_symbol("returnarrow",	0,			3);
+  fl_add_symbol("square",	draw_square,		1);
+  fl_add_symbol("circle",	draw_circle,		1);
+  fl_add_symbol("line",		draw_line,		1);
+  fl_add_symbol("plus",		draw_plus,		1);
+  fl_add_symbol("menu",		draw_menu,		1);
+  fl_add_symbol("UpArrow",	draw_uparrow,		1);
+  fl_add_symbol("DnArrow",	draw_downarrow,		1);
+  fl_add_symbol("||",		draw_doublebar,		1);
+  fl_add_symbol("search",       draw_search,            1);
+  fl_add_symbol("FLTK",         draw_fltk,              1);
+
+  fl_add_symbol("filenew",      draw_filenew,           1);
+  fl_add_symbol("fileopen",     draw_fileopen,          1);
+  fl_add_symbol("filesave",     draw_filesave,          1);
+  fl_add_symbol("filesaveas",   draw_filesaveas,        1);
+  fl_add_symbol("fileprint",    draw_fileprint,         1);
+
+  fl_add_symbol("refresh",      draw_refresh,           1);
+  fl_add_symbol("reload",       draw_reload,            1);
+  fl_add_symbol("undo",         draw_undo,              1);
+  fl_add_symbol("redo",         draw_redo,              1);
+
+//  fl_add_symbol("file",      draw_file,           1);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/fl_vertex.cxx b/Utilities/FLTK/src/fl_vertex.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..da6d32ccbc972df7adbd2459bae27ec50a76c993
--- /dev/null
+++ b/Utilities/FLTK/src/fl_vertex.cxx
@@ -0,0 +1,326 @@
+//
+// "$Id$"
+//
+// Portable drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Portable drawing code for drawing arbitrary shapes with
+// simple 2D transformations.  See also fl_arc.cxx
+
+// matt: the Quartz implementation purposly doesn't use the Quartz matrix
+//       operations for reasons of compatibility and maintainability
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <FL/x.H>
+#include <FL/Fl.H>
+#include <FL/math.h>
+#include <stdlib.h>
+
+struct matrix {double a, b, c, d, x, y;};
+
+static matrix m = {1, 0, 0, 1, 0, 0};
+
+static matrix stack[32];
+static int sptr = 0;
+
+void fl_push_matrix() {
+  if (sptr==32)
+    Fl::error("fl_push_matrix(): matrix stack overflow.");
+  else
+    stack[sptr++] = m;
+}
+
+void fl_pop_matrix() {
+  if (sptr==0)
+    Fl::error("fl_pop_matrix(): matrix stack underflow.");
+  else 
+    m = stack[--sptr];
+}
+
+void fl_mult_matrix(double a, double b, double c, double d, double x, double y) {
+  matrix o;
+  o.a = a*m.a + b*m.c;
+  o.b = a*m.b + b*m.d;
+  o.c = c*m.a + d*m.c;
+  o.d = c*m.b + d*m.d;
+  o.x = x*m.a + y*m.c + m.x;
+  o.y = x*m.b + y*m.d + m.y;
+  m = o;
+}
+
+void fl_scale(double x,double y) {fl_mult_matrix(x,0,0,y,0,0);}
+
+void fl_scale(double x) {fl_mult_matrix(x,0,0,x,0,0);}
+
+void fl_translate(double x,double y) {fl_mult_matrix(1,0,0,1,x,y);}
+
+void fl_rotate(double d) {
+  if (d) {
+    double s, c;
+    if (d == 0) {s = 0; c = 1;}
+    else if (d == 90) {s = 1; c = 0;}
+    else if (d == 180) {s = 0; c = -1;}
+    else if (d == 270 || d == -90) {s = -1; c = 0;}
+    else {s = sin(d*M_PI/180); c = cos(d*M_PI/180);}
+    fl_mult_matrix(c,-s,s,c,0,0);
+  }
+}
+
+// typedef what the x,y fields in a point are:
+#ifdef WIN32
+typedef int COORD_T;
+#  define XPOINT XPoint
+#elif defined(__APPLE_QUARTZ__)
+typedef float COORD_T;
+typedef struct { float x; float y; } QPoint;
+#  define XPOINT QPoint
+extern float fl_quartz_line_width_;
+#else
+typedef short COORD_T;
+#  define XPOINT XPoint
+#endif
+
+static XPOINT *p = (XPOINT *)0;
+
+static int p_size;
+static int n;
+static int what;
+enum {LINE, LOOP, POLYGON, POINT_};
+
+void fl_begin_points() {n = 0; what = POINT_;}
+
+void fl_begin_line() {n = 0; what = LINE;}
+
+void fl_begin_loop() {n = 0; what = LOOP;}
+
+void fl_begin_polygon() {n = 0; what = POLYGON;}
+
+double fl_transform_x(double x, double y) {return x*m.a + y*m.c + m.x;}
+
+double fl_transform_y(double x, double y) {return x*m.b + y*m.d + m.y;}
+
+double fl_transform_dx(double x, double y) {return x*m.a + y*m.c;}
+
+double fl_transform_dy(double x, double y) {return x*m.b + y*m.d;}
+
+static void fl_transformed_vertex(COORD_T x, COORD_T y) {
+  if (!n || x != p[n-1].x || y != p[n-1].y) {
+    if (n >= p_size) {
+      p_size = p ? 2*p_size : 16;
+      p = (XPOINT*)realloc((void*)p, p_size*sizeof(*p));
+    }
+    p[n].x = x;
+    p[n].y = y;
+    n++;
+  }
+}
+
+void fl_transformed_vertex(double xf, double yf) {
+#ifdef __APPLE_QUARTZ__
+  fl_transformed_vertex(COORD_T(xf), COORD_T(yf));
+#else
+  fl_transformed_vertex(COORD_T(rint(xf)), COORD_T(rint(yf)));
+#endif
+}
+
+void fl_vertex(double x,double y) {
+  fl_transformed_vertex(x*m.a + y*m.c + m.x, x*m.b + y*m.d + m.y);
+}
+
+void fl_end_points() {
+#ifdef WIN32
+  for (int i=0; i<n; i++) SetPixel(fl_gc, p[i].x, p[i].y, fl_RGB());
+#elif defined(__APPLE_QD__)
+  for (int i=0; i<n; i++) { MoveTo(p[i].x, p[i].y); Line(0, 0); } 
+#elif defined(__APPLE_QUARTZ__)
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+  for (int i=0; i<n; i++) { 
+    CGContextMoveToPoint(fl_gc, p[i].x, p[i].y);
+    CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
+    CGContextStrokePath(fl_gc);
+  }
+  if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
+#else
+  if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0);
+#endif
+}
+
+void fl_end_line() {
+  if (n < 2) {
+    fl_end_points();
+    return;
+  }
+#ifdef WIN32
+  if (n>1) Polyline(fl_gc, p, n);
+#elif defined(__APPLE_QD__)
+  if (n<=1) return;
+  MoveTo(p[0].x, p[0].y);
+  for (int i=1; i<n; i++) LineTo(p[i].x, p[i].y);
+#elif defined(__APPLE_QUARTZ__)
+  if (n<=1) return;
+  CGContextMoveToPoint(fl_gc, p[0].x, p[0].y);
+  for (int i=1; i<n; i++)
+    CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
+  CGContextStrokePath(fl_gc);
+#else
+  if (n>1) XDrawLines(fl_display, fl_window, fl_gc, p, n, 0);
+#endif
+}
+
+static void fixloop() {  // remove equal points from closed path
+  while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--;
+}
+
+void fl_end_loop() {
+  fixloop();
+  if (n>2) fl_transformed_vertex((COORD_T)p[0].x, (COORD_T)p[0].y);
+  fl_end_line();
+}
+
+void fl_end_polygon() {
+  fixloop();
+  if (n < 3) {
+    fl_end_line();
+    return;
+  }
+#ifdef WIN32
+  if (n>2) {
+    SelectObject(fl_gc, fl_brush());
+    Polygon(fl_gc, p, n);
+  }
+#elif defined(__APPLE_QD__)
+  if (n<=1) return;
+  PolyHandle ph = OpenPoly();
+  MoveTo(p[0].x, p[0].y);
+  for (int i=1; i<n; i++) LineTo(p[i].x, p[i].y);
+  ClosePoly();
+  PaintPoly(ph);
+  KillPoly(ph);
+#elif defined(__APPLE_QUARTZ__)
+  if (n<=1) return;
+  CGContextMoveToPoint(fl_gc, p[0].x, p[0].y);
+  for (int i=1; i<n; i++) 
+    CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
+  CGContextClosePath(fl_gc);
+  CGContextFillPath(fl_gc);
+#else
+  if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, Convex, 0);
+#endif
+}
+
+static int gap;
+#ifdef WIN32
+static int counts[20];
+static int numcount;
+#endif
+
+void fl_begin_complex_polygon() {
+  fl_begin_polygon();
+  gap = 0;
+#ifdef WIN32
+  numcount = 0;
+#endif
+}
+
+void fl_gap() {
+  while (n>gap+2 && p[n-1].x == p[gap].x && p[n-1].y == p[gap].y) n--;
+  if (n > gap+2) {
+    fl_transformed_vertex((COORD_T)p[gap].x, (COORD_T)p[gap].y);
+#ifdef WIN32
+    counts[numcount++] = n-gap;
+#endif
+    gap = n;
+  } else {
+    n = gap;
+  }
+}
+
+void fl_end_complex_polygon() {
+  fl_gap();
+  if (n < 3) {
+    fl_end_line();
+    return;
+  }
+#ifdef WIN32
+  if (n>2) {
+    SelectObject(fl_gc, fl_brush());
+    PolyPolygon(fl_gc, p, counts, numcount);
+  }
+#elif defined(__APPLE_QD__)
+  if (n<=1) return;
+  PolyHandle ph = OpenPoly();
+  MoveTo(p[0].x, p[0].y);
+  for (int i=1; i<n; i++) LineTo(p[i].x, p[i].y);
+  ClosePoly();
+  PaintPoly(ph);
+  KillPoly(ph);
+#elif defined(__APPLE_QUARTZ__)
+  if (n<=1) return;
+  CGContextMoveToPoint(fl_gc, p[0].x, p[0].y);
+  for (int i=1; i<n; i++)
+    CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
+  CGContextClosePath(fl_gc);
+  CGContextFillPath(fl_gc);
+#else
+  if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, 0, 0);
+#endif
+}
+
+// shortcut the closed circles so they use XDrawArc:
+// warning: these do not draw rotated ellipses correctly!
+// See fl_arc.c for portable version.
+
+void fl_circle(double x, double y,double r) {
+  double xt = fl_transform_x(x,y);
+  double yt = fl_transform_y(x,y);
+  double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a));
+  double ry = r * (m.b ? sqrt(m.b*m.b+m.d*m.d) : fabs(m.d));
+  int llx = (int)rint(xt-rx);
+  int w = (int)rint(xt+rx)-llx;
+  int lly = (int)rint(yt-ry);
+  int h = (int)rint(yt+ry)-lly;
+#ifdef WIN32
+  if (what==POLYGON) {
+    SelectObject(fl_gc, fl_brush());
+    Pie(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); 
+  } else
+    Arc(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); 
+#elif defined(__APPLE_QD__)
+  Rect rt; rt.left=llx; rt.right=llx+w; rt.top=lly; rt.bottom=lly+h;
+  (what == POLYGON ? PaintOval : FrameOval)(&rt);
+#elif defined(__APPLE_QUARTZ__)
+  // Quartz warning : circle won't scale to current matrix!
+  CGContextAddArc(fl_gc, xt, yt, (w+h)*0.25f, 0, 2.0f*M_PI, 1);
+  (what == POLYGON ? CGContextFillPath : CGContextStrokePath)(fl_gc);
+#else
+  (what == POLYGON ? XFillArc : XDrawArc)
+    (fl_display, fl_window, fl_gc, llx, lly, w, h, 0, 360*64);
+#endif
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/flstring.c b/Utilities/FLTK/src/flstring.c
new file mode 100644
index 0000000000000000000000000000000000000000..754dd143f0241d9fb0c61b7df5bad829aec02319
--- /dev/null
+++ b/Utilities/FLTK/src/flstring.c
@@ -0,0 +1,105 @@
+/*
+ * "$Id$"
+ *
+ * BSD string functions for the Fast Light Tool Kit (FLTK).
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+#include "flstring.h"
+
+
+/*
+ * 'fl_strlcat()' - Safely concatenate two strings.
+ */
+
+size_t				/* O - Length of string */
+fl_strlcat(char       *dst,	/* O - Destination string */
+           const char *src,	/* I - Source string */
+	   size_t     size) {	/* I - Size of destination string buffer */
+  size_t	srclen;		/* Length of source string */
+  size_t	dstlen;		/* Length of destination string */
+
+
+ /*
+  * Figure out how much room is left...
+  */
+
+  dstlen = strlen(dst);
+  size   -= dstlen + 1;
+
+  if (!size) return (dstlen);	/* No room, return immediately... */
+
+ /*
+  * Figure out how much room is needed...
+  */
+
+  srclen = strlen(src);
+
+ /*
+  * Copy the appropriate amount...
+  */
+
+  if (srclen > size) srclen = size;
+
+  memcpy(dst + dstlen, src, srclen);
+  dst[dstlen + srclen] = '\0';
+
+  return (dstlen + srclen);
+}
+
+
+/*
+ * 'fl_strlcpy()' - Safely copy two strings.
+ */
+
+size_t				/* O - Length of string */
+fl_strlcpy(char       *dst,	/* O - Destination string */
+           const char *src,	/* I - Source string */
+	   size_t      size) {	/* I - Size of destination string buffer */
+  size_t	srclen;		/* Length of source string */
+
+
+ /*
+  * Figure out how much room is needed...
+  */
+
+  size --;
+
+  srclen = strlen(src);
+
+ /*
+  * Copy the appropriate amount...
+  */
+
+  if (srclen > size) srclen = size;
+
+  memcpy(dst, src, srclen);
+  dst[srclen] = '\0';
+
+  return (srclen);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/Utilities/FLTK/src/flstring.h b/Utilities/FLTK/src/flstring.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e1fe36a817e12fcd39a1339fd9409a149c51b78
--- /dev/null
+++ b/Utilities/FLTK/src/flstring.h
@@ -0,0 +1,115 @@
+/*
+ * "$Id$"
+ *
+ * Common string header file for the Fast Light Tool Kit (FLTK).
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+#ifndef flstring_h
+#  define flstring_h
+
+#  include <FL/Fl_Export.H>
+/*#  include <config.h>*/
+#  include "fltk-config.h"
+
+#  include <stdio.h>
+#  include <stdarg.h>
+#  include <string.h>
+#  ifdef HAVE_STRINGS_H
+#    include <strings.h>
+#  endif /* HAVE_STRINGS_H */
+#  include <ctype.h>
+
+/*
+ * Apparently Unixware defines "index" to strchr (!) rather than
+ * providing a proper entry point or not providing the (obsolete)
+ * BSD function.  Make sure index is not defined...
+ */
+
+#  ifdef index
+#    undef index
+#  endif /* index */
+
+#  if defined(WIN32) && !defined(__CYGWIN__)
+#    define strcasecmp(s,t)	_stricmp((s), (t))
+#    define strncasecmp(s,t,n)	_strnicmp((s), (t), (n))
+// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
+// on Windows, which is supposed to be POSIX compliant...  Some of these functions
+// are also defined in ISO C99...
+#  define strdup _strdup
+#  define unlink _unlink
+#  elif defined(__EMX__)
+#    define strcasecmp(s,t)	stricmp((s), (t))
+#    define strncasecmp(s,t,n)	strnicmp((s), (t), (n))
+#  endif /* WIN32 */
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif /* __cplusplus */
+
+/*
+ * MetroWerks' CodeWarrior put thes "non-standard" functions in
+ * <extras.h> which unfortunatly does not play well otherwise
+ * when included - to be resolved...
+ */
+
+#  if defined(__APPLE__) && defined(__MWERKS__) && defined(_MSL_USING_MW_C_HEADERS)
+int strcasecmp(const char*,const char*);
+int strncasecmp(const char*,const char*,int);
+char *strdup(const char*);
+#  endif
+
+FL_EXPORT extern int fl_snprintf(char *, size_t, const char *, ...);
+#  if !HAVE_SNPRINTF
+#    define snprintf fl_snprintf
+#  endif /* !HAVE_SNPRINTF */
+
+FL_EXPORT extern int fl_vsnprintf(char *, size_t, const char *, va_list ap);
+#  if !HAVE_VSNPRINTF
+#    define vsnprintf fl_vsnprintf
+#  endif /* !HAVE_VSNPRINTF */
+
+/*
+ * strlcpy() and strlcat() are some really useful BSD string functions
+ * that work the way strncpy() and strncat() *should* have worked.
+ */
+
+FL_EXPORT extern size_t fl_strlcat(char *, const char *, size_t);
+#  if !HAVE_STRLCAT
+#    define strlcat fl_strlcat
+#  endif /* !HAVE_STRLCAT */
+
+FL_EXPORT extern size_t fl_strlcpy(char *, const char *, size_t);
+#  if !HAVE_STRLCPY
+#    define strlcpy fl_strlcpy
+#  endif /* !HAVE_STRLCPY */
+
+#  ifdef __cplusplus
+}
+#  endif /* __cplusplus */
+#endif /* !flstring_h */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/Utilities/FLTK/src/forms_bitmap.cxx b/Utilities/FLTK/src/forms_bitmap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..644d3b474c8caf49a9bf07916e30ed5f2d5dfb9c
--- /dev/null
+++ b/Utilities/FLTK/src/forms_bitmap.cxx
@@ -0,0 +1,52 @@
+//
+// "$Id$"
+//
+// Forms compatible bitmap function for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/forms.H>
+
+Fl_FormsBitmap::Fl_FormsBitmap(
+  Fl_Boxtype t, int X, int Y, int W, int H, const char* l)
+: Fl_Widget(X, Y, W, H, l) {
+  box(t);
+  b = 0;
+  color(FL_BLACK);
+  align(FL_ALIGN_BOTTOM);
+}
+
+void Fl_FormsBitmap::set(int W, int H, const uchar *bits) {
+  delete b;
+  bitmap(new Fl_Bitmap(bits, W, H));
+}
+
+void Fl_FormsBitmap::draw() {
+  draw_box(box(), selection_color());
+  if (b) {fl_color(color()); b->draw(x(), y(), w(), h());}
+  draw_label();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/forms_compatability.cxx b/Utilities/FLTK/src/forms_compatability.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..0fe44bacdd2910f5d4793e2151ac9ff2a74302ef
--- /dev/null
+++ b/Utilities/FLTK/src/forms_compatability.cxx
@@ -0,0 +1,211 @@
+//
+// "$Id$"
+//
+// Forms compatibility functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Forms library compatability functions.
+// Many more functions are defined as inlines in forms.h!
+
+#include <FL/forms.H>
+#include <stdlib.h>
+
+char fl_flip = 2;
+void fl_end_form() {
+  while (Fl_Group::current()) Fl_Group::current()->forms_end();
+}
+void Fl_Group::forms_end() {
+  // set the dimensions of a group to surround contents
+  if (children() && !w()) {
+    Fl_Widget*const* a = array();
+    Fl_Widget* o = *a++;
+    int rx = o->x();
+    int ry = o->y();
+    int rw = rx+o->w();
+    int rh = ry+o->h();
+    for (int i=children_-1; i--;) {
+      o = *a++;
+      if (o->x() < rx) rx = o->x();
+      if (o->y() < ry) ry = o->y();
+      if (o->x()+o->w() > rw) rw = o->x()+o->w();
+      if (o->y()+o->h() > rh) rh = o->y()+o->h();
+    }
+    x(rx);
+    y(ry);
+    w(rw-rx);
+    h(rh-ry);
+  }
+  // flip all the children's coordinate systems:
+  if (fl_flip) {
+    Fl_Widget* o = (type()>=FL_WINDOW) ? this : window();
+    int Y = o->h();
+    Fl_Widget*const* a = array();
+    for (int i=children(); i--;) {
+      Fl_Widget* ow = *a++;
+      int newy = Y-ow->y()-ow->h();
+      ow->y(newy);
+    }
+  }
+  end();
+}
+
+static int initargc;
+static char **initargv;
+
+void fl_initialize(int *argc, char **argv, const char *, FL_CMD_OPT *, int) {
+  initargc = *argc;
+  initargv = new char*[*argc+1];
+  int i,j;
+  for (i=0; i<=*argc; i++) initargv[i] = argv[i];
+  for (i=j=1; i<*argc; ) {
+    if (Fl::arg(*argc,argv,i));
+    else argv[j++] = argv[i++];
+  }
+  argv[j] = 0;
+  *argc = j;
+  if (fl_flip==2) fl_flip = 0;
+}
+
+char fl_modal_next; // set by fl_freeze_forms()
+
+void fl_show_form(Fl_Window *f,int place,int b,const char *n) {
+
+  f->label(n);
+  if (!b) f->clear_border();
+  if (fl_modal_next || b==FL_TRANSIENT) {f->set_modal(); fl_modal_next = 0;}
+
+  if (place & FL_PLACE_MOUSE) f->hotspot(f);
+
+  if (place & FL_PLACE_CENTER) {
+    int scr_x, scr_y, scr_w, scr_h;
+    Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+    f->position(scr_x+(scr_w-f->w())/2, scr_y+(scr_h-f->h())/2);
+  }
+
+  if (place & FL_PLACE_FULLSCREEN)
+    f->fullscreen();
+
+  if (place & (FL_PLACE_POSITION | FL_PLACE_GEOMETRY))
+    f->position(
+      (f->x() < 0) ? Fl::w()-f->w()+f->x()-1 : f->x(),
+      (f->y() < 0) ? Fl::h()-f->h()+f->y()-1 : f->y());
+
+// if (place & FL_PLACE_ASPECT) {
+// this is not yet implemented
+// it can be done by setting size_range().
+
+  if (place == FL_PLACE_FREE || place == FL_PLACE_SIZE)
+    f->free_position();
+
+  if (place == FL_PLACE_FREE || place & FL_FREE_SIZE)
+    if (!f->resizable()) f->resizable(f);
+
+  if (initargc) {f->show(initargc,initargv); initargc = 0;}
+  else f->show();
+}
+
+Fl_Widget *fl_do_forms(void) {
+  Fl_Widget *obj;
+  while (!(obj = Fl::readqueue())) if (!Fl::wait()) exit(0);
+  return obj;
+}
+
+Fl_Widget *fl_check_forms() {
+  Fl::check();
+  return Fl::readqueue();
+}
+
+void fl_set_graphics_mode(int /*r*/,int /*d*/) {}
+
+void Fl_FormsText::draw() {
+  draw_box();
+  align(align()|FL_ALIGN_INSIDE); // questionable method of compatability
+  draw_label();
+}
+
+// Create a forms button by selecting correct fltk subclass:
+
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Repeat_Button.H>
+
+Fl_Button *fl_add_button(uchar t,int x,int y,int w,int h,const char *l) {
+  Fl_Button *b;
+  switch (t) {
+  case FL_RETURN_BUTTON:
+  case FL_HIDDEN_RET_BUTTON:
+    b = new Fl_Return_Button(x,y,w,h,l);
+    break;
+  case FL_TOUCH_BUTTON:
+    b = new Fl_Repeat_Button(x,y,w,h,l);
+    break;
+  default:
+    b = new Fl_Button(x,y,w,h,l);
+  }
+  switch (t) {
+  case FL_TOGGLE_BUTTON:
+  case FL_RADIO_BUTTON:
+    b->type(t);
+    break;
+  case FL_HIDDEN_BUTTON:
+  case FL_HIDDEN_RET_BUTTON:
+    b->type(FL_HIDDEN_BUTTON);
+    break;
+  case FL_INOUT_BUTTON:
+    b->when(FL_WHEN_CHANGED);
+    break;
+  }
+  return b;
+}
+
+void fl_show_message(const char *q1,const char *q2,const char *q3) {
+  fl_message("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"");
+}
+
+void fl_show_alert(const char *q1,const char *q2,const char *q3,int) {
+  fl_alert("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"");
+}
+
+int fl_show_question(const char *q1,const char *q2,const char *q3) {
+  return fl_choice("%s\n%s\n%s", "No", "Yes", 0L, q1?q1:"", q2?q2:"", q3?q3:"");
+}
+
+int fl_show_choice(
+  const char *q1,
+  const char *q2,
+  const char *q3,
+  int, // number of buttons, ignored
+  const char *b0,
+  const char *b1,
+  const char *b2) {
+  return fl_choice("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"", b0,b1,b2)+1;
+}
+
+char *fl_show_simple_input(const char *str1, const char *defstr) {
+  const char *r = fl_input(str1, defstr);
+  return (char *)(r ? r : defstr);
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/forms_free.cxx b/Utilities/FLTK/src/forms_free.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5855f8b093187e7d18f7d5c97c68c787f700e7b2
--- /dev/null
+++ b/Utilities/FLTK/src/forms_free.cxx
@@ -0,0 +1,81 @@
+//
+// "$Id$"
+//
+// Forms free widget routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Emulation of the Forms "free" widget.
+// This emulation allows the free demo to run, and has allowed
+// me to port several other programs, but it is in no way
+// complete.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Free.H>
+
+void Fl_Free::step(void *v) {
+  Fl_Free *f = (Fl_Free *)v;
+  int old_event = Fl::e_number;
+  f->handle(Fl::e_number == FL_STEP);
+  Fl::e_number = old_event;
+  Fl::add_timeout(.01,step,v);
+}
+
+Fl_Free::Fl_Free(uchar t,int X, int Y, int W, int H,const char *l,
+		 FL_HANDLEPTR hdl) :
+Fl_Widget(X,Y,W,H,l) {
+  type(t);
+  hfunc = hdl;
+  if (t == FL_SLEEPING_FREE) set_flag(INACTIVE);
+  if (t == FL_CONTINUOUS_FREE || t == FL_ALL_FREE)
+    Fl::add_timeout(.01,step,this);
+}
+
+Fl_Free::~Fl_Free() {
+  Fl::remove_timeout(step,this);
+  hfunc(this,FL_FREEMEM,0,0,0);
+}
+
+void Fl_Free::draw() {hfunc(this,FL_DRAW,0,0,0);}
+
+int Fl_Free::handle(int e) {
+  char key = Fl::event_key();
+  switch (e) {
+  case FL_FOCUS:
+    if (type()!=FL_INPUT_FREE && type()!=FL_ALL_FREE) return 0;
+    break;
+  case FL_PUSH:
+  case FL_DRAG:
+  case FL_RELEASE:
+    key = 4-Fl::event_button();
+    break;
+  case FL_SHORTCUT:
+    return 0;
+  }
+  if (hfunc(this, e, float(Fl::event_x()), float(Fl::event_y()), key)) do_callback();
+  return 1;
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/forms_fselect.cxx b/Utilities/FLTK/src/forms_fselect.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f68a3db957f7e9a295cdbcb72dc6ad7631bfd213
--- /dev/null
+++ b/Utilities/FLTK/src/forms_fselect.cxx
@@ -0,0 +1,67 @@
+//
+// "$Id$"
+//
+// Forms file selection routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Emulate the Forms file chooser using the fltk file chooser.
+
+#include <FL/forms.H>
+#include "flstring.h"
+
+static char fl_directory[1024];
+static const char *fl_pattern;  // assummed passed value is static
+static char fl_filename[1024];
+
+char* fl_show_file_selector(const char *message,const char *dir,
+			    const char *pat,const char *fname) {
+  if (dir && dir[0]) strlcpy(fl_directory,dir,sizeof(fl_directory));
+  if (pat && pat[0]) fl_pattern = pat;
+  if (fname && fname[0]) strlcpy(fl_filename,fname,sizeof(fl_filename));
+  char *p = fl_directory+strlen(fl_directory);
+  if (p > fl_directory && *(p-1)!='/'
+#ifdef WIN32
+      && *(p-1)!='\\' && *(p-1)!=':'
+#endif
+      ) *p++ = '/';
+  strlcpy(p,fl_filename,sizeof(fl_directory) - (p - fl_directory));
+  const char *q = fl_file_chooser(message,fl_pattern,fl_directory);
+  if (!q) return 0;
+  strlcpy(fl_directory, q, sizeof(fl_directory));
+  p = (char *)fl_filename_name(fl_directory);
+  strlcpy(fl_filename, p, sizeof(fl_filename));
+  if (p > fl_directory+1) p--;
+  *p = 0;
+  return (char *)q;
+}
+
+char*	fl_get_directory() {return fl_directory;}
+
+char*	fl_get_pattern() {return (char *)fl_pattern;}
+
+char*	fl_get_filename() {return fl_filename;}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/forms_pixmap.cxx b/Utilities/FLTK/src/forms_pixmap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..94419ae284ab0480a12c83a3bf7dd5534a1de517
--- /dev/null
+++ b/Utilities/FLTK/src/forms_pixmap.cxx
@@ -0,0 +1,52 @@
+//
+// "$Id$"
+//
+// Forms pixmap drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <FL/forms.H>
+
+Fl_FormsPixmap::Fl_FormsPixmap(
+  Fl_Boxtype t, int X, int Y, int W, int H, const char* l)
+: Fl_Widget(X, Y, W, H, l) {
+  box(t);
+  b = 0;
+  color(FL_BLACK);
+  align(FL_ALIGN_BOTTOM);
+}
+
+void Fl_FormsPixmap::set(char*const* bits) {
+  delete b;
+  b = new Fl_Pixmap(bits);
+}
+
+void Fl_FormsPixmap::draw() {
+  draw_box(box(), selection_color());
+  if (b) {fl_color(color()); b->draw(x(), y(), w(), h());}
+  draw_label();
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/forms_timer.cxx b/Utilities/FLTK/src/forms_timer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..031d67f27147bec5b2c750ce14c72c863e7ee8f7
--- /dev/null
+++ b/Utilities/FLTK/src/forms_timer.cxx
@@ -0,0 +1,169 @@
+//
+// "$Id$"
+//
+// Forms timer object for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Emulate the Forms Timer object
+// You don't want to use this if you just want a timeout, call
+// Fl::add_timeout directly!
+
+#include <FL/Fl.H>
+#include <FL/Fl_Timer.H>
+#include <FL/fl_draw.H>
+#ifdef WIN32
+#  ifdef __MWERKS__
+#    include <time.h>
+#  else
+#    include <sys/types.h> 
+#    include <sys/timeb.h>
+#  endif
+#else
+#  include <time.h>
+#  include <sys/time.h>
+#endif
+#include <stdio.h>
+
+#define FL_TIMER_BLINKRATE	0.2
+
+void fl_gettime(long* sec, long* usec) {
+#ifdef WIN32
+# ifdef __MWERKS__
+  time_t localTime = time(NULL);
+  struct tm *now = localtime(&localTime);
+  *sec = now->tm_sec + 60*now->tm_min + 3600*now->tm_hour + 24*3600*now->tm_yday;
+  *usec = 0;
+# else
+  struct timeb tp;
+  ftime(&tp);
+  *sec = tp.time;
+  *usec = tp.millitm * 1000;
+# endif
+#else
+  struct timeval tp;
+  struct timezone tzp;
+  gettimeofday(&tp, &tzp);
+  *sec = tp.tv_sec;
+  *usec = tp.tv_usec;
+#endif
+}
+
+void Fl_Timer::draw() {
+  int tt;
+  Fl_Color col;
+  char str[32];
+  if (!on || delay>0.0)
+    col = color();
+  else if ((int) (delay / FL_TIMER_BLINKRATE) % 2)
+    col = color();
+  else
+    col = selection_color();
+  draw_box(box(), col);
+  if (type() == FL_VALUE_TIMER && delay>0.0) {
+    double d = direction_ ? total-delay : delay;
+    if (d < 60.0)
+      sprintf(str, "%.1f", d);
+    else {
+      tt = (int) ((d+0.05) / 60.0);
+      sprintf(str, "%d:%04.1f", tt, d - 60.0 * tt);
+    }
+    fl_font(labelfont(), labelsize());
+    fl_color(labelcolor());
+    fl_draw(str, x(), y(), w(), h(), FL_ALIGN_CENTER);
+  } else
+    draw_label();
+}
+
+void Fl_Timer::stepcb(void* v) {
+  ((Fl_Timer*)v)->step();
+}
+
+void Fl_Timer::step() {
+  if (!on) return;
+  double lastdelay = delay;
+  long sec, usec; fl_gettime(&sec, &usec);
+  delay -= (double) (sec - lastsec) + (double) (usec - lastusec) / 1000000.0;
+  lastsec = sec; lastusec = usec;
+  if (lastdelay > 0.0 && delay <= 0.0) {
+    if (type() == FL_HIDDEN_TIMER) {
+      on = 0;
+      delay = 0;
+    } else {
+      redraw();
+      Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+    }
+    set_changed();
+    do_callback();
+  } else {
+    if (type() == FL_VALUE_TIMER) redraw();
+    Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+  }
+}
+
+int Fl_Timer::handle(int event) {
+  if (event == FL_RELEASE && delay <= 0) value(0.0);
+  return 0;
+}
+
+Fl_Timer::~Fl_Timer() {
+  Fl::remove_timeout(stepcb, this);
+}
+
+Fl_Timer::Fl_Timer(uchar t, int X, int Y, int W, int H, const char* l)
+: Fl_Widget(X, Y, W, H, l) {
+  box(FL_DOWN_BOX);
+  selection_color(FL_RED);
+  delay = 0;
+  on = 0;
+  direction_ = 0;
+  type(t);
+  if (t == FL_HIDDEN_TIMER) clear_visible();
+  if (t == FL_VALUE_TIMER) align(FL_ALIGN_LEFT);
+}
+
+void Fl_Timer::value(double d) {
+  delay = total = d;
+  on = (d > 0.0);
+  fl_gettime(&(lastsec), &(lastusec));
+  if (type() != FL_HIDDEN_TIMER) redraw();
+  Fl::remove_timeout(stepcb, this);
+  if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+}
+
+void Fl_Timer::suspended(char d) {
+  if (!d) {
+    if (on) return;
+    on = (delay > 0.0);
+    fl_gettime(&(lastsec), &(lastusec));
+    if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+  } else {
+    if (!on) return;
+    on = 0;
+    Fl::remove_timeout(stepcb, this);
+  }
+}
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/gl_draw.cxx b/Utilities/FLTK/src/gl_draw.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6eac7a7ed13be62a51e5a606102919964ce048c0
--- /dev/null
+++ b/Utilities/FLTK/src/gl_draw.cxx
@@ -0,0 +1,232 @@
+//
+// "$Id$"
+//
+// OpenGL drawing support routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Functions from <FL/gl.h>
+// See also Fl_Gl_Window and gl_start.cxx
+
+#include "flstring.h"
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/gl.h>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include "Fl_Gl_Choice.H"
+#include "Fl_Font.H"
+
+#if USE_XFT
+extern XFontStruct* fl_xxfont();
+#endif // USE_XFT
+
+int   gl_height() {return fl_height();}
+int   gl_descent() {return fl_descent();}
+double gl_width(const char* s) {return fl_width(s);}
+double gl_width(const char* s, int n) {return fl_width(s,n);}
+double gl_width(uchar c) {return fl_width(c);}
+
+void  gl_font(int fontid, int size) {
+  fl_font(fontid, size);
+  if (!fl_fontsize->listbase) {
+#ifdef WIN32
+    int base = fl_fontsize->metr.tmFirstChar;
+    int count = fl_fontsize->metr.tmLastChar-base+1;
+    HFONT oldFid = (HFONT)SelectObject(fl_gc, fl_fontsize->fid);
+    fl_fontsize->listbase = glGenLists(256);
+    wglUseFontBitmaps(fl_gc, base, count, fl_fontsize->listbase+base); 
+    SelectObject(fl_gc, oldFid);
+#elif defined(__APPLE_QD__)
+    // undefined characters automatically receive an empty GL list in aglUseFont
+    fl_fontsize->listbase = glGenLists(256);
+    aglUseFont(aglGetCurrentContext(), fl_fontsize->font, fl_fontsize->face,
+               fl_fontsize->size, 0, 256, fl_fontsize->listbase);
+#elif defined(__APPLE_QUARTZ__)
+    short font, face, size;
+    uchar fn[256]; 
+    fn[0]=strlen(fl_fontsize->q_name); 
+    strcpy((char*)(fn+1), fl_fontsize->q_name);
+    GetFNum(fn, &font);
+    face = 0;
+    size = fl_fontsize->size;
+    fl_fontsize->listbase = glGenLists(256);
+    aglUseFont(aglGetCurrentContext(), font, face,
+               size, 0, 256, fl_fontsize->listbase);
+#else
+#  if USE_XFT
+    fl_xfont = fl_xxfont();
+#  endif // USE_XFT
+    int base = fl_xfont->min_char_or_byte2;
+    int count = fl_xfont->max_char_or_byte2-base+1;
+    fl_fontsize->listbase = glGenLists(256);
+    glXUseXFont(fl_xfont->fid, base, count, fl_fontsize->listbase+base);
+#endif
+  }
+  glListBase(fl_fontsize->listbase);
+}
+
+
+void gl_remove_displaylist_fonts()
+{
+# if HAVE_GL
+
+  // clear variables used mostly in fl_font
+  fl_font_ = 0;
+  fl_size_ = 0;
+
+  for (int j = 0 ; j < FL_FREE_FONT ; ++j)
+  {
+    Fl_FontSize* past = 0;
+    Fl_Fontdesc* s    = fl_fonts + j ;
+    Fl_FontSize* f    = s->first;
+    while (f != 0) {
+      if(f->listbase) {
+        if(f == s->first) {
+          s->first = f->next;
+        }
+        else {
+          past->next = f->next;
+        }
+
+        // It would be nice if this next line was in a descturctor somewhere
+        glDeleteLists(f->listbase, 256);
+
+        Fl_FontSize* tmp = f;
+        f = f->next;
+        delete tmp;
+      }
+      else {
+        past = f;
+        f = f->next;
+      }
+    }
+  }
+
+#endif
+}
+
+#ifdef __APPLE__
+const char *fl_iso2macRoman(const char*, int);
+#endif
+
+void gl_draw(const char* str, int n) {
+#ifdef __APPLE__
+  const char *txt = fl_iso2macRoman(str, n);
+  glCallLists(n, GL_UNSIGNED_BYTE, txt);
+#else
+  glCallLists(n, GL_UNSIGNED_BYTE, str);
+#endif
+}
+
+void gl_draw(const char* str, int n, int x, int y) {
+  glRasterPos2i(x, y);
+  gl_draw(str, n);
+}
+
+void gl_draw(const char* str, int n, float x, float y) {
+  glRasterPos2f(x, y);
+  gl_draw(str, n);
+}
+
+void gl_draw(const char* str) {
+  gl_draw(str, strlen(str));
+}
+
+void gl_draw(const char* str, int x, int y) {
+  gl_draw(str, strlen(str), x, y);
+}
+
+void gl_draw(const char* str, float x, float y) {
+  gl_draw(str, strlen(str), x, y);
+}
+
+static void gl_draw_invert(const char* str, int n, int x, int y) {
+  glRasterPos2i(x, -y);
+  gl_draw(str, n);
+}
+
+void gl_draw(
+  const char* str, 	// the (multi-line) string
+  int x, int y, int w, int h, 	// bounding box
+  Fl_Align align) {
+  fl_draw(str, x, -y-h, w, h, align, gl_draw_invert);
+}
+
+void gl_measure(const char* str, int& x, int& y) {fl_measure(str,x,y);}
+
+void gl_rect(int x, int y, int w, int h) {
+  if (w < 0) {w = -w; x = x-w;}
+  if (h < 0) {h = -h; y = y-h;}
+  glBegin(GL_LINE_STRIP);
+  glVertex2i(x+w-1, y+h-1);
+  glVertex2i(x+w-1, y);
+  glVertex2i(x, y);
+  glVertex2i(x, y+h-1);
+  glVertex2i(x+w, y+h-1);
+  glEnd();
+}
+
+#if HAVE_GL_OVERLAY
+extern uchar fl_overlay;
+extern int fl_overlay_depth;
+#endif
+
+void gl_color(Fl_Color i) {
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+  if (fl_overlay && fl_overlay_depth) {
+    if (fl_overlay_depth < 8) {
+      // only black & white produce the expected colors.  This could
+      // be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
+      int size = 1<<fl_overlay_depth;
+      if (!i) glIndexi(size-2);
+      else if (i >= size-2) glIndexi(size-1);
+      else glIndexi(i);
+    } else {
+      glIndexi(i ? i : FL_GRAY_RAMP);
+    }    
+    return;
+  }
+#else
+  if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return;}
+#endif
+#endif
+  uchar red, green, blue;
+  Fl::get_color(i, red, green, blue);
+  glColor3ub(red, green, blue);
+}
+  
+void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
+  if (!ld) ld = w*d;
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, ld/d);
+  glRasterPos2i(x,y);
+  glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/gl_start.cxx b/Utilities/FLTK/src/gl_start.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8714d2fea3347c416ed7d207cc22ea0890aae283
--- /dev/null
+++ b/Utilities/FLTK/src/gl_start.cxx
@@ -0,0 +1,136 @@
+//
+// "$Id$"
+//
+// OpenGL context routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// You MUST use gl_visual() to select the default visual before doing
+// show() of any windows.  Mesa will crash if you try to use a visual
+// not returned by glxChooseVisual.
+
+// This does not work with Fl_Double_Window's!  It will try to draw
+// into the front buffer.  Depending on the system this will either
+// crash or do nothing (when pixmaps are being used as back buffer
+// and GL is being done by hardware), work correctly (when GL is done
+// with software, such as Mesa), or draw into the front buffer and
+// be erased when the buffers are swapped (when double buffer hardware
+// is being used)
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include "Fl_Gl_Choice.H"
+
+extern int fl_clip_state_number; // in fl_rect.cxx
+
+static GLContext context;
+static int clip_state_number=-1;
+static int pw, ph;
+
+#ifdef WIN32
+static Fl_Gl_Choice* gl_choice;
+#endif
+
+#ifdef __APPLE__
+static Fl_Gl_Choice* gl_choice;
+#endif
+
+Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx
+
+void gl_start() {
+  if (!context) {
+#ifdef WIN32
+    if (!gl_choice) Fl::gl_visual(0);
+    context = fl_create_gl_context(Fl_Window::current(), gl_choice);
+#elif defined(__APPLE_QD__)
+    // \todo Mac : We need to check the code and verify it with Apple Sample code. The 'shiny'-test should at least work with the software OpenGL emulator
+    context = fl_create_gl_context(Fl_Window::current(), gl_choice);
+#elif defined(__APPLE_QUARTZ__)
+    // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+    context = fl_create_gl_context(Fl_Window::current(), gl_choice);
+#else
+    context = fl_create_gl_context(fl_visual);
+#endif
+  }
+  fl_set_gl_context(Fl_Window::current(), context);
+#if !defined(WIN32) && !defined(__APPLE__)
+  glXWaitX();
+#endif
+  if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) {
+    pw = Fl_Window::current()->w();
+    ph = Fl_Window::current()->h();
+    glLoadIdentity();
+    glViewport(0, 0, pw, ph);
+    glOrtho(0, pw, 0, ph, -1, 1);
+    glDrawBuffer(GL_FRONT);
+  }
+  if (clip_state_number != fl_clip_state_number) {
+    clip_state_number = fl_clip_state_number;
+    int x, y, w, h;
+    if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(),
+		    x, y, w, h)) {
+      fl_clip_region(XRectangleRegion(x,y,w,h));
+      glScissor(x, Fl_Window::current()->h()-(y+h), w, h);
+      glEnable(GL_SCISSOR_TEST);
+    } else {
+      glDisable(GL_SCISSOR_TEST);
+    }
+  }
+}
+
+void gl_finish() {
+  glFlush();
+#if !defined(WIN32) && !defined(__APPLE__)
+  glXWaitGL();
+#endif
+}
+
+int Fl::gl_visual(int mode, int *alist) {
+  Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist);
+  if (!c) return 0;
+#ifdef WIN32
+  gl_choice = c;
+#elif defined(__APPLE_QD__)
+  gl_choice = c;
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  gl_choice = c;
+#else
+  fl_visual = c->vis;
+  fl_colormap = c->colormap;
+#endif
+  return 1;
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/glut_compatability.cxx b/Utilities/FLTK/src/glut_compatability.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2ab4844d1cac68a33718a1a932f303a9bb34a491
--- /dev/null
+++ b/Utilities/FLTK/src/glut_compatability.cxx
@@ -0,0 +1,421 @@
+//
+// "$Id$"
+//
+// GLUT emulation routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Emulation of Glut using fltk.
+
+// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996.
+// "This program is freely distributable without licensing fees  and is
+// provided without guarantee or warrantee expressed or  implied. This
+// program is -not- in the public domain."
+
+// Although I have copied the GLUT API, none of my code is based on
+// any Glut implementation details and is therefore covered by the LGPL.
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#if HAVE_GL
+
+#include <FL/glut.H>
+
+#define MAXWINDOWS 32
+static Fl_Glut_Window *windows[MAXWINDOWS+1];
+
+Fl_Glut_Window *glut_window;
+int glut_menu;
+void (*glut_menustate_function)(int);
+void (*glut_menustatus_function)(int,int,int);
+
+static void default_reshape(int w, int h) {glViewport(0,0,w,h);}
+static void default_display() {}
+
+void Fl_Glut_Window::make_current() {
+  glut_window = this;
+  if (shown()) Fl_Gl_Window::make_current();
+}
+
+static int indraw;
+void Fl_Glut_Window::draw() {
+  glut_window = this;
+  indraw = 1;
+  if (!valid()) {reshape(w(),h()); valid(1);}
+  display();
+  indraw = 0;
+}
+
+void glutSwapBuffers() {
+  if (!indraw) glut_window->swap_buffers();
+}
+
+void Fl_Glut_Window::draw_overlay() {
+  glut_window = this;
+  if (!valid()) {reshape(w(),h()); valid(1);}
+  overlaydisplay();
+}
+
+static void domenu(int, int, int);
+
+int Fl_Glut_Window::handle(int event) {
+  make_current();
+  int ex = Fl::event_x();
+  int ey = Fl::event_y();
+  int button;
+  switch (event) {
+
+  case FL_PUSH:
+    if (keyboard || special) Fl::focus(this);
+    button = Fl::event_button()-1;
+    if (button<0) button = 0;
+    if (button>2) button = 2;
+    if (menu[button]) {domenu(menu[button],ex,ey); return 1;}
+    mouse_down |= 1<<button;
+    if (mouse) {mouse(button,GLUT_DOWN,ex,ey); return 1;}
+    if (motion) return 1;
+    break;
+
+  case FL_MOUSEWHEEL:
+    button = Fl::event_dy();
+    while (button < 0) {mouse(3,GLUT_DOWN,ex,ey); ++button;}
+    while (button > 0) {mouse(4,GLUT_DOWN,ex,ey); --button;}
+    return 1;
+    break;
+
+  case FL_RELEASE:
+    for (button = 0; button < 3; button++) if (mouse_down & (1<<button)) {
+      if (mouse) mouse(button,GLUT_UP,ex,ey);
+    }
+    mouse_down = 0;
+    return 1;
+
+  case FL_ENTER:
+    if (entry) {entry(GLUT_ENTERED); return 1;}
+    if (passivemotion) return 1;
+    break;
+
+  case FL_LEAVE:
+    if (entry) {entry(GLUT_LEFT); return 1;}
+    if (passivemotion) return 1;
+    break;
+
+  case FL_DRAG:
+    if (motion) {motion(ex, ey); return 1;}
+    break;
+
+  case FL_MOVE:
+    if (passivemotion) {passivemotion(ex, ey); return 1;}
+    break;
+
+  case FL_FOCUS:
+    if (keyboard || special) return 1;
+    break;
+
+  case FL_SHORTCUT:
+    if (!keyboard && !special) break;
+
+  case FL_KEYBOARD:
+    if (Fl::event_text()[0]) {
+      if (keyboard) {keyboard(Fl::event_text()[0],ex,ey); return 1;}
+      break;
+    } else {
+      if (special) {
+	int k = Fl::event_key();
+	if (k > FL_F && k <= FL_F_Last) k -= FL_F;
+	special(k,ex,ey);
+	return 1;
+      }
+      break;
+    }
+
+  case FL_HIDE:
+    if (visibility) visibility(GLUT_NOT_VISIBLE);
+    break;
+
+  case FL_SHOW:
+    if (visibility) visibility(GLUT_VISIBLE);
+    break;
+  }
+
+  return Fl_Gl_Window::handle(event);
+}
+
+static int glut_mode = GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
+
+void Fl_Glut_Window::_init() {
+  for (number=1; number<MAXWINDOWS; number++) if (!windows[number]) break;
+  windows[number] = this;
+  menu[0] = menu[1] = menu[2] = 0;
+  reshape = default_reshape;
+  display = default_display;
+  overlaydisplay = default_display;
+  keyboard = 0;
+  mouse = 0;
+  motion = 0;
+  passivemotion = 0;
+  entry = 0;
+  visibility = 0;
+  special = 0;
+  mouse_down = 0;
+  mode(glut_mode);
+}
+
+Fl_Glut_Window::Fl_Glut_Window(int W, int H, const char *t) :
+  Fl_Gl_Window(W,H,t) {_init();}
+
+Fl_Glut_Window::Fl_Glut_Window(int X,int Y,int W,int H, const char *t) :
+  Fl_Gl_Window(X,Y,W,H,t) {_init();}
+
+static int initargc;
+static char **initargv;
+
+void glutInit(int *argc, char **argv) {
+  initargc = *argc;
+  initargv = new char*[*argc+1];
+  int i,j;
+  for (i=0; i<=*argc; i++) initargv[i] = argv[i];
+  for (i=j=1; i<*argc; ) {
+    if (Fl::arg(*argc,argv,i));
+    else argv[j++] = argv[i++];
+  }
+  argv[j] = 0;
+  *argc = j;
+}
+
+void glutInitDisplayMode(unsigned int mode) {
+  glut_mode = mode;
+}
+
+void glutMainLoop() {Fl::run();}
+
+////////////////////////////////////////////////////////////////
+
+static int initx, inity, initw=300, inith=300, initpos;
+
+void glutInitWindowPosition(int x, int y) {
+  initx = x; inity = y; initpos = 1;
+}
+
+void glutInitWindowSize(int w, int h) {
+  initw = w; inith = h;
+}
+
+int glutCreateWindow(char *title) {
+  Fl_Glut_Window *W;
+  if (initpos) {
+    W = new Fl_Glut_Window(initx,inity,initw,inith,title);
+    initpos = 0;
+  } else {
+    W = new Fl_Glut_Window(initw,inith,title);
+  }
+  W->resizable(W);
+  if (initargc) {
+    W->show(initargc,initargv);
+    initargc = 0;
+  } else {
+    W->show();
+  }
+  W->make_current();
+  return W->number;
+}
+
+int glutCreateSubWindow(int win, int x, int y, int w, int h) {
+  Fl_Glut_Window *W = new Fl_Glut_Window(x,y,w,h,0);
+  windows[win]->add(W);
+  if (windows[win]->shown()) W->show();
+  W->make_current();
+  return W->number;
+}
+
+Fl_Glut_Window::~Fl_Glut_Window() {
+  if (glut_window == this) glut_window = 0;
+  windows[number] = 0;
+}
+
+void glutDestroyWindow(int win) {
+  // should destroy children!!!
+  delete windows[win];
+}
+
+void glutSetWindow(int win) {
+  windows[win]->make_current();
+}
+
+////////////////////////////////////////////////////////////////
+#include <FL/Fl_Menu_Item.H>
+
+struct menu {
+  void (*cb)(int);
+  Fl_Menu_Item *m;
+  int size;
+  int alloc;
+};
+
+#define MAXMENUS 32
+static menu menus[MAXMENUS+1];
+
+static void domenu(int n, int ex, int ey) {
+  glut_menu = n;
+  menu *m = &menus[n];
+  if (glut_menustate_function) glut_menustate_function(1);
+  if (glut_menustatus_function) glut_menustatus_function(1,ex,ey);
+  const Fl_Menu_Item* g = m->m->popup(Fl::event_x(), Fl::event_y(), 0);
+  if (g && g->callback_) ((void (*)(int))(g->callback_))(int(g->argument()));
+  if (glut_menustatus_function) glut_menustatus_function(0,ex,ey);
+  if (glut_menustate_function) glut_menustate_function(0);
+}
+
+int glutCreateMenu(void (*cb)(int)) {
+  int i;
+  for (i=1; i<MAXMENUS; i++) if (!menus[i].cb) break;
+  menu *m = &menus[i];
+  m->cb = cb;
+  return glut_menu = i;
+}
+
+void glutDestroyMenu(int n) {
+  menu *m = &menus[n];
+  delete[] m->m;
+  m->m = 0;
+  m->cb = 0;
+  m->size = m->alloc = 0;
+}
+
+static Fl_Menu_Item* additem(menu *m) {
+  if (m->size+1 >= m->alloc) {
+    m->alloc = m->size*2+10;
+    Fl_Menu_Item* nm = new Fl_Menu_Item[m->alloc];
+    for (int i=0; i<m->size; i++) nm[i] = m->m[i];
+    delete[] m->m;
+    m->m = nm;
+  }
+  int n = m->size++;
+  m->m[n+1].text = 0;
+  Fl_Menu_Item* i = &(m->m[n]);
+  i->shortcut_ = 0;
+  i->flags = 0;
+  i->labeltype_ = i->labelfont_ = i->labelsize_ = i->labelcolor_ = 0;
+  return i;
+}
+
+void glutAddMenuEntry(char *label, int value) {
+  menu *m = &menus[glut_menu];
+  Fl_Menu_Item* i = additem(m);
+  i->text = label;
+  i->callback_ = (Fl_Callback*)(m->cb);
+  i->user_data_ = (void *)value;
+}
+
+void glutAddSubMenu(char *label, int submenu) {
+  menu *m = &menus[glut_menu];
+  Fl_Menu_Item* i = additem(m);
+  i->text = label;
+  i->callback_ = 0;
+  i->user_data_ = (void *)(menus[submenu].m);
+  i->flags = FL_PUP_SUBMENU;
+}
+
+void glutChangeToMenuEntry(int item, char *label, int value) {
+  menu *m = &menus[glut_menu];
+  Fl_Menu_Item* i = &m->m[item-1];
+  i->text = label;
+  i->callback_ = (Fl_Callback*)(m->cb);
+  i->user_data_ = (void *)value;
+  i->flags = 0;
+}
+
+void glutChangeToSubMenu(int item, char *label, int submenu) {
+  menu *m = &menus[glut_menu];
+  Fl_Menu_Item* i = &m->m[item-1];
+  i->text = label;
+  i->callback_ = 0;
+  i->user_data_ = (void *)(menus[submenu].m);
+  i->flags = FL_PUP_SUBMENU;
+}
+
+void glutRemoveMenuItem(int item) {
+  menu *m = &menus[glut_menu];
+  if (item > m->size || item < 1) return;
+  for (int i = item-1; i <= m->size; i++) m->m[i] = m->m[i+1];
+  m->size--;
+}
+
+////////////////////////////////////////////////////////////////
+
+int glutGet(GLenum type) {
+  switch (type) {
+  case GLUT_RETURN_ZERO: return 0;
+  case GLUT_WINDOW_X: return glut_window->x();
+  case GLUT_WINDOW_Y: return glut_window->y();
+  case GLUT_WINDOW_WIDTH: return glut_window->w();
+  case GLUT_WINDOW_HEIGHT: return glut_window->h();
+  case GLUT_WINDOW_PARENT:
+    if (glut_window->parent())
+      return ((Fl_Glut_Window *)(glut_window->parent()))->number;
+    else
+      return 0;
+//case GLUT_WINDOW_NUM_CHILDREN:
+//case GLUT_WINDOW_CURSOR: return 
+  case GLUT_SCREEN_WIDTH: return Fl::w();
+  case GLUT_SCREEN_HEIGHT: return Fl::h();
+//case GLUT_SCREEN_WIDTH_MM:
+//case GLUT_SCREEN_HEIGHT_MM:
+  case GLUT_MENU_NUM_ITEMS: return menus[glut_menu].size;
+  case GLUT_DISPLAY_MODE_POSSIBLE: return Fl_Gl_Window::can_do(glut_mode);
+  case GLUT_INIT_WINDOW_X: return initx;
+  case GLUT_INIT_WINDOW_Y: return inity;
+  case GLUT_INIT_WINDOW_WIDTH: return initw;
+  case GLUT_INIT_WINDOW_HEIGHT: return inith;
+  case GLUT_INIT_DISPLAY_MODE: return glut_mode;
+//case GLUT_ELAPSED_TIME:
+  case GLUT_WINDOW_BUFFER_SIZE:
+    if (glutGet(GLUT_WINDOW_RGBA))
+      return glutGet(GLUT_WINDOW_RED_SIZE)+
+	glutGet(GLUT_WINDOW_GREEN_SIZE)+
+	glutGet(GLUT_WINDOW_BLUE_SIZE)+
+	glutGet(GLUT_WINDOW_ALPHA_SIZE);
+    else
+      return glutGet(GLUT_WINDOW_COLORMAP_SIZE);
+  default: {GLint p; glGetIntegerv(type, &p); return p;}
+  }
+}
+
+int glutLayerGet(GLenum type) {
+  switch (type) {
+  case GLUT_OVERLAY_POSSIBLE: return glut_window->can_do_overlay();
+//case GLUT_LAYER_IN_USE:
+//case GLUT_HAS_OVERLAY:
+  case GLUT_TRANSPARENT_INDEX: return 0; // true for SGI
+  case GLUT_NORMAL_DAMAGED: return glut_window->damage();
+  case GLUT_OVERLAY_DAMAGED: return 1; // kind of works...
+  default: return 0;
+  }
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/glut_font.cxx b/Utilities/FLTK/src/glut_font.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d5662dca3737e9568dff7096934de004bdbf41aa
--- /dev/null
+++ b/Utilities/FLTK/src/glut_font.cxx
@@ -0,0 +1,62 @@
+//
+// "$Id$"
+//
+// GLUT bitmap font routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// (sort of) emulation of Glut's bitmap drawing functions, using FL's
+// font stuff.  Not all the fonts match!
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#if HAVE_GL
+
+#include <FL/glut.H>
+#include <FL/gl.h>
+
+Glut_Bitmap_Font glutBitmap9By15 = {FL_SCREEN, 15};
+Glut_Bitmap_Font glutBitmap8By13 = {FL_SCREEN, 13};
+Glut_Bitmap_Font glutBitmapTimesRoman10 = {FL_TIMES, 10};
+Glut_Bitmap_Font glutBitmapTimesRoman24 = {FL_TIMES, 24};
+Glut_Bitmap_Font glutBitmapHelvetica10 = {FL_HELVETICA, 10};
+Glut_Bitmap_Font glutBitmapHelvetica12 = {FL_HELVETICA, 12};
+Glut_Bitmap_Font glutBitmapHelvetica18 = {FL_HELVETICA, 18};
+
+void glutBitmapCharacter(void* font, int character) {
+  gl_font(((Glut_Bitmap_Font *)font)->font,((Glut_Bitmap_Font *)font)->size);
+  char a[1]; a[0] = character;
+  gl_draw(a,1);
+}
+
+int glutBitmapWidth(void* font, int character) {
+  gl_font(((Glut_Bitmap_Font *)font)->font,((Glut_Bitmap_Font *)font)->size);
+  return int(gl_width(character)+.5);
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/makefile.wat b/Utilities/FLTK/src/makefile.wat
new file mode 100644
index 0000000000000000000000000000000000000000..6266889eb6bccab226662c6ef946795f136328d7
--- /dev/null
+++ b/Utilities/FLTK/src/makefile.wat
@@ -0,0 +1,226 @@
+#
+# "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $"
+#
+# Library makefile for the Fast Light Tool Kit (FLTK).
+#
+# Copyright 1998-2004 by Bill Spitzak and others.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+CPPFILES = &
+    Fl.obj &
+    Fl_Adjuster.obj &
+    Fl_Bitmap.obj &
+    Fl_Browser.obj &
+    Fl_Browser_.obj &
+    Fl_Browser_load.obj &
+    Fl_Box.obj &
+    Fl_Button.obj &
+    Fl_Chart.obj &
+    Fl_Check_Browser.obj &
+    Fl_Check_Button.obj &
+    Fl_Choice.obj &
+    Fl_Clock.obj &
+    Fl_Color_Chooser.obj &
+    Fl_Counter.obj &
+    Fl_Dial.obj &
+    Fl_Double_Window.obj &
+    Fl_File_Browser.obj &
+    Fl_File_Chooser.obj &
+    Fl_File_Chooser2.obj &
+    Fl_File_Icon.obj &
+    Fl_File_Input.obj &
+    Fl_Group.obj &
+    Fl_Help_View.obj &
+    Fl_Image.obj &
+    Fl_Input.obj &
+    Fl_Input_.obj &
+    Fl_Light_Button.obj &
+    Fl_Menu.obj &
+    Fl_Menu_.obj &
+    Fl_Menu_Bar.obj &
+    Fl_Sys_Menu_Bar.obj &
+    Fl_Menu_Button.obj &
+    Fl_Menu_Window.obj &
+    Fl_Menu_add.obj &
+    Fl_Menu_global.obj &
+    Fl_Multi_Label.obj &
+    Fl_Overlay_Window.obj &
+    Fl_Pack.obj &
+    Fl_Pixmap.obj &
+    Fl_Positioner.obj &
+    Fl_Preferences.obj &
+    Fl_Progress.obj &
+    Fl_Repeat_Button.obj &
+    Fl_Return_Button.obj &
+    Fl_Roller.obj &
+    Fl_Round_Button.obj &
+    Fl_Scroll.obj &
+    Fl_Scrollbar.obj &
+    Fl_Shared_Image.obj &
+    Fl_Single_Window.obj &
+    Fl_Slider.obj &
+    Fl_Tabs.obj &
+    Fl_Text_Buffer.obj &
+    Fl_Text_Display.obj &
+    Fl_Text_Editor.obj &
+    Fl_Tile.obj &
+    Fl_Tiled_Image.obj &
+    Fl_Tooltip.obj &
+    Fl_Valuator.obj &
+    Fl_Value_Input.obj &
+    Fl_Value_Output.obj &
+    Fl_Value_Slider.obj &
+    Fl_Widget.obj &
+    Fl_Window.obj &
+    Fl_Window_fullscreen.obj &
+    Fl_Window_hotspot.obj &
+    Fl_Window_iconize.obj &
+    Fl_Wizard.obj &
+    Fl_XBM_Image.obj &
+    Fl_XPM_Image.obj &
+    Fl_abort.obj &
+    Fl_add_idle.obj &
+    Fl_arg.obj &
+    Fl_compose.obj &
+    Fl_display.obj &
+    Fl_get_key.obj &
+    Fl_get_system_colors.obj &
+    Fl_grab.obj &
+    Fl_lock.obj &
+    Fl_own_colormap.obj &
+    Fl_visual.obj &
+    Fl_x.obj &
+    filename_absolute.obj &
+    filename_expand.obj &
+    filename_ext.obj &
+    filename_isdir.obj &
+    filename_list.obj &
+    filename_match.obj &
+    filename_setext.obj &
+    fl_arc.obj &
+    fl_arci.obj &
+    fl_ask.obj &
+    fl_boxtype.obj &
+    fl_color.obj &
+    fl_cursor.obj &
+    fl_curve.obj &
+    fl_diamond_box.obj &
+    fl_dnd.obj &
+    fl_draw.obj &
+    fl_draw_image.obj &
+    fl_draw_pixmap.obj &
+    fl_engraved_label.obj &
+    fl_file_dir.obj &
+    fl_font.obj &
+    fl_labeltype.obj &
+    fl_line_style.obj &
+    fl_oval_box.obj &
+    fl_overlay.obj &
+    fl_overlay_visual.obj &
+    fl_plastic.obj &
+    fl_read_image.obj &
+    fl_rect.obj &
+    fl_round_box.obj &
+    fl_rounded_box.obj &
+    fl_set_font.obj &
+    fl_set_fonts.obj &
+    fl_scroll_area.obj &
+    fl_shadow_box.obj &
+    fl_shortcut.obj &
+    fl_show_colormap.obj &
+    fl_symbols.obj &
+    fl_vertex.obj
+
+FLCPPFILES = &
+    forms_compatability.obj &
+    forms_bitmap.obj &
+    forms_free.obj &
+    forms_fselect.obj &
+    forms_pixmap.obj &
+    forms_timer.obj
+
+GLCPPFILES = &
+    Fl_Gl_Choice.obj &
+    Fl_Gl_Overlay.obj &
+    Fl_Gl_Window.obj &
+    gl_draw.obj &
+    gl_start.obj &
+    glut_compatability.obj &
+    glut_font.obj
+
+IMGCPPFILES = &
+    fl_images_core.obj &
+    Fl_BMP_Image.obj &
+    Fl_File_Icon2.obj &
+    Fl_GIF_Image.obj &
+    Fl_Help_Dialog.obj &
+    Fl_JPEG_Image.obj &
+    Fl_PNG_Image.obj &
+    Fl_PNM_Image.obj
+
+CFILES = fl_call_main.obj flstring.obj scandir.obj numericsort.obj vsnprintf.obj
+
+################################################################
+
+!include ../watcom.mif
+
+OBJECTS = $(CPPFILES) $(CFILES)
+FLOBJECTS = $(FLCPPFILES)
+GLOBJECTS = $(GLCPPFILES)
+IMGOBJECTS = $(IMGCPPFILES)
+
+# The four basic fltk libraries are defined in ../watcom.mif, so that appliactions
+# can also use them.
+all: $(LIBNAME) &
+     $(LIBNAMEFL) &
+     $(LIBNAMEGL) &
+     $(LIBNAMEIMG)
+
+# $(DSONAME) &
+# $(FLDSONAME) &
+# $(GLDSONAME) &
+# $(IMGDSONAME)
+
+
+$(LIBNAME): $(OBJECTS)
+    $(LIB) $(LIBOPTS) $@ $<
+
+$(LIBNAMEFL): $(FLOBJECTS)
+    $(LIB) $(LIBOPTS) $@ $<
+
+$(LIBNAMEGL): $(GLOBJECTS)
+    $(LIB) $(LIBOPTS) $@ $<
+
+$(LIBNAMEIMG): $(IMGOBJECTS)
+    $(LIB) $(LIBOPTS) $@ $<
+
+#
+# Clean all directories
+#
+clean : .SYMBOLIC
+    @echo Cleaning up.
+CLEANEXTS = exe map sym obj lk1
+    @for %a in ($(CLEANEXTS)) do -rm -f $(ODIR)\*.%a
+    -rm -f *.err
+    -rm -f $(LIBNAME)
+    -rm -f $(LIBNAMEFL)
+    -rm -f $(LIBNAMEGL)
+    -rm -f $(LIBNAMEIMG)
+
diff --git a/Utilities/FLTK/src/mediumarrow.h b/Utilities/FLTK/src/mediumarrow.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a1fe8cbcf77ae035e34351540729a44c7d3c408
--- /dev/null
+++ b/Utilities/FLTK/src/mediumarrow.h
@@ -0,0 +1,6 @@
+#define mediumarrow_width 16
+#define mediumarrow_height 16
+static unsigned char mediumarrow_bits[] = {
+   0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0xfc, 0x3f, 0x78, 0x00,
+   0x70, 0x00, 0x60, 0x02, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0xfc, 0x3f,
+   0x00, 0x1e, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x02};
diff --git a/Utilities/FLTK/src/new.xbm b/Utilities/FLTK/src/new.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..25a56c5939ef52d6b028224e3ecae6f3df487395
--- /dev/null
+++ b/Utilities/FLTK/src/new.xbm
@@ -0,0 +1,6 @@
+#define new_width 16
+#define new_height 16
+static unsigned char new_bits[] = {
+   0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x01, 0xfe, 0x01, 0x80,
+   0x31, 0x80, 0x31, 0x80, 0xfd, 0x80, 0xfd, 0x80, 0x31, 0x80, 0x31, 0x80,
+   0x01, 0x80, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/ns.xbm b/Utilities/FLTK/src/ns.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..f1ea18e1b47ba8d80771f4a6e23716cf454762d8
--- /dev/null
+++ b/Utilities/FLTK/src/ns.xbm
@@ -0,0 +1,8 @@
+#define ns_width 16
+#define ns_height 16
+#define ns_x_hot 8
+#define ns_y_hot 8
+static unsigned char ns_bits[] = {
+   0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
+   0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+   0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/ns_mask.xbm b/Utilities/FLTK/src/ns_mask.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..a69f261bb43ac9302a526d7ebb17c453aedb8c2c
--- /dev/null
+++ b/Utilities/FLTK/src/ns_mask.xbm
@@ -0,0 +1,8 @@
+#define ns_mask_width 16
+#define ns_mask_height 16
+#define ns_mask_x_hot 8
+#define ns_mask_y_hot 8
+static unsigned char ns_mask_bits[] = {
+   0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
+   0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
+   0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01};
diff --git a/Utilities/FLTK/src/numericsort.c b/Utilities/FLTK/src/numericsort.c
new file mode 100644
index 0000000000000000000000000000000000000000..95e878100c0592a777305fe20182fceb7258809f
--- /dev/null
+++ b/Utilities/FLTK/src/numericsort.c
@@ -0,0 +1,112 @@
+/*
+ * "$Id$"
+ *
+ * Numeric sorting routine for the Fast Light Tool Kit (FLTK).
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+/* My own scandir sorting function, useful for the film industry where
+   we have many files with numbers in their names: */
+
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <FL/filename.H>
+
+#if !defined(WIN32) || defined(__CYGWIN__)
+#  ifdef HAVE_DIRENT_H
+#    include <dirent.h>
+#  else
+#    define dirent direct
+#    if HAVE_SYS_NDIR_H
+#      include <sys/ndir.h>
+#    endif /* HAVE_SYS_NDIR_H */
+#    if HAVE_SYS_DIR_H
+#      include <sys/dir.h>
+#    endif /* HAVE_SYS_DIR_H */
+#    if HAVE_NDIR_H
+#      include <ndir.h>
+#    endif /* HAVE_NDIR_H */
+#  endif /* HAVE_DIRENT_H */
+#endif /* !WIN32 || __CYGWIN__ */
+
+/*
+ * 'numericsort()' - Compare two directory entries, possibly with
+ *                   a case-insensitive comparison...
+ */
+
+static int numericsort(struct dirent **A, struct dirent **B, int cs) {
+  const char* a = (*A)->d_name;
+  const char* b = (*B)->d_name;
+  int ret = 0;
+  for (;;) {
+    if (isdigit(*a & 255) && isdigit(*b & 255)) {
+      int diff,magdiff;
+      while (*a == '0') a++;
+      while (*b == '0') b++;
+      while (isdigit(*a & 255) && *a == *b) {a++; b++;}
+      diff = (isdigit(*a & 255) && isdigit(*b & 255)) ? *a - *b : 0;
+      magdiff = 0;
+      while (isdigit(*a & 255)) {magdiff++; a++;}
+      while (isdigit(*b & 255)) {magdiff--; b++;}
+      if (magdiff) {ret = magdiff; break;} /* compare # of significant digits*/
+      if (diff) {ret = diff; break;}	/* compare first non-zero digit */
+    } else {
+      if (cs) {
+      	/* compare case-sensitive */
+	if ((ret = *a-*b)) break;
+      } else {
+	/* compare case-insensitve */
+	if ((ret = tolower(*a & 255)-tolower(*b & 255))) break;
+      }
+
+      if (!*a) break;
+      a++; b++;
+    }
+  }
+  if (!ret) return 0;
+  else return (ret < 0) ? -1 : 1;
+}
+
+/*
+ * 'fl_casenumericsort()' - Compare directory entries with case-sensitivity.
+ */
+
+int fl_casenumericsort(struct dirent **A, struct dirent **B) {
+  return numericsort(A, B, 0);
+}
+
+/*
+ * 'fl_numericsort()' - Compare directory entries with case-sensitivity.
+ */
+
+int fl_numericsort(struct dirent **A, struct dirent **B) {
+  return numericsort(A, B, 1);
+}
+
+/*
+ * End of "$Id$".
+ */
diff --git a/Utilities/FLTK/src/scandir.c b/Utilities/FLTK/src/scandir.c
new file mode 100644
index 0000000000000000000000000000000000000000..197f63fd6c5e9c89992b98fad032b4aba4ee1832
--- /dev/null
+++ b/Utilities/FLTK/src/scandir.c
@@ -0,0 +1,124 @@
+/* Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+USA.  */
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  include "scandir_win32.c"
+#else
+
+#  include "flstring.h"
+
+#  if !HAVE_SCANDIR
+#    include <stdlib.h>
+#    include <sys/types.h>
+#    include <errno.h>
+
+#    if HAVE_DIRENT_H
+#      include <dirent.h>
+#      define NAMLEN(dirent) strlen((dirent)->d_name)
+#    else
+#      define dirent direct
+#      define NAMLEN(dirent) (dirent)->d_namlen
+#      if HAVE_SYS_NDIR_H
+#        include <sys/ndir.h>
+#      endif
+#      if HAVE_SYS_DIR_H
+#        include <sys/dir.h>
+#      endif
+#      if HAVE_NDIR_H
+#        include <ndir.h>
+#      endif
+#    endif
+
+int
+fl_scandir(const char *dir, struct dirent ***namelist,
+	   int (*select)(struct dirent *),
+	   int (*compar)(struct dirent **, struct dirent **))
+{
+  DIR *dp = opendir (dir);
+  struct dirent **v = NULL;
+  size_t vsize = 0, i;
+  struct dirent *d;
+  int save;
+
+  if (dp == NULL)
+    return -1;
+
+  save = errno;
+  errno = 0;
+
+  i = 0;
+  while ((d = readdir (dp)) != NULL)
+    if (select == NULL || (*select) (d))
+      {
+      size_t dsize;
+
+      if (i == vsize)
+        {
+          struct dirent **newv;
+          if (vsize == 0)
+            vsize = 10;
+          else
+            vsize *= 2;
+          newv = (struct dirent **) realloc (v, vsize * sizeof (*v));
+          if (newv == NULL)
+            {
+            lose:
+              errno = ENOMEM;
+              break;
+            }
+          v = newv;
+        }
+
+#    define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name))
+#    define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \
+                              _D_EXACT_NAMLEN (d) + 1)
+
+      dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
+      v[i] = (struct dirent *) malloc (dsize);
+      if (v[i] == NULL)
+        goto lose;
+
+      memcpy (v[i++], d, dsize);
+      }
+
+  if (errno != 0)
+    {
+      save = errno;
+      (void) closedir (dp);
+      while (i > 0)
+      free (v[--i]);
+      free (v);
+      errno = save;
+      return -1;
+    }
+
+  (void) closedir (dp);
+  errno = save;
+
+  /* Sort the list if we have a comparison function to sort with.  */
+  if (compar) qsort (v, i, sizeof (*v), (int (*)(const void *, const void *))compar);
+  *namelist = v;
+  return i;
+}
+
+#  endif
+#endif
+
+/*
+ * End of "$Id$".
+ */
diff --git a/Utilities/FLTK/src/scandir_win32.c b/Utilities/FLTK/src/scandir_win32.c
new file mode 100644
index 0000000000000000000000000000000000000000..00d0b8e6a7b569e80acc109d8af36e3454b2751e
--- /dev/null
+++ b/Utilities/FLTK/src/scandir_win32.c
@@ -0,0 +1,115 @@
+/*
+ * "$Id$"
+ *
+ * WIN32 scandir function for the Fast Light Tool Kit (FLTK).
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+#ifndef __CYGWIN__
+/* Emulation of posix scandir() call */
+
+#include <FL/filename.H>
+#include "flstring.h"
+#include <windows.h>
+#include <stdlib.h>
+
+int fl_scandir(const char *dirname, struct dirent ***namelist,
+	       int (*select)(struct dirent *),
+	       int (*compar)(struct dirent **, struct dirent **)) {
+  int len;
+  char *findIn, *d, is_dir = 0;
+  WIN32_FIND_DATA find;
+  HANDLE h;
+  int nDir = 0, NDir = 0;
+  struct dirent **dir = 0, *selectDir;
+  unsigned long ret;
+
+  len    = strlen(dirname);
+  findIn = (char *)malloc((size_t)(len+5));
+
+  if (!findIn) return -1;
+
+  strcpy(findIn, dirname);
+  for (d = findIn; *d; d++) if (*d=='/') *d='\\';
+  if ((len==0)) { strcpy(findIn, ".\\*"); }
+  if ((len==2)&&findIn[1]==':'&&isalpha(findIn[0])) { *d++ = '\\'; *d = 0; }
+  if ((len==1)&& (d[-1]=='.')) { strcpy(findIn, ".\\*"); is_dir = 1; }
+  if ((len>0) && (d[-1]=='\\')) { *d++ = '*'; *d = 0; is_dir = 1; }
+  if ((len>1) && (d[-1]=='.') && (d[-2]=='\\')) { d[-1] = '*'; is_dir = 1; }
+  if (!is_dir) { /* this file may still be a directory that we need to list */
+    DWORD attr = GetFileAttributes(findIn);
+    if (attr&FILE_ATTRIBUTE_DIRECTORY) 
+      strcpy(d, "\\*");
+  }
+  if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE) {
+    free(findIn);
+    ret = GetLastError();
+    if (ret != ERROR_NO_MORE_FILES) {
+      nDir = -1;
+    }
+    *namelist = dir;
+    return nDir;
+  }
+  do {
+    selectDir=(struct dirent*)malloc(sizeof(struct dirent)+strlen(find.cFileName)+2);
+    strcpy(selectDir->d_name, find.cFileName);
+    if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+      /* Append a trailing slash to directory names... */
+      strcat(selectDir->d_name, "/");
+    }
+    if (!select || (*select)(selectDir)) {
+      if (nDir==NDir) {
+	struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), (size_t)(NDir+33));
+	if (NDir) memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
+	if (dir) free(dir);
+	dir = tempDir;
+	NDir += 32;
+      }
+      dir[nDir] = selectDir;
+      nDir++;
+      dir[nDir] = 0;
+    } else {
+      free(selectDir);
+    }
+  } while (FindNextFile(h, &find));
+  ret = GetLastError();
+  if (ret != ERROR_NO_MORE_FILES) {
+    /* don't return an error code, because the dir list may still be valid
+       up to this point */ 
+  }
+  FindClose(h);
+
+  free (findIn);
+
+  if (compar) qsort(dir, (size_t)nDir, sizeof(*dir),
+		    (int(*)(const void*, const void*))compar);
+
+  *namelist = dir;
+  return nDir;
+}
+
+#endif
+
+/*
+ * End of "$Id$".
+ */
diff --git a/Utilities/FLTK/src/screen_xywh.cxx b/Utilities/FLTK/src/screen_xywh.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6ee7136ab461a8fde95899df884f9f0fa2b26272
--- /dev/null
+++ b/Utilities/FLTK/src/screen_xywh.cxx
@@ -0,0 +1,242 @@
+//
+// "$Id$"
+//
+// Screen/monitor bounding box API for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+/*OTB Modifications: conflict name with OTB/Utilities/ITK/Utilities/nifti/znzlib/config.h*/
+/*#include <config.h>*/
+#include "fltk-config.h"
+
+// Number of screens...
+static int num_screens = 0;
+
+#ifdef WIN32
+#  if !defined(HMONITOR_DECLARED) && (_WIN32_WINNT < 0x0500)
+#    define COMPILE_MULTIMON_STUBS
+#    include <multimon.h>
+#  endif // !HMONITOR_DECLARED && _WIN32_WINNT < 0x0500
+
+// BOOL EnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM)
+typedef BOOL (*fl_edm_func)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
+// BOOL GetMonitorInfo(HMONITOR, LPMONITORINFO)
+typedef BOOL (*fl_gmi_func)(HMONITOR, LPMONITORINFO);
+
+static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorInfoA
+
+static RECT screens[16];
+
+static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT, LPARAM) {
+  if (num_screens >= 16) return TRUE;
+
+  MONITORINFO mi;
+  mi.cbSize = sizeof(mi);
+
+//  GetMonitorInfo(mon, &mi);
+  fl_gmi(mon, &mi);
+
+  screens[num_screens] = mi.rcWork;
+  num_screens ++;
+  return TRUE;
+}
+
+static void screen_init() {
+  // Since not all versions of Windows include multiple monitor support,
+  // we do a run-time check for the required functions...
+  HMODULE hMod = GetModuleHandle("USER32.DLL");
+
+  if (hMod) {
+    // check that EnumDisplayMonitors is available
+    fl_edm_func fl_edm = (fl_edm_func)GetProcAddress(hMod, "EnumDisplayMonitors");
+
+    if (fl_edm) {
+      // We do have EnumDisplayMonitors, so lets find out how many monitors...
+      num_screens = GetSystemMetrics(SM_CMONITORS);
+
+      if (num_screens > 1) {
+        // If there is more than 1 monitor, enumerate them...
+        fl_gmi = (fl_gmi_func)GetProcAddress(hMod, "GetMonitorInfoA");
+
+        if (fl_gmi) {
+          // We have GetMonitorInfoA, enumerate all the screens...
+          num_screens = 0;
+//        EnumDisplayMonitors(0,0,screen_cb,0);
+          fl_edm(0, 0, screen_cb, 0);
+          return;
+        }
+      }
+    }
+  }
+
+  // If we get here, assume we have 1 monitor...
+  num_screens = 1;
+}
+#elif defined(__APPLE__)
+XRectangle screens[16];
+
+static void screen_init() {
+  GDHandle gd;
+
+  for (gd = GetDeviceList(), num_screens = 0; gd; gd = GetNextDevice(gd)) {
+    GDPtr gp = *gd;
+    screens[num_screens].x      = gp->gdRect.left;
+    screens[num_screens].y      = gp->gdRect.top;
+    screens[num_screens].width  = gp->gdRect.right - gp->gdRect.left;
+    screens[num_screens].height = gp->gdRect.bottom - gp->gdRect.top;
+
+    num_screens ++;
+    if (num_screens >= 16) break;
+  }
+}
+#elif HAVE_XINERAMA
+#  include <X11/extensions/Xinerama.h>
+
+// Screen data...
+static XineramaScreenInfo *screens;
+
+static void screen_init() {
+  if (!fl_display) fl_open_display();
+
+  if (XineramaIsActive(fl_display)) {
+    screens = XineramaQueryScreens(fl_display, &num_screens);
+  } else num_screens = 1;
+}
+#else
+static void screen_init() {
+  num_screens = 1;
+}
+#endif // WIN32
+
+
+// Return the number of screens...
+int Fl::screen_count() {
+  if (!num_screens) screen_init();
+
+  return num_screens;
+}
+
+// Return the screen bounding rect for the given mouse position...
+void Fl::screen_xywh(int &x, int &y, int &w, int &h, int mx, int my) {
+  if (!num_screens) screen_init();
+
+#ifdef WIN32
+  if (num_screens > 1) {
+    int i;
+
+    for (i = 0; i < num_screens; i ++) {
+      if (mx >= screens[i].left && mx < screens[i].right &&
+	  my >= screens[i].top && my < screens[i].bottom) {
+	x = screens[i].left;
+	y = screens[i].top;
+	w = screens[i].right - screens[i].left;
+	h = screens[i].bottom - screens[i].top;
+	return;
+      }
+    }
+  }
+#elif defined(__APPLE__)
+  if (num_screens > 1) {
+    int i;
+
+    for (i = 0; i < num_screens; i ++) {
+      if (mx >= screens[i].x &&
+	  mx < (screens[i].x + screens[i].width) &&
+	  my >= screens[i].y &&
+	  my < (screens[i].y + screens[i].height)) {
+	x = screens[i].x;
+	y = screens[i].y;
+	w = screens[i].width;
+	h = screens[i].height;
+	return;
+      }
+    }
+  }
+#elif HAVE_XINERAMA
+  if (num_screens > 1) {
+    int i;
+
+    for (i = 0; i < num_screens; i ++) {
+      if (mx >= screens[i].x_org &&
+	  mx < (screens[i].x_org + screens[i].width) &&
+	  my >= screens[i].y_org &&
+	  my < (screens[i].y_org + screens[i].height)) {
+	x = screens[i].x_org;
+	y = screens[i].y_org;
+	w = screens[i].width;
+	h = screens[i].height;
+	return;
+      }
+    }
+  }
+#endif // WIN32
+
+  x = Fl::x();
+  y = Fl::y();
+  w = Fl::w();
+  h = Fl::h();
+}
+
+// Return the screen bounding rect for the given screen...
+void Fl::screen_xywh(int &x, int &y, int &w, int &h, int n) {
+  if (!num_screens) screen_init();
+
+#ifdef WIN32
+  if (num_screens > 1 && n >= 0 && n < num_screens) {
+    x = screens[n].left;
+    y = screens[n].top;
+    w = screens[n].right - screens[n].left;
+    h = screens[n].bottom - screens[n].top;
+    return;
+  }
+#elif defined(__APPLE__)
+  if (num_screens > 1 && n >= 0 && n < num_screens) {
+    x = screens[n].x;
+    y = screens[n].y;
+    w = screens[n].width;
+    h = screens[n].height;
+    return;
+  }
+#elif HAVE_XINERAMA
+  if (num_screens > 1 && n >= 0 && n < num_screens) {
+    x = screens[n].x_org;
+    y = screens[n].y_org;
+    w = screens[n].width;
+    h = screens[n].height;
+    return;
+  }
+#endif // WIN32
+
+  x = Fl::x();
+  y = Fl::y();
+  w = Fl::w();
+  h = Fl::h();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/Utilities/FLTK/src/slowarrow.h b/Utilities/FLTK/src/slowarrow.h
new file mode 100644
index 0000000000000000000000000000000000000000..46a572c97d347daf02012f3ed9216bbfdec38c0b
--- /dev/null
+++ b/Utilities/FLTK/src/slowarrow.h
@@ -0,0 +1,6 @@
+#define slowarrow_width 16
+#define slowarrow_height 16
+static unsigned char slowarrow_bits[] = {
+   0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0xf0, 0x0f, 0x60, 0x00,
+   0x60, 0x00, 0x40, 0x02, 0x40, 0x02, 0x00, 0x06, 0x00, 0x06, 0xf0, 0x0f,
+   0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02};
diff --git a/Utilities/FLTK/src/tile.xpm b/Utilities/FLTK/src/tile.xpm
new file mode 100644
index 0000000000000000000000000000000000000000..872e0f70c5f497452a70e59bef617b98b492c9db
--- /dev/null
+++ b/Utilities/FLTK/src/tile.xpm
@@ -0,0 +1,91 @@
+/* XPM */
+static char	tile_cmap[3][32] = {
+"O c #FFFFFF",
+"o c #EFEFEF",
+". c #E8E8E8"
+};
+static const char * tile_xpm[] = {
+"64 64 3 1",
+tile_cmap[0],
+tile_cmap[1],
+tile_cmap[2],
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
+
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"................................................................",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"};
diff --git a/Utilities/FLTK/src/up.xbm b/Utilities/FLTK/src/up.xbm
new file mode 100644
index 0000000000000000000000000000000000000000..1a4f4b7e7d8e398a600aac2f8bd7d5b94ac622bd
--- /dev/null
+++ b/Utilities/FLTK/src/up.xbm
@@ -0,0 +1,6 @@
+#define up_width 16
+#define up_height 16
+static unsigned char up_bits[] = {
+   0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x31, 0xfe, 0x79, 0x80,
+   0xfd, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80,
+   0x01, 0x80, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00};
diff --git a/Utilities/FLTK/src/vsnprintf.c b/Utilities/FLTK/src/vsnprintf.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d1752b91921e75493501eeb85ffca5574e79588
--- /dev/null
+++ b/Utilities/FLTK/src/vsnprintf.c
@@ -0,0 +1,271 @@
+/*
+ * "$Id$"
+ *
+ * snprintf() and vsnprintf() functions for the Fast Light Tool Kit (FLTK).
+ *
+ * Copyright 1998-2005 by Bill Spitzak and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ *     http://www.fltk.org/str.php
+ */
+
+#include <stdio.h>
+#include "flstring.h"
+
+#ifdef HAVE_SYS_STDTYPES_H
+#  include <sys/stdtypes.h>
+#endif /* HAVE_SYS_STDTYPES_H */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int fl_vsnprintf(char* buffer, size_t bufsize, const char* format, va_list ap) {
+  char		*bufptr,		/* Pointer to position in buffer */
+		*bufend,		/* Pointer to end of buffer */
+		sign,			/* Sign of format width */
+		size,			/* Size character (h, l, L) */
+		type;			/* Format type character */
+  int		width,			/* Width of field */
+		prec;			/* Number of characters of precision */
+  char		tformat[100],		/* Temporary format string for sprintf() */
+		*tptr,			/* Pointer into temporary format */
+		temp[1024];		/* Buffer for formatted numbers */
+  char		*s;			/* Pointer to string */
+  int		slen;			/* Length of string */
+  int		bytes;			/* Total number of bytes needed */
+
+
+ /*
+  * Loop through the format string, formatting as needed...
+  */
+
+  bufptr = buffer;
+  bufend = buffer + bufsize - 1;
+  bytes  = 0;
+
+  while (*format) {
+    if (*format == '%') {
+      tptr = tformat;
+      *tptr++ = *format++;
+
+      if (*format == '%') {
+        if (bufptr && bufptr < bufend) *bufptr++ = *format;
+        bytes ++;
+        format ++;
+	continue;
+      } else if (strchr(" -+#\'", *format)) {
+        *tptr++ = *format;
+        sign = *format++;
+      } else sign = 0;
+
+      if (*format == '*') {
+        /* Get width from argument... */
+	format ++;
+	width = va_arg(ap, int);
+	snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
+	tptr += strlen(tptr);
+      } else {
+	width = 0;
+	while (isdigit(*format & 255)) {
+	  if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
+	  width = width * 10 + *format++ - '0';
+	}
+      }
+
+      if (*format == '.') {
+	if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
+        format ++;
+
+        if (*format == '*') {
+          /* Get precision from argument... */
+	  format ++;
+	  prec = va_arg(ap, int);
+	  snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
+	  tptr += strlen(tptr);
+	} else {
+	  prec = 0;
+	  while (isdigit(*format & 255)) {
+	    if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
+	    prec = prec * 10 + *format++ - '0';
+	  }
+	}
+      } else prec = -1;
+
+      if (*format == 'l' && format[1] == 'l') {
+        size = 'L';
+	if (tptr < (tformat + sizeof(tformat) - 2)) {
+	  *tptr++ = 'l';
+	  *tptr++ = 'l';
+	}
+	format += 2;
+      } else if (*format == 'h' || *format == 'l' || *format == 'L') {
+	if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
+        size = *format++;
+      }
+
+      if (!*format) break;
+
+      if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
+      type  = *format++;
+      *tptr = '\0';
+
+      switch (type) {
+	case 'E' : /* Floating point formats */
+	case 'G' :
+	case 'e' :
+	case 'f' :
+	case 'g' :
+	  if ((width + 2) > sizeof(temp)) break;
+
+	  sprintf(temp, tformat, va_arg(ap, double));
+
+          bytes += strlen(temp);
+
+          if (bufptr) {
+	    if ((bufptr + strlen(temp)) > bufend) {
+	      strncpy(bufptr, temp, (size_t)(bufend - bufptr));
+	      bufptr = bufend;
+	    } else {
+	      strcpy(bufptr, temp);
+	      bufptr += strlen(temp);
+	    }
+	  }
+	  break;
+
+        case 'B' : /* Integer formats */
+	case 'X' :
+	case 'b' :
+        case 'd' :
+	case 'i' :
+	case 'o' :
+	case 'u' :
+	case 'x' :
+	  if ((width + 2) > sizeof(temp)) break;
+
+	  sprintf(temp, tformat, va_arg(ap, int));
+
+          bytes += strlen(temp);
+
+	  if (bufptr) {
+	    if ((bufptr + strlen(temp)) > bufend) {
+	      strncpy(bufptr, temp, (size_t)(bufend - bufptr));
+	      bufptr = bufend;
+	    } else {
+	      strcpy(bufptr, temp);
+	      bufptr += strlen(temp);
+	    }
+	  }
+	  break;
+	    
+	case 'p' : /* Pointer value */
+	  if ((width + 2) > sizeof(temp)) break;
+
+	  sprintf(temp, tformat, va_arg(ap, void *));
+
+          bytes += strlen(temp);
+
+	  if (bufptr) {
+	    if ((bufptr + strlen(temp)) > bufend) {
+	      strncpy(bufptr, temp, (size_t)(bufend - bufptr));
+	      bufptr = bufend;
+	    } else {
+	      strcpy(bufptr, temp);
+	      bufptr += strlen(temp);
+	    }
+	  }
+	  break;
+
+        case 'c' : /* Character or character array */
+	  bytes += width;
+
+	  if (bufptr) {
+	    if (width <= 1) *bufptr++ = va_arg(ap, int);
+	    else {
+	      if ((bufptr + width) > bufend) width = bufend - bufptr;
+
+	      memcpy(bufptr, va_arg(ap, char *), (size_t)width);
+	      bufptr += width;
+	    }
+	  }
+	  break;
+
+	case 's' : /* String */
+	  if ((s = va_arg(ap, char *)) == NULL) s = "(null)";
+
+	  slen = strlen(s);
+	  if (slen > width && prec != width) width = slen;
+
+          bytes += width;
+
+	  if (bufptr) {
+	    if ((bufptr + width) > bufend) width = bufend - bufptr;
+
+            if (slen > width) slen = width;
+
+	    if (sign == '-') {
+	      strncpy(bufptr, s, (size_t)slen);
+	      memset(bufptr + slen, ' ', (size_t)(width - slen));
+	    } else {
+	      memset(bufptr, ' ', (size_t)(width - slen));
+	      strncpy(bufptr + width - slen, s, (size_t)slen);
+	    }
+
+	    bufptr += width;
+	  }
+	  break;
+
+	case 'n' : /* Output number of chars so far */
+	  *(va_arg(ap, int *)) = bytes;
+	  break;
+      }
+    } else {
+      bytes ++;
+
+      if (bufptr && bufptr < bufend) *bufptr++ = *format;
+      format ++;
+    }
+  }
+
+ /*
+  * Nul-terminate the string and return the number of characters needed.
+  */
+
+  if (bufptr) *bufptr = '\0';
+
+  return (bytes);
+}
+
+int fl_snprintf(char* str, size_t size, const char* fmt, ...) {
+  int ret;
+  va_list ap;
+  va_start(ap, fmt);
+  ret = vsnprintf(str, size, fmt, ap);
+  va_end(ap);
+  return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * End of "$Id$".
+ */
+
diff --git a/Utilities/FLTK/zlib/CMakeLists.txt b/Utilities/FLTK/zlib/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..006a7634f5489c071af6807c495b16e8ce01d72c
--- /dev/null
+++ b/Utilities/FLTK/zlib/CMakeLists.txt
@@ -0,0 +1,15 @@
+PROJECT(FLTKZLIB)
+INCLUDE_REGULAR_EXPRESSION("^(deflate|inf|trees|zconf|zlib|zutil).*$")
+
+INCLUDE_DIRECTORIES(${FLTKZLIB_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${FLTKZLIB_BINARY_DIR})
+
+# source files for zlib
+SET(ZLIB_SRCS
+adler32.c compress.c crc32.c deflate.c gzio.c inffast.c
+inflate.c inftrees.c trees.c uncompr.c zutil.c
+)
+
+ADD_LIBRARY(fltk_zlib ${ZLIB_SRCS})
+INSTALL_TARGETS(/lib fltk_zlib)
+
diff --git a/Utilities/FLTK/zlib/ChangeLog b/Utilities/FLTK/zlib/ChangeLog
new file mode 100644
index 0000000000000000000000000000000000000000..553774c0ca9715cc89d0cb7ff994ddbbc87f0ff5
--- /dev/null
+++ b/Utilities/FLTK/zlib/ChangeLog
@@ -0,0 +1,722 @@
+
+                ChangeLog file for zlib
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+    - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+    - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+  the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+  [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+  and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+  [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+  [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+  INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+  [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+  of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+  parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+  to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+  16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+  Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+  zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+  library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+  special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+    - Report 0 for huffman and rle strategies and for level == 0 or 1
+    - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+    - When Z_RLE requested, restrict matches to distance one
+    - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+    - Refine detection of Turbo C need for dummy returns
+    - Refine ZLIB_DLL compilation
+    - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+  write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+    - About 20% faster
+    - Does not allocate 32K window unless and until needed
+    - Automatically detects and decompresses gzip streams
+    - Raw inflate no longer needs an extra dummy byte at end
+    - Added inflateBack functions using a callback interface--even faster
+      than inflate, useful for file utilities (gzip, zip)
+    - Added inflateCopy() function to record state for random access on
+      externally generated deflate streams (e.g. in gzip files)
+    - More readable code (I hope)
+- New and improved crc32()
+    - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+  and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+  return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+  is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+    - Document raw deflate and inflate
+    - Update RFCs URL
+    - Point out that zlib and gzip formats are different
+    - Note that Z_BUF_ERROR is not fatal
+    - Document string limit for gzprintf() and possible buffer overflow
+    - Note requirement on avail_out when flushing
+    - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+  This creates a security problem described in
+  http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+  less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+  of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+  occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+  (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+  See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean"  (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+  . zutil.c, zutil.h: added "const" for zmem*
+  . Make_vms.com: fixed some typos
+  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+  . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+  . msdos/Makefile.*: use model-dependent name for the built zlib library
+  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+  See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+  completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+  compression ratio on some files. This also allows inlining _tr_tally for
+  matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+  on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+  the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+  them at run time (thanks to Ken Raeburn for this suggestion). To create
+  trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occuring only with compression level 0 (thanks to
+  Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+  (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+  inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+   contrib/asm386/ by Gilles Vollant <info@winimage.com>
+        386 asm code replacing longest_match().
+   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+   contrib/iostream2/  by Tyge L�vset <Tyge.Lovset@cmr.no>
+        Another C++ I/O streams interface
+   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+        A very simple tar.gz file extractor using zlib
+   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+        How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+  level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+  (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id: ChangeLog 3809 2004-09-08 16:04:43Z easysw $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+  bit, so the decompressor could decompress all the correct data but went
+  on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+  small and medium models; this makes the library incompatible with previous
+  versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+  avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+  and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
+     (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+  not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+  (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+  typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+  was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+  pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+  is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+  (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+  TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+  (one's complement) is now done inside crc32(). WARNING: this is
+  incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+  not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+  if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+  user-provided history buffer. This is supported only in deflateInit2
+  and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/Utilities/FLTK/zlib/FAQ b/Utilities/FLTK/zlib/FAQ
new file mode 100644
index 0000000000000000000000000000000000000000..47a7d60c6de3950778dedf10d631da929e27a227
--- /dev/null
+++ b/Utilities/FLTK/zlib/FAQ
@@ -0,0 +1,100 @@
+
+		Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page 
+http://www.zlib.org which may have more recent information.
+The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+    Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+    The zlib sources can be compiled without change to produce a DLL. If you
+    want a precompiled DLL, see http://www.winimage.com/zLibDll/ . Questions
+    about the zlib DLL should be sent to Gilles Vollant (info@winimage.com).
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+    See
+        * http://www.winimage.com/zLibDll/cmp-z-it.zip
+        * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
+        * contrib/visual-basic.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR
+
+    Make sure that before the call of compress, the length of the compressed
+    buffer is equal to the total size of the compressed buffer and not
+    zero. For Visual Basic, check that this parameter is passed by reference
+    ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR
+
+    Before making the call, make sure that avail_in and avail_out are not
+    zero. When setting the parameter flush equal to Z_FINISH, also make sure
+    that avail_out is big enough to allow processing all pending input.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+    It's in zlib.h for the moment, and Francis S. Lin has converted it to a
+    web page zlib.html. Volunteers to transform this to Unix-style man pages,
+    please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage
+    are in the files example.c and minigzip.c.
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+    Because we would like to keep zlib as a very small and simple
+    package. zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+    Most of the time, such problems are due to an incorrect usage of
+    zlib. Please try to reproduce the problem with a small program and send
+    the corresponding source to us at zlib@gzip.org . Do not send
+    multi-megabyte data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+    If "make test" produces something like
+
+       example.o(.text+0x154): undefined reference to `gzputc'
+      
+    check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+    /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+    See the directories contrib/delphi and contrib/delphi2 in the zlib
+    distribution.
+
+11. Can zlib handle .zip archives?
+
+    See the directory contrib/minizip in the zlib distribution.
+
+12. Can zlib handle .Z files?
+
+    No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+    the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+    make clean
+    ./configure -s
+    make
+
+14. Why does "make test" fail on Mac OS X?
+
+    Mac OS X already includes zlib as a shared library, and so -lz links the
+    shared library instead of the one that the "make" compiled. For zlib
+    1.1.3, the two are incompatible due to different compile-time
+    options. Simply change the -lz in the Makefile to libz.a, and it will use
+    the compiled library instead of the shared one and the "make test" will
+    succeed.
+
+15. I have a question about OttoPDF
+
+    We are not the authors of OttoPDF. The real author is on the OttoPDF web
+    site Joel Hainley jhainley@myndkryme.com.
diff --git a/Utilities/FLTK/zlib/INDEX b/Utilities/FLTK/zlib/INDEX
new file mode 100644
index 0000000000000000000000000000000000000000..a9de7844d166388625fa8b16722f1a00f9945830
--- /dev/null
+++ b/Utilities/FLTK/zlib/INDEX
@@ -0,0 +1,48 @@
+ChangeLog       history of changes
+FAQ             Frequently Asked Questions about zlib
+INDEX           this file
+Makefile        makefile for Unix (generated by configure)
+Makefile.in     makefile for Unix (template for configure)
+README          guess what
+algorithm.txt   description of the (de)compression algorithm
+configure       configure script for Unix
+zconf.in.h      template for zconf.h (used by configure)
+
+msdos/          makefiles for MSDOS
+old/            makefiles for various architectures and zlib documentation
+                files that have not yet been updated for zlib 1.2.x
+qnx/            makefiles for QNX
+win32/          makefiles for Windows
+
+                zlib public header files (must be kept):
+zconf.h
+zlib.h
+
+                private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzio.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+                source files for sample programs:
+example.c
+minigzip.c
+
+                unsupported contribution by third parties
+See contrib/README.contrib
diff --git a/Utilities/FLTK/zlib/Makefile b/Utilities/FLTK/zlib/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..398504bd67663a3d53e048fae39730d65dcf7b14
--- /dev/null
+++ b/Utilities/FLTK/zlib/Makefile
@@ -0,0 +1,107 @@
+#
+# "$Id: Makefile 4052 2005-02-24 21:55:12Z mike $"
+#
+# GNU ZIP library makefile for the Fast Light Toolkit (FLTK).
+#
+# Copyright 1997-2005 by Easy Software Products.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+include ../makeinclude
+
+
+#
+# Object files...
+#
+
+OBJS	=	adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o \
+		trees.o zutil.o inflate.o inftrees.o inffast.o
+
+LIBZ	=	../lib/libfltk_z$(LIBEXT)
+
+
+#
+# Make all targets...
+#
+
+all:	$(LIBZ)
+
+
+#
+# Clean all targets and object files...
+#
+
+clean:
+	$(RM) $(OBJS)
+	$(RM) $(LIBZ)
+
+
+#
+# Install everything...
+#
+
+install: $(LIBZ)
+	echo "Installing libfltk_z$(LIBEXT) in $(libdir)..."
+	-$(MKDIR) $(libdir)
+	$(RM) $(libdir)/libfltk_z$(LIBEXT)
+	$(CP) $(LIBZ) $(libdir)
+	$(RANLIB) $(libdir)/libfltk_z$(LIBEXT)
+	echo "Installing zlib headers in $(includedir)/FL/images..."
+	-$(MKDIR) $(includedir)/FL/images
+	$(CP) zconf.h zlib.h zutil.h $(includedir)/FL/images
+
+
+#
+# Uninstall everything...
+#
+
+uninstall:
+	echo "Uninstalling libfltk_z$(LIBEXT) in $(libdir)..."
+	$(RM) $(libdir)/libfltk_z$(LIBEXT)
+	echo "Uninstalling zlib headers in $(includedir)/FL/images..."
+	$(RM) $(includedir)/FL/images/zconf.h
+	$(RM) $(includedir)/FL/images/zlib.h
+	$(RM) $(includedir)/FL/images/zutil.h
+
+
+#
+# libfltk_z.a
+#
+
+$(LIBZ):	$(OBJS)
+	echo Archiving $@...
+	$(RM) $@
+	$(LIBCOMMAND) $@ $(OBJS)
+	$(RANLIB) $@
+
+#
+# Make dependencies...
+#
+
+depend:	$(OBJS:.o=.c)
+	makedepend -Y -I.. -f makedepend $(OBJS:.o=.c)
+
+include makedepend
+
+$(OBJS):	../makeinclude
+
+
+#
+# End of "$Id: Makefile 4052 2005-02-24 21:55:12Z mike $".
+#
diff --git a/Utilities/FLTK/zlib/README b/Utilities/FLTK/zlib/README
new file mode 100644
index 0000000000000000000000000000000000000000..0f1205481c1498b35d296eb74a0babc12c5280c2
--- /dev/null
+++ b/Utilities/FLTK/zlib/README
@@ -0,0 +1,126 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.1 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format). These documents are also available in other
+formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly. Another example is given in the file minigzip.c. The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile. In short "make test; make install" should work for most
+machines. For Unix: "./configure; make test; make install" For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or
+descrip.mms.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
+please check this site to verify that you have the latest version of zlib;
+otherwise get the latest version and check whether the problem still exists or
+not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
+for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of  Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.2.1 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
+CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
+availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+  -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+  compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+  when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+  necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+  other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+- When building a shared, i.e. dynamic library on Mac OS X, the library must be
+  installed before testing (do "make install" before "make test"), since the
+  library location is specified in the library.
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz. The deflate
+  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+  people who reported problems and suggested various improvements in zlib;
+  they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2003 Jean-loup Gailly and Mark Adler
+
+  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.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind.  The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.
diff --git a/Utilities/FLTK/zlib/adler32.c b/Utilities/FLTK/zlib/adler32.c
new file mode 100644
index 0000000000000000000000000000000000000000..624a1696eb03533349208d6fdbf5935be086b352
--- /dev/null
+++ b/Utilities/FLTK/zlib/adler32.c
@@ -0,0 +1,74 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL    /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+#ifdef NO_DIVIDE
+#  define MOD(a) \
+    do { \
+        if (a >= (BASE << 16)) a -= (BASE << 16); \
+        if (a >= (BASE << 15)) a -= (BASE << 15); \
+        if (a >= (BASE << 14)) a -= (BASE << 14); \
+        if (a >= (BASE << 13)) a -= (BASE << 13); \
+        if (a >= (BASE << 12)) a -= (BASE << 12); \
+        if (a >= (BASE << 11)) a -= (BASE << 11); \
+        if (a >= (BASE << 10)) a -= (BASE << 10); \
+        if (a >= (BASE << 9)) a -= (BASE << 9); \
+        if (a >= (BASE << 8)) a -= (BASE << 8); \
+        if (a >= (BASE << 7)) a -= (BASE << 7); \
+        if (a >= (BASE << 6)) a -= (BASE << 6); \
+        if (a >= (BASE << 5)) a -= (BASE << 5); \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? (int)len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+            buf += 16;
+            k -= 16;
+        }
+        if (k != 0) do {
+            s1 += *buf++;
+            s2 += s1;
+        } while (--k);
+        MOD(s1);
+        MOD(s2);
+    }
+    return (s2 << 16) | s1;
+}
diff --git a/Utilities/FLTK/zlib/algorithm.txt b/Utilities/FLTK/zlib/algorithm.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b022dde312a1139fde1d9c0ec90c9640108d9645
--- /dev/null
+++ b/Utilities/FLTK/zlib/algorithm.txt
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data.  The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length).  Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes.  (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast.  The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code.  It gets that many bits from the
+stream, and looks it up in the table.  The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table.  If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code.  However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table.  What inflate() does is
+simply to make the number of bits in the first table a variable, and  then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits.  Also the distance trees have 30 possible
+values, and the size of the first table is six bits.  Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like.  You are correct that it's not a Huffman tree.  It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol.  The
+symbol could be as short as one bit or as long as 15 bits.  If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits.  For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits.  Again, there are duplicated
+entries as needed.  The idea is that most of the time the symbol will be short
+and there will only be one table look up.  (That's whole idea behind data
+compression in the first place.)  For the less frequent long symbols, there
+will be two lookups.  If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient.  For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble.  Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is?  The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols.  At the
+other extreme, you could make a new table for every bit in the code.  In fact,
+that's essentially a Huffman tree.  But then you spend two much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble.  Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed.  That's compared to 64 entries for a single table.  Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table).  Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on.  For inflate, the
+meaning of a particular symbol is often more than just a letter.  It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value.  Or it might be the special end-of-block code.  The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly        Mark Adler
+jloup@gzip.org          madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://www.ietf.org/rfc/rfc1951.txt
diff --git a/Utilities/FLTK/zlib/compress.c b/Utilities/FLTK/zlib/compress.c
new file mode 100644
index 0000000000000000000000000000000000000000..24ef0291911008ce25f30e29dcb0cd8512aedb5b
--- /dev/null
+++ b/Utilities/FLTK/zlib/compress.c
@@ -0,0 +1,79 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+     If the default memLevel or windowBits for deflateInit() is changed, then
+   this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+    uLong sourceLen;
+{
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+}
diff --git a/Utilities/FLTK/zlib/crc32.c b/Utilities/FLTK/zlib/crc32.c
new file mode 100644
index 0000000000000000000000000000000000000000..689b2883b43c150f9c0511860c273da8c6d07b4d
--- /dev/null
+++ b/Utilities/FLTK/zlib/crc32.c
@@ -0,0 +1,311 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results about a factor
+ * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
+#    include <limits.h>
+#    define BYFOUR
+#    if (UINT_MAX == 0xffffffffUL)
+       typedef unsigned int u4;
+#    else
+#      if (ULONG_MAX == 0xffffffffUL)
+         typedef unsigned long u4;
+#      else
+#        if (USHRT_MAX == 0xffffffffUL)
+           typedef unsigned short u4;
+#        else
+#          undef BYFOUR     /* can't find a four-byte integer type! */
+#        endif
+#      endif
+#    endif
+#  endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+#  define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    unsigned long c;
+    int n, k;
+    unsigned long poly;            /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+    poly = 0UL;
+    for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+        poly |= 1UL << (31 - p[n]);
+
+    /* generate a crc for every 8-bit value */
+    for (n = 0; n < 256; n++) {
+        c = (unsigned long)n;
+        for (k = 0; k < 8; k++)
+            c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+        crc_table[0][n] = c;
+    }
+
+#ifdef BYFOUR
+    /* generate crc for each value followed by one, two, and three zeros, and
+       then the byte reversal of those as well as the first table */
+    for (n = 0; n < 256; n++) {
+        c = crc_table[0][n];
+        crc_table[4][n] = REV(c);
+        for (k = 1; k < 4; k++) {
+            c = crc_table[0][c & 0xff] ^ (c >> 8);
+            crc_table[k][n] = c;
+            crc_table[k + 4][n] = REV(c);
+        }
+    }
+#endif /* BYFOUR */
+
+  crc_table_empty = 0;
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const unsigned long FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const unsigned long FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+  if (crc_table_empty) make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+  return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        u4 endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = (u4)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = REV((u4)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
diff --git a/Utilities/FLTK/zlib/crc32.h b/Utilities/FLTK/zlib/crc32.h
new file mode 100644
index 0000000000000000000000000000000000000000..8053b6117c023f64554ea783b23fa06985acff7b
--- /dev/null
+++ b/Utilities/FLTK/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+  {
+    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+    0x2d02ef8dUL
+#ifdef BYFOUR
+  },
+  {
+    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+    0x9324fd72UL
+  },
+  {
+    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+    0xbe9834edUL
+  },
+  {
+    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+    0xde0506f1UL
+  },
+  {
+    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+    0x8def022dUL
+  },
+  {
+    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+    0x72fd2493UL
+  },
+  {
+    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+    0xed3498beUL
+  },
+  {
+    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+    0xf10605deUL
+#endif
+  }
+};
diff --git a/Utilities/FLTK/zlib/deflate.c b/Utilities/FLTK/zlib/deflate.c
new file mode 100644
index 0000000000000000000000000000000000000000..0525b2f33caa89c33764a8c7b843d57342845e45
--- /dev/null
+++ b/Utilities/FLTK/zlib/deflate.c
@@ -0,0 +1,1502 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifndef FASTEST
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_RLE) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->wrap = wrap;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->wrap == 2 ||
+        (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+        return Z_STREAM_ERROR;
+
+    s = strm->state;
+    if (s->wrap)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+        length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+        dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+    }
+    zmemcpy(s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+        INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    strm->state->bi_valid = bits;
+    strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if (func != configuration_table[level].func && strm->total_in != 0) {
+        /* Flush the last buffer: */
+        err = deflate(strm, Z_PARTIAL_FLUSH);
+    }
+    if (s->level != level) {
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds
+ * for every combination of windowBits and memLevel, as well as wrap.
+ * But even the conservative upper bound of about 14% expansion does not
+ * seem onerous for output buffer allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong destLen;
+
+    /* conservative upper bound */
+    destLen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+    /* if can't get parameters, return conservative bound */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return destLen;
+
+    /* if not default parameters, return conservative bound */
+    s = strm->state;
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return destLen;
+
+    /* default settings: return tight bound for that case */
+    return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        flush > Z_FINISH || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+#ifdef GZIP
+        if (s->wrap == 2) {
+            put_byte(s, 31);
+            put_byte(s, 139);
+            put_byte(s, 8);
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, s->level == 9 ? 2 :
+                        (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                         4 : 0));
+            put_byte(s, 255);
+            s->status = BUSY_STATE;
+            strm->adler = crc32(0L, Z_NULL, 0);
+        }
+        else
+#endif
+        {
+            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+            uInt level_flags;
+
+            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+                level_flags = 0;
+            else if (s->level < 6)
+                level_flags = 1;
+            else if (s->level == 6)
+                level_flags = 2;
+            else
+                level_flags = 3;
+            header |= (level_flags << 6);
+            if (s->strstart != 0) header |= PRESET_DICT;
+            header += 31 - (header % 31);
+
+            s->status = BUSY_STATE;
+            putShortMSB(s, header);
+
+            /* Save the adler32 of the preset dictionary: */
+            if (s->strstart != 0) {
+                putShortMSB(s, (uInt)(strm->adler >> 16));
+                putShortMSB(s, (uInt)(strm->adler & 0xffff));
+            }
+            strm->adler = adler32(0L, Z_NULL, 0);
+        }
+    }
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE && status != BUSY_STATE &&
+        status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    *dest = *source;
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    *ds = *ss;
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, strm->next_in, len);
+    }
+#endif
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2:
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+#ifndef FASTEST
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+                   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+        Assert(s->block_start >= 0L, "block gone");
+
+        s->strstart += s->lookahead;
+        s->lookahead = 0;
+
+        /* Emit a stored block if pending_buf will be full: */
+        max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+            /* strstart == 0 is possible when wraparound on 16-bit machine */
+            s->lookahead = (uInt)(s->strstart - max_start);
+            s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+        }
+        /* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+        }
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL; /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+#ifdef FASTEST
+            if ((s->strategy < Z_HUFFMAN_ONLY) ||
+                (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+                s->match_length = longest_match_fast (s, hash_head);
+            }
+#else
+            if (s->strategy < Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+                s->match_length = longest_match_fast (s, hash_head);
+            }
+#endif
+            /* longest_match() or longest_match_fast() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL;    /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy < Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+                s->match_length = longest_match_fast (s, hash_head);
+            }
+            /* longest_match() or longest_match_fast() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
diff --git a/Utilities/FLTK/zlib/deflate.h b/Utilities/FLTK/zlib/deflate.h
new file mode 100644
index 0000000000000000000000000000000000000000..e31f66be5215fa449cc6f20a3af725a3bf73982e
--- /dev/null
+++ b/Utilities/FLTK/zlib/deflate.h
@@ -0,0 +1,326 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2002 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    int   pending;       /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void _tr_init         OF((deflate_state *s));
+int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+void _tr_align        OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch _length_code[];
+  extern uch _dist_code[];
+#else
+  extern const uch _length_code[];
+  extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/Utilities/FLTK/zlib/gzio.c b/Utilities/FLTK/zlib/gzio.c
new file mode 100644
index 0000000000000000000000000000000000000000..4afd102b3f35765890ad15df32d02019d1be1fa1
--- /dev/null
+++ b/Utilities/FLTK/zlib/gzio.c
@@ -0,0 +1,1005 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+#ifdef NO_DEFLATE       /* for compatiblity with old definition */
+#  define NO_GZCOMPRESS
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef Z_BUFSIZE
+#  ifdef MAXSEG_64K
+#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+#  else
+#    define Z_BUFSIZE 16384
+#  endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+#  define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#ifdef __MVS__
+#  pragma map (fdopen , "\174\174FDOPEN")
+   FILE *fdopen(int, const char *);
+#endif
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+    z_stream stream;
+    int      z_err;   /* error code for last stream operation */
+    int      z_eof;   /* set if end of input file */
+    FILE     *file;   /* .gz file */
+    Byte     *inbuf;  /* input buffer */
+    Byte     *outbuf; /* output buffer */
+    uLong    crc;     /* crc32 of uncompressed data */
+    char     *msg;    /* error message */
+    char     *path;   /* path name for debugging only */
+    int      transparent; /* 1 if input file is not a .gz file */
+    char     mode;    /* 'w' or 'r' */
+    z_off_t  start;   /* start of compressed data in file (header skipped) */
+    z_off_t  in;      /* bytes into deflate or inflate */
+    z_off_t  out;     /* bytes out of deflate or inflate */
+    int      back;    /* one character push-back */
+    int      last;    /* true if push-back is last character */
+} gz_stream;
+
+
+local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
+local int do_flush        OF((gzFile file, int flush));
+local int    get_byte     OF((gz_stream *s));
+local void   check_header OF((gz_stream *s));
+local int    destroy      OF((gz_stream *s));
+local void   putLong      OF((FILE *file, uLong x));
+local uLong  getLong      OF((gz_stream *s));
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+   or path name (if fd == -1).
+     gz_open returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+    const char *path;
+    const char *mode;
+    int  fd;
+{
+    int err;
+    int level = Z_DEFAULT_COMPRESSION; /* compression level */
+    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+    char *p = (char*)mode;
+    gz_stream *s;
+    char fmode[80]; /* copy of mode, without the compression level */
+    char *m = fmode;
+
+    if (!path || !mode) return Z_NULL;
+
+    s = (gz_stream *)ALLOC(sizeof(gz_stream));
+    if (!s) return Z_NULL;
+
+    s->stream.zalloc = (alloc_func)0;
+    s->stream.zfree = (free_func)0;
+    s->stream.opaque = (voidpf)0;
+    s->stream.next_in = s->inbuf = Z_NULL;
+    s->stream.next_out = s->outbuf = Z_NULL;
+    s->stream.avail_in = s->stream.avail_out = 0;
+    s->file = NULL;
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->in = 0;
+    s->out = 0;
+    s->back = EOF;
+    s->crc = crc32(0L, Z_NULL, 0);
+    s->msg = NULL;
+    s->transparent = 0;
+
+    s->path = (char*)ALLOC(strlen(path)+1);
+    if (s->path == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    strcpy(s->path, path); /* do this early for debugging */
+
+    s->mode = '\0';
+    do {
+        if (*p == 'r') s->mode = 'r';
+        if (*p == 'w' || *p == 'a') s->mode = 'w';
+        if (*p >= '0' && *p <= '9') {
+            level = *p - '0';
+        } else if (*p == 'f') {
+          strategy = Z_FILTERED;
+        } else if (*p == 'h') {
+          strategy = Z_HUFFMAN_ONLY;
+        } else if (*p == 'R') {
+          strategy = Z_RLE;
+        } else {
+            *m++ = *p; /* copy the mode */
+        }
+    } while (*p++ && m != fmode + sizeof(fmode));
+    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+
+    if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+        err = Z_STREAM_ERROR;
+#else
+        err = deflateInit2(&(s->stream), level,
+                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+        /* windowBits is passed < 0 to suppress zlib header */
+
+        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+        if (err != Z_OK || s->outbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    } else {
+        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+        err = inflateInit2(&(s->stream), -MAX_WBITS);
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+         * present after the compressed stream.
+         */
+        if (err != Z_OK || s->inbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    }
+    s->stream.avail_out = Z_BUFSIZE;
+
+    errno = 0;
+    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+    if (s->file == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    if (s->mode == 'w') {
+        /* Write a very simple .gz header:
+         */
+        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+        s->start = 10L;
+        /* We use 10L instead of ftell(s->file) to because ftell causes an
+         * fflush on some systems. This version of the library doesn't use
+         * start anyway in write mode, so this initialization is not
+         * necessary.
+         */
+    } else {
+        check_header(s); /* skip the .gz header */
+        s->start = ftell(s->file) - s->stream.avail_in;
+    }
+
+    return (gzFile)s;
+}
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+   to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+    int fd;
+    const char *mode;
+{
+    char name[20];
+
+    if (fd < 0) return (gzFile)Z_NULL;
+    sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+    return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+    gzFile file;
+    int level;
+    int strategy;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    /* Make room to allow flushing */
+    if (s->stream.avail_out == 0) {
+
+        s->stream.next_out = s->outbuf;
+        if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+            s->z_err = Z_ERRNO;
+        }
+        s->stream.avail_out = Z_BUFSIZE;
+    }
+
+    return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+    gz_stream *s;
+{
+    if (s->z_eof) return EOF;
+    if (s->stream.avail_in == 0) {
+        errno = 0;
+        s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+        if (s->stream.avail_in == 0) {
+            s->z_eof = 1;
+            if (ferror(s->file)) s->z_err = Z_ERRNO;
+            return EOF;
+        }
+        s->stream.next_in = s->inbuf;
+    }
+    s->stream.avail_in--;
+    return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+      Check the gzip header of a gz_stream opened for reading. Set the stream
+    mode to transparent if the gzip magic header is not present; set s->err
+    to Z_DATA_ERROR if the magic header is present but the rest of the header
+    is incorrect.
+    IN assertion: the stream s has already been created sucessfully;
+       s->stream.avail_in is zero for the first time, but may be non-zero
+       for concatenated .gz files.
+*/
+local void check_header(s)
+    gz_stream *s;
+{
+    int method; /* method byte */
+    int flags;  /* flags byte */
+    uInt len;
+    int c;
+
+    /* Assure two bytes in the buffer so we can peek ahead -- handle case
+       where first byte of header is at the end of the buffer after the last
+       gzip segment */
+    len = s->stream.avail_in;
+    if (len < 2) {
+        if (len) s->inbuf[0] = s->stream.next_in[0];
+        errno = 0;
+        len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+        if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
+        s->stream.avail_in += len;
+        s->stream.next_in = s->inbuf;
+        if (s->stream.avail_in < 2) {
+            s->transparent = s->stream.avail_in;
+            return;
+        }
+    }
+
+    /* Peek ahead to check the gzip magic header */
+    if (s->stream.next_in[0] != gz_magic[0] ||
+        s->stream.next_in[1] != gz_magic[1]) {
+        s->transparent = 1;
+        return;
+    }
+    s->stream.avail_in -= 2;
+    s->stream.next_in += 2;
+
+    /* Check the rest of the gzip header */
+    method = get_byte(s);
+    flags = get_byte(s);
+    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+        s->z_err = Z_DATA_ERROR;
+        return;
+    }
+
+    /* Discard time, xflags and OS code: */
+    for (len = 0; len < 6; len++) (void)get_byte(s);
+
+    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+        len  =  (uInt)get_byte(s);
+        len += ((uInt)get_byte(s))<<8;
+        /* len is garbage if EOF but the loop below will quit anyway */
+        while (len-- != 0 && get_byte(s) != EOF) ;
+    }
+    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+        while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
+        while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
+        for (len = 0; len < 2; len++) (void)get_byte(s);
+    }
+    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+   Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+    gz_stream *s;
+{
+    int err = Z_OK;
+
+    if (!s) return Z_STREAM_ERROR;
+
+    TRYFREE(s->msg);
+
+    if (s->stream.state != NULL) {
+        if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+            err = Z_STREAM_ERROR;
+#else
+            err = deflateEnd(&(s->stream));
+#endif
+        } else if (s->mode == 'r') {
+            err = inflateEnd(&(s->stream));
+        }
+    }
+    if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+        if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+            err = Z_ERRNO;
+    }
+    if (s->z_err < 0) err = s->z_err;
+
+    TRYFREE(s->inbuf);
+    TRYFREE(s->outbuf);
+    TRYFREE(s->path);
+    TRYFREE(s);
+    return err;
+}
+
+/* ===========================================================================
+     Reads the given number of uncompressed bytes from the compressed file.
+   gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
+
+    next_out = (Byte*)buf;
+    s->stream.next_out = (Bytef*)buf;
+    s->stream.avail_out = len;
+
+    if (s->stream.avail_out && s->back != EOF) {
+        *next_out++ = s->back;
+        s->stream.next_out++;
+        s->stream.avail_out--;
+        s->back = EOF;
+        s->out++;
+        if (s->last) {
+            s->z_err = Z_STREAM_END;
+            return 1;
+        }
+    }
+
+    while (s->stream.avail_out != 0) {
+
+        if (s->transparent) {
+            /* Copy first the lookahead bytes: */
+            uInt n = s->stream.avail_in;
+            if (n > s->stream.avail_out) n = s->stream.avail_out;
+            if (n > 0) {
+                zmemcpy(s->stream.next_out, s->stream.next_in, n);
+                next_out += n;
+                s->stream.next_out = next_out;
+                s->stream.next_in   += n;
+                s->stream.avail_out -= n;
+                s->stream.avail_in  -= n;
+            }
+            if (s->stream.avail_out > 0) {
+                s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
+                                             s->file);
+            }
+            len -= s->stream.avail_out;
+            s->in  += len;
+            s->out += len;
+            if (len == 0) s->z_eof = 1;
+            return (int)len;
+        }
+        if (s->stream.avail_in == 0 && !s->z_eof) {
+
+            errno = 0;
+            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            if (s->stream.avail_in == 0) {
+                s->z_eof = 1;
+                if (ferror(s->file)) {
+                    s->z_err = Z_ERRNO;
+                    break;
+                }
+            }
+            s->stream.next_in = s->inbuf;
+        }
+        s->in += s->stream.avail_in;
+        s->out += s->stream.avail_out;
+        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+        s->in -= s->stream.avail_in;
+        s->out -= s->stream.avail_out;
+
+        if (s->z_err == Z_STREAM_END) {
+            /* Check CRC and original size */
+            s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+            start = s->stream.next_out;
+
+            if (getLong(s) != s->crc) {
+                s->z_err = Z_DATA_ERROR;
+            } else {
+                (void)getLong(s);
+                /* The uncompressed length returned by above getlong() may be
+                 * different from s->out in case of concatenated .gz files.
+                 * Check for such files:
+                 */
+                check_header(s);
+                if (s->z_err == Z_OK) {
+                    inflateReset(&(s->stream));
+                    s->crc = crc32(0L, Z_NULL, 0);
+                }
+            }
+        }
+        if (s->z_err != Z_OK || s->z_eof) break;
+    }
+    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+    return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+    gzFile file;
+{
+    unsigned char c;
+
+    return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+      Push one byte back onto the stream.
+*/
+int ZEXPORT gzungetc(c, file)
+    int c;
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
+    s->back = c;
+    s->out--;
+    s->last = (s->z_err == Z_STREAM_END);
+    if (s->last) s->z_err = Z_OK;
+    s->z_eof = 0;
+    return c;
+}
+
+
+/* ===========================================================================
+      Reads bytes from the compressed file until len-1 characters are
+   read, or a newline character is read and transferred to buf, or an
+   end-of-file condition is encountered.  The string is then terminated
+   with a null character.
+      gzgets returns buf, or Z_NULL in case of error.
+
+      The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+    gzFile file;
+    char *buf;
+    int len;
+{
+    char *b = buf;
+    if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+    *buf = '\0';
+    return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_GZCOMPRESS
+/* ===========================================================================
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+    gzFile file;
+    voidpc buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.next_in = (Bytef*)buf;
+    s->stream.avail_in = len;
+
+    while (s->stream.avail_in != 0) {
+
+        if (s->stream.avail_out == 0) {
+
+            s->stream.next_out = s->outbuf;
+            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+                s->z_err = Z_ERRNO;
+                break;
+            }
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        s->in += s->stream.avail_in;
+        s->out += s->stream.avail_out;
+        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+        s->in -= s->stream.avail_in;
+        s->out -= s->stream.avail_out;
+        if (s->z_err != Z_OK) break;
+    }
+    s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+    return (int)(len - s->stream.avail_in);
+}
+
+
+/* ===========================================================================
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    va_list va;
+    int len;
+
+    buf[sizeof(buf) - 1] = 0;
+    va_start(va, format);
+#ifdef NO_vsnprintf
+#  ifdef HAS_vsprintf_void
+    (void)vsprintf(buf, format, va);
+    va_end(va);
+    for (len = 0; len < sizeof(buf); len++)
+        if (buf[len] == 0) break;
+#  else
+    len = vsprintf(buf, format, va);
+    va_end(va);
+#  endif
+#else
+#  ifdef HAS_vsnprintf_void
+    (void)vsnprintf(buf, sizeof(buf), format, va);
+    va_end(va);
+    len = strlen(buf);
+#  else
+    len = vsnprintf(buf, sizeof(buf), format, va);
+    va_end(va);
+#  endif
+#endif
+    if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+        return 0;
+    return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+    gzFile file;
+    const char *format;
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    int len;
+
+    buf[sizeof(buf) - 1] = 0;
+#ifdef NO_snprintf
+#  ifdef HAS_sprintf_void
+    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    for (len = 0; len < sizeof(buf); len++)
+        if (buf[len] == 0) break;
+#  else
+    len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+                a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#else
+#  ifdef HAS_snprintf_void
+    snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    len = strlen(buf);
+#  else
+    len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#endif
+    if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+        return 0;
+    return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+    gzFile file;
+    int c;
+{
+    unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+    gzFile file;
+    const char *s;
+{
+    return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+    gzFile file;
+    int flush;
+{
+    uInt len;
+    int done = 0;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.avail_in = 0; /* should be zero already anyway */
+
+    for (;;) {
+        len = Z_BUFSIZE - s->stream.avail_out;
+
+        if (len != 0) {
+            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+                s->z_err = Z_ERRNO;
+                return Z_ERRNO;
+            }
+            s->stream.next_out = s->outbuf;
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        if (done) break;
+        s->out += s->stream.avail_out;
+        s->z_err = deflate(&(s->stream), flush);
+        s->out -= s->stream.avail_out;
+
+        /* Ignore the second of two consecutive flushes: */
+        if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+        /* deflate has finished flushing only when it hasn't used up
+         * all the available space in the output buffer:
+         */
+        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+
+        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+    }
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+     gzFile file;
+     int flush;
+{
+    gz_stream *s = (gz_stream*)file;
+    int err = do_flush (file, flush);
+
+    if (err) return err;
+    fflush(s->file);
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_GZCOMPRESS */
+
+/* ===========================================================================
+      Sets the starting position for the next gzread or gzwrite on the given
+   compressed file. The offset represents a number of bytes in the
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error.
+      SEEK_END is not implemented, returns error.
+      In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+    gzFile file;
+    z_off_t offset;
+    int whence;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || whence == SEEK_END ||
+        s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+        return -1L;
+    }
+
+    if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+        return -1L;
+#else
+        if (whence == SEEK_SET) {
+            offset -= s->in;
+        }
+        if (offset < 0) return -1L;
+
+        /* At this point, offset is the number of zero bytes to write. */
+        if (s->inbuf == Z_NULL) {
+            s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+            if (s->inbuf == Z_NULL) return -1L;
+            zmemzero(s->inbuf, Z_BUFSIZE);
+        }
+        while (offset > 0)  {
+            uInt size = Z_BUFSIZE;
+            if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+            size = gzwrite(file, s->inbuf, size);
+            if (size == 0) return -1L;
+
+            offset -= size;
+        }
+        return s->in;
+#endif
+    }
+    /* Rest of function is for reading only */
+
+    /* compute absolute position */
+    if (whence == SEEK_CUR) {
+        offset += s->out;
+    }
+    if (offset < 0) return -1L;
+
+    if (s->transparent) {
+        /* map to fseek */
+        s->back = EOF;
+        s->stream.avail_in = 0;
+        s->stream.next_in = s->inbuf;
+        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+        s->in = s->out = offset;
+        return offset;
+    }
+
+    /* For a negative seek, rewind and use positive seek */
+    if (offset >= s->out) {
+        offset -= s->out;
+    } else if (gzrewind(file) < 0) {
+        return -1L;
+    }
+    /* offset is now the number of bytes to skip. */
+
+    if (offset != 0 && s->outbuf == Z_NULL) {
+        s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+        if (s->outbuf == Z_NULL) return -1L;
+    }
+    if (offset && s->back != EOF) {
+        s->back = EOF;
+        s->out++;
+        offset--;
+        if (s->last) s->z_err = Z_STREAM_END;
+    }
+    while (offset > 0)  {
+        int size = Z_BUFSIZE;
+        if (offset < Z_BUFSIZE) size = (int)offset;
+
+        size = gzread(file, s->outbuf, (uInt)size);
+        if (size <= 0) return -1L;
+        offset -= size;
+    }
+    return s->out;
+}
+
+/* ===========================================================================
+     Rewinds input file.
+*/
+int ZEXPORT gzrewind (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r') return -1;
+
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->back = EOF;
+    s->stream.avail_in = 0;
+    s->stream.next_in = s->inbuf;
+    s->crc = crc32(0L, Z_NULL, 0);
+    if (!s->transparent) (void)inflateReset(&s->stream);
+    s->in = 0;
+    s->out = 0;
+    return fseek(s->file, s->start, SEEK_SET);
+}
+
+/* ===========================================================================
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+    gzFile file;
+{
+    return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    /* With concatenated compressed files that can have embedded
+     * crc trailers, z_eof is no longer the only/best indicator of EOF
+     * on a gz_stream. Handle end-of-stream error explicitly here.
+     */
+    if (s == NULL || s->mode != 'r') return 0;
+    if (s->z_eof) return 1;
+    return s->z_err == Z_STREAM_END;
+}
+
+/* ===========================================================================
+   Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+    FILE *file;
+    uLong x;
+{
+    int n;
+    for (n = 0; n < 4; n++) {
+        fputc((int)(x & 0xff), file);
+        x >>= 8;
+    }
+}
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets z_err in case
+   of error.
+*/
+local uLong getLong (s)
+    gz_stream *s;
+{
+    uLong x = (uLong)get_byte(s);
+    int c;
+
+    x += ((uLong)get_byte(s))<<8;
+    x += ((uLong)get_byte(s))<<16;
+    c = get_byte(s);
+    if (c == EOF) s->z_err = Z_DATA_ERROR;
+    x += ((uLong)c)<<24;
+    return x;
+}
+
+/* ===========================================================================
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+    gzFile file;
+{
+    int err;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) return Z_STREAM_ERROR;
+
+    if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+        return Z_STREAM_ERROR;
+#else
+        err = do_flush (file, Z_FINISH);
+        if (err != Z_OK) return destroy((gz_stream*)file);
+
+        putLong (s->file, s->crc);
+        putLong (s->file, (uLong)(s->in & 0xffffffff));
+#endif
+    }
+    return destroy((gz_stream*)file);
+}
+
+/* ===========================================================================
+     Returns the error message for the last error which occured on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occured in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+const char * ZEXPORT gzerror (file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    char *m;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) {
+        *errnum = Z_STREAM_ERROR;
+        return (const char*)ERR_MSG(Z_STREAM_ERROR);
+    }
+    *errnum = s->z_err;
+    if (*errnum == Z_OK) return (const char*)"";
+
+    m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+    TRYFREE(s->msg);
+    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+    if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
+    strcpy(s->msg, s->path);
+    strcat(s->msg, ": ");
+    strcat(s->msg, m);
+    return (const char*)s->msg;
+}
+
+/* ===========================================================================
+     Clear the error and end-of-file flags, and do the same for the real file.
+*/
+void ZEXPORT gzclearerr (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) return;
+    if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
+    s->z_eof = 0;
+    clearerr(s->file);
+}
diff --git a/Utilities/FLTK/zlib/inffast.c b/Utilities/FLTK/zlib/inffast.c
new file mode 100644
index 0000000000000000000000000000000000000000..c716440a92ac9edcf86bd89c10eb82479638bb4f
--- /dev/null
+++ b/Utilities/FLTK/zlib/inffast.c
@@ -0,0 +1,305 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+   Based on testing to date,
+   Pre-increment preferred for:
+   - PowerPC G3 (Adler)
+   - MIPS R5000 (Randers-Pehrson)
+   Post-increment preferred for:
+   - none
+   No measurable difference:
+   - Pentium III (Anderson)
+   - 68060 (Nikl)
+ */
+#ifdef POSTINC
+#  define OFF 0
+#  define PUP(a) *(a)++
+#else
+#  define OFF 1
+#  define PUP(a) *++(a)
+#endif
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *in;      /* local strm->next_in */
+    unsigned char FAR *last;    /* while in < last, enough input available */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned write;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code this;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in - OFF;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out - OFF;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+    wsize = state->wsize;
+    whave = state->whave;
+    write = state->write;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+        }
+        this = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(this.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(this.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", this.val));
+            PUP(out) = (unsigned char)(this.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(this.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+            }
+            this = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(this.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(this.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(this.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(PUP(in)) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+                    from = window - OFF;
+                    if (write == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (write < op) {      /* wrap around window */
+                        from += wsize + write - op;
+                        op -= write;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = window - OFF;
+                            if (write < len) {  /* some from start of window */
+                                op = write;
+                                len -= op;
+                                do {
+                                    PUP(out) = PUP(from);
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += write - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    }
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                this = dcode[this.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            this = lcode[this.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in + OFF;
+    strm->next_out = out + OFF;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and write == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/Utilities/FLTK/zlib/inffast.h b/Utilities/FLTK/zlib/inffast.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e88d2d97b568d37c44800c5aa7e54cfa33d46d3
--- /dev/null
+++ b/Utilities/FLTK/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/Utilities/FLTK/zlib/inffixed.h b/Utilities/FLTK/zlib/inffixed.h
new file mode 100644
index 0000000000000000000000000000000000000000..75ed4b5978de4be3c44ad48a060b75500f17a0a2
--- /dev/null
+++ b/Utilities/FLTK/zlib/inffixed.h
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications. It
+       is part of the implementation of the compression library and
+       is subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
diff --git a/Utilities/FLTK/zlib/inflate.c b/Utilities/FLTK/zlib/inflate.c
new file mode 100644
index 0000000000000000000000000000000000000000..a53b5c7446ebd7f097942faa28618cb897a51169
--- /dev/null
+++ b/Utilities/FLTK/zlib/inflate.c
@@ -0,0 +1,1270 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+                              unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->wsize = 0;
+    state->whave = 0;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (voidpf)state;
+    if (windowBits < 0) {
+        state->wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+        if (windowBits < 48) windowBits &= 15;
+#endif
+    }
+    if (windowBits < 8 || windowBits > 15) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+        return Z_STREAM_ERROR;
+    }
+    state->wbits = (unsigned)windowBits;
+    state->window = Z_NULL;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+               state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+    struct inflate_state FAR *state;
+    unsigned copy, dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->write = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    copy = out - strm->avail_out;
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+        state->write = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->write;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, strm->next_out - copy, copy);
+            state->write = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->write += dist;
+            if (state->write == state->wsize) state->write = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code this;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            if (BITS(4) + 8 > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->flags & 0x0200) CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->flags & 0x0200) CRC2(state->check, hold);
+                INITBITS();
+            }
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->flags & 0x0200)
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                } while (len && copy < have);
+                if (state->flags & 0x02000)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                } while (len && copy < have);
+                if (state->flags & 0x02000)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if (hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = REVERSE(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+            if (flush == Z_BLOCK) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    this = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (this.val < 16) {
+                    NEEDBITS(this.bits);
+                    DROPBITS(this.bits);
+                    state->lens[state->have++] = this.val;
+                }
+                else {
+                    if (this.val == 16) {
+                        NEEDBITS(this.bits + 2);
+                        DROPBITS(this.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (this.val == 17) {
+                        NEEDBITS(this.bits + 3);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(this.bits + 7);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* build code tables */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                break;
+            }
+            for (;;) {
+                this = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (this.op && (this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            state->length = (unsigned)this.val;
+            if ((int)(this.op) == 0) {
+                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", this.val));
+                state->mode = LIT;
+                break;
+            }
+            if (this.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(this.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                this = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)this.val;
+            state->extra = (unsigned)(this.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            if (state->offset > state->whave + out - left) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->write) {
+                    copy -= state->write;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->write - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if (out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     REVERSE(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+        if (updatewindow(strm, out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if (state->wrap && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+    struct inflate_state FAR *state;
+    unsigned long id;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode != DICT) return Z_STREAM_ERROR;
+
+    /* check for correct dictionary id */
+    id = adler32(0L, Z_NULL, 0);
+    id = adler32(id, dictionary, dictLength);
+    if (id != state->check) return Z_DATA_ERROR;
+
+    /* copy dictionary to window */
+    if (updatewindow(strm, strm->avail_out)) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    if (dictLength > state->wsize) {
+        zmemcpy(state->window, dictionary + dictLength - state->wsize,
+                state->wsize);
+        state->whave = state->wsize;
+    }
+    else {
+        zmemcpy(state->window + state->wsize - dictLength, dictionary,
+                dictLength);
+        state->whave = dictLength;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+
+    /* check input */
+    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    *dest = *source;
+    *copy = *state;
+    copy->lencode = copy->codes + (state->lencode - state->codes);
+    copy->distcode = copy->codes + (state->distcode - state->codes);
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL)
+        zmemcpy(window, state->window, 1U << state->wbits);
+    copy->window = window;
+    dest->state = (voidpf)copy;
+    return Z_OK;
+}
diff --git a/Utilities/FLTK/zlib/inflate.h b/Utilities/FLTK/zlib/inflate.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a12c8fd2963bfa45e884077679c706e1f6a2ab7
--- /dev/null
+++ b/Utilities/FLTK/zlib/inflate.h
@@ -0,0 +1,117 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+#ifdef GUNZIP
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+#endif
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN,        /* i: waiting for length/lit code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+#ifdef GUNZIP
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+#endif
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+        NAME -> COMMENT -> HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+    Read deflate blocks:
+            TYPE -> STORED or TABLE or LEN or CHECK
+            STORED -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN
+    Read deflate codes:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 7K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned write;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+};
diff --git a/Utilities/FLTK/zlib/inftrees.c b/Utilities/FLTK/zlib/inftrees.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b791afd97e016f00814bfb2485eea72a092141a
--- /dev/null
+++ b/Utilities/FLTK/zlib/inftrees.c
@@ -0,0 +1,321 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+   " inflate 1.2.1 Copyright 1995-2003 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code this;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 76, 66};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) return -1;            /* no codes! */
+    for (min = 1; min <= MAXBITS; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked when a LENS table is being made
+       against the space in *table, ENOUGH, minus the maximum space needed by
+       the worst case distance code, MAXD.  This should never happen, but the
+       sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+       This assumes that when type == LENS, bits == 9.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if (type == LENS && used >= ENOUGH - MAXD)
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        this.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            this.op = (unsigned char)0;
+            this.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            this.op = (unsigned char)(extra[work[sym]]);
+            this.val = base[work[sym]];
+        }
+        else {
+            this.op = (unsigned char)(32 + 64);         /* end of block */
+            this.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = this;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += 1U << curr;
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if (type == LENS && used >= ENOUGH - MAXD)
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /*
+       Fill in rest of table for incomplete codes.  This loop is similar to the
+       loop above in incrementing huff for table indices.  It is assumed that
+       len is equal to curr + drop, so there is no loop needed to increment
+       through high index bits.  When the current sub-table is filled, the loop
+       drops back to the root table to fill in any remaining entries there.
+     */
+    this.op = (unsigned char)64;                /* invalid code marker */
+    this.bits = (unsigned char)(len - drop);
+    this.val = (unsigned short)0;
+    while (huff != 0) {
+        /* when done with sub-table, drop back to root table */
+        if (drop != 0 && (huff & mask) != low) {
+            drop = 0;
+            len = root;
+            next = *table;
+            curr = root;
+            this.bits = (unsigned char)len;
+        }
+
+        /* put invalid code marker in table */
+        next[huff >> drop] = this;
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
diff --git a/Utilities/FLTK/zlib/inftrees.h b/Utilities/FLTK/zlib/inftrees.h
new file mode 100644
index 0000000000000000000000000000000000000000..82d365a7e901c749e7181527b62330c11c255695
--- /dev/null
+++ b/Utilities/FLTK/zlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree.  The maximum found in a long but non-
+   exhaustive search was 1004 code structures (850 for length/literals
+   and 154 for distances, the latter actually the result of an
+   exhaustive search).  The true maximum is not known, but the value
+   below is more than safe. */
+#define ENOUGH 1440
+#define MAXD 154
+
+/* Type of code to build for inftable() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
diff --git a/Utilities/FLTK/zlib/makedepend b/Utilities/FLTK/zlib/makedepend
new file mode 100644
index 0000000000000000000000000000000000000000..57128516999681920aa14864a436400b86282de2
--- /dev/null
+++ b/Utilities/FLTK/zlib/makedepend
@@ -0,0 +1,13 @@
+# DO NOT DELETE
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zutil.h zlib.h zconf.h crc32.h
+gzio.o: zutil.h zlib.h zconf.h
+uncompr.o: zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+zutil.o: zutil.h zlib.h zconf.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
diff --git a/Utilities/FLTK/zlib/makefile.wat b/Utilities/FLTK/zlib/makefile.wat
new file mode 100644
index 0000000000000000000000000000000000000000..00a8755b74b568806b3c2d373493113ab86fc4fa
--- /dev/null
+++ b/Utilities/FLTK/zlib/makefile.wat
@@ -0,0 +1,60 @@
+#
+# "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $"
+#
+# GNU ZIP library makefile for the Fast Light Toolkit (FLTK).
+#
+# Copyright 1997-2004 by Easy Software Products.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+#
+# Please report all bugs and problems to "fltk-bugs@fltk.org".
+#
+
+LIBNAMEROOT=ftlk_z
+
+!include ../watcom.mif
+
+
+#
+# Object files...
+#
+
+LIBOBJS = adler32.obj compress.obj crc32.obj gzio.obj uncompr.obj deflate.obj &
+          trees.obj zutil.obj inflate.obj inftrees.obj inffast.obj
+
+
+#
+# Make all targets...
+#
+
+all: $(LIBNAME)
+
+$(LIBNAME): $(LIBOBJS)
+    $(LIB) $(LIBOPTS) $@ $<
+
+#
+# Clean all directories
+#
+clean : .SYMBOLIC
+    @echo Cleaning up.
+CLEANEXTS = obj
+    @for %a in ($(CLEANEXTS)) do -rm -f $(ODIR)\*.%a
+    -rm -f *.err
+    -rm -f $(LIBNAME)
+
+#
+# End of "$Id: makefile.wat 4359 2005-05-19 16:07:13Z mike $".
+#
diff --git a/Utilities/FLTK/zlib/trees.c b/Utilities/FLTK/zlib/trees.c
new file mode 100644
index 0000000000000000000000000000000000000000..bb09554938be7000c6efd03c2deebce81e0951df
--- /dev/null
+++ b/Utilities/FLTK/zlib/trees.c
@@ -0,0 +1,1215 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2003 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (val << s->bi_valid);\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if (tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+        s->compressed_len += 10L;
+#endif
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+         /* Check if the file is ascii or binary */
+        if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n = 0;
+    unsigned ascii_freq = 0;
+    unsigned bin_freq = 0;
+    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
+    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
+    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/Utilities/FLTK/zlib/trees.h b/Utilities/FLTK/zlib/trees.h
new file mode 100644
index 0000000000000000000000000000000000000000..72facf900f7787e26fe05781e08ecf26b42fbd3a
--- /dev/null
+++ b/Utilities/FLTK/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
diff --git a/Utilities/FLTK/zlib/uncompr.c b/Utilities/FLTK/zlib/uncompr.c
new file mode 100644
index 0000000000000000000000000000000000000000..b59e3d0defb24b22c83167609f2cc5eb7620b96b
--- /dev/null
+++ b/Utilities/FLTK/zlib/uncompr.c
@@ -0,0 +1,61 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+            return Z_DATA_ERROR;
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
diff --git a/Utilities/FLTK/zlib/zconf.h b/Utilities/FLTK/zlib/zconf.h
new file mode 100644
index 0000000000000000000000000000000000000000..3cea897eda7975b0bc82a97e01bbbde230def9d8
--- /dev/null
+++ b/Utilities/FLTK/zlib/zconf.h
@@ -0,0 +1,323 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_  z_deflateInit_
+#  define deflate       z_deflate
+#  define deflateEnd    z_deflateEnd
+#  define inflateInit_  z_inflateInit_
+#  define inflate       z_inflate
+#  define inflateEnd    z_inflateEnd
+#  define deflateInit2_ z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy   z_deflateCopy
+#  define deflateReset  z_deflateReset
+#  define deflatePrime  z_deflatePrime
+#  define deflateParams z_deflateParams
+#  define deflateBound  z_deflateBound
+#  define inflateInit2_ z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync   z_inflateSync
+#  define inflateSyncPoint z_inflateSyncPoint
+#  define inflateCopy   z_inflateCopy
+#  define inflateReset  z_inflateReset
+#  define compress      z_compress
+#  define compress2     z_compress2
+#  define compressBound z_compressBound
+#  define uncompress    z_uncompress
+#  define adler32       z_adler32
+#  define crc32         z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte          z_Byte
+#  define uInt          z_uInt
+#  define uLong         z_uLong
+#  define Bytef         z_Bytef
+#  define charf         z_charf
+#  define intf          z_intf
+#  define uIntf         z_uIntf
+#  define uLongf        z_uLongf
+#  define voidpf        z_voidpf
+#  define voidp         z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if 0           /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>   /* for off_t */
+#  endif
+#  define z_off_t  off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define  z_off_t long
+#endif
+
+#if defined(__OS400__)
+#define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#  ifdef FAR
+#    undef FAR
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(deflateBound,"DEBND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(compressBound,"CMBND")
+#   pragma map(inflate_table,"INTABL")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/Utilities/FLTK/zlib/zlib.3 b/Utilities/FLTK/zlib/zlib.3
new file mode 100644
index 0000000000000000000000000000000000000000..890098449dd212d57d14d8214091af27354bedb0
--- /dev/null
+++ b/Utilities/FLTK/zlib/zlib.3
@@ -0,0 +1,159 @@
+.TH ZLIB 3 "17 November 2003"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms will be added later
+and will have the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+(for example if an input file is mmap'ed),
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I example.c
+and
+.IR minigzip.c .
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source,
+and are concerned primarily with bug fixes and portability enhancements.
+.LP
+A Java implementation of
+.I zlib
+is available in the Java Development Kit 1.1:
+.IP
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs@cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://www.cpan.org/modules/by-module/Compress/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk@magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://www.python.org/doc/lib/module-zlib.html
+.LP
+A
+.I zlib
+binding for
+.IR tcl (1),
+written by Andreas Kupries (a.kupries@westend.com),
+is availlable at:
+.IP
+http://www.westend.com/~kupries/doc/trf/man/man.html
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/unzip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+web site.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at either of these locations:
+.IP
+http://www.zlib.org
+.br
+http://www.gzip.org/zlib/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
+.br
+http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
+.br
+http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
+.LP
+These documents are also available in other formats from:
+.IP
+ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+.LP
+Mark Nelson (markn@ieee.org) wrote an article about
+.I zlib
+for the Jan. 1997 issue of  Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://www.gzip.org/zlib/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS
+Version 1.2.1
+Copyright (C) 1995-2003 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+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.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/Utilities/FLTK/zlib/zlib.h b/Utilities/FLTK/zlib/zlib.h
new file mode 100644
index 0000000000000000000000000000000000000000..92edf96ff3ecf8c671d06401eb5c2ff2c5162e71
--- /dev/null
+++ b/Utilities/FLTK/zlib/zlib.h
@@ -0,0 +1,1200 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.1, November 17th, 2003
+
+  Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler
+
+  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.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.1"
+#define ZLIB_VERNUM 0x1210
+
+/*
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The compressed data format used by the in-memory functions is the zlib
+  format, which is a zlib wrapper documented in RFC 1950, wrapped around a
+  deflate stream, which is itself documented in RFC 1951.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+     The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+     This library does not provide any functions to write gzip files in memory.
+  However such functions could be easily written using zlib's deflate function,
+  the documentation in the gzip RFC, and the examples in gzio.c.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  the compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  the value returned by deflateBound (see below). If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update data_type if it can make a good guess about
+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+  Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+  if and when it get to the next deflate block boundary. When decoding the zlib
+  or gzip format, this will cause inflate() to return immediately after the
+  header and before the first block. When doing a raw inflate, inflate() will
+  go ahead and process the first block, and will return when it gets to the end
+  of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64
+  if inflate() is currently decoding the last block in the deflate stream,
+  plus 128 if inflate() returned immediately after decoding an end-of-block
+  code or decoding the complete header up to just before the first byte of the
+  deflate stream. The end-of-block will not be indicated until all of the
+  uncompressed data from that block has been written to strm->next_out.  The
+  number of unused bits may in general be greater than seven, except when
+  bit 7 of data_type is set, in which case the number of unused bits will be
+  less than eight.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster approach
+  may be used for the single inflate() call.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call. So the only effect of the flush parameter in this implementation
+  is on the return value of inflate(), as noted below, or when it returns early
+  because Z_BLOCK is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm-adler to the adler32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the adler32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below. At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically.  Any information
+  contained in the gzip header is not retained, so applications that need that
+  information should instead use raw inflate, see inflateInit2() below, or
+  inflateBack() and perform their own processing of the gzip header and
+  trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing. If Z_DATA_ERROR is returned, the application may then
+  call inflateSync() to look for a good compression block if a partial recovery
+  of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer). It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+   determines the window size. deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding. Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper. The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero),
+   no header crc, and the operating system will be set to 255 (unknown).
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding). Filtered data consists mostly of small values with a somewhat
+   random distribution. In this case, the compression algorithm is tuned to
+   compress them better. The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+   Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+   parameter only affects the compression ratio but not the correctness of the
+   compressed output even if it is not set appropriately.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any
+   call of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit()
+   or deflateInit2().  This would be used to allocate an output buffer
+   for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+  is that this function is used to start off the deflate output with the
+  bits leftover from a previous deflate stream when appending to it.  As such,
+  this function can only be used for raw deflate, and must be used before the
+  first deflate() call after a deflateInit2() or deflateReset().  bits must be
+  less than or equal to 16, and that many of the least significant bits of
+  value will be inserted in the output.
+
+      deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used. If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+   determines the window size. inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream. This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values. If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is. Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding. Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+   memLevel). msg is set to null if there is no error message.  inflateInit2
+   does not perform any decompression apart from reading the zlib header if
+   present: this will be done by inflate(). (So next_in and avail_in may be
+   modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate
+   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by this call of
+   inflate. The compressor and decompressor must use exactly the same
+   dictionary (see deflateSetDictionary).
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+   be allocated, or Z_VERSION_ERROR if the version of the library does not
+   match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is more efficient than inflate() for
+   file i/o applications in that it avoids copying between the output and the
+   sliding window by simply making the window itself the output buffer.  This
+   function trusts the application to not change the output buffer passed by
+   the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free
+   the allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects
+   only the raw deflate stream to decompress.  This is different from the
+   normal behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format
+   error in the deflate stream (in which case strm->msg is set to indicate the
+   nature of the error), or Z_STREAM_ERROR if the stream was not properly
+   initialized.  In the case of Z_BUF_ERROR, an input or output error can be
+   distinguished using strm->next_in which will be Z_NULL only if in() returned
+   an error.  If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+   out() returning non-zero.  (in() will always be called before out(), so
+   strm->next_in is assured to be defined if out() returns non-zero.)  Note
+   that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level and memory usage,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least the value returned
+   by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before
+   a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+   Huffman only compression as in "wb1h", or 'R' for run-length encoding
+   as in "wb1R". (See the description of deflateInit2 for more information
+   about the strategy parameter.)
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).  */
+
+ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy. See the description
+   of deflateInit2 for the meaning of these parameters.
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT    gzwrite OF((gzFile file,
+                                   voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).  The number of
+   uncompressed bytes written is limited to 4095. The caller should assure that
+   this limit is not exceeded. If it is exceeded, then gzprintf() will return
+   return an error (0) with nothing written. In this case, there may also be a
+   buffer overflow with unpredictable consequences, which is possible only if
+   zlib was compiled with the insecure functions sprintf() or vsprintf()
+   because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+      Reads bytes from the compressed file until len-1 characters are read, or
+   a newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  The string is then terminated with a null
+   character.
+      gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
+/*
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
+/*
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT    gzungetc OF((int c, gzFile file));
+/*
+      Push one character back onto the stream to be read again later.
+   Only one character of push-back is allowed.  gzungetc() returns the
+   character pushed, or -1 on failure.  gzungetc() will fail if a
+   character has been pushed but not read yet, or if c is -1. The pushed
+   character will be discarded if the stream is repositioned with gzseek()
+   or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
+                                      z_off_t offset, int whence));
+/*
+      Sets the starting position for the next gzread or gzwrite on the
+   given compressed file. The offset represents a number of bytes in the
+   uncompressed data stream. The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow. If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+/*
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+
+   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file. This is analogous to the
+   clearerr() function in stdio. This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running crc with the bytes buf[0..len-1] and return the updated
+   crc. If buf is NULL, this function returns the required initial value
+   for the crc. Pre- and post-conditioning (one's complement) is performed
+   within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+        ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char   * ZEXPORT zError           OF((int err));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/Utilities/FLTK/zlib/zutil.c b/Utilities/FLTK/zlib/zutil.c
new file mode 100644
index 0000000000000000000000000000000000000000..0ef4f99f57ebd5e1c527e8b196f81c3bb32cfa77
--- /dev/null
+++ b/Utilities/FLTK/zlib/zutil.c
@@ -0,0 +1,319 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch (sizeof(uInt)) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch (sizeof(uLong)) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch (sizeof(voidpf)) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch (sizeof(z_off_t)) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef DEBUG
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1 << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1 << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1 << 20;
+#endif
+#ifdef FASTEST
+    flags += 1 << 21;
+#endif
+#ifdef STDC
+#  ifdef NO_vsnprintf
+        flags += 1 << 25;
+#    ifdef HAS_vsprintf_void
+        flags += 1 << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+        flags += 1 << 26;
+#    endif
+#  endif
+#else
+        flags += 1 << 24;
+#  ifdef NO_snprintf
+        flags += 1 << 25;
+#    ifdef HAS_sprintf_void
+        flags += 1 << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+        flags += 1 << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int z_verbose = verbose;
+
+void z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* does not exist on WCE */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void  zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/Utilities/FLTK/zlib/zutil.h b/Utilities/FLTK/zlib/zutil.h
new file mode 100644
index 0000000000000000000000000000000000000000..87b70acec23c2ce62a05853699c31df684d64c2d
--- /dev/null
+++ b/Utilities/FLTK/zlib/zutil.h
@@ -0,0 +1,258 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  if defined(__TURBOC__) || defined(__BORLANDC__)
+#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+       /* Allow compilation with ANSI keywords only enabled */
+       void _Cdecl farfree( void *block );
+       void *_Cdecl farmalloc( unsigned long nbytes );
+#    else
+#      include <alloc.h>
+#    endif
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#    include <unix.h> /* for fdopen */
+#  else
+#    ifndef fdopen
+#      define fdopen(fd,mode) NULL /* No fdopen() */
+#    endif
+#  endif
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#ifdef WIN32
+#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
+#    define OS_CODE  0x0b
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+     /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+        but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+     /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      define vsnprintf _vsnprintf
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#endif
+
+#ifdef HAVE_STRERROR
+   extern char *strerror OF((int));
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
+   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
+   extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int z_verbose;
+   extern void z_error    OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void   zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */