diff --git a/accessible/src/atk/nsAccessNodeWrap.cpp b/accessible/src/atk/nsAccessNodeWrap.cpp index 446cbfe6c4af..8c4b6463169a 100644 --- a/accessible/src/atk/nsAccessNodeWrap.cpp +++ b/accessible/src/atk/nsAccessNodeWrap.cpp @@ -38,6 +38,9 @@ #include "nsAccessNodeWrap.h" #include "nsApplicationAccessibleWrap.h" +#include "nsMaiInterfaceText.h" + +PRBool nsAccessNodeWrap::gHaveNewTextSignals = PR_FALSE; /* For documentation of the accessibility architecture, * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html @@ -68,6 +71,7 @@ nsAccessNodeWrap::~nsAccessNodeWrap() void nsAccessNodeWrap::InitAccessibility() { nsAccessNode::InitXPAccessibility(); + gHaveNewTextSignals = g_signal_lookup("text-insert", ATK_TYPE_TEXT); } void nsAccessNodeWrap::ShutdownAccessibility() diff --git a/accessible/src/atk/nsAccessNodeWrap.h b/accessible/src/atk/nsAccessNodeWrap.h index 22ceab81bb57..6ee2215a8505 100644 --- a/accessible/src/atk/nsAccessNodeWrap.h +++ b/accessible/src/atk/nsAccessNodeWrap.h @@ -53,6 +53,13 @@ public: // construction, destruction static void InitAccessibility(); static void ShutdownAccessibility(); + + /* + * do we have text-remove and text-insert signals if not we need to use + * text-changed see nsAccessibleWrap::FireAtkTextChangedEvent() and + * bug 619002 + */ + static PRBool gHaveNewTextSignals; }; #endif diff --git a/accessible/src/atk/nsAccessibleWrap.cpp b/accessible/src/atk/nsAccessibleWrap.cpp index e1137ff0139c..7473d71d2836 100644 --- a/accessible/src/atk/nsAccessibleWrap.cpp +++ b/accessible/src/atk/nsAccessibleWrap.cpp @@ -1361,14 +1361,27 @@ nsAccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent, PRInt32 start = event->GetStartOffset(); PRUint32 length = event->GetLength(); PRBool isInserted = event->IsTextInserted(); - PRBool isFromUserInput = aEvent->IsFromUserInput(); + char* signal_name = nsnull; - char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete", - isFromUserInput ? "" : kNonUserInputEvent, NULL); - g_signal_emit_by_name(aObject, signal_name, start, length); - g_free (signal_name); + if (gHaveNewTextSignals) { + nsAutoString text; + event->GetModifiedText(text); + signal_name = g_strconcat(isInserted ? "text-insert" : "text-remove", + isFromUserInput ? "" : "::system", NULL); + g_signal_emit_by_name(aObject, signal_name, start, length, + NS_ConvertUTF16toUTF8(text).get()); + } else { + // XXX remove this code and the gHaveNewTextSignals check when we can + // stop supporting old atk since it doesn't really work anyway + // see bug 619002 + signal_name = g_strconcat(isInserted ? "text_changed::insert" : + "text_changed::delete", + isFromUserInput ? "" : kNonUserInputEvent, NULL); + g_signal_emit_by_name(aObject, signal_name, start, length); + } + g_free(signal_name); return NS_OK; } diff --git a/accessible/src/html/nsHTMLFormControlAccessible.cpp b/accessible/src/html/nsHTMLFormControlAccessible.cpp index d76d6e4644a8..38d88793f02a 100644 --- a/accessible/src/html/nsHTMLFormControlAccessible.cpp +++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp @@ -422,6 +422,9 @@ nsHTMLTextFieldAccessible::GetNameInternal(nsAString& aName) NS_IMETHODIMP nsHTMLTextFieldAccessible::GetValue(nsAString& _retval) { + if (IsDefunct()) + return NS_ERROR_FAILURE; + if (NativeState() & states::PROTECTED) // Don't return password text! return NS_ERROR_FAILURE; diff --git a/browser/base/content/aboutDialog.js b/browser/base/content/aboutDialog.js index 4d00acca6be1..8ceb09ecfdd5 100644 --- a/browser/base/content/aboutDialog.js +++ b/browser/base/content/aboutDialog.js @@ -65,9 +65,9 @@ function init(aEvent) // Pref is unset } - // Include the build ID if this is a "pre" (i.e. non-release) build + // Include the build ID if this is an "a#" (nightly or aurora) build let version = Services.appinfo.version; - if (version.indexOf("pre") != -1) { + if (/a\d+$/.test(version)) { let buildID = Services.appinfo.appBuildID; let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8); document.getElementById("version").value += " (" + buildDate + ")"; diff --git a/browser/base/content/browser-tabview.js b/browser/base/content/browser-tabview.js index f4ce5ec1af46..9f44218680c2 100644 --- a/browser/base/content/browser-tabview.js +++ b/browser/base/content/browser-tabview.js @@ -171,11 +171,10 @@ let TabView = { show: function() { if (this.isVisible()) return; - + + let self = this; this._initFrame(function() { - let event = document.createEvent("Events"); - event.initEvent("tabviewshow", false, false); - dispatchEvent(event); + self._window.UI.showTabView(true); }); }, @@ -184,9 +183,7 @@ let TabView = { if (!this.isVisible()) return; - let event = document.createEvent("Events"); - event.initEvent("tabviewhide", false, false); - dispatchEvent(event); + this._window.UI.exit(); }, // ---------- diff --git a/browser/base/content/tabview/search.js b/browser/base/content/tabview/search.js index e22bef0a2b09..b7d17ad62c3e 100644 --- a/browser/base/content/tabview/search.js +++ b/browser/base/content/tabview/search.js @@ -132,7 +132,7 @@ var TabUtils = { // of active Panoramas as well as for windows in which // Panorama has yet to be activated. We uses object sniffing to // determine the type of tab and then returns its name. - return tab.label != undefined ? tab.label : tab.$tabTitle[0].innerHTML; + return tab.label != undefined ? tab.label : tab.$tabTitle[0].textContent; }, // --------- diff --git a/browser/base/content/tabview/ui.js b/browser/base/content/tabview/ui.js index 7ed660e2b1a4..d7fb0fec6e44 100644 --- a/browser/base/content/tabview/ui.js +++ b/browser/base/content/tabview/ui.js @@ -163,11 +163,6 @@ let UI = { this._storageSanity(data); this._pageBounds = data.pageBounds; - // ___ hook into the browser - gWindow.addEventListener("tabviewshow", function() { - self.showTabView(true); - }, false); - // ___ currentTab this._currentTab = gBrowser.selectedTab; @@ -226,10 +221,6 @@ let UI = { self.uninit(); }); - gWindow.addEventListener("tabviewhide", function() { - self.exit(); - }, false); - // ___ setup key handlers this._setTabViewFrameKeyHandlers(); diff --git a/browser/base/content/test/tabview/browser_tabview_bug595560.js b/browser/base/content/test/tabview/browser_tabview_bug595560.js index f85dc54c5b7b..85fdca91debf 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug595560.js +++ b/browser/base/content/test/tabview/browser_tabview_bug595560.js @@ -25,8 +25,10 @@ function onTabViewWindowLoaded() { window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false); ok(TabView.isVisible(), "Tab View is visible"); - let contentWindow = document.getElementById("tab-view").contentWindow; - testOne(contentWindow); + afterAllTabItemsUpdated(function() { + let contentWindow = document.getElementById("tab-view").contentWindow; + testOne(contentWindow); + }); } function testOne(contentWindow) { diff --git a/browser/base/content/test/tabview/browser_tabview_bug626791.js b/browser/base/content/test/tabview/browser_tabview_bug626791.js index bc91fd9c536e..4029255d6a61 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug626791.js +++ b/browser/base/content/test/tabview/browser_tabview_bug626791.js @@ -20,10 +20,6 @@ function test() { prefix + ": panorama button should not be in the toolbar"); } - let assertNumberOfGroups = function (num) { - is(cw.GroupItems.groupItems.length, num, prefix + ': there are ' + num + ' groups'); - } - let assertNumberOfTabs = function (num) { is(win.gBrowser.tabs.length, num, prefix + ': there are ' + num + ' tabs'); } @@ -91,7 +87,7 @@ function test() { assertToolbarButtonExists(); next(); - }); + }, win); } let testDragToCreateOrphan = function (tab) { @@ -124,14 +120,19 @@ function test() { prefix = 're-adding-after-removal'; assertToolbarButtonNotExists(); - TabView.firstUseExperienced = true; + win.TabView.firstUseExperienced = true; + assertToolbarButtonExists(); removeToolbarButton(); - - TabView.firstUseExperienced = true; - TabView._addToolbarButton(); - assertToolbarButtonNotExists(); - next(); + + win.close(); + + newWindowWithTabView(function (newWin) { + win = newWin; + win.TabView.firstUseExperienced = true; + assertToolbarButtonNotExists(); + next(); + }); } let tests = [testNameGroup, testDragToCreateGroup, testCreateOrphan, @@ -140,39 +141,39 @@ function test() { let next = function () { let test = tests.shift(); - if (win) - win.close(); - if (!test) { finish(); return; } - newWindowWithTabView( - function (newWin) { - cw = win.TabView.getContentWindow(); - let groupItem = cw.GroupItems.groupItems[0]; - groupItem.setSize(200, 200, true); - groupItem.setUserSize(); + if (win) + win.close(); + TabView.firstUseExperienced = false; + + let onLoad = function (newWin) { + win = newWin; + removeToolbarButton(); + } + + let onShow = function () { + cw = win.TabView.getContentWindow(); + + let groupItem = cw.GroupItems.groupItems[0]; + groupItem.setSize(200, 200, true); + groupItem.setUserSize(); + + SimpleTest.waitForFocus(function () { assertToolbarButtonNotExists(); test(); - }, - function(newWin) { - win = newWin; - removeToolbarButton(); - TabView.firstUseExperienced = false; - TabView.init(); - } - ); + }, cw); + } + + newWindowWithTabView(onShow, onLoad); } waitForExplicitFinish(); - - registerCleanupFunction(function () { - if (win && !win.closed) - win.close(); - }); + registerCleanupFunction(function () win && win.close()); next(); } diff --git a/browser/components/sessionstore/test/browser/browser_586068-cascaded_restore.js b/browser/components/sessionstore/test/browser/browser_586068-cascaded_restore.js index ef6122bd1c2c..52037cb388c7 100644 --- a/browser/components/sessionstore/test/browser/browser_586068-cascaded_restore.js +++ b/browser/components/sessionstore/test/browser/browser_586068-cascaded_restore.js @@ -760,6 +760,3 @@ function countTabs() { return [needsRestore, isRestoring, wasRestored]; } -function r() { - return "" + Date.now() + Math.random(); -} diff --git a/browser/components/sessionstore/test/browser/browser_590268.js b/browser/components/sessionstore/test/browser/browser_590268.js index a44666c49a9c..2ab3de505306 100644 --- a/browser/components/sessionstore/test/browser/browser_590268.js +++ b/browser/components/sessionstore/test/browser/browser_590268.js @@ -170,8 +170,3 @@ function test() { // Restore state ss.setBrowserState(JSON.stringify(state)); } - -// Helper function to create a random value -function r() { - return "" + Date.now() + Math.random(); -} diff --git a/browser/components/sessionstore/test/browser/browser_600545.js b/browser/components/sessionstore/test/browser/browser_600545.js index 780f1b5f5565..43b59a8879d2 100644 --- a/browser/components/sessionstore/test/browser/browser_600545.js +++ b/browser/components/sessionstore/test/browser/browser_600545.js @@ -50,54 +50,6 @@ function testBug600545() { // Set the pref to false to cause non-app tabs to be stripped out on a save Services.prefs.setBoolPref("browser.sessionstore.resume_from_crash", false); - // Need to wait for SessionStore's saveState function to be called - // so that non-pinned tabs will be stripped from non-active window - function waitForSaveState(aSaveStateCallback) { - let topic = "sessionstore-state-write"; - Services.obs.addObserver(function() { - Services.obs.removeObserver(arguments.callee, topic, false); - executeSoon(aSaveStateCallback); - }, topic, false); - }; - - // Need to wait for all tabs to be restored before reading browser state - function waitForBrowserState(aState, aSetStateCallback) { - let tabsRestored = 0; - let expectedTabs = getStateTabCount(aState); - - // We know that there are only 2 windows total, so just be specific - let newWin; - - // Used to determine when tabs have been restored - function onTabRestored(aEvent) { - if (++tabsRestored == expectedTabs) { - gBrowser.tabContainer.removeEventListener("SSTabRestored", onTabRestored, true); - newWin.gBrowser.tabContainer.removeEventListener("SSTabRestored", onTabRestored, true); - executeSoon(aSetStateCallback); - } - } - - // We also want to catch the 2nd window, so we need to observe domwindowopened - function windowObserver(aSubject, aTopic, aData) { - let theWin = aSubject.QueryInterface(Ci.nsIDOMWindow); - if (aTopic == "domwindowopened") { - theWin.addEventListener("load", function() { - theWin.removeEventListener("load", arguments.callee, false); - - // So we can remove the event listener in onTabRestored - newWin = theWin; - - Services.ww.unregisterNotification(windowObserver); - theWin.gBrowser.tabContainer.addEventListener("SSTabRestored", onTabRestored, true); - }, false); - } - } - - Services.ww.registerNotification(windowObserver); - gBrowser.tabContainer.addEventListener("SSTabRestored", onTabRestored, true); - ss.setBrowserState(JSON.stringify(aState)); - } - // This tests the following use case: // When multiple windows are open and browser.sessionstore.resume_from_crash // preference is false, tab session data for non-active window is stripped for @@ -124,6 +76,8 @@ function testBug600545() { ] }; waitForBrowserState(state, function() { + // Need to wait for SessionStore's saveState function to be called + // so that non-pinned tabs will be stripped from non-active window waitForSaveState(function () { let expectedNumberOfTabs = getStateTabCount(state); let retrievedState = JSON.parse(ss.getBrowserState()); diff --git a/browser/components/sessionstore/test/browser/browser_607016.js b/browser/components/sessionstore/test/browser/browser_607016.js index 7b2e93c0288a..e2c77d51b901 100644 --- a/browser/components/sessionstore/test/browser/browser_607016.js +++ b/browser/components/sessionstore/test/browser/browser_607016.js @@ -148,7 +148,3 @@ function test() { ss.setBrowserState(JSON.stringify(state)); } -// Helper function to create a random value -function r() { - return "" + Date.now() + Math.random(); -} diff --git a/browser/components/sessionstore/test/browser/browser_618151.js b/browser/components/sessionstore/test/browser/browser_618151.js index 8aa27e307d71..a6df99b495cd 100644 --- a/browser/components/sessionstore/test/browser/browser_618151.js +++ b/browser/components/sessionstore/test/browser/browser_618151.js @@ -80,19 +80,6 @@ function runNextTest() { } } -// helper, works only for single window -function waitForBrowserState(aState, aSetStateCallback) { - let tabsRestored = 0; - gBrowser.tabContainer.addEventListener("SSTabRestored", function() { - if (++tabsRestored == aState.windows[0].tabs.length) { - gBrowser.tabContainer.removeEventListener("SSTabRestored", arguments.callee, true); - executeSoon(aSetStateCallback); - } - }, true); - ss.setBrowserState(JSON.stringify(aState)); -} - - function test_setup() { function onSSTabRestored(aEvent) { gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false); diff --git a/browser/components/shell/src/nsGNOMEShellService.cpp b/browser/components/shell/src/nsGNOMEShellService.cpp index ca7043209925..2fde1ebe5876 100644 --- a/browser/components/shell/src/nsGNOMEShellService.cpp +++ b/browser/components/shell/src/nsGNOMEShellService.cpp @@ -106,20 +106,23 @@ nsGNOMEShellService::Init() { nsresult rv; - // GConf _must_ be available, or we do not allow + // GConf or GIO _must_ be available, or we do not allow // CreateInstance to succeed. nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (!gconf) + if (!gconf && !giovfs) return NS_ERROR_NOT_AVAILABLE; // Check G_BROKEN_FILENAMES. If it's set, then filenames in glib use // the locale encoding. If it's not set, they use UTF-8. mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nsnull; + if (GetAppPathFromLauncher()) + return NS_OK; + nsCOMPtr dirSvc (do_GetService("@mozilla.org/file/directory_service;1")); NS_ENSURE_TRUE(dirSvc, NS_ERROR_NOT_AVAILABLE); @@ -137,6 +140,34 @@ nsGNOMEShellService::Init() NS_IMPL_ISUPPORTS1(nsGNOMEShellService, nsIShellService) +PRBool +nsGNOMEShellService::GetAppPathFromLauncher() +{ + gchar *tmp; + + const char *launcher = PR_GetEnv("MOZ_APP_LAUNCHER"); + if (!launcher) + return PR_FALSE; + + if (g_path_is_absolute(launcher)) { + mAppPath = launcher; + tmp = g_path_get_basename(launcher); + gchar *fullpath = g_find_program_in_path(tmp); + if (fullpath && mAppPath.Equals(fullpath)) + mAppIsInPath = PR_TRUE; + g_free(fullpath); + } else { + tmp = g_find_program_in_path(launcher); + if (!tmp) + return PR_FALSE; + mAppPath = tmp; + mAppIsInPath = PR_TRUE; + } + + g_free(tmp); + return PR_TRUE; +} + PRBool nsGNOMEShellService::KeyMatchesAppName(const char *aKeyValue) const { @@ -163,6 +194,27 @@ nsGNOMEShellService::KeyMatchesAppName(const char *aKeyValue) const return matches; } +PRBool +nsGNOMEShellService::CheckHandlerMatchesAppName(const nsACString &handler) const +{ + gint argc; + gchar **argv; + nsCAutoString command(handler); + + // The string will be something of the form: [/path/to/]browser "%s" + // We want to remove all of the parameters and get just the binary name. + + if (g_shell_parse_argv(command.get(), &argc, &argv, NULL) && argc > 0) { + command.Assign(argv[0]); + g_strfreev(argv); + } + + if (!KeyMatchesAppName(command.get())) + return PR_FALSE; // the handler is set to another app + + return PR_TRUE; +} + NS_IMETHODIMP nsGNOMEShellService::IsDefaultBrowser(PRBool aStartupCheck, PRBool* aIsDefaultBrowser) @@ -172,31 +224,37 @@ nsGNOMEShellService::IsDefaultBrowser(PRBool aStartupCheck, mCheckedThisSession = PR_TRUE; nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); PRBool enabled; nsCAutoString handler; + nsCOMPtr gioApp; for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) { if (!appProtocols[i].essential) continue; - handler.Truncate(); - gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name), - &enabled, handler); + if (gconf) { + handler.Truncate(); + gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name), + &enabled, handler); - // The string will be something of the form: [/path/to/]browser "%s" - // We want to remove all of the parameters and get just the binary name. - - gint argc; - gchar **argv; - - if (g_shell_parse_argv(handler.get(), &argc, &argv, NULL) && argc > 0) { - handler.Assign(argv[0]); - g_strfreev(argv); + if (!CheckHandlerMatchesAppName(handler) || !enabled) + return NS_OK; // the handler is disabled or set to another app } - if (!KeyMatchesAppName(handler.get()) || !enabled) - return NS_OK; // the handler is disabled or set to another app + if (giovfs) { + handler.Truncate(); + giovfs->GetAppForURIScheme(nsDependentCString(appProtocols[i].name), + getter_AddRefs(gioApp)); + if (!gioApp) + return NS_OK; + + gioApp->GetCommand(handler); + + if (!CheckHandlerMatchesAppName(handler)) + return NS_OK; // the handler is set to another app + } } *aIsDefaultBrowser = PR_TRUE; @@ -214,9 +272,20 @@ nsGNOMEShellService::SetDefaultBrowser(PRBool aClaimAllTypes, #endif nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); if (gconf) { - nsCAutoString appKeyValue(mAppPath); - appKeyValue.Append(" \"%s\""); + nsCAutoString appKeyValue; + if (mAppIsInPath) { + // mAppPath is in the users path, so use only the basename as the launcher + gchar *tmp = g_path_get_basename(mAppPath.get()); + appKeyValue = tmp; + g_free(tmp); + } else { + appKeyValue = mAppPath; + } + + appKeyValue.AppendLiteral(" %s"); + for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) { if (appProtocols[i].essential || aClaimAllTypes) { gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name), @@ -225,13 +294,8 @@ nsGNOMEShellService::SetDefaultBrowser(PRBool aClaimAllTypes, } } - // set handler for .html and xhtml files and MIME types: - if (aClaimAllTypes) { + if (giovfs) { nsresult rv; - nsCOMPtr giovfs = - do_GetService(NS_GIOSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, NS_OK); - nsCOMPtr bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -254,10 +318,20 @@ nsGNOMEShellService::SetDefaultBrowser(PRBool aClaimAllTypes, getter_AddRefs(appInfo)); NS_ENSURE_SUCCESS(rv, rv); - // Add mime types for html, xhtml extension and set app to just created appinfo. - for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) { - appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType)); - appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions)); + // set handler for the protocols + for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) { + if (appProtocols[i].essential || aClaimAllTypes) { + appInfo->SetAsDefaultForURIScheme(nsDependentCString(appProtocols[i].name)); + } + } + + // set handler for .html and xhtml files and MIME types: + if (aClaimAllTypes) { + // Add mime types for html, xhtml extension and set app to just created appinfo. + for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) { + appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType)); + appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions)); + } } } @@ -367,24 +441,26 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, // if the file was written successfully, set it as the system wallpaper nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCAutoString options; - if (aPosition == BACKGROUND_TILE) - options.Assign("wallpaper"); - else if (aPosition == BACKGROUND_STRETCH) - options.Assign("stretched"); - else - options.Assign("centered"); + if (gconf) { + nsCAutoString options; + if (aPosition == BACKGROUND_TILE) + options.Assign("wallpaper"); + else if (aPosition == BACKGROUND_STRETCH) + options.Assign("stretched"); + else + options.Assign("centered"); - gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options); + gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options); - // Set the image to an empty string first to force a refresh - // (since we could be writing a new image on top of an existing - // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) - gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), - EmptyCString()); + // Set the image to an empty string first to force a refresh + // (since we could be writing a new image on top of an existing + // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) + gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), + EmptyCString()); - gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath); - gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), PR_TRUE); + gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath); + gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), PR_TRUE); + } return rv; } @@ -398,7 +474,9 @@ nsGNOMEShellService::GetDesktopBackgroundColor(PRUint32 *aColor) nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); nsCAutoString background; - gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); + if (gconf) { + gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); + } if (background.IsEmpty()) { *aColor = 0; @@ -437,10 +515,12 @@ nsGNOMEShellService::SetDesktopBackgroundColor(PRUint32 aColor) NS_ASSERTION(aColor <= 0xffffff, "aColor has extra bits"); nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCAutoString colorString; - ColorToCString(aColor, colorString); + if (gconf) { + nsCAutoString colorString; + ColorToCString(aColor, colorString); - gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString); + gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString); + } return NS_OK; } @@ -456,7 +536,17 @@ nsGNOMEShellService::OpenApplication(PRInt32 aApplication) else return NS_ERROR_NOT_AVAILABLE; + nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); + if (giovfs) { + nsCOMPtr gioApp; + giovfs->GetAppForURIScheme(scheme, getter_AddRefs(gioApp)); + if (gioApp) + return gioApp->Launch(EmptyCString()); + } + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + if (!gconf) + return NS_ERROR_FAILURE; PRBool enabled; nsCAutoString appCommand; diff --git a/browser/components/shell/src/nsGNOMEShellService.h b/browser/components/shell/src/nsGNOMEShellService.h index 1fdbd0152b59..d5171b293702 100644 --- a/browser/components/shell/src/nsGNOMEShellService.h +++ b/browser/components/shell/src/nsGNOMEShellService.h @@ -43,7 +43,7 @@ class nsGNOMEShellService : public nsIShellService { public: - nsGNOMEShellService() : mCheckedThisSession(PR_FALSE) { } + nsGNOMEShellService() : mCheckedThisSession(PR_FALSE), mAppIsInPath(PR_FALSE) { } NS_DECL_ISUPPORTS NS_DECL_NSISHELLSERVICE @@ -54,10 +54,13 @@ private: ~nsGNOMEShellService() {} NS_HIDDEN_(PRBool) KeyMatchesAppName(const char *aKeyValue) const; + NS_HIDDEN_(PRBool) CheckHandlerMatchesAppName(const nsACString& handler) const; + NS_HIDDEN_(PRBool) GetAppPathFromLauncher(); PRPackedBool mCheckedThisSession; PRPackedBool mUseLocaleFilenames; nsCString mAppPath; + PRPackedBool mAppIsInPath; }; #endif // nsgnomeshellservice_h____ diff --git a/build/automation.py.in b/build/automation.py.in index c90e3b766db7..a29185d671a9 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -634,10 +634,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t pExitCode = ctypes.wintypes.DWORD() ctypes.windll.kernel32.GetExitCodeProcess(pHandle, ctypes.byref(pExitCode)) ctypes.windll.kernel32.CloseHandle(pHandle) - if (pExitCode.value == STILL_ACTIVE): - return True - else: - return False + return pExitCode.value == STILL_ACTIVE def killPid(self, pid): PROCESS_TERMINATE = 0x0001 @@ -668,10 +665,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t # Wait on it to see if it's a zombie. This can throw OSError.ECHILD if # the process terminates before we get to this point. wpid, wstatus = os.waitpid(pid, os.WNOHANG) - if wpid == 0: - return True - - return False + return wpid == 0 except OSError, err: # Catch the errors we might expect from os.kill/os.waitpid, # and re-raise any others @@ -917,49 +911,35 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t return status - """ - Copies an "installed" extension into the extensions directory of the given profile - extensionSource - the source location of the extension files. This can be either + """ + Copies an extension into the extensions directory of the given profile. + extensionSource - the source location of the extension files. This can be either a directory or a path to an xpi file. profileDir - the profile directory we are copying into. We will create the - "extensions" directory there if it doesn't exist + "extensions" directory there if it doesn't exist. extensionID - the id of the extension to be used as the containing directory for the - extension, i.e. + extension, if extensionSource is a directory, i.e. this is the name of the folder in the /extensions/ """ - def installExtension(self, extensionSource, profileDir, extensionID): - if (not os.path.exists(extensionSource)): - self.log.info("INFO | automation.py | Cannot install extension no source at: %s", extensionSource) - return - - if (not os.path.exists(profileDir)): - self.log.info("INFO | automation.py | Cannot install extension invalid profileDir at: %s", profileDir) + def installExtension(self, extensionSource, profileDir, extensionID = None): + if not os.path.isdir(profileDir): + self.log.info("INFO | automation.py | Cannot install extension, invalid profileDir at: %s", profileDir) return - # See if we have an XPI or a directory - if (os.path.isfile(extensionSource)): - tmpd = tempfile.mkdtemp() - extrootdir = self.extractZip(extensionSource, tmpd) - else: - extrootdir = extensionSource extnsdir = os.path.join(profileDir, "extensions") - extnshome = os.path.join(extnsdir, extensionID) - # Now we copy the extension source into the extnshome - shutil.copytree(extrootdir, extnshome) - - def extractZip(self, filename, dest): - z = zipfile.ZipFile(filename, 'r') - for n in z.namelist(): - fullpath = os.path.join(dest, n) - parentdir = os.path.dirname(fullpath) - if not os.path.isdir(parentdir): - os.makedirs(parentdir) - if (not n.endswith(os.sep)): - data = z.read(n) - f = open(fullpath, 'w') - f.write(data) - f.close() - z.close() - return dest + if os.path.isfile(extensionSource): + # Copy extension xpi directly. + # "destination file is created or overwritten". + shutil.copy2(extensionSource, extnsdir) + elif os.path.isdir(extensionSource): + if extensionID == None: + self.log.info("INFO | automation.py | Cannot install extension, missing extensionID") + return + # Copy extension tree into its own directory. + # "destination directory must not already exist". + shutil.copytree(extensionSource, os.path.join(extnsdir, extensionID)) + else: + self.log.info("INFO | automation.py | Cannot install extension, invalid extensionSource at: %s", extensionSource) + return diff --git a/config/config.mk b/config/config.mk index 27257382c15e..c2276abb5587 100644 --- a/config/config.mk +++ b/config/config.mk @@ -342,6 +342,11 @@ ifdef SIMPLE_PROGRAMS NO_PROFILE_GUIDED_OPTIMIZE = 1 endif +# No sense in profiling unit tests +ifdef CPP_UNIT_TESTS +NO_PROFILE_GUIDED_OPTIMIZE = 1 +endif + # Enable profile-based feedback ifndef NO_PROFILE_GUIDED_OPTIMIZE ifdef MOZ_PROFILE_GENERATE @@ -442,11 +447,10 @@ PURIFY = purify $(PURIFYOPTIONS) QUANTIFY = quantify $(QUANTIFYOPTIONS) ifdef CROSS_COMPILE XPIDL_COMPILE = $(LIBXUL_DIST)/host/bin/host_xpidl$(HOST_BIN_SUFFIX) -XPIDL_LINK = $(LIBXUL_DIST)/host/bin/host_xpt_link$(HOST_BIN_SUFFIX) else XPIDL_COMPILE = $(LIBXUL_DIST)/bin/xpidl$(BIN_SUFFIX) -XPIDL_LINK = $(LIBXUL_DIST)/bin/xpt_link$(BIN_SUFFIX) endif +XPIDL_LINK = $(PYTHON) $(SDK_BIN_DIR)/xpt.py link # Java macros JAVA_GEN_DIR = _javagen diff --git a/config/rules.mk b/config/rules.mk index c869a11f3bd1..619263bab59c 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -361,6 +361,11 @@ ifeq (,$(filter-out WINNT WINCE,$(HOST_OS_ARCH))) HOST_PDBFILE=$(basename $(@F)).pdb endif +# Don't build SIMPLE_PROGRAMS during the MOZ_PROFILE_GENERATE pass +ifdef MOZ_PROFILE_GENERATE +SIMPLE_PROGRAMS := +endif + ifndef TARGETS TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(JAVA_LIBRARY) endif @@ -1570,7 +1575,7 @@ $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_COMPILE) $(XPIDL_GEN_DIR)/.done # no need to link together if XPIDLSRCS contains only XPIDL_MODULE ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS))) -$(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) $(GLOBAL_DEPS) $(XPIDL_LINK) +$(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) $(GLOBAL_DEPS) $(XPIDL_LINK) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) endif # XPIDL_MODULE.xpt != XPIDLSRCS @@ -1701,7 +1706,7 @@ endif endif # SDK_LIBRARY -ifneq (,$(SDK_BINARY)) +ifneq (,$(strip $(SDK_BINARY))) $(SDK_BIN_DIR):: $(NSINSTALL) -D $@ diff --git a/configure.in b/configure.in index 8f667097278f..e0da9a9f62c8 100644 --- a/configure.in +++ b/configure.in @@ -3589,36 +3589,39 @@ AC_SUBST(XEXT_LIBS) AC_SUBST(XT_LIBS) AC_SUBST(XSS_LIBS) -AC_MSG_CHECKING(for ARM SIMD support in compiler) -# We try to link so that this also fails when -# building with LTO. -AC_TRY_LINK([], - [asm("uqadd8 r1, r1, r2");], - result="yes", result="no") -AC_MSG_RESULT("$result") -if test "$result" = "yes"; then - AC_DEFINE(HAVE_ARM_SIMD) - HAVE_ARM_SIMD=1 -fi -AC_SUBST(HAVE_ARM_SIMD) +if test "$CPU_ARCH" = "arm"; then + AC_MSG_CHECKING(for ARM SIMD support in compiler) + # We try to link so that this also fails when + # building with LTO. + AC_TRY_LINK([], + [asm("uqadd8 r1, r1, r2");], + result="yes", result="no") + AC_MSG_RESULT("$result") + if test "$result" = "yes"; then + AC_DEFINE(HAVE_ARM_SIMD) + HAVE_ARM_SIMD=1 + fi -AC_MSG_CHECKING(for ARM NEON support in compiler) -_SAVE_CFLAGS="$CFLAGS" -if test "$GNU_CC"; then - # gcc needs -mfpu=neon to recognize NEON instructions - CFLAGS="$CFLAGS -mfpu=neon -mfloat-abi=softfp" -fi -# We try to link so that this also fails when -# building with LTO. -AC_TRY_LINK([], - [asm("vadd.i8 d0, d0, d0");], - result="yes", result="no") -AC_MSG_RESULT("$result") -if test "$result" = "yes"; then - AC_DEFINE(HAVE_ARM_NEON) - HAVE_ARM_NEON=1 -fi -CFLAGS="$_SAVE_CFLAGS" + AC_MSG_CHECKING(for ARM NEON support in compiler) + _SAVE_CFLAGS="$CFLAGS" + if test "$GNU_CC"; then + # gcc needs -mfpu=neon to recognize NEON instructions + CFLAGS="$CFLAGS -mfpu=neon -mfloat-abi=softfp" + fi + # We try to link so that this also fails when + # building with LTO. + AC_TRY_LINK([], + [asm("vadd.i8 d0, d0, d0");], + result="yes", result="no") + AC_MSG_RESULT("$result") + if test "$result" = "yes"; then + AC_DEFINE(HAVE_ARM_NEON) + HAVE_ARM_NEON=1 + fi + CFLAGS="$_SAVE_CFLAGS" +fi # CPU_ARCH = arm + +AC_SUBST(HAVE_ARM_SIMD) AC_SUBST(HAVE_ARM_NEON) dnl ======================================================== diff --git a/content/base/public/nsDOMFile.h b/content/base/public/nsDOMFile.h index 3cc4c57621a6..f0fd79c7cad8 100644 --- a/content/base/public/nsDOMFile.h +++ b/content/base/public/nsDOMFile.h @@ -44,6 +44,7 @@ #include "nsIDOMFileList.h" #include "nsIDOMFileError.h" #include "nsIInputStream.h" +#include "nsIJSNativeInitializer.h" #include "nsCOMArray.h" #include "nsCOMPtr.h" #include "mozilla/AutoRestore.h" @@ -57,13 +58,16 @@ class nsIInputStream; class nsIClassInfo; class nsDOMFile : public nsIDOMFile, + public nsIDOMBlob_MOZILLA_2_0_BRANCH, public nsIXHRSendable, - public nsICharsetDetectionObserver + public nsICharsetDetectionObserver, + public nsIJSNativeInitializer { public: NS_DECL_ISUPPORTS NS_DECL_NSIDOMBLOB NS_DECL_NSIDOMFILE + NS_DECL_NSIDOMBLOB_MOZILLA_2_0_BRANCH NS_DECL_NSIXHRSENDABLE nsDOMFile(nsIFile *aFile, const nsAString& aContentType) @@ -96,6 +100,17 @@ public: // from nsICharsetDetectionObserver NS_IMETHOD Notify(const char *aCharset, nsDetectionConfident aConf); + // nsIJSNativeInitializer + NS_IMETHOD Initialize(nsISupports* aOwner, + JSContext* aCx, + JSObject* aObj, + PRUint32 aArgc, + jsval* aArgv); + + // DOMClassInfo constructor (for File("foo")) + static nsresult + NewFile(nsISupports* *aNewObject); + protected: nsCOMPtr mFile; @@ -149,8 +164,9 @@ public: NS_IMETHOD GetSize(PRUint64*); NS_IMETHOD GetInternalStream(nsIInputStream**); NS_IMETHOD GetMozFullPathInternal(nsAString&); - NS_IMETHOD Slice(PRUint64 aStart, PRUint64 aLength, - const nsAString& aContentType, nsIDOMBlob **aBlob); + NS_IMETHOD MozSlice(PRInt64 aStart, PRInt64 aEnd, + const nsAString& aContentType, PRUint8 optional_argc, + nsIDOMBlob **aBlob); protected: friend class DataOwnerAdapter; // Needs to see DataOwner diff --git a/content/base/public/nsIDOMFile.idl b/content/base/public/nsIDOMFile.idl index 9cb5bdca0418..57506b6acf5a 100644 --- a/content/base/public/nsIDOMFile.idl +++ b/content/base/public/nsIDOMFile.idl @@ -49,9 +49,9 @@ interface nsIDOMBlob : nsISupports readonly attribute unsigned long long size; readonly attribute DOMString type; - nsIDOMBlob slice(in unsigned long long start, - in unsigned long long length, - [optional] in DOMString contentType); + [noscript] nsIDOMBlob slice(in unsigned long long start, + in unsigned long long length, + [optional] in DOMString contentType); [noscript] readonly attribute nsIInputStream internalStream; // The caller is responsible for releasing the internalUrl from the @@ -59,6 +59,14 @@ interface nsIDOMBlob : nsISupports [noscript] DOMString getInternalUrl(in nsIPrincipal principal); }; +[scriptable, uuid(cb5b4191-a555-4e57-b8d2-88091184b59f)] +interface nsIDOMBlob_MOZILLA_2_0_BRANCH : nsISupports +{ + [optional_argc] nsIDOMBlob mozSlice(in long long start, + [optional] in long long end, + [optional] in DOMString contentType); +}; + [scriptable, uuid(ae1405b0-e411-481e-9606-b29ec7982687)] interface nsIDOMFile : nsIDOMBlob { diff --git a/content/base/src/nsDOMDocumentType.cpp b/content/base/src/nsDOMDocumentType.cpp index 20fb07ef806f..d61c9415f936 100644 --- a/content/base/src/nsDOMDocumentType.cpp +++ b/content/base/src/nsDOMDocumentType.cpp @@ -58,8 +58,6 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType, nsNodeInfoManager *aNodeInfoManager, nsIPrincipal *aPrincipal, nsIAtom *aName, - nsIDOMNamedNodeMap *aEntities, - nsIDOMNamedNodeMap *aNotations, const nsAString& aPublicId, const nsAString& aSystemId, const nsAString& aInternalSubset) @@ -69,17 +67,13 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType, NS_ENSURE_ARG_POINTER(aDocType); NS_ENSURE_ARG_POINTER(aName); - nsresult rv; - nsRefPtr nimgr; if (aNodeInfoManager) { nimgr = aNodeInfoManager; } else { nimgr = new nsNodeInfoManager(); - NS_ENSURE_TRUE(nimgr, NS_ERROR_OUT_OF_MEMORY); - - rv = nimgr->Init(nsnull); + nsresult rv = nimgr->Init(nsnull); NS_ENSURE_SUCCESS(rv, rv); nimgr->SetDocumentPrincipal(aPrincipal); @@ -90,12 +84,8 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType, kNameSpaceID_None); NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY); - *aDocType = new nsDOMDocumentType(ni.forget(), aName, aEntities, aNotations, - aPublicId, aSystemId, aInternalSubset); - if (!*aDocType) { - return NS_ERROR_OUT_OF_MEMORY; - } - + *aDocType = new nsDOMDocumentType(ni.forget(), aName, aPublicId, aSystemId, + aInternalSubset); NS_ADDREF(*aDocType); return NS_OK; @@ -103,15 +93,11 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType, nsDOMDocumentType::nsDOMDocumentType(already_AddRefed aNodeInfo, nsIAtom *aName, - nsIDOMNamedNodeMap *aEntities, - nsIDOMNamedNodeMap *aNotations, const nsAString& aPublicId, const nsAString& aSystemId, const nsAString& aInternalSubset) : nsGenericDOMDataNode(aNodeInfo), mName(aName), - mEntities(aEntities), - mNotations(aNotations), mPublicId(aPublicId), mSystemId(aSystemId), mInternalSubset(aInternalSubset) @@ -158,30 +144,6 @@ nsDOMDocumentType::GetName(nsAString& aName) return NS_OK; } -NS_IMETHODIMP -nsDOMDocumentType::GetEntities(nsIDOMNamedNodeMap** aEntities) -{ - NS_ENSURE_ARG_POINTER(aEntities); - - *aEntities = mEntities; - - NS_IF_ADDREF(*aEntities); - - return NS_OK; -} - -NS_IMETHODIMP -nsDOMDocumentType::GetNotations(nsIDOMNamedNodeMap** aNotations) -{ - NS_ENSURE_ARG_POINTER(aNotations); - - *aNotations = mNotations; - - NS_IF_ADDREF(*aNotations); - - return NS_OK; -} - NS_IMETHODIMP nsDOMDocumentType::GetPublicId(nsAString& aPublicId) { @@ -238,8 +200,8 @@ nsGenericDOMDataNode* nsDOMDocumentType::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const { nsCOMPtr ni = aNodeInfo; - return new nsDOMDocumentType(ni.forget(), mName, mEntities, mNotations, - mPublicId, mSystemId, mInternalSubset); + return new nsDOMDocumentType(ni.forget(), mName, mPublicId, mSystemId, + mInternalSubset); } nsresult diff --git a/content/base/src/nsDOMDocumentType.h b/content/base/src/nsDOMDocumentType.h index f6e1a00028db..015f0130cd95 100644 --- a/content/base/src/nsDOMDocumentType.h +++ b/content/base/src/nsDOMDocumentType.h @@ -39,8 +39,8 @@ * Implementation of DOM Core's nsIDOMDocumentType node. */ -#ifndef nsDOMDocumentType_h___ -#define nsDOMDocumentType_h___ +#ifndef nsDOMDocumentType_h +#define nsDOMDocumentType_h #include "nsCOMPtr.h" #include "nsIDOMDocumentType.h" @@ -59,8 +59,6 @@ class nsDOMDocumentType : public nsGenericDOMDataNode, public: nsDOMDocumentType(already_AddRefed aNodeInfo, nsIAtom *aName, - nsIDOMNamedNodeMap *aEntities, - nsIDOMNamedNodeMap *aNotations, const nsAString& aPublicId, const nsAString& aSystemId, const nsAString& aInternalSubset); @@ -86,8 +84,6 @@ public: virtual nsXPCClassInfo* GetClassInfo(); protected: nsCOMPtr mName; - nsCOMPtr mEntities; - nsCOMPtr mNotations; nsString mPublicId; nsString mSystemId; nsString mInternalSubset; @@ -98,10 +94,8 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType, nsNodeInfoManager *aOwnerDoc, nsIPrincipal *aPrincipal, nsIAtom *aName, - nsIDOMNamedNodeMap *aEntities, - nsIDOMNamedNodeMap *aNotations, const nsAString& aPublicId, const nsAString& aSystemId, const nsAString& aInternalSubset); -#endif // nsDOMDocument_h___ +#endif // nsDOMDocumentType_h diff --git a/content/base/src/nsDOMFile.cpp b/content/base/src/nsDOMFile.cpp index d22f004826d3..ee0103fc1085 100644 --- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -64,6 +64,7 @@ #include "nsFileDataProtocolHandler.h" #include "nsStringStream.h" #include "CheckedInt.h" +#include "nsJSUtils.h" #include "plbase64.h" #include "prmem.h" @@ -139,9 +140,11 @@ DOMCI_DATA(Blob, nsDOMFile) NS_INTERFACE_MAP_BEGIN(nsDOMFile) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile) NS_INTERFACE_MAP_ENTRY(nsIDOMBlob) + NS_INTERFACE_MAP_ENTRY(nsIDOMBlob_MOZILLA_2_0_BRANCH) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, mIsFullFile) NS_INTERFACE_MAP_ENTRY(nsIXHRSendable) NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver) + NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, mIsFullFile) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !mIsFullFile) NS_INTERFACE_MAP_END @@ -163,6 +166,14 @@ DOMFileResult(nsresult rv) return rv; } +/* static */ nsresult +nsDOMFile::NewFile(nsISupports* *aNewObject) +{ + nsCOMPtr file = do_QueryObject(new nsDOMFile(nsnull)); + file.forget(aNewObject); + return NS_OK; +} + NS_IMETHODIMP nsDOMFile::GetFileName(nsAString &aFileName) { @@ -245,23 +256,54 @@ nsDOMFile::GetType(nsAString &aType) return NS_OK; } -// Makes sure that aStart and aStart + aLength is less then or equal to aSize +// Makes sure that aStart and aEnd is less then or equal to aSize and greater +// than 0 void -ClampToSize(PRUint64 aSize, PRUint64& aStart, PRUint64& aLength) +ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd) { - if (aStart > aSize) { - aStart = aLength = 0; + CheckedInt64 newStartOffset = aStart; + if (aStart < -aSize) { + newStartOffset = 0; } - CheckedUint64 endOffset = aStart; - endOffset += aLength; - if (!endOffset.valid() || endOffset.value() > aSize) { - aLength = aSize - aStart; + else if (aStart < 0) { + newStartOffset += aSize; + } + else if (aStart > aSize) { + newStartOffset = aSize; + } + + CheckedInt64 newEndOffset = aEnd; + if (aEnd < -aSize) { + newEndOffset = 0; + } + else if (aEnd < 0) { + newEndOffset += aSize; + } + else if (aEnd > aSize) { + newEndOffset = aSize; + } + + if (!newStartOffset.valid() || !newEndOffset.valid() || + newStartOffset.value() >= newEndOffset.value()) { + aStart = aEnd = 0; + } + else { + aStart = newStartOffset.value(); + aEnd = newEndOffset.value(); } } NS_IMETHODIMP nsDOMFile::Slice(PRUint64 aStart, PRUint64 aLength, const nsAString& aContentType, nsIDOMBlob **aBlob) +{ + return MozSlice(aStart, aStart + aLength, aContentType, 2, aBlob); +} + +NS_IMETHODIMP +nsDOMFile::MozSlice(PRInt64 aStart, PRInt64 aEnd, + const nsAString& aContentType, PRUint8 optional_argc, + nsIDOMBlob **aBlob) { *aBlob = nsnull; @@ -269,10 +311,15 @@ nsDOMFile::Slice(PRUint64 aStart, PRUint64 aLength, PRUint64 thisLength; nsresult rv = GetSize(&thisLength); NS_ENSURE_SUCCESS(rv, rv); - ClampToSize(thisLength, aStart, aLength); + + if (!optional_argc) { + aEnd = (PRInt64)thisLength; + } + + ParseSize((PRInt64)thisLength, aStart, aEnd); // Create the new file - NS_ADDREF(*aBlob = new nsDOMFile(this, aStart, aLength, aContentType)); + NS_ADDREF(*aBlob = new nsDOMFile(this, aStart, aEnd - aStart, aContentType)); return NS_OK; } @@ -574,6 +621,48 @@ nsDOMFile::Notify(const char* aCharset, nsDetectionConfident aConf) return NS_OK; } +NS_IMETHODIMP +nsDOMFile::Initialize(nsISupports* aOwner, + JSContext* aCx, + JSObject* aObj, + PRUint32 aArgc, + jsval* aArgv) +{ + if (!nsContentUtils::IsCallerChrome()) { + return NS_ERROR_DOM_SECURITY_ERR; // Real short trip + } + + NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED); + + // We expect to get a path to represent as a File object + if (!JSVAL_IS_STRING(aArgv[0])) + return NS_ERROR_UNEXPECTED; + + JSString* str = JS_ValueToString(aCx, aArgv[0]); + NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS); + + nsDependentJSString xpcomStr; + if (!xpcomStr.init(aCx, str)) { + return NS_ERROR_XPC_BAD_CONVERT_JS; + } + + nsCOMPtr localFile; + nsresult rv = NS_NewLocalFile(xpcomStr, + PR_FALSE, getter_AddRefs(localFile)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr file = do_QueryInterface(localFile, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + PRBool exists; + rv = file->Exists(&exists); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND); + + mFile = file; + return NS_OK; +} + nsresult nsDOMFile::ConvertStream(nsIInputStream *aStream, const char *aCharset, @@ -627,16 +716,22 @@ nsDOMMemoryFile::GetSize(PRUint64 *aFileSize) } NS_IMETHODIMP -nsDOMMemoryFile::Slice(PRUint64 aStart, PRUint64 aLength, - const nsAString& aContentType, nsIDOMBlob **aBlob) +nsDOMMemoryFile::MozSlice(PRInt64 aStart, PRInt64 aEnd, + const nsAString& aContentType, PRUint8 optional_argc, + nsIDOMBlob **aBlob) { *aBlob = nsnull; + if (!optional_argc) { + aEnd = (PRInt64)mLength; + } + // Truncate aLength and aStart so that we stay within this file. - ClampToSize(mLength, aStart, aLength); + ParseSize((PRInt64)mLength, aStart, aEnd); // Create the new file - NS_ADDREF(*aBlob = new nsDOMMemoryFile(this, aStart, aLength, aContentType)); + NS_ADDREF(*aBlob = new nsDOMMemoryFile(this, aStart, aEnd - aStart, + aContentType)); return NS_OK; } diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index bdb4ccb06ec0..523c9cf59328 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -1441,8 +1441,8 @@ nsDOMImplementation::CreateDocumentType(const nsAString& aQualifiedName, // Indicate that there is no internal subset (not just an empty one) nsAutoString voidString; voidString.SetIsVoid(PR_TRUE); - return NS_NewDOMDocumentType(aReturn, nsnull, mPrincipal, name, nsnull, - nsnull, aPublicId, aSystemId, voidString); + return NS_NewDOMDocumentType(aReturn, nsnull, mPrincipal, name, aPublicId, + aSystemId, voidString); } NS_IMETHODIMP @@ -1507,8 +1507,6 @@ nsDOMImplementation::CreateHTMLDocument(const nsAString& aTitle, NULL, // aNodeInfoManager mPrincipal, // aPrincipal nsGkAtoms::html, // aName - NULL, // aEntities - NULL, // aNotations EmptyString(), // aPublicId EmptyString(), // aSystemId voidString); // aInternalSubset @@ -8285,7 +8283,10 @@ nsDocument::RemoveImage(imgIRequest* aImage) // Get the old count. It should exist and be > 0. PRUint32 count; - PRBool found = mImageTracker.Get(aImage, &count); +#ifdef DEBUG + PRBool found = +#endif + mImageTracker.Get(aImage, &count); NS_ABORT_IF_FALSE(found, "Removing image that wasn't in the tracker!"); NS_ABORT_IF_FALSE(count > 0, "Entry in the cache tracker with count 0!"); diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 7476757a0b6c..333131d9ec84 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -4582,7 +4582,9 @@ nsGenericElement::MaybeCheckSameAttrVal(PRInt32 aNamespaceID, nsIAtom* aName, // Need to store the old value info.mValue->ToString(*aOldValue); valueMatches = aValue.Equals(*aOldValue); - } else if (aNotify) { + } else { + NS_ABORT_IF_FALSE(aNotify, + "Either hasListeners or aNotify should be true."); valueMatches = info.mValue->Equals(aValue, eCaseMatters); } if (valueMatches && aPrefix == info.mName->GetPrefix()) { diff --git a/content/base/src/nsInProcessTabChildGlobal.cpp b/content/base/src/nsInProcessTabChildGlobal.cpp index 6ba11e4adadf..aacd83c83950 100644 --- a/content/base/src/nsInProcessTabChildGlobal.cpp +++ b/content/base/src/nsInProcessTabChildGlobal.cpp @@ -129,7 +129,10 @@ nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal() nsresult nsInProcessTabChildGlobal::Init() { - nsresult rv = InitTabChildGlobal(); +#ifdef DEBUG + nsresult rv = +#endif + InitTabChildGlobal(); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Couldn't initialize nsInProcessTabChildGlobal"); mMessageManager = new nsFrameMessageManager(PR_FALSE, diff --git a/content/base/src/nsNodeInfoManager.h b/content/base/src/nsNodeInfoManager.h index 0ce5a0a7dc47..2d7d8ca5211f 100644 --- a/content/base/src/nsNodeInfoManager.h +++ b/content/base/src/nsNodeInfoManager.h @@ -138,8 +138,6 @@ protected: nsNodeInfoManager *, nsIPrincipal *, nsIAtom *, - nsIDOMNamedNodeMap *, - nsIDOMNamedNodeMap *, const nsAString& , const nsAString& , const nsAString& ); diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index 2695d9c715a4..6e168d2648ff 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -1077,6 +1077,10 @@ nsObjectLoadingContent::ObjectState() const case ePluginUnsupported: state |= NS_EVENT_STATE_TYPE_UNSUPPORTED; break; + case ePluginOutdated: + case ePluginOtherState: + // Do nothing, but avoid a compile warning + break; } return state; }; diff --git a/content/base/src/nsWebSocket.cpp b/content/base/src/nsWebSocket.cpp index efbfa21486da..7c222ff278b2 100644 --- a/content/base/src/nsWebSocket.cpp +++ b/content/base/src/nsWebSocket.cpp @@ -897,6 +897,9 @@ IMPL_RUNNABLE_ON_MAIN_THREAD_METHOD_BEGIN(DoInitialRequest) buf->AppendLiteral("\r\n"); } break; + + case numberRequestHeaders: + break; } headersToSend.RemoveElementAt(headerPosToSendNow); @@ -1733,10 +1736,9 @@ IMPL_RUNNABLE_ON_MAIN_THREAD_METHOD_BEGIN(AddWSConnecting) NS_ASSERTION(index == nsTArray::NoIndex, "The ws connection shouldn't be already added in the " "serialization list."); + bool inserted = !! #endif - - PRBool inserted = - !!(sWSsConnecting->InsertElementSorted(this, nsWSNetAddressComparator())); + sWSsConnecting->InsertElementSorted(this, nsWSNetAddressComparator()); NS_ASSERTION(inserted, "Couldn't insert the ws connection into the " "serialization list."); } diff --git a/content/base/src/nsXMLContentSerializer.cpp b/content/base/src/nsXMLContentSerializer.cpp index 47ce17d9a461..111541d65ad2 100644 --- a/content/base/src/nsXMLContentSerializer.cpp +++ b/content/base/src/nsXMLContentSerializer.cpp @@ -1319,7 +1319,8 @@ void nsXMLContentSerializer::IncrIndentation(nsIAtom* aName) { // we want to keep the source readable - if(mDoWrap && mIndent.Length() >= mMaxColumn - MIN_INDENTED_LINE_LENGTH) { + if (mDoWrap && + mIndent.Length() >= PRUint32(mMaxColumn) - MIN_INDENTED_LINE_LENGTH) { ++mIndentOverflow; } else { @@ -1658,7 +1659,7 @@ nsXMLContentSerializer::AppendToStringFormatedWrapped(const nsASingleFragmentStr PRBool mayIgnoreStartOfLineWhitespaceSequence = (!mColPos || (mIsIndentationAddedOnCurrentLine && sequenceStartAfterAWhitespace && - mColPos == mIndent.Length())); + PRUint32(mColPos) == mIndent.Length())); while (pos < end) { sequenceStart = pos; diff --git a/content/base/test/chrome/Makefile.in b/content/base/test/chrome/Makefile.in index 89365034dac1..7e48f254ecb2 100644 --- a/content/base/test/chrome/Makefile.in +++ b/content/base/test/chrome/Makefile.in @@ -60,6 +60,8 @@ _CHROME_FILES = \ test_bug616841.xul \ file_bug616841.xul \ test_bug635835.xul \ + test_fileconstructor.xul \ + fileconstructor_file.png \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/base/test/chrome/fileconstructor_file.png b/content/base/test/chrome/fileconstructor_file.png new file mode 100644 index 000000000000..51e8aaf38c1b Binary files /dev/null and b/content/base/test/chrome/fileconstructor_file.png differ diff --git a/content/base/test/chrome/test_fileconstructor.xul b/content/base/test/chrome/test_fileconstructor.xul new file mode 100644 index 000000000000..9fe58716241f --- /dev/null +++ b/content/base/test/chrome/test_fileconstructor.xul @@ -0,0 +1,70 @@ + + + + + + + Test for Bug 607114 + + + + + + Mozilla Bug 607114 +

+ +
+
+ + + + +
diff --git a/content/base/test/test_fileapi.html b/content/base/test/test_fileapi.html index 8cfbb0df5002..29d48333fc67 100644 --- a/content/base/test/test_fileapi.html +++ b/content/base/test/test_fileapi.html @@ -20,6 +20,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=414796
 
+  
+
diff --git a/layout/reftests/editor/selection_visibility_after_reframe-ref.html b/layout/reftests/editor/selection_visibility_after_reframe-ref.html
new file mode 100644
index 000000000000..c227b39c8f70
--- /dev/null
+++ b/layout/reftests/editor/selection_visibility_after_reframe-ref.html
@@ -0,0 +1,6 @@
+
+
+  
+    
+  
+
diff --git a/layout/reftests/editor/selection_visibility_after_reframe.html b/layout/reftests/editor/selection_visibility_after_reframe.html
new file mode 100644
index 000000000000..b05f130a1372
--- /dev/null
+++ b/layout/reftests/editor/selection_visibility_after_reframe.html
@@ -0,0 +1,14 @@
+
+
+  
+    
+    
+  
+
diff --git a/layout/xul/base/src/nsMenuBarFrame.cpp b/layout/xul/base/src/nsMenuBarFrame.cpp
index 02965e590a92..f1b80e536eb3 100644
--- a/layout/xul/base/src/nsMenuBarFrame.cpp
+++ b/layout/xul/base/src/nsMenuBarFrame.cpp
@@ -414,13 +414,13 @@ nsMenuBarFrame::ChangeMenuItem(nsMenuFrame* aMenuItem,
 }
 
 nsMenuFrame*
-nsMenuBarFrame::Enter()
+nsMenuBarFrame::Enter(nsGUIEvent* aEvent)
 {
   if (!mCurrentMenu)
     return nsnull;
 
   if (mCurrentMenu->IsOpen())
-    return mCurrentMenu->Enter();
+    return mCurrentMenu->Enter(aEvent);
 
   return mCurrentMenu;
 }
diff --git a/layout/xul/base/src/nsMenuBarFrame.h b/layout/xul/base/src/nsMenuBarFrame.h
index 34e131697507..67ad5cbb2091 100644
--- a/layout/xul/base/src/nsMenuBarFrame.h
+++ b/layout/xul/base/src/nsMenuBarFrame.h
@@ -112,7 +112,7 @@ public:
 
   // Called when Enter is pressed while the menubar is focused. If the current
   // menu is open, let the child handle the key.
-  nsMenuFrame* Enter();
+  nsMenuFrame* Enter(nsGUIEvent* aEvent);
 
   // Used to handle ALT+key combos
   nsMenuFrame* FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent);
diff --git a/layout/xul/base/src/nsMenuFrame.cpp b/layout/xul/base/src/nsMenuFrame.cpp
index 828015ac3778..9eeae9d7bc8d 100644
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -832,7 +832,7 @@ nsMenuFrame::SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, PRBool aDebug)
 // In either case, do nothing if the item is disabled.
 //
 nsMenuFrame*
-nsMenuFrame::Enter()
+nsMenuFrame::Enter(nsGUIEvent *aEvent)
 {
   if (IsDisabled()) {
 #ifdef XP_WIN
@@ -853,7 +853,7 @@ nsMenuFrame::Enter()
   if (!IsOpen()) {
     // The enter key press applies to us.
     if (!IsMenu() && mMenuParent)
-      Execute(0);          // Execute our event handler
+      Execute(aEvent);          // Execute our event handler
     else
       return this;
   }
diff --git a/layout/xul/base/src/nsMenuFrame.h b/layout/xul/base/src/nsMenuFrame.h
index 950fbc872e4d..d6a69ae0a4c8 100644
--- a/layout/xul/base/src/nsMenuFrame.h
+++ b/layout/xul/base/src/nsMenuFrame.h
@@ -174,7 +174,7 @@ public:
   // one in its parent popup. This will carry out the command attached to
   // the menuitem. If the menu should be opened, this frame will be returned,
   // otherwise null will be returned.
-  nsMenuFrame* Enter();
+  nsMenuFrame* Enter(nsGUIEvent* aEvent);
 
   virtual void SetParent(nsIFrame* aParent);
 
diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp
index d8558e53eeac..01ea5c398b63 100644
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -1235,52 +1235,50 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, PRBool aIsMove)
     vFlip = FlipStyle_Outside;
   }
 
-  // if a panel is being moved, don't flip it. But always do this for content
-  // shells, so that the popup doesn't extend outside the containing frame.
-  if (aIsMove && mPopupType == ePopupTypePanel && !mInContentShell) {
-    hFlip = vFlip = FlipStyle_None;
+  // If a panel is being moved, don't constrain or flip it. But always do this for
+  // content shells, so that the popup doesn't extend outside the containing frame.
+  if (mInContentShell || !aIsMove || mPopupType != ePopupTypePanel) {
+    nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect);
+
+    // ensure that anchorRect is on screen
+    if (!anchorRect.IntersectRect(anchorRect, screenRect)) {
+      anchorRect.width = anchorRect.height = 0;
+      // if the anchor isn't within the screen, move it to the edge of the screen.
+      if (anchorRect.x < screenRect.x)
+        anchorRect.x = screenRect.x;
+      if (anchorRect.XMost() > screenRect.XMost())
+        anchorRect.x = screenRect.XMost();
+      if (anchorRect.y < screenRect.y)
+        anchorRect.y = screenRect.y;
+      if (anchorRect.YMost() > screenRect.YMost())
+        anchorRect.y = screenRect.YMost();
+    }
+
+    // shrink the the popup down if it is larger than the screen size
+    if (mRect.width > screenRect.width)
+      mRect.width = screenRect.width;
+    if (mRect.height > screenRect.height)
+      mRect.height = screenRect.height;
+
+    // at this point the anchor (anchorRect) is within the available screen
+    // area (screenRect) and the popup is known to be no larger than the screen.
+    // Next, check if there is enough space to show the popup at full size when
+    // positioned at screenPoint. If not, flip the popups to the opposite side
+    // of their anchor point, or resize them as necessary.
+    mRect.width = FlipOrResize(screenPoint.x, mRect.width, screenRect.x,
+                               screenRect.XMost(), anchorRect.x, anchorRect.XMost(),
+                               margin.left, margin.right, offsetForContextMenu, hFlip, &mHFlip);
+
+    mRect.height = FlipOrResize(screenPoint.y, mRect.height, screenRect.y,
+                                screenRect.YMost(), anchorRect.y, anchorRect.YMost(),
+                                margin.top, margin.bottom, offsetForContextMenu, vFlip, &mVFlip);
+
+    NS_ASSERTION(screenPoint.x >= screenRect.x && screenPoint.y >= screenRect.y &&
+                 screenPoint.x + mRect.width <= screenRect.XMost() &&
+                 screenPoint.y + mRect.height <= screenRect.YMost(),
+                 "Popup is offscreen");
   }
 
-  nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect);
-
-  // ensure that anchorRect is on screen
-  if (!anchorRect.IntersectRect(anchorRect, screenRect)) {
-    anchorRect.width = anchorRect.height = 0;
-    // if the anchor isn't within the screen, move it to the edge of the screen.
-    if (anchorRect.x < screenRect.x)
-      anchorRect.x = screenRect.x;
-    if (anchorRect.XMost() > screenRect.XMost())
-      anchorRect.x = screenRect.XMost();
-    if (anchorRect.y < screenRect.y)
-      anchorRect.y = screenRect.y;
-    if (anchorRect.YMost() > screenRect.YMost())
-      anchorRect.y = screenRect.YMost();
-  }
-
-  // shrink the the popup down if it is larger than the screen size
-  if (mRect.width > screenRect.width)
-    mRect.width = screenRect.width;
-  if (mRect.height > screenRect.height)
-    mRect.height = screenRect.height;
-
-  // at this point the anchor (anchorRect) is within the available screen
-  // area (screenRect) and the popup is known to be no larger than the screen.
-  // Next, check if there is enough space to show the popup at full size when
-  // positioned at screenPoint. If not, flip the popups to the opposite side
-  // of their anchor point, or resize them as necessary.
-  mRect.width = FlipOrResize(screenPoint.x, mRect.width, screenRect.x,
-                             screenRect.XMost(), anchorRect.x, anchorRect.XMost(),
-                             margin.left, margin.right, offsetForContextMenu, hFlip, &mHFlip);
-
-  mRect.height = FlipOrResize(screenPoint.y, mRect.height, screenRect.y,
-                              screenRect.YMost(), anchorRect.y, anchorRect.YMost(),
-                              margin.top, margin.bottom, offsetForContextMenu, vFlip, &mVFlip);
-
-  NS_ASSERTION(screenPoint.x >= screenRect.x && screenPoint.y >= screenRect.y &&
-               screenPoint.x + mRect.width <= screenRect.XMost() &&
-               screenPoint.y + mRect.height <= screenRect.YMost(),
-               "Popup is offscreen");
-
   // determine the x and y position of the view by subtracting the desired
   // screen position from the screen position of the root frame.
   nsPoint viewPoint = screenPoint - rootScreenRect.TopLeft();
@@ -1539,13 +1537,13 @@ nsMenuPopupFrame::ChangeMenuItem(nsMenuFrame* aMenuItem,
 }
 
 nsMenuFrame*
-nsMenuPopupFrame::Enter()
+nsMenuPopupFrame::Enter(nsGUIEvent* aEvent)
 {
   mIncrementalString.Truncate();
 
   // Give it to the child.
   if (mCurrentMenu)
-    return mCurrentMenu->Enter();
+    return mCurrentMenu->Enter(aEvent);
 
   return nsnull;
 }
diff --git a/layout/xul/base/src/nsMenuPopupFrame.h b/layout/xul/base/src/nsMenuPopupFrame.h
index 1ff8c27253e0..789d96954988 100644
--- a/layout/xul/base/src/nsMenuPopupFrame.h
+++ b/layout/xul/base/src/nsMenuPopupFrame.h
@@ -234,7 +234,7 @@ public:
   // that menu, or null if no menu should be opened. Also, calling Enter will
   // reset the current incremental search string, calculated in
   // FindMenuWithShortcut.
-  nsMenuFrame* Enter();
+  nsMenuFrame* Enter(nsGUIEvent* aEvent);
 
   nsPopupType PopupType() const { return mPopupType; }
   PRBool IsMenu() { return mPopupType == ePopupTypeMenu; }
diff --git a/layout/xul/base/src/nsXULPopupManager.cpp b/layout/xul/base/src/nsXULPopupManager.cpp
index 4f17070d7d0b..2499cdeeb8b2 100644
--- a/layout/xul/base/src/nsXULPopupManager.cpp
+++ b/layout/xul/base/src/nsXULPopupManager.cpp
@@ -1731,6 +1731,13 @@ nsXULPopupManager::CancelMenuTimer(nsMenuParent* aMenuParent)
   }
 }
 
+static nsGUIEvent* DOMKeyEventToGUIEvent(nsIDOMEvent* aEvent)
+{
+  nsCOMPtr privateEvent(do_QueryInterface(aEvent));
+  nsEvent* evt = privateEvent ? privateEvent->GetInternalNSEvent() : nsnull;
+  return (evt->eventStructType == NS_KEY_EVENT) ? static_cast(evt) : nsnull;
+}
+
 PRBool
 nsXULPopupManager::HandleShortcutNavigation(nsIDOMKeyEvent* aKeyEvent,
                                             nsMenuPopupFrame* aFrame)
@@ -1745,7 +1752,8 @@ nsXULPopupManager::HandleShortcutNavigation(nsIDOMKeyEvent* aKeyEvent,
     if (result) {
       aFrame->ChangeMenuItem(result, PR_FALSE);
       if (action) {
-        nsMenuFrame* menuToOpen = result->Enter();
+        nsGUIEvent* evt = DOMKeyEventToGUIEvent(aKeyEvent);
+        nsMenuFrame* menuToOpen = result->Enter(evt);
         if (menuToOpen) {
           nsCOMPtr content = menuToOpen->GetContent();
           ShowMenu(content, PR_TRUE, PR_FALSE);
@@ -2178,10 +2186,11 @@ nsXULPopupManager::KeyPress(nsIDOMEvent* aKeyEvent)
     // Enter method will return a menu if one needs to be opened as a result.
     nsMenuFrame* menuToOpen = nsnull;
     nsMenuChainItem* item = GetTopVisibleMenu();
+    nsGUIEvent* evt = DOMKeyEventToGUIEvent(aKeyEvent);
     if (item)
-      menuToOpen = item->Frame()->Enter();
+      menuToOpen = item->Frame()->Enter(evt);
     else if (mActiveMenuBar)
-      menuToOpen = mActiveMenuBar->Enter();
+      menuToOpen = mActiveMenuBar->Enter(evt);
     if (menuToOpen) {
       nsCOMPtr content = menuToOpen->GetContent();
       ShowMenu(content, PR_TRUE, PR_FALSE);
diff --git a/memory/mozalloc/mozalloc.cpp b/memory/mozalloc/mozalloc.cpp
index 5cd2a00c1d24..ec172dab2e5f 100644
--- a/memory/mozalloc/mozalloc.cpp
+++ b/memory/mozalloc/mozalloc.cpp
@@ -42,6 +42,8 @@
 #include                   // for std::bad_alloc
 #include 
 
+#include 
+
 #if defined(MALLOC_H)
 #  include MALLOC_H             // for memalign, valloc where available
 #endif // if defined(MALLOC_H)
diff --git a/modules/libimg/png/CHANGES b/modules/libimg/png/CHANGES
index 0dff4892299f..6574a0bea482 100644
--- a/modules/libimg/png/CHANGES
+++ b/modules/libimg/png/CHANGES
@@ -1479,7 +1479,7 @@ version 1.2.9beta5 [March 4, 2006]
   Removed trailing blanks from source files.
   Put version and date of latest change in each source file, and changed
     copyright year accordingly.
-  More cleanup of configure.ac, Makefile.ac, and associated scripts.
+  More cleanup of configure.ac, Makefile.am, and associated scripts.
   Restored scripts/makefile.elf which was inadvertently deleted.
 
 version 1.2.9beta6 [March 6, 2006]
@@ -2610,6 +2610,191 @@ version 1.4.3rc03 [June 23, 2010]
 version 1.4.3 [June 26, 2010]
   Updated some of the "last changed" dates.
 
+version 1.4.4beta01 [July 12, 2010]
+  Removed extraneous new_push_process_row.c file.
+  Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5
+  Removed some newly-added TAB characters from pngpread.c.
+  Fixed some indentation in pngpread.c and pngrutil.c
+  Changed "extern PNG_EXPORT" to "PNG_EXPORT" in png.h (Jan Nijtmans)
+  Changed "extern" to "PNG_EXTERN" in pngpriv.h (except for the 'extern "C" {')
+  Put "#ifndef PNG_EXTERN, #endif" around "#define PNG_EXTERN" in pngpriv.h
+
+version 1.4.4beta02 [July 24, 2010]
+  Added -DNO_PNG_SNPRINTF to CFLAGS in scripts/makefile.dj2
+  Moved the definition of png_snprintf() outside of the enclosing
+    #ifdef blocks in pngconf.h
+  Added a special case typedef of png_longjmp_ptr for WATCOM.
+
+version 1.4.4beta03 [July 24, 2010]
+  Removed reference to cbuilder5/* from Makefile.in and Makefile.am
+  Eliminated the new special case typedef of png_longjmp_ptr for WATCOM
+    and made a special case "#define PNGAPI" in pngconf.h instead.
+
+version 1.4.4beta04 [July 31, 2010]
+  Updated the read macros and functions from 1.5.0beta38.
+
+version 1.4.4beta05 [August 6, 2010]
+  Updated projects/visualc71 so it can find scripts/pnglibconf.h
+  Removed unused png_mem_* defines from pngconf.h.
+  Correct use of _WINDOWS_ in pngconf.h
+
+version 1.4.4beta06 [August 11, 2010]
+  Don't try to use version-script with cygwin/mingw.
+  Revised contrib/gregbook to work under cygwin/mingw.
+
+version 1.4.4beta07 [August 26, 2010]
+  Updated prebuilt aclocal.m4 and ltmain.sh
+  Add .dll.a to the list of extensions to be symlinked by Makefile.am (Yaakov)
+  Updated CMakeLists.txt to use CMAKE_INSTALL_LIBDIR variable; useful for
+    installing libpng in /usr/lib64 (Funda Wang).
+  Revised CMakeLists.txt to put the man pages in share/man/man* not man/man*
+  Revised CMakeLists.txt to make symlinks instead of copies when installing.
+  Changed PNG_LIB_NAME from pngNN to libpngNN in CMakeLists.txt (Philip Lowman)
+  Moved "#include pngusr.h" ahead of PNG_USER_PRIVATEBUILD test in pngconf.h
+  Eliminated a deprecated reference to png_ptr->io_ptr in pngtest.c
+  Eliminated new unnecessary #if tests regarding the sCAL chunk from pngrutil.c
+
+version 1.4.4beta08 [September 2, 2010]
+  Updated the xcode project to work with libpng-1.4.x and added iOS targets
+    for simulator and device (Philippe Hausler).
+
+version 1.4.4rc01 [September 10, 2010]
+  No changes.
+
+version 1.4.4rc02 [September 13, 2010]
+  Revised CMakeLists.txt (Philip Lowman).
+
+version 1.4.4rc03 [September 14, 2010]
+  Removed an extraneous close-double-quote from CMakeLists.txt
+  Eliminated another deprecated reference to png_ptr->io_ptr in pngtest.c
+
+version 1.4.4rc04 [September 16, 2010]
+  Fixed indentation and removed debugging message from CMakeLists.txt
+  Revised autogen.sh to recognize and use $AUTOCONF, $AUTOMAKE, $AUTOHEADER,
+    $AUTOPOINT, $ACLOCAL and $LIBTOOLIZE
+
+version 1.4.4rc05 [September 20, 2010]
+  Rebuilt configure scripts with automake-1.11.1 instead of automake-1.11.
+  Removed unused mkinstalldirs file.
+
+version 1.4.4 [September 23, 2010]
+  No changes.
+
+version 1.4.5beta01 [September 25, 2010]
+  Fixed possible configure.ac bug introduced in version 1.4.4rc05.
+  Rebuilt configure scripts with autoconf-2.68 instead of autoconf-2.65
+
+version 1.4.5beta02 [October 5, 2010]
+  Reverted configure scripts to autoconf-2.65
+  Fixed problem with symbols creation in Makefile.am which was assuming that
+    all versions of cpp write to standard output by default (Martin Banky). The
+    bug was introduced in libpng-1.2.9beta5.
+
+version 1.4.5beta03 [October 8, 2010]
+  Wrapped long lines in CMakeLists.txt and introduced ${libpng_public_hdrs}
+  Undid Makefile.am revision of 1.4.5beta02.
+
+version 1.4.5beta04 [November 8, 2010]
+  Check for out-of-range text compression mode in png_set_text().
+
+version 1.4.5rc01 [November 19, 2010]
+  No changes.
+
+version 1.4.5beta05 [November 20, 2010]
+  Revised png_get_uint_32, png_get_int_32, png_get_uint_16 (Cosmin)
+  Moved reading of file signature into png_read_sig (Cosmin)
+  Fixed atomicity of chunk header serialization (Cosmin)
+  Added test for io_state in pngtest.c (Cosmin)
+  Added "#!/bin/sh" at the top of contrib/pngminim/*/gather.sh scripts.
+
+version 1.4.5beta06 [November 21, 2010]
+  Restored the parentheses in pngrutil.c; they are needed when the
+    png_get_*int_*() functions are compiled (i.e., when PNG_USE_READ_MACROS
+    is not defined).
+  Make the "png_get_uint_16" macro return a png_uint_32 in libpng-1.4 for API
+    compatibility.
+  Changes to remove gcc warnings (John Bowler)
+    Certain optional gcc warning flags resulted in warnings in libpng code.
+    With these changes only -Wconversion and -Wcast-qual cannot be turned on.
+    Changes are trivial rearrangements of code.  -Wconversion is not possible
+    for pngrutil.c (because of the widespread use of += et al on variables
+    smaller than (int) or (unsigned int)) and -Wcast-qual is not possible
+    with pngwio.c and pngwutil.c because the 'write' callback and zlib
+    compression both fail to declare their input buffers with 'const'.
+
+version 1.4.5beta07 [November 25, 2010]
+  Reverted png_get_uint_16 macro to beta05 and added comment about the
+    potential API incompatibility.
+
+version 1.4.5rc02 [December 2, 2010]
+  No changes.
+
+version 1.4.5rc03 [December 3, 2010]
+  Added missing vstudio/*/*.vcxproj files to the zip and 7z distributions.
+
+version 1.4.5 [December 9, 2010]
+  Removed PNG_NO_WRITE_GAMMA from pngminim/encoder/pngusr.h
+
+version 1.4.6beta01 [December 29, 2010]
+  Fixed bug in background transformation handling in pngrtran.c (it was
+    looking for the flag in png_ptr->transformations instead of in
+    png_ptr->flags) (David Raymond).
+
+version 1.4.6beta02 [January 14, 2011]
+  Fixed misspelled macros in contrib/pngminim (Cosmin).
+  Updated CMakeLists.txt (Clifford Yapp).
+
+version 1.4.6beta03 [January 14, 2011]
+  Fixed some typecasts in png_debug statements (Cosmin).
+
+version 1.4.6beta04 [January 22, 2011]
+  Updated documentation of png_set|get_tRNS() (Thomas Klausner).
+  Added png_const_structp and png_const_infop types, and used them in
+    prototypes for most png_get_*() functions.
+  In the manual, describe the png_get_IHDR() arguments in the correct order.
+  Ported change in png_do_rgb_to_gray() from libpng-1.5.1, to make
+    it more robust against internal libpng coding errors.
+
+version 1.4.6beta05 [January 23, 2011]
+
+  Updated the synopses in the manual to reflect recent changes.
+  Fixed a typo in the *.def files and deleted entries that are now
+    declared in pngpriv.h
+
+version 1.4.6beta06 [March 19, 2011]
+  Updated contrib/pngsuite/README to add the word "modify".
+  Added the private PNG_UNUSED() macro definition in pngconf.h.
+
+version 1.4.6beta07 [March 22, 2011]
+  ifdef out mask arrays in pngread.c when interlacing is not supported.
+  Added attribute definition (warnings) for MSC_VER >= 1300 in pngconf.h
+  Added -D_CRT_SECURE_NO_DEPRECATE to CFLAGS in makefile.vcwin32
+  Fixed mistake in the descriptions of user read_transform and write_transform
+    function prototypes in the manual.  The row_info struct is png_row_infop.
+  Added a request in the manual that applications do not use "png_" or
+    "PNG_" to begin any of their own symbols.
+  Fixed incorrect examples of callback prototypes in the manual, that were
+    introduced in libpng-1.0.0.
+  Removed "strip" from contrib/pngminim/*/makefile.
+  Fixed a bug (present since libpng-1.0.7) that makes png_handle_sPLT() fail
+    to compile when PNG_NO_POINTER_INDEXING is defined (Chubanov Kirill)
+
+version 1.4.6rc01 [March 31, 2011]
+  No changes.
+
+version 1.4.6rc02 [April 6, 2011]
+  Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03).
+
+version 1.4.6 [April 8, 2011]
+  No changes.
+
+version 1.4.7rc01 [April 9, 2011]
+  Relocated misplaced new declarations in pngwutil.c.
+
+version 1.4.7 [April 10, 2011]
+  Disabled PNG_PEDANTIC_WARNINGS for all MSC versions as in libpng-1.4.5.
+
+
 Send comments/corrections/commendations to glennrp at users.sourceforge.net
 or to png-mng-implement at lists.sf.net (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement).
diff --git a/modules/libimg/png/LICENSE b/modules/libimg/png/LICENSE
index dd89a6684784..4915b94409c0 100644
--- a/modules/libimg/png/LICENSE
+++ b/modules/libimg/png/LICENSE
@@ -10,8 +10,8 @@ this sentence.
 
 This code is released under the libpng license.
 
-libpng versions 1.2.6, August 15, 2004, through 1.4.3, June 26, 2010, are
-Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are
+libpng versions 1.2.6, August 15, 2004, through 1.4.7, April 10, 2011, are
+Copyright (c) 2004, 2006-2010 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
 
@@ -108,4 +108,4 @@ certification mark of the Open Source Initiative.
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-June 26, 2010
+April 10, 2011
diff --git a/modules/libimg/png/MOZCHANGES b/modules/libimg/png/MOZCHANGES
index 5bb742bf917f..3772db631a54 100644
--- a/modules/libimg/png/MOZCHANGES
+++ b/modules/libimg/png/MOZCHANGES
@@ -1,6 +1,8 @@
 
 Changes made to pristine png source by mozilla.org developers.
 
+2011/04/08  -- Synced with libpng-1.4.7 (bug #624133).
+
 2010/06/30  -- Synced with libpng-1.4.3 (bug #564792).
 
 2010/02/26  -- Synced with libpng-1.4.1 (bug #544747).
diff --git a/modules/libimg/png/README b/modules/libimg/png/README
index 799f3ebe0227..fe1b500e0699 100644
--- a/modules/libimg/png/README
+++ b/modules/libimg/png/README
@@ -1,4 +1,4 @@
-README for libpng version 1.4.3 - June 26, 2010 (shared library 14.0)
+README for libpng version 1.4.7 - April 10, 2011 (shared library 14.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
@@ -185,9 +185,9 @@ Files in this distribution:
        makefile.std     =>  Generic UNIX makefile (cc, creates static
                             libpng.a)
        makefile.elf     =>  Linux/ELF makefile symbol versioning,
-                            gcc, creates libpng14.so.14.1.4.3)
+                            (gcc, creates libpng14.so.14.1.4.7)
        makefile.linux   =>  Linux/ELF makefile
-                            (gcc, creates libpng14.so.14.1.4.3)
+                            (gcc, creates libpng14.so.14.1.4.7)
        makefile.gcc     =>  Generic makefile (gcc, creates static libpng.a)
        makefile.knr     =>  Archaic UNIX Makefile that converts files with
                             ansi2knr (Requires ansi2knr.c from
@@ -209,12 +209,12 @@ Files in this distribution:
        makefile.openbsd =>  OpenBSD makefile
        makefile.sgi     =>  Silicon Graphics IRIX (cc, creates static lib)
        makefile.sggcc   =>  Silicon Graphics
-                            (gcc, creates libpng14.so.14.1.4.3)
+                            (gcc, creates libpng14.so.14.1.4.7)
        makefile.sunos   =>  Sun makefile
        makefile.solaris =>  Solaris 2.X makefile
-                            (gcc, creates libpng14.so.14.1.4.3)
+                            (gcc, creates libpng14.so.14.1.4.7)
        makefile.so9     =>  Solaris 9 makefile
-                            (gcc, creates libpng14.so.14.1.4.3)
+                            (gcc, creates libpng14.so.14.1.4.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
diff --git a/modules/libimg/png/mozpngconf.h b/modules/libimg/png/mozpngconf.h
index efa24dbe72ef..b2f7de8f48c0 100644
--- a/modules/libimg/png/mozpngconf.h
+++ b/modules/libimg/png/mozpngconf.h
@@ -42,15 +42,23 @@
 
 #define PNG_NO_GLOBAL_ARRAYS
 
+#ifdef _MSC_VER
+/* The PNG_PEDANTIC_WARNINGS (attributes) fail to build with some MSC
+ * compilers; we'll play it safe and disable them for all MSC compilers.
+ */
+#define PNG_NO_PEDANTIC_WARNINGS
+#endif
+
 #ifndef MOZ_PNG_READ
 #define PNG_NO_READ_SUPPORTED
 #endif
+#define PNG_NO_READ_BGR
 #define PNG_NO_SET_USER_LIMITS
 #define PNG_NO_USER_LIMITS
 #define PNG_NO_ASSEMBLER_CODE
 #define PNG_NO_WARN_UNINITIALIZED_ROW
 #define PNG_NO_READ_BACKGROUND
-#define PNG_NO_READ_DITHER
+#define PNG_NO_READ_QUANTIZE
 #define PNG_NO_READ_INVERT
 #define PNG_NO_READ_SHIFT
 #define PNG_NO_READ_PACK
@@ -61,8 +69,10 @@
 #define PNG_NO_READ_INVERT_ALPHA
 #define PNG_NO_READ_RGB_TO_GRAY
 #define PNG_NO_READ_USER_TRANSFORM
+
 #define PNG_NO_READ_bKGD
 #define PNG_NO_READ_hIST
+#define PNG_NO_READ_oFFs
 #define PNG_NO_READ_pCAL
 #define PNG_NO_READ_pHYs
 #define PNG_NO_READ_sBIT
@@ -75,7 +85,6 @@
 #define PNG_NO_READ_EMPTY_PLTE
 #define PNG_NO_READ_OPT_PLTE
 #define PNG_NO_READ_STRIP_ALPHA
-#define PNG_NO_READ_oFFs
 #define PNG_NO_SEQUENTIAL_READ_SUPPORTED
 
 #ifndef MOZ_PNG_WRITE
@@ -118,6 +127,7 @@
 
 #define PNG_NO_HANDLE_AS_UNKNOWN
 #define PNG_NO_INFO_IMAGE
+#define PNG_NO_IO_STATE
 #define PNG_NO_USER_MEM
 #define PNG_NO_FIXED_POINT_SUPPORTED
 #define PNG_NO_MNG_FEATURES
@@ -126,7 +136,7 @@
 #define PNG_NO_ZALLOC_ZERO
 #define PNG_NO_ERROR_NUMBERS
 #define PNG_NO_EASY_ACCESS
-
+#define PNG_NO_TIME_RFC1123
 
 /* Mangle names of exported libpng functions so different libpng versions
    can coexist. It is recommended that if you do this, you give your
diff --git a/modules/libimg/png/png.c b/modules/libimg/png/png.c
index dab4f36459dc..2316a8e25fda 100644
--- a/modules/libimg/png/png.c
+++ b/modules/libimg/png/png.c
@@ -1,8 +1,8 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * Last changed in libpng 1.4.2 [May 6, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [March 8, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -17,11 +17,7 @@
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef version_1_4_3 Your_png_h_is_not_version_1_4_3;
-
-/* Version information for C files.  This had better match the version
- * string defined in png.h.
- */
+typedef version_1_4_7 Your_png_h_is_not_version_1_4_7;
 
 /* 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
@@ -543,21 +539,21 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
 
 png_charp PNGAPI
-png_get_copyright(png_structp png_ptr)
+png_get_copyright(png_const_structp png_ptr)
 {
-   png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
+   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
 #ifdef PNG_STRING_COPYRIGHT
       return PNG_STRING_COPYRIGHT
 #else
 #ifdef __STDC__
    return ((png_charp) PNG_STRING_NEWLINE \
-     "libpng version 1.4.3 - June 26, 2010" PNG_STRING_NEWLINE \
+     "libpng version 1.4.7 - April 10, 2011" PNG_STRING_NEWLINE \
      "Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
      PNG_STRING_NEWLINE);
 #else
-      return ((png_charp) "libpng version 1.4.3 - June 26, 2010\
+      return ((png_charp) "libpng version 1.4.7 - April 10, 2011\
       Copyright (c) 1998-2010 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.");
@@ -574,23 +570,23 @@ png_get_copyright(png_structp png_ptr)
  * it is guaranteed that png.c uses the correct version of png.h.
  */
 png_charp PNGAPI
-png_get_libpng_ver(png_structp png_ptr)
+png_get_libpng_ver(png_const_structp png_ptr)
 {
    /* Version of *.c files used when building libpng */
-   png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
+   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
    return ((png_charp) PNG_LIBPNG_VER_STRING);
 }
 
 png_charp PNGAPI
-png_get_header_ver(png_structp png_ptr)
+png_get_header_ver(png_const_structp png_ptr)
 {
    /* Version of *.h files used when building libpng */
-   png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
+   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
    return ((png_charp) PNG_LIBPNG_VER_STRING);
 }
 
 png_charp PNGAPI
-png_get_header_version(png_structp png_ptr)
+png_get_header_version(png_const_structp png_ptr)
 {
    /* Returns longer string containing both version and date */
    png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
@@ -678,7 +674,7 @@ png_convert_size(size_t size)
 */
 
 void /* PRIVATE */
-png_64bit_product (long v1, long v2, unsigned long *hi_product,
+png_64bit_product(long v1, long v2, unsigned long *hi_product,
    unsigned long *lo_product)
 {
    int a, b, c, d;
diff --git a/modules/libimg/png/png.h b/modules/libimg/png/png.h
index 400d30db3e09..543af1399f47 100644
--- a/modules/libimg/png/png.h
+++ b/modules/libimg/png/png.h
@@ -1,8 +1,8 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.4.3 - June 26, 2010
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * libpng version 1.4.7 - April 10, 2011
+ * Copyright (c) 1998-2011 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.)
  *
@@ -11,7 +11,7 @@
  * 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.4.3 - June 26, 2010: Glenn
+ *  libpng versions 0.97, January 1998, through 1.4.7 - April 10, 2011: Glenn
  *  See also "Contributing Authors", below.
  *
  * Note about libpng version numbers:
@@ -145,6 +145,19 @@
  *    1.4.3beta01-05          14    10403  14.so.14.3[.0]
  *    1.4.3rc01-03            14    10403  14.so.14.3[.0]
  *    1.4.3                   14    10403  14.so.14.3[.0]
+ *    1.4.4beta01-08          14    10404  14.so.14.4[.0]
+ *    1.4.4rc01-05            14    10404  14.so.14.4[.0]
+ *    1.4.4                   14    10404  14.so.14.4[.0]
+ *    1.4.5beta01-04          14    10405  14.so.14.5[.0]
+ *    1.4.5rc01               14    10405  14.so.14.5[.0]
+ *    1.4.5beta05-07          14    10405  14.so.14.5[.0]
+ *    1.4.5rc02-03            14    10405  14.so.14.5[.0]
+ *    1.4.5                   14    10405  14.so.14.5[.0]
+ *    1.4.6beta01-07          14    10406  14.so.14.6[.0]
+ *    1.4.6rc01               14    10406  14.so.14.6[.0]
+ *    1.4.6                   14    10406  14.so.14.6[.0]
+ *    1.4.7rc01               14    10407  14.so.14.7[.0]
+ *    1.4.7                   14    10407  14.so.14.7[.0]
  *
  *    Henceforth the source version will match the shared-library major
  *    and minor numbers; the shared-library major version number will be
@@ -176,7 +189,7 @@
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.2.6, August 15, 2004, through 1.4.3, June 26, 2010, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.4.7, April 10, 2011, are
  * Copyright (c) 2004, 2006-2010 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:
@@ -288,13 +301,13 @@
  * Y2K compliance in libpng:
  * =========================
  *
- *    June 26, 2010
+ *    April 10, 2011
  *
  *    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.4.3 are Y2K compliant.  It is my belief that earlier
+ *    upward through 1.4.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
@@ -350,9 +363,9 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.4.3"
+#define PNG_LIBPNG_VER_STRING "1.4.7"
 #define PNG_HEADER_VERSION_STRING \
-   " libpng version 1.4.3 - June 26, 2010\n"
+   " libpng version 1.4.7 - April 10, 2011\n"
 
 #define PNG_LIBPNG_VER_SONUM   14
 #define PNG_LIBPNG_VER_DLLNUM  14
@@ -360,7 +373,7 @@
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   4
-#define PNG_LIBPNG_VER_RELEASE 3
+#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:
  */
@@ -390,7 +403,7 @@
  * 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 10403 /* 1.4.3 */
+#define PNG_LIBPNG_VER 10407 /* 1.4.7 */
 
 #ifndef PNG_VERSION_INFO_ONLY
 /* Include the compression library's header */
@@ -910,6 +923,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
 } png_info;
 
 typedef png_info FAR * png_infop;
+typedef PNG_CONST png_info FAR * png_const_infop;
 typedef png_info FAR * FAR * png_infopp;
 
 /* Maximum positive integer used in PNG is (2^31)-1 */
@@ -1034,6 +1048,7 @@ typedef png_row_info FAR * FAR * png_row_infopp;
  */
 typedef struct png_struct_def png_struct;
 typedef png_struct FAR * png_structp;
+typedef PNG_CONST png_struct FAR * png_const_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));
@@ -1051,7 +1066,7 @@ typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
    png_uint_32, int));
 
 #ifdef PNG_APNG_SUPPORTED
-typedef void (PNGAPI *png_progressive_frame_ptr) PNGARG((png_structp, 
+typedef void (PNGAPI *png_progressive_frame_ptr) PNGARG((png_structp,
    png_uint_32));
 #endif
 #endif
@@ -1530,7 +1545,7 @@ struct png_struct_def
 /* 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_4_3;
+typedef png_structp version_1_4_7;
 
 typedef png_struct FAR * FAR * png_structpp;
 
@@ -1541,12 +1556,12 @@ typedef png_struct FAR * FAR * png_structpp;
  */
 
 /* Returns the version number of the library */
-extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
+PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
 
 /* Tell lib we have already handled the first  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,
+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
@@ -1554,7 +1569,7 @@ extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
  * 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_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
@@ -1563,19 +1578,19 @@ extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
 #define png_check_sig(sig,n) !png_sig_cmp((sig), 0, (n))
 
 /* Allocate and initialize png_ptr struct for reading, and any other memory. */
-extern PNG_EXPORT(png_structp,png_create_read_struct)
+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)) PNG_ALLOCATED;
 
 /* Allocate and initialize png_ptr struct for writing, and any other memory */
-extern PNG_EXPORT(png_structp,png_create_write_struct)
+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)) PNG_ALLOCATED;
 
-extern PNG_EXPORT(png_size_t,png_get_compression_buffer_size)
-   PNGARG((png_structp png_ptr));
+PNG_EXPORT(png_size_t,png_get_compression_buffer_size)
+   PNGARG((png_const_structp png_ptr));
 
-extern PNG_EXPORT(void,png_set_compression_buffer_size)
+PNG_EXPORT(void,png_set_compression_buffer_size)
    PNGARG((png_structp png_ptr, png_size_t size));
 
 /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
@@ -1589,7 +1604,7 @@ extern PNG_EXPORT(void,png_set_compression_buffer_size)
  * allocated by the library - the call will return NULL on a mismatch
  * indicating an ABI mismatch.
  */
-extern PNG_EXPORT(jmp_buf*, png_set_longjmp_fn)
+PNG_EXPORT(jmp_buf*, png_set_longjmp_fn)
    PNGARG((png_structp png_ptr, png_longjmp_ptr longjmp_fn, size_t
        jmp_buf_size));
 #  define png_jmpbuf(png_ptr) \
@@ -1601,170 +1616,170 @@ extern PNG_EXPORT(jmp_buf*, png_set_longjmp_fn)
 
 #ifdef PNG_READ_SUPPORTED
 /* Reset the compression stream */
-extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
+PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
 #endif
 
 /* 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)
+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)) PNG_ALLOCATED;
-extern PNG_EXPORT(png_structp,png_create_write_struct_2)
+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)) PNG_ALLOCATED;
 #endif
 
 /* Write the PNG file signature. */
-extern PNG_EXPORT(void,png_write_sig) PNGARG((png_structp png_ptr));
+PNG_EXPORT(void,png_write_sig) PNGARG((png_structp png_ptr));
 
 /* Write a PNG chunk - size, type, (optional) data, CRC. */
-extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
+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_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_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));
+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)
+PNG_EXPORT(png_infop,png_create_info_struct)
    PNGARG((png_structp png_ptr)) PNG_ALLOCATED;
 
-extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
+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_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_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 /* Read the information before the actual image data. */
-extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 #endif
 
 #ifdef PNG_TIME_RFC1123_SUPPORTED
-extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
+PNG_EXPORT(png_charp,png_convert_to_rfc1123)
    PNGARG((png_structp png_ptr, png_timep ptime));
 #endif
 
 #ifdef PNG_CONVERT_tIME_SUPPORTED
 /* Convert from a struct tm to png_time */
-extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
+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,
+PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
    time_t ttime));
 #endif /* PNG_CONVERT_tIME_SUPPORTED */
 
 #ifdef 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_expand_gray_1_2_4_to_8) PNGARG((png_structp
+PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+PNG_EXPORT(void,png_set_expand_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));
+PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+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));
+PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
 #endif
 
 #ifdef 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));
+PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
 #endif
 
 #ifdef 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,
+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,
+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_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_const_structp
    png_ptr));
 #endif
 
-extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
+PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
    png_colorp palette));
 
 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
+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));
+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));
+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_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. */
-extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
    png_uint_32 filler, int flags));
 #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));
+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));
+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));
+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_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));
+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));
+PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
 #endif
 
 #ifdef 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_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
@@ -1776,14 +1791,14 @@ extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
 
 #ifdef 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));
+PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
 #endif
 
 #ifdef PNG_READ_QUANTIZE_SUPPORTED
 /* Turn on quantizing, and reduce the palette to the number of colors
  * available.  Prior to libpng-1.4.2, this was png_set_dither().
  */
-extern PNG_EXPORT(void,png_set_quantize) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_quantize) PNGARG((png_structp png_ptr,
    png_colorp palette, int num_palette, int maximum_colors,
    png_uint_16p histogram, int full_quantize));
 #endif
@@ -1793,7 +1808,7 @@ extern PNG_EXPORT(void,png_set_quantize) PNGARG((png_structp png_ptr,
 #ifdef 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,
+PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
    double screen_gamma, double default_file_gamma));
 #endif
 #endif
@@ -1801,85 +1816,85 @@ extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
 
 #ifdef 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));
+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));
+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));
+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_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 /* Read one or more rows of image data. */
-extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
    png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
 #endif
 
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 /* Read a row of data. */
-extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
    png_bytep row,
    png_bytep display_row));
 #endif
 
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 /* Read the whole image into memory at once. */
-extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
+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_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_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_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
    png_bytepp image));
 
 #ifdef PNG_WRITE_APNG_SUPPORTED
 extern PNG_EXPORT (void,png_write_frame_head) PNGARG((png_structp png_ptr,
    png_infop png_info, png_bytepp row_pointers,
    png_uint_32 width, png_uint_32 height,
-   png_uint_32 x_offset, png_uint_32 y_offset, 
+   png_uint_32 x_offset, png_uint_32 y_offset,
    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
    png_byte blend_op));
 
 extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr,
    png_infop png_info));
 #endif
-   
+
 /* Write the end of the PNG file. */
-extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 /* Read the end of the PNG file. */
-extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
+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_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_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
    png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
 
 /* Free any memory associated with the png_struct and the png_info_structs */
-extern PNG_EXPORT(void,png_destroy_write_struct)
+PNG_EXPORT(void,png_destroy_write_struct)
    PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
 
 /* Set the libpng method of handling chunk CRC errors */
-extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
+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
@@ -1909,7 +1924,7 @@ extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
 /* 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,
+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
@@ -1966,7 +1981,7 @@ extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int 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,
+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
@@ -1987,19 +2002,19 @@ extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
  * 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,
+PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
    int level));
 
-extern PNG_EXPORT(void,png_set_compression_mem_level)
+PNG_EXPORT(void,png_set_compression_mem_level)
    PNGARG((png_structp png_ptr, int mem_level));
 
-extern PNG_EXPORT(void,png_set_compression_strategy)
+PNG_EXPORT(void,png_set_compression_strategy)
    PNGARG((png_structp png_ptr, int strategy));
 
-extern PNG_EXPORT(void,png_set_compression_window_bits)
+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,
+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
@@ -2013,7 +2028,7 @@ extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
 
 #ifdef PNG_STDIO_SUPPORTED
 /* 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_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr,
     png_FILE_p fp));
 #endif
 
@@ -2025,11 +2040,11 @@ extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr,
  * default function will be used.
  */
 
-extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
+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));
+PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_const_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.
@@ -2041,54 +2056,54 @@ extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
  * default flush function, which uses the standard *FILE structure, will
  * be used.
  */
-extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
+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_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));
+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_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_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_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));
+PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_const_structp png_ptr));
 #endif
 
 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
+PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
    png_ptr, png_user_transform_ptr read_user_transform_fn));
 #endif
 
 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
+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)
-extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+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));
+PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+   PNGARG((png_const_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_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_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_const_structp
    png_ptr));
 #endif
 
@@ -2096,50 +2111,52 @@ extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
 /* 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_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));
+
 #ifdef PNG_READ_APNG_SUPPORTED
-extern PNG_EXPORT(void,png_set_progressive_frame_fn) PNGARG((png_structp png_ptr,
+extern PNG_EXPORT(void,png_set_progressive_frame_fn) PNGARG((png_structp
+   png_ptr,
    png_progressive_frame_ptr frame_info_fn,
    png_progressive_frame_ptr frame_end_fn));
 #endif
 
 /* Returns the user pointer associated with the push read functions */
-extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
-   PNGARG((png_structp png_ptr));
+PNG_EXPORT(png_voidp,png_get_progressive_ptr)
+   PNGARG((png_const_structp png_ptr));
 
 /* Function to be called when data becomes available */
-extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
+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_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_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
    png_alloc_size_t size)) PNG_ALLOCATED;
 /* Added at libpng version 1.4.0 */
-extern PNG_EXPORT(png_voidp,png_calloc) PNGARG((png_structp png_ptr,
+PNG_EXPORT(png_voidp,png_calloc) PNGARG((png_structp png_ptr,
    png_alloc_size_t size)) PNG_ALLOCATED;
 
 /* Added at libpng version 1.2.4 */
-extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
+PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
    png_alloc_size_t size)) PNG_ALLOCATED;
 
 /* Frees a pointer allocated by png_malloc() */
-extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
+PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
 
 /* Free data that was allocated internally */
-extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 free_me, int num));
 /* 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_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int freer, png_uint_32 mask));
 /* Assignments for png_data_freer */
 #define PNG_DESTROY_WILL_FREE_DATA 1
@@ -2161,45 +2178,45 @@ extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
 #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_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
    png_alloc_size_t size)) PNG_ALLOCATED;
-extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
    png_voidp ptr));
 #endif
 
 #ifndef PNG_NO_ERROR_TEXT
 /* Fatal error in PNG image of libpng - can't continue */
-extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
    png_const_charp error_message)) PNG_NORETURN;
 
 /* 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_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
    png_const_charp error_message)) PNG_NORETURN;
 
 #else
 /* Fatal error in PNG image of libpng - can't continue */
-extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)) PNG_NORETURN;
+PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)) PNG_NORETURN;
 #endif
 
 /* Non-fatal error in libpng.  Can continue, but may have a problem. */
-extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
+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_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
    png_const_charp warning_message));
 
 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
 /* Benign error in libpng.  Can continue, but may have a problem.
  * User can choose whether to handle as a fatal error or as a warning. */
-extern PNG_EXPORT(void,png_benign_error) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_benign_error) PNGARG((png_structp png_ptr,
    png_const_charp warning_message));
 
 /* Same, chunk name is prepended to message. */
-extern PNG_EXPORT(void,png_chunk_benign_error) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_chunk_benign_error) PNGARG((png_structp png_ptr,
    png_const_charp warning_message));
 
-extern PNG_EXPORT(void,png_set_benign_errors) PNGARG((png_structp
+PNG_EXPORT(void,png_set_benign_errors) PNGARG((png_structp
    png_ptr, int allowed));
 #endif
 
@@ -2216,109 +2233,109 @@ extern PNG_EXPORT(void,png_set_benign_errors) PNGARG((png_structp
  * 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));
+PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_uint_32 flag));
 
 /* Returns number of bytes needed to hold a transformed row. */
-extern PNG_EXPORT(png_size_t,png_get_rowbytes) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
+PNG_EXPORT(png_size_t,png_get_rowbytes) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr));
 
 #ifdef 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));
+PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_const_structp png_ptr,
+   png_const_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_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));
+PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_const_structp png_ptr,
+   png_const_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));
+PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_const_structp
+   png_ptr, png_const_infop info_ptr));
+PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_const_structp
+   png_ptr, png_const_infop info_ptr));
+PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_const_structp
+   png_ptr, png_const_infop info_ptr));
+PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_const_structp
+   png_ptr, png_const_infop info_ptr));
+PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_const_structp
+   png_ptr, png_const_infop info_ptr));
+PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_const_structp
+   png_ptr, png_const_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));
+PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_const_structp png_ptr,
+   png_infop info_ptr));
 
 #ifdef PNG_bKGD_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
+PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_const_structp png_ptr,
    png_infop info_ptr, png_color_16p *background));
 #endif
 
 #ifdef PNG_bKGD_SUPPORTED
-extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_16p background));
 #endif
 
 #ifdef 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,
+PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_const_structp png_ptr,
+   png_const_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
+PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_const_structp png_ptr,
+   png_const_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));
@@ -2327,12 +2344,12 @@ extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
 
 #ifdef PNG_cHRM_SUPPORTED
 #ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
+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_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,
@@ -2342,132 +2359,132 @@ extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
 
 #ifdef 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));
+PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_const_structp png_ptr,
+   png_const_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));
+PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_fixed_point *int_file_gamma));
 #endif
 
 #ifdef PNG_gAMA_SUPPORTED
 #ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
+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_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_fixed_point int_file_gamma));
 #endif
 
 #ifdef 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));
+PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_uint_16p *hist));
 #endif
 
 #ifdef PNG_hIST_SUPPORTED
-extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
+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_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_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));
 
 #ifdef 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,
+PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
    int *unit_type));
 #endif
 
 #ifdef PNG_oFFs_SUPPORTED
-extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
+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
 
 #ifdef 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,
+PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_const_structp png_ptr,
+   png_const_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
 
 #ifdef PNG_pCAL_SUPPORTED
-extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
+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
 
 #ifdef 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));
+PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
 #endif
 
 #ifdef PNG_pHYs_SUPPORTED
-extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
+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));
+PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_colorp *palette, int *num_palette));
 
-extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_colorp palette, int num_palette));
 
 #ifdef PNG_sBIT_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
+PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_const_structp png_ptr,
    png_infop info_ptr, png_color_8p *sig_bit));
 #endif
 
 #ifdef PNG_sBIT_SUPPORTED
-extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_8p sig_bit));
 #endif
 
 #ifdef PNG_sRGB_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
-   png_infop info_ptr, int *intent));
+PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, int *intent));
 #endif
 
 #ifdef PNG_sRGB_SUPPORTED
-extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
+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_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int intent));
 #endif
 
 #ifdef 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_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_const_structp png_ptr,
+   png_const_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
 
 #ifdef PNG_iCCP_SUPPORTED
-extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+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
 
 #ifdef 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));
+PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_sPLT_tpp entries));
 #endif
 
 #ifdef PNG_sPLT_SUPPORTED
-extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_sPLT_tp entries, int nentries));
 #endif
 
 #ifdef 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));
+PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_textp *text_ptr, int *num_text));
 #endif
 
 /* Note while png_set_text() will accept a structure whose text,
@@ -2478,28 +2495,28 @@ extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
  */
 
 #ifdef PNG_TEXT_SUPPORTED
-extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_textp text_ptr, int num_text));
 #endif
 
 #ifdef PNG_tIME_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
+PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_const_structp png_ptr,
    png_infop info_ptr, png_timep *mod_time));
 #endif
 
 #ifdef PNG_tIME_SUPPORTED
-extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_timep mod_time));
 #endif
 
 #ifdef PNG_tRNS_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
+PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_const_structp png_ptr,
    png_infop info_ptr, png_bytep *trans_alpha, int *num_trans,
    png_color_16p *trans_color));
 #endif
 
 #ifdef PNG_tRNS_SUPPORTED
-extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_bytep trans_alpha, int num_trans,
    png_color_16p trans_color));
 #endif
@@ -2509,23 +2526,23 @@ extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
 
 #ifdef 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));
+PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_const_structp png_ptr,
+   png_const_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));
+PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
 #endif
 #endif
 #endif /* PNG_sCAL_SUPPORTED */
 
 #ifdef PNG_sCAL_SUPPORTED
 #ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+PNG_EXPORT(void,png_set_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(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
+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
@@ -2534,21 +2551,21 @@ extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
 #ifdef PNG_APNG_SUPPORTED
 extern PNG_EXPORT(png_uint_32,png_get_acTL) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
-extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr, 
+extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
 extern PNG_EXPORT(png_uint_32,png_get_num_frames) PNGARG((png_structp png_ptr,
    png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32,png_get_num_plays) 
+extern PNG_EXPORT(png_uint_32,png_get_num_plays)
    PNGARG((png_structp png_ptr, png_infop info_ptr));
 
-extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL) 
-   PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, 
-   png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset, 
+extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL)
+   PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
+   png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
    png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
    png_byte *blend_op));
-extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL) 
-   PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width, 
-   png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset, 
+extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL)
+   PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
+   png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
    png_byte blend_op));
 extern PNG_EXPORT(void,png_ensure_fcTL_is_valid)
@@ -2594,47 +2611,47 @@ extern PNG_EXPORT(void,png_read_frame_head) PNGARG((png_structp png_ptr,
            = 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_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
    png_ptr, int keep, png_bytep chunk_list, int num_chunks));
 PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
    chunk_name));
 #endif
 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
+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)
+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));
+PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_const_structp
+   png_ptr, png_const_infop info_ptr, png_unknown_chunkpp entries));
 #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_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int mask));
 
 #ifdef 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_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_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
                         png_infop info_ptr,
                         int transforms,
                         png_voidp params));
 #endif
 
-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_EXPORT(png_charp,png_get_copyright) PNGARG((png_const_structp png_ptr));
+PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_const_structp png_ptr));
+PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_const_structp
     png_ptr));
-extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
+PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_const_structp png_ptr));
 
 #ifdef PNG_MNG_FEATURES_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
+PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
    png_ptr, png_uint_32 mng_features_permitted));
 #endif
 
@@ -2648,57 +2665,58 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
  * 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_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
    png_ptr, png_uint_32 strip_mode));
 #endif
 
 /* Added in libpng-1.2.6 */
 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
-extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
+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_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_const_structp
    png_ptr));
-extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
+PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_const_structp
    png_ptr));
 /* Added in libpng-1.4.0 */
-extern PNG_EXPORT(void,png_set_chunk_cache_max) PNGARG((png_structp
+PNG_EXPORT(void,png_set_chunk_cache_max) PNGARG((png_structp
    png_ptr, png_uint_32 user_chunk_cache_max));
-extern PNG_EXPORT(png_uint_32,png_get_chunk_cache_max)
-   PNGARG((png_structp png_ptr));
+PNG_EXPORT(png_uint_32,png_get_chunk_cache_max)
+   PNGARG((png_const_structp png_ptr));
 /* Added in libpng-1.4.1 */
-extern PNG_EXPORT(void,png_set_chunk_malloc_max) PNGARG((png_structp
+PNG_EXPORT(void,png_set_chunk_malloc_max) PNGARG((png_structp
    png_ptr, png_alloc_size_t user_chunk_cache_max));
-extern PNG_EXPORT(png_alloc_size_t,png_get_chunk_malloc_max)
-   PNGARG((png_structp png_ptr));
+PNG_EXPORT(png_alloc_size_t,png_get_chunk_malloc_max)
+   PNGARG((png_const_structp png_ptr));
 #endif
 
 #if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
-PNG_EXPORT(png_uint_32,png_get_pixels_per_inch) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
+PNG_EXPORT(png_uint_32,png_get_pixels_per_inch)
+   PNGARG((png_const_structp png_ptr, png_const_infop info_ptr));
 
-PNG_EXPORT(png_uint_32,png_get_x_pixels_per_inch) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
+PNG_EXPORT(png_uint_32,png_get_x_pixels_per_inch)
+   PNGARG((png_const_structp png_ptr, png_const_infop info_ptr));
 
-PNG_EXPORT(png_uint_32,png_get_y_pixels_per_inch) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
+PNG_EXPORT(png_uint_32,png_get_y_pixels_per_inch)
+   PNGARG((png_const_structp png_ptr, png_const_infop info_ptr));
 
-PNG_EXPORT(float,png_get_x_offset_inches) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
+PNG_EXPORT(float,png_get_x_offset_inches) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr));
 
-PNG_EXPORT(float,png_get_y_offset_inches) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
+PNG_EXPORT(float,png_get_y_offset_inches) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr));
 
 #ifdef PNG_pHYs_SUPPORTED
-PNG_EXPORT(png_uint_32,png_get_pHYs_dpi) PNGARG((png_structp png_ptr,
-png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+PNG_EXPORT(png_uint_32,png_get_pHYs_dpi) PNGARG((png_const_structp png_ptr,
+   png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+   int *unit_type));
 #endif /* PNG_pHYs_SUPPORTED */
 #endif  /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
 
 /* Added in libpng-1.4.0 */
 #ifdef PNG_IO_STATE_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_io_state) PNGARG((png_structp png_ptr));
+PNG_EXPORT(png_uint_32,png_get_io_state) PNGARG((png_const_structp png_ptr));
 
-extern PNG_EXPORT(png_bytep,png_get_io_chunk_name)
+PNG_EXPORT(png_bytep,png_get_io_chunk_name)
    PNGARG((png_structp png_ptr));
 
 /* The flags returned by png_get_io_state() are the following: */
@@ -2764,44 +2782,52 @@ extern PNG_EXPORT(png_bytep,png_get_io_chunk_name)
  * The png_get_int_32() routine assumes we are using two's complement
  * format for negative values, which is almost certainly true.
  */
-/* We could make special-case BIG_ENDIAN macros that do direct reads here */
 #  define png_get_uint_32(buf) \
      (((png_uint_32)(*(buf)) << 24) + \
       ((png_uint_32)(*((buf) + 1)) << 16) + \
       ((png_uint_32)(*((buf) + 2)) << 8) + \
       ((png_uint_32)(*((buf) + 3))))
+
+  /* The following definition introduces an API incompatibility (but not
+   * an ABI incompatibility) with libpng-1.4.0 through 1.4.4.  Prior to
+   * libpng-1.4.5 the macro, which is used by default, returned (incorrectly)
+   * a (png_uint_32), while the function, if used instead, correctly returned
+   * a (png_uint_16).
+   *
+   * Libpng versions 1.0.x and 1.2.x only used a function so are not affected
+   * by this potential API incompatibility between macros.
+   */
 #  define png_get_uint_16(buf) \
-     (((png_uint_32)(*(buf)) << 8) + \
-      ((png_uint_32)(*((buf) + 1))))
-#ifdef PNG_GET_INT_32_SUPPORTED
+     ((png_uint_16) \
+       (((unsigned int)(*(buf)) << 8) + \
+        ((unsigned int)(*((buf) + 1)))))
+
 #  define png_get_int_32(buf) \
-     (((png_int_32)(*(buf)) << 24) + \
-      ((png_int_32)(*((buf) + 1)) << 16) + \
-      ((png_int_32)(*((buf) + 2)) << 8) + \
-      ((png_int_32)(*((buf) + 3))))
-#endif
+     ((png_int_32)((*(buf) & 0x80) \
+      ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \
+      : (png_int_32)png_get_uint_32(buf)))
 #else
-extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
-extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
+PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
+PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
 #ifdef PNG_GET_INT_32_SUPPORTED
-extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
+PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
 #endif
 #endif
-extern PNG_EXPORT(png_uint_32,png_get_uint_31)
+PNG_EXPORT(png_uint_32,png_get_uint_31)
   PNGARG((png_structp png_ptr, png_bytep buf));
 /* No png_get_int_16 -- may be added if there's a real need for it. */
 
 /* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
-extern PNG_EXPORT(void,png_save_uint_32)
+PNG_EXPORT(void,png_save_uint_32)
    PNGARG((png_bytep buf, png_uint_32 i));
-extern PNG_EXPORT(void,png_save_int_32)
+PNG_EXPORT(void,png_save_int_32)
    PNGARG((png_bytep buf, png_int_32 i));
 
 /* 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.
  */
-extern PNG_EXPORT(void,png_save_uint_16)
+PNG_EXPORT(void,png_save_uint_16)
    PNGARG((png_bytep buf, unsigned int i));
 /* No png_save_int_16 -- may be added if there's a real need for it. */
 
diff --git a/modules/libimg/png/pngconf.h b/modules/libimg/png/pngconf.h
index 5e7be7ae6f39..7775bff9f7fb 100644
--- a/modules/libimg/png/pngconf.h
+++ b/modules/libimg/png/pngconf.h
@@ -1,9 +1,9 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.4.3 - June 26, 2010
+ * libpng version 1.4.7 - April 10, 2011
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2011 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.)
  *
@@ -46,14 +46,14 @@
  * includes the resource compiler for Windows DLL configurations.
  */
 #ifdef PNG_USER_CONFIG
+#  include "pngusr.h"
 #  ifndef PNG_USER_PRIVATEBUILD
 #    define PNG_USER_PRIVATEBUILD
 #  endif
-#  include "pngusr.h"
 #endif
 
 /*
- * If you create a private DLL you need to define in "pngusr.h" the followings:
+ * If you create a private DLL you should define in "pngusr.h" the following:
  * #define PNG_USER_PRIVATEBUILD 
  *  e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
@@ -61,7 +61,7 @@
  *        distinguish your DLL from those of the official release. These
  *        correspond to the trailing letters that come after the version
  *        number and must match your private DLL name>
- *  e.g. // private DLL "libpng13gx.dll"
+ *  e.g. // private DLL "libpng14gx.dll"
  *       #define PNG_USER_DLLFNAME_POSTFIX "gx"
  *
  * The following macros are also at your disposal if you want to complete the
@@ -86,6 +86,18 @@
 
 /* End of material added to libpng-1.2.8 */
 
+/* Added at libpng-1.4.6 */
+#ifndef PNG_UNUSED
+/* Unused formal parameter warnings are silenced using the following macro
+ * which is expected to have no bad effects on performance (optimizing
+ * compilers will probably remove it entirely).  Note that if you replace
+ * it with something other than whitespace, you must include the terminating
+ * semicolon.
+ */
+#  define PNG_UNUSED(param) (void)param;
+#endif
+/* End of material added to libpng-1.4.6 */
+
 #ifndef PNG_VERSION_INFO_ONLY
 
 /* This is the size of the compression buffer, and thus the size of
@@ -271,11 +283,19 @@
  * #define PNG_NO_STDIO
  */
 
+#ifdef _WIN32_WCE
+#  define PNG_NO_CONSOLE_IO
+#  define PNG_NO_STDIO
+#  define PNG_NO_TIME_RFC1123
+#  ifdef PNG_DEBUG
+#    undef PNG_DEBUG
+#  endif
+#endif
+
 #if !defined(PNG_NO_STDIO) && !defined(PNG_STDIO_SUPPORTED)
 #  define PNG_STDIO_SUPPORTED
 #endif
 
-
 #ifdef PNG_BUILD_DLL
 #  if !defined(PNG_CONSOLE_IO_SUPPORTED) && !defined(PNG_NO_CONSOLE_IO)
 #    define PNG_NO_CONSOLE_IO
@@ -441,7 +461,7 @@
 
 /* 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.
+ * If you do not want to use const, define PNG_NO_CONST.
  */
 
 #ifndef PNG_CONST
@@ -456,8 +476,10 @@
  * 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
+ * to an #undef, or pass in PNG_NO_feature 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
@@ -1129,7 +1151,7 @@ typedef unsigned char png_byte;
 #else
    typedef size_t png_size_t;
 #endif
-#define png_sizeof(x) sizeof(x)
+#define png_sizeof(x) (sizeof (x))
 
 /* The following is needed for medium model support.  It cannot be in the
  * pngpriv.h header.  Needs modification for other compilers besides
@@ -1251,6 +1273,13 @@ typedef char            FAR * FAR * FAR * png_charppp;
 #  define PNG_DLL
 #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.
+ */
+
 #ifdef __CYGWIN__
 #  undef PNGAPI
 #  define PNGAPI __cdecl
@@ -1258,14 +1287,11 @@ typedef char            FAR * FAR * FAR * png_charppp;
 #  define PNG_IMPEXP
 #endif
 
-#define PNG_USE_LOCAL_ARRAYS /* Not used in libpng, defined for legacy apps */
-
-/* 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.
- */
+#ifdef __WATCOMC__
+#  ifndef PNGAPI
+#    define PNGAPI
+#  endif
+#endif
 
 #if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
 #  ifndef PNG_NO_MODULEDEF
@@ -1350,6 +1376,8 @@ typedef char            FAR * FAR * FAR * png_charppp;
 #  define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
 #endif
 
+#define PNG_USE_LOCAL_ARRAYS /* Not used in libpng, defined for legacy apps */
+
 /* Support for compiler specific function attributes.  These are used
  * so that where compiler support is available incorrect use of API
  * functions in png.h will generate compiler warnings.
@@ -1378,15 +1406,15 @@ typedef char            FAR * FAR * FAR * png_charppp;
 #    endif
 #    ifndef PNG_ALLOCATED
 #      define PNG_ALLOCATED  __attribute__((__malloc__))
+#    endif
+#    ifndef PNG_DEPRECATED
+#      define PNG_DEPRECATED __attribute__((__deprecated__))
 #    endif
 
     /* This specifically protects structure members that should only be
      * accessed from within the library, therefore should be empty during
      * a library build.
      */
-#    ifndef PNG_DEPRECATED
-#      define PNG_DEPRECATED __attribute__((__deprecated__))
-#    endif
 #    ifndef PNG_DEPSTRUCT
 #      define PNG_DEPSTRUCT  __attribute__((__deprecated__))
 #    endif
@@ -1427,7 +1455,7 @@ typedef char            FAR * FAR * FAR * png_charppp;
 
 /* memory model/platform independent fns */
 #ifndef PNG_ABORT
-#  ifdef _WINDOWS_
+#  if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_))
 #     define PNG_ABORT() ExitProcess(0)
 #  else
 #     define PNG_ABORT() abort()
@@ -1448,7 +1476,8 @@ typedef char            FAR * FAR * FAR * png_charppp;
 #  define png_memset  _fmemset
 #  define png_sprintf sprintf
 #else
-#  ifdef _WINDOWS_  /* Favor Windows over C runtime fns */
+#  if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_))
+#    /* Favor Windows over C runtime fns */
 #    define CVT_PTR(ptr)         (ptr)
 #    define CVT_PTR_NOCHECK(ptr) (ptr)
 #    define png_strcpy  lstrcpyA
@@ -1468,31 +1497,32 @@ typedef char            FAR * FAR * FAR * png_charppp;
 #    define png_memcpy  memcpy
 #    define png_memset  memset
 #    define png_sprintf sprintf
-#    ifndef PNG_NO_SNPRINTF
-#      ifdef _MSC_VER
-#        define png_snprintf _snprintf   /* Added to v 1.2.19 */
-#        define png_snprintf2 _snprintf
-#        define png_snprintf6 _snprintf
-#      else
-#        define png_snprintf snprintf   /* Added to v 1.2.19 */
-#        define png_snprintf2 snprintf
-#        define png_snprintf6 snprintf
-#      endif
-#    else
-       /* You don't have or don't want to use snprintf().  Caution: Using
-        * sprintf instead of snprintf exposes your application to accidental
-        * or malevolent buffer overflows.  If you don't have snprintf()
-        * as a general rule you should provide one (you can get one from
-        * Portable OpenSSH).
-        */
-#      define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1)
-#      define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2)
-#      define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
-          sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
-#    endif
 #  endif
 #endif
 
+#ifndef PNG_NO_SNPRINTF
+#  ifdef _MSC_VER
+#    define png_snprintf _snprintf   /* Added to v 1.2.19 */
+#    define png_snprintf2 _snprintf
+#    define png_snprintf6 _snprintf
+#  else
+#    define png_snprintf snprintf   /* Added to v 1.2.19 */
+#    define png_snprintf2 snprintf
+#    define png_snprintf6 snprintf
+#  endif
+#else
+   /* You don't have or don't want to use snprintf().  Caution: Using
+    * sprintf instead of snprintf exposes your application to accidental
+    * or malevolent buffer overflows.  If you don't have snprintf()
+    * as a general rule you should provide one (you can get one from
+    * Portable OpenSSH).
+    */
+#  define png_snprintf(s1,n,fmt,x1) png_sprintf(s1,fmt,x1)
+#  define png_snprintf2(s1,n,fmt,x1,x2) png_sprintf(s1,fmt,x1,x2)
+#  define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
+      png_sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
+#endif
+
 /* png_alloc_size_t is guaranteed to be no smaller than png_size_t,
  * and no smaller than png_uint_32.  Casts from png_size_t or png_uint_32
  * to png_alloc_size_t are not necessary; in fact, it is recommended
@@ -1503,22 +1533,19 @@ typedef char            FAR * FAR * FAR * png_charppp;
  * to encounter practical situations that require such conversions.
  */
 #if defined(__TURBOC__) && !defined(__FLAT__)
-#  define  png_mem_alloc farmalloc
-#  define  png_mem_free  farfree
    typedef unsigned long png_alloc_size_t;
 #else
 #  if defined(_MSC_VER) && defined(MAXSEG_64K)
-#    define  png_mem_alloc(s) halloc(s, 1)
-#    define  png_mem_free     hfree
      typedef unsigned long    png_alloc_size_t;
 #  else
-#    if defined(_WINDOWS_) && (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL)
-#      define  png_mem_alloc(s) HeapAlloc(GetProcessHeap(), 0, s)
-#      define  png_mem_free(p)  HeapFree(GetProcessHeap(), 0, p)
-       typedef DWORD            png_alloc_size_t;
+     /* This is an attempt to detect an old Windows system where (int) is
+      * actually 16 bits, in that case png_malloc must have an argument with a
+      * bigger size to accomodate the requirements of the library.
+      */
+#    if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \
+        (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL)
+       typedef DWORD         png_alloc_size_t;
 #    else
-#      define  png_mem_alloc malloc
-#      define  png_mem_free  free
        typedef png_size_t    png_alloc_size_t;
 #    endif
 #  endif
diff --git a/modules/libimg/png/pngerror.c b/modules/libimg/png/pngerror.c
index 633eae29f9eb..c196b11ce049 100644
--- a/modules/libimg/png/pngerror.c
+++ b/modules/libimg/png/pngerror.c
@@ -1,8 +1,8 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * Last changed in libpng 1.4.0 [January 3, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [March 8, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -306,7 +306,7 @@ png_default_error(png_structp png_ptr, png_const_charp error_message)
    /* Here if not setjmp support or if png_ptr is null. */
    PNG_ABORT();
 #ifndef PNG_CONSOLE_IO_SUPPORTED
-   error_message = error_message; /* Make compiler happy */
+   PNG_UNUSED(error_message) /* Make compiler happy */
 #endif
 }
 
@@ -352,9 +352,9 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message)
      fprintf(stderr, PNG_STRING_NEWLINE);
    }
 #else
-   warning_message = warning_message; /* Make compiler happy */
+   PNG_UNUSED(warning_message) /* Make compiler happy */
 #endif
-   png_ptr = png_ptr; /* Make compiler happy */
+   PNG_UNUSED(png_ptr) /* Make compiler happy */
 }
 #endif /* PNG_WARNINGS_SUPPORTED */
 
@@ -380,7 +380,7 @@ png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
  * pointer before png_write_destroy and png_read_destroy are called.
  */
 png_voidp PNGAPI
-png_get_error_ptr(png_structp png_ptr)
+png_get_error_ptr(png_const_structp png_ptr)
 {
    if (png_ptr == NULL)
       return NULL;
diff --git a/modules/libimg/png/pngget.c b/modules/libimg/png/pngget.c
index 32d4e4a7248e..6af81a8e6c84 100644
--- a/modules/libimg/png/pngget.c
+++ b/modules/libimg/png/pngget.c
@@ -1,8 +1,8 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * Last changed in libpng 1.4.2 [May 6, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [April 10, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -18,7 +18,8 @@
 #include "pngpriv.h"
 
 png_uint_32 PNGAPI
-png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
+png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr,
+    png_uint_32 flag)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return(info_ptr->valid & flag);
@@ -28,7 +29,7 @@ png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
 }
 
 png_size_t PNGAPI
-png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
+png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return(info_ptr->rowbytes);
@@ -39,7 +40,7 @@ png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
 
 #ifdef PNG_INFO_IMAGE_SUPPORTED
 png_bytepp PNGAPI
-png_get_rows(png_structp png_ptr, png_infop info_ptr)
+png_get_rows(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return(info_ptr->row_pointers);
@@ -52,7 +53,7 @@ png_get_rows(png_structp png_ptr, png_infop info_ptr)
 #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)
+png_get_image_width(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return info_ptr->width;
@@ -61,7 +62,7 @@ png_get_image_width(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_uint_32 PNGAPI
-png_get_image_height(png_structp png_ptr, png_infop info_ptr)
+png_get_image_height(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return info_ptr->height;
@@ -70,7 +71,7 @@ png_get_image_height(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_byte PNGAPI
-png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
+png_get_bit_depth(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return info_ptr->bit_depth;
@@ -79,7 +80,7 @@ png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_byte PNGAPI
-png_get_color_type(png_structp png_ptr, png_infop info_ptr)
+png_get_color_type(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return info_ptr->color_type;
@@ -88,7 +89,7 @@ png_get_color_type(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_byte PNGAPI
-png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
+png_get_filter_type(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return info_ptr->filter_type;
@@ -97,7 +98,7 @@ png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_byte PNGAPI
-png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
+png_get_interlace_type(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return info_ptr->interlace_type;
@@ -106,7 +107,7 @@ png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_byte PNGAPI
-png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
+png_get_compression_type(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return info_ptr->compression_type;
@@ -115,7 +116,7 @@ png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_uint_32 PNGAPI
-png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+png_get_x_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
 #ifdef PNG_pHYs_SUPPORTED
@@ -136,7 +137,7 @@ png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_uint_32 PNGAPI
-png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+png_get_y_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
 #ifdef PNG_pHYs_SUPPORTED
@@ -157,7 +158,7 @@ png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_uint_32 PNGAPI
-png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+png_get_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
 #ifdef PNG_pHYs_SUPPORTED
@@ -180,7 +181,7 @@ png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 
 #ifdef PNG_FLOATING_POINT_SUPPORTED
 float PNGAPI
-png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
+png_get_pixel_aspect_ratio(png_const_structp png_ptr, png_const_infop info_ptr)
    {
    if (png_ptr != NULL && info_ptr != NULL)
 #ifdef PNG_pHYs_SUPPORTED
@@ -204,7 +205,7 @@ png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
 #endif
 
 png_int_32 PNGAPI
-png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
+png_get_x_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
 #ifdef PNG_oFFs_SUPPORTED
@@ -226,7 +227,7 @@ png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_int_32 PNGAPI
-png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
+png_get_y_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
 
@@ -248,7 +249,7 @@ png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_int_32 PNGAPI
-png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+png_get_x_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
 
@@ -270,7 +271,7 @@ png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_int_32 PNGAPI
-png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+png_get_y_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
 
@@ -293,35 +294,35 @@ png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 
 #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)
+png_get_pixels_per_inch(png_const_structp png_ptr, png_const_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)
+png_get_x_pixels_per_inch(png_const_structp png_ptr, png_const_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)
+png_get_y_pixels_per_inch(png_const_structp png_ptr, png_const_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)
+png_get_x_offset_inches(png_const_structp png_ptr, png_const_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)
+png_get_y_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
      *.00003937);
@@ -329,7 +330,7 @@ png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
 
 #ifdef PNG_pHYs_SUPPORTED
 png_uint_32 PNGAPI
-png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
+png_get_pHYs_dpi(png_const_structp png_ptr, png_const_infop info_ptr,
    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
 {
    png_uint_32 retval = 0;
@@ -369,7 +370,7 @@ png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
 #endif  /* PNG_EASY_ACCESS_SUPPORTED */
 
 png_byte PNGAPI
-png_get_channels(png_structp png_ptr, png_infop info_ptr)
+png_get_channels(png_const_structp png_ptr, png_const_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return(info_ptr->channels);
@@ -378,7 +379,7 @@ png_get_channels(png_structp png_ptr, png_infop info_ptr)
 }
 
 png_bytep PNGAPI
-png_get_signature(png_structp png_ptr, png_infop info_ptr)
+png_get_signature(png_const_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
       return(info_ptr->signature);
@@ -388,7 +389,7 @@ png_get_signature(png_structp png_ptr, png_infop info_ptr)
 
 #ifdef PNG_bKGD_SUPPORTED
 png_uint_32 PNGAPI
-png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
+png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr,
    png_color_16p *background)
 {
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
@@ -406,7 +407,7 @@ png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
 #ifdef PNG_cHRM_SUPPORTED
 #ifdef PNG_FLOATING_POINT_SUPPORTED
 png_uint_32 PNGAPI
-png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
+png_get_cHRM(png_const_structp png_ptr, png_const_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)
 {
@@ -437,7 +438,7 @@ png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
 #endif
 #ifdef PNG_FIXED_POINT_SUPPORTED
 png_uint_32 PNGAPI
-png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+png_get_cHRM_fixed(png_const_structp png_ptr, png_const_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)
@@ -472,7 +473,7 @@ png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
 #ifdef 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)
+png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr, double *file_gamma)
 {
    png_debug1(1, "in %s retrieval function", "gAMA");
 
@@ -487,7 +488,7 @@ png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
 #endif
 #ifdef PNG_FIXED_POINT_SUPPORTED
 png_uint_32 PNGAPI
-png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
+png_get_gAMA_fixed(png_const_structp png_ptr, png_const_infop info_ptr,
     png_fixed_point *int_file_gamma)
 {
    png_debug1(1, "in %s retrieval function", "gAMA");
@@ -505,7 +506,8 @@ png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_sRGB_SUPPORTED
 png_uint_32 PNGAPI
-png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
+png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr,
+    int *file_srgb_intent)
 {
    png_debug1(1, "in %s retrieval function", "sRGB");
 
@@ -521,7 +523,7 @@ png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
 
 #ifdef PNG_iCCP_SUPPORTED
 png_uint_32 PNGAPI
-png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+png_get_iCCP(png_const_structp png_ptr, png_const_infop info_ptr,
              png_charpp name, int *compression_type,
              png_charpp profile, png_uint_32 *proflen)
 {
@@ -545,7 +547,7 @@ png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_sPLT_SUPPORTED
 png_uint_32 PNGAPI
-png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
+png_get_sPLT(png_const_structp png_ptr, png_const_infop info_ptr,
              png_sPLT_tpp spalettes)
 {
    if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
@@ -559,7 +561,8 @@ png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_hIST_SUPPORTED
 png_uint_32 PNGAPI
-png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
+png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr,
+    png_uint_16p *hist)
 {
    png_debug1(1, "in %s retrieval function", "hIST");
 
@@ -614,7 +617,7 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_oFFs_SUPPORTED
 png_uint_32 PNGAPI
-png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
+png_get_oFFs(png_const_structp png_ptr, png_const_infop info_ptr,
    png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
 {
    png_debug1(1, "in %s retrieval function", "oFFs");
@@ -633,7 +636,7 @@ png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_pCAL_SUPPORTED
 png_uint_32 PNGAPI
-png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
+png_get_pCAL(png_const_structp png_ptr, png_const_infop info_ptr,
    png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
    png_charp *units, png_charpp *params)
 {
@@ -659,7 +662,7 @@ png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
 #ifdef PNG_sCAL_SUPPORTED
 #ifdef PNG_FLOATING_POINT_SUPPORTED
 png_uint_32 PNGAPI
-png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+png_get_sCAL(png_const_structp png_ptr, png_const_infop info_ptr,
              int *unit, double *width, double *height)
 {
     if (png_ptr != NULL && info_ptr != NULL &&
@@ -675,7 +678,7 @@ png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
 #else
 #ifdef PNG_FIXED_POINT_SUPPORTED
 png_uint_32 PNGAPI
-png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+png_get_sCAL_s(png_const_structp png_ptr, png_const_infop info_ptr,
              int *unit, png_charpp width, png_charpp height)
 {
     if (png_ptr != NULL && info_ptr != NULL &&
@@ -694,7 +697,7 @@ png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_pHYs_SUPPORTED
 png_uint_32 PNGAPI
-png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
+png_get_pHYs(png_const_structp png_ptr, png_const_infop info_ptr,
    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
 {
    png_uint_32 retval = 0;
@@ -727,7 +730,8 @@ png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
 #endif
 
 png_uint_32 PNGAPI
-png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
+png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr,
+    png_colorp *palette,
    int *num_palette)
 {
    png_debug1(1, "in %s retrieval function", "PLTE");
@@ -745,7 +749,8 @@ png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
 
 #ifdef PNG_sBIT_SUPPORTED
 png_uint_32 PNGAPI
-png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
+png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr,
+    png_color_8p *sig_bit)
 {
    png_debug1(1, "in %s retrieval function", "sBIT");
 
@@ -761,8 +766,8 @@ png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
 
 #ifdef 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)
+png_get_text(png_const_structp png_ptr, png_const_infop info_ptr,
+    png_textp *text_ptr, int *num_text)
 {
    if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
    {
@@ -786,7 +791,8 @@ png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
 
 #ifdef PNG_tIME_SUPPORTED
 png_uint_32 PNGAPI
-png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
+png_get_tIME(png_const_structp png_ptr, png_infop info_ptr,
+    png_timep *mod_time)
 {
    png_debug1(1, "in %s retrieval function", "tIME");
 
@@ -802,7 +808,7 @@ png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
 
 #ifdef PNG_tRNS_SUPPORTED
 png_uint_32 PNGAPI
-png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
+png_get_tRNS(png_const_structp png_ptr, png_infop info_ptr,
    png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
 {
    png_uint_32 retval = 0;
@@ -848,7 +854,7 @@ png_get_acTL(png_structp png_ptr, png_infop info_ptr,
              png_uint_32 *num_frames, png_uint_32 *num_plays)
 {
     png_debug1(1, "in %s retrieval function", "acTL");
-    
+
     if (png_ptr != NULL && info_ptr != NULL &&
         (info_ptr->valid & PNG_INFO_acTL) &&
         num_frames != NULL && num_plays != NULL)
@@ -857,7 +863,7 @@ png_get_acTL(png_structp png_ptr, png_infop info_ptr,
         *num_plays = info_ptr->num_plays;
         return (1);
     }
-    
+
     return (0);
 }
 
@@ -865,7 +871,7 @@ png_uint_32 PNGAPI
 png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_num_frames()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->num_frames);
     return (0);
@@ -875,7 +881,7 @@ png_uint_32 PNGAPI
 png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_num_plays()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->num_plays);
     return (0);
@@ -889,11 +895,11 @@ png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
              png_byte *dispose_op, png_byte *blend_op)
 {
     png_debug1(1, "in %s retrieval function", "fcTL");
-    
+
     if (png_ptr != NULL && info_ptr != NULL &&
         (info_ptr->valid & PNG_INFO_fcTL) &&
-        width != NULL && height != NULL && 
-        x_offset != NULL && x_offset != NULL && 
+        width != NULL && height != NULL &&
+        x_offset != NULL && x_offset != NULL &&
         delay_num != NULL && delay_den != NULL &&
 	dispose_op != NULL && blend_op != NULL)
     {
@@ -907,7 +913,7 @@ png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
         *blend_op = info_ptr->next_frame_blend_op;
         return (1);
     }
-    
+
     return (0);
 }
 
@@ -915,7 +921,7 @@ png_uint_32 PNGAPI
 png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_width()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_width);
     return (0);
@@ -925,7 +931,7 @@ png_uint_32 PNGAPI
 png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_height()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_height);
     return (0);
@@ -935,7 +941,7 @@ png_uint_32 PNGAPI
 png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_x_offset()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_x_offset);
     return (0);
@@ -945,7 +951,7 @@ png_uint_32 PNGAPI
 png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_y_offset()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_y_offset);
     return (0);
@@ -955,7 +961,7 @@ png_uint_16 PNGAPI
 png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_delay_num()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_delay_num);
     return (0);
@@ -965,7 +971,7 @@ png_uint_16 PNGAPI
 png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_delay_den()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_delay_den);
     return (0);
@@ -975,7 +981,7 @@ png_byte PNGAPI
 png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_dispose_op()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_dispose_op);
     return (0);
@@ -985,7 +991,7 @@ png_byte PNGAPI
 png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_get_next_frame_blend_op()");
-    
+
     if (png_ptr != NULL && info_ptr != NULL)
         return (info_ptr->next_frame_blend_op);
     return (0);
@@ -995,16 +1001,17 @@ png_byte PNGAPI
 png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
 {
     png_debug(1, "in png_first_frame_is_hidden()");
-    
+
     if (png_ptr != NULL)
        return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
-    
+
     return 0;
 }
 #endif /* PNG_APNG_SUPPORTED */
+
 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
 png_uint_32 PNGAPI
-png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
+png_get_unknown_chunks(png_const_structp png_ptr, png_const_infop info_ptr,
              png_unknown_chunkpp unknowns)
 {
    if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
@@ -1018,7 +1025,7 @@ png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
 png_byte PNGAPI
-png_get_rgb_to_gray_status (png_structp png_ptr)
+png_get_rgb_to_gray_status(png_const_structp png_ptr)
 {
    return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
 }
@@ -1026,14 +1033,14 @@ png_get_rgb_to_gray_status (png_structp png_ptr)
 
 #ifdef PNG_USER_CHUNKS_SUPPORTED
 png_voidp PNGAPI
-png_get_user_chunk_ptr(png_structp png_ptr)
+png_get_user_chunk_ptr(png_const_structp png_ptr)
 {
    return (png_ptr? png_ptr->user_chunk_ptr : NULL);
 }
 #endif
 
 png_size_t PNGAPI
-png_get_compression_buffer_size(png_structp png_ptr)
+png_get_compression_buffer_size(png_const_structp png_ptr)
 {
    return (png_ptr ? png_ptr->zbuf_size : 0L);
 }
@@ -1043,25 +1050,24 @@ png_get_compression_buffer_size(png_structp png_ptr)
 /* These functions were added to libpng 1.2.6 and were enabled
  * by default in libpng-1.4.0 */
 png_uint_32 PNGAPI
-png_get_user_width_max (png_structp png_ptr)
+png_get_user_width_max(png_const_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)
+png_get_user_height_max(png_const_structp png_ptr)
 {
     return (png_ptr? png_ptr->user_height_max : 0);
 }
-
 /* This function was added to libpng 1.4.0 */
 png_uint_32 PNGAPI
-png_get_chunk_cache_max (png_structp png_ptr)
+png_get_chunk_cache_max(png_const_structp png_ptr)
 {
     return (png_ptr? png_ptr->user_chunk_cache_max : 0);
 }
 /* This function was added to libpng 1.4.1 */
 png_alloc_size_t PNGAPI
-png_get_chunk_malloc_max (png_structp png_ptr)
+png_get_chunk_malloc_max(png_const_structp png_ptr)
 {
     return (png_ptr?
        png_ptr->user_chunk_malloc_max : 0);
@@ -1071,13 +1077,13 @@ png_get_chunk_malloc_max (png_structp png_ptr)
 /* These functions were added to libpng 1.4.0 */
 #ifdef PNG_IO_STATE_SUPPORTED
 png_uint_32 PNGAPI
-png_get_io_state (png_structp png_ptr)
+png_get_io_state(png_const_structp png_ptr)
 {
     return png_ptr->io_state;
 }
 
 png_bytep PNGAPI
-png_get_io_chunk_name (png_structp png_ptr)
+png_get_io_chunk_name(png_structp png_ptr)
 {
    return png_ptr->chunk_name;
 }
diff --git a/modules/libimg/png/pngmem.c b/modules/libimg/png/pngmem.c
index c8a3f6f59af1..911f36881ca6 100644
--- a/modules/libimg/png/pngmem.c
+++ b/modules/libimg/png/pngmem.c
@@ -1,8 +1,8 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * Last changed in libpng 1.4.2 [May 6, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [April 10, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -601,7 +601,7 @@ png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
  * pointer before png_write_destroy and png_read_destroy are called.
  */
 png_voidp PNGAPI
-png_get_mem_ptr(png_structp png_ptr)
+png_get_mem_ptr(png_const_structp png_ptr)
 {
    if (png_ptr == NULL)
       return (NULL);
diff --git a/modules/libimg/png/pngpread.c b/modules/libimg/png/pngpread.c
index 4af9b96b1b0a..391d75392e00 100644
--- a/modules/libimg/png/pngpread.c
+++ b/modules/libimg/png/pngpread.c
@@ -1,8 +1,8 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * Last changed in libpng 1.4.3 [June 26, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [March 8, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -234,9 +234,9 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    }
-   
+
 #ifdef PNG_READ_APNG_SUPPORTED
-   if (png_ptr->num_frames_read > 0 && 
+   if (png_ptr->num_frames_read > 0 &&
        png_ptr->num_frames_read < info_ptr->num_frames)
    {
       if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
@@ -244,7 +244,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
          /* Discard trailing IDATs for the first frame */
          if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
             png_error(png_ptr, "out of place IDAT");
-         
+
          if (png_ptr->push_length + 4 > png_ptr->buffer_size)
          {
             png_push_save_buffer(png_ptr);
@@ -262,13 +262,13 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
             return;
          }
          png_ensure_sequence_number(png_ptr, 4);
-         
+
          if (!(png_ptr->mode & PNG_HAVE_fcTL))
          {
             /* Discard trailing fdATs for frames other than the first */
             if (png_ptr->num_frames_read < 2)
                png_error(png_ptr, "out of place fdAT");
-            
+
             if (png_ptr->push_length + 4 > png_ptr->buffer_size)
             {
                png_push_save_buffer(png_ptr);
@@ -284,7 +284,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
             png_ptr->idat_size = png_ptr->push_length - 4;
             png_ptr->mode |= PNG_HAVE_IDAT;
             png_ptr->process_mode = PNG_READ_IDAT_MODE;
-            
+
             return;
          }
       }
@@ -295,23 +295,23 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
             png_push_save_buffer(png_ptr);
             return;
          }
-         
+
          png_read_reset(png_ptr);
          png_ptr->mode &= ~PNG_HAVE_fcTL;
-         
+
          png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
-         
+
          if (!(png_ptr->mode & PNG_HAVE_fcTL))
             png_error(png_ptr, "missing required fcTL chunk");
-         
+
          png_read_reinit(png_ptr, info_ptr);
          png_progressive_read_reset(png_ptr);
-         
+
          if (png_ptr->frame_info_fn != NULL)
             (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
-         
+
          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
-         
+
          return;
       }
       else
@@ -327,11 +327,11 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
          return;
       }
-      
+
       return;
    }
 #endif /* PNG_READ_APNG_SUPPORTED */
-   
+
    if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       if (png_ptr->mode & PNG_AFTER_IDAT)
          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
@@ -921,7 +921,7 @@ png_push_read_IDAT(png_structp png_ptr)
               return;
           }
       }
-      else 
+      else
 #endif
 #ifdef PNG_READ_APNG_SUPPORTED
       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)
@@ -942,7 +942,7 @@ png_push_read_IDAT(png_structp png_ptr)
       }
 
       png_ptr->idat_size = png_ptr->push_length;
-      
+
 #ifdef PNG_READ_APNG_SUPPORTED
       if (png_ptr->num_frames_read > 0)
       {
@@ -1032,7 +1032,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
     * or the stream marked as finished.
     */
    while (png_ptr->zstream.avail_in > 0 &&
-	  !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+      !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    {
       int ret;
 
@@ -1061,49 +1061,49 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
       /* Check for any failure before proceeding. */
       if (ret != Z_OK && ret != Z_STREAM_END)
       {
-	 /* Terminate the decompression. */
-	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         /* Terminate the decompression. */
+         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
 
          /* This may be a truncated stream (missing or
-	  * damaged end code).  Treat that as a warning.
-	  */
+          * damaged end code).  Treat that as a warning.
+          */
          if (png_ptr->row_number >= png_ptr->num_rows ||
-	     png_ptr->pass > 6)
-	    png_warning(png_ptr, "Truncated compressed data in IDAT");
-	 else
-	    png_error(png_ptr, "Decompression error in IDAT");
+             png_ptr->pass > 6)
+            png_warning(png_ptr, "Truncated compressed data in IDAT");
+         else
+            png_error(png_ptr, "Decompression error in IDAT");
 
-	 /* Skip the check on unprocessed input */
+         /* Skip the check on unprocessed input */
          return;
       }
 
       /* Did inflate output any data? */
       if (png_ptr->zstream.next_out != png_ptr->row_buf)
       {
-	 /* Is this unexpected data after the last row?
-	  * If it is, artificially terminate the LZ output
-	  * here.
-	  */
+         /* Is this unexpected data after the last row?
+          * If it is, artificially terminate the LZ output
+          * here.
+          */
          if (png_ptr->row_number >= png_ptr->num_rows ||
-	     png_ptr->pass > 6)
+             png_ptr->pass > 6)
          {
-	    /* Extra data. */
-	    png_warning(png_ptr, "Extra compressed data in IDAT");
+            /* Extra data. */
+            png_warning(png_ptr, "Extra compressed data in IDAT");
             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-	    /* Do no more processing; skip the unprocessed
-	     * input check below.
-	     */
+            /* Do no more processing; skip the unprocessed
+             * input check below.
+             */
             return;
-	 }
+         }
 
-	 /* Do we have a complete row? */
-	 if (png_ptr->zstream.avail_out == 0)
-	    png_push_process_row(png_ptr);
+         /* Do we have a complete row? */
+         if (png_ptr->zstream.avail_out == 0)
+            png_push_process_row(png_ptr);
       }
 
       /* And check for the end of the stream. */
       if (ret == Z_STREAM_END)
-	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    }
 
    /* All the data should have been processed, if anything
@@ -1177,7 +1177,7 @@ png_push_process_row(png_structp png_ptr)
 
             if (png_ptr->pass == 6 && png_ptr->height <= 4)
             {
-                  png_push_have_row(png_ptr, NULL);
+                png_push_have_row(png_ptr, NULL);
                 png_read_push_finish_row(png_ptr);
             }
 
@@ -1217,7 +1217,7 @@ png_push_process_row(png_structp png_ptr)
 
             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
             {
-                  png_push_have_row(png_ptr, NULL);
+               png_push_have_row(png_ptr, NULL);
                png_read_push_finish_row(png_ptr);
             }
 
@@ -1267,13 +1267,13 @@ png_push_process_row(png_structp png_ptr)
 
             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
             {
-                  png_push_have_row(png_ptr, NULL);
+               png_push_have_row(png_ptr, NULL);
                png_read_push_finish_row(png_ptr);
             }
 
             if (png_ptr->pass == 6) /* Pass 5 might be empty */
             {
-                  png_push_have_row(png_ptr, NULL);
+               png_push_have_row(png_ptr, NULL);
                png_read_push_finish_row(png_ptr);
             }
 
@@ -1292,12 +1292,14 @@ png_push_process_row(png_structp png_ptr)
 
             if (png_ptr->pass == 6) /* Skip top generated row */
             {
-                  png_push_have_row(png_ptr, NULL);
+               png_push_have_row(png_ptr, NULL);
                png_read_push_finish_row(png_ptr);
             }
 
             break;
          }
+
+         default:
          case 6:
          {
             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
@@ -1306,7 +1308,7 @@ png_push_process_row(png_structp png_ptr)
             if (png_ptr->pass != 6)
                break;
 
-                  png_push_have_row(png_ptr, NULL);
+            png_push_have_row(png_ptr, NULL);
             png_read_push_finish_row(png_ptr);
          }
       }
@@ -1391,7 +1393,7 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       {
          png_error(png_ptr, "Out of place tEXt");
-         info_ptr = info_ptr; /* To quiet some compiler warnings */
+         PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
       }
 
 #ifdef PNG_MAX_MALLOC_64K
@@ -1489,7 +1491,7 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       {
          png_error(png_ptr, "Out of place zTXt");
-         info_ptr = info_ptr; /* To quiet some compiler warnings */
+         PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
       }
 
 #ifdef PNG_MAX_MALLOC_64K
@@ -1690,7 +1692,7 @@ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       {
          png_error(png_ptr, "Out of place iTXt");
-         info_ptr = info_ptr; /* To quiet some compiler warnings */
+         PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
       }
 
 #ifdef PNG_MAX_MALLOC_64K
@@ -1817,15 +1819,14 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
    {
 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
-          PNG_HANDLE_CHUNK_ALWAYS
+         PNG_HANDLE_CHUNK_ALWAYS
 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
-          && png_ptr->read_user_chunk_fn == NULL
+         && png_ptr->read_user_chunk_fn == NULL
 #endif
-          )
+         )
 #endif
          png_chunk_error(png_ptr, "unknown critical chunk");
-
-      info_ptr = info_ptr; /* To quiet some compiler warnings */
+         PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
    }
 
 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
@@ -1915,7 +1916,7 @@ png_push_have_row(png_structp png_ptr, png_bytep row)
 }
 
 void PNGAPI
-png_progressive_combine_row (png_structp png_ptr,
+png_progressive_combine_row(png_structp png_ptr,
    png_bytep old_row, png_bytep new_row)
 {
    PNG_CONST int FARDATA png_pass_dsp_mask[7] =
@@ -1955,7 +1956,7 @@ png_set_progressive_frame_fn(png_structp png_ptr,
 #endif
 
 png_voidp PNGAPI
-png_get_progressive_ptr(png_structp png_ptr)
+png_get_progressive_ptr(png_const_structp png_ptr)
 {
    if (png_ptr == NULL)
       return (NULL);
diff --git a/modules/libimg/png/pngpriv.h b/modules/libimg/png/pngpriv.h
index e73f1088e722..3406469a17c7 100644
--- a/modules/libimg/png/pngpriv.h
+++ b/modules/libimg/png/pngpriv.h
@@ -1,9 +1,9 @@
 
 /* pngpriv.h - private declarations for use inside libpng
  *
- * libpng version 1.4.3 - June 26, 2010
+ * libpng version 1.4.7 - April 10, 2011
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2011 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.)
  *
@@ -28,14 +28,16 @@
 
 #include 
 
+#ifndef PNG_EXTERN
 /* The functions exported by PNG_EXTERN are 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 extern
  */
-#define PNG_EXTERN
+#  define PNG_EXTERN
+#endif
 
 /* Other defines specific to compilers can go here.  Try to keep
  * them inside an appropriate ifdef/endif pair for portability.
@@ -75,10 +77,6 @@
 #if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
     defined(_WIN32) || defined(__WIN32__)
 #  include   /* defines _WINDOWS_ macro */
-/* I have no idea why is this necessary... */
-#  ifdef _MSC_VER
-#    include 
-#  endif
 #endif
 
 /* Various modes of operation.  Note that after an init, mode is set to
@@ -301,6 +299,9 @@ PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
 PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
    png_size_t length));
 
+/* Read and check the PNG file signature */
+PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr));
+
 /* Read the chunk header (length + type name) */
 PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr));
 
@@ -481,9 +482,9 @@ PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
 PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
    png_uint_32 num_frames, png_uint_32 num_plays));
 
-PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr, 
-   png_uint_32 width, png_uint_32 height, 
-   png_uint_32 x_offset, png_uint_32 y_offset, 
+PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
+   png_uint_32 width, png_uint_32 height,
+   png_uint_32 x_offset, png_uint_32 y_offset,
    png_uint_16 delay_num, png_uint_16 delay_den,
    png_byte dispose_op, png_byte blend_op));
 #endif
@@ -550,7 +551,7 @@ PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr));
 #ifdef PNG_WRITE_APNG_SUPPORTED
 /* Private, reset some things to become ready for writing next frame */
 PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr, 
+PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 width, png_uint_32 height));
 #endif
 
@@ -706,7 +707,7 @@ PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
 #endif
 
 #ifdef PNG_READ_iCCP_SUPPORTED
-extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
+PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif /* PNG_READ_iCCP_SUPPORTED */
 
@@ -741,7 +742,7 @@ PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
 #endif
 
 #ifdef PNG_READ_sPLT_SUPPORTED
-extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif /* PNG_READ_sPLT_SUPPORTED */
 
@@ -778,7 +779,7 @@ PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr,
 PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr));
 PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
-PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr, 
+PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr,
    png_uint_32 length));
 #endif
 
@@ -874,14 +875,14 @@ PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
    int filter_type));
 
 /* 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_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_infop end_info_ptr));
 
 /* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
-extern void png_write_destroy PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr));
 
 #ifdef USE_FAR_KEYWORD  /* memory model conversion function */
-extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
+PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
    int check));
 #endif /* USE_FAR_KEYWORD */
 
diff --git a/modules/libimg/png/pngread.c b/modules/libimg/png/pngread.c
index f614f7f7c32b..2f20550abd2f 100644
--- a/modules/libimg/png/pngread.c
+++ b/modules/libimg/png/pngread.c
@@ -1,8 +1,8 @@
 
 /* pngread.c - read a PNG file
  *
- * Last changed in libpng 1.4.1 [February 25, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [March 8, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -214,34 +214,12 @@ void PNGAPI
 png_read_info(png_structp png_ptr, png_infop info_ptr)
 {
    png_debug(1, "in png_read_info");
- 
+
    if (png_ptr == NULL || info_ptr == NULL)
       return;
- 
-   /* 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;
 
-#ifdef PNG_IO_STATE_SUPPORTED
-      png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
-#endif
-
-      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;
-   }
+   /* Read and check the PNG file signature. */
+   png_read_sig(png_ptr, info_ptr);
 
    for (;;)
    {
@@ -442,22 +420,22 @@ void PNGAPI
 png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
 {
     png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
-    
+
     png_debug(0, "Reading frame head");
-    
+
     if (!(png_ptr->mode & PNG_HAVE_acTL))
         png_error(png_ptr, "attempt to png_read_frame_head() but "
                            "no acTL present");
-    
+
     /* do nothing for the main IDAT */
     if (png_ptr->num_frames_read == 0)
         return;
-    
+
     png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
-    
+
     png_read_reset(png_ptr);
     png_ptr->mode &= ~PNG_HAVE_fcTL;
-    
+
     have_chunk_after_DAT = 0;
     for (;;)
     {
@@ -466,13 +444,13 @@ png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
         PNG_fcTL;
         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);
-        
+
         if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
         {
             /* discard trailing IDATs for the first frame */
@@ -488,7 +466,7 @@ png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
         else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
         {
             png_ensure_sequence_number(png_ptr, length);
-            
+
             /* discard trailing fdATs for frames other than the first */
             if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
                 png_crc_finish(png_ptr, length - 4);
@@ -496,7 +474,7 @@ png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
             {
                 png_ptr->idat_size = length - 4;
                 png_ptr->mode |= PNG_HAVE_IDAT;
-                
+
                 break;
             }
             else
@@ -517,7 +495,7 @@ void PNGAPI
 png_read_update_info(png_structp png_ptr, png_infop info_ptr)
 {
    png_debug(1, "in png_read_update_info");
- 
+
    if (png_ptr == NULL)
       return;
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
@@ -539,7 +517,7 @@ void PNGAPI
 png_start_read_image(png_structp png_ptr)
 {
    png_debug(1, "in png_start_read_image");
- 
+
    if (png_ptr == NULL)
       return;
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
@@ -556,14 +534,16 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
    PNG_fdAT;
    PNG_IEND;
 #endif
+#ifdef PNG_READ_INTERLACING_SUPPORTED
    PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
       0xff};
    PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
    int ret;
- 
+#endif
+
    if (png_ptr == NULL)
       return;
- 
+
    png_debug2(1, "in png_read_row (row %lu, pass %d)",
       (unsigned long) png_ptr->row_number, png_ptr->pass);
 
@@ -619,6 +599,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
                return;
             }
             break;
+
          case 1:
             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
             {
@@ -629,6 +610,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
                return;
             }
             break;
+
          case 2:
             if ((png_ptr->row_number & 0x07) != 4)
             {
@@ -639,6 +621,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
                return;
             }
             break;
+
          case 3:
             if ((png_ptr->row_number & 3) || png_ptr->width < 3)
             {
@@ -649,6 +632,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
                return;
             }
             break;
+
          case 4:
             if ((png_ptr->row_number & 3) != 2)
             {
@@ -659,6 +643,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
                return;
             }
             break;
+
          case 5:
             if ((png_ptr->row_number & 1) || png_ptr->width < 2)
             {
@@ -669,6 +654,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
                return;
             }
             break;
+
+         default:
          case 6:
             if (!(png_ptr->row_number & 1))
             {
@@ -822,7 +809,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
    png_bytepp dp;
 
    png_debug(1, "in png_read_rows");
- 
+
    if (png_ptr == NULL)
       return;
    rp = row;
@@ -873,7 +860,7 @@ png_read_image(png_structp png_ptr, png_bytepp image)
    png_bytepp rp;
 
    png_debug(1, "in png_read_image");
- 
+
    if (png_ptr == NULL)
       return;
 
@@ -911,7 +898,7 @@ void PNGAPI
 png_read_end(png_structp png_ptr, png_infop info_ptr)
 {
    png_debug(1, "in png_read_end");
- 
+
    if (png_ptr == NULL)
       return;
    png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
@@ -1096,7 +1083,7 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
 #endif
 
    png_debug(1, "in png_destroy_read_struct");
- 
+
    if (png_ptr_ptr != NULL)
       png_ptr = *png_ptr_ptr;
    if (png_ptr == NULL)
@@ -1172,7 +1159,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
 #endif
 
    png_debug(1, "in png_read_destroy");
- 
+
    if (info_ptr != NULL)
       png_info_destroy(png_ptr, info_ptr);
 
@@ -1455,8 +1442,8 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
    /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
    png_read_end(png_ptr, info_ptr);
 
-   transforms = transforms; /* Quiet compiler warnings */
-   params = params;
+   PNG_UNUSED(transforms)   /* Quiet compiler warnings */
+   PNG_UNUSED(params)
 
 }
 #endif /* PNG_INFO_IMAGE_SUPPORTED */
diff --git a/modules/libimg/png/pngrio.c b/modules/libimg/png/pngrio.c
index 59059caf6927..710f4f0f460c 100644
--- a/modules/libimg/png/pngrio.c
+++ b/modules/libimg/png/pngrio.c
@@ -1,8 +1,8 @@
 
 /* pngrio.c - functions for data input
  *
- * Last changed in libpng 1.4.1 [February 25, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [January 14, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -33,7 +33,7 @@ void /* PRIVATE */
 png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    png_debug1(4, "reading %d bytes", (int)length);
- 
+
    if (png_ptr->read_data_fn != NULL)
       (*(png_ptr->read_data_fn))(png_ptr, data, length);
    else
diff --git a/modules/libimg/png/pngrtran.c b/modules/libimg/png/pngrtran.c
index b5e8f1a26f2b..8bb8c2b232fd 100644
--- a/modules/libimg/png/pngrtran.c
+++ b/modules/libimg/png/pngrtran.c
@@ -1,8 +1,8 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * Last changed in libpng 1.4.2 [May 6, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [%RDATE%]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -26,7 +26,7 @@ void PNGAPI
 png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
 {
    png_debug(1, "in png_set_crc_action");
- 
+
    if (png_ptr == NULL)
       return;
 
@@ -98,7 +98,7 @@ png_set_background(png_structp png_ptr,
    int need_expand, double background_gamma)
 {
    png_debug(1, "in png_set_background");
- 
+
    if (png_ptr == NULL)
       return;
    if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
@@ -686,6 +686,11 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
               break;
 
       case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+         break;
+
+      default:
+         png_error(png_ptr, "invalid error action in png_set_rgb_to_gray");
+         break;
    }
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 #ifdef PNG_READ_EXPAND_SUPPORTED
@@ -828,6 +833,8 @@ png_init_read_transformations(png_structp png_ptr)
                }
                break;
 
+            default:
+
             case 8:
 
             case 16:
@@ -1001,7 +1008,7 @@ png_init_read_transformations(png_structp png_ptr)
              */
             png_ptr->transformations &= ~PNG_BACKGROUND;
             png_ptr->transformations &= ~PNG_GAMMA;
-            png_ptr->transformations |= PNG_STRIP_ALPHA;
+            png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
          }
          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
          else
@@ -1028,6 +1035,9 @@ png_init_read_transformations(png_structp png_ptr)
                   gs = 1.0 / (png_ptr->background_gamma *
                      png_ptr->screen_gamma);
                   break;
+
+               default:
+                  png_error(png_ptr, "invalid background gamma type");
             }
 
             png_ptr->background_1.gray = (png_uint_16)(pow(
@@ -1121,7 +1131,7 @@ png_init_read_transformations(png_structp png_ptr)
 
       /* Handled alpha, still need to strip the channel. */
       png_ptr->transformations &= ~PNG_BACKGROUND;
-      png_ptr->transformations |= PNG_STRIP_ALPHA;
+      png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
    }
 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
 
@@ -1626,6 +1636,9 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
             }
             break;
          }
+
+         default:
+            break;
       }
       row_info->bit_depth = 8;
       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
@@ -1682,6 +1695,9 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
 
       switch (row_info->bit_depth)
       {
+         default:
+            break;
+
          case 2:
          {
             png_bytep bp;
@@ -2274,7 +2290,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
 
    png_debug(1, "in png_do_rgb_to_gray");
 
-   if (
+   if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&
       (row_info->color_type & PNG_COLOR_MASK_COLOR))
    {
       png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
@@ -2798,6 +2814,9 @@ png_do_background(png_row_infop row_info, png_bytep row,
                   }
                   break;
                }
+
+               default:
+                  break;
             }
             break;
          }
@@ -3230,6 +3249,9 @@ png_do_background(png_row_infop row_info, png_bytep row,
             }
             break;
          }
+
+         default:
+            break;
       }
 
       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
@@ -3428,6 +3450,9 @@ png_do_gamma(png_row_infop row_info, png_bytep row,
             }
             break;
          }
+
+         default:
+            break;
       }
    }
 }
@@ -3522,6 +3547,9 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
                }
                break;
             }
+
+            default:
+               break;
          }
          row_info->bit_depth = 8;
          row_info->pixel_depth = 8;
@@ -3672,6 +3700,9 @@ png_do_expand(png_row_infop row_info, png_bytep row,
                   }
                   break;
                }
+
+               default:
+                  break;
             }
 
             row_info->bit_depth = 8;
diff --git a/modules/libimg/png/pngrutil.c b/modules/libimg/png/pngrutil.c
index 6b5eb2b8ef7a..c540b94b67ab 100644
--- a/modules/libimg/png/pngrutil.c
+++ b/modules/libimg/png/pngrutil.c
@@ -1,8 +1,8 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.4.3 [June 26, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [March 8, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -23,50 +23,98 @@
 png_uint_32 PNGAPI
 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");
-   return (i);
-}
-#ifndef PNG_USE_READ_MACROS
-/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
-png_uint_32 PNGAPI
-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));
+   png_uint_32 val = png_get_uint_32(buf);
 
-   return (i);
+   if (val > PNG_UINT_31_MAX)
+     png_error(png_ptr, "PNG unsigned integer out of range");
+   return (val);
+}
+
+#ifndef PNG_USE_READ_MACROS
+/* The parentheses around "PNGAPI function_name" in the following three
+ * functions are necessary because they allow the macros to co-exist with
+ * these (unused but exported) functions.
+ */
+
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 (PNGAPI
+png_get_uint_32)(png_bytep buf)
+{
+   png_uint_32 uval = png_get_uint_32(buf);
+   if ((uval & 0x80000000L) == 0) /* non-negative */
+      return uval;
+
+   uval = (uval ^ 0xffffffffL) + 1;  /* 2's complement: -x = ~x+1 */
+   return -(png_int_32)uval;
 }
 
 /* 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.
+ * data is stored in the PNG file in two's complement format and there
+ * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
+ * the following code does a two's complement to native conversion.
  */
-png_int_32 PNGAPI
-png_get_int_32(png_bytep buf)
+png_int_32 (PNGAPI
+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));
+   png_uint_32 uval = png_get_uint_32(buf);
+   if ((uval & 0x80000000L) == 0) /* non-negative */
+      return uval;
 
-   return (i);
+   uval = (uval ^ 0xffffffffL) + 1;  /* 2's complement: -x = ~x+1 */
+   return -(png_int_32)uval;
 }
 
 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
-png_uint_16 PNGAPI
-png_get_uint_16(png_bytep buf)
+png_uint_16 (PNGAPI
+png_get_uint_16)(png_bytep buf)
 {
-   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
-      (png_uint_16)(*(buf + 1)));
+   /* ANSI-C requires an int value to accomodate at least 16 bits so this
+    * works and allows the compiler not to worry about possible narrowing
+    * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
+    * than 16 bits either.)
+    */
+   unsigned int val =
+       ((unsigned int)(*buf) << 8) +
+       ((unsigned int)(*(buf + 1)));
 
-   return (i);
+   return (png_uint_16)val;
 }
 #endif /* PNG_USE_READ_MACROS */
 
+/* Read and check the PNG file signature */
+void /* PRIVATE */
+png_read_sig(png_structp png_ptr, png_infop info_ptr)
+{
+   png_size_t num_checked, num_to_check;
+
+   /* Exit if the user application does not expect a signature. */
+   if (png_ptr->sig_bytes >= 8)
+      return;
+
+   num_checked = png_ptr->sig_bytes;
+   num_to_check = 8 - num_checked;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
+#endif
+
+   /* The signature must be serialized in a single I/O call. */
+   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;
+}
+
 /* Read the chunk header (length + type name).
  * Put the type name into png_ptr->chunk_name, and return the length.
  */
@@ -77,32 +125,31 @@ png_read_chunk_header(png_structp png_ptr)
    png_uint_32 length;
 
 #ifdef PNG_IO_STATE_SUPPORTED
-   /* Inform the I/O callback that the chunk header is being read.
-    * PNG_IO_CHUNK_HDR requires a single I/O call.
-    */
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
 #endif
 
-   /* Read the length and the chunk name */
+   /* Read the length and the chunk name.
+    * This must be performed in a single I/O call.
+    */
    png_read_data(png_ptr, buf, 8);
    length = png_get_uint_31(png_ptr, buf);
 
-   /* Put the chunk name into png_ptr->chunk_name */
+   /* Put the chunk name into png_ptr->chunk_name. */
    png_memcpy(png_ptr->chunk_name, buf + 4, 4);
 
    png_debug2(0, "Reading %s chunk, length = %lu",
-      png_ptr->chunk_name, length);
+      png_ptr->chunk_name, (unsigned long)length);
 
-   /* Reset the crc and run it over the chunk name */
+   /* Reset the crc and run it over the chunk name. */
    png_reset_crc(png_ptr);
    png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
 
-   /* Check to see if chunk name is valid */
+   /* Check to see if chunk name is valid. */
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 
 #ifdef PNG_IO_STATE_SUPPORTED
-   /* Inform the I/O callback that chunk data will (possibly) be read.
-    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
+   /* It is unspecified how many I/O calls will be performed
+    * during the serialization of the chunk data.
     */
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
 #endif
@@ -116,6 +163,7 @@ png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
 {
    if (png_ptr == NULL)
       return;
+
    png_read_data(png_ptr, buf, length);
    png_calculate_crc(png_ptr, buf, length);
 }
@@ -135,6 +183,7 @@ png_crc_finish(png_structp png_ptr, png_uint_32 skip)
    {
       png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
    }
+
    if (i)
    {
       png_crc_read(png_ptr, png_ptr->zbuf, i);
@@ -149,11 +198,13 @@ png_crc_finish(png_structp png_ptr, png_uint_32 skip)
       {
          png_chunk_warning(png_ptr, "CRC error");
       }
+
       else
       {
          png_chunk_benign_error(png_ptr, "CRC error");
          return (0);
       }
+
       return (1);
    }
 
@@ -176,6 +227,7 @@ png_crc_error(png_structp png_ptr)
           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
          need_crc = 0;
    }
+
    else                                                    /* critical */
    {
       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
@@ -183,11 +235,10 @@ png_crc_error(png_structp png_ptr)
    }
 
 #ifdef PNG_IO_STATE_SUPPORTED
-   /* Inform the I/O callback that the chunk CRC is being read */
-   /* PNG_IO_CHUNK_CRC requires the I/O to be done at once */
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
 #endif
 
+   /* The chunk CRC must be serialized in a single I/O call. */
    png_read_data(png_ptr, crc_bytes, 4);
 
    if (need_crc)
@@ -195,6 +246,7 @@ png_crc_error(png_structp png_ptr)
       crc = png_get_uint_32(crc_bytes);
       return ((int)(crc != png_ptr->crc));
    }
+
    else
       return (0);
 }
@@ -234,6 +286,7 @@ png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
             if (avail < copy) copy = avail;
             png_memcpy(output + count, png_ptr->zbuf, copy);
          }
+
          count += avail;
       }
 
@@ -267,9 +320,11 @@ png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
                case Z_BUF_ERROR:
                   msg = "Buffer error in compressed datastream in %s chunk";
                   break;
+
                case Z_DATA_ERROR:
                   msg = "Data error in compressed datastream in %s chunk";
                   break;
+
                default:
                   msg = "Incomplete compressed datastream in %s chunk";
                   break;
@@ -369,6 +424,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
             png_warning(png_ptr, "png_inflate logic error");
             png_free(png_ptr, text);
          }
+
          else
           png_warning(png_ptr, "Not enough memory to decompress chunk");
       }
@@ -652,7 +708,7 @@ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    }
    png_crc_finish(png_ptr, length);
 
-   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
+   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
 }
 
 #ifdef PNG_READ_gAMA_SUPPORTED
@@ -1165,9 +1221,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_bytep entry_start;
    png_sPLT_t new_palette;
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
    png_sPLT_entryp pp;
-#endif
    int data_length, entry_size, i;
    png_uint_32 skip = 0;
    png_size_t slength;
@@ -1306,7 +1360,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
           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;
+      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
    }
 #endif
 
@@ -1675,7 +1729,7 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    }
 
    png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
-      length + 1);
+      (unsigned long)(length + 1));
    png_free(png_ptr, png_ptr->chunkdata);
    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    if (png_ptr->chunkdata == NULL)
@@ -1813,7 +1867,7 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    }
 
    png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
-      length + 1);
+      (unsigned long)(length + 1));
    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    if (png_ptr->chunkdata == NULL)
    {
@@ -1880,9 +1934,6 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
       png_warning(png_ptr, "malformed height string in sCAL chunk");
       png_free(png_ptr, png_ptr->chunkdata);
       png_ptr->chunkdata = NULL;
-#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
-      png_free(png_ptr, swidth);
-#endif
       return;
    }
 #else
@@ -1893,9 +1944,7 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
       png_free(png_ptr, png_ptr->chunkdata);
       png_ptr->chunkdata = NULL;
-#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
       png_free(png_ptr, swidth);
-#endif
       return;
    }
    png_memcpy(sheight, ep, png_strlen(ep));
@@ -2357,7 +2406,7 @@ png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     png_uint_32 num_frames;
     png_uint_32 num_plays;
     png_uint_32 didSet;
-    
+
     png_debug(1, "in png_handle_acTL");
 
     if (!(png_ptr->mode & PNG_HAVE_IHDR))
@@ -2382,13 +2431,13 @@ png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
         png_crc_finish(png_ptr, length);
         return;
     }
-    
+
     png_crc_read(png_ptr, data, 8);
     png_crc_finish(png_ptr, 0);
-    
+
     num_frames = png_get_uint_31(png_ptr, data);
     num_plays = png_get_uint_31(png_ptr, data + 4);
-    
+
     /* the set function will do error checking on num_frames */
     didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
     if(didSet)
@@ -2407,9 +2456,11 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     png_uint_16 delay_den;
     png_byte dispose_op;
     png_byte blend_op;
-    
+
     png_debug(1, "in png_handle_fcTL");
-    
+
+    png_ensure_sequence_number(png_ptr, length);
+   
     if (!(png_ptr->mode & PNG_HAVE_IHDR))
     {
         png_error(png_ptr, "Missing IHDR before fcTL");
@@ -2420,13 +2471,13 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
         * but correct. PNG_HAVE_IDAT is unset before the frame head is read
         * i can't think of a better message */
         png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
-        png_crc_finish(png_ptr, length);
+        png_crc_finish(png_ptr, length-4);
         return;
     }
     else if (png_ptr->mode & PNG_HAVE_fcTL)
     {
         png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
-        png_crc_finish(png_ptr, length);
+        png_crc_finish(png_ptr, length-4);
         return;
     }
     else if (length != 26)
@@ -2435,12 +2486,10 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
         png_crc_finish(png_ptr, length);
         return;
     }
-    
-    png_ensure_sequence_number(png_ptr, length);
-    
+
     png_crc_read(png_ptr, data, 22);
     png_crc_finish(png_ptr, 0);
-    
+
     width = png_get_uint_31(png_ptr, data);
     height = png_get_uint_31(png_ptr, data + 4);
     x_offset = png_get_uint_31(png_ptr, data + 8);
@@ -2449,21 +2498,29 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     delay_den = png_get_uint_16(data + 18);
     dispose_op = data[20];
     blend_op = data[21];
-    
+
     if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
         png_error(png_ptr, "fcTL for the first frame must have zero offset");
-    if (png_ptr->num_frames_read == 0 && 
+    if (png_ptr->num_frames_read == 0 &&
         (width != info_ptr->width || height != info_ptr->height))
         png_error(png_ptr, "size in first frame's fcTL must match "
                            "the size in IHDR");
-    
-    /* the set function will do more error checking */
-    png_set_next_frame_fcTL(png_ptr, info_ptr, width, height, 
-                            x_offset, y_offset, delay_num, delay_den,
-                            dispose_op, blend_op);
-    
-    png_read_reinit(png_ptr, info_ptr);
-    
+
+    if (info_ptr != NULL)
+    {
+        if (png_ptr->num_frames_read == 0 &&
+            (width != info_ptr->width || height != info_ptr->height))
+            png_error(png_ptr, "size in first frame's fcTL must match "
+                               "the size in IHDR");
+        
+        /* the set function will do more error checking */
+        png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
+                                x_offset, y_offset, delay_num, delay_den,
+                                dispose_op, blend_op);
+        
+        png_read_reinit(png_ptr, info_ptr);
+    }
+
     png_ptr->mode |= PNG_HAVE_fcTL;
 }
 
@@ -2481,8 +2538,8 @@ void /* PRIVATE */
 png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
     png_ensure_sequence_number(png_ptr, length);
-    
-    /* This function is only called from png_read_end(), png_read_info(), 
+
+    /* This function is only called from png_read_end(), png_read_info(),
     * and png_push_read_chunk() which means that:
     * - the user doesn't want to read this frame
     * - or this is an out-of-place fdAT
@@ -2496,17 +2553,17 @@ png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
 {
     png_byte data[4];
     png_uint_32 sequence_number;
-    
+
     if (length < 4)
         png_error(png_ptr, "invalid fcTL or fdAT chunk found");
-    
+
     png_crc_read(png_ptr, data, 4);
     sequence_number = png_get_uint_31(png_ptr, data);
-    
+
     if (sequence_number != png_ptr->next_seq_num)
         png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
                            "number found");
-    
+
     png_ptr->next_seq_num++;
 }
 #endif /* PNG_READ_APNG_SUPPORTED */
@@ -2621,7 +2678,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    png_crc_finish(png_ptr, skip);
 
 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
-   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
+   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
 #endif
 }
 
@@ -3077,7 +3134,7 @@ png_do_read_interlace(png_structp png_ptr)
       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
    }
 #ifndef PNG_READ_PACKSWAP_SUPPORTED
-   transformations = transformations; /* Silence compiler warning */
+   PNG_UNUSED(transformations)  /* Silence compiler warning */
 #endif
 }
 #endif /* PNG_READ_INTERLACING_SUPPORTED */
@@ -3087,7 +3144,8 @@ 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");
-   png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
+   png_debug2(2, "row = %lu, filter = %d",
+      (unsigned long)png_ptr->row_number, filter);
    switch (filter)
    {
       case PNG_FILTER_VALUE_NONE:
@@ -3278,17 +3336,10 @@ png_read_finish_row(png_structp png_ptr)
          {
             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);
+               png_ptr->idat_size = png_read_chunk_header(png_ptr);
                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;
@@ -3535,13 +3586,13 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
 
    png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
 
-   png_debug1(3, "width = %lu,", png_ptr->width);
-   png_debug1(3, "height = %lu,", png_ptr->height);
-   png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
-   png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
-   png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
+   png_debug1(3, "width = %lu,", (unsigned long)png_ptr->width);
+   png_debug1(3, "height = %lu,", (unsigned long)png_ptr->height);
+   png_debug1(3, "iwidth = %lu,", (unsigned long)png_ptr->iwidth);
+   png_debug1(3, "num_rows = %lu,", (unsigned long)png_ptr->num_rows);
+   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
    png_debug1(3, "irowbytes = %lu",
-       PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
+       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
 
    png_ptr->flags |= PNG_FLAG_ROW_INIT;
 }
@@ -3585,7 +3636,7 @@ png_progressive_read_reset(png_structp png_ptr)
 
     /* offset to next interlace block in the y direction */
     const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-    
+
     if (png_ptr->interlaced)
     {
         if (!(png_ptr->transformations & PNG_INTERLACE))
diff --git a/modules/libimg/png/pngset.c b/modules/libimg/png/pngset.c
index 10bf08e01571..d1f53473197a 100644
--- a/modules/libimg/png/pngset.c
+++ b/modules/libimg/png/pngset.c
@@ -1,8 +1,8 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * Last changed in libpng 1.4.1 [February 25, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [January 14, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -260,7 +260,7 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
       info_ptr->rowbytes = 0;
    else
       info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
-   
+
 #if defined(PNG_APNG_SUPPORTED)
    /* for non-animated png. this may be overwritten from an acTL chunk later */
    info_ptr->num_frames = 1;
@@ -695,6 +695,13 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
       if (text_ptr[i].key == NULL)
           continue;
 
+      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
+          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
+      {
+         png_warning(png_ptr, "text compression mode is out of range");
+         continue;
+      }
+
       key_len = png_strlen(text_ptr[i].key);
 
       if (text_ptr[i].compression <= 0)
@@ -939,49 +946,49 @@ png_set_sPLT(png_structp png_ptr,
 
 #if defined(PNG_APNG_SUPPORTED)
 png_uint_32 PNGAPI
-png_set_acTL(png_structp png_ptr, png_infop info_ptr, 
+png_set_acTL(png_structp png_ptr, png_infop info_ptr,
     png_uint_32 num_frames, png_uint_32 num_plays)
 {
     png_debug1(1, "in %s storage function", "acTL");
 
     if (png_ptr == NULL || info_ptr == NULL)
     {
-        png_warning(png_ptr, 
+        png_warning(png_ptr,
                     "Call to png_set_acTL() with NULL png_ptr "
                     "or info_ptr ignored");
         return (0);
     }
     if (num_frames == 0)
     {
-        png_warning(png_ptr, 
+        png_warning(png_ptr,
                     "Ignoring attempt to set acTL with num_frames zero");
         return (0);
     }
     if (num_frames > PNG_UINT_31_MAX)
     {
-        png_warning(png_ptr, 
+        png_warning(png_ptr,
                     "Ignoring attempt to set acTL with num_frames > 2^31-1");
         return (0);
     }
     if (num_plays > PNG_UINT_31_MAX)
     {
-        png_warning(png_ptr, 
+        png_warning(png_ptr,
                     "Ignoring attempt to set acTL with num_plays "
                     "> 2^31-1");
         return (0);
     }
-    
+
     info_ptr->num_frames = num_frames;
     info_ptr->num_plays = num_plays;
-    
+
     info_ptr->valid |= PNG_INFO_acTL;
-    
+
     return (1);
 }
 
 /* delay_num and delay_den can hold any 16-bit values including zero */
 png_uint_32 PNGAPI
-png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr, 
+png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
     png_uint_32 width, png_uint_32 height,
     png_uint_32 x_offset, png_uint_32 y_offset,
     png_uint_16 delay_num, png_uint_16 delay_den,
@@ -991,15 +998,15 @@ png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
 
     if (png_ptr == NULL || info_ptr == NULL)
     {
-        png_warning(png_ptr, 
+        png_warning(png_ptr,
                     "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
                     "ignored");
         return (0);
     }
-    
-    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, 
+
+    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
                              delay_num, delay_den, dispose_op, blend_op);
-    
+
     /* For efficiency, ignore BLEND_OP_OVER when image is opaque.
      * See bug #441971 and #455140
      */
@@ -1023,20 +1030,20 @@ png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
     info_ptr->next_frame_delay_den = delay_den;
     info_ptr->next_frame_dispose_op = dispose_op;
     info_ptr->next_frame_blend_op = blend_op;
-    
+
     info_ptr->valid |= PNG_INFO_fcTL;
-    
+
     return (1);
 }
 
 void /* PRIVATE */
-png_ensure_fcTL_is_valid(png_structp png_ptr, 
+png_ensure_fcTL_is_valid(png_structp png_ptr,
     png_uint_32 width, png_uint_32 height,
     png_uint_32 x_offset, png_uint_32 y_offset,
     png_uint_16 delay_num, png_uint_16 delay_den,
     png_byte dispose_op, png_byte blend_op)
 {
-    if (width + x_offset > png_ptr->first_frame_width || 
+    if (width + x_offset > png_ptr->first_frame_width ||
         height + y_offset > png_ptr->first_frame_height)
         png_error(png_ptr, "dimensions of a frame are greater than"
                            "the ones in IHDR");
@@ -1064,15 +1071,15 @@ png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
                               png_byte is_hidden)
 {
     png_debug(1, "in png_first_frame_is_hidden()");
-    
+
     if (png_ptr == NULL)
         return 0;
-    
+
     if(is_hidden)
         png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
     else
         png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
-    
+
     return 1;
 }
 #endif /* PNG_APNG_SUPPORTED */
@@ -1149,7 +1156,7 @@ png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
 
 #ifdef PNG_MNG_FEATURES_SUPPORTED
 png_uint_32 PNGAPI
-png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
+png_permit_mng_features(png_structp png_ptr, png_uint_32 mng_features)
 {
    png_debug(1, "in png_permit_mng_features");
 
@@ -1263,7 +1270,7 @@ png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
 #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_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
@@ -1278,7 +1285,7 @@ png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
 
 /* This function was added to libpng 1.4.0 */
 void PNGAPI
-png_set_chunk_cache_max (png_structp png_ptr,
+png_set_chunk_cache_max(png_structp png_ptr,
    png_uint_32 user_chunk_cache_max)
 {
     if (png_ptr)
@@ -1287,7 +1294,7 @@ png_set_chunk_cache_max (png_structp png_ptr,
 
 /* This function was added to libpng 1.4.1 */
 void PNGAPI
-png_set_chunk_malloc_max (png_structp png_ptr,
+png_set_chunk_malloc_max(png_structp png_ptr,
    png_alloc_size_t user_chunk_malloc_max)
 {
     if (png_ptr)
diff --git a/modules/libimg/png/pngtrans.c b/modules/libimg/png/pngtrans.c
index f80679a19d18..05eb2d05a37e 100644
--- a/modules/libimg/png/pngtrans.c
+++ b/modules/libimg/png/pngtrans.c
@@ -1,8 +1,8 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * Last changed in libpng 1.4.2 [April 29, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [April 10, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -662,7 +662,7 @@ png_set_user_transform_info(png_structp png_ptr, png_voidp
  * are called.
  */
 png_voidp PNGAPI
-png_get_user_transform_ptr(png_structp png_ptr)
+png_get_user_transform_ptr(png_const_structp png_ptr)
 {
    if (png_ptr == NULL)
       return (NULL);
@@ -673,5 +673,5 @@ png_get_user_transform_ptr(png_structp png_ptr)
 #endif
 }
 #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
-	  PNG_WRITE_USER_TRANSFORM_SUPPORTED */
+          PNG_WRITE_USER_TRANSFORM_SUPPORTED */
 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/modules/libimg/png/pngwrite.c b/modules/libimg/png/pngwrite.c
index 00dc2a904c83..f38132a51f63 100644
--- a/modules/libimg/png/pngwrite.c
+++ b/modules/libimg/png/pngwrite.c
@@ -1,8 +1,8 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * Last changed in libpng 1.4.0 [January 3, 2010]
- * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.6 [March 8, 2011]
+ * Copyright (c) 1998-2011 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.)
  *
@@ -669,8 +669,8 @@ png_write_row(png_structp png_ptr, png_bytep row)
    if (png_ptr == NULL)
       return;
 
-   png_debug2(1, "in png_write_row (row %ld, pass %d)",
-      png_ptr->row_number, png_ptr->pass);
+   png_debug2(1, "in png_write_row (row %lu, pass %d)",
+      (unsigned long)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)
@@ -786,7 +786,8 @@ png_write_row(png_structp png_ptr, png_bytep row)
       png_ptr->row_info.width);
 
    png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type);
-   png_debug1(3, "row_info->width = %lu", png_ptr->row_info.width);
+   png_debug1(3, "row_info->width = %lu",
+      (unsigned long)png_ptr->row_info.width);
    png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels);
    png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth);
    png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth);
@@ -1458,33 +1459,33 @@ png_write_png(png_structp png_ptr, png_infop info_ptr,
    /* It is REQUIRED to call this to finish writing the rest of the file */
    png_write_end(png_ptr, info_ptr);
 
-   transforms = transforms; /* Quiet compiler warnings */
-   params = params;
+   PNG_UNUSED(transforms)   /* Quiet compiler warnings */
+   PNG_UNUSED(params)
 }
 #endif
 
 #if defined(PNG_WRITE_APNG_SUPPORTED)
 void PNGAPI
 png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
-    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height, 
-    png_uint_32 x_offset, png_uint_32 y_offset, 
+    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
+    png_uint_32 x_offset, png_uint_32 y_offset,
     png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
     png_byte blend_op)
 {
     png_debug(1, "in png_write_frame_head");
-    
+
     /* there is a chance this has been set after png_write_info was called,
     * so it would be set but not written. is there a way to be sure? */
     if (!(info_ptr->valid & PNG_INFO_acTL))
         png_error(png_ptr, "png_write_frame_head(): acTL not set");
-    
+
     png_write_reset(png_ptr);
-    
+
     png_write_reinit(png_ptr, info_ptr, width, height);
-    
-    if ( !(png_ptr->num_frames_written == 0 && 
+
+    if ( !(png_ptr->num_frames_written == 0 &&
            (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
-        png_write_fcTL(png_ptr, width, height, x_offset, y_offset, 
+        png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
                        delay_num, delay_den, dispose_op, blend_op);
 }
 
@@ -1492,9 +1493,8 @@ void PNGAPI
 png_write_frame_tail(png_structp png_ptr, png_infop png_info)
 {
     png_debug(1, "in png_write_frame_tail");
-    
+
     png_ptr->num_frames_written++;
 }
 #endif /* PNG_WRITE_APNG_SUPPORTED */
-
 #endif /* PNG_WRITE_SUPPORTED */
diff --git a/modules/libimg/png/pngwtran.c b/modules/libimg/png/pngwtran.c
index 070caa544de1..2925a9337722 100644
--- a/modules/libimg/png/pngwtran.c
+++ b/modules/libimg/png/pngwtran.c
@@ -195,6 +195,9 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
                *dp = (png_byte)v;
             break;
          }
+
+         default:
+            break;
       }
       row_info->bit_depth = (png_byte)bit_depth;
       row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
diff --git a/modules/libimg/png/pngwutil.c b/modules/libimg/png/pngwutil.c
index 0e6fad915252..69598735cbcb 100644
--- a/modules/libimg/png/pngwutil.c
+++ b/modules/libimg/png/pngwutil.c
@@ -246,10 +246,12 @@ png_text_compress(png_structp png_ptr,
     */
 
    /* Set up the compression buffers */
+   /* TODO: the following cast hides a potential overflow problem. */
    png_ptr->zstream.avail_in = (uInt)text_len;
+   /* NOTE: assume zlib doesn't overwrite the input */
    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;
+   png_ptr->zstream.avail_out = png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = png_ptr->zbuf;
 
    /* This is the same compression loop as in png_write_row() */
    do
@@ -688,11 +690,29 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
          if (length >= 2 &&
              png_ptr->height < 16384 && png_ptr->width < 16384)
          {
+            unsigned int z_cinfo;
+            unsigned int half_z_window_size;
+
+            /* Compute the maximum possible length of the datastream */
+
+            /* Number of pixels, plus for each row a filter byte and possible
+             * and possibly a padding byte, so increase the maximum
+             * size to account for these.
+             */
             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);
+
+            /* If it's interlaced, each block of 8 rows is sent as up to
+             * 14 rows, i.e., 6 additional rows, each with a filter byte
+             * and possibly a padding byte
+             */
+            if (png_ptr->interlaced)
+               uncompressed_idat_size += ((png_ptr->height + 7)/8) *
+                   (png_ptr->bit_depth < 8 ? 12 : 6);
+
+            z_cinfo = z_cmf >> 4;
+            half_z_window_size = 1 << (z_cinfo + 7);
             while (uncompressed_idat_size <= half_z_window_size &&
                    half_z_window_size >= 256)
             {
@@ -721,16 +741,16 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
    else
    {
       png_byte buf[4];
-      
+
       png_write_chunk_start(png_ptr, (png_bytep)png_fdAT, 4 + length);
-      
+
       png_save_uint_32(buf, png_ptr->next_seq_num);
       png_write_chunk_data(png_ptr, buf, 4);
-      
+
       png_write_chunk_data(png_ptr, data, length);
-      
+
       png_write_chunk_end(png_ptr);
-      
+
       png_ptr->next_seq_num++;
    }
 #endif
@@ -1748,43 +1768,43 @@ png_write_acTL(png_structp png_ptr,
 {
     PNG_acTL;
     png_byte data[16];
-    
+
     png_debug(1, "in png_write_acTL");
-    
+
     png_ptr->num_frames_to_write = num_frames;
-    
+
     if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
         num_frames--;
-    
+
     png_save_uint_32(data, num_frames);
     png_save_uint_32(data + 4, num_plays);
-    
+
     png_write_chunk(png_ptr, (png_bytep)png_acTL, data, (png_size_t)8);
 }
 
 void /* PRIVATE */
-png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height, 
+png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
     png_uint_32 x_offset, png_uint_32 y_offset,
-    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, 
+    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
     png_byte blend_op)
 {
     PNG_fcTL;
     png_byte data[26];
-    
+
     png_debug(1, "in png_write_fcTL");
-    
+
     if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
         png_error(png_ptr, "x and/or y offset for the first frame aren't 0");
-    if (png_ptr->num_frames_written == 0 && 
-        (width != png_ptr->first_frame_width || 
+    if (png_ptr->num_frames_written == 0 &&
+        (width != png_ptr->first_frame_width ||
          height != png_ptr->first_frame_height))
         png_error(png_ptr, "width and/or height in the first frame's fcTL "
                            "don't match the ones in IHDR");
-    
+
     /* more error checking */
-    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, 
+    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
                              delay_num, delay_den, dispose_op, blend_op);
-    
+
     png_save_uint_32(data, png_ptr->next_seq_num);
     png_save_uint_32(data + 4, width);
     png_save_uint_32(data + 8, height);
@@ -1794,9 +1814,9 @@ png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
     png_save_uint_16(data + 22, delay_den);
     data[24] = dispose_op;
     data[25] = blend_op;
-    
+
     png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)26);
-    
+
     png_ptr->next_seq_num++;
 }
 #endif /* PNG_WRITE_APNG_SUPPORTED */
@@ -2883,24 +2903,24 @@ png_write_reset(png_structp png_ptr)
 }
 
 void /* PRIVATE */
-png_write_reinit(png_structp png_ptr, png_infop info_ptr, 
+png_write_reinit(png_structp png_ptr, png_infop info_ptr,
                  png_uint_32 width, png_uint_32 height)
 {
-    if (png_ptr->num_frames_written == 0 && 
-        (width != png_ptr->first_frame_width || 
+    if (png_ptr->num_frames_written == 0 &&
+        (width != png_ptr->first_frame_width ||
          height != png_ptr->first_frame_height))
         png_error(png_ptr, "width and/or height in the first frame's fcTL "
                            "don't match the ones in IHDR");
-    if (width > png_ptr->first_frame_width || 
+    if (width > png_ptr->first_frame_width ||
         height > png_ptr->first_frame_height)
         png_error(png_ptr, "width and/or height for a frame greater than"
                            "the ones in IHDR");
-    
-    png_set_IHDR(png_ptr, info_ptr, width, height, 
-                 info_ptr->bit_depth, info_ptr->color_type, 
+
+    png_set_IHDR(png_ptr, info_ptr, width, height,
+                 info_ptr->bit_depth, info_ptr->color_type,
                  info_ptr->interlace_type, info_ptr->compression_type,
                  info_ptr->filter_type);
-   
+
     png_ptr->width = width;
     png_ptr->height = height;
     png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
diff --git a/modules/plugin/base/src/nsNPAPIPlugin.cpp b/modules/plugin/base/src/nsNPAPIPlugin.cpp
index 3ddb0e21bb3f..7ee47d0d5ee1 100644
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -329,6 +329,7 @@ nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
   // Blacklist Flash 10.0 or lower since it may try to negotiate Carbon/Quickdraw
   // which are not supported out of process. Also blacklist Flash 10.1 if this
   // machine has an Intel GMA9XX GPU because Flash will negotiate Quickdraw graphics.
+  // Never blacklist Flash >= 10.2.
   if (aPluginTag->mFileName.EqualsIgnoreCase("flash player.plugin")) {
     // If the first '.' is before position 2 or the version 
     // starts with 10.0 then we are dealing with Flash 10 or less.
@@ -341,12 +342,9 @@ nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
       if (versionPrefix.EqualsASCII("10.0")) {
         return PR_FALSE;
       }
-    }
-
-    // At this point we have Flash 10.1+ but now we also need to blacklist
-    // if the machine has a Intel GMA9XX GPU.
-    if (GMA9XXGraphics()) {
-      return PR_FALSE;
+      if (versionPrefix.EqualsASCII("10.1") && GMA9XXGraphics()) {
+        return PR_FALSE;
+      }
     }
   }
 #endif
diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp
index fdfc9d77daa1..c8b81c490e3c 100644
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -625,8 +625,6 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
                             aBuilder->GetNodeInfoManager(),
                             nsnull,
                             name,
-                            nsnull,
-                            nsnull,
                             publicId,
                             systemId,
                             voidString);
diff --git a/testing/mochitest/chrome/Makefile.in b/testing/mochitest/chrome/Makefile.in
index 4e7fad935572..c6b73a5c0b1e 100644
--- a/testing/mochitest/chrome/Makefile.in
+++ b/testing/mochitest/chrome/Makefile.in
@@ -45,6 +45,8 @@ include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _STATIC_FILES = test_sample.xul \
+		test_synthesizeDragStart.xul \
+		test_synthesizeDrop.xul \
 		$(NULL)
 
 libs:: $(_STATIC_FILES)
diff --git a/testing/mochitest/tests/SimpleTest/tests/test_synthesizeDragStart.xul b/testing/mochitest/chrome/test_synthesizeDragStart.xul
similarity index 100%
rename from testing/mochitest/tests/SimpleTest/tests/test_synthesizeDragStart.xul
rename to testing/mochitest/chrome/test_synthesizeDragStart.xul
diff --git a/testing/mochitest/tests/SimpleTest/tests/test_synthesizeDrop.xul b/testing/mochitest/chrome/test_synthesizeDrop.xul
similarity index 95%
rename from testing/mochitest/tests/SimpleTest/tests/test_synthesizeDrop.xul
rename to testing/mochitest/chrome/test_synthesizeDrop.xul
index d4b24bc4d675..0ffe88223e79 100644
--- a/testing/mochitest/tests/SimpleTest/tests/test_synthesizeDrop.xul
+++ b/testing/mochitest/chrome/test_synthesizeDrop.xul
@@ -41,8 +41,6 @@
  * Assure EventUtils can perform synthesizeDrop as specified
  */
 
-_tests\testing\mochitest\chrome\testing\mochitest\tests\SimpleTest\tests\test_synthesizeDrop.xul
-
 -->
 
+ *  Jonathan Protzenko 
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -44,6 +45,11 @@
 
 function run_test() {
   do_check_true(typeof(this['MODULE_IMPORTED']) == "undefined");
-  Components.utils.import("resource://test/import_module.jsm");
+  do_check_true(typeof(this['MODULE_URI']) == "undefined");
+  let uri = "resource://test/import_module.jsm";
+  Components.utils.import(uri);
+  do_check_true(MODULE_URI == uri);
   do_check_true(MODULE_IMPORTED);
+  do_check_true(SUBMODULE_IMPORTED);
+  do_check_true(same_scope);
 }
diff --git a/toolkit/content/tests/chrome/window_largemenu.xul b/toolkit/content/tests/chrome/window_largemenu.xul
index 49b975d6c05d..2cf5612e5889 100644
--- a/toolkit/content/tests/chrome/window_largemenu.xul
+++ b/toolkit/content/tests/chrome/window_largemenu.xul
@@ -264,7 +264,8 @@ function nextContextMenuTest(desiredHeight)
 function testPopupMovement()
 {
   var button = document.getElementById("label");
-  var popup = document.getElementById((gTests[gTestIndex] == "panel movement") ? "panel" : "popup");
+  var isPanelTest = (gTests[gTestIndex] == "panel movement");
+  var popup = document.getElementById(isPanelTest ? "panel" : "popup");
 
   var screenX, screenY, buttonScreenX, buttonScreenY;
   var rect = popup.getBoundingClientRect();
@@ -273,21 +274,36 @@ function testPopupMovement()
   popup.moveTo(1, 1);
   [screenX, screenY] = getScreenXY(popup);
 
-  var expectedx = overlapOSChrome ? 1 : (screen.availLeft < 1 ? 1 : screen.availLeft);
-  var expectedy = overlapOSChrome ? 1 : (screen.availTop < 1 ? 1 : screen.availTop);
+  var expectedx = 1, expectedy = 1;
+  if (!isPanelTest && !overlapOSChrome) {
+    if (screen.availLeft >= 1) expectedx = screen.availLeft;
+    if (screen.availTop >= 1) expectedy = screen.availTop;
+  }
   is(screenX, expectedx, gTests[gTestIndex] + " (1, 1) x");
   is(screenY, expectedy, gTests[gTestIndex] + " (1, 1) y");
 
   popup.moveTo(100, 8000);
-  var expectedy = (overlapOSChrome ? screen.height + screen.top : screen.availHeight + screen.availTop) -
-                  Math.round(rect.height) - 3;
+  if (isPanelTest) {
+    expectedy = 8000;
+  }
+  else {
+    expectedy = (overlapOSChrome ? screen.height + screen.top : screen.availHeight + screen.availTop) -
+                Math.round(rect.height) - 3;
+  }
+
   [screenX, screenY] = getScreenXY(popup);
   is(screenX, 100, gTests[gTestIndex] + " (100, 8000) x");
   is(screenY, expectedy, gTests[gTestIndex] + " (100, 8000) y");
 
   popup.moveTo(6000, 100);
-  expectedx = (overlapOSChrome ? screen.width + screen.left : screen.availWidth + screen.availLeft) -
-              Math.round(rect.width) - 3;
+
+  if (isPanelTest) {
+    expectedx = 6000;
+  }
+  else {
+    expectedx = (overlapOSChrome ? screen.width + screen.left : screen.availWidth + screen.availLeft) -
+                Math.round(rect.width) - 3;
+  }
 
   [screenX, screenY] = getScreenXY(popup);
   is(screenX, expectedx, gTests[gTestIndex] + " (6000, 100) x");
diff --git a/toolkit/content/tests/widgets/test_datepicker.xul b/toolkit/content/tests/widgets/test_datepicker.xul
index a336e5fa1624..3f52f9ad022b 100644
--- a/toolkit/content/tests/widgets/test_datepicker.xul
+++ b/toolkit/content/tests/widgets/test_datepicker.xul
@@ -133,6 +133,22 @@ function testtag_datepicker(dp, type, testid)
   setDateField("value", "2000-a-19", true, 2002, 6, 15);
   setDateField("dateValue", "none", true, 2002, 6, 15);
 
+  // grid and popup types can display a different month than the current one
+  var isGridOrPopup = (type == "grid" || type == "popup");
+  dp.displayedMonth = 3;
+  testtag_comparedate(dp, testid + "set displayedMonth",
+                      2002, isGridOrPopup ? 6 : 3, 15, 3);
+
+  dp.displayedYear = 2009;
+  testtag_comparedate(dp, testid + "set displayedYear",
+                      isGridOrPopup ? 2002 : 2009, isGridOrPopup ? 6 : 3, 15, 3, 2009);
+
+  if (isGridOrPopup) {
+    dp.value = "2008-02-29";
+    dp.displayedYear = 2009;
+    is(dp.displayedMonth, 1, "set displayedYear during leap year");
+  }
+
   is(dp.open, false, testid + "open false");
   if (type != "popup") {
     dp.open = true;
@@ -241,7 +257,56 @@ function testtag_datepicker_UI_grid(dp, type, testid)
   synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up");
   is(dp.value, "2003-02-15", testid + "key page up");
 
+  // check handling at the start and end of the month
+  dp.value = "2010-10-01";
+  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-10-01");
+  is(dp.displayedMonth, 8, testid + "key page up 2010-10-01 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page up 2010-10-01 displayedYear");
+
+  dp.value = "2010-10-01";
+  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-10-01");
+  is(dp.displayedMonth, 10, testid + "key page down 2010-10-01 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page down 2010-10-01 displayedYear");
+
+  dp.value = "2010-10-31";
+  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-10-31");
+  is(dp.displayedMonth, 8, testid + "key page up 2010-10-31 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page up 2010-10-01 displayedYear");
+  dp.value = "2010-10-31";
+  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-10-31");
+  is(dp.displayedMonth, 10, testid + "key page down 2010-10-31 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page up 2010-10-31 displayedYear");
+
+  // check handling at the end of february
+  dp.value = "2010-03-31";
+  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-03-31");
+  is(dp.displayedMonth, 1, testid + "key page up 2010-03-31 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page up 2010-03-31 displayedYear");
+  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-02-28");
+  is(dp.displayedMonth, 0, testid + "key page up 2010-02-28 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page up 2010-02-28 displayedYear");
+
+  dp.value = "2010-01-31";
+  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-01-31");
+  is(dp.displayedMonth, 1, testid + "key page down 2010-01-31 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page up 2010-01-31 displayedYear");
+  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-02-28");
+  is(dp.displayedMonth, 2, testid + "key page down 2010-02-28 displayedMonth");
+  is(dp.displayedYear, 2010, testid + "key page up 2010-02-28 displayedYear");
+
+  // check handling at the end of february during a leap year
+  dp.value = "2008-01-31";
+  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2008-01-31");
+  is(dp.displayedMonth, 1, testid + "key page down 2008-01-31 displayedMonth");
+  is(dp.displayedYear, 2008, testid + "key page up 2008-01-31 displayedYear");
+  dp.value = "2008-03-31";
+  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2008-03-31");
+  is(dp.displayedMonth, 1, testid + "key page up 2008-03-31 displayedMonth");
+  is(dp.displayedYear, 2008, testid + "key page up 2008-03-31 displayedYear");
+
   // the value of a read only datepicker cannot be changed
+  dp.value = "2003-02-15";
+
   dp.readOnly = true;
   synthesizeKeyExpectEvent("VK_LEFT", { }, ktarget, "!change", testid + "key left read only");
   is(dp.value, "2003-02-15", testid + "key left read only");
@@ -314,7 +379,7 @@ function testtag_getdatestring(year, month, date)
   return year + "-" + month + "-" + date;
 }
 
-function testtag_comparedate(dp, testid, year, month, date)
+function testtag_comparedate(dp, testid, year, month, date, displayedMonth, displayedYear)
 {
   is(dp.value, testtag_getdatestring(year, month, date), testid + " value");
   if (testid.indexOf("initial") == -1)
@@ -330,6 +395,8 @@ function testtag_comparedate(dp, testid, year, month, date)
 
   is(dp.year, year, testid + " year");
   is(dp.month, month, testid + " month");
+  is(dp.displayedMonth, displayedMonth ? displayedMonth : month, testid + " displayedMonth");
+  is(dp.displayedYear, displayedYear ? displayedYear : year, testid + " displayedYear");
   is(dp.date, date, testid + " date");
 }
 
diff --git a/toolkit/content/tests/widgets/test_menulist_keynav.xul b/toolkit/content/tests/widgets/test_menulist_keynav.xul
index 8bef77c5df08..404c6c29ca77 100644
--- a/toolkit/content/tests/widgets/test_menulist_keynav.xul
+++ b/toolkit/content/tests/widgets/test_menulist_keynav.xul
@@ -27,6 +27,7 @@
 SimpleTest.waitForExplicitFinish();
 
 var gShowPopup = false;
+var gModifiers = 0;
 
 var iswin = (navigator.platform.indexOf("Win") == 0);
 
@@ -112,7 +113,7 @@ function differentPressed()
 
   list.open = false;
 
-  SimpleTest.finish();
+  checkEnter();
 }
 
 function keyCheck(list, key, index, testname)
@@ -122,6 +123,50 @@ function keyCheck(list, key, index, testname)
   is(list.selectedItem, item, testname + " selectedItem");
 }
 
+function checkModifiers(event)
+{
+  var expectedModifiers = (gModifiers == 1);
+  is(event.shiftKey, expectedModifiers, "shift key pressed");
+  is(event.ctrlKey, expectedModifiers, "ctrl key pressed");
+  is(event.altKey, expectedModifiers, "alt key pressed");
+  is(event.metaKey, expectedModifiers, "meta key pressed");
+  gModifiers++;
+}
+
+function checkEnter()
+{
+  var list = $("list");
+  list.addEventListener("popuphidden", checkEnterWithModifiers, false);
+  list.addEventListener("command", checkModifiers, false);
+  list.open = true;
+  synthesizeKey("VK_ENTER", { });
+}
+
+function checkEnterWithModifiers()
+{
+  is(gModifiers, 1, "modifiers checked when not set");
+
+  var list = $("list");
+  ok(!list.open, "list closed on enter press");
+  list.removeEventListener("popuphidden", checkEnterWithModifiers, false);
+
+  list.addEventListener("popuphidden", done, false);
+  list.open = true;
+
+  synthesizeKey("VK_ENTER", { shiftKey: true, ctrlKey: true, altKey: true, metaKey: true });
+}
+
+function done()
+{
+  is(gModifiers, 2, "modifiers checked when set");
+
+  var list = $("list");
+  ok(!list.open, "list closed on enter press with modifiers");
+  list.removeEventListener("popuphidden", done, false);
+
+  SimpleTest.finish();
+}
+
 SimpleTest.waitForFocus(runTests);
 
 ]]>
diff --git a/toolkit/content/widgets/datetimepicker.xml b/toolkit/content/widgets/datetimepicker.xml
index 40ec91a815a7..532269abe93a 100644
--- a/toolkit/content/widgets/datetimepicker.xml
+++ b/toolkit/content/widgets/datetimepicker.xml
@@ -20,7 +20,7 @@
    - the Initial Developer. All Rights Reserved.
    -
    - Contributor(s):
-   -   Neil Deakin  (Original Author)
+   -   Neil Deakin  (Original Author)
    -
    - Alternatively, the contents of this file may be used under the terms of
    - either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -645,6 +645,11 @@
       
       
 
+      
+      
+
       
         
         
@@ -989,6 +994,25 @@
         
       
 
+      
+        
+          return this._displayedDate.getMonth();
+        
+        
+          this._updateUI(this.monthField, val, true);
+          return val;
+        
+      
+      
+        
+          return this._displayedDate.getFullYear();
+        
+        
+          this._updateUI(this.yearField, val, true);
+          return val;
+        
+      
+
       
         
           
         
         
-        
+        
         
           
         
       
+      
+        
+          return document.getAnonymousElementByAttribute(this, "anonid", "grid").displayedMonth;
+        
+        
+          document.getAnonymousElementByAttribute(this, "anonid", "grid").displayedMonth = val;
+          return val;
+        
+      
+      
+        
+          return document.getAnonymousElementByAttribute(this, "anonid", "grid").displayedYear;
+        
+        
+          document.getAnonymousElementByAttribute(this, "anonid", "grid").displayedYear = val;
+          return val;
+        
+      
     
   
 
diff --git a/toolkit/content/widgets/numberbox.xml b/toolkit/content/widgets/numberbox.xml
index 82c8e62079ef..fab66a345541 100644
--- a/toolkit/content/widgets/numberbox.xml
+++ b/toolkit/content/widgets/numberbox.xml
@@ -16,7 +16,7 @@
     
       
         
+                    xbl:inherits="onfocus,onblur,value,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
       
       
     
diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in
index aa4077caf23b..072f69dfa9c5 100644
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -253,6 +253,11 @@ ifdef MOZ_ENABLE_LIBXUL
 include $(srcdir)/libxul-rules.mk
 endif
 
+ifeq ($(OS_ARCH),OpenBSD)
+# Needed by nsAuthGSSAPI
+EXTRA_DSO_LDOPTS += -lkrb5 -lcrypto
+endif
+
 ifdef MOZ_JAVAXPCOM
 dlldeps-javaxpcom.cpp: $(topsrcdir)/extensions/java/xpcom/src/dlldeps-javaxpcom.cpp
 	$(INSTALL) $^ .
diff --git a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
index a024daedad46..723e2f8c2f84 100644
--- a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
@@ -1,5 +1,3 @@
-# LOCALIZATION NOTE: Do not translate  
-
 restartTitle=Close %S
 restartMessageNoUnlocker=%S is already running, but is not responding. To open a new window, you must first close the existing %S process, or restart your system.
 restartMessageUnlocker=%S is already running, but is not responding. The old %S process must be closed to open a new window.
diff --git a/toolkit/mozapps/update/test/Makefile.in b/toolkit/mozapps/update/test/Makefile.in
index 8e8258b0a9bd..c44325d56f68 100644
--- a/toolkit/mozapps/update/test/Makefile.in
+++ b/toolkit/mozapps/update/test/Makefile.in
@@ -113,6 +113,8 @@ libs:: unit/head_update.js.in
 	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) $^ > $(TESTROOT)/unit/head_update.js
 
 ifndef ANDROID
+ifndef MOZ_PROFILE_GENERATE
 libs::
 	$(INSTALL) TestAUSHelper$(BIN_SUFFIX) $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit
+endif
 endif # ANDROID
diff --git a/toolkit/mozapps/update/updater/progressui_win.cpp b/toolkit/mozapps/update/updater/progressui_win.cpp
index 84af536258de..d8a73a03930f 100644
--- a/toolkit/mozapps/update/updater/progressui_win.cpp
+++ b/toolkit/mozapps/update/updater/progressui_win.cpp
@@ -204,6 +204,8 @@ InitDialog(HWND hDlg)
 
   ReleaseDC(hWndInfo, hDCInfo);
 
+  CenterDialog(hDlg);  // make dialog appear in the center of the screen
+
   SetTimer(hDlg, TIMER_ID, TIMER_INTERVAL, NULL);
 }
 
diff --git a/toolkit/system/gnome/nsGIOService.cpp b/toolkit/system/gnome/nsGIOService.cpp
index de1cf9c5ded4..675ae397c1b3 100644
--- a/toolkit/system/gnome/nsGIOService.cpp
+++ b/toolkit/system/gnome/nsGIOService.cpp
@@ -106,15 +106,15 @@ nsGIOMimeApp::GetCommand(nsACString& aCommand)
 {
   get_commandline_t g_app_info_get_commandline_ptr;
 
-  void *libHandle = dlopen("libgio-2.0.so", RTLD_LAZY);
+  void *libHandle = dlopen("libgio-2.0.so.0", RTLD_LAZY);
   if (!libHandle) {
     return NS_ERROR_FAILURE;
   }
   dlerror(); /* clear any existing error */
   g_app_info_get_commandline_ptr =
     (get_commandline_t) dlsym(libHandle, "g_app_info_get_commandline");
-  if (dlerror() != NULL) {
-    const char cmd = *g_app_info_get_commandline_ptr(mApp);
+  if (dlerror() == NULL) {
+    const char *cmd = g_app_info_get_commandline_ptr(mApp);
     if (!cmd) {
       dlclose(libHandle);
       return NS_ERROR_FAILURE;
@@ -282,6 +282,33 @@ nsGIOMimeApp::SetAsDefaultForFileExtensions(nsACString const& fileExts)
   return NS_OK;
 }
 
+/**
+ * Set default application for URI's of a particular scheme
+ * @param aURIScheme string containing the URI scheme
+ * @return NS_OK when application was set as default for URI scheme,
+ * NS_ERROR_FAILURE otherwise
+ */
+NS_IMETHODIMP
+nsGIOMimeApp::SetAsDefaultForURIScheme(nsACString const& aURIScheme)
+{
+  GError *error = NULL;
+  nsCAutoString contentType("x-scheme-handler/");
+  contentType.Append(aURIScheme);
+
+  g_app_info_set_as_default_for_type(mApp,
+                                     contentType.get(),
+                                     &error);
+  if (error) {
+    g_warning("Cannot set application as default for URI scheme (%s): %s",
+              PromiseFlatCString(aURIScheme).get(),
+              error->message);
+    g_error_free(error);
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
 nsresult
 nsGIOService::Init()
 {
@@ -321,6 +348,23 @@ nsGIOService::GetMimeTypeFromExtension(const nsACString& aExtension,
 }
 // used in nsGNOMERegistry
 // -----------------------------------------------------------------------------
+NS_IMETHODIMP
+nsGIOService::GetAppForURIScheme(const nsACString& aURIScheme,
+                                 nsIGIOMimeApp** aApp)
+{
+  *aApp = nsnull;
+
+  GAppInfo *app_info = g_app_info_get_default_for_uri_scheme(
+                          PromiseFlatCString(aURIScheme).get());
+  if (app_info) {
+    nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info);
+    NS_ADDREF(*aApp = mozApp);
+  } else {
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsGIOService::GetAppForMimeType(const nsACString& aMimeType,
                                 nsIGIOMimeApp**   aApp)
@@ -419,50 +463,23 @@ nsGIOService::CreateAppFromCommand(nsACString const& cmd,
   GAppInfo *app_info = NULL, *app_info_from_list = NULL;
   GList *apps = g_app_info_get_all();
   GList *apps_p = apps;
-  get_commandline_t g_app_info_get_commandline_ptr;
-
-  void *libHandle = dlopen("libgio-2.0.so", RTLD_LAZY);
-  if (!libHandle) {
-    return NS_ERROR_FAILURE;
-  }
-  dlerror(); /* clear any existing error */
-  g_app_info_get_commandline_ptr =
-    (get_commandline_t) dlsym(libHandle, "g_app_info_get_commandline");
-  if (dlerror() != NULL) {
-    g_app_info_get_commandline_ptr = NULL;
-  }
 
   // Try to find relevant and existing GAppInfo in all installed application
+  // We do this by comparing each GAppInfo's executable with out own
   while (apps_p) {
     app_info_from_list = (GAppInfo*) apps_p->data;
-    /* This is  a silly test. It just compares app names but not
-     * commands. This is due to old version of Glib/Gio. The required
-     * function which allows to do a regular check of existence of desktop file
-     * is possible by using function g_app_info_get_commandline. This function
-     * has been introduced in Glib 2.20. */
-    if (app_info_from_list && strcmp(g_app_info_get_name(app_info_from_list),
-                                     PromiseFlatCString(appName).get()) == 0 )
-    {
-      if (g_app_info_get_commandline_ptr)
-      {
-        /* Following test is only possible with Glib >= 2.20.
-         * Compare path only by using strncmp */
-        if (strncmp(g_app_info_get_commandline_ptr(app_info_from_list),
-                    PromiseFlatCString(cmd).get(),
-                    strlen(PromiseFlatCString(cmd).get())) == 0)
-        {
-          app_info = app_info_from_list;
-          break;
-        } else {
-          g_object_unref(app_info_from_list);
-        }
-      } else {
+    if (!app_info) {
+      // If the executable is not absolute, get it's full path
+      char *executable = g_find_program_in_path(g_app_info_get_executable(app_info_from_list));
+
+      if (executable && strcmp(executable, PromiseFlatCString(cmd).get()) == 0) {
+        g_object_ref (app_info_from_list);
         app_info = app_info_from_list;
-        break;
       }
-    } else {
-      g_object_unref(app_info_from_list);
+      g_free(executable);
     }
+
+    g_object_unref(app_info_from_list);
     apps_p = apps_p->next;
   }
   g_list_free(apps);
@@ -477,12 +494,10 @@ nsGIOService::CreateAppFromCommand(nsACString const& cmd,
   if (!app_info) {
     g_warning("Cannot create application info from command: %s", error->message);
     g_error_free(error);
-    dlclose(libHandle);
     return NS_ERROR_FAILURE;
   }
   nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info);
   NS_ENSURE_TRUE(mozApp, NS_ERROR_OUT_OF_MEMORY);
   NS_ADDREF(*appInfo = mozApp);
-  dlclose(libHandle);
   return NS_OK;
 }
diff --git a/tools/trace-malloc/Makefile.in b/tools/trace-malloc/Makefile.in
index b678ea1d2d72..ac50f705cd97 100644
--- a/tools/trace-malloc/Makefile.in
+++ b/tools/trace-malloc/Makefile.in
@@ -68,7 +68,9 @@ CSRCS            = \
 		formdata.c \
 		$(NULL)
 
+ifndef MOZ_PROFILE_GENERATE
 PROGRAM		= spacetrace$(BIN_SUFFIX)
+endif
 
 ifeq ($(OS_ARCH),WINNT)
 LOCAL_INCLUDES	+= -I$(topsrcdir)/config/os2
diff --git a/uriloader/exthandler/tests/Makefile.in b/uriloader/exthandler/tests/Makefile.in
index afb95935fe80..0ef170614e61 100644
--- a/uriloader/exthandler/tests/Makefile.in
+++ b/uriloader/exthandler/tests/Makefile.in
@@ -75,5 +75,7 @@ export PERSONAL_MAILCAP=$(shell cd $(srcdir) && pwd)/mailcap
 endif
 
 # need the executable for running the xpcshell unit tests
+ifneq (,$(SIMPLE_PROGRAMS))
 libs::
 	$(INSTALL) $(SIMPLE_PROGRAMS) $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit
+endif
diff --git a/widget/src/windows/LSPAnnotator.cpp b/widget/src/windows/LSPAnnotator.cpp
index ba55088cee17..a4f1bdf9a347 100644
--- a/widget/src/windows/LSPAnnotator.cpp
+++ b/widget/src/windows/LSPAnnotator.cpp
@@ -74,8 +74,6 @@ LSPAnnotationGatherer::Annotate()
   PRBool enabled;
   if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) {
     cr->AnnotateCrashReport(NS_LITERAL_CSTRING("Winsock_LSP"), mString);
-    nsCString note = NS_LITERAL_CSTRING("Winsock LSPs: ");
-    note.Append(mString);
   }
   mThread->Shutdown();
 }
diff --git a/xpcom/system/nsIGIOService.idl b/xpcom/system/nsIGIOService.idl
index b0489a660182..b5b320519d56 100644
--- a/xpcom/system/nsIGIOService.idl
+++ b/xpcom/system/nsIGIOService.idl
@@ -46,7 +46,7 @@ interface nsIURI;
    with nsIGIOService::GetAppForMimeType. */
 // 66009894-9877-405b-9321-bf30420e34e6 prev uuid
 
-[scriptable, uuid(e77021b4-4012-407d-b686-7a1f18050109)] 
+[scriptable, uuid(ca6bad0c-8a48-48ac-82c7-27bb8f510fbe)] 
 interface nsIGIOMimeApp : nsISupports
 {
   const long EXPECTS_URIS  = 0;
@@ -62,6 +62,7 @@ interface nsIGIOMimeApp : nsISupports
   void launch(in AUTF8String uri);
   void setAsDefaultForMimeType(in AUTF8String mimeType);
   void setAsDefaultForFileExtensions(in AUTF8String extensions);
+  void setAsDefaultForURIScheme(in AUTF8String uriScheme);
 };
 
 /*
@@ -77,7 +78,7 @@ interface nsIGIOMimeApp : nsISupports
  */
 
 // prev id dea20bf0-4e4d-48c5-b932-dc3e116dc64b
-[scriptable, uuid(47e372c2-78bb-4899-8114-56aa7d9cdac5)]
+[scriptable, uuid(eda22a30-84e1-4e16-9ca0-cd1553c2b34a)]
 interface nsIGIOService : nsISupports
 {
 
@@ -87,6 +88,9 @@ interface nsIGIOService : nsISupports
      should not include a leading dot. */
   AUTF8String        getMimeTypeFromExtension(in AUTF8String extension);
 
+  /* Obtain the preferred application for opening a given URI scheme */
+  nsIGIOMimeApp      getAppForURIScheme(in AUTF8String aURIScheme);
+
   /* Obtain the preferred application for opening a given MIME type */
   nsIGIOMimeApp      getAppForMimeType(in AUTF8String mimeType);
 
diff --git a/xpcom/tests/Makefile.in b/xpcom/tests/Makefile.in
index bb031c9627b3..74f8f2ef5ec2 100644
--- a/xpcom/tests/Makefile.in
+++ b/xpcom/tests/Makefile.in
@@ -172,7 +172,9 @@ LOCAL_INCLUDES	= \
 
 libs::
 	$(INSTALL) $(srcdir)/test.properties $(DIST)/bin/res
+ifneq (,$(SIMPLE_PROGRAMS))
 	$(INSTALL) $(SIMPLE_PROGRAMS) $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit
+endif
 
 # Copy TestHarness.h into its own module, for ease of setting up includes
 # correctly.
diff --git a/xpcom/tests/windows/Makefile.in b/xpcom/tests/windows/Makefile.in
index 0816d46263e3..86f5dc43f851 100644
--- a/xpcom/tests/windows/Makefile.in
+++ b/xpcom/tests/windows/Makefile.in
@@ -44,9 +44,6 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE		= xpcom
 
-
-include $(topsrcdir)/config/config.mk
-
 CPP_UNIT_TESTS	= \
                   TestCOM.cpp \
                   $(NULL)
diff --git a/xpcom/threads/nsEventQueue.h b/xpcom/threads/nsEventQueue.h
index c919ac034f3f..1e231aae585f 100644
--- a/xpcom/threads/nsEventQueue.h
+++ b/xpcom/threads/nsEventQueue.h
@@ -96,7 +96,6 @@ private:
 
   // Page objects are linked together to form a simple deque.
 
-  struct Page; friend struct Page; // VC6!
   struct Page {
     struct Page *mNext;
     nsIRunnable *mEvents[EVENTS_PER_PAGE];
diff --git a/xpcom/typelib/xpt/tools/Makefile.in b/xpcom/typelib/xpt/tools/Makefile.in
index 21daa5c05d70..138197a5b7eb 100644
--- a/xpcom/typelib/xpt/tools/Makefile.in
+++ b/xpcom/typelib/xpt/tools/Makefile.in
@@ -45,64 +45,15 @@ include $(DEPTH)/config/autoconf.mk
 MODULE		= xpcom
 INTERNAL_TOOLS	= 1
 
-SIMPLE_PROGRAMS	= xpt_dump$(BIN_SUFFIX) xpt_link$(BIN_SUFFIX)
-
-CSRCS		= xpt_dump.c xpt_link.c
-
-SDK_BINARY     =                   \
-		$(SIMPLE_PROGRAMS) \
-		$(NULL)
-
-ifdef CROSS_COMPILE
-HOST_SIMPLE_PROGRAMS	= $(addprefix host_, $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=$(HOST_BIN_SUFFIX)))
-HOST_CSRCS		= $(CSRCS)
-endif
-
-LIBS		= $(DIST)/lib/$(LIB_PREFIX)xpt.$(LIB_SUFFIX)
-
-ifdef WRAP_MALLOC_CFLAGS
-LIBS		+= -lmozalloc
-endif
-
-USE_STATIC_LIBS = 1
+SDK_BINARY = \
+  xpt.py \
+  $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
-# Do not link to jemalloc
-ifeq ($(OS_ARCH),SunOS)
-SOLARIS_JEMALLOC_LDFLAGS =
-endif
-
-# Compile directly against the static lib, so we can use the tools
-# during the build without the shared library path being set.
-ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
-DEFINES		+= -DEXPORT_XPT_API
-endif
-
-ifdef CROSS_COMPILE
-HOST_LIBS		= $(DIST)/host/lib/$(LIB_PREFIX)hostxpt.$(LIB_SUFFIX)
-HOST_EXTRA_DEPS		= $(wildcard $(DIST)/host/lib/$(LIB_PREFIX)hostxpt.*)
-
-ifdef HOST_NSPR_MDCPUCFG
-HOST_CFLAGS	+= -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG)
-endif
-
-ifdef WINCE
-# Compile directly against the static lib, so we can use the tools
-# during the build without the shared library path being set.
-HOST_CFLAGS +=  -DEXPORT_XPT_API
-LDFLAGS += -NODEFAULTLIB:MSVCRT
-endif
-
-endif
-
-
-# Build xpt_link and xpt_dump early.  (libs creates .deps used by libs.)
+# Install xpt.py in SDK early
 export::
 	@$(MAKE) libs
 
-# XXX, bug 417045, make -jN combines badly with -save-temps in   
-# CFLAGS/CXXFLAGS (for stabs symbols with XCode3)
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-.NOTPARALLEL:
-endif
+check::
+	$(PYTHON) $(srcdir)/runtests.py
diff --git a/xpcom/typelib/xpt/tools/runtests.py b/xpcom/typelib/xpt/tools/runtests.py
new file mode 100755
index 000000000000..b4ac9b1742cc
--- /dev/null
+++ b/xpcom/typelib/xpt/tools/runtests.py
@@ -0,0 +1,750 @@
+#!/usr/bin/env python
+# Copyright 2010,2011 Mozilla Foundation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE MOZILLA FOUNDATION ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE MOZILLA FOUNDATION OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation
+# are those of the authors and should not be interpreted as representing
+# official policies, either expressed or implied, of the Mozilla
+# Foundation.
+
+import difflib
+import os
+from StringIO import StringIO
+import subprocess
+import sys
+import tempfile
+import unittest
+import xpt
+
+def get_output(bin, file):
+    p = subprocess.Popen([bin, file], stdout=subprocess.PIPE)
+    stdout, _ = p.communicate()
+    return stdout
+
+if "MOZILLA_OBJDIR" in os.environ:
+    class CheckXPTDump(unittest.TestCase):
+        def test_xpt_dump_diffs(self):
+            MOZILLA_OBJDIR = os.environ["MOZILLA_OBJDIR"]
+            xptdump = os.path.abspath(os.path.join(MOZILLA_OBJDIR,
+                                                   "dist", "bin", "xpt_dump"))
+            components = os.path.abspath(os.path.join(MOZILLA_OBJDIR,
+                                                   "dist", "bin", "components"))
+            for f in os.listdir(components):
+                if not f.endswith(".xpt"):
+                    continue
+                fullpath = os.path.join(components, f)
+                # read a Typelib and dump it to a string
+                t = xpt.Typelib.read(fullpath)
+                self.assert_(t is not None)
+                outf = StringIO()
+                t.dump(outf)
+                out = outf.getvalue()
+                # now run xpt_dump on it
+                out2 = get_output(xptdump, fullpath)
+                if out != out2:
+                    print "diff %s" % f
+                    for line in difflib.unified_diff(out2.split("\n"), out.split("\n"), lineterm=""):
+                        print line
+                self.assert_(out == out2, "xpt_dump output should be identical for %s" % f)
+
+class TestIIDString(unittest.TestCase):
+    def test_iid_str_roundtrip(self):
+        iid_str = "11223344-5566-7788-9900-aabbccddeeff"
+        iid = xpt.Typelib.string_to_iid(iid_str)
+        self.assertEqual(iid_str, xpt.Typelib.iid_to_string(iid))
+
+    def test_iid_roundtrip(self):
+        iid = "\x11\x22\x33\x44\x55\x66\x77\x88\x99\x00\xaa\xbb\xcc\xdd\xee\xff"
+        iid_str = xpt.Typelib.iid_to_string(iid)
+        self.assertEqual(iid, xpt.Typelib.string_to_iid(iid_str))
+
+class TypelibCompareMixin:
+    def assertEqualTypelibs(self, t1, t2):
+        self.assert_(t1 is not None, "Should not be None")
+        self.assert_(t2 is not None, "Should not be None")
+        self.assertEqual(t1.version, t2.version, "Versions should be equal")
+        self.assertEqual(len(t1.interfaces), len(t2.interfaces),
+                         "Number of interfaces should be equal")
+        for i, j in zip(t1.interfaces, t2.interfaces):
+            self.assertEqualInterfaces(i, j)
+
+    def assertEqualInterfaces(self, i1, i2):
+        self.assert_(i1 is not None, "Should not be None")
+        self.assert_(i2 is not None, "Should not be None")
+        self.assertEqual(i1.name, i2.name, "Names should be equal")
+        self.assertEqual(i1.iid, i2.iid, "IIDs should be equal")
+        self.assertEqual(i1.namespace, i2.namespace,
+                         "Namespaces should be equal")
+        self.assertEqual(i1.resolved, i2.resolved,
+                         "Resolved status should be equal")
+        if i1.resolved:
+            if i1.parent or i2.parent:
+                # Can't test exact equality, probably different objects
+                self.assertEqualInterfaces(i1.parent, i2.parent)
+            self.assertEqual(len(i1.methods), len(i2.methods))
+            for m, n in zip(i1.methods, i2.methods):
+                self.assertEqualMethods(m, n)
+            self.assertEqual(len(i1.constants), len(i2.constants))
+            for c, d in zip(i1.constants, i2.constants):
+                self.assertEqualConstants(c, d)
+            self.assertEqual(i1.scriptable, i2.scriptable,
+                             "Scriptable status should be equal")
+            self.assertEqual(i1.function, i2.function,
+                             "Function status should be equal")
+
+    def assertEqualMethods(self, m1, m2):
+        self.assert_(m1 is not None, "Should not be None")
+        self.assert_(m2 is not None, "Should not be None")
+        self.assertEqual(m1.name, m2.name, "Names should be equal")
+        self.assertEqual(m1.getter, m2.getter, "Getter flag should be equal")
+        self.assertEqual(m1.setter, m2.setter, "Setter flag should be equal")
+        self.assertEqual(m1.notxpcom, m2.notxpcom,
+                         "notxpcom flag should be equal")
+        self.assertEqual(m1.constructor, m2.constructor,
+                         "constructor flag should be equal")
+        self.assertEqual(m1.hidden, m2.hidden, "hidden flag should be equal")
+        self.assertEqual(m1.optargc, m2.optargc, "optargc flag should be equal")
+        self.assertEqual(m1.implicit_jscontext, m2.implicit_jscontext,
+                         "implicit_jscontext flag should be equal")
+        for p1, p2 in zip(m1.params, m2.params):
+            self.assertEqualParams(p1, p2)
+        self.assertEqualParams(m1.result, m2.result)
+        
+    def assertEqualConstants(self, c1, c2):
+        self.assert_(c1 is not None, "Should not be None")
+        self.assert_(c2 is not None, "Should not be None")
+        self.assertEqual(c1.name, c2.name)
+        self.assertEqual(c1.value, c2.value)
+        self.assertEqualTypes(c1.type, c2.type)
+
+    def assertEqualParams(self, p1, p2):
+        self.assert_(p1 is not None, "Should not be None")
+        self.assert_(p2 is not None, "Should not be None")
+        self.assertEqualTypes(p1.type, p2.type)
+        self.assertEqual(p1.in_, p2.in_)
+        self.assertEqual(p1.out, p2.out)
+        self.assertEqual(p1.retval, p2.retval)
+        self.assertEqual(p1.shared, p2.shared)
+        self.assertEqual(p1.dipper, p2.dipper)
+        self.assertEqual(p1.optional, p2.optional)
+        
+    def assertEqualTypes(self, t1, t2):
+        self.assert_(t1 is not None, "Should not be None")
+        self.assert_(t2 is not None, "Should not be None")
+        self.assertEqual(type(t1), type(t2), "type types should be equal")
+        self.assertEqual(t1.pointer, t2.pointer,
+                         "pointer flag should be equal for %s and %s" % (t1, t2))
+        self.assertEqual(t1.unique_pointer, t2.unique_pointer)
+        self.assertEqual(t1.reference, t2.reference)
+        if isinstance(t1, xpt.SimpleType):
+            self.assertEqual(t1.tag, t2.tag)
+        elif isinstance(t1, xpt.InterfaceType):
+            self.assertEqualInterfaces(t1.iface, t2.iface)
+        elif isinstance(t1, xpt.InterfaceIsType):
+            self.assertEqual(t1.param_index, t2.param_index)
+        elif isinstance(t1, xpt.ArrayType):
+            self.assertEqualTypes(t1.element_type, t2.element_type)
+            self.assertEqual(t1.size_is_arg_num, t2.size_is_arg_num)
+            self.assertEqual(t1.length_is_arg_num, t2.length_is_arg_num)
+        elif isinstance(t1, xpt.StringWithSizeType) or isinstance(t1, xpt.WideStringWithSizeType):
+            self.assertEqual(t1.size_is_arg_num, t2.size_is_arg_num)
+            self.assertEqual(t1.length_is_arg_num, t2.length_is_arg_num)
+
+#TODO: test flags in various combinations
+class TestTypelibRoundtrip(unittest.TestCase, TypelibCompareMixin):
+    def checkRoundtrip(self, t):
+        fd, f = tempfile.mkstemp()
+        os.close(fd)
+        t.write(f)
+        t2 = xpt.Typelib.read(f)
+        os.remove(f)
+        self.assert_(t2 is not None)
+        self.assertEqualTypelibs(t, t2)
+        
+    def test_simple(self):
+        t = xpt.Typelib()
+        # add an unresolved interface
+        t.interfaces.append(xpt.Interface("IFoo"))
+        self.checkRoundtrip(t)
+        
+        t = xpt.Typelib()
+        # add an unresolved interface with an IID
+        t.interfaces.append(xpt.Interface("IBar", "11223344-5566-7788-9900-aabbccddeeff"))
+        self.checkRoundtrip(t)
+
+    def test_parent(self):
+        """
+        Test that an interface's parent property is correctly serialized
+        and deserialized.
+
+        """
+        t = xpt.Typelib()
+        pi = xpt.Interface("IParent")
+        t.interfaces.append(pi)
+        t.interfaces.append(xpt.Interface("IChild", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                          parent=pi, resolved=True))
+        self.checkRoundtrip(t)
+
+    def test_ifaceFlags(self):
+        """
+        Test that an interface's flags are correctly serialized
+        and deserialized.
+
+        """
+        t = xpt.Typelib()
+        t.interfaces.append(xpt.Interface("IFlags", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                          resolved=True,
+                                          scriptable=True,
+                                          function=True))
+        self.checkRoundtrip(t)
+
+    def test_constants(self):
+        c = xpt.Constant("X", xpt.SimpleType(xpt.Type.Tags.uint32),
+                         0xF000F000)
+        i = xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                          constants=[c])
+        t = xpt.Typelib(interfaces=[i])
+        self.checkRoundtrip(t)
+        # tack on some more constants
+        i.constants.append(xpt.Constant("Y",
+                                        xpt.SimpleType(xpt.Type.Tags.int16),
+                                        -30000))
+        i.constants.append(xpt.Constant("Z",
+                                        xpt.SimpleType(xpt.Type.Tags.uint16),
+                                        0xB0B0))
+        i.constants.append(xpt.Constant("A",
+                                        xpt.SimpleType(xpt.Type.Tags.int32),
+                                        -1000000))
+        self.checkRoundtrip(t)
+
+    def test_methods(self):
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        i = xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                          methods=[m])
+        t = xpt.Typelib(interfaces=[i])
+        self.checkRoundtrip(t)
+        # add some more methods
+        i.methods.append(xpt.Method("One", xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                    params=[
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.int64)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.float, pointer=True))
+                                        ]))
+        self.checkRoundtrip(t)
+        # test some other types (should really be more thorough)
+        i.methods.append(xpt.Method("Two", xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                    params=[
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.UTF8String, pointer=True)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.wchar_t_ptr, pointer=True))
+                                        ]))
+        self.checkRoundtrip(t)
+        # add a method with an InterfaceType argument
+        bar = xpt.Interface("IBar")
+        t.interfaces.append(bar)
+        i.methods.append(xpt.Method("IFaceMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                    params=[
+                                        xpt.Param(xpt.InterfaceType(bar))
+                                        ]))
+        self.checkRoundtrip(t)
+
+        # add a method with an InterfaceIsType argument
+        i.methods.append(xpt.Method("IFaceIsMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.void)),
+                                    params=[
+                                        xpt.Param(xpt.InterfaceIsType(1)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.nsIID))
+                                        ]))
+        self.checkRoundtrip(t)
+
+        # add a method with an ArrayType argument
+        i.methods.append(xpt.Method("ArrayMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.void)),
+                                    params=[
+                                        xpt.Param(xpt.ArrayType(
+                                            xpt.SimpleType(xpt.Type.Tags.int32),
+                                            1, 2)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                        ]))
+        self.checkRoundtrip(t)
+        
+        # add a method with a StringWithSize and WideStringWithSize arguments
+        i.methods.append(xpt.Method("StringWithSizeMethod", xpt.Param(xpt.SimpleType(xpt.Type.Tags.void)),
+                                    params=[
+                                        xpt.Param(xpt.StringWithSizeType(
+                                            1, 2)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                        xpt.Param(xpt.WideStringWithSizeType(
+                                            4, 5)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                        xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32)),
+                                        ]))
+        self.checkRoundtrip(t)
+
+class TestInterfaceCmp(unittest.TestCase):
+    def test_unresolvedName(self):
+        """
+        Test comparison function on xpt.Interface by name.
+        
+        """
+        i1 = xpt.Interface("ABC")
+        i2 = xpt.Interface("DEF")
+        self.assert_(i1 < i2)
+        self.assert_(i1 != i2)
+
+    def test_unresolvedEqual(self):
+        """
+        Test comparison function on xpt.Interface with equal names and IIDs.
+        
+        """
+        i1 = xpt.Interface("ABC")
+        i2 = xpt.Interface("ABC")
+        self.assert_(i1 == i2)
+
+    def test_unresolvedIID(self):
+        """
+        Test comparison function on xpt.Interface with different IIDs.
+        
+        """
+        # IIDs sort before names
+        i1 = xpt.Interface("ABC", iid="22334411-5566-7788-9900-aabbccddeeff")
+        i2 = xpt.Interface("DEF", iid="11223344-5566-7788-9900-aabbccddeeff")
+        self.assert_(i2 < i1)
+        self.assert_(i2 != i1)
+
+    def test_unresolvedResolved(self):
+        """
+        Test comparison function on xpt.Interface with interfaces with
+        identical names and IIDs but different resolved status.
+        
+        """
+        i1 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff")
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        i2 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff",
+                           methods=[m])
+        self.assert_(i2 < i1)
+        self.assert_(i2 != i1)
+
+    def test_resolvedIdentical(self):
+        """
+        Test comparison function on xpt.Interface with interfaces with
+        identical names and IIDs, both of which are resolved.
+        
+        """
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        i1 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff",
+                           methods=[m])
+        i2 = xpt.Interface("ABC", iid="11223344-5566-7788-9900-aabbccddeeff",
+                           methods=[m])
+        self.assert_(i2 == i1)
+
+class TestTypelibMerge(unittest.TestCase):
+    def test_mergeDifferent(self):
+        """
+        Test that merging two typelibs with completely different interfaces
+        produces the correctly merged typelib.
+        
+        """
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        t1.interfaces.append(xpt.Interface("IFoo"))
+        t2 = xpt.Typelib()
+        # add an unresolved interface
+        t2.interfaces.append(xpt.Interface("IBar"))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        # Interfaces should wind up sorted
+        self.assertEqual("IBar", t1.interfaces[0].name)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+
+        # Add some IID values
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
+        t2 = xpt.Typelib()
+        # add an unresolved interface
+        t2.interfaces.append(xpt.Interface("IBar", iid="44332211-6655-8877-0099-aabbccddeeff"))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        # Interfaces should wind up sorted
+        self.assertEqual("IFoo", t1.interfaces[0].name)
+        self.assertEqual("IBar", t1.interfaces[1].name)
+
+    def test_mergeConflict(self):
+        """
+        Test that merging two typelibs with conflicting interface definitions
+        raises an error.
+        
+        """
+        # Same names, different IIDs
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
+        t2 = xpt.Typelib()
+        # add an unresolved interface, same name different IID
+        t2.interfaces.append(xpt.Interface("IFoo", iid="44332211-6655-8877-0099-aabbccddeeff"))
+        self.assertRaises(xpt.DataError, t1.merge, t2)
+
+        # Same IIDs, different names
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
+        t2 = xpt.Typelib()
+        # add an unresolved interface, same IID different name
+        t2.interfaces.append(xpt.Interface("IBar", iid="11223344-5566-7788-9900-aabbccddeeff"))
+        self.assertRaises(xpt.DataError, t1.merge, t2)
+
+    def test_mergeUnresolvedIID(self):
+        """
+        Test that merging a typelib with an unresolved definition of
+        an interface that's also unresolved in this typelib, but one
+        has a valid IID copies the IID value to the resulting typelib.
+
+        """
+        # Unresolved in both, but t1 has an IID value
+        t1 = xpt.Typelib()
+        # add an unresolved interface with a valid IID
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
+        t2 = xpt.Typelib()
+        # add an unresolved interface, no IID
+        t2.interfaces.append(xpt.Interface("IFoo"))
+        t1.merge(t2)
+        
+        self.assertEqual(1, len(t1.interfaces))
+        self.assertEqual("IFoo", t1.interfaces[0].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
+        # Unresolved in both, but t2 has an IID value
+        t1 = xpt.Typelib()
+        # add an unresolved interface, no IID
+        t1.interfaces.append(xpt.Interface("IFoo"))
+        t2 = xpt.Typelib()
+        # add an unresolved interface with a valid IID
+        t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff"))
+        t1.merge(t2)
+        
+        self.assertEqual(1, len(t1.interfaces))
+        self.assertEqual("IFoo", t1.interfaces[0].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
+
+    def test_mergeResolvedUnresolved(self):
+        """
+        Test that merging two typelibs, one of which contains an unresolved
+        reference to an interface, and the other of which contains a
+        resolved reference to the same interface results in keeping the
+        resolved reference.
+
+        """
+        # t1 has an unresolved interface, t2 has a resolved version
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        t1.interfaces.append(xpt.Interface("IFoo"))
+        t2 = xpt.Typelib()
+        # add a resolved interface
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t1.merge(t2)
+        
+        self.assertEqual(1, len(t1.interfaces))
+        self.assertEqual("IFoo", t1.interfaces[0].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
+        self.assert_(t1.interfaces[0].resolved)
+        self.assertEqual(1, len(t1.interfaces[0].methods))
+        self.assertEqual("Bar", t1.interfaces[0].methods[0].name)
+
+        # t1 has a resolved interface, t2 has an unresolved version
+        t1 = xpt.Typelib()
+        # add a resolved interface
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t2 = xpt.Typelib()
+        # add an unresolved interface
+        t2.interfaces.append(xpt.Interface("IFoo"))
+        t1.merge(t2)
+        
+        self.assertEqual(1, len(t1.interfaces))
+        self.assertEqual("IFoo", t1.interfaces[0].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[0].iid)
+        self.assert_(t1.interfaces[0].resolved)
+        self.assertEqual(1, len(t1.interfaces[0].methods))
+        self.assertEqual("Bar", t1.interfaces[0].methods[0].name)
+
+    def test_mergeReplaceParents(self):
+        """
+        Test that merging an interface results in other interfaces' parent
+        member being updated properly.
+
+        """
+        # t1 has an unresolved interface, t2 has a resolved version,
+        # but t1 also has another interface whose parent is the unresolved
+        # interface.
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        pi = xpt.Interface("IFoo")
+        t1.interfaces.append(pi)
+        # add a child of the unresolved interface
+        t1.interfaces.append(xpt.Interface("IChild", iid="11111111-1111-1111-1111-111111111111",
+                                           resolved=True, parent=pi))
+        t2 = xpt.Typelib()
+        # add a resolved interface
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        self.assertEqual("IChild", t1.interfaces[0].name)
+        self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
+        self.assert_(t1.interfaces[0].resolved)
+        # Ensure that IChild's parent has been updated
+        self.assertEqual(t1.interfaces[1], t1.interfaces[0].parent)
+        self.assert_(t1.interfaces[0].parent.resolved)
+
+        # t1 has a resolved interface, t2 has an unresolved version,
+        # but t2 also has another interface whose parent is the unresolved
+        # interface.
+        t1 = xpt.Typelib()
+        # add a resolved interface
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t2 = xpt.Typelib()
+        # add an unresolved interface
+        pi = xpt.Interface("IFoo")
+        t2.interfaces.append(pi)
+        # add a child of the unresolved interface
+        t2.interfaces.append(xpt.Interface("IChild", iid="11111111-1111-1111-1111-111111111111",
+                                           resolved=True, parent=pi))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        self.assertEqual("IChild", t1.interfaces[0].name)
+        self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
+        self.assert_(t1.interfaces[0].resolved)
+        # Ensure that IChild's parent has been updated
+        self.assertEqual(t1.interfaces[1], t1.interfaces[0].parent)
+        self.assert_(t1.interfaces[0].parent.resolved)
+
+    def test_mergeReplaceRetval(self):
+        """
+        Test that merging an interface correctly updates InterfaceType
+        return values on methods of other interfaces.
+
+        """
+        # t1 has an unresolved interface and an interface that uses the
+        # unresolved interface as a return value from a method. t2
+        # has a resolved version of the unresolved interface.
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        i = xpt.Interface("IFoo")
+        t1.interfaces.append(i)
+        # add an interface that uses the unresolved interface
+        # as a return value in a method.
+        p = xpt.Param(xpt.InterfaceType(i))
+        m = xpt.Method("ReturnIface", p)
+        t1.interfaces.append(xpt.Interface("IRetval", iid="11111111-1111-1111-1111-111111111111",
+                                           methods=[m]))
+        t2 = xpt.Typelib()
+        # add a resolved interface
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        self.assertEqual("IRetval", t1.interfaces[0].name)
+        self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
+        self.assert_(t1.interfaces[1].resolved)
+        # Ensure that IRetval's method's return value type has been updated.
+        self.assertEqual(1, len(t1.interfaces[0].methods))
+        self.assert_(t1.interfaces[0].methods[0].result.type.iface.resolved)
+        self.assertEqual(t1.interfaces[1],
+                         t1.interfaces[0].methods[0].result.type.iface)
+
+        # t1 has a resolved interface. t2 has an unresolved version and
+        # an interface that uses the unresolved interface as a return value
+        # from a method.
+        t1 = xpt.Typelib()
+        # add a resolved interface
+        p = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        m = xpt.Method("Bar", p)
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t2 = xpt.Typelib()
+        # add an unresolved interface
+        i = xpt.Interface("IFoo")
+        t2.interfaces.append(i)
+        # add an interface that uses the unresolved interface
+        # as a return value in a method.
+        p = xpt.Param(xpt.InterfaceType(i))
+        m = xpt.Method("ReturnIface", p)
+        t2.interfaces.append(xpt.Interface("IRetval", iid="11111111-1111-1111-1111-111111111111",
+                                           methods=[m]))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        self.assertEqual("IRetval", t1.interfaces[0].name)
+        self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
+        self.assert_(t1.interfaces[1].resolved)
+        # Ensure that IRetval's method's return value type has been updated.
+        self.assertEqual(1, len(t1.interfaces[0].methods))
+        self.assert_(t1.interfaces[0].methods[0].result.type.iface.resolved)
+        self.assertEqual(t1.interfaces[1],
+                         t1.interfaces[0].methods[0].result.type.iface)
+
+    def test_mergeReplaceParams(self):
+        """
+        Test that merging an interface correctly updates InterfaceType
+        params on methods of other interfaces.
+
+        """
+        # t1 has an unresolved interface and an interface that uses the
+        # unresolved interface as a param value in a method. t2
+        # has a resolved version of the unresolved interface.
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        i = xpt.Interface("IFoo")
+        t1.interfaces.append(i)
+        # add an interface that uses the unresolved interface
+        # as a param value in a method.
+        vp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        p = xpt.Param(xpt.InterfaceType(i))
+        m = xpt.Method("IfaceParam", vp, params=[p])
+        t1.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
+                                           methods=[m]))
+        t2 = xpt.Typelib()
+        # add a resolved interface
+        m = xpt.Method("Bar", vp)
+        t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        self.assertEqual("IParam", t1.interfaces[0].name)
+        self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
+        self.assert_(t1.interfaces[1].resolved)
+        # Ensure that IRetval's method's param type has been updated.
+        self.assertEqual(1, len(t1.interfaces[0].methods))
+        self.assert_(t1.interfaces[0].methods[0].params[0].type.iface.resolved)
+        self.assertEqual(t1.interfaces[1],
+                         t1.interfaces[0].methods[0].params[0].type.iface)
+
+        # t1 has a resolved interface. t2 has an unresolved version
+        # and an interface that uses the unresolved interface as a
+        # param value in a method.
+        t1 = xpt.Typelib()
+        # add a resolved interface
+        m = xpt.Method("Bar", vp)
+        t1.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t2 = xpt.Typelib()
+        # add an unresolved interface
+        i = xpt.Interface("IFoo")
+        t2.interfaces.append(i)
+        # add an interface that uses the unresolved interface
+        # as a param value in a method.
+        vp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        p = xpt.Param(xpt.InterfaceType(i))
+        m = xpt.Method("IfaceParam", vp, params=[p])
+        t2.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
+                                           methods=[m]))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        self.assertEqual("IParam", t1.interfaces[0].name)
+        self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
+        self.assert_(t1.interfaces[1].resolved)
+        # Ensure that IRetval's method's param type has been updated.
+        self.assertEqual(1, len(t1.interfaces[0].methods))
+        self.assert_(t1.interfaces[0].methods[0].params[0].type.iface.resolved)
+        self.assertEqual(t1.interfaces[1],
+                         t1.interfaces[0].methods[0].params[0].type.iface)
+
+
+    def test_mergeReplaceArrayTypeParams(self):
+        """
+        Test that merging an interface correctly updates ArrayType
+        params whose element_type is an InterfaceType on methods
+        of other interfaces.
+
+        """
+        # t1 has an unresolved interface and an interface that uses the
+        # unresolved interface as a type in an ArrayType in a parameter
+        # of a method. t2 has a resolved version of the unresolved interface.
+        t1 = xpt.Typelib()
+        # add an unresolved interface
+        i = xpt.Interface("IFoo")
+        t1.interfaces.append(i)
+        # add an interface that uses the unresolved interface
+        # as a type in an ArrayType in a param value in a method.
+        vp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.void))
+        intp = xpt.Param(xpt.SimpleType(xpt.Type.Tags.int32))
+        p = xpt.Param(xpt.ArrayType(xpt.InterfaceType(i), 1, 2))
+        m = xpt.Method("ArrayIfaceParam", vp, params=[p, intp, intp])
+        t1.interfaces.append(xpt.Interface("IParam", iid="11111111-1111-1111-1111-111111111111",
+                                           methods=[m]))
+        t2 = xpt.Typelib()
+        # add a resolved interface
+        m = xpt.Method("Bar", vp)
+        t2.interfaces.append(xpt.Interface("IFoo", iid="11223344-5566-7788-9900-aabbccddeeff",
+                                           methods=[m]))
+        t1.merge(t2)
+        
+        self.assertEqual(2, len(t1.interfaces))
+        self.assertEqual("IParam", t1.interfaces[0].name)
+        self.assertEqual("11111111-1111-1111-1111-111111111111", t1.interfaces[0].iid)
+        self.assertEqual("IFoo", t1.interfaces[1].name)
+        self.assertEqual("11223344-5566-7788-9900-aabbccddeeff", t1.interfaces[1].iid)
+        self.assert_(t1.interfaces[1].resolved)
+        # Ensure that IRetval's method's param type has been updated.
+        self.assertEqual(1, len(t1.interfaces[0].methods))
+        self.assert_(t1.interfaces[0].methods[0].params[0].type.element_type.iface.resolved)
+        self.assertEqual(t1.interfaces[1],
+                         t1.interfaces[0].methods[0].params[0].type.element_type.iface)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/xpcom/typelib/xpt/tools/xpt.py b/xpcom/typelib/xpt/tools/xpt.py
new file mode 100644
index 000000000000..0de9451a0623
--- /dev/null
+++ b/xpcom/typelib/xpt/tools/xpt.py
@@ -0,0 +1,1318 @@
+#!/usr/bin/env python
+# Copyright 2010,2011 Mozilla Foundation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE MOZILLA FOUNDATION ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE MOZILLA FOUNDATION OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation
+# are those of the authors and should not be interpreted as representing
+# official policies, either expressed or implied, of the Mozilla
+# Foundation.
+
+"""
+A module for working with XPCOM Type Libraries.
+
+The XPCOM Type Library File Format is described at:
+http://www.mozilla.org/scriptable/typelib_file.html . It is used
+to provide type information for calling methods on XPCOM objects
+from scripting languages such as JavaScript.
+
+This module provides a set of classes representing the parts of
+a typelib in a high-level manner, as well as methods for reading
+and writing them from files.
+
+The usable public interfaces are currently:
+Typelib.read(filename) - read a typelib from a file on disk, return
+                         a Typelib object.
+
+xpt_dump(filename)     - read a typelib from a file on disk, dump
+                         the contents to stdout in a human-readable
+                         format.
+
+Typelib()              - construct a new Typelib object
+Interface()            - construct a new Interface object
+Method()               - construct a new object representing a method
+                         defined on an Interface
+Constant()             - construct a new object representing a constant
+                         defined on an Interface
+Param()                - construct a new object representing a parameter
+                         to a method
+SimpleType()           - construct a new object representing a simple
+                         data type
+InterfaceType()        - construct a new object representing a type that
+                         is an IDL-defined interface
+
+"""
+
+from __future__ import with_statement
+import mmap
+import os, sys
+import struct
+
+# header magic
+XPT_MAGIC = "XPCOM\nTypeLib\r\n\x1a"
+TYPELIB_VERSION = (1, 2)
+
+class FileFormatError(Exception):
+    pass
+
+class DataError(Exception):
+    pass
+
+# Magic for creating enums
+def M_add_class_attribs(attribs):
+    def foo(name, bases, dict_):
+        for v, k in attribs:
+            dict_[k] = v
+        return type(name, bases, dict_)
+    return foo
+
+def enum(*names):
+    class Foo(object):
+        __metaclass__ = M_add_class_attribs(enumerate(names))
+        def __setattr__(self, name, value):  # this makes it read-only
+            raise NotImplementedError
+    return Foo()
+
+# Descriptor types as described in the spec
+class Type(object):
+    """
+    Data type of a method parameter or return value. Do not instantiate
+    this class directly. Rather, use one of its subclasses.
+    
+    """
+    _prefixdescriptor = struct.Struct(">B")
+    Tags = enum(
+        # The first 18 entries are SimpleTypeDescriptor
+        'int8',
+        'int16',
+        'int32',
+        'int64',
+        'uint8',
+        'uint16',
+        'uint32',
+        'uint64',
+        'float',
+        'double',
+        'boolean',
+        'char',
+        'wchar_t',
+        'void',
+        # the following four values are only valid as pointers
+        'nsIID',
+        'DOMString',
+        'char_ptr',
+        'wchar_t_ptr',
+        # InterfaceTypeDescriptor
+        'Interface',
+        # InterfaceIsTypeDescriptor
+        'InterfaceIs',
+        # ArrayTypeDescriptor
+        'Array',
+        # StringWithSizeTypeDescriptor
+        'StringWithSize',
+        # WideStringWithSizeTypeDescriptor
+        'WideStringWithSize',
+        #XXX: These are also SimpleTypes (but not in the spec)
+        # http://hg.mozilla.org/mozilla-central/annotate/0e0e2516f04e/xpcom/typelib/xpt/tools/xpt_dump.c#l69
+        'UTF8String',
+        'CString',
+        'AString',
+        'jsval',
+        )
+
+    def __init__(self, pointer=False, unique_pointer=False, reference=False):
+        self.pointer = pointer
+        self.unique_pointer = unique_pointer
+        self.reference = reference
+
+    @staticmethod
+    def decodeflags(byte):
+        """
+        Given |byte|, an unsigned uint8 containing flag bits,
+        decode the flag bits as described in
+        http://www.mozilla.org/scriptable/typelib_file.html#TypeDescriptor
+        and return a dict of flagname: (True|False) suitable
+        for passing to Type.__init__ as **kwargs.
+        
+        """
+        return {'pointer': bool(byte & 0x80),
+                'unique_pointer': bool(byte & 0x40),
+                'reference': bool(byte & 0x20),
+                }
+
+    def encodeflags(self):
+        """
+        Encode the flag bits of this Type object. Returns a byte.
+
+        """
+        flags = 0
+        if self.pointer:
+            flags |= 0x80
+        if self.unique_pointer:
+            flags |= 0x40
+        if self.reference:
+            flags |= 0x20
+        return flags
+    
+    @staticmethod
+    def read(typelib, map, data_pool, offset):
+        """
+        Read a TypeDescriptor at |offset| from the mmaped file |map| with
+        data pool offset |data_pool|. Returns (Type, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this TypeDescriptor.
+        
+        """
+        start = data_pool + offset - 1
+        (data,) = Type._prefixdescriptor.unpack(map[start:start + Type._prefixdescriptor.size])
+        # first three bits are the flags
+        flags = data & 0xE0
+        flags = Type.decodeflags(flags)
+        # last five bits is the tag
+        tag = data & 0x1F
+        offset += Type._prefixdescriptor.size
+        t = None
+        if tag <= Type.Tags.wchar_t_ptr or tag >= Type.Tags.UTF8String:
+            t = SimpleType.get(data, tag, flags)
+        elif tag == Type.Tags.Interface:
+            t, offset = InterfaceType.read(typelib, map, data_pool, offset, flags)
+        elif tag == Type.Tags.InterfaceIs:
+            t, offset = InterfaceIsType.read(typelib, map, data_pool, offset, flags)
+        elif tag == Type.Tags.Array:
+            t, offset = ArrayType.read(typelib, map, data_pool, offset, flags)
+        elif tag == Type.Tags.StringWithSize:
+            t, offset = StringWithSizeType.read(typelib, map, data_pool, offset, flags)
+        elif tag == Type.Tags.WideStringWithSize:
+            t, offset = WideStringWithSizeType.read(typelib, map, data_pool, offset, flags)
+        return t, offset
+
+    def write(self, typelib, file):
+        """
+        Write a TypeDescriptor to |file|, which is assumed
+        to be seeked to the proper position. For types other than
+        SimpleType, this is not sufficient for writing the TypeDescriptor,
+        and the subclass method must be called.
+
+        """
+        file.write(Type._prefixdescriptor.pack(self.encodeflags() | self.tag))
+
+class SimpleType(Type):
+    """
+    A simple data type. (SimpleTypeDescriptor from the typelib specification.)
+
+    """
+    _cache = {}
+
+    def __init__(self, tag, **kwargs):
+        Type.__init__(self, **kwargs)
+        self.tag = tag
+
+    @staticmethod
+    def get(data, tag, flags):
+        """
+        Get a SimpleType object representing |data| (a TypeDescriptorPrefix).
+        May return an already-created object. If no cached object is found,
+        construct one with |tag| and |flags|.
+        
+        """
+        if data not in SimpleType._cache:
+            SimpleType._cache[data] = SimpleType(tag, **flags)
+        return SimpleType._cache[data]
+
+    def __str__(self):
+        s = "unknown"
+        if self.tag == Type.Tags.char_ptr and self.pointer:
+            return "string"
+        if self.tag == Type.Tags.wchar_t_ptr and self.pointer:
+            return "wstring"
+        for t in dir(Type.Tags):
+            if self.tag == getattr(Type.Tags, t):
+                s = t
+                break
+
+        if self.pointer:
+            if self.reference:
+                s += " &"
+            else:
+                s += " *"
+        return s
+
+class InterfaceType(Type):
+    """
+    A type representing a pointer to an IDL-defined interface.
+    (InterfaceTypeDescriptor from the typelib specification.)
+
+    """
+    _descriptor = struct.Struct(">H")
+
+    def __init__(self, iface, pointer=True, **kwargs):
+        if not pointer:
+            raise DataError, "InterfaceType is not valid with pointer=False"
+        Type.__init__(self, pointer=pointer, **kwargs)
+        self.iface = iface
+        self.tag = Type.Tags.Interface
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset, flags):
+        """
+        Read an InterfaceTypeDescriptor at |offset| from the mmaped
+        file |map| with data pool offset |data_pool|.
+        Returns (InterfaceType, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this InterfaceTypeDescriptor.
+        
+        """
+        if not flags['pointer']:
+            return None, offset
+        start = data_pool + offset - 1
+        (iface_index,) = InterfaceType._descriptor.unpack(map[start:start + InterfaceType._descriptor.size])
+        offset += InterfaceType._descriptor.size
+        iface = None
+        # interface indices are 1-based
+        if iface_index > 0 and iface_index <= len(typelib.interfaces):
+            iface = typelib.interfaces[iface_index - 1]
+        return InterfaceType(iface, **flags), offset
+
+    def write(self, typelib, file):
+        """
+        Write an InterfaceTypeDescriptor to |file|, which is assumed
+        to be seeked to the proper position.
+
+        """
+        Type.write(self, typelib, file)
+        # write out the interface index (1-based)
+        file.write(InterfaceType._descriptor.pack(typelib.interfaces.index(self.iface) + 1))
+
+    def __str__(self):
+        if self.iface:
+            return self.iface.name
+        return "unknown interface"
+
+class InterfaceIsType(Type):
+    """
+    A type representing an interface described by one of the other
+    arguments to the method. (InterfaceIsTypeDescriptor from the
+    typelib specification.)
+    
+    """
+    _descriptor = struct.Struct(">B")
+    _cache = {}
+
+    def __init__(self, param_index, pointer=True, **kwargs):
+        if not pointer:
+            raise DataError, "InterfaceIsType is not valid with pointer=False"
+        Type.__init__(self, pointer=pointer, **kwargs)
+        self.param_index = param_index
+        self.tag = Type.Tags.InterfaceIs
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset, flags):
+        """
+        Read an InterfaceIsTypeDescriptor at |offset| from the mmaped
+        file |map| with data pool offset |data_pool|.
+        Returns (InterfaceIsType, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this InterfaceIsTypeDescriptor.
+        May return a cached value.
+        
+        """
+        if not flags['pointer']:
+            return None, offset
+        start = data_pool + offset - 1
+        (param_index,) = InterfaceIsType._descriptor.unpack(map[start:start + InterfaceIsType._descriptor.size])
+        offset += InterfaceIsType._descriptor.size
+        if param_index not in InterfaceIsType._cache:
+            InterfaceIsType._cache[param_index] = InterfaceIsType(param_index, **flags)
+        return InterfaceIsType._cache[param_index], offset
+
+    def write(self, typelib, file):
+        """
+        Write an InterfaceIsTypeDescriptor to |file|, which is assumed
+        to be seeked to the proper position.
+
+        """
+        Type.write(self, typelib, file)
+        file.write(InterfaceIsType._descriptor.pack(self.param_index))
+
+    def __str__(self):
+        return "InterfaceIs *"
+
+class ArrayType(Type):
+    """
+    A type representing an Array of elements of another type, whose
+    size and length are passed as separate parameters to a method.
+    (ArrayTypeDescriptor from the typelib specification.)
+    
+    """
+    _descriptor = struct.Struct(">BB")
+
+    def __init__(self, element_type, size_is_arg_num, length_is_arg_num,
+                 pointer=True, **kwargs):
+        if not pointer:
+            raise DataError, "ArrayType is not valid with pointer=False"
+        Type.__init__(self, pointer=pointer, **kwargs)
+        self.element_type = element_type
+        self.size_is_arg_num = size_is_arg_num
+        self.length_is_arg_num = length_is_arg_num
+        self.tag = Type.Tags.Array
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset, flags):
+        """
+        Read an ArrayTypeDescriptor at |offset| from the mmaped
+        file |map| with data pool offset |data_pool|.
+        Returns (ArrayType, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this ArrayTypeDescriptor.
+        """
+        if not flags['pointer']:
+            return None, offset
+        start = data_pool + offset - 1
+        (size_is_arg_num, length_is_arg_num) = ArrayType._descriptor.unpack(map[start:start + ArrayType._descriptor.size])
+        offset += ArrayType._descriptor.size
+        t, offset = Type.read(typelib, map, data_pool, offset)
+        return ArrayType(t, size_is_arg_num, length_is_arg_num, **flags), offset
+
+    def write(self, typelib, file):
+        """
+        Write an ArrayTypeDescriptor to |file|, which is assumed
+        to be seeked to the proper position.
+
+        """
+        Type.write(self, typelib, file)
+        file.write(ArrayType._descriptor.pack(self.size_is_arg_num,
+                                              self.length_is_arg_num))
+        self.element_type.write(typelib, file)
+
+    def __str__(self):
+        return "%s []" % str(self.element_type)
+
+class StringWithSizeType(Type):
+    """
+    A type representing a UTF-8 encoded string whose size and length
+    are passed as separate arguments to a method. (StringWithSizeTypeDescriptor
+    from the typelib specification.)
+
+    """
+    _descriptor = struct.Struct(">BB")
+
+    def __init__(self, size_is_arg_num, length_is_arg_num,
+                 pointer=True, **kwargs):
+        if not pointer:
+            raise DataError, "StringWithSizeType is not valid with pointer=False"
+        Type.__init__(self, pointer=pointer, **kwargs)
+        self.size_is_arg_num = size_is_arg_num
+        self.length_is_arg_num = length_is_arg_num
+        self.tag = Type.Tags.StringWithSize
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset, flags):
+        """
+        Read an StringWithSizeTypeDescriptor at |offset| from the mmaped
+        file |map| with data pool offset |data_pool|.
+        Returns (StringWithSizeType, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this StringWithSizeTypeDescriptor.
+        """
+        if not flags['pointer']:
+            return None, offset
+        start = data_pool + offset - 1
+        (size_is_arg_num, length_is_arg_num) = StringWithSizeType._descriptor.unpack(map[start:start + StringWithSizeType._descriptor.size])
+        offset += StringWithSizeType._descriptor.size
+        return StringWithSizeType(size_is_arg_num, length_is_arg_num, **flags), offset
+    
+    def write(self, typelib, file):
+        """
+        Write a StringWithSizeTypeDescriptor to |file|, which is assumed
+        to be seeked to the proper position.
+
+        """
+        Type.write(self, typelib, file)
+        file.write(StringWithSizeType._descriptor.pack(self.size_is_arg_num,
+                                                       self.length_is_arg_num))
+        
+    def __str__(self):
+        return "string_s"
+
+class WideStringWithSizeType(Type):
+    """
+    A type representing a UTF-16 encoded string whose size and length
+    are passed as separate arguments to a method.
+    (WideStringWithSizeTypeDescriptor from the typelib specification.)
+
+    """    
+    _descriptor = struct.Struct(">BB")
+
+    def __init__(self, size_is_arg_num, length_is_arg_num,
+                 pointer=True, **kwargs):
+        if not pointer:
+            raise DataError, "WideStringWithSizeType is not valid with pointer=False"
+        Type.__init__(self, pointer=pointer, **kwargs)
+        self.size_is_arg_num = size_is_arg_num
+        self.length_is_arg_num = length_is_arg_num
+        self.tag = Type.Tags.WideStringWithSize
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset, flags):
+        """
+        Read an WideStringWithSizeTypeDescriptor at |offset| from the mmaped
+        file |map| with data pool offset |data_pool|.
+        Returns (WideStringWithSizeType, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this WideStringWithSizeTypeDescriptor.
+        """
+        if not flags['pointer']:
+            return None, offset
+        start = data_pool + offset - 1
+        (size_is_arg_num, length_is_arg_num) = WideStringWithSizeType._descriptor.unpack(map[start:start + WideStringWithSizeType._descriptor.size])
+        offset += WideStringWithSizeType._descriptor.size
+        return WideStringWithSizeType(size_is_arg_num, length_is_arg_num, **flags), offset
+
+    def write(self, typelib, file):
+        """
+        Write a WideStringWithSizeTypeDescriptor to |file|, which is assumed
+        to be seeked to the proper position.
+
+        """
+        Type.write(self, typelib, file)
+        file.write(WideStringWithSizeType._descriptor.pack(self.size_is_arg_num,
+                                                           self.length_is_arg_num))
+
+    def __str__(self):
+        return "wstring_s"
+
+class Param(object):
+    """
+    A parameter to a method, or the return value of a method.
+    (ParamDescriptor from the typelib specification.)
+
+    """
+    _descriptorstart = struct.Struct(">B")
+
+    def __init__(self, type, in_=True, out=False, retval=False,
+                 shared=False, dipper=False, optional=False):
+        """
+        Construct a Param object with the specified |type| and
+        flags. Params default to "in".
+
+        """
+        self.type = type
+        self.in_ = in_
+        self.out = out
+        self.retval = retval
+        self.shared = shared
+        self.dipper = dipper
+        self.optional = optional
+
+    @staticmethod
+    def decodeflags(byte):
+        """
+        Given |byte|, an unsigned uint8 containing flag bits,
+        decode the flag bits as described in
+        http://www.mozilla.org/scriptable/typelib_file.html#ParamDescriptor
+        and return a dict of flagname: (True|False) suitable
+        for passing to Param.__init__ as **kwargs
+        """
+        return {'in_': bool(byte & 0x80),
+                'out': bool(byte & 0x40),
+                'retval': bool(byte & 0x20),
+                'shared': bool(byte & 0x10),
+                'dipper': bool(byte & 0x08),
+                #XXX: Not in the spec, see:
+                # http://hg.mozilla.org/mozilla-central/annotate/0e0e2516f04e/xpcom/typelib/xpt/public/xpt_struct.h#l456
+                'optional': bool(byte & 0x04),
+                }
+
+    def encodeflags(self):
+        """
+        Encode the flags of this Param. Return a byte suitable for
+        writing to a typelib file.
+
+        """
+        flags = 0
+        if self.in_:
+            flags |= 0x80
+        if self.out:
+            flags |= 0x40
+        if self.retval:
+            flags |= 0x20
+        if self.shared:
+            flags |= 0x10
+        if self.dipper:
+            flags |= 0x08
+        if self.optional:
+            flags |= 0x04
+        return flags
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset):
+        """
+        Read a ParamDescriptor at |offset| from the mmaped file |map| with
+        data pool offset |data_pool|. Returns (Param, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this ParamDescriptor.
+        """
+        start = data_pool + offset - 1
+        (flags,) = Param._descriptorstart.unpack(map[start:start + Param._descriptorstart.size])
+        # only the first five bits are flags
+        flags &= 0xFC
+        flags = Param.decodeflags(flags)
+        offset += Param._descriptorstart.size
+        t, offset = Type.read(typelib, map, data_pool, offset)
+        p = Param(t, **flags)
+        return p, offset
+
+    def write(self, typelib, file):
+        """
+        Write a ParamDescriptor to |file|, which is assumed to be seeked
+        to the correct position.
+
+        """
+        file.write(Param._descriptorstart.pack(self.encodeflags()))
+        self.type.write(typelib, file)
+
+    def prefix(self):
+        """
+        Return a human-readable string representing the flags set
+        on this Param.
+
+        """
+        s = ""
+        if self.out:
+            if self.in_:
+                s = "inout "
+            else:
+                s = "out "
+        else:
+            s = "in "
+        if self.dipper:
+            s += "dipper "
+        if self.retval:
+            s += "retval "
+        if self.shared:
+            s += "shared "
+        if self.optional:
+            s += "optional "
+        return s
+            
+    def __str__(self):
+        return self.prefix() + str(self.type)
+
+class Method(object):
+    """
+    A method of an interface, defining its associated parameters
+    and return value.
+    (MethodDescriptor from the typelib specification.)
+    
+    """
+    _descriptorstart = struct.Struct(">BIB")
+    
+    def __init__(self, name, result,
+                 params=[], getter=False, setter=False, notxpcom=False,
+                 constructor=False, hidden=False, optargc=False,
+                 implicit_jscontext=False):
+        self.name = name
+        self._name_offset = 0
+        self.getter = getter
+        self.setter = setter
+        self.notxpcom = notxpcom
+        self.constructor = constructor
+        self.hidden = hidden
+        self.optargc = optargc
+        self.implicit_jscontext = implicit_jscontext
+        self.params = list(params)
+        self.result = result
+
+    def read_params(self, typelib, map, data_pool, offset, num_args):
+        """
+        Read |num_args| ParamDescriptors representing this Method's arguments
+        from the mmaped file |map| with data pool at the offset |data_pool|,
+        starting at |offset| into self.params. Returns the offset
+        suitable for reading the data following the ParamDescriptor array.
+        
+        """
+        for i in range(num_args):
+            p, offset = Param.read(typelib, map, data_pool, offset)
+            self.params.append(p)
+        return offset
+
+    def read_result(self, typelib, map, data_pool, offset):
+        """
+        Read a ParamDescriptor representing this Method's return type
+        from the mmaped file |map| with data pool at the offset |data_pool|,
+        starting at |offset| into self.result. Returns the offset
+        suitable for reading the data following the ParamDescriptor.
+        
+        """
+        self.result, offset = Param.read(typelib, map, data_pool, offset)
+        return offset
+
+    @staticmethod
+    def decodeflags(byte):
+        """
+        Given |byte|, an unsigned uint8 containing flag bits,
+        decode the flag bits as described in
+        http://www.mozilla.org/scriptable/typelib_file.html#MethodDescriptor
+        and return a dict of flagname: (True|False) suitable
+        for passing to Method.__init__ as **kwargs
+        
+        """
+        return {'getter': bool(byte & 0x80),
+                'setter': bool(byte & 0x40),
+                'notxpcom': bool(byte & 0x20),
+                'constructor': bool(byte & 0x10),
+                'hidden': bool(byte & 0x08),
+                # Not in the spec, see
+                # http://hg.mozilla.org/mozilla-central/annotate/0e0e2516f04e/xpcom/typelib/xpt/public/xpt_struct.h#l489
+                'optargc': bool(byte & 0x04),
+                'implicit_jscontext': bool(byte & 0x02),
+                }
+
+    def encodeflags(self):
+        """
+        Encode the flags of this Method object, return a byte suitable
+        for writing to a typelib file.
+
+        """
+        flags = 0
+        if self.getter:
+            flags |= 0x80
+        if self.setter:
+            flags |= 0x40
+        if self.notxpcom:
+            flags |= 0x20
+        if self.constructor:
+            flags |= 0x10
+        if self.hidden:
+            flags |= 0x08
+        if self.optargc:
+            flags |= 0x04
+        if self.implicit_jscontext:
+            flags |= 0x02
+        return flags
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset):
+        """
+        Read a MethodDescriptor at |offset| from the mmaped file |map| with
+        data pool offset |data_pool|. Returns (Method, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this MethodDescriptor.
+        
+        """
+        start = data_pool + offset - 1
+        flags, name_offset, num_args = Method._descriptorstart.unpack(map[start:start + Method._descriptorstart.size])
+        # only the first seven bits are flags
+        flags &= 0xFE
+        flags = Method.decodeflags(flags)
+        name = Typelib.read_string(map, data_pool, name_offset)
+        m = Method(name, None, **flags)
+        offset += Method._descriptorstart.size
+        offset = m.read_params(typelib, map, data_pool, offset, num_args)
+        offset = m.read_result(typelib, map, data_pool, offset)
+        return m, offset
+
+    def write(self, typelib, file):
+        """
+        Write a MethodDescriptor to |file|, which is assumed to be
+        seeked to the right position.
+
+        """
+        file.write(Method._descriptorstart.pack(self.encodeflags(),
+                                                self._name_offset,
+                                                len(self.params)))
+        for p in self.params:
+            p.write(typelib, file)
+        self.result.write(typelib, file)
+
+    def write_name(self, file, data_pool_offset):
+        """
+        Write this method's name to |file|.
+        Assumes that |file| is currently seeked to an unused portion
+        of the data pool.
+
+        """
+        if self.name:
+            self._name_offset = file.tell() - data_pool_offset + 1
+            file.write(self.name + "\x00")
+        else:
+            self._name_offset = 0
+
+class Constant(object):
+    """
+    A constant value of a specific type defined on an interface.
+    (ConstantDesciptor from the typelib specification.)
+
+    """
+    _descriptorstart = struct.Struct(">I")
+    # Actual value is restricted to this set of types
+    #XXX: the spec lies, the source allows a bunch more
+    # http://hg.mozilla.org/mozilla-central/annotate/9c85f9aaec8c/xpcom/typelib/xpt/src/xpt_struct.c#l689
+    typemap = {Type.Tags.int16: '>h',
+               Type.Tags.uint16: '>H',
+               Type.Tags.int32: '>i',
+               Type.Tags.uint32: '>I'}
+
+    def __init__(self, name, type, value):
+        self.name = name
+        self._name_offset = 0        
+        self.type = type
+        self.value = value
+
+    @staticmethod
+    def read(typelib, map, data_pool, offset):
+        """
+        Read a ConstDescriptor at |offset| from the mmaped file |map| with
+        data pool offset |data_pool|. Returns (Constant, next offset),
+        where |next offset| is an offset suitable for reading the data
+        following this ConstDescriptor.
+        
+        """
+        start = data_pool + offset - 1
+        (name_offset,) = Constant._descriptorstart.unpack(map[start:start + Constant._descriptorstart.size])
+        name = Typelib.read_string(map, data_pool, name_offset)
+        offset += Constant._descriptorstart.size
+        # Read TypeDescriptor
+        t, offset = Type.read(typelib, map, data_pool, offset)
+        c = None
+        if isinstance(t, SimpleType) and t.tag in Constant.typemap:
+            tt = Constant.typemap[t.tag]
+            start = data_pool + offset - 1
+            (val,) = struct.unpack(tt, map[start:start + struct.calcsize(tt)])
+            offset += struct.calcsize(tt)
+            c = Constant(name, t, val)
+        return c, offset
+
+    def write(self, typelib, file):
+        """
+        Write a ConstDescriptor to |file|, which is assumed
+        to be seeked to the proper position.
+
+        """
+        file.write(Constant._descriptorstart.pack(self._name_offset))
+        self.type.write(typelib, file)
+        tt = Constant.typemap[self.type.tag]
+        file.write(struct.pack(tt, self.value))
+
+    def write_name(self, file, data_pool_offset):
+        """
+        Write this constants's name to |file|.
+        Assumes that |file| is currently seeked to an unused portion
+        of the data pool.
+
+        """
+        if self.name:
+            self._name_offset = file.tell() - data_pool_offset + 1
+            file.write(self.name + "\x00")
+        else:
+            self._name_offset = 0
+
+    def __repr__(self):
+        return "Constant(%s, %s, %d)" % (self.name, str(self.type), self.value)
+
+class Interface(object):
+    """
+    An Interface represents an object, with its associated methods
+    and constant values.
+    (InterfaceDescriptor from the typelib specification.)
+    
+    """
+    _direntry = struct.Struct(">16sIII")    
+    _descriptorstart = struct.Struct(">HH")
+
+    UNRESOLVED_IID = "00000000-0000-0000-0000-000000000000"
+    
+    def __init__(self, name, iid=UNRESOLVED_IID, namespace="",
+                 resolved=False, parent=None, methods=[], constants=[],
+                 scriptable=False, function=False):
+        self.resolved = resolved
+        #TODO: should validate IIDs!
+        self.iid = iid
+        self.name = name
+        self.namespace = namespace
+        # if unresolved, all the members following this are unusable
+        self.parent = parent
+        self.methods = list(methods)
+        self.constants = list(constants)
+        self.scriptable = scriptable
+        self.function = function
+        # For sanity, if someone constructs an Interface and passes
+        # in methods or constants, then it's resolved.
+        if self.methods or self.constants:
+            # make sure it has a valid IID
+            if self.iid == Interface.UNRESOLVED_IID:
+                raise DataError, "Cannot instantiate Interface %s containing methods or constants with an unresolved IID" % self.name
+            self.resolved = True
+        # These are only used for writing out the interface
+        self._descriptor_offset = 0
+        self._name_offset = 0
+        self._namespace_offset = 0
+
+    def __repr__(self):
+        return "Interface('%s', '%s', '%s', methods=%s)" % (self.name, self.iid, self.namespace, self.methods)
+
+    def __str__(self):
+        return "Interface(name='%s', iid='%s')" % (self.name, self.iid)
+
+    def __cmp__(self, other):
+        c = cmp(self.iid, other.iid)
+        if c != 0:
+            return c
+        c = cmp(self.name, other.name)
+        if c != 0:
+            return c
+        c = cmp(self.namespace, other.namespace)
+        if c != 0:
+            return c
+        # names and IIDs are the same, check resolved
+        if self.resolved != other.resolved:
+            if self.resolved:
+                return -1
+            else:
+                return 1
+        else:
+            # both unresolved, but names and IIDs are the same, so equal
+            return 0
+        #TODO: actually compare methods etc
+        return 0
+
+    def read_descriptor(self, typelib, map, data_pool):
+        offset = self._descriptor_offset
+        if offset == 0:
+            return
+        start = data_pool + offset - 1
+        parent, num_methods = Interface._descriptorstart.unpack(map[start:start + Interface._descriptorstart.size])
+        if parent > 0 and parent <= len(typelib.interfaces):
+            self.parent = typelib.interfaces[parent - 1]
+        # Read methods
+        offset += Interface._descriptorstart.size
+        for i in range(num_methods):
+            m, offset = Method.read(typelib, map, data_pool, offset)
+            self.methods.append(m)
+        # Read constants
+        start = data_pool + offset - 1
+        (num_constants, ) = struct.unpack(">H", map[start:start + struct.calcsize(">H")])
+        offset = offset + struct.calcsize(">H")
+        for i in range(num_constants):
+            c, offset = Constant.read(typelib, map, data_pool, offset)
+            self.constants.append(c)
+        # Read flags
+        start = data_pool + offset - 1
+        (flags, ) = struct.unpack(">B", map[start:start + struct.calcsize(">B")])
+        offset = offset + struct.calcsize(">B")
+        # only the first two bits are flags
+        flags &= 0xC0
+        if flags & 0x80:
+            self.scriptable = True
+        if flags & 0x40:
+            self.function = True
+        self.resolved = True
+
+    def write_directory_entry(self, file):
+        """
+        Write an InterfaceDirectoryEntry for this interface
+        to |file|, which is assumed to be seeked to the correct offset.
+
+        """
+        file.write(Interface._direntry.pack(Typelib.string_to_iid(self.iid),
+                                            self._name_offset,
+                                            self._namespace_offset,
+                                            self._descriptor_offset))
+
+    def write(self, typelib, file, data_pool_offset):
+        """
+        Write an InterfaceDescriptor to |file|, which is assumed
+        to be seeked to the proper position. If this interface
+        is not resolved, do not write any data.
+
+        """
+        if not self.resolved:
+            self._descriptor_offset = 0
+            return
+        self._descriptor_offset = file.tell() - data_pool_offset + 1
+        parent_idx = 0
+        if self.parent:
+            parent_idx = typelib.interfaces.index(self.parent) + 1
+        file.write(Interface._descriptorstart.pack(parent_idx, len(self.methods)))
+        for m in self.methods:
+            m.write(typelib, file)
+        file.write(struct.pack(">H", len(self.constants)))
+        for c in self.constants:
+            c.write(typelib, file)
+        flags = 0
+        if self.scriptable:
+            flags |= 0x80
+        if self.function:
+            flags |= 0x40
+        file.write(struct.pack(">B", flags))
+        
+    def write_names(self, file, data_pool_offset):
+        """
+        Write this interface's name and namespace to |file|,
+        as well as the names of all of its methods and constants.
+        Assumes that |file| is currently seeked to an unused portion
+        of the data pool.
+
+        """
+        if self.name:
+            self._name_offset = file.tell() - data_pool_offset + 1
+            file.write(self.name + "\x00")
+        else:
+            self._name_offset = 0
+        if self.namespace:
+            self._namespace_offset = file.tell() - data_pool_offset + 1
+            file.write(self.namespace + "\x00")
+        else:
+            self._namespace_offset = 0
+        for m in self.methods:
+            m.write_name(file, data_pool_offset)
+        for c in self.constants:
+            c.write_name(file, data_pool_offset)
+
+class Typelib(object):
+    """
+    A typelib represents one entire typelib file and all the interfaces
+    referenced within, whether defined entirely within the typelib or
+    merely referenced by name or IID.
+
+    Typelib objects may be instantiated directly and populated with data,
+    or the static Typelib.read method may be called to read one from a file.
+
+    """
+    _header = struct.Struct(">16sBBHIII")
+
+    def __init__(self, version=TYPELIB_VERSION, interfaces=[], annotations=[]):
+        """
+        Instantiate a new Typelib.
+
+        """
+        self.version = version
+        self.interfaces = list(interfaces)
+        self.annotations = list(annotations)
+
+    @staticmethod
+    def iid_to_string(iid):
+        """
+        Convert a 16-byte IID into a UUID string.
+
+        """
+        def hexify(s):
+            return ''.join(["%02x" % ord(x) for x in s])
+        return "%s-%s-%s-%s-%s" % (hexify(iid[:4]), hexify(iid[4:6]),
+                                   hexify(iid[6:8]), hexify(iid[8:10]),
+                                   hexify(iid[10:]))
+
+    @staticmethod
+    def string_to_iid(iid_str):
+        """
+        Convert a UUID string into a 16-byte IID.
+
+        """
+        s = iid_str.replace('-','')
+        return ''.join([chr(int(s[i:i+2], 16)) for i in range(0, len(s), 2)])
+    
+    @staticmethod
+    def read_string(map, data_pool, offset):
+        if offset == 0:
+            return ""
+        sz = map.find('\x00', data_pool + offset - 1)
+        if sz == -1:
+            return ""
+        return map[data_pool + offset - 1:sz]
+    
+    @staticmethod
+    def read(filename):
+        """
+        Read a typelib from the file named |filename| and return
+        the constructed Typelib object.
+
+        """
+        with open(filename, "r+b") as f:
+            st = os.fstat(f.fileno())
+            map = mmap.mmap(f.fileno(), st.st_size)
+            data = Typelib._header.unpack(map[:Typelib._header.size])
+            if data[0] != XPT_MAGIC:
+                raise FileFormatError, "Bad magic: %s" % data[0]
+            xpt = Typelib((data[1], data[2]))
+            num_interfaces = data[3]
+            file_length = data[4]
+            if file_length != st.st_size:
+                raise FileFormatError, "File is of wrong length, got %d bytes, expected %d" % (st.st_size, file_length)
+            #XXX: by spec this is a zero-based file offset. however,
+            # the xpt_xdr code always subtracts 1 from data offsets
+            # (because that's what you do in the data pool) so it
+            # winds up accidentally treating this as 1-based.
+            # Filed as: https://bugzilla.mozilla.org/show_bug.cgi?id=575343
+            interface_directory_offset = data[5] - 1
+            data_pool_offset = data[6]
+            # make a half-hearted attempt to read Annotations,
+            # since XPIDL doesn't produce any anyway.
+            start = Typelib._header.size
+            (anno, ) = struct.unpack(">B", map[start:start + struct.calcsize(">B")])
+            islast = anno & 0x80
+            tag = anno & 0x7F
+            if tag == 0: # EmptyAnnotation
+                xpt.annotations.append(None)
+            # We don't bother handling PrivateAnnotations or anything
+            
+            for i in range(num_interfaces):
+                # iid, name, namespace, interface_descriptor
+                start = interface_directory_offset + i * Interface._direntry.size
+                end = interface_directory_offset + (i+1) * Interface._direntry.size
+                ide = Interface._direntry.unpack(map[start:end])
+                iid = Typelib.iid_to_string(ide[0])
+                name = Typelib.read_string(map, data_pool_offset, ide[1])
+                namespace = Typelib.read_string(map, data_pool_offset, ide[2])
+                iface = Interface(name, iid, namespace)
+                iface._descriptor_offset = ide[3]
+                xpt.interfaces.append(iface)
+            for iface in xpt.interfaces:
+                iface.read_descriptor(xpt, map, data_pool_offset)
+            map.close()
+        return xpt
+    
+    def __repr__(self):
+        return "" % len(self.interfaces)
+
+    def _sanityCheck(self):
+        """
+        Check certain assumptions about data contained in this typelib.
+        Sort the interfaces array by IID, check that all interfaces
+        referenced by methods exist in the array.
+
+        """
+        self.interfaces.sort()
+        for i in self.interfaces:
+            if i.parent and i.parent not in self.interfaces:
+                raise DataError, "Interface %s has parent %s not present in typelib!" % (i.name, i.parent.name)
+            for m in i.methods:
+                for n, p in enumerate(m.params):
+                    if isinstance(p, InterfaceType) and \
+                        p.iface not in self.interfaces:
+                        raise DataError, "Interface method %s::%s, parameter %d references interface %s not present in typelib!" % (i.name, m.name, n, p.iface.name)
+                if isinstance(m.result, InterfaceType) and m.result.iface not in self.interfaces:
+                    raise DataError, "Interface method %s::%s, result references interface %s not present in typelib!" % (i.name, m.name, m.result.iface.name)
+
+    def write(self, filename):
+        """
+        Write the contents of this typelib to the file named |filename|.
+
+        """
+        self._sanityCheck()
+        with open(filename, "wb") as f:
+            # write out space for a header + one empty annotation,
+            # padded to 4-byte alignment.
+            headersize = (Typelib._header.size + 1)
+            if headersize % 4:
+                headersize += 4 - headersize % 4
+            f.write("\x00" * headersize)
+            # save this offset, it's the interface directory offset.
+            interface_directory_offset = f.tell()
+            # write out space for an interface directory
+            f.write("\x00" * Interface._direntry.size * len(self.interfaces))
+            # save this offset, it's the data pool offset.
+            data_pool_offset = f.tell()
+            # write out all the interface descriptors to the data pool
+            for i in self.interfaces:
+                i.write_names(f, data_pool_offset)
+                i.write(self, f, data_pool_offset)
+            # now, seek back and write the header
+            file_len = f.tell()
+            f.seek(0)
+            f.write(Typelib._header.pack(XPT_MAGIC,
+                                         TYPELIB_VERSION[0],
+                                         TYPELIB_VERSION[1],
+                                         len(self.interfaces),
+                                         file_len,
+                                         interface_directory_offset,
+                                         data_pool_offset))
+            # write an empty annotation
+            f.write(struct.pack(">B", 0x80))
+            # now write the interface directory
+            #XXX: bug-compatible with existing xpt lib, put it one byte
+            # ahead of where it's supposed to be.
+            f.seek(interface_directory_offset - 1)
+            for i in self.interfaces:
+                i.write_directory_entry(f)
+
+    def merge(self, other):
+        """
+        Merge the contents of Typelib |other| into this typelib.
+
+        """
+        # This will be a list of (replaced interface, replaced with)
+        # containing interfaces that were replaced with interfaces from
+        # another typelib, and the interface that replaced them.
+        merged_interfaces = []
+        for i in other.interfaces:
+            if i in self.interfaces:
+                continue
+            # See if there's a copy of this interface with different
+            # resolved status or IID value.
+            merged = False
+            for j in self.interfaces:
+                if i.name == j.name:
+                    if i.resolved != j.resolved:
+                        # prefer resolved interfaces over unresolved
+                        if j.resolved:
+                            # keep j
+                            merged_interfaces.append((i, j))
+                            merged = True
+                            # Fixup will happen after processing all interfaces.
+                        else:
+                            # replace j with i
+                            merged_interfaces.append((j, i))
+                            merged = True
+                            self.interfaces[self.interfaces.index(j)] = i
+                    elif i.iid != j.iid:
+                        # Prefer unresolved interfaces with valid IIDs
+                        if j.iid == Interface.UNRESOLVED_IID:
+                            # replace j with i
+                            merged_interfaces.append((j, i))
+                            merged = True
+                            self.interfaces[self.interfaces.index(j)] = i
+                        elif i.iid == Interface.UNRESOLVED_IID:
+                            # keep j
+                            merged_interfaces.append((i, j))
+                            merged = True
+                            # Fixup will happen after processing all interfaces.
+                        else:
+                            # Same name, different IIDs, raise an exception
+                            raise DataError, \
+                                  "Typelibs contain definitions of interface %s"\
+                                  " with different IIDs!" % i.name
+                elif i.iid == j.iid and i.iid != Interface.UNRESOLVED_IID:
+                    # Same IID, different names, raise an exception
+                    raise DataError, \
+                          "Typelibs contain definitions of interface %s"\
+                          " with different names (%s vs. %s)!" %  \
+                          (i.iid, i.name, j.name)
+            if not merged:
+                # No partially matching interfaces, so just take this interface
+                self.interfaces.append(i)
+        # Now fixup any merged interfaces
+        def checkType(t, replaced_from, replaced_to):
+            if isinstance(t, InterfaceType) and t.iface == replaced_from:
+                t.iface = replaced_to
+            elif isinstance(t, ArrayType) and \
+                 isinstance(t.element_type, InterfaceType) and \
+                 t.element_type.iface == replaced_from:
+                t.element_type.iface = replaced_to
+        
+        for replaced_from, replaced_to in merged_interfaces:
+            for i in self.interfaces:
+                # Replace parent references
+                if i.parent is not None and i.parent == replaced_from:
+                    i.parent = replaced_to
+                for m in i.methods:
+                    # Replace InterfaceType params and return values
+                    checkType(m.result.type, replaced_from, replaced_to)
+                    for p in m.params:
+                        checkType(p.type, replaced_from, replaced_to)
+        self._sanityCheck()
+        #TODO: do we care about annotations? probably not
+
+    def dump(self, out):
+        """
+        Print a human-readable listing of the contents of this typelib
+        to |out|, in the format of xpt_dump.
+        
+        """
+        out.write("""Header:
+   Major version:         %d
+   Minor version:         %d
+   Number of interfaces:  %d
+   Annotations:\n""" % (self.version[0], self.version[1], len(self.interfaces)))
+        for i, a in enumerate(self.annotations):
+            if a is None:
+                out.write("      Annotation #%d is empty.\n" % i)
+        out.write("\nInterface Directory:\n")
+        for i in self.interfaces:
+            out.write("   - %s::%s (%s):\n" % (i.namespace, i.name, i.iid))
+            if not i.resolved:
+                out.write("      [Unresolved]\n")
+            else:
+                if i.parent:
+                    out.write("      Parent: %s::%s\n" % (i.parent.namespace,
+                                                    i.parent.name))
+                out.write("""      Flags:
+         Scriptable: %s
+         Function: %s\n""" % (i.scriptable and "TRUE" or "FALSE",
+                              i.function and "TRUE" or "FALSE"))
+                out.write("      Methods:\n")
+                if len(i.methods) == 0:
+                    out.write("         No Methods\n")
+                else:
+                    for m in i.methods:
+                        out.write("   %s%s%s%s%s%s%s %s %s(%s);\n" % (
+                            m.getter and "G" or " ",
+                            m.setter and "S" or " ",
+                            m.hidden and "H" or " ",
+                            m.notxpcom and "N" or " ",
+                            m.constructor and "C" or " ",
+                            m.optargc and "O" or " ",
+                            m.implicit_jscontext and "J" or " ",
+                            str(m.result.type),
+                            m.name,
+                            m.params and ", ".join(str(p) for p in m.params) or ""
+                            ))
+                out.write("      Constants:\n")
+                if len(i.constants) == 0:
+                    out.write("         No Constants\n")
+                else:
+                    for c in i.constants:
+                        out.write("         %s %s = %d;\n" % (c.type, c.name, c.value))
+
+def xpt_dump(file):
+    """
+    Dump the contents of |file| to stdout in the format of xpt_dump.
+
+    """
+    t = Typelib.read(file)
+    t.dump(sys.stdout)
+
+def xpt_link(dest, inputs):
+    """
+    Link all of the xpt files in |inputs| together and write the
+    result ot |dest|.
+
+    """
+    if not inputs:
+        print >>sys.stderr, "Usage: xpt_link  "
+        return
+    t1 = Typelib.read(inputs[0])
+    for f in inputs[1:]:
+        t2 = Typelib.read(f)
+        t1.merge(t2)
+    t1.write(dest)
+
+if __name__ == '__main__':
+    if len(sys.argv) < 3:
+        print >>sys.stderr, "xpt  "
+        sys.exit(1)
+    if sys.argv[1] == 'dump':
+        xpt_dump(sys.argv[2])
+    elif sys.argv[1] == 'link':
+        xpt_link(sys.argv[2], sys.argv[3:])
diff --git a/xpcom/typelib/xpt/tools/xpt_dump.c b/xpcom/typelib/xpt/tools/xpt_dump.c
deleted file mode 100644
index 5b6a0ac57c59..000000000000
--- a/xpcom/typelib/xpt/tools/xpt_dump.c
+++ /dev/null
@@ -1,971 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * A utility for dumping the contents of a typelib file (.xpt) to screen 
- */ 
-
-#include "xpt_xdr.h"
-#include 
-#ifdef XP_OS2
-#include 
-#endif
-#include 
-#include 
-#include 
-#include "prprf.h"
-
-#ifdef WINCE
-#include 
-static void perror(const char* a) {}
-#endif
-
-#define BASE_INDENT 3
-
-static char *type_array[32] = 
-            {"int8",        "int16",       "int32",       "int64",
-             "uint8",       "uint16",      "uint32",      "uint64",
-             "float",       "double",      "boolean",     "char",
-             "wchar_t",     "void",        "nsIID",       "reserved",
-             "reserved",    "reserved",    "reserved",    "reserved",
-             "reserved",    "reserved",    "reserved",    "reserved",
-             "reserved",    "reserved",    "jsval",       "reserved",
-             "reserved",    "reserved",    "reserved",    "reserved"};
-
-static char *ptype_array[32] = 
-            {"int8 *",      "int16 *",     "int32 *",     "int64 *",
-             "uint8 *",     "uint16 *",    "uint32 *",    "uint64 *",
-             "float *",     "double *",    "boolean *",   "char *",
-             "wchar_t *",   "void *",      "nsIID *",     "DOMString *",
-             "string",      "wstring",     "Interface *", "InterfaceIs *",
-             "array",       "string_s",    "wstring_s",   "UTF8String *",
-             "CString *",   "AString *",   "jsval *",     "reserved",
-             "reserved",    "reserved",    "reserved",    "reserved"};
-
-static char *rtype_array[32] = 
-            {"int8 &",      "int16 &",     "int32 &",     "int64 &",
-             "uint8 &",     "uint16 &",    "uint32 &",    "uint64 &",
-             "float &",     "double &",    "boolean &",   "char &",
-             "wchar_t &",   "void &",      "nsIID &",     "DOMString &",
-             "string &",    "wstring &",   "Interface &", "InterfaceIs &",
-             "array &",     "string_s &",  "wstring_s &", "UTF8String &",
-             "CString &",   "AString &",   "jsval &",     "reserved",
-             "reserved",    "reserved",    "reserved",    "reserved"};
-
-PRBool param_problems = PR_FALSE;
-
-PRBool
-XPT_DumpHeader(XPTCursor *cursor, XPTHeader *header, 
-               const int indent, PRBool verbose_mode);
-
-PRBool
-XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode);
-
-PRBool
-XPT_DumpInterfaceDirectoryEntry(XPTCursor *cursor,
-                                XPTInterfaceDirectoryEntry *ide, 
-                                XPTHeader *header, const int indent,
-                                PRBool verbose_mode);
-
-PRBool
-XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id, 
-                            XPTHeader *header, const int indent,
-                            PRBool verbose_mode);
-
-PRBool
-XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
-                         XPTInterfaceDescriptor *id,
-                         const int indent, PRBool verbose_mode);
-PRBool
-XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td,
-                     XPTInterfaceDescriptor *id,
-                     char **type_string);
-
-PRBool
-XPT_DumpXPTString(XPTString *str);
-
-PRBool
-XPT_DumpParamDescriptor(XPTHeader *header, XPTParamDescriptor *pd,
-                        XPTInterfaceDescriptor *id,
-                        const int indent, PRBool verbose_mode,
-                        PRBool is_result);
-
-PRBool
-XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, 
-                       XPTInterfaceDescriptor *id,
-                       int indent, PRBool verbose_mode);
-
-PRBool
-XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd,
-                        XPTInterfaceDescriptor *id,
-                        const int indent, PRBool verbose_mode);
-
-static void
-xpt_dump_usage(char *argv[]) {
-    fprintf(stdout, "Usage: %s [-v] \n"
-            "       -v verbose mode\n", argv[0]);
-}
-
-static size_t get_file_length(const char* filename)
-{
-#ifndef WINCE
-    struct stat file_stat;
-    if (stat(filename, &file_stat) != 0) {
-        perror("FAILED: get_file_length");
-        exit(1);
-    }
-    return file_stat.st_size;
-#else
-    DWORD fileSize;
-    HANDLE hFile = CreateFile(filename, 
-                              GENERIC_READ,
-                              0, 
-                              NULL,
-                              OPEN_EXISTING, 
-                              FILE_ATTRIBUTE_NORMAL, 
-                              NULL);
-    if (hFile == INVALID_HANDLE_VALUE)
-        return -1;
-    fileSize = GetFileSize(hFile,  NULL);
-    CloseHandle(hFile);
-    return fileSize;
-#endif
-}
-
-int 
-main(int argc, char **argv)
-{
-    PRBool verbose_mode = PR_FALSE;
-    XPTArena *arena;
-    XPTState *state;
-    XPTCursor curs, *cursor = &curs;
-    XPTHeader *header;
-    size_t flen;
-    char *name;
-    char *whole;
-    FILE *in;
-    int result = 1;
-
-    switch (argc) {
-    case 2:
-        if (argv[1][0] == '-') {
-            xpt_dump_usage(argv);
-            return 1;
-        }
-        name = argv[1];
-        flen = get_file_length(name);
-        in = fopen(name, "rb");
-        break;
-    case 3:
-        verbose_mode = PR_TRUE;
-        if (argv[1][0] != '-' || argv[1][1] != 'v') {
-            xpt_dump_usage(argv);
-            return 1;
-        }
-        name = argv[2];
-        flen = get_file_length(name);
-        in = fopen(name, "rb");
-        break;
-    default:
-        xpt_dump_usage(argv);
-        return 1;
-    }
-
-    if (!in) {
-        perror("FAILED: fopen");
-        return 1;
-    }
-
-    arena = XPT_NewArena(1024, sizeof(double), "main xpt_dump arena");
-    if (!arena) {
-        perror("XPT_NewArena failed");
-        return 1;
-    }
-
-    /* after arena creation all exits via 'goto out' */
-
-    whole = XPT_MALLOC(arena, flen);
-    if (!whole) {
-        perror("FAILED: XPT_MALLOC for whole");
-        goto out;
-    }
-
-    if (flen > 0) {
-        size_t rv = fread(whole, 1, flen, in);
-        if (rv < flen) {
-            fprintf(stderr, "short read (%u vs %u)! ouch!\n",
-                    (unsigned int)rv, (unsigned int)flen);
-            goto out;
-        }
-        if (ferror(in) != 0 || fclose(in) != 0)
-            perror("FAILED: Unable to read typelib file.\n");
-
-        state = XPT_NewXDRState(XPT_DECODE, whole, flen);
-        if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) {
-            fprintf(stdout, "XPT_MakeCursor failed for %s\n", name);
-            goto out;
-        }
-        if (!XPT_DoHeader(arena, cursor, &header)) {
-            fprintf(stdout,
-                    "DoHeader failed for %s.  Is %s a valid .xpt file?\n",
-                    name, name);
-            goto out;
-        }
-
-        if (!XPT_DumpHeader(cursor, header, BASE_INDENT, verbose_mode)) {
-            perror("FAILED: XPT_DumpHeader");
-            goto out;
-        }
-   
-        if (param_problems) {
-            fprintf(stdout, "\nWARNING: ParamDescriptors are present with "
-                    "bad in/out/retval flag information.\n"
-                    "These have been marked with 'XXX'.\n"
-                    "Remember, retval params should always be marked as out!\n");
-        }
-
-        XPT_DestroyXDRState(state);
-        XPT_FREE(arena, whole);
-
-    } else {
-        fclose(in);
-        perror("FAILED: file length <= 0");
-        goto out;
-    }
-
-    result = 0;
-
-out:
-    XPT_DestroyArena(arena);
-    return result;
-}
-
-PRBool
-XPT_DumpHeader(XPTCursor *cursor, XPTHeader *header, 
-               const int indent, PRBool verbose_mode) 
-{
-    int i;
-    
-    fprintf(stdout, "Header:\n");
-
-    if (verbose_mode) {
-        fprintf(stdout, "%*sMagic beans:           ", indent, " ");
-        for (i=0; i<16; i++) {
-            fprintf(stdout, "%02x", header->magic[i]);
-        }
-        fprintf(stdout, "\n");
-        if (strncmp((const char*)header->magic, XPT_MAGIC, 16) == 0)
-            fprintf(stdout, "%*s                       PASSED\n", indent, " ");
-        else
-            fprintf(stdout, "%*s                       FAILED\n", indent, " ");
-    }
-    fprintf(stdout, "%*sMajor version:         %d\n", indent, " ",
-            header->major_version);
-    fprintf(stdout, "%*sMinor version:         %d\n", indent, " ",
-            header->minor_version);    
-    fprintf(stdout, "%*sNumber of interfaces:  %d\n", indent, " ",
-            header->num_interfaces);
-
-    if (verbose_mode) {
-        fprintf(stdout, "%*sFile length:           %d\n", indent, " ",
-                header->file_length);
-        fprintf(stdout, "%*sData pool offset:      %d\n\n", indent, " ",
-                header->data_pool);
-    }
-    
-    fprintf(stdout, "%*sAnnotations:\n", indent, " ");
-    if (!XPT_DumpAnnotations(header->annotations, indent*2, verbose_mode))
-        return PR_FALSE;
-
-    fprintf(stdout, "\nInterface Directory:\n");
-    for (i=0; inum_interfaces; i++) {
-        if (verbose_mode) {
-            fprintf(stdout, "%*sInterface #%d:\n", indent, " ", i);
-            if (!XPT_DumpInterfaceDirectoryEntry(cursor,
-                                                 &header->interface_directory[i],
-                                                 header, indent*2,
-                                                 verbose_mode)) {
-                return PR_FALSE;
-            }
-        } else {
-            if (!XPT_DumpInterfaceDirectoryEntry(cursor,
-                                                 &header->interface_directory[i],
-                                                 header, indent,
-                                                 verbose_mode)) {
-                return PR_FALSE;
-            }
-        }
-    }
-
-    return PR_TRUE;
-}    
-
-PRBool
-XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode) 
-{
-    int i = -1;
-    XPTAnnotation *last;
-    int new_indent = indent + BASE_INDENT;
-
-    do {
-        i++;
-        if (XPT_ANN_IS_PRIVATE(ann->flags)) {
-            if (verbose_mode) {
-                fprintf(stdout, "%*sAnnotation #%d is private.\n", 
-                        indent, " ", i);
-            } else {
-                fprintf(stdout, "%*sAnnotation #%d:\n", 
-                        indent, " ", i);
-            }                
-            fprintf(stdout, "%*sCreator:      ", new_indent, " ");
-            if (!XPT_DumpXPTString(ann->creator))
-                return PR_FALSE;
-            fprintf(stdout, "\n");
-            fprintf(stdout, "%*sPrivate Data: ", new_indent, " ");            
-            if (!XPT_DumpXPTString(ann->private_data))
-                return PR_FALSE;
-            fprintf(stdout, "\n");
-        } else {
-            fprintf(stdout, "%*sAnnotation #%d is empty.\n", 
-                    indent, " ", i);
-        }
-        last = ann;
-        ann = ann->next;
-    } while (!XPT_ANN_IS_LAST(last->flags));
-        
-    if (verbose_mode) {
-        fprintf(stdout, "%*sAnnotation #%d is the last annotation.\n", 
-                indent, " ", i);
-    }
-
-    return PR_TRUE;
-}
-
-static void
-print_IID(struct nsID *iid, FILE *file)
-{
-    fprintf(file, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-            (PRUint32) iid->m0, (PRUint32) iid->m1,(PRUint32) iid->m2,
-            (PRUint32) iid->m3[0], (PRUint32) iid->m3[1],
-            (PRUint32) iid->m3[2], (PRUint32) iid->m3[3],
-            (PRUint32) iid->m3[4], (PRUint32) iid->m3[5],
-            (PRUint32) iid->m3[6], (PRUint32) iid->m3[7]);
-            
-}
-
-PRBool
-XPT_DumpInterfaceDirectoryEntry(XPTCursor *cursor, 
-                                XPTInterfaceDirectoryEntry *ide, 
-                                XPTHeader *header, const int indent,
-                                PRBool verbose_mode)
-{
-    int new_indent = indent + BASE_INDENT;
-
-    if (verbose_mode) {
-        fprintf(stdout, "%*sIID:                             ", indent, " ");
-        print_IID(&ide->iid, stdout);
-        fprintf(stdout, "\n");
-        
-        fprintf(stdout, "%*sName:                            %s\n", 
-                indent, " ", ide->name);
-        fprintf(stdout, "%*sNamespace:                       %s\n", 
-                indent, " ", ide->name_space ? ide->name_space : "none");
-        fprintf(stdout, "%*sAddress of interface descriptor: %p\n", 
-                indent, " ", (void*)(ide->interface_descriptor));
-
-        fprintf(stdout, "%*sDescriptor:\n", indent, " ");
-    
-        if (!XPT_DumpInterfaceDescriptor(cursor, ide->interface_descriptor, 
-                                         header, new_indent, verbose_mode)) {
-            return PR_FALSE;
-        }
-    } else {
-        fprintf(stdout, "%*s- %s::%s (", indent, " ", 
-                ide->name_space ? ide->name_space : "", ide->name);
-        print_IID(&ide->iid, stdout);
-        fprintf(stdout, "):\n");
-        if (!XPT_DumpInterfaceDescriptor(cursor, ide->interface_descriptor, 
-                                         header, new_indent, verbose_mode)) {
-            return PR_FALSE;
-        }
-    }
-
-    return PR_TRUE;
-}    
-
-PRBool
-XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id,
-                            XPTHeader *header, const int indent,
-                            PRBool verbose_mode)
-{
-    XPTInterfaceDirectoryEntry *parent_ide;
-    int i;
-    int new_indent = indent + BASE_INDENT;
-    int more_indent = new_indent + BASE_INDENT;
-
-    if (!id) {
-        fprintf(stdout, "%*s[Unresolved]\n", indent, " ");
-        return PR_TRUE;
-    }
-
-    if (id->parent_interface) {
-
-        parent_ide = &header->interface_directory[id->parent_interface - 1];
-
-        fprintf(stdout, "%*sParent: %s::%s\n", indent, " ", 
-                parent_ide->name_space ? 
-                parent_ide->name_space : "", 
-                parent_ide->name);
-    }
-
-    fprintf(stdout, "%*sFlags:\n", indent, " ");
-
-    fprintf(stdout, "%*sScriptable: %s\n", new_indent, " ", 
-            XPT_ID_IS_SCRIPTABLE(id->flags) ? "TRUE" : "FALSE");
-
-    fprintf(stdout, "%*sFunction: %s\n", new_indent, " ", 
-            XPT_ID_IS_FUNCTION(id->flags) ? "TRUE" : "FALSE");
-
-    if (verbose_mode) {
-        if (id->parent_interface) {
-            fprintf(stdout, 
-                    "%*sIndex of parent interface (in data pool): %d\n", 
-                    indent, " ", id->parent_interface);
-            
-        }
-    } else {
-    }   
-
-    if (id->num_methods > 0) {
-        if (verbose_mode) {
-            fprintf(stdout, 
-                    "%*s# of Method Descriptors:                   %d\n", 
-                    indent, " ", id->num_methods);
-        } else {
-            fprintf(stdout, "%*sMethods:\n", indent, " ");
-        }
-
-        for (i=0; inum_methods; i++) {
-            if (verbose_mode) {
-                fprintf(stdout, "%*sMethod #%d:\n", new_indent, " ", i);
-                if (!XPT_DumpMethodDescriptor(header,
-                                              &id->method_descriptors[i], id,
-                                              more_indent, verbose_mode)) {
-                    return PR_FALSE;
-                } 
-            } else { 
-                if (!XPT_DumpMethodDescriptor(header,
-                                              &id->method_descriptors[i], id,
-                                              new_indent, verbose_mode)) {
-                    return PR_FALSE;
-                } 
-            }
-        }        
-    } else {
-        fprintf(stdout, "%*sMethods:\n", indent, " ");
-        fprintf(stdout, "%*sNo Methods\n", new_indent, " ");
-    }
-    
-    if (id->num_constants > 0) {
-        if (verbose_mode) {
-            fprintf(stdout, 
-                    "%*s# of Constant Descriptors:                  %d\n", 
-                    indent, " ", id->num_constants);
-        } else {
-            fprintf(stdout, "%*sConstants:\n", indent, " ");
-        }
-        
-        for (i=0; inum_constants; i++) {
-            if (verbose_mode) {
-                fprintf(stdout, "%*sConstant #%d:\n", new_indent, " ", i);
-                if (!XPT_DumpConstDescriptor(header, 
-                                             &id->const_descriptors[i], id,
-                                             more_indent, verbose_mode))
-                return PR_FALSE;
-            } else {
-                if (!XPT_DumpConstDescriptor(header, 
-                                             &id->const_descriptors[i], id,
-                                             new_indent, verbose_mode)) {
-                    return PR_FALSE;
-                }
-            }
-        }
-    } else { 
-        fprintf(stdout, "%*sConstants:\n", indent, " ");
-        fprintf(stdout, "%*sNo Constants\n", new_indent, " ");
-    }
-
-    return PR_TRUE;
-}
-
-PRBool
-XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
-                         XPTInterfaceDescriptor *id,
-                         const int indent, PRBool verbose_mode)
-{
-    int i;
-    int new_indent = indent + BASE_INDENT;
-    int more_indent = new_indent + BASE_INDENT;
-
-    if (verbose_mode) {
-        fprintf(stdout, "%*sName:             %s\n", indent, " ", md->name);
-        fprintf(stdout, "%*sIs Getter?        ", indent, " ");
-        if (XPT_MD_IS_GETTER(md->flags))
-            fprintf(stdout, "TRUE\n");
-        else 
-            fprintf(stdout, "FALSE\n");
-        
-        fprintf(stdout, "%*sIs Setter?        ", indent, " ");
-        if (XPT_MD_IS_SETTER(md->flags))
-            fprintf(stdout, "TRUE\n");
-        else 
-            fprintf(stdout, "FALSE\n");
-        
-        fprintf(stdout, "%*sIs NotXPCOM?      ", indent, " ");
-        if (XPT_MD_IS_NOTXPCOM(md->flags))
-            fprintf(stdout, "TRUE\n");
-        else 
-            fprintf(stdout, "FALSE\n");
-        
-        fprintf(stdout, "%*sIs Constructor?   ", indent, " ");
-        if (XPT_MD_IS_CTOR(md->flags))
-            fprintf(stdout, "TRUE\n");
-        else 
-            fprintf(stdout, "FALSE\n");
-        
-        fprintf(stdout, "%*sIs Hidden?        ", indent, " ");
-        if (XPT_MD_IS_HIDDEN(md->flags))
-            fprintf(stdout, "TRUE\n");
-        else 
-            fprintf(stdout, "FALSE\n");
-
-        fprintf(stdout, "%*sWants Optional Argc?        ", indent, " ");
-        if (XPT_MD_WANTS_OPT_ARGC(md->flags))
-            fprintf(stdout, "TRUE\n");
-        else 
-            fprintf(stdout, "FALSE\n");
-
-        fprintf(stdout, "%*sWants JSContext?        ", indent, " ");
-        if (XPT_MD_WANTS_CONTEXT(md->flags))
-            fprintf(stdout, "TRUE\n");
-        else 
-            fprintf(stdout, "FALSE\n");
-
-        fprintf(stdout, "%*s# of arguments:   %d\n", indent, " ", md->num_args);
-        fprintf(stdout, "%*sParameter Descriptors:\n", indent, " ");
-        
-        for (i=0; inum_args; i++) {
-            fprintf(stdout, "%*sParameter #%d:\n", new_indent, " ", i);
-            
-            if (!XPT_DumpParamDescriptor(header, &md->params[i], id, 
-                                         more_indent, verbose_mode, PR_FALSE))
-                return PR_FALSE;
-        }
-   
-        fprintf(stdout, "%*sResult:\n", indent, " ");
-        if (!XPT_DumpParamDescriptor(header, md->result, id, new_indent,
-                                     verbose_mode, PR_TRUE)) {
-            return PR_FALSE;
-        }
-    } else {
-        char *param_type;
-        XPTParamDescriptor *pd;
-
-        if (!XPT_GetStringForType(header, &md->result->type, id, ¶m_type)) {
-            return PR_FALSE;
-        }
-        fprintf(stdout, "%*s%c%c%c%c%c%c%c %s %s(", indent - 6, " ",
-                XPT_MD_IS_GETTER(md->flags) ? 'G' : ' ',
-                XPT_MD_IS_SETTER(md->flags) ? 'S' : ' ',
-                XPT_MD_IS_HIDDEN(md->flags) ? 'H' : ' ',
-                XPT_MD_IS_NOTXPCOM(md->flags) ? 'N' : ' ',
-                XPT_MD_IS_CTOR(md->flags) ? 'C' : ' ',
-                XPT_MD_WANTS_OPT_ARGC(md->flags) ? 'O' : ' ',
-                XPT_MD_WANTS_CONTEXT(md->flags) ? 'J' : ' ',
-                param_type, md->name);
-        for (i=0; inum_args; i++) {
-            if (i!=0) {
-                fprintf(stdout, ", ");
-            }
-            pd = &md->params[i];
-            if (XPT_PD_IS_IN(pd->flags)) {
-                fprintf(stdout, "in");
-                if (XPT_PD_IS_OUT(pd->flags)) {
-                    fprintf(stdout, "out ");
-                    if (XPT_PD_IS_RETVAL(pd->flags)) {
-                        fprintf(stdout, "retval ");
-                    }
-                    if (XPT_PD_IS_SHARED(pd->flags)) {
-                        fprintf(stdout, "shared ");
-                    }
-                } else {
-                    fprintf(stdout, " ");
-                    if (XPT_PD_IS_DIPPER(pd->flags)) {
-                        fprintf(stdout, "dipper ");
-                    }
-                    if (XPT_PD_IS_RETVAL(pd->flags)) {
-                        fprintf(stdout, "retval ");
-                    }
-                }
-                if (XPT_PD_IS_OPTIONAL(pd->flags)) {
-                    fprintf(stdout, "optional ");
-                }
-            } else {
-                if (XPT_PD_IS_OUT(pd->flags)) {
-                    fprintf(stdout, "out ");
-                    if (XPT_PD_IS_RETVAL(pd->flags)) {
-                        fprintf(stdout, "retval ");
-                    }
-                    if (XPT_PD_IS_SHARED(pd->flags)) {
-                        fprintf(stdout, "shared ");
-                    }
-                    if (XPT_PD_IS_OPTIONAL(pd->flags)) {
-                        fprintf(stdout, "optional ");
-                    }
-                } else {
-                    param_problems = PR_TRUE;
-                    fprintf(stdout, "XXX ");
-                }
-            }
-            if (!XPT_GetStringForType(header, &pd->type, id, ¶m_type)) {
-                return PR_FALSE;
-            }
-            fprintf(stdout, "%s", param_type);
-        }
-        fprintf(stdout, ");\n");   
-    }
-    return PR_TRUE;
-}
-    
-PRBool
-XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td,
-                     XPTInterfaceDescriptor *id,
-                     char **type_string)
-{
-    static char buf[128]; /* ugly non-reentrant use of static buffer! */
-    PRBool isArray = PR_FALSE;
-
-    int tag = XPT_TDP_TAG(td->prefix);
-    
-    if (tag == TD_ARRAY) {
-        isArray = PR_TRUE;
-        td = &id->additional_types[td->type.additional_type];
-        tag = XPT_TDP_TAG(td->prefix);
-    }
-    
-    if (tag == TD_INTERFACE_TYPE) {
-        int idx = td->type.iface;
-        if (!idx || idx > header->num_interfaces)
-            *type_string = "UNKNOWN_INTERFACE";
-        else
-            *type_string = header->interface_directory[idx-1].name;
-    } else if (XPT_TDP_IS_POINTER(td->prefix.flags)) {
-        if (XPT_TDP_IS_REFERENCE(td->prefix.flags))
-            *type_string = rtype_array[tag];
-        else
-            *type_string = ptype_array[tag];
-    } else {
-        *type_string = type_array[tag];
-    }
-
-    if(isArray) {
-        sprintf(buf, "%s []", *type_string);
-        *type_string = buf;
-    }
-
-    return PR_TRUE;
-}
-
-PRBool
-XPT_DumpXPTString(XPTString *str)
-{
-    int i;
-    for (i=0; ilength; i++) {
-        fprintf(stdout, "%c", str->bytes[i]);
-    }
-    return PR_TRUE;
-}
-
-PRBool
-XPT_DumpParamDescriptor(XPTHeader *header, XPTParamDescriptor *pd,
-                        XPTInterfaceDescriptor *id,
-                        const int indent, PRBool verbose_mode, 
-                        PRBool is_result)
-{
-    int new_indent = indent + BASE_INDENT;
-    
-    if (!XPT_PD_IS_IN(pd->flags) && 
-        !XPT_PD_IS_OUT(pd->flags) &&
-        (XPT_PD_IS_RETVAL(pd->flags) ||
-         XPT_PD_IS_SHARED(pd->flags))) {
-        param_problems = PR_TRUE;
-        fprintf(stdout, "XXX\n");
-    } else {
-        if (!XPT_PD_IS_IN(pd->flags) && !XPT_PD_IS_OUT(pd->flags)) {
-            if (is_result) {
-                if (XPT_TDP_TAG(pd->type.prefix) != TD_UINT32 &&
-                    XPT_TDP_TAG(pd->type.prefix) != TD_VOID) {
-                    param_problems = PR_TRUE;
-                    fprintf(stdout, "XXX\n");   
-                }
-            } else {
-                param_problems = PR_TRUE;
-                fprintf(stdout, "XXX\n");
-            }
-        }
-    }
-
-    fprintf(stdout, "%*sIn Param?   ", indent, " ");
-    if (XPT_PD_IS_IN(pd->flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-    
-    fprintf(stdout, "%*sOut Param?  ", indent, " ");
-    if (XPT_PD_IS_OUT(pd->flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-    
-    fprintf(stdout, "%*sRetval?     ", indent, " ");
-    if (XPT_PD_IS_RETVAL(pd->flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-
-    fprintf(stdout, "%*sShared?     ", indent, " ");
-    if (XPT_PD_IS_SHARED(pd->flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-
-    fprintf(stdout, "%*sDipper?     ", indent, " ");
-    if (XPT_PD_IS_DIPPER(pd->flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-
-    fprintf(stdout, "%*sOptional?     ", indent, " ");
-    if (XPT_PD_IS_OPTIONAL(pd->flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-
-
-    fprintf(stdout, "%*sType Descriptor:\n", indent, " ");
-    if (!XPT_DumpTypeDescriptor(&pd->type, id, new_indent, verbose_mode))
-        return PR_FALSE;
-    
-    return PR_TRUE;
-}
-
-PRBool
-XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, 
-                       XPTInterfaceDescriptor *id,
-                       int indent, PRBool verbose_mode)
-{
-    int new_indent;
-
-    if (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
-        fprintf(stdout, "%*sArray (size in arg %d and length in arg %d) of...\n", 
-            indent, " ", td->argnum, td->argnum2);
-        td = &id->additional_types[td->type.additional_type];
-        indent += BASE_INDENT;
-    }
-
-    new_indent = indent + BASE_INDENT;
-
-    fprintf(stdout, "%*sIs Pointer?        ", indent, " ");
-    if (XPT_TDP_IS_POINTER(td->prefix.flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-
-    fprintf(stdout, "%*sIs Unique Pointer? ", indent, " ");
-    if (XPT_TDP_IS_UNIQUE_POINTER(td->prefix.flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-
-    fprintf(stdout, "%*sIs Reference?      ", indent, " ");
-    if (XPT_TDP_IS_REFERENCE(td->prefix.flags))
-        fprintf(stdout, "TRUE\n");
-    else 
-        fprintf(stdout, "FALSE\n");
-
-    fprintf(stdout, "%*sTag:               %d\n", indent, " ", 
-            XPT_TDP_TAG(td->prefix));
-    
-    if (XPT_TDP_TAG(td->prefix) == TD_PSTRING_SIZE_IS ||
-        XPT_TDP_TAG(td->prefix) == TD_PWSTRING_SIZE_IS) {
-        fprintf(stdout, "%*s - size in arg %d and length in arg %d\n", 
-            indent, " ", td->argnum, td->argnum2);
-    }
-
-    if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
-        fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " "); 
-        fprintf(stdout, "%*sIndex of IDE:             %d\n", new_indent, " ", 
-                td->type.iface);
-    }
-
-    if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE) {
-        fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " "); 
-        fprintf(stdout, "%*sIndex of Method Argument: %d\n", new_indent, " ", 
-                td->argnum);        
-    }
-
-    return PR_TRUE;
-}
-
-PRBool
-XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd,
-                        XPTInterfaceDescriptor *id,
-                        const int indent, PRBool verbose_mode)
-{
-    int new_indent = indent + BASE_INDENT;
-    char *const_type;
-/*      char *out; */
-    PRUint32 uintout;
-    PRInt32 intout;
-
-    if (verbose_mode) {
-        fprintf(stdout, "%*sName:   %s\n", indent, " ", cd->name);
-        fprintf(stdout, "%*sType Descriptor: \n", indent, " ");
-        if (!XPT_DumpTypeDescriptor(&cd->type, id, new_indent, verbose_mode))
-            return PR_FALSE;
-        fprintf(stdout, "%*sValue:  ", indent, " ");
-    } else {
-        if (!XPT_GetStringForType(header, &cd->type, id, &const_type)) {
-            return PR_FALSE;
-        }
-        fprintf(stdout, "%*s%s %s = ", indent, " ", const_type, cd->name);
-    }        
-
-    switch(XPT_TDP_TAG(cd->type.prefix)) {
-    case TD_INT8:
-        fprintf(stdout, "%d", cd->value.i8);
-        break;
-    case TD_INT16:
-        fprintf(stdout, "%d", cd->value.i16);
-        break;
-    case TD_INT64:
-        /* XXX punt for now to remove NSPR linkage...
-         * borrow from mozilla/nsprpub/pr/src/io/prprf.c::cvt_ll? */
-
-/*          out = PR_smprintf("%lld", cd->value.i64); */
-/*          fputs(out, stdout); */
-/*          PR_smprintf_free(out); */
-        LL_L2I(intout, cd->value.i64);
-        fprintf(stdout, "%d", intout);
-        break;
-    case TD_INT32:
-        fprintf(stdout, "%d", cd->value.i32);
-        break;
-    case TD_UINT8:
-        fprintf(stdout, "%u", cd->value.ui8);
-        break;
-    case TD_UINT16:
-        fprintf(stdout, "%u", cd->value.ui16);
-        break;
-    case TD_UINT64:
-/*          out = PR_smprintf("%lld", cd->value.ui64); */
-/*          fputs(out, stdout); */
-/*          PR_smprintf_free(out); */
-        /* XXX punt for now to remove NSPR linkage. */
-        LL_L2UI(uintout, cd->value.ui64);
-        fprintf(stdout, "%u", uintout);
-        break;
-    case TD_UINT32:
-        fprintf(stdout, "%u", cd->value.ui32);
-        break;
-    case TD_FLOAT:
-        fprintf(stdout, "%f", cd->value.flt);
-        break;
-    case TD_DOUBLE:
-        fprintf(stdout, "%g", cd->value.dbl);
-        break;
-    case TD_BOOL:
-        if (cd->value.bul)
-            fprintf(stdout, "TRUE");
-        else 
-            fprintf(stdout, "FALSE");
-            break;
-    case TD_CHAR:
-        fprintf(stdout, "%c", cd->value.ch);
-        break;
-    case TD_WCHAR:
-        fprintf(stdout, "%c", cd->value.wch & 0xff);
-        break;
-    case TD_VOID:
-        fprintf(stdout, "VOID");
-        break;
-    case TD_PNSIID:
-        if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
-            print_IID(cd->value.iid, stdout);
-        } else 
-            return PR_FALSE;
-        break;
-    case TD_PSTRING:
-        if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
-            fprintf(stdout, "%s", cd->value.str);
-        } else 
-            return PR_FALSE;
-        break;
-    case TD_PWSTRING:
-        if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
-            PRUint16 *ch = cd->value.wstr;
-            while (*ch) {
-                fprintf(stdout, "%c", *ch & 0xff);
-                ch++;
-            }
-        } else 
-            return PR_FALSE;
-        break;
-    default:
-        perror("Unrecognized type");
-        return PR_FALSE;
-        break;   
-    }
-    
-    if (verbose_mode) {
-        fprintf(stdout, "\n");
-    } else {
-        fprintf(stdout, ";\n");
-    }
-
-    return PR_TRUE;
-}
diff --git a/xpcom/typelib/xpt/tools/xpt_link.c b/xpcom/typelib/xpt/tools/xpt_link.c
deleted file mode 100644
index 76bb903ff301..000000000000
--- a/xpcom/typelib/xpt/tools/xpt_link.c
+++ /dev/null
@@ -1,929 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * A utility for linking multiple typelib files. 
- */ 
-
-#include "xpt_xdr.h"
-#include 
-#include 
-#include 
-#include 
-#include "prlong.h"
-
-#ifdef WINCE
-#include "windows.h"
-static void perror(const char* a) {}
-#endif
-
-#ifndef NULL
-#define NULL (void *) 0
-#endif
-
-/* Forward declarations. */
-typedef struct fixElement fixElement;
-static int compare_IDEs_by_IID(const void *ap, const void *bp);
-static int compare_IDE_with_zero(const void *ap);
-static int compare_IDEs_by_name(const void *ap, const void *bp);
-static int compare_IDEs_by_name_space(const void *ap, const void *bp);
-static int compare_strings(const void *ap, const void *bp);
-static int compare_pointers(const void *ap, const void *bp);
-static int compare_fixElements_by_IID(const void *ap, const void *bp);
-static int compare_fixElements_by_name(const void *ap, const void *bp);
-static int compare_IIDs(const void *ap, const void *bp);
-PRBool shrink_IDE_array(XPTInterfaceDirectoryEntry *ide, 
-                        int element_to_delete, int num_interfaces);
-PRBool update_fix_array(XPTArena *arena, fixElement *fix, int element_to_delete, 
-                        int num_interfaces, int replacement); 
-static int get_new_index(const fixElement *fix, int num_elements,
-                         int target_file, int target_interface);
-PRBool copy_IDE(XPTInterfaceDirectoryEntry *from, 
-                XPTInterfaceDirectoryEntry *to);
-PRBool copy_fixElement(fixElement *from, fixElement *to);
-static void print_IID(struct nsID *iid, FILE *file);
-static void xpt_link_usage(char *argv[]);
-
-struct fixElement {
-    nsID iid;
-    char* name;
-    int file_num;
-    int interface_num;
-    PRBool is_deleted;
-    /* These next two variables will point you to the substitute interface
-     * if this one has been deleted.
-     */
-    int maps_to_file_num;
-    int maps_to_interface_num;
-};
-
-/* Global variables. */
-PRUint16 trueNumberOfInterfaces = 0;
-PRUint16 totalNumberOfInterfaces = 0;
-PRUint16 oldTotalNumberOfInterfaces = 0;
-
-/* The following globals are explained in xpt_struct.h */
-PRUint8 major_version     = XPT_MAJOR_VERSION;
-PRUint8 minor_version     = XPT_MINOR_VERSION;
-
-static size_t get_file_length(const char* filename)
-{
-#ifndef WINCE
-    struct stat file_stat;
-    if (stat(filename, &file_stat) != 0) {
-        perror("FAILED: get_file_length");
-        exit(1);
-    }
-    return file_stat.st_size;
-#else
-    DWORD fileSize;
-    HANDLE hFile = CreateFile(filename, 
-                              GENERIC_READ,
-                              0, 
-                              NULL,
-                              OPEN_EXISTING, 
-                              FILE_ATTRIBUTE_NORMAL, 
-                              NULL);
-    if (hFile == INVALID_HANDLE_VALUE)
-        return -1;
-    fileSize = GetFileSize(hFile,  NULL);
-    CloseHandle(hFile);
-    return fileSize;
-#endif
-}
-
-int 
-main(int argc, char **argv)
-{
-    #ifdef XP_OS2   /* Shell does not expand wildcards on OS/2, doesn't work with OW */
-    _wildcard (&argc, &argv);
-    #endif
-
-    XPTArena *arena;
-    XPTState *state;
-    XPTCursor curs, *cursor = &curs;
-    XPTHeader *header;
-    XPTInterfaceDirectoryEntry *IDE_array = NULL;
-    XPTInterfaceDescriptor *id;
-    XPTTypeDescriptor *td;
-    XPTAnnotation *ann, *first_ann;
-    PRUint32 header_sz, len;
-    PRUint32 oldOffset;
-    PRUint32 newOffset;
-    size_t flen = 0;
-    char *head, *data, *whole;
-    const char *outFileName;
-    FILE *in, *out;
-    fixElement *fix_array = NULL;
-    int i,j;
-    int k = 0;
-
-    if (argc < 3) {
-        xpt_link_usage(argv);
-        return 1;
-    }
-        
-    arena = XPT_NewArena(1024 * 10, sizeof(double), "main xpt_link arena");
-    if (!arena) {
-        perror("FAILED: XPT_NewArena");
-        return 1;
-    }
-
-    first_ann = XPT_NewAnnotation(arena, XPT_ANN_LAST, NULL, NULL);
-
-    /* Check if the "-t version numnber" cmd line arg is present */
-    i = 1;
-    if (argv[i][0] == '-' && argv[i][1] == 't') {
-        /* Parse for "-t version number" */
-
-        /* If -t is the last argument on the command line, we have a problem */
-        if (i + 1 == argc) {
-            fprintf(stderr, "ERROR: missing version number after -t\n");
-            xpt_link_usage(argv);
-            return 1;
-        }
-
-        /*
-         * Assume that the argument after "-t" is the version number string
-         * and search for it in our internal list of acceptable version
-         * numbers.
-         */
-
-        switch (XPT_ParseVersionString(argv[++i], &major_version, 
-                                       &minor_version)) {
-          case XPT_VERSION_CURRENT:            
-          case XPT_VERSION_OLD: 
-            break; 
-          case XPT_VERSION_UNSUPPORTED: 
-            fprintf(stderr, "ERROR: version \"%s\" not supported.\n", 
-                    argv[i]);
-            xpt_link_usage(argv);
-            return 1;          
-          case XPT_VERSION_UNKNOWN: 
-          default:
-            fprintf(stderr, "ERROR: version \"%s\" not recognised.\n", 
-                    argv[i]);
-            xpt_link_usage(argv);
-            return 1;          
-        }
-            
-        /* Hang onto the output file name. It's needed later. */
-        outFileName = argv[++i];
-
-        /* Increment i to the cmd line arg after outFileName */
-        i++;
-    }
-    else {        
-        outFileName = argv[1];
-        i = 2;
-    }
-
-    for ( /* use i from earlier */ ; i < argc; i++) {
-        char *name = argv[i];
-
-        flen = get_file_length(name);
-        if (!flen) {
-            fprintf(stderr, "ERROR: file %s is zero length\n", name);
-            return 1;
-        }
-
-        in = fopen(name, "rb");
-        if (!in) {
-            perror("FAILED: fopen");
-            return 1;
-        }
-
-        whole = XPT_MALLOC(arena, flen);
-        if (!whole) {
-            perror("FAILED: XPT_MALLOC for whole");
-            return 1;
-        }
-        
-        if (flen > 0) {
-            size_t rv = fread(whole, 1, flen, in);
-            if (rv < flen) {
-                fprintf(stderr, "short read (%u vs %u)! ouch!\n",
-                        (unsigned int)rv, (unsigned int)flen);
-                return 1;
-            }
-            if (ferror(in) != 0 || fclose(in) != 0) {
-                perror("FAILED: Unable to read typelib file.\n");
-                return 1;
-            }
-            
-            state = XPT_NewXDRState(XPT_DECODE, whole, flen);
-            if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) {
-                fprintf(stdout, "XPT_MakeCursor failed for %s\n", name);
-                return 1;
-            }
-            if (!XPT_DoHeader(arena, cursor, &header)) {
-                fprintf(stdout,
-                        "DoHeader failed for %s.  Is %s a valid .xpt file?\n",
-                        name, name);
-                return 1;
-            }
-            
-            /*
-             * Make sure that the version of the typelib file is less than or
-             * equal to the version specified in the -t cmd line arg.
-             */
-
-            if ((header->major_version > major_version ||
-                (header->major_version == major_version &&
-                 header->minor_version > minor_version))) { 
-                fprintf(stderr, "FAILED: %s's version, %d.%d, is newer than "
-                                "the version (%d.%d) specified in the -t "
-                                "command line argument.\n", 
-                                name, header->major_version, header->minor_version,
-                                major_version, minor_version);
-                return 1;
-            }
-            
-            oldTotalNumberOfInterfaces = totalNumberOfInterfaces;
-            totalNumberOfInterfaces += header->num_interfaces;
-            if (header->num_interfaces > 0) {
-                XPTInterfaceDirectoryEntry *newIDE;
-                fixElement *newFix;
-  
-                newIDE = (XPTInterfaceDirectoryEntry *)
-                    XPT_MALLOC(arena, totalNumberOfInterfaces * 
-                               sizeof(XPTInterfaceDirectoryEntry));
-                if (!newIDE) {
-                    perror("FAILED: XPT_MALLOC of IDE_array");
-                    return 1;
-                }
-
-                if (IDE_array) {
-                    if (oldTotalNumberOfInterfaces)
-                        memcpy(newIDE, IDE_array,
-                               oldTotalNumberOfInterfaces * 
-                               sizeof(XPTInterfaceDirectoryEntry));
-                    XPT_FREE(arena, IDE_array);
-                }
-                IDE_array = newIDE;
-
-
-                newFix = (fixElement *)
-                    XPT_MALLOC(arena, 
-                               totalNumberOfInterfaces * sizeof(fixElement));
-                if (!newFix) {
-                    perror("FAILED: XPT_MALLOC of fix_array");
-                    return 1;
-                }
-
-                if (fix_array) {
-                    if (oldTotalNumberOfInterfaces)
-                        memcpy(newFix, fix_array,
-                               oldTotalNumberOfInterfaces * 
-                               sizeof(fixElement));
-                    XPT_FREE(arena, fix_array);
-                }
-                fix_array = newFix;
-            
-                for (j=0; jnum_interfaces; j++) {
-                    if (!copy_IDE(&header->interface_directory[j], 
-                                  &IDE_array[k])) {
-                        perror("FAILED: 1st copying of IDE");
-                        return 1;
-                    }
-                    fix_array[k].iid = IDE_array[k].iid;
-                    fix_array[k].name = IDE_array[k].name;
-                    fix_array[k].file_num = i-2;
-                    fix_array[k].interface_num = j+1;
-                    fix_array[k].is_deleted = PR_FALSE;
-                    fix_array[k].maps_to_file_num = i-2;
-                    fix_array[k].maps_to_interface_num = j+1;
-
-                    k++;
-                }
-            }
-            
-            /* Copy the annotations if they are not 'empty'
-             */
-            if (header->annotations != NULL &&
-                header->annotations->flags != XPT_ANN_LAST) {
-                ann = first_ann;
-                while (ann->next != NULL) {
-                    ann = ann->next;
-                }
-                ann->next = header->annotations;
-            }
-            
-            XPT_FREEIF(arena, header);
-            if (state)
-                XPT_DestroyXDRState(state);
-            XPT_FREE(arena, whole);
-            flen = 0;            
-
-        } else {
-            fclose(in);
-            perror("FAILED: file length <= 0");
-            return 1;
-        }
-    }
-
-    /* Make sure the last annotation is the only one marked as XP_ANN_LAST.
-     */
-    ann = first_ann;
-    while (ann->next != NULL) {
-        ann->flags &= ~XPT_ANN_LAST;
-        ann = ann->next;
-    }    
-    ann->flags |= XPT_ANN_LAST;
-
-    /* Sort both IDE_array and fix_array by name so we can check for 
-     * name_space::name collisions. 
-     */
-    qsort(IDE_array, 
-          totalNumberOfInterfaces, 
-          sizeof(XPTInterfaceDirectoryEntry), 
-          compare_IDEs_by_name);
-
-    qsort(fix_array, 
-          totalNumberOfInterfaces, 
-          sizeof(fixElement), 
-          compare_fixElements_by_name);
-
-    /* trueNumberOfInterfaces == number of interfaces left after deletions
-     * are made. Initialize it here to be the same as the total number of
-     * interfaces we'ce encountered thus far.
-     */
-    trueNumberOfInterfaces = totalNumberOfInterfaces;
-
-    /* Iterate through the sorted interfaces. Start at one so we don't 
-     * accidentally walk off the end of the array.
-     */
-    i = 1;
-    while (i != trueNumberOfInterfaces) {
-        
-        /* Check for name_space::name collision. 
-         */
-        if (compare_strings(IDE_array[i-1].name, 
-                            IDE_array[i].name) == 0 && 
-            compare_strings(IDE_array[i-1].name_space, 
-                             IDE_array[i].name_space) == 0) {
-            int to_delete = -1;
-            /* If one of the interfaces is unresolved, delete that one 
-             * preferentially. If they're both unresolved, but one of
-             * them has an IID and the other IID is empty, then delete
-             * the one with the empty IID.
-             */
-            if (!IDE_array[i-1].interface_descriptor) {
-                if (!IDE_array[i].interface_descriptor) {
-                    /* both unresolved, see if one has a zero IID */
-                    if (compare_IDE_with_zero(&IDE_array[i])) {
-                        /* one or both is zero, doesn't really matter */
-                        to_delete = i;
-                    } else if (compare_IDE_with_zero(&IDE_array[i - 1])) {
-                        to_delete = i - 1;
-                    } else if(compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0) {
-                        /* they're the same, so just pick one */
-                        to_delete = i;
-                    } else {
-                        /*XXX: error, unresolved references with different IIDs? */
-                        char *ns = IDE_array[i].name_space;
-                        fprintf(stderr,
-                        "ERROR: found duplicate unresolved interfaces "
-                        "%s%s%s\n",
-                        ns ? ns : "", ns ? "::" : "", IDE_array[i].name);
-                        return 1;
-                    }
-                }
-                else {
-                    /* just i-1 is unresolved */
-                    to_delete = i - 1;
-                }
-            } else if (!IDE_array[i].interface_descriptor ||
-                       (compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0)) {
-                to_delete = i;
-            } else {
-                /* Found interfaces with duplicate names but different
-                 * iids! */
-                char *ns = IDE_array[i].name_space;
-                fprintf(stderr,
-                        "ERROR: found duplicate definitions of interface "
-                        "%s%s%s with iids \n",
-                        ns ? ns : "", ns ? "::" : "", IDE_array[i].name);
-                print_IID(&IDE_array[i].iid, stderr);
-                fprintf(stderr, " and ");
-                print_IID(&IDE_array[i-1].iid, stderr);
-                fprintf(stderr, "\n");
-                return 1;
-            }
-
-            if (to_delete == (i - 1)) {
-                /* Shrink the IDE_array to delete the duplicate interface.
-                 */
-                if (!shrink_IDE_array(IDE_array, 
-                                      i-1, 
-                                      trueNumberOfInterfaces)) {
-                    perror("FAILED: shrink_IDE_array");
-                    return 1;
-                }
-                /* Update the fix array. This involves moving the deleted 
-                 * entry to the end of the array (rather than deleting it)
-                 * and mapping it to the "replacement" element so we can
-                 * update interface indices appropriately later.
-                 */
-                update_fix_array(arena, fix_array, i-1, 
-                                 totalNumberOfInterfaces, i);
-                /* Decrement the true number of interfaces since we just
-                 * deleted one. There's more than one way to get out of
-                 * this loop.
-                 */
-                trueNumberOfInterfaces--;
-            } else if (to_delete == i) {
-                /* Shrink the IDE_array to delete the duplicate interface.
-                 */
-                if (!shrink_IDE_array(IDE_array, 
-                                      i, 
-                                      trueNumberOfInterfaces)) {
-                    perror("FAILED: shrink_IDE_array");
-                    return 1;
-                }
-                /* Update the fix array. This involves moving the deleted 
-                 * entry to the end of the array (rather than deleting it)
-                 * and mapping it to the "replacement" element so we can
-                 * update interface indices appropriately later.
-                 */
-                update_fix_array(arena, fix_array, i, 
-                                 totalNumberOfInterfaces, i-1);
-                /* Decrement the true number of interfaces since we just
-                 * deleted one. There's more than one way to get out of
-                 * this loop.
-                 */
-                trueNumberOfInterfaces--;
-            } else {
-                /* XXX: error! */
-                char *ns = IDE_array[i].name_space;
-                fprintf(stderr,
-                        "ERROR: duplicate interfaces, don't know what to do "
-                        "%s%s%s\n",
-                        ns ? ns : "", ns ? "::" : "", IDE_array[i].name);
-                return 1;
-            }
-        } else {
-            /* Only increment if there was no name_space::name collision.
-             */
-            i++;
-        }
-    }
-
-    /* Sort the IDE_array (put them in their final order) so that updating
-     * of indices will be meaningful.
-     */
-    qsort(IDE_array, 
-          trueNumberOfInterfaces, 
-          sizeof(XPTInterfaceDirectoryEntry), 
-          compare_IDEs_by_IID);
-
-    /* Sort the fix_array to match the IDE_array. 
-     */
-    qsort(fix_array, 
-          trueNumberOfInterfaces, 
-          sizeof(fixElement), 
-          compare_fixElements_by_IID);
-
-    /* Iterate through the remaining interfaces (those not deleted) 
-     * looking for references to interfaces (such as id->parent_interface)
-     * which need an updated index number.
-     */
-    for (i=0; iparent_interface && id->parent_interface != 0) {
-                id->parent_interface = 
-                    get_new_index(fix_array, totalNumberOfInterfaces,
-                                  fix_array[i].file_num, id->parent_interface);
-            }
-            /* Iterate through the method descriptors looking for params of
-             * type TD_INTERFACE_TYPE.
-             */
-            for (j=0; jnum_methods; j++) {
-                /* Cycle through the params first.
-                 */
-                for (k=0; kmethod_descriptors[j].num_args; k++) {
-                    /* Define td to save some keystrokes.
-                     */
-                    td = &id->method_descriptors[j].params[k].type;
-
-                    while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
-                        td = &id->additional_types[td->type.additional_type];
-                    }
-
-                    if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
-                        td->type.iface = 
-                            get_new_index(fix_array, 
-                                          totalNumberOfInterfaces,
-                                          fix_array[i].file_num, 
-                                          td->type.iface);
-                    }                                                
-                }
-
-                /* Check the result param too. Define td again to save 
-                 * some keystrokes.
-                 */
-                td = &id->method_descriptors[j].result->type;
-                if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
-                    td->type.iface = 
-                        get_new_index(fix_array, totalNumberOfInterfaces,
-                                      fix_array[i].file_num, 
-                                      td->type.iface);
-                }                
-            }
-        } 
-    }
-    
-    /* Iterate through the array quickly looking for duplicate IIDS.
-     * This shouldn't happen, i.e. is a failure condition, so bail
-     * if we find a duplicate. If we have more than one entry, start 
-     * at one so we don't accidentally grep the ether.
-     */
-    if (trueNumberOfInterfaces>1) {
-        for (i=1; iannotations = first_ann;
-    for (i=0; iinterface_directory[i])) {
-            perror("FAILED: 2nd copying of IDE");
-            return 1;
-        }
-    }
-    
-    header_sz = XPT_SizeOfHeaderBlock(header); 
-
-    state = XPT_NewXDRState(XPT_ENCODE, NULL, 0);
-    if (!state) {
-        perror("FAILED: error creating XDRState");
-        return 1;
-    }
-    
-    XPT_SetDataOffset(state, header_sz);
-
-    if (!XPT_MakeCursor(state, XPT_HEADER, header_sz, cursor)) {
-        perror("FAILED: error making cursor");
-        return 1;
-    }
-    oldOffset = cursor->offset;
-    if (!XPT_DoHeader(arena, cursor, &header)) {
-        perror("FAILED: error doing Header");
-        return 1;
-    }
-    newOffset = cursor->offset;
-    XPT_GetXDRDataLength(state, XPT_HEADER, &len);
-    header->file_length = len;
-    XPT_GetXDRDataLength(state, XPT_DATA, &len);
-    header->file_length += len;
-    XPT_SeekTo(cursor, oldOffset);
-    if (!XPT_DoHeaderPrologue(arena, cursor, &header, NULL)) {
-        perror("FAILED: error doing Header");
-        return 1;
-    }
-    XPT_SeekTo(cursor, newOffset);
-    out = fopen(outFileName, "wb");
-    if (!out) {
-        perror("FAILED: fopen");
-        return 1;
-    }
-
-    XPT_GetXDRData(state, XPT_HEADER, &head, &len);
-    fwrite(head, len, 1, out);
- 
-    XPT_GetXDRData(state, XPT_DATA, &data, &len);
-    fwrite(data, len, 1, out);
- 
-    if (ferror(out) != 0 || fclose(out) != 0) {
-        fprintf(stderr, "Error writing file: %s\n", argv[1]);
-    } else {
-/*        fprintf(stderr, "File written: %s\n", argv[1]); */
-    }
- 
-    if (state)
-        XPT_DestroyXDRState(state);
-    
-    XPT_DestroyArena(arena);
-
-    return 0;        
-}
-
-static int 
-compare_IDEs_by_IID(const void *ap,
-                    const void *bp)
-{
-    const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
-    
-    int answer = compare_IIDs(&ide1->iid, &ide2->iid);
-    if(!answer)
-        answer = compare_strings(ide1->name, ide2->name);
-
-    return answer;
-}  
-
-/* For detecting unresolved interfaces. */
-const nsID iid_zero = { 0x0, 0x0, 0x0,
-                        { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
-
-static int
-compare_IDE_with_zero(const void *ap)
-{
-    const XPTInterfaceDirectoryEntry *ide1 = ap;
-
-    return compare_IIDs(&ide1->iid, &iid_zero);
-}
-
-static int 
-compare_fixElements_by_IID(const void *ap,
-                           const void *bp)
-{
-    const fixElement *fix1 = ap, *fix2 = bp;
-    
-    int answer = compare_IIDs(&fix1->iid, &fix2->iid);
-    if(!answer)
-        answer = compare_strings(fix1->name, fix2->name);
-
-    return answer;
-}  
-
-static int 
-compare_IDEs_by_name(const void *ap,
-                     const void *bp)
-{
-    const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
-
-    int answer = compare_strings(ide1->name, ide2->name);
-    if(!answer)
-        answer = compare_pointers(ide1->name, ide2->name);
-
-    return answer;
-}
-
-static int 
-compare_IDEs_by_name_space(const void *ap,
-                           const void *bp)
-{
-    const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
-    
-    return compare_strings(ide1->name_space, ide2->name_space);
-}
-
-static int 
-compare_strings(const void *ap, const void *bp)
-{
-    const char *string1 = ap, *string2 = bp;
-
-    if (!string1 && !string2)
-        return 0;
-    if (!string1)
-        return -1;
-    if (!string2)
-        return 1;
-
-    return strcmp(string1, string2);    
-}     
-
-static int 
-compare_pointers(const void *ap, const void *bp)
-{
-    if (ap == bp) {
-#ifdef DEBUG_jband
-        perror("name addresses were equal!");
-#endif
-        return 0;
-    }
-    if (ap > bp)
-        return 1;
-    return -1;
-}        
-
-static int 
-compare_fixElements_by_name(const void *ap,
-                            const void *bp)
-{
-    const fixElement *fix1 = ap, *fix2 = bp;
-
-    int answer= compare_strings(fix1->name, fix2->name);
-    if(!answer)
-        answer = compare_pointers(fix1->name, fix2->name);
-
-    return answer;
-}
-
-static int
-compare_IIDs(const void *ap, const void *bp)
-{
-    const nsID *a = ap, *b = bp;
-    int i;
-#define COMPARE(field) if (a->field > b->field) return 1; \
-                       if (b->field > a->field) return -1;
-    COMPARE(m0);
-    COMPARE(m1);
-    COMPARE(m2);
-    for (i = 0; i < 8; i++) {
-        COMPARE(m3[i]);
-    }
-    return 0;
-#undef COMPARE
-}
-
-PRBool 
-shrink_IDE_array(XPTInterfaceDirectoryEntry *ide, int element_to_delete,
-                    int num_interfaces)
-{
-    int i;
-
-    if (element_to_delete >= num_interfaces) {
-        return PR_FALSE;
-    }
-
-    for (i=element_to_delete+1; i= num_interfaces) {
-        return PR_FALSE;
-    }
-
-    deleted = XPT_CALLOC(arena, sizeof(fixElement));
-    if (!copy_fixElement(&fix[element_to_delete], deleted)) {
-        return PR_FALSE;
-    }
-    deleted->is_deleted = PR_TRUE;
-    deleted->maps_to_file_num = fix[replacement].file_num;
-    deleted->maps_to_interface_num = fix[replacement].interface_num;
-    
-    for (i=element_to_delete+1; iiid = from->iid;
-    to->name = from->name;
-    to->name_space = from->name_space;
-    to->interface_descriptor = from->interface_descriptor;
-    return PR_TRUE;
-}
-
-PRBool
-copy_fixElement(fixElement *from, fixElement *to)
-{
-    if (!from || !to) {
-        return PR_FALSE;
-    }
-
-    to->iid = from->iid;
-    to->name = from->name;
-    to->file_num = from->file_num;
-    to->interface_num = from->interface_num;
-    to->is_deleted = from->is_deleted;
-    to->maps_to_file_num = from->maps_to_file_num;
-    to->maps_to_interface_num = from->maps_to_interface_num;
-
-    return PR_TRUE;    
-}
-
-static void
-print_IID(struct nsID *iid, FILE *file)
-{
-    fprintf(file, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-            (PRUint32) iid->m0, (PRUint32) iid->m1,(PRUint32) iid->m2,
-            (PRUint32) iid->m3[0], (PRUint32) iid->m3[1],
-            (PRUint32) iid->m3[2], (PRUint32) iid->m3[3],
-            (PRUint32) iid->m3[4], (PRUint32) iid->m3[5],
-            (PRUint32) iid->m3[6], (PRUint32) iid->m3[7]); 
-}
-
-static void
-xpt_link_usage(char *argv[]) 
-{
-    fprintf(stdout, "Usage: %s [-t version number] outfile file1.xpt file2.xpt ...\n"
-            "       Links multiple typelib files into one outfile\n"
-            "       -t create a typelib of an older version number\n", argv[0]);
-}
-