Compare commits

..

2 Commits

Author SHA1 Message Date
pavlov%netscape.com
c45c2db17b new shit
git-svn-id: svn://10.0.0.236/branches/IMGLIB2_NEW@91713 18797224-902f-48f8-a5cc-f745e15eee43
2001-04-08 23:55:33 +00:00
(no author)
ebc0074860 This commit was manufactured by cvs2svn to create branch 'IMGLIB2_NEW'.
git-svn-id: svn://10.0.0.236/branches/IMGLIB2_NEW@91429 18797224-902f-48f8-a5cc-f745e15eee43
2001-04-05 06:02:33 +00:00
126 changed files with 10309 additions and 5646 deletions

View File

@@ -1,19 +0,0 @@
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = \
base \
pgsql \
build
ifdef ENABLE_TESTS
DIRS += \
sqltest \
tests
endif
include $(topsrcdir)/config/rules.mk

View File

@@ -1,11 +0,0 @@
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DIRS = \
public \
src \
resources
include $(topsrcdir)/config/rules.mk

View File

@@ -1,19 +0,0 @@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = sql
XPIDLSRCS = \
mozISqlConnection.idl \
mozISqlRequest.idl \
mozISqlDataSource.idl \
mozISqlInputStream.idl \
mozISqlRequestObserver.idl \
mozISqlResult.idl \
mozISqlResultEnumerator.idl \
mozISqlService.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,124 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
interface mozISqlResult;
interface mozISqlRequest;
interface mozISqlRequestObserver;
/**
* @status UNDER_REVIEW
*/
[scriptable, uuid(f16397a4-1ecb-4e08-84f8-27750c04b779)]
interface mozISqlConnection : nsISupports
{
readonly attribute AString serverVersion;
/**
* The most recent error message.
*/
readonly attribute AString errorMessage;
/**
* The ID of the most recently added record.
*/
readonly attribute long lastID;
/**
* Set up the connection.
*
* @param aHost The host name.
* @param aPort The port at which the host is listening.
* @param aDatabase The real database name to connect to.
* @param aUsername The username to connect as.
* @param aPassword The password to use in authentification phase.
*/
void init(in AString aHost,
in long aPort,
in AString aDatabase,
in AString aUsername,
in AString aPassword);
/**
* Execute the query synchronously and return database result.
*
* @param aQuery The query to execute.
*/
mozISqlResult executeQuery(in AString aQuery);
/**
* Execute the update synchronously and return number of updated rows.
*
* @param aUpdate The update to execute.
*/
long executeUpdate(in AString aUpdate);
mozISqlRequest asyncExecuteQuery(in AString aQuery,
in nsISupports aContext,
in mozISqlRequestObserver aObserver);
mozISqlRequest asyncExecuteUpdate(in AString aQuery,
in nsISUpports aContext,
in mozISqlRequestObserver aObserver);
/**
* Begin transaction.
*/
void beginTransaction();
/**
* Commit transaction.
*/
void commitTransaction();
/**
* Rollback transaction.
*/
void rollbackTransaction();
/**
* Get primary keys.
*
* @param aSchema The schema.
* @param aTable The table name.
*/
mozISqlResult getPrimaryKeys(in AString aSchema, in AString aTable);
};

View File

@@ -1,65 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
interface nsIRDFResource;
/**
* @status UNDER_REVIEW
*/
[scriptable, uuid(3c0a954f-b595-46a4-932c-3660f55e2e10)]
interface mozISqlDataSource : nsISupports
{
/**
* Retrieve the RDF resource associated with the specified row.
*
* @param aRowIndex The row index.
*/
nsIRDFResource getResourceAtIndex(in long aRowIndex);
/**
* Retrieve the index associated with specified RDF resource.
*
* @param aResource The resource.
*/
long getIndexOfResource(in nsIRDFResource aResource);
};

View File

@@ -1,52 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
/**
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(555f2485-ba82-4c5c-9dd2-d801104dc09e)]
interface mozISqlInputStream : nsISupports
{
AString getColumnHeader(in long aColumnIndex);
void setColumnHeader(in long aColumnIndex, in AString aLabel);
};

View File

@@ -1,77 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
interface mozISqlConnection;
interface mozISqlRequestObserver;
interface mozISqlResult;
/**
* @status UNDER_REVIEW
*/
[scriptable, uuid(f67cb817-5e07-49ff-aacc-5c80585c5031)]
interface mozISqlRequest : nsISupports
{
readonly attribute AString errorMessage;
readonly attribute mozISqlResult result;
readonly attribute long affectedRows;
readonly attribute long lastID;
readonly attribute AString query;
readonly attribute nsISupports ctxt;
readonly attribute mozISqlRequestObserver observer;
const long STATUS_NONE = 0;
const long STATUS_EXECUTED = 1;
const long STATUS_COMPLETE = 2;
const long STATUS_ERROR = 3;
const long STATUS_CANCELLED = 4;
readonly attribute long status;
void cancel();
};

View File

@@ -1,56 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
interface mozISqlRequest;
/**
* @status UNDER_REVIEW
*/
[scriptable, uuid(9e950bc0-e252-41ef-ac6f-3e3c4acd9dd8)]
interface mozISqlRequestObserver : nsISupports
{
void onStartRequest(in mozISqlRequest aRequest,
in nsISupports aContext);
void onStopRequest(in mozISqlRequest aRequest,
in nsISupports aContext);
};

View File

@@ -1,87 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
interface mozISqlConnection;
interface mozISqlResultEnumerator;
interface mozISqlInputStream;
/**
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(08c220b0-7140-456a-89e9-c94609a7392d)]
interface mozISqlResult : nsISupports
{
readonly attribute mozISqlConnection connection;
readonly attribute AString query;
readonly attribute AString tableName;
readonly attribute long rowCount;
readonly attribute long columnCount;
AString getColumnName(in long aColumnIndex);
long getColumnIndex(in AString aColumnName);
const long TYPE_STRING = 1;
const long TYPE_INT = 2;
const long TYPE_FLOAT = 3;
const long TYPE_DECIMAL = 4;
const long TYPE_DATE = 5;
const long TYPE_TIME = 6;
const long TYPE_DATETIME = 7;
const long TYPE_BOOL = 8;
long getColumnType(in long aColumnIndex);
AString getColumnTypeAsString(in long aColumnIndex);
long getColumnDisplaySize(in long aColumnIndex);
mozISqlResultEnumerator enumerate();
mozISqlInputStream open();
void reload();
};

View File

@@ -1,126 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
interface nsIVariant;
/**
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(dcc0d29e-2b44-460e-b39f-89121ff8b963)]
interface mozISqlResultEnumerator : nsISupports
{
readonly attribute AString errorMessage;
boolean next();
boolean previous();
void beforeFirst();
void first();
void last();
void relative(in long aRows);
void absolute(in long aRowIndex);
boolean isNull(in long aColumnIndex);
nsIVariant getVariant(in long aColumnIndex);
AString getString(in long aColumnIndex);
long getInt(in long aColumnIndex);
float getFloat(in long aColumnIndex);
float getDecimal(in long aColumnIndex);
long long getDate(in long aColumnIndex);
boolean getBool(in long aColumnIndex);
void setNull(in long aColumnIndex);
void setDefault(in long aColumnIndex);
void copy(in long aColumnIndex);
void setVariant(in long aColumnIndex, in nsIVariant aValue);
void setString(in long aColumnIndex, in AString aValue);
void setInt(in long aColumnIndex, in long aValue);
void setFloat(in long aColumnIndex, in float aValue);
void setDecimal(in long aColumnIndex, in float aValue);
void setDate(in long aColumnIndex, in long long aValue);
void setBool(in long aColumnIndex, in boolean aValue);
void setNullValues();
void setDefaultValues();
void copyValues();
boolean canInsert();
boolean canUpdate();
boolean canDelete();
long insertRow();
long updateRow();
long deleteRow();
readonly attribute AString currentCondition;
};

View File

@@ -1,81 +0,0 @@
/* ***** 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) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <varga@utcru.sk>
*
* 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
* 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 ***** */
#include "nsISupports.idl"
interface mozISqlConnection;
/**
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(1ceb35b7-daa8-4ce4-ac67-125fb17cb019)]
interface mozISqlService : nsISupports
{
readonly attribute AString errorMessage;
void addAlias(in ACString aURI,
in AString aName,
in AString aType,
in AString aHostname,
in long aPort,
in AString aDatabase);
boolean hasAlias(in ACString aURI);
void getAlias(in ACString aURI,
out AString aName,
out AString aType,
out AString aHostname,
out long aPort,
out AString aDatabase);
void updateAlias(in ACString aURI,
in AString aName,
in AString aType,
in AString aHostname,
in long aPort,
in AString aDatabase);
void removeAlias(in ACString aURI);
mozISqlConnection getConnection(in ACString aURI);
mozISqlConnection getNewConnection(in ACString aURI);
};

View File

@@ -1,6 +0,0 @@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(topsrcdir)/config/rules.mk

View File

@@ -1,39 +0,0 @@
var sqlService = null;
var name;
var type;
var hostname;
var port;
var database;
function init() {
sqlService = Components.classes["@mozilla.org/sql/service;1"]
.getService(Components.interfaces.mozISqlService);
name = document.getElementById("name");
type = document.getElementById("type");
hostname = document.getElementById("hostname");
port = document.getElementById("port");
database = document.getElementById("database");
if (window.arguments) {
// get original values
var uri = window.arguments[0];
sqlService.getAlias(uri, name, type, hostname, port, database);
}
}
function onAccept() {
if (window.arguments) {
// update an existing alias
var uri = window.arguments[0];
sqlService.updateAlias(uri, name.value, type.value, hostname.value,
port.value, database.value);
}
else {
// add a new database
var uri = "urn:aliases:" + name.value;
sqlService.addAlias(uri, name.value, type.value, hostname.value,
port.value, database.value);
}
}

View File

@@ -1,46 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://sql/locale/aliasDialog.dtd">
<dialog id="aliasDialog"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&window.title;"
width="250" height="180"
buttons="accept,cancel" buttonpack="center"
ondialogaccept="return onAccept(event);"
onload="init()">
<script type="application/x-javascript" src="aliasDialog.js"/>
<grid flex="1">
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row>
<label value="&name.label;"/>
<textbox id="name"/>
</row>
<row>
<label value="&type.label;"/>
<textbox id="type"/>
</row>
<row>
<label value="&hostname.label;"/>
<textbox id="hostname"/>
</row>
<row>
<label value="&port.label;"/>
<textbox id="port"/>
</row>
<row>
<label value="&database.label;"/>
<textbox id="database"/>
</row>
</rows>
</grid>
</dialog>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<!-- list all the packages being supplied by this jar -->
<RDF:Seq about="urn:mozilla:package:root">
<RDF:li resource="urn:mozilla:package:sql"/>
</RDF:Seq>
<!-- package information -->
<RDF:Description about="urn:mozilla:package:sql"
chrome:displayName="SQL support"
chrome:author="mozilla.org"
chrome:authorURL="http://www.mozilla.org/projects/sql/index.html"
chrome:name="sql"
chrome:extension="true"
chrome:settingsURL="chrome://sql/content/sqlSettings.xul"
chrome:description="Allow applications to directly connect to SQL databases.">
</RDF:Description>
</RDF:RDF>

View File

@@ -1,36 +0,0 @@
var sqlService = null;
function getSqlService() {
if (! sqlService)
sqlService = Components.classes["@mozilla.org/sql/service;1"]
.getService(Components.interfaces.mozISqlService);
return sqlService;
}
function getSelectedAlias() {
var tree = document.getElementById("aliasesTree");
return tree.builderView.getResourceAtIndex(tree.currentIndex).Value;
}
function updateButtons() {
var tree = document.getElementById("aliasesTree");
const buttons = ["updateButton", "removeButton"];
for (i = 0; i < buttons.length; i++)
document.getElementById(buttons[i]).disabled = tree.currentIndex < 0;
}
function addAlias() {
window.openDialog("aliasDialog.xul", "addAlias", "chrome,modal=yes,resizable=no,centerscreen");
}
function updateAlias() {
var alias = getSelectedAlias();
window.openDialog("aliasDialog.xul", "updateDatabase", "chrome,modal=yes,resizable=no,centerscreen", alias);
}
function removeAlias() {
var sqlService = getSqlService();
var alias = getSelectedAlias();
sqlService.removeAlias(alias);
updateButtons();
}

View File

@@ -1,55 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://sql/locale/sqlSettings.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&header.label;"
width="450" height="350">
<script type="application/x-javascript" src="sqlSettings.js"/>
<groupbox flex="1">
<caption label="&aliases.label;"/>
<hbox flex="1">
<tree id="aliasesTree" flex="1"
seltype="single"
datasources="rdf:sql" ref="SQL:AliasesRoot" flags="dont-build-content"
onselect="updateButtons()">
<treecols>
<treecol id="nameCol" flex="1" label="&nameCol.label;"
sort="rdf:http://www.mozilla.org/SQL-rdf#name"
sortActive="true" sortDirection="ascending"/>
<treecol id="typeCol" flex="1" label="&typeCol.label;"
sort="rdf:http://www.mozilla.org/SQL-rdf#type"/>
<treecol id="hostnameCol" flex="1" label="&hostnameCol.label;"
sort="rdf:http://www.mozilla.org/SQL-rdf#hostname"/>
<treecol id="portCol" flex="1" label="&portCol.label;"
sort="rdf:http://www.mozilla.org/SQL-rdf#port"/>
<treecol id="databaseCol" flex="1" label="&databaseCol.label;"
sort="rdf:http://www.mozilla.org/SQL-rdf#database"/>
</treecols>
<template>
<treechildren>
<treeitem uri="rdf:*">
<treerow>
<treecell label="rdf:http://www.mozilla.org/SQL-rdf#name"/>
<treecell label="rdf:http://www.mozilla.org/SQL-rdf#type"/>
<treecell label="rdf:http://www.mozilla.org/SQL-rdf#hostname"/>
<treecell label="rdf:http://www.mozilla.org/SQL-rdf#port"/>
<treecell label="rdf:http://www.mozilla.org/SQL-rdf#database"/>
</treerow>
</treeitem>
</treechildren>
</template>
</tree>
<vbox>
<button id="addButton" label="&add.label;" oncommand="addAlias()"/>
<button id="updateButton" label="&update.label;" disabled="true" oncommand="updateAlias()"/>
<button id="removeButton" label="&remove.label;" disabled="true" oncommand="removeAlias()"/>
</vbox>
</hbox>
</groupbox>
</dialog>

View File

@@ -1,9 +0,0 @@
sql.jar:
content/sql/contents.rdf (content/contents.rdf)
content/sql/sqlSettings.xul (content/sqlSettings.xul)
content/sql/sqlSettings.js (content/sqlSettings.js)
content/sql/aliasDialog.xul (content/aliasDialog.xul)
content/sql/aliasDialog.js (content/aliasDialog.js)
locale/en-US/sql/contents.rdf (locale/en-US/contents.rdf)
locale/en-US/sql/sqlSettings.dtd (locale/en-US/sqlSettings.dtd)
locale/en-US/sql/aliasDialog.dtd (locale/en-US/aliasDialog.dtd)

View File

@@ -1,7 +0,0 @@
<!ENTITY window.title "Alias">
<!ENTITY name.label "Name:">
<!ENTITY type.label "Type:">
<!ENTITY hostname.label "Hostname:">
<!ENTITY port.label "Port:">
<!ENTITY database.label "Database:">

View File

@@ -1,23 +0,0 @@
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<!-- list all the locales being supplied by this package -->
<RDF:Seq about="urn:mozilla:locale:root">
<RDF:li resource="urn:mozilla:locale:en-US"/>
</RDF:Seq>
<!-- locale information -->
<RDF:Description about="urn:mozilla:locale:en-US"
chrome:displayName="English(US)"
chrome:author="mozilla.org"
chrome:name="en-US"
chrome:previewURL="http://www.mozilla.org/locales/en-US.gif">
<chrome:packages>
<RDF:Seq about="urn:mozilla:locale:en-US:packages">
<RDF:li resource="urn:mozilla:locale:en-US:sql"/>
</RDF:Seq>
</chrome:packages>
</RDF:Description>
</RDF:RDF>

View File

@@ -1,12 +0,0 @@
<!ENTITY header.label "SQL support">
<!ENTITY aliases.label "Aliases">
<!ENTITY nameCol.label "Name">
<!ENTITY typeCol.label "Type">
<!ENTITY hostnameCol.label "Hostname">
<!ENTITY portCol.label "Port">
<!ENTITY databaseCol.label "Database">
<!ENTITY add.label "Add alias">
<!ENTITY update.label "Update alias">
<!ENTITY remove.label "Remove alias">

View File

@@ -1,33 +0,0 @@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = sql
LIBRARY_NAME = sqlbase_s
REQUIRES = xpcom \
string \
unicharutil \
locale \
necko \
rdf \
windowwatcher \
$(NULL)
CPPSRCS = \
mozSqlConnection.cpp \
mozSqlRequest.cpp \
mozSqlResult.cpp \
mozSqlService.cpp
EXPORTS = \
mozSqlConnection.h \
mozSqlRequest.h \
mozSqlResult.h \
mozSqlService.h
FORCE_STATIC_LIB=1
include $(topsrcdir)/config/rules.mk

View File

@@ -1,237 +0,0 @@
#include "nsIProxyObjectManager.h"
#include "mozSqlRequest.h"
#include "mozSqlConnection.h"
mozSqlConnection::mozSqlConnection()
: mLock(nsnull),
mCondVar(nsnull),
mThread(nsnull),
mShutdown(PR_FALSE),
mWaiting(PR_FALSE)
{
NS_INIT_ISUPPORTS();
mExecLock = PR_NewLock();
}
mozSqlConnection::~mozSqlConnection()
{
mRequests.Clear();
if (mCondVar)
PR_DestroyCondVar(mCondVar);
PR_DestroyLock(mExecLock);
if (mLock)
PR_DestroyLock(mLock);
}
// We require a special implementation of Release, which knows about
// a circular strong reference
NS_IMPL_THREADSAFE_ADDREF(mozSqlConnection)
NS_IMPL_THREADSAFE_QUERY_INTERFACE3(mozSqlConnection,
mozISqlConnection,
nsIRunnable,
nsISupportsWeakReference)
NS_IMETHODIMP_(nsrefcnt)
mozSqlConnection::Release()
{
PR_AtomicDecrement((PRInt32*)&mRefCnt);
// Delete if the last reference is our strong circular reference.
if (mThread && mRefCnt == 1) {
PR_Lock(mLock);
mRequests.Clear();
mShutdown = PR_TRUE;
if (mWaiting)
PR_NotifyCondVar(mCondVar);
else
CancelExec();
PR_Unlock(mLock);
return 0;
}
else if (mRefCnt == 0) {
delete this;
return 0;
}
return mRefCnt;
}
NS_IMETHODIMP
mozSqlConnection::GetServerVersion(nsAString& aServerVersion)
{
aServerVersion = mServerVersion;
return NS_OK;
}
NS_IMETHODIMP
mozSqlConnection::GetErrorMessage(nsAString& aErrorMessage)
{
aErrorMessage = mErrorMessage;
return NS_OK;
}
NS_IMETHODIMP
mozSqlConnection::GetLastID(PRInt32* aLastID)
{
*aLastID = mLastID;
return NS_OK;
}
NS_IMETHODIMP
mozSqlConnection::Init(const nsAString & aHost, PRInt32 aPort,
const nsAString & aDatabase, const nsAString & aUsername,
const nsAString & aPassword)
{
// descendants have to implement this themselves
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
mozSqlConnection::ExecuteQuery(const nsAString& aQuery, mozISqlResult** _retval)
{
PR_Lock(mExecLock);
nsresult rv = RealExec(aQuery, _retval, nsnull);
PR_Unlock(mExecLock);
return rv;
}
NS_IMETHODIMP
mozSqlConnection::ExecuteUpdate(const nsAString& aUpdate, PRInt32* _retval)
{
PR_Lock(mExecLock);
nsresult rv = RealExec(aUpdate, nsnull, _retval);
PR_Unlock(mExecLock);
return rv;
}
NS_IMETHODIMP
mozSqlConnection::AsyncExecuteQuery(const nsAString& aQuery, nsISupports* aCtxt,
mozISqlRequestObserver* aObserver,
mozISqlRequest **_retval)
{
if (!mThread) {
mLock = PR_NewLock();
mCondVar = PR_NewCondVar(mLock);
NS_NewThread(getter_AddRefs(mThread), this, 0, PR_UNJOINABLE_THREAD);
}
mozSqlRequest* request = new mozSqlRequest(this);
if (! request)
return NS_ERROR_OUT_OF_MEMORY;
request->mIsQuery = PR_TRUE;
request->mQuery = aQuery;
request->mCtxt = aCtxt;
nsresult rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(mozISqlRequestObserver),
aObserver,
PROXY_SYNC | PROXY_ALWAYS,
getter_AddRefs(request->mObserver));
if (NS_FAILED(rv))
return rv;
PR_Lock(mLock);
mRequests.AppendObject(request);
if (mWaiting && mRequests.Count() == 1)
PR_NotifyCondVar(mCondVar);
PR_Unlock(mLock);
NS_ADDREF(*_retval = request);
return NS_OK;
}
NS_IMETHODIMP
mozSqlConnection::AsyncExecuteUpdate(const nsAString& aQuery, nsISupports* aCtxt,
mozISqlRequestObserver* aObserver,
mozISqlRequest **_retval)
{
return NS_OK;
}
NS_IMETHODIMP
mozSqlConnection::BeginTransaction()
{
PRInt32 affectedRows;
return ExecuteUpdate(NS_LITERAL_STRING("begin"), &affectedRows);
}
NS_IMETHODIMP
mozSqlConnection::CommitTransaction()
{
PRInt32 affectedRows;
return ExecuteUpdate(NS_LITERAL_STRING("commit"), &affectedRows);
}
NS_IMETHODIMP
mozSqlConnection::RollbackTransaction()
{
PRInt32 affectedRows;
return ExecuteUpdate(NS_LITERAL_STRING("rollback"), &affectedRows);
}
NS_IMETHODIMP
mozSqlConnection::GetPrimaryKeys(const nsAString& aSchema, const nsAString& aTable, mozISqlResult** _retval)
{
// descendants have to implement this themselves
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
mozSqlConnection::Run()
{
while(!mShutdown) {
PR_Lock(mLock);
while (mRequests.Count()) {
mCurrentRequest = mRequests[0];
mRequests.RemoveObjectAt(0);
mozSqlRequest* r = (mozSqlRequest*)mCurrentRequest.get();
r->mObserver->OnStartRequest(mCurrentRequest, r->mCtxt);
r->mStatus = mozISqlRequest::STATUS_EXECUTED;
PR_Unlock(mLock);
nsresult rv = ExecuteQuery(r->mQuery, getter_AddRefs(r->mResult));
PR_Lock(mLock);
if (NS_SUCCEEDED(rv))
r->mStatus = mozISqlRequest::STATUS_COMPLETE;
else {
r->mStatus = mozISqlRequest::STATUS_ERROR;
GetErrorMessage(r->mErrorMessage);
}
r->mObserver->OnStopRequest(mCurrentRequest, r->mCtxt);
mCurrentRequest = nsnull;
}
mWaiting = PR_TRUE;
PR_WaitCondVar(mCondVar, PR_INTERVAL_NO_TIMEOUT);
mWaiting = PR_FALSE;
PR_Unlock(mLock);
}
return NS_OK;
}
nsresult
mozSqlConnection::CancelRequest(mozISqlRequest* aRequest)
{
PR_Lock(mLock);
if (mCurrentRequest == aRequest)
CancelExec();
else {
if (mRequests.RemoveObject(aRequest))
((mozSqlRequest*)aRequest)->mStatus = mozISqlRequest::STATUS_CANCELLED;
}
PR_Unlock(mLock);
return NS_OK;
}

View File

@@ -1,53 +0,0 @@
#ifndef mozSqlConnection_h
#define mozSqlConnection_h
#include "prcvar.h"
#include "nsString.h"
#include "nsCOMArray.h"
#include "nsWeakReference.h"
#include "nsIThread.h"
#include "nsIRunnable.h"
#include "mozISqlConnection.h"
#include "mozISqlRequest.h"
#include "mozISqlResult.h"
class mozSqlConnection : public mozISqlConnection,
public nsIRunnable,
public nsSupportsWeakReference
{
public:
mozSqlConnection();
virtual ~mozSqlConnection();
NS_DECL_ISUPPORTS
NS_DECL_MOZISQLCONNECTION
NS_DECL_NSIRUNNABLE
friend class mozSqlRequest;
friend class mozSqlResult;
protected:
virtual nsresult RealExec(const nsAString& aQuery,
mozISqlResult** aResult, PRInt32* aAffectedRows) = 0;
virtual nsresult CancelExec() = 0;
virtual nsresult GetIDName(nsAString& aIDName) = 0;
nsresult CancelRequest(mozISqlRequest* aRequest);
nsString mServerVersion;
nsString mErrorMessage;
PRInt32 mLastID;
PRLock* mLock;
PRCondVar* mCondVar;
PRLock* mExecLock;
nsCOMPtr<nsIThread> mThread;
nsCOMArray<mozISqlRequest> mRequests;
nsCOMPtr<mozISqlRequest> mCurrentRequest;
PRBool mShutdown;
PRBool mWaiting;
};
#endif // mozSqlConnection_h

View File

@@ -1,86 +0,0 @@
#include "mozSqlConnection.h"
#include "mozSqlRequest.h"
mozSqlRequest::mozSqlRequest(mozISqlConnection* aConnection)
: mAffectedRows(-1),
mIsQuery(PR_TRUE),
mStatus(mozISqlRequest::STATUS_NONE)
{
NS_INIT_ISUPPORTS();
mConnection = do_GetWeakReference(aConnection);
}
mozSqlRequest::~mozSqlRequest()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS1(mozSqlRequest,
mozISqlRequest);
NS_IMETHODIMP
mozSqlRequest::GetErrorMessage(nsAString & aErrorMessage)
{
aErrorMessage = mErrorMessage;
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::GetResult(mozISqlResult * *aResult)
{
NS_IF_ADDREF(*aResult = mResult);
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::GetAffectedRows(PRInt32 *aAffectedRows)
{
*aAffectedRows = mAffectedRows;
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::GetLastID(PRInt32* aLastID)
{
*aLastID = mLastID;
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::GetQuery(nsAString & aQuery)
{
aQuery = mQuery;
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::GetCtxt(nsISupports * *aCtxt)
{
NS_IF_ADDREF(*aCtxt = mCtxt);
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::GetObserver(mozISqlRequestObserver * *aObserver)
{
NS_IF_ADDREF(*aObserver = mObserver);
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::GetStatus(PRInt32 *aStatus)
{
*aStatus = mStatus;
return NS_OK;
}
NS_IMETHODIMP
mozSqlRequest::Cancel()
{
nsCOMPtr<mozISqlConnection> connection = do_QueryReferent(mConnection);
if (!connection)
return NS_ERROR_FAILURE;
mozISqlConnection* connectionRaw = connection.get();
return ((mozSqlConnection*)connectionRaw)->CancelRequest(this);
}

View File

@@ -1,41 +0,0 @@
#ifndef mozSqlRequest_h
#define mozSqlRequest_h
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIWeakReference.h"
#include "mozISqlConnection.h"
#include "mozISqlResult.h"
#include "mozISqlRequest.h"
#include "mozISqlRequestObserver.h"
class mozSqlRequest : public mozISqlRequest
{
public:
mozSqlRequest(mozISqlConnection* aConnection);
virtual ~mozSqlRequest();
NS_DECL_ISUPPORTS
NS_DECL_MOZISQLREQUEST
friend class mozSqlConnection;
protected:
nsCOMPtr<nsIWeakReference> mConnection;
nsString mErrorMessage;
nsCOMPtr<mozISqlResult> mResult;
PRInt32 mAffectedRows;
PRInt32 mLastID;
PRBool mIsQuery;
nsString mQuery;
nsCOMPtr<nsISupports> mCtxt;
nsCOMPtr<mozISqlRequestObserver> mObserver;
PRInt32 mStatus;
};
#endif // mozSqlRequest_h

File diff suppressed because it is too large Load Diff

View File

@@ -1,367 +0,0 @@
#ifndef mozSqlResult_h
#define mozSqlResult_h
#include "nsCRT.h"
#include "nsFixedSizeAllocator.h"
#include "nsVoidArray.h"
#include "nsCOMArray.h"
#include "nsHashtable.h"
#include "nsCOMPtr.h"
#include "nsWeakReference.h"
#include "nsISimpleEnumerator.h"
#include "nsIRDFService.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsIDateTimeFormat.h"
#include "nsIInputStream.h"
#include "mozISqlConnection.h"
#include "mozISqlDataSource.h"
#include "mozISqlResult.h"
#include "mozISqlResultEnumerator.h"
#include "mozISqlInputStream.h"
#define CELL_FLAG_NULL 0x80
#define CELL_FLAG_DEFAULT 0x40
#define CELL_FLAG_MASK ~(CELL_FLAG_NULL | CELL_FLAG_DEFAULT)
class ColumnInfo {
public:
static ColumnInfo*
Create(nsFixedSizeAllocator& aAllocator,
PRUnichar* aName,
PRInt32 aType,
PRInt32 aSize,
PRInt32 aMod,
nsIRDFResource* aProperty) {
void* place = aAllocator.Alloc(sizeof(ColumnInfo));
return place ? ::new(place) ColumnInfo(aName, aType, aSize, aMod, aProperty) : nsnull;
}
static void
Destroy(nsFixedSizeAllocator& aAllocator, ColumnInfo* aColumnInfo) {
aColumnInfo->~ColumnInfo();
aAllocator.Free(aColumnInfo, sizeof(ColumnInfo));
}
ColumnInfo(PRUnichar* aName, PRInt32 aType, PRInt32 aSize, PRInt32 aMod, nsIRDFResource* aProperty)
: mName(aName),
mType(aType),
mSize(aSize),
mMod(aMod),
mProperty(aProperty) {
NS_IF_ADDREF(mProperty);
}
~ColumnInfo() {
if (mName)
nsMemory::Free(mName);
NS_IF_RELEASE(mProperty);
}
PRUnichar* mName;
PRInt32 mType;
PRInt32 mSize;
PRInt32 mMod;
nsIRDFResource* mProperty;
private:
// Hide so that only Create() and Destroy() can be used to
// allocate and deallocate from the heap
static void* operator new(size_t) CPP_THROW_NEW { return 0; }
static void operator delete(void*, size_t) {}
};
class Cell {
public:
static Cell*
Create(nsFixedSizeAllocator& aAllocator,
PRInt32 aType) {
void* place = aAllocator.Alloc(sizeof(Cell));
return place ? ::new(place) Cell(aType) : nsnull;
}
static Cell*
Create(nsFixedSizeAllocator& aAllocator,
PRInt32 aType,
Cell* aSrcCell) {
void* place = aAllocator.Alloc(sizeof(Cell));
if (! place)
return nsnull;
Cell* newCell = ::new(place) Cell(aType);
Copy(aSrcCell, newCell);
return newCell;
}
static void
Copy(Cell* aSrcCell, Cell* aDestCell) {
if (aSrcCell->IsNull())
aDestCell->SetNull(PR_TRUE);
else {
aDestCell->SetNull(PR_FALSE);
PRInt32 type = aSrcCell->GetType();
if (type == mozISqlResult::TYPE_STRING)
aDestCell->SetString(nsCRT::strdup(aSrcCell->mString));
else if (type == mozISqlResult::TYPE_INT)
aDestCell->mInt = aSrcCell->mInt;
else if (type == mozISqlResult::TYPE_FLOAT ||
type == mozISqlResult::TYPE_DECIMAL)
aDestCell->mFloat = aSrcCell->mFloat;
else if (type == mozISqlResult::TYPE_DATE ||
type == mozISqlResult::TYPE_TIME ||
type == mozISqlResult::TYPE_DATETIME)
aDestCell->mDate = aSrcCell->mDate;
else if (type == mozISqlResult::TYPE_BOOL)
aDestCell->mBool = aSrcCell->mBool;
}
}
static void
Destroy(nsFixedSizeAllocator& aAllocator, Cell* aCell) {
aCell->~Cell();
aAllocator.Free(aCell, sizeof(Cell));
}
Cell(PRInt32 aType)
: mString(nsnull),
mType(aType | CELL_FLAG_NULL) {
}
~Cell() {
if ((GetType() == mozISqlResult::TYPE_STRING) && mString) {
nsMemory::Free(mString);
}
}
void SetString(PRUnichar* aString) {
if (mString)
nsMemory::Free(mString);
mString = aString;
}
PRInt32 GetType() {
return mType & CELL_FLAG_MASK;
}
void SetNull(PRBool aNull) {
mType &= CELL_FLAG_MASK;
if (aNull)
mType |= CELL_FLAG_NULL;
}
void SetDefault(PRBool aDefault) {
mType &= CELL_FLAG_MASK;
if (aDefault)
mType |= CELL_FLAG_DEFAULT;
}
PRBool IsNull() {
return mType & CELL_FLAG_NULL;
}
PRBool IsDefault() {
return mType & CELL_FLAG_DEFAULT;
}
union {
PRUnichar* mString;
PRInt32 mInt;
float mFloat;
PRInt64 mDate;
PRBool mBool;
};
private:
static void* operator new(size_t) CPP_THROW_NEW { return 0; }
static void operator delete(void*, size_t) {}
PRInt8 mType;
};
class Row {
public:
static Row*
Create(nsFixedSizeAllocator& aAllocator,
nsIRDFResource* aSource,
nsVoidArray& aColumnInfo) {
void* place = aAllocator.Alloc(sizeof(Row));
if (! place)
return nsnull;
Row* newRow = ::new(place) Row(aSource, aColumnInfo.Count());
for (PRInt32 i = 0; i < aColumnInfo.Count(); i++) {
Cell* newCell = Cell::Create(aAllocator, ((ColumnInfo*)aColumnInfo[i])->mType);
newRow->mCells[i] = newCell;
}
return newRow;
}
static Row*
Create(nsFixedSizeAllocator& aAllocator,
nsIRDFResource* aSource,
nsVoidArray& aColumnInfo,
Row* aSrcRow) {
void* place = aAllocator.Alloc(sizeof(Row));
if (! place)
return nsnull;
Row* newRow = ::new(place) Row(aSource, aColumnInfo.Count());
for (PRInt32 i = 0; i < aColumnInfo.Count(); i++) {
Cell* srcCell = aSrcRow->mCells[i];
Cell* newCell = Cell::Create(aAllocator, ((ColumnInfo*)aColumnInfo[i])->mType, srcCell);
newRow->mCells[i] = newCell;
}
return newRow;
}
static void
Copy(PRInt32 aColumnCount, Row* aSrcRow, Row* aDestRow) {
for (PRInt32 i = 0; i < aColumnCount; i++) {
Cell* srcCell = aSrcRow->mCells[i];
Cell* destCell = aDestRow->mCells[i];
Cell::Copy(srcCell, destCell);
}
}
static void
Destroy(nsFixedSizeAllocator& aAllocator, PRInt32 aColumnCount, Row* aRow) {
for (PRInt32 i = 0; i < aColumnCount; i++)
Cell::Destroy(aAllocator, aRow->mCells[i]);
aRow->~Row();
aAllocator.Free(aRow, sizeof(*aRow));
}
Row(nsIRDFResource* aSource, PRInt32 aColumnCount)
: mSource(aSource)
{
NS_IF_ADDREF(mSource);
mCells = new Cell*[aColumnCount];
}
~Row() {
delete[] mCells;
NS_IF_RELEASE(mSource);
}
nsIRDFResource* mSource;
Cell** mCells;
private:
static void* operator new(size_t) CPP_THROW_NEW { return 0; }
static void operator delete(void*, size_t) {}
};
class mozSqlResult : public mozISqlResult,
public mozISqlDataSource,
public nsIRDFDataSource,
public nsIRDFRemoteDataSource
{
public:
mozSqlResult(mozISqlConnection* aConnection,
const nsAString& aQuery);
nsresult Init();
nsresult Rebuild();
virtual ~mozSqlResult();
NS_DECL_ISUPPORTS
NS_DECL_MOZISQLRESULT
NS_DECL_MOZISQLDATASOURCE
NS_DECL_NSIRDFDATASOURCE
NS_DECL_NSIRDFREMOTEDATASOURCE
friend class mozSqlResultEnumerator;
friend class mozSqlResultStream;
protected:
virtual nsresult BuildColumnInfo() = 0 ;
virtual nsresult BuildRows() = 0;
virtual void ClearNativeResult() = 0;
void ClearColumnInfo();
void ClearRows();
nsresult EnsureTableName();
nsresult EnsurePrimaryKeys();
void AppendValue(Cell* aCell, nsAutoString& aValues);
nsresult AppendKeys(Row* aRow, nsAutoString& aKeys);
nsresult GetValues(Row* aRow, mozISqlResult** aResult, PRBool aUseID);
nsresult CopyValues(mozISqlResult* aResult, Row* aRow);
virtual nsresult CanInsert(PRBool* _retval) = 0;
virtual nsresult CanUpdate(PRBool* _retval) = 0;
virtual nsresult CanDelete(PRBool* _retval) = 0;
nsresult InsertRow(Row* aSrcRow, PRInt32* _retval);
nsresult UpdateRow(PRInt32 aRowIndex, Row* aSrcRow, PRInt32* _retval);
nsresult DeleteRow(PRInt32 aRowIndex, PRInt32* _retval);
nsresult GetCondition(Row* aRow, nsAString& aCurrentCondition);
static PRInt32 gRefCnt;
static nsIRDFService* gRDFService;
static nsIDateTimeFormat* gFormat;
static nsIRDFResource* kSQL_ResultRoot;
static nsIRDFResource* kNC_Child;
static nsIRDFLiteral* kNullLiteral;
static nsIRDFLiteral* kTrueLiteral;
static nsIRDFLiteral* kFalseLiteral;
nsCOMPtr<mozISqlConnection> mConnection;
nsString mErrorMessage;
nsString mQuery;
nsString mTableName;
nsFixedSizeAllocator mAllocator;
nsAutoVoidArray mColumnInfo;
nsVoidArray mRows;
nsObjectHashtable mSources;
nsCOMArray<nsIRDFObserver> mObservers;
nsCOMPtr<mozISqlResultEnumerator> mPrimaryKeys;
PRInt32 mCanInsert;
PRInt32 mCanUpdate;
PRInt32 mCanDelete;
};
class mozSqlResultEnumerator : public mozISqlResultEnumerator,
public nsISimpleEnumerator
{
public:
mozSqlResultEnumerator(mozSqlResult* aResult);
virtual ~mozSqlResultEnumerator();
NS_DECL_ISUPPORTS
NS_DECL_MOZISQLRESULTENUMERATOR
NS_DECL_NSISIMPLEENUMERATOR
private:
mozSqlResult* mResult;
PRInt32 mCurrentIndex;
Row* mCurrentRow;
Row* mBuffer;
};
class mozSqlResultStream : public mozISqlInputStream,
public nsIInputStream
{
public:
mozSqlResultStream(mozSqlResult* aResult);
virtual ~mozSqlResultStream();
NS_DECL_ISUPPORTS
NS_DECL_MOZISQLINPUTSTREAM
NS_DECL_NSIINPUTSTREAM
protected:
nsresult EnsureBuffer();
private:
mozSqlResult* mResult;
char* mBuffer;
PRUint32 mLength;
PRUint32 mPosition;
};
#endif // mozSqlResult_h

View File

@@ -1,624 +0,0 @@
#include "nsReadableUtils.h"
#include "nsXPIDLString.h"
#include "nsCRT.h"
#include "nsIAtom.h"
#include "nsISupportsUtils.h"
#include "nsIServiceManager.h"
#include "rdf.h"
#include "nsRDFCID.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsNetUtil.h"
#include "nsIRDFXMLSink.h"
#include "nsIWindowWatcher.h"
#include "nsIPrompt.h"
#include "mozSqlService.h"
#include "mozSqlConnection.h"
#define SQL_NAMESPACE_URI "http://www.mozilla.org/SQL-rdf#"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
nsIRDFService* mozSqlService::gRDFService;
nsIRDFContainerUtils* mozSqlService::gRDFContainerUtils;
nsIRDFResource* mozSqlService::kSQL_AliasesRoot;
nsIRDFResource* mozSqlService::kSQL_Name;
nsIRDFResource* mozSqlService::kSQL_Type;
nsIRDFResource* mozSqlService::kSQL_Hostname;
nsIRDFResource* mozSqlService::kSQL_Port;
nsIRDFResource* mozSqlService::kSQL_Database;
mozSqlService::mozSqlService()
: mConnectionCache(nsnull)
{
NS_INIT_ISUPPORTS();
}
mozSqlService::~mozSqlService()
{
gRDFService->UnregisterDataSource(this);
delete mConnectionCache;
NS_IF_RELEASE(kSQL_AliasesRoot);
NS_IF_RELEASE(kSQL_Name);
NS_IF_RELEASE(kSQL_Type);
NS_IF_RELEASE(kSQL_Hostname);
NS_IF_RELEASE(kSQL_Port);
NS_IF_RELEASE(kSQL_Database);
nsServiceManager::ReleaseService(kRDFContainerUtilsCID, gRDFContainerUtils);
gRDFContainerUtils = nsnull;
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
gRDFService = nsnull;
}
NS_IMPL_ISUPPORTS3(mozSqlService,
mozISqlService,
nsIRDFDataSource,
nsIRDFRemoteDataSource);
NS_IMETHODIMP
mozSqlService::GetErrorMessage(nsAString& aErrorMessage)
{
aErrorMessage = mErrorMessage;
return NS_OK;
}
nsresult
mozSqlService::Init()
{
nsresult rv;
rv = nsServiceManager::GetService(kRDFServiceCID, NS_GET_IID(nsIRDFService),
(nsISupports**) &gRDFService);
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kRDFContainerUtilsCID, NS_GET_IID(nsIRDFContainerUtils),
(nsISupports**) &gRDFContainerUtils);
if (NS_FAILED(rv)) return rv;
gRDFService->GetResource(NS_LITERAL_CSTRING("SQL:AliasesRoot"),
&kSQL_AliasesRoot);
gRDFService->GetResource(NS_LITERAL_CSTRING(SQL_NAMESPACE_URI "name"),
&kSQL_Name);
gRDFService->GetResource(NS_LITERAL_CSTRING(SQL_NAMESPACE_URI "type"),
&kSQL_Type);
gRDFService->GetResource(NS_LITERAL_CSTRING(SQL_NAMESPACE_URI "hostname"),
&kSQL_Hostname);
gRDFService->GetResource(NS_LITERAL_CSTRING(SQL_NAMESPACE_URI "port"),
&kSQL_Port);
gRDFService->GetResource(NS_LITERAL_CSTRING(SQL_NAMESPACE_URI "database"),
&kSQL_Database);
nsCOMPtr<nsIFile> file;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
rv = file->AppendNative(NS_LITERAL_CSTRING("sql.rdf"));
if (NS_FAILED(rv)) return rv;
nsCAutoString sql;
NS_GetURLSpecFromFile(file, sql);
rv = gRDFService->GetDataSourceBlocking(sql.get(), getter_AddRefs(mInner));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(mInner);
if (sink) {
nsCOMPtr<nsIAtom> prefix = getter_AddRefs(NS_NewAtom("SQL"));
sink->AddNameSpace(prefix, NS_ConvertASCIItoUCS2(SQL_NAMESPACE_URI));
}
return gRDFService->RegisterDataSource(this, PR_FALSE);
}
NS_IMETHODIMP
mozSqlService::AddAlias(const nsACString& aURI,
const nsAString& aName,
const nsAString& aType,
const nsAString& aHostname,
PRInt32 aPort,
const nsAString& aDatabase)
{
nsCOMPtr<nsIRDFResource> resource;
gRDFService->GetResource(aURI, getter_AddRefs(resource));
nsCOMPtr<nsIRDFLiteral> rdfLiteral;
nsCOMPtr<nsIRDFInt> rdfInt;
gRDFService->GetLiteral(PromiseFlatString(aName).get(), getter_AddRefs(rdfLiteral));
mInner->Assert(resource, kSQL_Name, rdfLiteral, PR_TRUE);
gRDFService->GetLiteral(PromiseFlatString(aType).get(), getter_AddRefs(rdfLiteral));
mInner->Assert(resource, kSQL_Type, rdfLiteral, PR_TRUE);
gRDFService->GetLiteral(PromiseFlatString(aHostname).get(), getter_AddRefs(rdfLiteral));
mInner->Assert(resource, kSQL_Hostname, rdfLiteral, PR_TRUE);
gRDFService->GetIntLiteral(aPort, getter_AddRefs(rdfInt));
mInner->Assert(resource, kSQL_Port, rdfInt, PR_TRUE);
gRDFService->GetLiteral(PromiseFlatString(aDatabase).get(), getter_AddRefs(rdfLiteral));
mInner->Assert(resource, kSQL_Database, rdfLiteral, PR_TRUE);
nsresult rv = EnsureAliasesContainer();
if (NS_FAILED(rv))
return rv;
mAliasesContainer->AppendElement(resource);
Flush();
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::HasAlias(const nsACString& aURI, PRBool* _retval)
{
nsCOMPtr<nsIRDFResource> resource;
gRDFService->GetResource(aURI, getter_AddRefs(resource));
nsresult rv = EnsureAliasesContainer();
if (NS_FAILED(rv))
return rv;
PRInt32 aliasIndex;
mAliasesContainer->IndexOf(resource, &aliasIndex);
*_retval = aliasIndex != -1;
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::GetAlias(const nsACString& aURI,
nsAString& aName,
nsAString& aType,
nsAString& aHostname,
PRInt32* aPort,
nsAString& aDatabase)
{
nsCOMPtr<nsIRDFResource> resource;
gRDFService->GetResource(aURI, getter_AddRefs(resource));
nsCOMPtr<nsIRDFNode> rdfNode;
nsCOMPtr<nsIRDFLiteral> rdfLiteral;
nsCOMPtr<nsIRDFInt> rdfInt;
const PRUnichar* value;
mInner->GetTarget(resource, kSQL_Name, PR_TRUE, getter_AddRefs(rdfNode));
if (rdfNode) {
rdfLiteral = do_QueryInterface(rdfNode);
rdfLiteral->GetValueConst(&value);
aName.Assign(value);
}
mInner->GetTarget(resource, kSQL_Type, PR_TRUE, getter_AddRefs(rdfNode));
if (rdfNode) {
rdfLiteral = do_QueryInterface(rdfNode);
rdfLiteral->GetValueConst(&value);
aType.Assign(value);
}
mInner->GetTarget(resource, kSQL_Hostname, PR_TRUE, getter_AddRefs(rdfNode));
if (rdfNode) {
rdfLiteral = do_QueryInterface(rdfNode);
rdfLiteral->GetValueConst(&value);
aHostname.Assign(value);
}
mInner->GetTarget(resource, kSQL_Port, PR_TRUE, getter_AddRefs(rdfNode));
if (rdfNode) {
rdfInt = do_QueryInterface(rdfNode);
rdfInt->GetValue(aPort);
}
mInner->GetTarget(resource, kSQL_Database, PR_TRUE, getter_AddRefs(rdfNode));
if (rdfNode) {
rdfLiteral = do_QueryInterface(rdfNode);
rdfLiteral->GetValueConst(&value);
aDatabase.Assign(value);
}
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::UpdateAlias(const nsACString& aURI,
const nsAString& aName,
const nsAString& aType,
const nsAString& aHostname,
PRInt32 aPort,
const nsAString& aDatabase)
{
nsCOMPtr<nsIRDFResource> resource;
gRDFService->GetResource(aURI, getter_AddRefs(resource));
nsCOMPtr<nsIRDFNode> rdfNode;
nsCOMPtr<nsIRDFLiteral> rdfLiteral;
nsCOMPtr<nsIRDFInt> rdfInt;
mInner->GetTarget(resource, kSQL_Name, PR_TRUE, getter_AddRefs(rdfNode));
gRDFService->GetLiteral(PromiseFlatString(aName).get(), getter_AddRefs(rdfLiteral));
mInner->Change(resource, kSQL_Name, rdfNode, rdfLiteral);
mInner->GetTarget(resource, kSQL_Type, PR_TRUE, getter_AddRefs(rdfNode));
gRDFService->GetLiteral(PromiseFlatString(aType).get(), getter_AddRefs(rdfLiteral));
mInner->Change(resource, kSQL_Type, rdfNode, rdfLiteral);
mInner->GetTarget(resource, kSQL_Hostname, PR_TRUE, getter_AddRefs(rdfNode));
gRDFService->GetLiteral(PromiseFlatString(aHostname).get(), getter_AddRefs(rdfLiteral));
mInner->Change(resource, kSQL_Hostname, rdfNode, rdfLiteral);
mInner->GetTarget(resource, kSQL_Port, PR_TRUE, getter_AddRefs(rdfNode));
gRDFService->GetIntLiteral(aPort, getter_AddRefs(rdfInt));
mInner->Change(resource, kSQL_Port, rdfNode, rdfInt);
mInner->GetTarget(resource, kSQL_Database, PR_TRUE, getter_AddRefs(rdfNode));
gRDFService->GetLiteral(PromiseFlatString(aDatabase).get(), getter_AddRefs(rdfLiteral));
mInner->Change(resource, kSQL_Database, rdfNode, rdfLiteral);
Flush();
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::RemoveAlias(const nsACString &aURI)
{
nsCOMPtr<nsIRDFResource> resource;
gRDFService->GetResource(aURI, getter_AddRefs(resource));
nsCOMPtr<nsIRDFNode> rdfNode;
mInner->GetTarget(resource, kSQL_Name, PR_TRUE, getter_AddRefs(rdfNode));
mInner->Unassert(resource, kSQL_Name, rdfNode);
mInner->GetTarget(resource, kSQL_Type, PR_TRUE, getter_AddRefs(rdfNode));
mInner->Unassert(resource, kSQL_Type, rdfNode);
mInner->GetTarget(resource, kSQL_Hostname, PR_TRUE, getter_AddRefs(rdfNode));
mInner->Unassert(resource, kSQL_Hostname, rdfNode);
mInner->GetTarget(resource, kSQL_Port, PR_TRUE, getter_AddRefs(rdfNode));
mInner->Unassert(resource, kSQL_Port, rdfNode);
mInner->GetTarget(resource, kSQL_Database, PR_TRUE, getter_AddRefs(rdfNode));
mInner->Unassert(resource, kSQL_Database, rdfNode);
nsresult rv = EnsureAliasesContainer();
if (NS_FAILED(rv))
return rv;
mAliasesContainer->RemoveElement(resource, PR_TRUE);
Flush();
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::GetConnection(const nsACString &aURI, mozISqlConnection **_retval)
{
nsCStringKey key(aURI);
nsCOMPtr<nsIWeakReference> weakRef;
nsCOMPtr<mozISqlConnection> conn;
if (mConnectionCache) {
weakRef = getter_AddRefs(NS_STATIC_CAST(nsIWeakReference*, mConnectionCache->Get(&key)));
if (weakRef) {
conn = do_QueryReferent(weakRef);
if (conn)
NS_ADDREF(*_retval = conn);
}
}
if (! *_retval) {
nsresult rv = GetNewConnection(aURI, getter_AddRefs(conn));
if (NS_FAILED(rv))
return rv;
weakRef = do_GetWeakReference(conn);
if (! mConnectionCache)
mConnectionCache = new nsSupportsHashtable(16);
mConnectionCache->Put(&key, weakRef);
NS_ADDREF(*_retval = conn);
}
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::GetNewConnection(const nsACString &aURI, mozISqlConnection **_retval)
{
PRBool hasAlias;
HasAlias(aURI, &hasAlias);
if (!hasAlias)
return NS_ERROR_FAILURE;
nsresult rv;
nsAutoString name;
nsAutoString type;
nsAutoString hostname;
PRInt32 port;
nsAutoString database;
GetAlias(aURI, name, type, hostname, &port, database);
nsCAutoString contractID(
NS_LITERAL_CSTRING("@mozilla.org/sql/connection;1?type=") +
NS_ConvertUCS2toUTF8(type));
nsCOMPtr<mozISqlConnection> conn = do_CreateInstance(contractID.get());
if (! conn)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIWindowWatcher> watcher(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
nsCOMPtr<nsIPrompt> prompter;
watcher->GetNewPrompter(0, getter_AddRefs(prompter));
PRBool retval;
do {
nsXPIDLString username;
nsXPIDLString password;
prompter->PromptUsernameAndPassword(
nsnull, // in wstring dialogTitle
nsnull, // in wstring text
getter_Copies(username),
getter_Copies(password),
nsnull, // in wstring checkMsg
nsnull, // inout boolean checkValue
&retval
);
if (retval) {
rv = conn->Init(hostname, port, database, username, password);
if (NS_FAILED(rv)) {
conn->GetErrorMessage(mErrorMessage);
prompter->Alert(nsnull, mErrorMessage.get());
}
}
} while(retval && NS_FAILED(rv));
NS_IF_ADDREF(*_retval = conn);
return rv;
}
NS_IMETHODIMP
mozSqlService::GetURI(char** aURI)
{
if (!aURI)
return NS_ERROR_NULL_POINTER;
*aURI = nsCRT::strdup("rdf:sql");
if (!(*aURI))
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::GetSource(nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue,
nsIRDFResource** aSource)
{
return mInner->GetSource(aProperty, aTarget, aTruthValue, aSource);
}
NS_IMETHODIMP
mozSqlService::GetSources(nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue,
nsISimpleEnumerator** aSources) {
return mInner->GetSources(aProperty, aTarget, aTruthValue, aSources);
}
NS_IMETHODIMP
mozSqlService::GetTarget(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
PRBool aTruthValue,
nsIRDFNode** aTarget) {
return mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget);
}
NS_IMETHODIMP
mozSqlService::GetTargets(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
PRBool aTruthValue,
nsISimpleEnumerator** aTargets) {
return mInner->GetTargets(aSource, aProperty, aTruthValue, aTargets);
}
NS_IMETHODIMP
mozSqlService::Assert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue)
{
return mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
}
NS_IMETHODIMP
mozSqlService::Unassert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
return mInner->Unassert(aSource, aProperty, aTarget);
}
NS_IMETHODIMP
mozSqlService::Change(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget)
{
return mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
}
NS_IMETHODIMP
mozSqlService::Move(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
return mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
}
NS_IMETHODIMP
mozSqlService::HasAssertion(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue,
PRBool* hasAssertion)
{
return mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, hasAssertion);
}
NS_IMETHODIMP
mozSqlService::AddObserver(nsIRDFObserver* aObserver)
{
return mInner->AddObserver(aObserver);
}
NS_IMETHODIMP
mozSqlService::RemoveObserver(nsIRDFObserver* aObserver)
{
return mInner->RemoveObserver(aObserver);
}
NS_IMETHODIMP
mozSqlService::HasArcIn(nsIRDFNode* aNode,
nsIRDFResource* aArc,
PRBool* _retval)
{
return mInner->HasArcIn(aNode, aArc, _retval);
}
NS_IMETHODIMP
mozSqlService::HasArcOut(nsIRDFResource* aSource,
nsIRDFResource* aArc,
PRBool* _retval)
{
return mInner->HasArcOut(aSource, aArc, _retval);
}
NS_IMETHODIMP
mozSqlService::ArcLabelsIn(nsIRDFNode* aNode,
nsISimpleEnumerator** aLabels)
{
return mInner->ArcLabelsIn(aNode, aLabels);
}
NS_IMETHODIMP
mozSqlService::ArcLabelsOut(nsIRDFResource* aSource,
nsISimpleEnumerator** aLabels)
{
return mInner->ArcLabelsIn(aSource, aLabels);
}
NS_IMETHODIMP
mozSqlService::GetAllResources(nsISimpleEnumerator** aResult)
{
return mInner->GetAllResources(aResult);
}
NS_IMETHODIMP
mozSqlService::GetAllCmds(nsIRDFResource* aSource,
nsISimpleEnumerator** aCommands)
{
return mInner->GetAllCmds(aSource, aCommands);
}
NS_IMETHODIMP
mozSqlService::IsCommandEnabled(nsISupportsArray* aSources,
nsIRDFResource* aCommand,
nsISupportsArray* aArguments,
PRBool* aResult)
{
return mInner->IsCommandEnabled(aSources, aCommand, aArguments, aResult);
}
NS_IMETHODIMP
mozSqlService::DoCommand(nsISupportsArray* aSources,
nsIRDFResource* aCommand,
nsISupportsArray* aArguments)
{
return mInner->DoCommand(aSources, aCommand, aArguments);
}
NS_IMETHODIMP
mozSqlService::BeginUpdateBatch()
{
return mInner->BeginUpdateBatch();
}
NS_IMETHODIMP
mozSqlService::EndUpdateBatch()
{
return mInner->EndUpdateBatch();
}
// nsIRDFRemoteDataSource
NS_IMETHODIMP
mozSqlService::GetLoaded(PRBool* aResult)
{
nsCOMPtr<nsIRDFRemoteDataSource> remote(do_QueryInterface(mInner));
return remote->GetLoaded(aResult);
}
NS_IMETHODIMP
mozSqlService::Init(const char* aURI)
{
return NS_OK;
}
NS_IMETHODIMP
mozSqlService::Refresh(PRBool aBlocking)
{
nsCOMPtr<nsIRDFRemoteDataSource> remote(do_QueryInterface(mInner));
return remote->Refresh(aBlocking);
}
NS_IMETHODIMP
mozSqlService::Flush()
{
nsCOMPtr<nsIRDFRemoteDataSource> remote(do_QueryInterface(mInner));
return remote->Flush();
}
NS_IMETHODIMP
mozSqlService::FlushTo(const char *aURI)
{
nsCOMPtr<nsIRDFRemoteDataSource> remote(do_QueryInterface(mInner));
return remote->FlushTo(aURI);
}
nsresult
mozSqlService::EnsureAliasesContainer()
{
if (! mAliasesContainer) {
PRBool isContainer;
nsresult rv = gRDFContainerUtils->IsContainer(mInner, kSQL_AliasesRoot, &isContainer);
if (NS_FAILED(rv)) return rv;
if (!isContainer) {
rv = gRDFContainerUtils->MakeSeq(mInner, kSQL_AliasesRoot, getter_AddRefs(mAliasesContainer));
if (NS_FAILED(rv)) return rv;
}
else {
mAliasesContainer = do_CreateInstance(NS_RDF_CONTRACTID "/container;1", &rv);
if (NS_FAILED(rv)) return rv;
rv = mAliasesContainer->Init(mInner, kSQL_AliasesRoot);
if (NS_FAILED(rv)) return rv;
}
}
return NS_OK;
}

View File

@@ -1,52 +0,0 @@
#ifndef mozSqlService_h
#define mozSqlService_h
#include "nsHashtable.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsIRDFService.h"
#include "nsIRDFContainerUtils.h"
#include "mozISqlService.h"
#define MOZ_SQLSERVICE_CLASSNAME "SQL service"
#define MOZ_SQLSERVICE_CID \
{0x1ceb35b7, 0xdaa8, 0x4ce4, {0xac, 0x67, 0x12, 0x5f, 0xb1, 0x7c, 0xb0, 0x19}}
#define MOZ_SQLSERVICE_CONTRACTID "@mozilla.org/sql/service;1"
#define MOZ_SQLDATASOURCE_CONTRACTID "@mozilla.org/rdf/datasource;1?name=sql"
class mozSqlService : public mozISqlService,
public nsIRDFDataSource,
public nsIRDFRemoteDataSource
{
public:
mozSqlService();
virtual ~mozSqlService();
nsresult Init();
NS_DECL_ISUPPORTS
NS_DECL_MOZISQLSERVICE
NS_DECL_NSIRDFDATASOURCE
NS_DECL_NSIRDFREMOTEDATASOURCE
protected:
nsresult EnsureAliasesContainer();
private:
static nsIRDFService* gRDFService;
static nsIRDFContainerUtils* gRDFContainerUtils;
static nsIRDFResource* kSQL_AliasesRoot;
static nsIRDFResource* kSQL_Name;
static nsIRDFResource* kSQL_Type;
static nsIRDFResource* kSQL_Hostname;
static nsIRDFResource* kSQL_Port;
static nsIRDFResource* kSQL_Database;
nsString mErrorMessage;
nsCOMPtr<nsIRDFDataSource> mInner;
nsCOMPtr<nsIRDFContainer> mAliasesContainer;
nsSupportsHashtable* mConnectionCache;
};
#endif /* mozSqlService_h */

View File

@@ -1,21 +0,0 @@
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = \
src
include $(topsrcdir)/config/rules.mk
XPI_FILE = sql-$(shell date +%Y%m%d)-$(OS_ARCH).xpi
xpi:
zip -j $(DIST)/$(XPI_FILE) $(srcdir)/install.js
cd $(DIST); zip -r $(XPI_FILE) \
bin/components/sql.xpt \
bin/components/sqlpgsql.xpt \
bin/components/$(LIB_PREFIX)sql$(DLL_SUFFIX) \
bin/chrome/sql.jar

View File

@@ -1,58 +0,0 @@
// this function verifies disk space in kilobytes
function verifyDiskSpace(dirPath, spaceRequired)
{
var spaceAvailable;
// Get the available disk space on the given path
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
// Convert the available disk space into kilobytes
spaceAvailable = parseInt(spaceAvailable / 1024);
// do the verification
if(spaceAvailable < spaceRequired)
{
logComment("Insufficient disk space: " + dirPath);
logComment(" required : " + spaceRequired + " K");
logComment(" available: " + spaceAvailable + " K");
return(false);
}
return(true);
}
var srDest = 200;
var err = initInstall("SQL Support", "SQL", "0.1");
logComment("initInstall: " + err);
var fProgram = getFolder("Program");
logComment("fProgram: " + fProgram);
if (verifyDiskSpace(fProgram, srDest))
{
err = addDirectory("Program", "0.1", "bin", fProgram, "", true);
logComment("addDirectory() returned: " + err);
var chromeFolder = getFolder("Chrome", "sql.jar");
registerChrome(CONTENT | DELAYED_CHROME, chromeFolder, "content/sql/");
registerChrome(LOCALE | DELAYED_CHROME, chromeFolder, "locale/en-US/sql/");
err = getLastError();
if (err == ACCESS_DENIED) {
alert("Unable to write to program directory " + fProgram + ".\n You will need to restart the browser with administrator/root privileges to install this software. After installing as root (or administrator), you will need to restart the browser one more time to register the installed software.\n After the second restart, you can go back to running the browser without privileges!");
cancelInstall(err);
logComment("cancelInstall() due to error: " + err);
}
else if (err != SUCCESS) {
cancelInstall(err);
logComment("cancelInstall() due to error: " + err);
}
else {
performInstall();
logComment("performInstall() returned: " + err);
}
}
else
cancelInstall(INSUFFICIENT_DISK_SPACE);

View File

@@ -1,40 +0,0 @@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = sql
MODULE_NAME = sqlModule
LIBRARY_NAME = sql
SHORT_LIBNAME = sql
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
REQUIRES = xpcom \
string \
rdf \
$(NULL)
CPPSRCS = \
mozSqlModule.cpp
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/$(LIB_PREFIX)sqlbase_s.$(LIB_SUFFIX)
EXTRA_DSO_LDOPTS = \
$(MOZ_COMPONENT_LIBS) \
$(MOZ_UNICHARUTIL_LIBS) \
$(NULL)
ifdef MOZ_ENABLE_PGSQL
DEFINES += -DMOZ_ENABLE_PGSQL
SHARED_LIBRARY_LIBS += $(DIST)/lib/$(LIB_PREFIX)sqlpgsql_s.$(LIB_SUFFIX)
EXTRA_DSO_LDOPTS += -L$(MOZ_PGSQL_LIBS) -lpq
endif
include $(topsrcdir)/config/rules.mk
ifdef MOZ_ENABLE_PGSQL
INCLUDES += -I$(MOZ_PGSQL_INCLUDES)
endif

View File

@@ -1,33 +0,0 @@
#include "nsIGenericFactory.h"
#include "mozSqlService.h"
#ifdef MOZ_ENABLE_PGSQL
#include "mozSqlConnectionPgsql.h"
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozSqlService, Init)
#ifdef MOZ_ENABLE_PGSQL
NS_GENERIC_FACTORY_CONSTRUCTOR(mozSqlConnectionPgsql)
#endif
static nsModuleComponentInfo components[] =
{
{ MOZ_SQLSERVICE_CLASSNAME,
MOZ_SQLSERVICE_CID,
MOZ_SQLSERVICE_CONTRACTID,
mozSqlServiceConstructor
},
{ MOZ_SQLSERVICE_CLASSNAME,
MOZ_SQLSERVICE_CID,
MOZ_SQLDATASOURCE_CONTRACTID,
mozSqlServiceConstructor
},
#ifdef MOZ_ENABLE_PGSQL
{ MOZ_SQLCONNECTIONPGSQL_CLASSNAME,
MOZ_SQLCONNECTIONPGSQL_CID,
MOZ_SQLCONNECTIONPGSQL_CONTRACTID,
mozSqlConnectionPgsqlConstructor
}
#endif
};
NS_IMPL_NSGETMODULE("sql", components)

View File

@@ -1,10 +0,0 @@
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DIRS = \
public \
src
include $(topsrcdir)/config/rules.mk

View File

@@ -1,14 +0,0 @@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = sql
XPIDL_MODULE = sqlpgsql
XPIDLSRCS = \
mozISqlConnectionPgsql.idl \
mozISqlResultPgsql.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,8 +0,0 @@
#include "nsISupports.idl"
[scriptable, uuid(0cf1eefe-611d-48fa-ae27-0a6f40d6a33e)]
interface mozISqlConnectionPgsql : nsISupports
{
};

View File

@@ -1,8 +0,0 @@
#include "nsISupports.idl"
[scriptable, uuid(f6573169-286d-4a20-8253-9abb07bdba29)]
interface mozISqlResultPgsql : nsISupports
{
};

View File

@@ -1,28 +0,0 @@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = sql
LIBRARY_NAME = sqlpgsql_s
REQUIRES = xpcom \
string \
locale \
rdf \
$(NULL)
CPPSRCS = \
mozSqlConnectionPgsql.cpp \
mozSqlResultPgsql.cpp
EXPORTS = \
mozSqlConnectionPgsql.h \
mozSqlResultPgsql.h
FORCE_STATIC_LIB=1
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(MOZ_PGSQL_INCLUDES)

View File

@@ -1,240 +0,0 @@
#include "prprf.h"
#include "mozSqlConnectionPgsql.h"
#include "mozSqlResultPgsql.h"
mozSqlConnectionPgsql::mozSqlConnectionPgsql()
: mConnection(nsnull)
{
}
mozSqlConnectionPgsql::~mozSqlConnectionPgsql()
{
if (mConnection)
PQfinish(mConnection);
}
NS_IMPL_ADDREF_INHERITED(mozSqlConnectionPgsql, mozSqlConnection)
NS_IMPL_RELEASE_INHERITED(mozSqlConnectionPgsql, mozSqlConnection)
// QueryInterface
NS_INTERFACE_MAP_BEGIN(mozSqlConnectionPgsql)
NS_INTERFACE_MAP_ENTRY(mozISqlConnectionPgsql)
NS_INTERFACE_MAP_END_INHERITING(mozSqlConnection)
NS_IMETHODIMP
mozSqlConnectionPgsql::Init(const nsAString & aHost, PRInt32 aPort,
const nsAString & aDatabase, const nsAString & aUsername,
const nsAString & aPassword)
{
if (mConnection)
return NS_OK;
if (aPort == -1)
aPort = 5432;
char port[11];
char options[] = "";
char tty[] = "";
PR_snprintf(port, 11, "%d", aPort);
mConnection = PQsetdbLogin(NS_ConvertUCS2toUTF8(aHost).get(),
port, options, tty,
NS_ConvertUCS2toUTF8(aDatabase).get(),
NS_ConvertUCS2toUTF8(aUsername).get(),
NS_ConvertUCS2toUTF8(aPassword).get());
return Setup();
}
NS_IMETHODIMP
mozSqlConnectionPgsql::GetPrimaryKeys(const nsAString& aSchema, const nsAString& aTable, mozISqlResult** _retval)
{
nsAutoString select;
nsAutoString from;
nsAutoString where;
if (mVersion >= SERVER_VERSION(7,3,0)) {
select = NS_LITERAL_STRING("SELECT n.nspname AS TABLE_SCHEM, ");
from = NS_LITERAL_STRING(" FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_index i");
where = NS_LITERAL_STRING(" AND ct.relnamespace = n.oid ");
if (!aSchema.IsEmpty()) {
where.Append(NS_LITERAL_STRING(" AND n.nspname = '") + aSchema);
where.Append(PRUnichar('\''));
}
}
else {
select = NS_LITERAL_STRING("SELECT NULL AS TABLE_SCHEM, ");
from = NS_LITERAL_STRING(" FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i ");
}
if (!aTable.IsEmpty()) {
where.Append(NS_LITERAL_STRING(" AND ct.relname = '") + aTable);
where.Append(PRUnichar('\''));
}
NS_NAMED_LITERAL_STRING(select2, " ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME, a.attnum AS KEY_SEQ, ci.relname AS PK_NAME ");
NS_NAMED_LITERAL_STRING(where2, " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid AND a.attrelid=ci.oid AND i.indisprimary ");
NS_NAMED_LITERAL_STRING(order2, " ORDER BY table_name, pk_name, key_seq");
return RealExec(select + select2 + from + where2 + where + order2, _retval, nsnull);
}
nsresult
mozSqlConnectionPgsql::Setup()
{
if (PQstatus(mConnection) == CONNECTION_BAD) {
mErrorMessage.Assign(NS_ConvertUTF8toUCS2(PQerrorMessage(mConnection)));
mConnection = nsnull;
return NS_ERROR_FAILURE;
}
PQsetClientEncoding(mConnection, "UNICODE");
/*
PGresult* result = PQexec(mConnection, "SET DATESTYLE TO US");
PRInt32 stat = PQresultStatus(result);
if (stat != PGRES_COMMAND_OK) {
mErrorMessage.Assign(NS_ConvertUTF8toUCS2(PQresultErrorMessage(result)));
PQfinish(mConnection);
mConnection = nsnull;
return NS_ERROR_FAILURE;
}
*/
PGresult* result = PQexec(mConnection, "select version()");
PRInt32 stat = PQresultStatus(result);
if (stat != PGRES_TUPLES_OK) {
mErrorMessage.Assign(NS_ConvertUTF8toUCS2(PQresultErrorMessage(result)));
return NS_ERROR_FAILURE;
}
char* version = PQgetvalue(result, 0, 0);
NS_ConvertUTF8toUCS2 buffer(version);
nsAString::const_iterator start, end, iter;
buffer.BeginReading(iter);
buffer.EndReading(end);
while (iter != end && !nsCRT::IsAsciiSpace(*iter))
++iter;
while (iter != end && nsCRT::IsAsciiSpace(*iter))
++iter;
start = iter;
while (iter != end && !nsCRT::IsAsciiSpace(*iter))
++iter;
mServerVersion = Substring(start,iter);
PRInt32 numbers[3] = {0,0,0};
mServerVersion.BeginReading(iter);
mServerVersion.EndReading(end);
for (PRInt32 i = 0; i < 3; i++) {
start = iter;
while (iter != end && *iter != PRUnichar('.'))
++iter;
nsAutoString v(Substring(start,iter));
PRInt32 err;
numbers[i] = v.ToInteger(&err);
while (iter != end && *iter == PRUnichar('.'))
++iter;
}
mVersion = SERVER_VERSION(numbers[0], numbers[1], numbers[2]);
return NS_OK;
}
nsresult
mozSqlConnectionPgsql::RealExec(const nsAString& aQuery,
mozISqlResult** aResult, PRInt32* aAffectedRows)
{
if (! mConnection)
return NS_ERROR_NOT_INITIALIZED;
PGresult* r;
r = PQexec(mConnection, NS_ConvertUCS2toUTF8(aQuery).get());
PRInt32 stat = PQresultStatus(r);
if (PQstatus(mConnection) == CONNECTION_BAD) {
PQreset(mConnection);
nsresult rv = Setup();
if (NS_FAILED(rv))
return rv;
r = PQexec(mConnection, NS_ConvertUCS2toUTF8(aQuery).get());
stat = PQresultStatus(r);
}
if (stat == PGRES_TUPLES_OK) {
if (!aResult)
return NS_ERROR_NULL_POINTER;
static char select1[] = "select t.oid, case when t.typbasetype = 0 then t.typname else (select t2.typname from pg_type t2 where t2.oid=t.typbasetype) end as typname from pg_type t where t.oid in (";
static char select2[] = "select oid, typname from pg_type where oid in (";
char* select;
if (mVersion >= SERVER_VERSION(7,3,0))
select = select1;
else
select = select2;
PRInt32 columnCount = PQnfields(r);
char* query = (char*)malloc(strlen(select) + columnCount * 11 + 2);
strcpy(query, select);
for (PRInt32 i = 0; i < columnCount; i++) {
PRInt32 oid = PQftype(r, i);
char oidStr[11];
if (i)
sprintf(oidStr, ",%d", oid);
else
sprintf(oidStr, "%d", oid);
strcat(query, oidStr);
}
strcat(query, ")");
PGresult* types = PQexec(mConnection, query);
free(query);
stat = PQresultStatus(types);
if (stat != PGRES_TUPLES_OK) {
mErrorMessage.Assign(NS_ConvertUTF8toUCS2(PQresultErrorMessage(types)));
return NS_ERROR_FAILURE;
}
if (*aResult) {
((mozSqlResultPgsql*)*aResult)->SetResult(r, types);
nsresult rv = ((mozSqlResult*)*aResult)->Rebuild();
if (NS_FAILED(rv))
return rv;
NS_ADDREF(*aResult);
}
else {
mozSqlResult* result = new mozSqlResultPgsql(this, aQuery);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
((mozSqlResultPgsql*)result)->SetResult(r, types);
nsresult rv = result->Init();
if (NS_FAILED(rv))
return rv;
NS_ADDREF(*aResult = result);
}
}
else if (stat == PGRES_COMMAND_OK) {
if (!aAffectedRows)
return NS_ERROR_NULL_POINTER;
PR_sscanf(PQcmdTuples(r), "%d", aAffectedRows);
mLastID = PQoidValue(r);
}
else {
mErrorMessage.Assign(NS_ConvertUTF8toUCS2(PQresultErrorMessage(r)));
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
mozSqlConnectionPgsql::CancelExec()
{
if (!PQrequestCancel(mConnection)) {
mErrorMessage.Assign(NS_ConvertUTF8toUCS2(PQerrorMessage(mConnection)));
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
mozSqlConnectionPgsql::GetIDName(nsAString& aIDName)
{
aIDName = NS_LITERAL_STRING("OID");
return NS_OK;
}

View File

@@ -1,47 +0,0 @@
#ifndef mozSqlConnectionPgsql_h
#define mozSqlConnectionPgsql_h
#include "libpq-fe.h"
#include "mozSqlConnection.h"
#include "mozISqlConnectionPgsql.h"
#define MOZ_SQLCONNECTIONPGSQL_CLASSNAME "PosgreSQL SQL Connection"
#define MOZ_SQLCONNECTIONPGSQL_CID \
{0x0cf1eefe, 0x611d, 0x48fa, {0xae, 0x27, 0x0a, 0x6f, 0x40, 0xd6, 0xa3, 0x3e }}
#define MOZ_SQLCONNECTIONPGSQL_CONTRACTID "@mozilla.org/sql/connection;1?type=pgsql"
#define SERVER_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
class mozSqlConnectionPgsql : public mozSqlConnection,
public mozISqlConnectionPgsql
{
public:
mozSqlConnectionPgsql();
virtual ~mozSqlConnectionPgsql();
NS_DECL_ISUPPORTS
NS_IMETHOD Init(const nsAString& aHost, PRInt32 aPort,
const nsAString& aDatabase, const nsAString& aUsername,
const nsAString& aPassword);
NS_IMETHOD GetPrimaryKeys(const nsAString& aSchema, const nsAString& aTable, mozISqlResult** _retval);
NS_DECL_MOZISQLCONNECTIONPGSQL
protected:
nsresult Setup();
virtual nsresult RealExec(const nsAString& aQuery,
mozISqlResult** aResult, PRInt32* aAffectedRows);
virtual nsresult CancelExec();
virtual nsresult GetIDName(nsAString& aIDName);
private:
PGconn* mConnection;
PRInt32 mVersion;
};
#endif // mozSqlConnectionPgsql_h

View File

@@ -1,235 +0,0 @@
#include "prprf.h"
#include "nsReadableUtils.h"
#include "mozSqlResultPgsql.h"
mozSqlResultPgsql::mozSqlResultPgsql(mozISqlConnection* aConnection,
const nsAString& aQuery)
: mozSqlResult(aConnection, aQuery),
mResult(nsnull),
mTypes(nsnull)
{
}
void
mozSqlResultPgsql::SetResult(PGresult* aResult,
PGresult* aTypes)
{
mResult = aResult;
mTypes = aTypes;
}
mozSqlResultPgsql::~mozSqlResultPgsql()
{
ClearNativeResult();
}
NS_IMPL_ADDREF_INHERITED(mozSqlResultPgsql, mozSqlResult)
NS_IMPL_RELEASE_INHERITED(mozSqlResultPgsql, mozSqlResult)
// QueryInterface
NS_INTERFACE_MAP_BEGIN(mozSqlResultPgsql)
NS_INTERFACE_MAP_ENTRY(mozISqlResultPgsql)
NS_INTERFACE_MAP_END_INHERITING(mozSqlResult)
PRInt32
mozSqlResultPgsql::GetColType(PRInt32 aColumnIndex)
{
PRInt32 oid = PQftype(mResult, aColumnIndex);
for (PRInt32 i = 0; i < PQntuples(mTypes); i++) {
char* value = PQgetvalue(mTypes, i, 0);
PRInt32 o;
PR_sscanf(value, "%d", &o);
if (o == oid) {
char* type = PQgetvalue(mTypes, i, 1);
if (! strcmp(type, "int2"))
return mozISqlResult::TYPE_INT;
else if (! strcmp(type, "int4"))
return mozISqlResult::TYPE_INT;
else if (! strcmp(type, "float4"))
return mozISqlResult::TYPE_STRING;
else if (! strcmp(type, "numeric"))
return mozISqlResult::TYPE_STRING;
else if (! strcmp(type, "date"))
return mozISqlResult::TYPE_STRING;
else if (! strcmp(type, "time"))
return mozISqlResult::TYPE_STRING;
else if (! strcmp(type, "timestamp"))
return mozISqlResult::TYPE_STRING;
else if (! strcmp(type, "bool"))
return mozISqlResult::TYPE_BOOL;
else
return mozISqlResult::TYPE_STRING;
}
}
return mozISqlResult::TYPE_STRING;
}
nsresult
mozSqlResultPgsql::BuildColumnInfo()
{
for (PRInt32 i = 0; i < PQnfields(mResult); i++) {
char* n = PQfname(mResult, i);
PRUnichar* name = ToNewUnicode(NS_ConvertUTF8toUCS2(n));
PRInt32 type = GetColType(i);
PRInt32 size = PQfsize(mResult, i);
PRInt32 mod = PQfmod(mResult, i);
nsCAutoString uri(NS_LITERAL_CSTRING("http://www.mozilla.org/SQL-rdf#"));
uri.Append(n);
nsCOMPtr<nsIRDFResource> property;
gRDFService->GetResource(uri, getter_AddRefs(property));
ColumnInfo* columnInfo = ColumnInfo::Create(mAllocator, name, type, size, mod, property);
mColumnInfo.AppendElement(columnInfo);
}
return NS_OK;
}
nsresult
mozSqlResultPgsql::BuildRows()
{
for(PRInt32 i = 0; i < PQntuples(mResult); i++) {
nsCOMPtr<nsIRDFResource> resource;
nsresult rv = gRDFService->GetAnonymousResource(getter_AddRefs(resource));
if (NS_FAILED(rv)) return rv;
Row* row = Row::Create(mAllocator, resource, mColumnInfo);
for (PRInt32 j = 0; j < mColumnInfo.Count(); j++) {
if (! PQgetisnull(mResult, i, j)) {
char* value = PQgetvalue(mResult, i, j);
Cell* cell = row->mCells[j];
cell->SetNull(PR_FALSE);
PRInt32 type = cell->GetType();
if (type == mozISqlResult::TYPE_STRING)
cell->SetString(ToNewUnicode(NS_ConvertUTF8toUCS2(value)));
else if (type == mozISqlResult::TYPE_INT)
PR_sscanf(value, "%d", &cell->mInt);
else if (type == mozISqlResult::TYPE_FLOAT)
PR_sscanf(value, "%f", &cell->mFloat);
else if (type == mozISqlResult::TYPE_DECIMAL)
PR_sscanf(value, "%f", &cell->mFloat);
else if (type == mozISqlResult::TYPE_DATE ||
type == mozISqlResult::TYPE_TIME ||
type == mozISqlResult::TYPE_DATETIME)
PR_ParseTimeString(value, PR_FALSE, &cell->mDate);
else if (type == mozISqlResult::TYPE_BOOL)
cell->mBool = !strcmp(value, "t");
}
}
mRows.AppendElement(row);
nsVoidKey key(resource);
mSources.Put(&key, row);
}
return NS_OK;
}
void
mozSqlResultPgsql::ClearNativeResult()
{
if (mResult) {
PQclear(mResult);
mResult = nsnull;
}
if (mTypes) {
PQclear(mTypes);
mTypes = nsnull;
}
}
nsresult
mozSqlResultPgsql::EnsureTablePrivileges()
{
nsresult rv = EnsureTableName();
if (NS_FAILED(rv))
return rv;
NS_NAMED_LITERAL_STRING(select, "select ");
NS_NAMED_LITERAL_STRING(func, "has_table_privilege(SESSION_USER, '");
NS_NAMED_LITERAL_STRING(comma, ", ");
NS_NAMED_LITERAL_STRING(ins, "', 'INSERT')");
NS_NAMED_LITERAL_STRING(upd, "', 'UPDATE')");
NS_NAMED_LITERAL_STRING(del, "','DELETE')");
nsCOMPtr<mozISqlResult> result;
rv = mConnection->ExecuteQuery(
select + func + mTableName + ins +
comma + func + mTableName + upd +
comma + func + mTableName + del,
getter_AddRefs(result));
if (NS_FAILED(rv)) {
mConnection->GetErrorMessage(mErrorMessage);
return rv;
}
nsCOMPtr<mozISqlResultEnumerator> enumerator;
rv = result->Enumerate(getter_AddRefs(enumerator));
if (NS_FAILED(rv))
return rv;
rv = enumerator->First();
if (NS_FAILED(rv))
return rv;
rv = enumerator->GetBool(0, &mCanInsert);
if (NS_FAILED(rv))
return rv;
rv = enumerator->GetBool(1, &mCanUpdate);
if (NS_FAILED(rv))
return rv;
return enumerator->GetBool(2, &mCanDelete);
}
nsresult
mozSqlResultPgsql::CanInsert(PRBool* _retval)
{
if (mCanInsert >= 0) {
*_retval = mCanInsert;
return NS_OK;
}
nsresult rv = EnsureTablePrivileges();
if (NS_FAILED(rv))
return rv;
*_retval = mCanInsert;
return NS_OK;
}
nsresult
mozSqlResultPgsql::CanUpdate(PRBool* _retval)
{
if (mCanUpdate >= 0) {
*_retval = mCanUpdate;
return NS_OK;
}
nsresult rv = EnsureTablePrivileges();
if (NS_FAILED(rv))
return rv;
*_retval = mCanUpdate;
return NS_OK;
}
nsresult
mozSqlResultPgsql::CanDelete(PRBool* _retval)
{
if (mCanDelete >= 0) {
*_retval = mCanDelete;
return NS_OK;
}
nsresult rv = EnsureTablePrivileges();
if (NS_FAILED(rv))
return rv;
*_retval = mCanDelete;
return NS_OK;
}

View File

@@ -1,39 +0,0 @@
#ifndef mozSqlResultPgsql_h
#define mozSqlResultPgsql_h
#include "libpq-fe.h"
#include "mozSqlResult.h"
#include "mozISqlResultPgsql.h"
class mozSqlResultPgsql : public mozSqlResult,
public mozISqlResultPgsql
{
public:
mozSqlResultPgsql(mozISqlConnection* aConnection,
const nsAString& aQuery);
void SetResult(PGresult* aResult,
PGresult* aTypes);
virtual ~mozSqlResultPgsql();
NS_DECL_ISUPPORTS
NS_DECL_MOZISQLRESULTPGSQL
protected:
PRInt32 GetColType(PRInt32 aColumnIndex);
virtual nsresult BuildColumnInfo();
virtual nsresult BuildRows();
virtual void ClearNativeResult();
nsresult EnsureTablePrivileges();
virtual nsresult CanInsert(PRBool* _retval);
virtual nsresult CanUpdate(PRBool* _retval);
virtual nsresult CanDelete(PRBool* _retval);
private:
PGresult* mResult;
PGresult* mTypes;
};
#endif // mozSqlResultPgsql_h

View File

@@ -1,15 +0,0 @@
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
XPI_FILE = sqltest-$(shell date +%Y%m%d).xpi
xpi:
zip -j $(DIST)/$(XPI_FILE) $(srcdir)/install.js
cd $(DIST); zip -r $(XPI_FILE) \
bin/chrome/sqltest.jar

View File

@@ -1,17 +0,0 @@
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<!-- list all the packages being supplied by this jar -->
<RDF:Seq about="urn:mozilla:package:root">
<RDF:li resource="urn:mozilla:package:sqltest"/>
</RDF:Seq>
<!-- package information -->
<RDF:Description about="urn:mozilla:package:sqltest"
chrome:displayName="SQL test"
chrome:author="mozilla.org"
chrome:name="sqltest">
</RDF:Description>
</RDF:RDF>

View File

@@ -1,57 +0,0 @@
// this function verifies disk space in kilobytes
function verifyDiskSpace(dirPath, spaceRequired)
{
var spaceAvailable;
// Get the available disk space on the given path
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
// Convert the available disk space into kilobytes
spaceAvailable = parseInt(spaceAvailable / 1024);
// do the verification
if(spaceAvailable < spaceRequired)
{
logComment("Insufficient disk space: " + dirPath);
logComment(" required : " + spaceRequired + " K");
logComment(" available: " + spaceAvailable + " K");
return(false);
}
return(true);
}
var srDest = 100;
var err = initInstall("SQL test", "SQLTEST", "0.1");
logComment("initInstall: " + err);
var fProgram = getFolder("Program");
logComment("fProgram: " + fProgram);
if (verifyDiskSpace(fProgram, srDest))
{
err = addDirectory("Program", "0.1", "bin", fProgram, "", true);
logComment("addDirectory() returned: " + err);
var chromeFolder = getFolder("Chrome", "sqltest.jar");
registerChrome(CONTENT | DELAYED_CHROME, chromeFolder, "content/sqltest/");
err = getLastError();
if (err == ACCESS_DENIED) {
alert("Unable to write to program directory " + fProgram + ".\n You will need to restart the browser with administrator/root privileges to install this software. After installing as root (or administrator), you will need to restart the browser one more time to register the installed software.\n After the second restart, you can go back to running the browser without privileges!");
cancelInstall(err);
logComment("cancelInstall() due to error: " + err);
}
else if (err != SUCCESS) {
cancelInstall(err);
logComment("cancelInstall() due to error: " + err);
}
else {
performInstall();
logComment("performInstall() returned: " + err);
}
}
else
cancelInstall(INSUFFICIENT_DISK_SPACE);

View File

@@ -1,7 +0,0 @@
sqltest.jar:
content/sqltest/contents.rdf (contents.rdf)
content/sqltest/sqltest.xul (sqltest.xul)
content/sqltest/sqltest.js (sqltest.js)
content/sqltest/sqltest.css (sqltest.css)
content/sqltest/sqltestDialog.xul (sqltestDialog.xul)
content/sqltest/sqltestDialog.js (sqltestDialog.js)

View File

@@ -1,8 +0,0 @@
treechildren:-moz-tree-cell {
border-right: 1px solid ThreeDFace;
border-bottom: 1px solid ThreeDFace;
}
.spacer {
height: 10px;
}

View File

@@ -1,126 +0,0 @@
const alias = "urn:aliases:sqltest";
const complete = Components.interfaces.mozISqlRequest.STATUS_COMPLETE;
var connection;
var result;
var startupObserver = {
onStartRequest: function(request, ctxt) {
},
onStopRequest: function(request, ctxt) {
if (request.status == complete) {
result = request.result;
var ds = result.QueryInterface(Components.interfaces.nsIRDFDataSource);
var menulist = document.getElementById("statesMenulist");
menulist.database.AddDataSource(ds);
menulist.builder.rebuild();
menulist.selectedIndex = 0;
var tree = document.getElementById("statesTree");
tree.database.AddDataSource(ds);
tree.builder.rebuild();
}
else {
alert(request.errorMessage);
}
}
};
var observer = {
onStartRequest: function(request, ctxt) {
},
onStopRequest: function(request, ctxt) {
if (request.status == complete) {
var element = document.getElementById("asyncStateName");
if (request.result.rowCount) {
var enumerator = request.result.enumerate();
enumerator.first();
element.value = enumerator.getVariant(0);
}
else {
element.value = "Not found";
}
}
else {
alert(request.errorMessage);
}
}
};
function init() {
var service = Components.classes["@mozilla.org/sql/service;1"]
.getService(Components.interfaces.mozISqlService);
if (!service.hasAlias(alias)) {
alert("The alias for the sqltest was not defined.");
return;
}
try {
connection = service.getConnection(alias);
}
catch (ex) {
alert(service.errorMessage);
return;
}
var query = "select code, name from states";
var request = connection.asyncExecuteQuery(query, null, startupObserver);
}
function syncFindState() {
var code = document.getElementById("syncStateCode").value
var query = "select name from states where code = '" + code + "'";
try {
var result = connection.executeQuery(query);
var element = document.getElementById("syncStateName");
if (result.rowCount) {
var enumerator = result.enumerate();
enumerator.first();
element.value = enumerator.getVariant(0);
}
else {
element.value = "Not found";
}
}
catch (ex) {
alert(connection.errorMessage);
}
}
function asyncFindState() {
var code = document.getElementById("asyncStateCode").value;
var query = "select name from states where code = '" + code + "'";
var request = connection.asyncExecuteQuery(query, null, observer);
}
function getSelectedRowIndex() {
var tree = document.getElementById("statesTree");
var currentIndex = tree.currentIndex;
var resource = tree.builderView.getResourceAtIndex(currentIndex);
var datasource = result.QueryInterface(Components.interfaces.mozISqlDataSource);
return datasource.getIndexOfResource(resource);
}
function doInsert() {
window.openDialog("sqltestDialog.xul", "testDialog", "chrome,modal=yes,resizable=no", result);
}
function doUpdate() {
var rowIndex = this.getSelectedRowIndex();
window.openDialog("sqltestDialog.xul", "testDialog", "chrome,modal=yes,resizable=no", result, rowIndex);
}
function doDelete() {
var rowIndex = this.getSelectedRowIndex();
var enumerator = result.enumerate();
enumerator.absolute(rowIndex);
try {
enumerator.deleteRow();
}
catch(ex) {
alert(enumerator.errorMessage);
}
}

View File

@@ -1,118 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="sqltest.css" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical"
width="640" height="480"
title="SQL test"
onload="init()">
<script type="application/x-javascript" src="sqltest.js"/>
<popupset>
<popup id="editContextMenu">
<menuitem label="Insert" oncommand="doInsert()"/>
<menuitem label="Update" oncommand="doUpdate()"/>
<menuitem label="Delete" oncommand="doDelete()"/>
</popup>
</popupset>
<tabbox flex="1">
<tabs>
<tab label="Sync test"/>
<tab label="Async test"/>
<tab label="Widgets"/>
</tabs>
<tabpanels flex="1">
<vbox>
<text class="label" value="Type a state code and then hit ENTER. You should get a state name."/>
<spacer class="spacer"/>
<grid>
<columns>
<column/>
</columns>
<rows>
<row>
<text class="label" value="State code:"/>
<hbox>
<textbox id="syncStateCode" size="2" maxlength="2" onkeyup="if (event.keyCode == 13) syncFindState()"/>
</hbox>
</row>
<row>
<text class="label" value="State name:"/>
<textbox id="syncStateName"/>
</row>
</rows>
</grid>
</vbox>
<vbox>
<text class="label" value="Type a state code and then hit ENTER. You should get a state name."/>
<spacer class="spacer"/>
<grid>
<columns>
<column/>
</columns>
<rows>
<row>
<text class="label" value="State code:"/>
<hbox>
<textbox id="asyncStateCode" size="2" maxlength="2" onkeyup="if (event.keyCode == 13) asyncFindState()"/>
</hbox>
</row>
<row>
<text class="label" value="State name:"/>
<textbox id="asyncStateName"/>
</row>
</rows>
</grid>
</vbox>
<vbox>
<text class="label" value="You should see a menulist filled with all the states."/>
<spacer class="spacer"/>
<hbox>
<menulist id="statesMenulist"
datasources="rdf:null" ref="SQL:ResultRoot">
<template>
<menupopup>
<menuitem uri="..."
value="rdf:http://www.mozilla.org/SQL-rdf#code"
label="rdf:http://www.mozilla.org/SQL-rdf#name"/>
</menupopup>
</template>
</menulist>
</hbox>
<spacer class="spacer"/>
<text value="You should see codes and names of all states in this tree. You can even edit them using the context menu."/>
<spacer class="spacer"/>
<tree id="statesTree" flex="1"
context="editContextMenu"
seltype="single" enableColumnDrag="true"
datasources="rdf:null" ref="SQL:ResultRoot" flags="dont-build-content">
<treecols>
<treecol id="codeCol"
label="State code"
sort="rdf:http://www.mozilla.org/SQL-rdf#code"
sortActive="true" sortDirection="ascending"/>
<splitter class="tree-splitter"/>
<treecol id="nameCol" flex="1"
label="State name"
sort="rdf:http://www.mozilla.org/SQL-rdf#name"/>
</treecols>
<template>
<treechildren>
<treeitem uri="rdf:*">
<treerow>
<treecell label="rdf:http://www.mozilla.org/SQL-rdf#code"/>
<treecell label="rdf:http://www.mozilla.org/SQL-rdf#name"/>
</treerow>
</treeitem>
</treechildren>
</template>
</tree>
</vbox>
</tabpanels>
</tabbox>
</window>

View File

@@ -1,41 +0,0 @@
var result;
var enumerator;
function init() {
result = window.arguments[0];
enumerator = result.enumerate();
if (window.arguments.length == 2) {
enumerator.absolute(window.arguments[1]);
var columnCount = result.columnCount;
for(var i = 0; i < columnCount; i++) {
if (!enumerator.isNull(i)) {
var element = document.getElementById(result.getColumnName(i));
element.value = enumerator.getVariant(i);
}
}
}
}
function onAccept() {
var columnCount = result.columnCount;
for (var i = 0; i < columnCount; i++) {
var element = document.getElementById(result.getColumnName(i));
if (element.value)
enumerator.setVariant(i, element.value);
else
enumerator.setNull(i);
}
try {
if (window.arguments.length == 2)
enumerator.updateRow();
else
enumerator.insertRow();
}
catch(ex) {
alert(enumerator.errorMessage);
return false;
}
return true;
}

View File

@@ -1,33 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<dialog id="testDialog"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Test dialog"
buttons="accept,cancel" buttonpack="center"
ondialogaccept="return onAccept();"
onload="init()">
<script type="application/x-javascript" src="sqltestDialog.js"/>
<grid flex="1">
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row>
<label value="Code:"/>
<hbox>
<textbox id="code" size="2" maxlength="2" oninput="this.value = this.value.toUpperCase()"/>
</hbox>
</row>
<row>
<label value="Name:"/>
<textbox id="name" size="30" maxlength="30"/>
</row>
</rows>
</grid>
</dialog>

View File

@@ -1,4 +0,0 @@
create table states (
code varchar(2) primary key,
name varchar(30)
);

View File

@@ -1,51 +0,0 @@
AL Alabama
AK Alaska
AZ Arizona
AR Arkansas
CA California
CO Colorado
CT Connecticut
DE Delaware
FL Florida
GA Georgia
HI Hawaii
ID Idaho
IL Illinois
IN Indiana
IA Iowa
KS Kansas
KY Kentucky
LA Louisiana
ME Maine
MD Maryland
MA Massachusetts
MI Michigan
MN Minnesota
MS Mississippi
MO Missouri
MT Montana
NE Nebraska
NV Nevada
NH New Hampshire
NJ New Jersey
NM New Mexico
NY New York
NC North Carolina
ND North Dakota
OH Ohio
OK Oklahoma
OR Oregon
PA Pennsylvania
RI Rhode Island
SC South Carolina
SD South Dakota
TN Tennessee
TX Texas
UT Utah
VT Vermont
VA Virginia
WA Washington
DC Washington,D.C.
WV West Virginia
WI Wisconsin
WY Wyoming

View File

@@ -1,6 +0,0 @@
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,33 @@
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src decoders
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,32 @@
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = ppm png gif jpeg
include $(topsrcdir)/config/rules.mk

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,323 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef _GIF_H_
#define _GIF_H_
/* gif2.h
The interface for the GIF87/89a decoder.
*/
// List of possible parsing states
typedef enum {
gif_gather,
gif_init, //1
gif_type,
gif_version,
gif_global_header,
gif_global_colormap,
gif_image_start, //6
gif_image_header,
gif_image_colormap,
gif_image_body,
gif_lzw_start,
gif_lzw, //11
gif_sub_block,
gif_extension,
gif_control_extension,
gif_consume_block,
gif_skip_block,
gif_done, //17
gif_oom,
gif_error,
gif_comment_extension,
gif_application_extension,
gif_netscape_extension_block,
gif_consume_netscape_extension,
gif_consume_comment,
gif_delay,
gif_wait_for_buffer_full,
gif_stop_animating //added for animation stop
} gstate;
/* "Disposal" method indicates how the image should be handled in the
framebuffer before the subsequent image is displayed. */
typedef enum
{
DISPOSE_NOT_SPECIFIED = 0,
DISPOSE_KEEP = 1, /* Leave it in the framebuffer */
DISPOSE_OVERWRITE_BGCOLOR = 2, /* Overwrite with background color */
DISPOSE_OVERWRITE_PREVIOUS = 4 /* Save-under */
} gdispose;
/* A RGB triplet representing a single pixel in the image's colormap
(if present.) */
typedef struct _GIF_RGB
{
PRUint8 red, green, blue, pad; /* Windows requires the fourth byte &
many compilers pad it anyway. */
/* XXX: hist_count appears to be unused */
//PRUint16 hist_count; /* Histogram frequency count. */
} GIF_RGB;
/* Colormap information. */
typedef struct _GIF_ColorMap {
int32 num_colors; /* Number of colors in the colormap.
A negative value can be used to denote a
possibly non-unique set. */
GIF_RGB *map; /* Colormap colors. */
PRUint8 *index; /* NULL, if map is in index order. Otherwise
specifies the indices of the map entries. */
void *table; /* Lookup table for this colormap. Private to
the Image Library. */
} GIF_ColorMap;
/* An indexed RGB triplet. */
typedef struct _GIF_IRGB {
PRUint8 index;
PRUint8 red, green, blue;
} GIF_IRGB;
/* A GIF decoder's state */
typedef struct gif_struct {
void* clientptr;
/* Callbacks for this decoder instance*/
int (PR_CALLBACK *GIFCallback_NewPixmap)();
int (PR_CALLBACK *GIFCallback_BeginGIF)(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aLogicalScreenBackgroundRGBIndex);
int (PR_CALLBACK* GIFCallback_EndGIF)(
void* aClientData,
int aAnimationLoopCount);
int (PR_CALLBACK* GIFCallback_BeginImageFrame)(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey);
int (PR_CALLBACK* GIFCallback_EndImageFrame)(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout);
int (PR_CALLBACK* GIFCallback_SetupColorspaceConverter)();
int (PR_CALLBACK* GIFCallback_ResetPalette)();
int (PR_CALLBACK* GIFCallback_InitTransparentPixel)();
int (PR_CALLBACK* GIFCallback_DestroyTransparentPixel)();
int (PR_CALLBACK* GIFCallback_HaveDecodedRow)(
void* aClientData,
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
int aXOffset, /* With respect to GIF logical screen origin */
int aLength, /* Length of the row? */
int aRow, /* Row number? */
int aDuplicateCount, /* Number of times to duplicate the row? */
PRUint8 aDrawMode, /* il_draw_mode */
int aInterlacePass);
int (PR_CALLBACK *GIFCallback_HaveImageAll)(
void* aClientData);
/* Parsing state machine */
gstate state; /* Curent decoder master state */
PRUint8 *hold; /* Accumulation buffer */
int32 hold_size; /* Capacity, in bytes, of accumulation buffer */
PRUint8 *gather_head; /* Next byte to read in accumulation buffer */
int32 gather_request_size; /* Number of bytes to accumulate */
int32 gathered; /* bytes accumulated so far*/
gstate post_gather_state; /* State after requested bytes accumulated */
int32 requested_buffer_fullness; /* For netscape application extension */
/* LZW decoder state machine */
PRUint8 *stack; /* Base of decoder stack */
PRUint8 *stackp; /* Current stack pointer */
PRUint16 *prefix;
PRUint8 *suffix;
int datasize;
int codesize;
int codemask;
int clear_code; /* Codeword used to trigger dictionary reset */
int avail; /* Index of next available slot in dictionary */
int oldcode;
PRUint8 firstchar;
int count; /* Remaining # bytes in sub-block */
int bits; /* Number of unread bits in "datum" */
int32 datum; /* 32-bit input buffer */
/* Output state machine */
int ipass; /* Interlace pass; Ranges 1-4 if interlaced. */
PRUintn rows_remaining; /* Rows remaining to be output */
PRUintn irow; /* Current output row, starting at zero */
PRUint8 *rgbrow; /* Temporary storage for dithering/mapping */
PRUint8 *rowbuf; /* Single scanline temporary buffer */
PRUint8 *rowend; /* Pointer to end of rowbuf */
PRUint8 *rowp; /* Current output pointer */
/* Parameters for image frame currently being decoded*/
PRUintn x_offset, y_offset; /* With respect to "screen" origin */
PRUintn height, width;
PRUintn last_x_offset, last_y_offset; /* With respect to "screen" origin */
PRUintn last_height, last_width;
int interlaced; /* TRUE, if scanlines arrive interlaced order */
int tpixel; /* Index of transparent pixel */
GIF_IRGB* transparent_pixel;
int is_transparent; /* TRUE, if tpixel is valid */
int control_extension; /* TRUE, if image control extension present */
int is_local_colormap_defined;
gdispose disposal_method; /* Restore to background, leave in place, etc.*/
gdispose last_disposal_method;
GIF_RGB *local_colormap; /* Per-image colormap */
int local_colormap_size; /* Size of local colormap array. */
PRUint32 delay_time; /* Display time, in milliseconds,
for this image in a multi-image GIF */
/* Global (multi-image) state */
int screen_bgcolor; /* Logical screen background color */
int version; /* Either 89 for GIF89 or 87 for GIF87 */
PRUintn screen_width; /* Logical screen width & height */
PRUintn screen_height;
GIF_RGB *global_colormap; /* Default colormap if local not supplied */
int global_colormap_size; /* Size of global colormap array. */
int images_decoded; /* Counts images for multi-part GIFs */
int destroy_pending; /* Stream has ended */
int progressive_display; /* If TRUE, do Haeberli interlace hack */
int loop_count; /* Netscape specific extension block to control
the number of animation loops a GIF renders. */
} gif_struct;
/* Create a new gif_struct */
extern PRBool gif_create(gif_struct **gs);
/* These are the APIs that the client calls to intialize,
push data to, and shut down the GIF decoder. */
PRBool GIFInit(
gif_struct* gs,
void* aClientData,
int (*PR_CALLBACK GIFCallback_NewPixmap)(),
int (*PR_CALLBACK GIFCallback_BeginGIF)(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aBackgroundRGBIndex),
int (*PR_CALLBACK GIFCallback_EndGIF)(
void* aClientData,
int aAnimationLoopCount),
int (*PR_CALLBACK GIFCallback_BeginImageFrame)(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey),
int (*PR_CALLBACK GIFCallback_EndImageFrame)(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout),
int (*PR_CALLBACK GIFCallback_SetupColorspaceConverter)(),
int (*PR_CALLBACK GIFCallback_ResetPalette)(),
int (*PR_CALLBACK GIFCallback_InitTransparentPixel)(),
int (*PR_CALLBACK GIFCallback_DestroyTransparentPixel)(),
int (*PR_CALLBACK GIFCallback_HaveDecodedRow)(
void* aClientData,
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
int aXOffset, /* With respect to GIF logical screen origin */
int aLength, /* Length of the row? */
int aRow, /* Row number? */
int aDuplicateCount, /* Number of times to duplicate the row? */
PRUint8 aDrawMode, /* il_draw_mode */
int aInterlacePass),
int (*PR_CALLBACK GIFCallback_HaveImageAll)(
void* aClientData)
);
extern void gif_destroy(gif_struct* aGIFStruct);
int gif_write(gif_struct* aGIFStruct, const PRUint8 * buf, PRUint32 numbytes);
PRUint8 gif_write_ready(gif_struct* aGIFStruct);
extern void gif_complete(gif_struct** aGIFStruct);
extern void gif_delay_time_callback(/* void *closure */);
/* Callback functions that the client must implement and pass in
pointers for during the GIFInit call. These will be called back
when the decoder has a decoded rows, frame size information, etc.*/
/* GIFCallback_LogicalScreenSize is called only once to notify the client
of the logical screen size, which will be the size of the total image. */
typedef int (*PR_CALLBACK BEGINGIF_CALLBACK)(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aLogicalScreenBackgroundRGBIndex);
typedef int (PR_CALLBACK *GIFCallback_EndGIF)(
void* aClientData,
int aAnimationLoopCount);
/* GIFCallback_BeginImageFrame is called at the beginning of each frame of
a GIF.*/
typedef int (PR_CALLBACK *GIFCallback_BeginImageFrame)(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFraqeYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight);
extern int GIFCallback_EndImageFrame(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout); /* Time in milliseconds this frame should be displayed before the next frame.
This information appears in a sub control block, so we don't
transmit it back to the client until we're done with the frame. */
/*
extern int GIFCallback_SetupColorspaceConverter();
extern int GIFCallback_ResetPalette();
extern int GIFCallback_InitTransparentPixel();
extern int GIFCallback_DestroyTransparentPixel();
*/
extern int GIFCallback_HaveDecodedRow();
extern int GIFCallback_HaveImageAll();
#endif

View File

@@ -0,0 +1,42 @@
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imggif
LIBRARY_NAME = imggif
IS_COMPONENT = 1
REQUIRES = xpcom necko layout gfx2 imglib2
CPPSRCS = GIF2.cpp nsGIFDecoder2.cpp nsGIFModule.cpp
EXTRA_DSO_LDOPTS = $(GIF_LIBS) $(ZLIB_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,52 @@
#!nmake
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imggif
LIBRARY_NAME = imggif
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsGIFDecoder2.obj \
.\$(OBJDIR)\GIF2.obj \
.\$(OBJDIR)\nsGIFModule.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,506 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Chris Saari <saari@netscape.com>
*/
#include "nsGIFDecoder2.h"
#include "nsIInputStream.h"
#include "nsIComponentManager.h"
#include "nsIImage.h"
#include "nsMemory.h"
#include "imgIContainerObserver.h"
#include "nsRect.h"
//////////////////////////////////////////////////////////////////////
// GIF Decoder Implementation
// This is an adaptor between GIF2 and imgIDecoder
NS_IMPL_ISUPPORTS2(nsGIFDecoder2, imgIDecoder, nsIOutputStream);
nsGIFDecoder2::nsGIFDecoder2()
{
NS_INIT_ISUPPORTS();
mImageFrame = nsnull;
mGIFStruct = nsnull;
mAlphaLine = nsnull;
}
nsGIFDecoder2::~nsGIFDecoder2(void)
{
if (mAlphaLine)
nsMemory::Free(mAlphaLine);
if (mGIFStruct) {
gif_destroy(mGIFStruct);
mGIFStruct = nsnull;
}
}
//******************************************************************************
/** imgIDecoder methods **/
//******************************************************************************
//******************************************************************************
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsGIFDecoder2::Init(imgIRequest *aRequest)
{
mImageRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImageContainer));
/* do gif init stuff */
/* Always decode to 24 bit pixdepth */
PRBool created = gif_create(&mGIFStruct);
NS_ASSERTION(created, "gif_create failed");
// Call GIF decoder init routine
GIFInit(
mGIFStruct,
this,
NewPixmap,
BeginGIF,
EndGIF,
BeginImageFrame,
EndImageFrame,
SetupColorspaceConverter,
ResetPalette,
InitTransparentPixel,
DestroyTransparentPixel,
HaveDecodedRow,
HaveImageAll);
return NS_OK;
}
//******************************************************************************
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsGIFDecoder2::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mImageRequest;
NS_IF_ADDREF(*aRequest);
return NS_OK;
}
//******************************************************************************
/** nsIOutputStream methods **/
//******************************************************************************
//******************************************************************************
/* void close (); */
NS_IMETHODIMP nsGIFDecoder2::Close()
{
if (mGIFStruct) {
gif_destroy(mGIFStruct);
mGIFStruct = nsnull;
}
return NS_OK;
}
//******************************************************************************
/* void flush (); */
NS_IMETHODIMP nsGIFDecoder2::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsGIFDecoder2::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* static callback from nsIInputStream::ReadSegments */
static NS_METHOD ReadDataOut(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, closure);
*writeCount = decoder->ProcessData((unsigned char*)fromRawSegment, count);
return NS_OK;
}
//******************************************************************************
PRUint32 nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count)
{
// Push the data to the GIF decoder
// First we ask if the gif decoder is ready for more data, and if so, push it.
// In the new decoder, we should always be able to process more data since
// we don't wait to decode each frame in an animation now.
if(gif_write_ready(mGIFStruct)) {
gif_write(mGIFStruct, data, count);
}
return count; // we always consume all the data
}
//******************************************************************************
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsGIFDecoder2::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
inStr->ReadSegments(
ReadDataOut, // Callback
this,
count,
_retval);
// if error
//mRequest->Cancel(NS_BINDING_ABORTED); // XXX is this the correct error ?
return NS_OK;
}
//******************************************************************************
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsGIFDecoder2::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsGIFDecoder2::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
NS_IMETHODIMP nsGIFDecoder2::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsGIFDecoder2::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
NS_IMETHODIMP nsGIFDecoder2::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//******************************************************************************
// GIF decoder callback methods. Part of pulic API for GIF2
//******************************************************************************
//******************************************************************************
int BeginGIF(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aBackgroundRGBIndex)
{
// copy GIF info into imagelib structs
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
if (decoder->mObserver)
decoder->mObserver->OnStartDecode(nsnull, nsnull);
decoder->mImageContainer->Init(aLogicalScreenWidth, aLogicalScreenHeight, decoder->mObserver);
if (decoder->mObserver)
decoder->mObserver->OnStartContainer(nsnull, nsnull, decoder->mImageContainer);
return 0;
}
//******************************************************************************
int EndGIF(
void* aClientData,
int aAnimationLoopCount)
{
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
if (decoder->mObserver) {
decoder->mObserver->OnStopContainer(nsnull, nsnull, decoder->mImageContainer);
decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
decoder->mImageContainer->SetLoopCount(aAnimationLoopCount);
decoder->mImageContainer->DecodingComplete();
return 0;
}
//******************************************************************************
int BeginImageFrame(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey) /* don't have this info yet */
{
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
decoder->mImageFrame = nsnull; // clear out our current frame reference
decoder->mGIFStruct->x_offset = aFrameXOffset;
decoder->mGIFStruct->y_offset = aFrameYOffset;
decoder->mGIFStruct->width = aFrameWidth;
decoder->mGIFStruct->height = aFrameHeight;
return 0;
}
//******************************************************************************
int EndImageFrame(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout) /* Time this frame should be displayed before the next frame
we can't have this in the image frame init because it doesn't
show up in the GIF frame header, it shows up in a sub control
block.*/
{
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
// We actually have the timeout information before we get the lzw encoded image
// data, at least according to the spec, but we delay in setting the timeout for
// the image until here to help ensure that we have the whole image frame decoded before
// we go off and try to display another frame.
// XXXXXXXX
// decoder->mImageFrame->SetTimeout(aDelayTimeout);
decoder->mImageContainer->EndFrameDecode(aFrameNumber, aDelayTimeout);
if (decoder->mObserver)
decoder->mObserver->OnStopFrame(nsnull, nsnull, decoder->mImageFrame);
decoder->mImageFrame = nsnull;
return 0;
}
//******************************************************************************
// GIF decoder callback
int HaveImageAll(
void* aClientData)
{
return 0;
}
//******************************************************************************
// GIF decoder callback notification that it has decoded a row
int HaveDecodedRow(
void* aClientData,
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
int aXOffset, // With respect to GIF logical screen origin
int aLength, // Length of the row?
int aRowNumber, // Row number?
int aDuplicateCount, // Number of times to duplicate the row?
PRUint8 aDrawMode, // il_draw_mode
int aInterlacePass) // interlace pass (1-4)
{
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
PRUint32 bpr, abpr;
// We have to delay allocation of the image frame until now because
// we won't have control block info (transparency) until now. The conrol
// block of a GIF stream shows up after the image header since transparency
// is added in GIF89a and control blocks are how the extensions are done.
// How annoying.
if(! decoder->mImageFrame) {
gfx_format format = gfxIFormats::RGB;
if (decoder->mGIFStruct->is_transparent)
format = gfxIFormats::RGB_A1;
#ifdef XP_PC
// XXX this works...
format += 1; // RGB to BGR
#endif
// initalize the frame and append it to the container
decoder->mImageFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
decoder->mImageFrame->Init(
decoder->mGIFStruct->x_offset, decoder->mGIFStruct->y_offset,
decoder->mGIFStruct->width, decoder->mGIFStruct->height, format);
decoder->mImageContainer->AppendFrame(decoder->mImageFrame);
if (decoder->mObserver)
decoder->mObserver->OnStartFrame(nsnull, nsnull, decoder->mImageFrame);
decoder->mImageFrame->GetImageBytesPerRow(&bpr);
decoder->mImageFrame->GetAlphaBytesPerRow(&abpr);
if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
if (decoder->mAlphaLine)
nsMemory::Free(decoder->mAlphaLine);
decoder->mAlphaLine = (PRUint8 *)nsMemory::Alloc(abpr);
}
} else {
decoder->mImageFrame->GetImageBytesPerRow(&bpr);
decoder->mImageFrame->GetAlphaBytesPerRow(&abpr);
}
if (aRowBufPtr) {
nscoord width;
decoder->mImageFrame->GetWidth(&width);
PRUint32 iwidth = width;
gfx_format format;
decoder->mImageFrame->GetFormat(&format);
// XXX map the data into colors
int cmapsize;
GIF_RGB* cmap;
if(decoder->mGIFStruct->local_colormap) {
cmapsize = decoder->mGIFStruct->local_colormap_size;
cmap = decoder->mGIFStruct->local_colormap;
} else {
cmapsize = decoder->mGIFStruct->global_colormap_size;
cmap = decoder->mGIFStruct->global_colormap;
}
PRUint8* rgbRowIndex = aRGBrowBufPtr;
PRUint8* rowBufIndex = aRowBufPtr;
switch (format) {
case gfxIFormats::RGB:
{
while(rowBufIndex != decoder->mGIFStruct->rowend) {
#ifdef XP_MAC
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
#endif
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
++rowBufIndex;
}
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
}
break;
case gfxIFormats::BGR:
{
while(rowBufIndex != decoder->mGIFStruct->rowend) {
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
++rowBufIndex;
}
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
}
break;
case gfxIFormats::RGB_A1:
case gfxIFormats::BGR_A1:
{
memset(aRGBrowBufPtr, 0, bpr);
memset(decoder->mAlphaLine, 0, abpr);
PRUint32 iwidth = (PRUint32)width;
for (PRUint32 x=0; x<iwidth; x++) {
if (*rowBufIndex != decoder->mGIFStruct->tpixel) {
#ifdef XP_PC
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
#else
#ifdef XP_MAC
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
#endif
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
#endif
decoder->mAlphaLine[x>>3] |= 1<<(7-x&0x7);
} else {
#ifdef XP_MAC
rgbRowIndex+=4;
#else
rgbRowIndex+=3;
#endif
}
++rowBufIndex;
}
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine, abpr, aRowNumber*abpr);
}
break;
default:
break;
}
nsRect r(0, aRowNumber, width, 1);
decoder->mObserver->OnDataAvailable(nsnull, nsnull, decoder->mImageFrame, &r);
}
return 0;
}
//******************************************************************************
int ResetPalette()
{
return 0;
}
//******************************************************************************
int SetupColorspaceConverter()
{
return 0;
}
//******************************************************************************
int EndImageFrame()
{
return 0;
}
//******************************************************************************
int NewPixmap()
{
return 0;
}
//******************************************************************************
int InitTransparentPixel()
{
return 0;
}
//******************************************************************************
int DestroyTransparentPixel()
{
return 0;
}

View File

@@ -0,0 +1,114 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Chris Saari <saari@netscape.com>
*/
#ifndef _nsGIFDecoder2_h
#define _nsGIFDecoder2_h
#include "nsCOMPtr.h"
#include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#include "GIF2.h"
#define NS_GIFDECODER2_CID \
{ /* 797bec5a-1dd2-11b2-a7f8-ca397e0179c4 */ \
0x797bec5a, \
0x1dd2, \
0x11b2, \
{0xa7, 0xf8, 0xca, 0x39, 0x7e, 0x01, 0x79, 0xc4} \
}
//////////////////////////////////////////////////////////////////////
// nsGIFDecoder2 Definition
class nsGIFDecoder2 : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsGIFDecoder2();
virtual ~nsGIFDecoder2();
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
NS_METHOD ProcessData(unsigned char *data, PRUint32 count);
nsCOMPtr<imgIContainer> mImageContainer;
nsCOMPtr<gfxIImageFrame> mImageFrame;
nsCOMPtr<imgIRequest> mImageRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
gif_struct *mGIFStruct;
PRUint8 *mAlphaLine;
};
// static callbacks for the GIF decoder
static int PR_CALLBACK BeginGIF(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aBackgroundRGBIndex);
static int PR_CALLBACK HaveDecodedRow(
void* aClientData,
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
int aXOffset, // With respect to GIF logical screen origin
int aLength, // Length of the row?
int aRow, // Row number?
int aDuplicateCount, // Number of times to duplicate the row?
PRUint8 aDrawMode, // il_draw_mode
int aInterlacePass);
static int PR_CALLBACK NewPixmap();
static int PR_CALLBACK EndGIF(
void* aClientData,
int aAnimationLoopCount);
static int PR_CALLBACK BeginImageFrame(
void* aClientData,
PRUint32 aFrameNumber, /* Frame number, 1-n */
PRUint32 aFrameXOffset, /* X offset in logical screen */
PRUint32 aFrameYOffset, /* Y offset in logical screen */
PRUint32 aFrameWidth,
PRUint32 aFrameHeight,
GIF_RGB* aTransparencyChromaKey);
static int PR_CALLBACK EndImageFrame(
void* aClientData,
PRUint32 aFrameNumber,
PRUint32 aDelayTimeout);
static int PR_CALLBACK SetupColorspaceConverter();
static int PR_CALLBACK ResetPalette();
static int PR_CALLBACK InitTransparentPixel();
static int PR_CALLBACK DestroyTransparentPixel();
static int PR_CALLBACK HaveImageAll(
void* aClientData);
#endif

View File

@@ -0,0 +1,41 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Chris Saari <saari@netscape.com>
*/
#include "nsGIFDecoder2.h"
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIFDecoder2)
static nsModuleComponentInfo components[] =
{
{ "GIF Decoder",
NS_GIFDECODER2_CID,
"@mozilla.org/image/decoder;2?type=image/gif",
nsGIFDecoder2Constructor, },
};
NS_IMPL_NSGETMODULE("nsGIFModule2", components)

View File

@@ -0,0 +1,18 @@
?AddRef@nsGIFDecoder2@@UAGKXZ ; 2550
?Release@nsGIFDecoder2@@UAGKXZ ; 2550
?gif_write_ready@@YAEPAUgif_struct@@@Z ; 1624
?ProcessData@nsGIFDecoder2@@QAGIPAEI@Z ; 1624
?gif_write@@YAHPAUgif_struct@@PBEI@Z ; 1624
?WriteFrom@nsGIFDecoder2@@UAGIPAVnsIInputStream@@IPAI@Z ; 1309
?Close@nsGIFDecoder2@@UAGIXZ ; 1275
??_GnsGIFDecoder2@@UAEPAXI@Z ; 1275
??0nsGIFDecoder2@@QAE@XZ ; 1275
??1nsGIFDecoder2@@UAE@XZ ; 1275
?QueryInterface@nsGIFDecoder2@@UAGIABUnsID@@PAPAX@Z ; 1275
?GIFInit@@YAHPAUgif_struct@@PAXP6AHXZP6AH1IIE@ZP6AH1H@ZP6AH1IIIIIPAU_GIF_RGB@@@ZP6AH1II@Z2222P6AH1PAE8HHHHEH@ZP6AH1@Z@Z ; 1275
?Init@nsGIFDecoder2@@UAGIPAVimgIRequest@@@Z ; 1275
?Flush@nsGIFDecoder2@@UAGIXZ ; 1275
?gif_destroy@@YAXPAUgif_struct@@@Z ; 1275
?gif_create@@YAHPAPAUgif_struct@@@Z ; 1275
?il_BACat@@YAPADPAPADIPBDI@Z ; 698
_NSGetModule ; 1

View File

@@ -0,0 +1,378 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIconChannel.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsXPIDLString.h"
#include "nsMimeTypes.h"
#include "nsMemory.h"
#include "nsIStringStream.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIMimeService.h"
#include "nsCExternalHandlerService.h"
#include "plstr.h"
#include <Files.h>
#include <QuickDraw.h>
// nsIconChannel methods
nsIconChannel::nsIconChannel()
{
NS_INIT_REFCNT();
mStatus = NS_OK;
}
nsIconChannel::~nsIconChannel()
{}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsIconChannel,
nsIChannel,
nsIRequest)
nsresult nsIconChannel::Init(nsIURI* uri)
{
nsresult rv;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP nsIconChannel::GetName(PRUnichar* *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsIconChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv = NS_ERROR_FAILURE;
mStatus = status;
return rv;
}
NS_IMETHODIMP nsIconChannel::Suspend(void)
{
NS_NOTREACHED("nsIconChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::Resume(void)
{
NS_NOTREACHED("nsIconChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetURI(nsIURI* aURI)
{
mUrl = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::Open(nsIInputStream **_retval)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
// get the file name from the url
nsXPIDLCString fileName; // will contain a dummy file we'll use to figure out the type of icon desired.
nsXPIDLCString filePath; // will contain an optional parameter for small vs. large icon. default is small
mUrl->GetHost(getter_Copies(fileName));
nsCOMPtr<nsIURL> url (do_QueryInterface(mUrl));
if (url)
url->GetFileBaseName(getter_Copies(filePath));
nsresult rv = NS_OK;
nsCOMPtr<nsIMIMEService> mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
// extract the extension out of the dummy file so we can look it up in the mime service.
char * chFileName = fileName.get(); // get the underlying buffer
char * fileExtension = PL_strrchr(chFileName, '.');
if (!fileExtension) return NS_ERROR_FAILURE; // no file extension to work from.
// look the file extension up in the registry.
nsCOMPtr<nsIMIMEInfo> mimeInfo;
mimeService->GetFromExtension(fileExtension, getter_AddRefs(mimeInfo));
NS_ENSURE_TRUE(mimeInfo, NS_ERROR_FAILURE);
// get the mac creator and file type for this mime object
PRUint32 macType;
PRUint32 macCreator;
mimeInfo->GetMacType(&macType);
mimeInfo->GetMacCreator(&macCreator);
// get a refernce to the desktop database
DTPBRec pb;
OSErr err = noErr;
memset(&pb, 0, sizeof(DTPBRec));
pb.ioCompletion = nil;
pb.ioVRefNum = 0; // default desktop volume
pb.ioNamePtr = nil;
err = PBDTGetPath(&pb);
if (err != noErr) return NS_ERROR_FAILURE;
pb.ioFileCreator = macCreator;
pb.ioFileType = macType;
pb.ioCompletion = nil;
pb.ioTagInfo = 0;
PRUint32 numPixelsInRow = 0;
if (filePath && !nsCRT::strcmp(filePath, "large"))
{
pb.ioDTReqCount = kLarge8BitIconSize;
pb.ioIconType = kLarge8BitIcon;
numPixelsInRow = 32;
}
else
{
pb.ioDTReqCount = kSmall8BitIconSize;
pb.ioIconType = kSmall8BitIcon;
numPixelsInRow = 16;
}
// allocate a buffer large enough to handle the icon
PRUint8 * bitmapData = (PRUint8 *) nsMemory::Alloc (pb.ioDTReqCount);
pb.ioDTBuffer = (Ptr) bitmapData;
err = PBDTGetIcon(&pb, false);
if (err != noErr) return NS_ERROR_FAILURE; // unable to fetch the icon....
nsCString iconBuffer;
iconBuffer.Assign((char) numPixelsInRow);
iconBuffer.Append((char) numPixelsInRow);
CTabHandle cTabHandle = GetCTable(72);
if (!cTabHandle) return NS_ERROR_FAILURE;
HLock((Handle) cTabHandle);
CTabPtr colTable = *cTabHandle;
RGBColor rgbCol;
PRUint8 redValue, greenValue, blueValue;
for (PRUint32 index = 0; index < pb.ioDTReqCount; index ++)
{
// each byte in bitmapData needs to be converted from an 8 bit system color into
// 24 bit RGB data which our special icon image decoder can understand.
ColorSpec colSpec = colTable->ctTable[ bitmapData[index]];
rgbCol = colSpec.rgb;
redValue = rgbCol.red & 0xff;
greenValue = rgbCol.green & 0xff;
blueValue = rgbCol.blue & 0xff;
// for some reason the image code on the mac expects each RGB pixel value to be padded with a preceding byte.
// so add the padding here....
iconBuffer.Append((char) 0);
iconBuffer.Append((char) redValue);
iconBuffer.Append((char) greenValue);
iconBuffer.Append((char) blueValue);
}
HUnlock((Handle) cTabHandle);
DisposeCTable(cTabHandle);
nsMemory::Free(bitmapData);
// now that the color bitmask is taken care of, we need to do the same thing again for the transparency
// bit mask....
if (filePath && !nsCRT::strcmp(filePath, "large"))
{
pb.ioDTReqCount = kLargeIconSize;
pb.ioIconType = kLargeIcon;
}
else
{
pb.ioDTReqCount = kSmallIconSize;
pb.ioIconType = kSmallIcon;
}
// allocate a buffer large enough to handle the icon
bitmapData = (PRUint8 *) nsMemory::Alloc (pb.ioDTReqCount);
pb.ioDTBuffer = (Ptr) bitmapData;
err = PBDTGetIcon(&pb, false);
PRUint32 index = pb.ioDTReqCount/2;
while (index < pb.ioDTReqCount)
{
iconBuffer.Append((char) bitmapData[index]);
iconBuffer.Append((char) bitmapData[index + 1]);
if (numPixelsInRow == 32)
{
iconBuffer.Append((char) bitmapData[index + 2]);
iconBuffer.Append((char) bitmapData[index + 3]);
index += 4;
}
else
{
iconBuffer.Append((char) 255); // 2 bytes of padding
iconBuffer.Append((char) 255);
index += 2;
}
}
nsMemory::Free(bitmapData);
// turn our nsString into a stream looking object...
aListener->OnStartRequest(this, ctxt);
// turn our string into a stream...
nsCOMPtr<nsISupports> streamSupports;
NS_NewByteInputStream(getter_AddRefs(streamSupports), iconBuffer.get(), iconBuffer.Length());
nsCOMPtr<nsIInputStream> inputStr (do_QueryInterface(streamSupports));
aListener->OnDataAvailable(this, ctxt, inputStr, 0, iconBuffer.Length());
aListener->OnStopRequest(this, ctxt, NS_OK, nsnull);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetContentType(char* *aContentType)
{
if (!aContentType) return NS_ERROR_NULL_POINTER;
*aContentType = nsCRT::strdup("image/icon");
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetContentType(const char *aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsIconChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#ifndef nsIconChannel_h___
#define nsIconChannel_h___
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIURI.h"
class nsIconChannel : public nsIChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
nsIconChannel();
virtual ~nsIconChannel();
nsresult Init(nsIURI* uri);
protected:
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIURI> mOriginalURI;
PRUint32 mLoadAttributes;
PRInt32 mContentLength;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsISupports> mOwner;
nsresult mStatus;
};
#endif /* nsIconChannel_h___ */

View File

@@ -0,0 +1,62 @@
#!nmake
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Scott MacGregor <mscott@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
DIR=win
MODULE = imgicon
LIBRARY_NAME = imgicon
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsIconDecoder.obj \
.\$(OBJDIR)\nsIconModule.obj \
.\$(OBJDIR)\nsIconProtocolHandler.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(DIST)\lib\imgiconwin_s.lib \
$(NULL)
WIN_LIBS= shell32.lib
INCS = $(INCS) \
-I$(DEPTH)\dist\include \
-I$(DEPTH)\modules\libpr0n\decoders\icon\win \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,195 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*
*/
#include "nsIconDecoder.h"
#include "nsIInputStream.h"
#include "imgIContainer.h"
#include "imgIContainerObserver.h"
#include "nspr.h"
#include "nsIComponentManager.h"
#include "nsRect.h"
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder);
NS_IMPL_THREADSAFE_RELEASE(nsIconDecoder);
NS_INTERFACE_MAP_BEGIN(nsIconDecoder)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIOutputStream)
NS_INTERFACE_MAP_ENTRY(nsIOutputStream)
NS_INTERFACE_MAP_ENTRY(imgIDecoder)
NS_INTERFACE_MAP_END_THREADSAFE
nsIconDecoder::nsIconDecoder()
{
NS_INIT_ISUPPORTS();
}
nsIconDecoder::~nsIconDecoder()
{ }
/** imgIDecoder methods **/
NS_IMETHODIMP nsIconDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImage));
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
if (!mFrame) return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP nsIconDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
NS_IMETHODIMP nsIconDecoder::Close()
{
if (mObserver)
{
mObserver->OnStopFrame(nsnull, nsnull, mFrame);
mObserver->OnStopContainer(nsnull, nsnull, mImage);
mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
return NS_OK;
}
NS_IMETHODIMP nsIconDecoder::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
nsresult rv;
char *buf = (char *)PR_Malloc(count);
if (!buf) return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
// read the data from the input stram...
PRUint32 readLen;
rv = inStr->Read(buf, count, &readLen);
char *data = buf;
if (NS_FAILED(rv)) return rv;
// since WriteFrom is only called once, go ahead and fire the on start notifications..
mObserver->OnStartDecode(nsnull, nsnull);
PRUint32 i = 0;
// Read size
PRInt32 w, h;
w = data[0];
h = data[1];
data += 2;
readLen -= i + 2;
mImage->Init(w, h, mObserver);
if (mObserver)
mObserver->OnStartContainer(nsnull, nsnull, mImage);
mFrame->Init(0, 0, w, h, gfxIFormats::RGB_A1);
mImage->AppendFrame(mFrame);
if (mObserver)
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
PRUint32 bpr, abpr;
nscoord width, height;
mFrame->GetImageBytesPerRow(&bpr);
mFrame->GetAlphaBytesPerRow(&abpr);
mFrame->GetWidth(&width);
mFrame->GetHeight(&height);
i = 0;
PRInt32 rownum = 0; // XXX this better not have a decimal
PRInt32 wroteLen = 0;
do
{
PRUint8 *line = (PRUint8*)data + i*bpr;
mFrame->SetImageData(line, bpr, (rownum++)*bpr);
nsRect r(0, rownum, width, 1);
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
wroteLen += bpr ;
i++;
} while(rownum < height);
// now we want to send in the alpha data...
for (rownum = 0; rownum < height; rownum ++)
{
PRUint8 * line = (PRUint8*) data + abpr * rownum + height*bpr;
mFrame->SetAlphaData(line, abpr, (rownum)*abpr);
}
PR_FREEIF(buf);
return NS_OK;
}
NS_IMETHODIMP nsIconDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#ifndef nsIconDecoder_h__
#define nsIconDecoder_h__
#include "imgIDecoder.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#define NS_ICONDECODER_CID \
{ /* FFC08380-256C-11d5-9905-001083010E9B */ \
0xffc08380, \
0x256c, \
0x11d5, \
{ 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } \
}
//////////////////////////////////////////////////////////////////////////////////////////////
// The icon decoder is a decoder specifically tailored for loading icons
// from the OS. We've defined our own little format to represent these icons
// and this decoder takes that format and converts it into 24-bit RGB with alpha channel
// support. It was modeled a bit off the PPM decoder.
//
// Assumptions about the decoder:
// (1) We receive ALL of the data from the icon channel in one OnDataAvailable call. We don't
// support multiple ODA calls yet.
// (2) the format of the incoming data is as follows:
// The first two bytes contain the width and the height of the icon.
// Followed by 3 bytes per pixel for the color bitmap row after row. (for heigh * width * 3 bytes)
// Followed by bit mask data (used for transparency on the alpha channel).
//
//
//////////////////////////////////////////////////////////////////////////////////////////////
class nsIconDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsIconDecoder();
virtual ~nsIconDecoder();
private:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
};
#endif // nsIconDecoder_h__

View File

@@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsIconDecoder.h"
#include "nsIconProtocolHandler.h"
// objects that just require generic constructors
/******************************************************************************
* Protocol CIDs
*/
#define NS_ICONPROTOCOL_CID { 0xd0f9db12, 0x249c, 0x11d5, { 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } }
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconDecoder)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconProtocolHandler)
static nsModuleComponentInfo components[] =
{
{ "icon decoder",
NS_ICONDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/icon",
nsIconDecoderConstructor, },
{ "Icon Protocol Handler",
NS_ICONPROTOCOL_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "icon",
nsIconProtocolHandlerConstructor
}
};
NS_IMPL_NSGETMODULE("nsIconDecoderModule", components)

View File

@@ -0,0 +1,90 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIconChannel.h"
#include "nsIconProtocolHandler.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kStandardURICID, NS_STANDARDURL_CID);
////////////////////////////////////////////////////////////////////////////////
nsIconProtocolHandler::nsIconProtocolHandler()
{
NS_INIT_REFCNT();
}
nsIconProtocolHandler::~nsIconProtocolHandler()
{}
NS_IMPL_ISUPPORTS2(nsIconProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference)
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
NS_IMETHODIMP nsIconProtocolHandler::GetScheme(char* *result)
{
*result = nsCRT::strdup("icon");
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP nsIconProtocolHandler::GetDefaultPort(PRInt32 *result)
{
*result = 0;
return NS_OK;
}
NS_IMETHODIMP nsIconProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI, nsIURI **result)
{
nsresult rv;
// no concept of a relative icon url
NS_ASSERTION(!aBaseURI, "base url passed into icon protocol handler");
nsCOMPtr<nsIURI> url = do_CreateInstance(kStandardURICID, &rv);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
*result = url;
NS_IF_ADDREF(*result);
return rv;
}
NS_IMETHODIMP nsIconProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result)
{
nsCOMPtr<nsIChannel> channel;
NS_NEWXPCOM(channel, nsIconChannel);
if (channel)
NS_STATIC_CAST(nsIconChannel*,NS_STATIC_CAST(nsIChannel*, channel))->Init(url);
*result = channel;
NS_IF_ADDREF(*result);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#ifndef nsIconProtocolHandler_h___
#define nsIconProtocolHandler_h___
#include "nsWeakReference.h"
#include "nsIProtocolHandler.h"
class nsIconProtocolHandler : public nsIProtocolHandler, public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
// nsIconProtocolHandler methods:
nsIconProtocolHandler();
virtual ~nsIconProtocolHandler();
protected:
};
#endif /* nsIconProtocolHandler_h___ */

View File

@@ -0,0 +1,46 @@
#!gmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Scott MacGregor <mscott@netscape.com>
DEPTH=..\..\..\..\..
MODULE=imgicon
LIBRARY_NAME=imgiconwin_s
CPP_OBJS=\
.\$(OBJDIR)\nsIconChannel.obj \
$(NULL)
INCS = $(INCS) \
-I$(DEPTH)\dist\include \
-I..\ \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,377 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#include "nsIconChannel.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsXPIDLString.h"
#include "nsMimeTypes.h"
#include "nsMemory.h"
#include "nsIStringStream.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
// we need windows.h to read out registry information...
#include <windows.h>
#include <shellapi.h>
// nsIconChannel methods
nsIconChannel::nsIconChannel()
{
NS_INIT_REFCNT();
mStatus = NS_OK;
}
nsIconChannel::~nsIconChannel()
{}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsIconChannel,
nsIChannel,
nsIRequest)
nsresult nsIconChannel::Init(nsIURI* uri)
{
nsresult rv;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP nsIconChannel::GetName(PRUnichar* *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsIconChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv = NS_ERROR_FAILURE;
mStatus = status;
return rv;
}
NS_IMETHODIMP nsIconChannel::Suspend(void)
{
NS_NOTREACHED("nsIconChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::Resume(void)
{
NS_NOTREACHED("nsIconChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetURI(nsIURI* aURI)
{
mUrl = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::Open(nsIInputStream **_retval)
{
return NS_ERROR_FAILURE;
}
void InvertRows(unsigned char * aInitialBuffer, PRUint32 sizeOfBuffer, PRUint32 numBytesPerRow)
{
PRUint32 numRows = sizeOfBuffer / numBytesPerRow;
void * temporaryRowHolder = (void *) nsMemory::Alloc(numBytesPerRow);
PRUint32 currentRow = 0;
PRUint32 lastRow = (numRows - 1) * numBytesPerRow;
while (currentRow < lastRow)
{
// store the current row into a temporary buffer
nsCRT::memcpy(temporaryRowHolder, (void *) &aInitialBuffer[currentRow], numBytesPerRow);
nsCRT::memcpy((void *) &aInitialBuffer[currentRow], (void *)&aInitialBuffer[lastRow], numBytesPerRow);
nsCRT::memcpy((void *) &aInitialBuffer[lastRow], temporaryRowHolder, numBytesPerRow);
lastRow -= numBytesPerRow;
currentRow += numBytesPerRow;
}
}
NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
// get the file name from the url
nsXPIDLCString fileName; // will contain a dummy file we'll use to figure out the type of icon desired.
nsXPIDLCString filePath; // will contain an optional parameter for small vs. large icon. default is small
mUrl->GetHost(getter_Copies(fileName));
nsCOMPtr<nsIURL> url (do_QueryInterface(mUrl));
if (url)
url->GetFileBaseName(getter_Copies(filePath));
// 1) get a hIcon for the file.
SHFILEINFO sfi;
UINT infoFlags = SHGFI_USEFILEATTRIBUTES | SHGFI_ICON;
if (filePath && !nsCRT::strcmp(filePath, "large"))
infoFlags |= SHGFI_LARGEICON;
else // default to small
infoFlags |= SHGFI_SMALLICON;
LONG result= SHGetFileInfo(fileName, FILE_ATTRIBUTE_ARCHIVE, &sfi, sizeof(sfi), infoFlags);
if (result > 0 && sfi.hIcon)
{
// we got a handle to an icon. Now we want to get a bitmap for the icon using GetIconInfo....
ICONINFO pIconInfo;
result = GetIconInfo(sfi.hIcon, &pIconInfo);
if (result > 0)
{
// now we have the bit map we need to get info about the bitmap
BITMAPINFO pBitMapInfo;
BITMAPINFOHEADER pBitMapInfoHeader;
pBitMapInfo.bmiHeader.biBitCount = 0;
pBitMapInfo.bmiHeader.biSize = sizeof(pBitMapInfoHeader);
HDC pDC = CreateCompatibleDC(NULL); // get a device context for the screen.
result = GetDIBits(pDC, pIconInfo.hbmColor, 0, 0, NULL, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0 && pBitMapInfo.bmiHeader.biSizeImage > 0)
{
// allocate a buffer to hold the bit map....this should be a buffer that's biSizeImage...
unsigned char * buffer = (PRUint8 *) nsMemory::Alloc(pBitMapInfo.bmiHeader.biSizeImage);
result = GetDIBits(pDC, pIconInfo.hbmColor, 0, pBitMapInfo.bmiHeader.biHeight, (void *) buffer, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0)
{
PRUint32 bytesPerPixel = pBitMapInfo.bmiHeader.biBitCount / 8;
InvertRows(buffer, pBitMapInfo.bmiHeader.biSizeImage, pBitMapInfo.bmiHeader.biWidth * bytesPerPixel);
// Convert our little icon buffer which is padded to 4 bytes per pixel into a nice 3 byte per pixel
// description.
nsCString iconBuffer;
iconBuffer.Assign((char) pBitMapInfo.bmiHeader.biWidth);
iconBuffer.Append((char) pBitMapInfo.bmiHeader.biHeight);
PRInt32 index = 0;
if (pBitMapInfo.bmiHeader.biBitCount == 16)
{
PRUint8 redValue, greenValue, blueValue, partialGreen;
while (index < pBitMapInfo.bmiHeader.biSizeImage)
{
DWORD dst=(DWORD) buffer[index];
PRUint16 num = 0;
num = (PRUint8) buffer[index];
num <<= 8;
num |= (PRUint8) buffer[index+1];
//blueValue = (PRUint8)((*dst)&(0x1F));
//greenValue = (PRUint8)(((*dst)>>5)&(0x1F));
//redValue = (PRUint8)(((*dst)>>10)&(0x1F));
redValue = ((PRUint32) (((float)(num & 0x7c00) / 0x7c00) * 0xFF0000) & 0xFF0000)>> 16;
greenValue = ((PRUint32)(((float)(num & 0x03E0) / 0x03E0) * 0x00FF00) & 0x00FF00)>> 8;
blueValue = ((PRUint32)(((float)(num & 0x001F) / 0x001F) * 0x0000FF) & 0x0000FF);
// now we have the right RGB values...
iconBuffer.Append((char) redValue);
iconBuffer.Append((char) greenValue);
iconBuffer.Append((char) blueValue);
index += bytesPerPixel;
}
}
else
{
while (index <pBitMapInfo.bmiHeader.biSizeImage)
{
iconBuffer.Append((char) buffer[index]);
iconBuffer.Append((char) buffer[index+1]);
iconBuffer.Append((char) buffer[index+2]);
index += bytesPerPixel;
}
}
// now we need to tack on the alpha data...which is hbmMask
pBitMapInfo.bmiHeader.biBitCount = 0;
pBitMapInfo.bmiHeader.biSize = sizeof(pBitMapInfoHeader);
result = GetDIBits(pDC, pIconInfo.hbmMask, 0, 0, NULL, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0 && pBitMapInfo.bmiHeader.biSizeImage > 0)
{
// allocate a buffer to hold the bit map....this should be a buffer that's biSizeImage...
unsigned char * maskBuffer = (PRUint8 *) nsMemory::Alloc(pBitMapInfo.bmiHeader.biSizeImage);
result = GetDIBits(pDC, pIconInfo.hbmMask, 0, pBitMapInfo.bmiHeader.biHeight, (void *) maskBuffer, &pBitMapInfo, DIB_RGB_COLORS);
if (result > 0)
{
InvertRows(maskBuffer, pBitMapInfo.bmiHeader.biSizeImage, 4);
index = 0;
// for some reason the bit mask on windows are flipped from the values we really want for transparency.
// So complement each byte in the bit mask.
while (index < pBitMapInfo.bmiHeader.biSizeImage)
{
maskBuffer[index]^=255;
index += 1;
}
iconBuffer.Append((char *) maskBuffer, pBitMapInfo.bmiHeader.biSizeImage);
}
nsMemory::Free(maskBuffer);
} // if we have a mask buffer to apply
// turn our nsString into a stream looking object...
aListener->OnStartRequest(this, ctxt);
// turn our string into a stream...
nsCOMPtr<nsISupports> streamSupports;
NS_NewByteInputStream(getter_AddRefs(streamSupports), iconBuffer.get(), iconBuffer.Length());
nsCOMPtr<nsIInputStream> inputStr (do_QueryInterface(streamSupports));
aListener->OnDataAvailable(this, ctxt, inputStr, 0, iconBuffer.Length());
aListener->OnStopRequest(this, ctxt, NS_OK, nsnull);
} // if we got valid bits for the main bitmap mask
nsMemory::Free(buffer);
}
DeleteDC(pDC);
}
}
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetContentType(char* *aContentType)
{
if (!aContentType) return NS_ERROR_NULL_POINTER;
*aContentType = nsCRT::strdup("image/icon");
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetContentType(const char *aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsIconChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP nsIconChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Brian Ryner.
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
* All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
*/
#ifndef nsIconChannel_h___
#define nsIconChannel_h___
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIURI.h"
class nsIconChannel : public nsIChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
nsIconChannel();
virtual ~nsIconChannel();
nsresult Init(nsIURI* uri);
protected:
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIURI> mOriginalURI;
PRUint32 mLoadAttributes;
PRInt32 mContentLength;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsISupports> mOwner;
nsresult mStatus;
};
#endif /* nsIconChannel_h___ */

View File

@@ -0,0 +1,42 @@
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imgjpeg
LIBRARY_NAME = imgjpeg
IS_COMPONENT = 1
REQUIRES = xpcom string necko layout jpeg gfx2 imglib2
CPPSRCS = nsJPEGDecoder.cpp nsJPEGFactory.cpp
EXTRA_DSO_LDOPTS = $(JPEG_LIBS) $(ZLIB_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,52 @@
#!nmake
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imgjpeg
LIBRARY_NAME = imgjpeg
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsJPEGDecoder.obj \
.\$(OBJDIR)\nsJPEGFactory.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\jpeg3250.lib \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,829 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*
*/
#include "nsJPEGDecoder.h"
#include "nsIInputStream.h"
#include "nspr.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "imgIContainerObserver.h"
#include "ImageLogging.h"
NS_IMPL_ISUPPORTS2(nsJPEGDecoder, imgIDecoder, nsIOutputStream)
#if defined(PR_LOGGING)
PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder");
#else
#define gJPEGlog
#endif
void PR_CALLBACK init_source (j_decompress_ptr jd);
boolean PR_CALLBACK fill_input_buffer (j_decompress_ptr jd);
void PR_CALLBACK skip_input_data (j_decompress_ptr jd, long num_bytes);
void PR_CALLBACK term_source (j_decompress_ptr jd);
void PR_CALLBACK my_error_exit (j_common_ptr cinfo);
/* Normal JFIF markers can't have more bytes than this. */
#define MAX_JPEG_MARKER_LENGTH (((PRUint32)1 << 16) - 1)
/* Possible states for JPEG source manager */
enum data_source_state {
READING_BACK = 0, /* Must be zero for init purposes */
READING_NEW
};
/*
* Implementation of a JPEG src object that understands our state machine
*/
typedef struct {
/* public fields; must be first in this struct! */
struct jpeg_source_mgr pub;
nsJPEGDecoder *decoder;
} decoder_source_mgr;
nsJPEGDecoder::nsJPEGDecoder()
{
NS_INIT_ISUPPORTS();
mState = JPEG_HEADER;
mFillState = READING_BACK;
mSamples = nsnull;
mSamples3 = nsnull;
mRGBPadRow = nsnull;
mRGBPadRowLength = 0;
mBytesToSkip = 0;
memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
mCompletedPasses = 0;
mBuffer = nsnull;
mBufferLen = mBufferSize = 0;
mBackBuffer = nsnull;
mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0;
}
nsJPEGDecoder::~nsJPEGDecoder()
{
if (mBuffer)
PR_Free(mBuffer);
if (mBackBuffer)
PR_Free(mBackBuffer);
if (mRGBPadRow)
PR_Free(mRGBPadRow);
}
/** imgIDecoder methods **/
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsJPEGDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(mRequest);
aRequest->GetImage(getter_AddRefs(mImage));
/* We set up the normal JPEG error routines, then override error_exit. */
mInfo.err = jpeg_std_error(&mErr.pub);
/* mInfo.err = jpeg_std_error(&mErr.pub); */
mErr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(mErr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
return NS_ERROR_FAILURE;
}
/* Step 1: allocate and initialize JPEG decompression object */
jpeg_create_decompress(&mInfo);
decoder_source_mgr *src;
if (mInfo.src == NULL) {
//mInfo.src = PR_NEWZAP(decoder_source_mgr);
src = PR_NEWZAP(decoder_source_mgr);
if (!src) {
return PR_FALSE;
}
mInfo.src = (struct jpeg_source_mgr *) src;
}
/* Step 2: specify data source (eg, a file) */
/* Setup callback functions. */
src->pub.init_source = init_source;
src->pub.fill_input_buffer = fill_input_buffer;
src->pub.skip_input_data = skip_input_data;
src->pub.resync_to_restart = jpeg_resync_to_restart;
src->pub.term_source = term_source;
src->decoder = this;
return NS_OK;
}
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsJPEGDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
/* void close (); */
NS_IMETHODIMP nsJPEGDecoder::Close()
{
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::Close\n", this));
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER)
NS_WARNING("Never finished decoding the JPEG.");
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(&mInfo);
return NS_OK;
}
/* void flush (); */
NS_IMETHODIMP nsJPEGDecoder::Flush()
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::Flush");
PRUint32 ret;
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER)
return this->WriteFrom(nsnull, 0, &ret);
return NS_OK;
}
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsJPEGDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
LOG_SCOPE_WITH_PARAM(gJPEGlog, "nsJPEGDecoder::WriteFrom", "count", count);
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
// XXX above what is this?
if (inStr) {
if (!mBuffer) {
mBuffer = (JOCTET *)PR_Malloc(count);
mBufferSize = count;
} else if (count > mBufferSize) {
mBuffer = (JOCTET *)PR_Realloc(mBuffer, count);
mBufferSize = count;
}
nsresult rv = inStr->Read((char*)mBuffer, count, &mBufferLen);
*_retval = mBufferLen;
//nsresult rv = mOutStream->WriteFrom(inStr, count, _retval);
NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- mOutStream->WriteFrom failed");
}
// else no input stream.. Flush() ?
nsresult error_code = NS_ERROR_FAILURE;
/* Return here if there is a fatal error. */
if ((error_code = setjmp(mErr.setjmp_buffer)) != 0) {
return error_code;
}
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::WriteFrom -- processing JPEG data\n", this));
decoder_source_mgr *src = NS_REINTERPRET_CAST(decoder_source_mgr *, mInfo.src);
switch (mState) {
case JPEG_HEADER:
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_HEADER case");
/* Step 3: read file parameters with jpeg_read_header() */
if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED)
return NS_OK; /* I/O suspension */
/*
* Don't allocate a giant and superfluous memory buffer
* when the image is a sequential JPEG.
*/
mInfo.buffered_image = jpeg_has_multiple_scans(&mInfo);
/* Used to set up image size so arrays can be allocated */
jpeg_calc_output_dimensions(&mInfo);
mObserver->OnStartDecode(nsnull, nsnull);
mImage->Init(mInfo.image_width, mInfo.image_height, mObserver);
mObserver->OnStartContainer(nsnull, nsnull, mImage);
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
gfx_format format;
#ifdef XP_PC
format = gfxIFormats::BGR;
#else
format = gfxIFormats::RGB;
#endif
mFrame->Init(0, 0, mInfo.image_width, mInfo.image_height, format);
mImage->AppendFrame(mFrame);
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
/*
* Make a one-row-high sample array that will go away
* when done with image. Always make it big enough to
* hold an RGB row. Since this uses the IJG memory
* manager, it must be allocated before the call to
* jpeg_start_compress().
*/
int row_stride;
if(mInfo.output_components == 1)
row_stride = mInfo.output_width;
else
row_stride = mInfo.output_width * 4; // use 4 instead of mInfo.output_components
// so we don't have to fuss with byte alignment.
// Mac wants 4 anyways.
mSamples = (*mInfo.mem->alloc_sarray)((j_common_ptr) &mInfo,
JPOOL_IMAGE,
row_stride, 1);
#if defined(XP_PC) || defined(XP_MAC)
// allocate buffer to do byte flipping if needed
if (mInfo.output_components == 3) {
mRGBPadRow = (PRUint8*) PR_MALLOC(row_stride);
mRGBPadRowLength = row_stride;
memset(mRGBPadRow, 0, mRGBPadRowLength);
}
#endif
/* Allocate RGB buffer for conversion from greyscale. */
if (mInfo.output_components != 3) {
row_stride = mInfo.output_width * 4;
mSamples3 = (*mInfo.mem->alloc_sarray)((j_common_ptr) &mInfo,
JPOOL_IMAGE,
row_stride, 1);
}
mState = JPEG_START_DECOMPRESS;
}
case JPEG_START_DECOMPRESS:
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_START_DECOMPRESS case");
/* Step 4: set parameters for decompression */
/* FIXME -- Should reset dct_method and dither mode
* for final pass of progressive JPEG
*/
mInfo.dct_method = JDCT_FASTEST;
mInfo.dither_mode = JDITHER_ORDERED;
mInfo.do_fancy_upsampling = FALSE;
mInfo.enable_2pass_quant = FALSE;
mInfo.do_block_smoothing = TRUE;
/* Step 5: Start decompressor */
if (jpeg_start_decompress(&mInfo) == FALSE)
return NS_OK; /* I/O suspension */
/* If this is a progressive JPEG ... */
if (mInfo.buffered_image) {
mState = JPEG_DECOMPRESS_PROGRESSIVE;
} else {
mState = JPEG_DECOMPRESS_SEQUENTIAL;
}
}
case JPEG_DECOMPRESS_SEQUENTIAL:
{
if (mState == JPEG_DECOMPRESS_SEQUENTIAL)
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_SEQUENTIAL case");
if (OutputScanlines(-1) == PR_FALSE)
return NS_OK; /* I/O suspension */
/* If we've completed image output ... */
NS_ASSERTION(mInfo.output_scanline == mInfo.output_height, "We didn't process all of the data!");
mState = JPEG_DONE;
}
}
case JPEG_DECOMPRESS_PROGRESSIVE:
{
if (mState == JPEG_DECOMPRESS_PROGRESSIVE)
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_PROGRESSIVE case");
int status;
do {
status = jpeg_consume_input(&mInfo);
} while (!((status == JPEG_SUSPENDED) ||
(status == JPEG_REACHED_EOI)));
switch (status) {
case JPEG_REACHED_EOI:
// End of image
mState = JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT;
break;
case JPEG_SUSPENDED:
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::WriteFrom -- suspending\n", this));
return NS_OK; /* I/O suspension */
default:
printf("got someo other state!?\n");
}
}
}
case JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT:
{
if (mState == JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT)
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT case");
// XXX progressive? ;)
// not really progressive according to the state machine... -saari
jpeg_start_output(&mInfo, mInfo.input_scan_number);
if (OutputScanlines(-1) == PR_FALSE)
return NS_OK; /* I/O suspension */
jpeg_finish_output(&mInfo);
mState = JPEG_DONE;
}
}
case JPEG_DONE:
{
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_DONE case");
/* Step 7: Finish decompression */
if (jpeg_finish_decompress(&mInfo) == FALSE)
return NS_OK; /* I/O suspension */
mState = JPEG_SINK_NON_JPEG_TRAILER;
/* we're done dude */
break;
}
case JPEG_SINK_NON_JPEG_TRAILER:
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::WriteFrom -- entering JPEG_SINK_NON_JPEG_TRAILER case\n", this));
break;
}
return NS_OK;
}
int
nsJPEGDecoder::OutputScanlines(int num_scanlines)
{
int pass = 0;
if (mState == JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT)
pass = -1;
else
pass = mCompletedPasses + 1;
while ((mInfo.output_scanline < mInfo.output_height) && num_scanlines--) {
JSAMPROW samples;
/* Request one scanline. Returns 0 or 1 scanlines. */
int ns = jpeg_read_scanlines(&mInfo, mSamples, 1);
if (ns != 1) {
return PR_FALSE; /* suspend */
}
/* If grayscale image ... */
if (mInfo.output_components == 1) {
JSAMPLE j;
JSAMPLE *j1 = mSamples[0];
const JSAMPLE *j1end = j1 + mInfo.output_width;
JSAMPLE *j3 = mSamples3[0];
/* Convert from grayscale to RGB. */
while (j1 < j1end) {
#ifdef XP_MAC
j = *j1++;
j3[0] = 0;
j3[1] = j;
j3[2] = j;
j3[3] = j;
j3 += 4;
#else
j = *j1++;
j3[0] = j;
j3[1] = j;
j3[2] = j;
j3 += 3;
#endif
}
samples = mSamples3[0];
} else {
/* 24-bit color image */
#ifdef XP_PC
memset(mRGBPadRow, 0, mInfo.output_width * 4);
PRUint8 *ptrOutputBuf = mRGBPadRow;
JSAMPLE *j1 = mSamples[0];
for (PRUint32 i=0;i<mInfo.output_width;++i) {
ptrOutputBuf[2] = *j1++;
ptrOutputBuf[1] = *j1++;
ptrOutputBuf[0] = *j1++;
ptrOutputBuf += 3;
}
samples = mRGBPadRow;
#else
#ifdef XP_MAC
memset(mRGBPadRow, 0, mInfo.output_width * 4);
PRUint8 *ptrOutputBuf = mRGBPadRow;
JSAMPLE *j1 = mSamples[0];
for (PRUint32 i=0;i<mInfo.output_width;++i) {
ptrOutputBuf[0] = 0;
ptrOutputBuf[1] = *j1++;
ptrOutputBuf[2] = *j1++;
ptrOutputBuf[3] = *j1++;
ptrOutputBuf += 4;
}
samples = mRGBPadRow;
#else
samples = mSamples[0];
#endif
#endif
}
PRUint32 bpr;
mFrame->GetImageBytesPerRow(&bpr);
mFrame->SetImageData(
samples, // data
bpr, // length
(mInfo.output_scanline-1) * bpr); // offset
nsRect r(0, mInfo.output_scanline, mInfo.output_width, 1);
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
}
return PR_TRUE;
}
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsJPEGDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsJPEGDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsJPEGDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsJPEGDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsJPEGDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* Override the standard error method in the IJG JPEG decoder code. */
void PR_CALLBACK
my_error_exit (j_common_ptr cinfo)
{
nsresult error_code = NS_ERROR_FAILURE;
decoder_error_mgr *err = (decoder_error_mgr *) cinfo->err;
#if 0
#ifdef DEBUG
/*ptn fix later */
if (il_debug >= 1) {
char buffer[JMSG_LENGTH_MAX];
/* Create the message */
(*cinfo->err->format_message) (cinfo, buffer);
ILTRACE(1,("%s\n", buffer));
}
#endif
/* Convert error to a browser error code */
if (cinfo->err->msg_code == JERR_OUT_OF_MEMORY)
error_code = MK_OUT_OF_MEMORY;
else
error_code = MK_IMAGE_LOSSAGE;
#endif
char buffer[JMSG_LENGTH_MAX];
/* Create the message */
(*cinfo->err->format_message) (cinfo, buffer);
fprintf(stderr, "my_error_exit()\n%s\n", buffer);
/* Return control to the setjmp point. */
longjmp(err->setjmp_buffer, error_code);
}
/******************************************************************************/
/*-----------------------------------------------------------------------------
* This is the callback routine from the IJG JPEG library used to supply new
* data to the decompressor when its input buffer is exhausted. It juggles
* multiple buffers in an attempt to avoid unnecessary copying of input data.
*
* (A simpler scheme is possible: It's much easier to use only a single
* buffer; when fill_input_buffer() is called, move any unconsumed data
* (beyond the current pointer/count) down to the beginning of this buffer and
* then load new data into the remaining buffer space. This approach requires
* a little more data copying but is far easier to get right.)
*
* At any one time, the JPEG decompressor is either reading from the necko
* input buffer, which is volatile across top-level calls to the IJG library,
* or the "backtrack" buffer. The backtrack buffer contains the remaining
* unconsumed data from the necko buffer after parsing was suspended due
* to insufficient data in some previous call to the IJG library.
*
* When suspending, the decompressor will back up to a convenient restart
* point (typically the start of the current MCU). The variables
* next_input_byte & bytes_in_buffer indicate where the restart point will be
* if the current call returns FALSE. Data beyond this point must be
* rescanned after resumption, so it must be preserved in case the decompressor
* decides to backtrack.
*
* Returns:
* TRUE if additional data is available, FALSE if no data present and
* the JPEG library should therefore suspend processing of input stream
*---------------------------------------------------------------------------*/
/******************************************************************************/
/* data source manager method
/******************************************************************************/
/******************************************************************************/
/* data source manager method
Initialize source. This is called by jpeg_read_header() before any
data is actually read. May leave
bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
will occur immediately).
*/
void PR_CALLBACK
init_source (j_decompress_ptr jd)
{
}
/******************************************************************************/
/* data source manager method
Skip num_bytes worth of data. The buffer pointer and count should
be advanced over num_bytes input bytes, refilling the buffer as
needed. This is used to skip over a potentially large amount of
uninteresting data (such as an APPn marker). In some applications
it may be possible to optimize away the reading of the skipped data,
but it's not clear that being smart is worth much trouble; large
skips are uncommon. bytes_in_buffer may be zero on return.
A zero or negative skip count should be treated as a no-op.
*/
void PR_CALLBACK
skip_input_data (j_decompress_ptr jd, long num_bytes)
{
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
if (num_bytes > (long)src->pub.bytes_in_buffer) {
/*
* Can't skip it all right now until we get more data from
* network stream. Set things up so that fill_input_buffer
* will skip remaining amount.
*/
src->decoder->mBytesToSkip = (size_t)num_bytes - src->pub.bytes_in_buffer;
src->pub.next_input_byte += src->pub.bytes_in_buffer;
src->pub.bytes_in_buffer = 0;
} else {
/* Simple case. Just advance buffer pointer */
src->pub.bytes_in_buffer -= (size_t)num_bytes;
src->pub.next_input_byte += num_bytes;
}
}
/******************************************************************************/
/* data source manager method
This is called whenever bytes_in_buffer has reached zero and more
data is wanted. In typical applications, it should read fresh data
into the buffer (ignoring the current state of next_input_byte and
bytes_in_buffer), reset the pointer & count to the start of the
buffer, and return TRUE indicating that the buffer has been reloaded.
It is not necessary to fill the buffer entirely, only to obtain at
least one more byte. bytes_in_buffer MUST be set to a positive value
if TRUE is returned. A FALSE return should only be used when I/O
suspension is desired.
*/
boolean PR_CALLBACK
fill_input_buffer (j_decompress_ptr jd)
{
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
unsigned char *new_buffer = (unsigned char *)src->decoder->mBuffer;
PRUint32 new_buflen = src->decoder->mBufferLen;
PRUint32 bytesToSkip = src->decoder->mBytesToSkip;
switch(src->decoder->mFillState) {
case READING_BACK:
{
if (!new_buffer || new_buflen == 0)
return PR_FALSE; /* suspend */
src->decoder->mBufferLen = 0;
if (bytesToSkip != 0) {
if (bytesToSkip < new_buflen) {
/* All done skipping bytes; Return what's left. */
new_buffer += bytesToSkip;
new_buflen -= bytesToSkip;
src->decoder->mBytesToSkip = 0;
} else {
/* Still need to skip some more data in the future */
src->decoder->mBytesToSkip -= (size_t)new_buflen;
return PR_FALSE; /* suspend */
}
}
src->decoder->mBackBufferUnreadLen = src->pub.bytes_in_buffer;
src->pub.next_input_byte = new_buffer;
src->pub.bytes_in_buffer = (size_t)new_buflen;
src->decoder->mFillState = READING_NEW;
return PR_TRUE;
}
break;
case READING_NEW:
{
if (src->pub.next_input_byte != src->decoder->mBuffer) {
/* Backtrack data has been permanently consumed. */
src->decoder->mBackBufferUnreadLen = 0;
src->decoder->mBackBufferLen = 0;
}
/* Save remainder of netlib buffer in backtrack buffer */
PRUint32 new_backtrack_buflen = src->pub.bytes_in_buffer + src->decoder->mBackBufferLen;
/* Make sure backtrack buffer is big enough to hold new data. */
if (src->decoder->mBackBufferSize < new_backtrack_buflen) {
/* Round up to multiple of 16 bytes. */
PRUint32 roundup_buflen = ((new_backtrack_buflen + 15) >> 4) << 4;
if (src->decoder->mBackBufferSize) {
src->decoder->mBackBuffer =
(JOCTET *)PR_REALLOC(src->decoder->mBackBuffer, roundup_buflen);
} else {
src->decoder->mBackBuffer = (JOCTET*)PR_MALLOC(roundup_buflen);
}
/* Check for OOM */
if (!src->decoder->mBackBuffer) {
#if 0
j_common_ptr cinfo = (j_common_ptr)(&src->js->jd);
cinfo->err->msg_code = JERR_OUT_OF_MEMORY;
my_error_exit(cinfo);
#endif
}
src->decoder->mBackBufferSize = (size_t)roundup_buflen;
/* Check for malformed MARKER segment lengths. */
if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) {
my_error_exit((j_common_ptr)(&src->decoder->mInfo));
}
}
/* Copy remainder of netlib buffer into backtrack buffer. */
nsCRT::memmove(src->decoder->mBackBuffer + src->decoder->mBackBufferLen,
src->pub.next_input_byte,
src->pub.bytes_in_buffer);
/* Point to start of data to be rescanned. */
src->pub.next_input_byte = src->decoder->mBackBuffer + src->decoder->mBackBufferLen - src->decoder->mBackBufferUnreadLen;
src->pub.bytes_in_buffer += src->decoder->mBackBufferUnreadLen;
src->decoder->mBackBufferLen = (size_t)new_backtrack_buflen;
src->decoder->mFillState = READING_BACK;
return PR_FALSE;
}
break;
}
return PR_FALSE;
}
/******************************************************************************/
/* data source manager method */
/*
* Terminate source --- called by jpeg_finish_decompress() after all
* data has been read to clean up JPEG source manager. NOT called by
* jpeg_abort() or jpeg_destroy().
*/
void PR_CALLBACK
term_source (j_decompress_ptr jd)
{
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
if (src->decoder->mObserver) {
src->decoder->mObserver->OnStopFrame(nsnull, nsnull, src->decoder->mFrame);
src->decoder->mObserver->OnStopContainer(nsnull, nsnull, src->decoder->mImage);
src->decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
/* No work necessary here */
}

View File

@@ -0,0 +1,121 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef nsJPEGDecoder_h__
#define nsJPEGDecoder_h__
#include "imgIDecoder.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "imgIDecoderObserver.h"
#include "imgIRequest.h"
#include "nsIInputStream.h"
#include "nsIPipe.h"
extern "C" {
#include "jpeglib.h"
}
#include <setjmp.h>
#define NS_JPEGDECODER_CID \
{ /* 5871a422-1dd2-11b2-ab3f-e2e56be5da9c */ \
0x5871a422, \
0x1dd2, \
0x11b2, \
{0xab, 0x3f, 0xe2, 0xe5, 0x6b, 0xe5, 0xda, 0x9c} \
}
typedef struct {
struct jpeg_error_mgr pub; /* "public" fields for IJG library*/
jmp_buf setjmp_buffer; /* For handling catastropic errors */
} decoder_error_mgr;
typedef enum {
JPEG_HEADER, /* Reading JFIF headers */
JPEG_START_DECOMPRESS,
JPEG_DECOMPRESS_PROGRESSIVE, /* Output progressive pixels */
JPEG_DECOMPRESS_SEQUENTIAL, /* Output sequential pixels */
JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT,
JPEG_DONE,
JPEG_SINK_NON_JPEG_TRAILER, /* Some image files have a */
/* non-JPEG trailer */
JPEG_ERROR
} jstate;
class nsJPEGDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsJPEGDecoder();
virtual ~nsJPEGDecoder();
PRBool FillInput(j_decompress_ptr jd);
PRUint32 mBytesToSkip;
protected:
int OutputScanlines(int num_scanlines);
public:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver;
struct jpeg_decompress_struct mInfo;
decoder_error_mgr mErr;
jstate mState;
JSAMPARRAY mSamples;
JSAMPARRAY mSamples3;
PRUint8* mRGBPadRow;
PRUint32 mRGBPadRowLength;
PRInt32 mCompletedPasses;
PRInt32 mPasses;
int mFillState;
JOCTET *mBuffer;
PRUint32 mBufferLen; // amount of data currently in mBuffer
PRUint32 mBufferSize; // size in bytes what mBuffer was created with
JOCTET *mBackBuffer;
PRUint32 mBackBufferLen; // Offset of end of active backtrack data
PRUint32 mBackBufferSize; // size in bytes what mBackBuffer was created with
PRUint32 mBackBufferUnreadLen; // amount of data currently in mBackBuffer
};
#endif // nsJPEGDecoder_h__

View File

@@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsJPEGDecoder.h"
// objects that just require generic constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGDecoder)
static nsModuleComponentInfo components[] =
{
{ "ppm decoder",
NS_JPEGDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/jpeg",
nsJPEGDecoderConstructor, },
};
NS_IMPL_NSGETMODULE("nsJPEGDecoderModule", components)

View File

@@ -0,0 +1,16 @@
?Release@nsJPEGDecoder@@UAGKXZ ; 172
?AddRef@nsJPEGDecoder@@UAGKXZ ; 172
?fill_input_buffer@@YAEPAUjpeg_decompress_struct@@@Z ; 126
?skip_input_data@@YAXPAUjpeg_decompress_struct@@J@Z ; 109
?WriteFrom@nsJPEGDecoder@@UAGIPAVnsIInputStream@@IPAI@Z ; 106
?OutputScanlines@nsJPEGDecoder@@IAEHH@Z ; 93
?init_source@@YAXPAUjpeg_decompress_struct@@@Z ; 86
??1nsJPEGDecoder@@UAE@XZ ; 86
?Close@nsJPEGDecoder@@UAGIXZ ; 86
?term_source@@YAXPAUjpeg_decompress_struct@@@Z ; 86
?Init@nsJPEGDecoder@@UAGIPAVimgIRequest@@@Z ; 86
??0nsJPEGDecoder@@QAE@XZ ; 86
?Flush@nsJPEGDecoder@@UAGIXZ ; 86
?QueryInterface@nsJPEGDecoder@@UAGIABUnsID@@PAPAX@Z ; 86
??_EnsJPEGDecoder@@UAEPAXI@Z ; 86
_NSGetModule ; 1

View File

@@ -0,0 +1,26 @@
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH=..\..\..
DIRS = ppm gif png jpeg
!include $(DEPTH)\config\rules.mak

View File

@@ -0,0 +1,42 @@
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imgpng
LIBRARY_NAME = imgpng
IS_COMPONENT = 1
REQUIRES = xpcom necko layout png gfx2 imglib2
CPPSRCS = nsPNGDecoder.cpp nsPNGFactory.cpp
EXTRA_DSO_LDOPTS = $(PNG_LIBS) $(ZLIB_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,53 @@
#!nmake
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imgpng
LIBRARY_NAME = imgpng
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsPNGDecoder.obj \
.\$(OBJDIR)\nsPNGFactory.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\png.lib \
$(DIST)\lib\zlib.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,553 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*
*/
#include "nsPNGDecoder.h"
#include "nsIInputStream.h"
#include "nspr.h"
#include "nsIComponentManager.h"
#include "png.h"
#include "nsIStreamObserver.h"
#include "nsRect.h"
#include "nsMemory.h"
#include "imgIContainerObserver.h"
// XXX we need to be sure to fire onStopDecode messages to mObserver in error cases.
NS_IMPL_ISUPPORTS2(nsPNGDecoder, imgIDecoder, nsIOutputStream)
nsPNGDecoder::nsPNGDecoder()
{
NS_INIT_ISUPPORTS();
mPNG = nsnull;
mInfo = nsnull;
colorLine = 0;
alphaLine = 0;
interlacebuf = 0;
}
nsPNGDecoder::~nsPNGDecoder()
{
if (colorLine)
nsMemory::Free(colorLine);
if (alphaLine)
nsMemory::Free(alphaLine);
if (interlacebuf)
nsMemory::Free(interlacebuf);
}
/** imgIDecoder methods **/
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsPNGDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImage));
/* do png init stuff */
/* Initialize the container's source image header. */
/* Always decode to 24 bit pixdepth */
mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL,
NULL);
if (!mPNG) {
return NS_ERROR_FAILURE;
}
mInfo = png_create_info_struct(mPNG);
if (!mInfo) {
png_destroy_read_struct(&mPNG, NULL, NULL);
return NS_ERROR_FAILURE;
}
/* use ic as libpng "progressive pointer" (retrieve in callbacks) */
png_set_progressive_read_fn(mPNG, NS_STATIC_CAST(png_voidp, this), nsPNGDecoder::info_callback, nsPNGDecoder::row_callback, nsPNGDecoder::end_callback);
return NS_OK;
}
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsPNGDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
/* void close (); */
NS_IMETHODIMP nsPNGDecoder::Close()
{
if (mPNG)
png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL);
return NS_OK;
}
/* void flush (); */
NS_IMETHODIMP nsPNGDecoder::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsPNGDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
static NS_METHOD ReadDataOut(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, closure);
// we need to do the setjmp here otherwise bad things will happen
if (setjmp(decoder->mPNG->jmpbuf)) {
png_destroy_read_struct(&decoder->mPNG, &decoder->mInfo, NULL);
// is this NS_ERROR_FAILURE enough?
decoder->mRequest->Cancel(NS_BINDING_ABORTED); // XXX is this the correct error ?
return NS_ERROR_FAILURE;
}
*writeCount = decoder->ProcessData((unsigned char*)fromRawSegment, count);
return NS_OK;
}
PRUint32 nsPNGDecoder::ProcessData(unsigned char *data, PRUint32 count)
{
png_process_data(mPNG, mInfo, data, count);
return count; // we always consume all the data
}
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsPNGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
// PRUint32 sourceOffset = *_retval;
inStr->ReadSegments(ReadDataOut, this, count, _retval);
return NS_OK;
}
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsPNGDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsPNGDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPNGDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsPNGDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPNGDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void
nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
{
/* int number_passes; NOT USED */
png_uint_32 width, height;
int bit_depth, color_type, interlace_type, compression_type, filter_type;
int channels;
double LUT_exponent, CRT_exponent = 2.2, display_exponent, aGamma;
png_bytep trans=NULL;
int num_trans =0;
/* always decode to 24-bit RGB or 32-bit RGBA */
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, &compression_type, &filter_type);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
png_set_expand(png_ptr);
}
if (bit_depth == 16)
png_set_strip_16(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
#ifdef XP_PC
// windows likes BGR
png_set_bgr(png_ptr);
#endif
/* set up gamma correction for Mac, Unix and (Win32 and everything else)
* using educated guesses for display-system exponents; do preferences
* later */
#if defined(XP_MAC)
LUT_exponent = 1.8 / 2.61;
#elif defined(XP_UNIX)
# if defined(__sgi)
LUT_exponent = 1.0 / 1.7; /* typical default for SGI console */
# elif defined(NeXT)
LUT_exponent = 1.0 / 2.2; /* typical default for NeXT cube */
# else
LUT_exponent = 1.0; /* default for most other Unix workstations */
# endif
#else
LUT_exponent = 1.0; /* virtually all PCs and most other systems */
#endif
/* (alternatively, could check for SCREEN_GAMMA environment variable) */
display_exponent = LUT_exponent * CRT_exponent;
if (png_get_gAMA(png_ptr, info_ptr, &aGamma))
png_set_gamma(png_ptr, display_exponent, aGamma);
else
png_set_gamma(png_ptr, display_exponent, 0.45455);
/* let libpng expand interlaced images */
if (interlace_type == PNG_INTERLACE_ADAM7) {
/* number_passes = */
png_set_interlace_handling(png_ptr);
}
/* now all of those things we set above are used to update various struct
* members and whatnot, after which we can get channels, rowbytes, etc. */
png_read_update_info(png_ptr, info_ptr);
channels = png_get_channels(png_ptr, info_ptr);
PR_ASSERT(channels == 3 || channels == 4);
/*---------------------------------------------------------------*/
/* copy PNG info into imagelib structs (formerly png_set_dims()) */
/*---------------------------------------------------------------*/
PRInt32 alpha_bits = 1;
if (channels > 3) {
/* check if alpha is coming from a tRNS chunk and is binary */
if (num_trans) {
/* if it's not a indexed color image, tRNS means binary */
if (color_type == PNG_COLOR_TYPE_PALETTE) {
for (int i=0; i<num_trans; i++) {
if ((trans[i] != 0) && (trans[i] != 255)) {
alpha_bits = 8;
break;
}
}
}
} else {
alpha_bits = 8;
}
}
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
if (decoder->mObserver)
decoder->mObserver->OnStartDecode(nsnull, nsnull);
// since the png is only 1 frame, initalize the container to the width and height of the frame
decoder->mImage->Init(width, height, decoder->mObserver);
if (decoder->mObserver)
decoder->mObserver->OnStartContainer(nsnull, nsnull, decoder->mImage);
decoder->mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
#if 0
// XXX should we longjmp to png_ptr->jumpbuf here if we failed?
if (!decoder->mFrame)
return NS_ERROR_FAILURE;
#endif
gfx_format format;
if (channels == 3) {
format = gfxIFormats::RGB;
} else if (channels > 3) {
if (alpha_bits == 8) {
decoder->mImage->GetPreferredAlphaChannelFormat(&format);
} else if (alpha_bits == 1) {
format = gfxIFormats::RGB_A1;
}
}
#ifdef XP_PC
// XXX this works...
format += 1; // RGB to BGR
#endif
// then initalize the frame and append it to the container
decoder->mFrame->Init(0, 0, width, height, format);
decoder->mImage->AppendFrame(decoder->mFrame);
if (decoder->mObserver)
decoder->mObserver->OnStartFrame(nsnull, nsnull, decoder->mFrame);
PRUint32 bpr, abpr;
decoder->mFrame->GetImageBytesPerRow(&bpr);
decoder->mFrame->GetAlphaBytesPerRow(&abpr);
decoder->colorLine = (PRUint8 *)nsMemory::Alloc(bpr);
if (channels > 3)
decoder->alphaLine = (PRUint8 *)nsMemory::Alloc(abpr);
if (interlace_type == PNG_INTERLACE_ADAM7) {
decoder->interlacebuf = (PRUint8 *)nsMemory::Alloc(channels*width*height);
decoder->ibpr = channels*width;
if (!decoder->interlacebuf) {
// return NS_ERROR_FAILURE;
}
}
return;
}
void
nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass)
{
/* libpng comments:
*
* this function is called for every row in the image. If the
* image is interlacing, and you turned on the interlace handler,
* this function will be called for every row in every pass.
* Some of these rows will not be changed from the previous pass.
* When the row is not changed, the new_row variable will be NULL.
* The rows and passes are called in order, so you don't really
* need the row_num and pass, but I'm supplying them because it
* may make your life easier.
*
* For the non-NULL rows of interlaced images, you must call
* png_progressive_combine_row() passing in the row and the
* old row. You can call this function for NULL rows (it will
* just return) and for non-interlaced images (it just does the
* memcpy for you) if it will make the code easier. Thus, you
* can just do this for all cases:
*
* png_progressive_combine_row(png_ptr, old_row, new_row);
*
* where old_row is what was displayed for previous rows. Note
* that the first pass (pass == 0 really) will completely cover
* the old row, so the rows do not have to be initialized. After
* the first pass (and only for interlaced images), you will have
* to pass the current row, and the function will combine the
* old row and the new row.
*/
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
PRUint32 bpr, abpr;
decoder->mFrame->GetImageBytesPerRow(&bpr);
decoder->mFrame->GetAlphaBytesPerRow(&abpr);
png_bytep line;
if (decoder->interlacebuf) {
line = decoder->interlacebuf+(row_num*decoder->ibpr);
png_progressive_combine_row(png_ptr, line, new_row);
}
else
line = new_row;
if (new_row) {
nscoord width;
decoder->mFrame->GetWidth(&width);
PRUint32 iwidth = width;
gfx_format format;
decoder->mFrame->GetFormat(&format);
PRUint8 *aptr, *cptr;
// The mac specific ifdefs in the code below are there to make sure we
// always fill in 4 byte pixels right now, which is what the mac always
// allocates for its pixel buffers in true color mode. This will change
// when we start storing images with color palettes when they don't need
// true color support (GIFs).
switch (format) {
case gfxIFormats::RGB:
case gfxIFormats::BGR:
#ifdef XP_MAC
cptr = decoder->colorLine;
for (PRUint32 x=0; x<iwidth; x++) {
*cptr++ = 0;
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
#else
decoder->mFrame->SetImageData((PRUint8*)line, bpr, row_num*bpr);
#endif
break;
case gfxIFormats::RGB_A1:
case gfxIFormats::BGR_A1:
{
cptr = decoder->colorLine;
aptr = decoder->alphaLine;
memset(aptr, 0, abpr);
for (PRUint32 x=0; x<iwidth; x++) {
#ifdef XP_MAC
*cptr++ = 0;
#endif
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
if (*line++) {
aptr[x>>3] |= 1<<(7-x&0x7);
}
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
}
break;
case gfxIFormats::RGB_A8:
case gfxIFormats::BGR_A8:
{
cptr = decoder->colorLine;
aptr = decoder->alphaLine;
for (PRUint32 x=0; x<iwidth; x++) {
#ifdef XP_MAC
*cptr++ = 0;
#endif
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
*aptr++ = *line++;
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
}
break;
case gfxIFormats::RGBA:
case gfxIFormats::BGRA:
#ifdef XP_MAC
{
cptr = decoder->colorLine;
aptr = decoder->alphaLine;
for (PRUint32 x=0; x<iwidth; x++) {
*cptr++ = 0;
*cptr++ = *line++;
*cptr++ = *line++;
*cptr++ = *line++;
*aptr++ = *line++;
}
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
}
#else
decoder->mFrame->SetImageData(line, bpr, row_num*bpr);
#endif
break;
}
nsRect r(0, row_num, width, 1);
decoder->mObserver->OnDataAvailable(nsnull, nsnull, decoder->mFrame, &r);
}
}
void
nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
{
/* libpng comments:
*
* this function is called when the whole image has been read,
* including any chunks after the image (up to and including
* the IEND). You will usually have the same info chunk as you
* had in the header, although some data may have been added
* to the comments and time fields.
*
* Most people won't do much here, perhaps setting a flag that
* marks the image as finished.
*/
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
if (decoder->mObserver) {
decoder->mObserver->OnStopFrame(nsnull, nsnull, decoder->mFrame);
decoder->mObserver->OnStopContainer(nsnull, nsnull, decoder->mImage);
decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
}

View File

@@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef nsPNGDecoder_h__
#define nsPNGDecoder_h__
#include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#include "nsCOMPtr.h"
#include "png.h"
#define NS_PNGDECODER_CID \
{ /* 36fa00c2-1dd2-11b2-be07-d16eeb4c50ed */ \
0x36fa00c2, \
0x1dd2, \
0x11b2, \
{0xbe, 0x07, 0xd1, 0x6e, 0xeb, 0x4c, 0x50, 0xed} \
}
class nsPNGDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsPNGDecoder();
virtual ~nsPNGDecoder();
PR_STATIC_CALLBACK(void)
info_callback(png_structp png_ptr, png_infop info_ptr);
PR_STATIC_CALLBACK(void)
row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass);
PR_STATIC_CALLBACK(void)
end_callback(png_structp png_ptr, png_infop info_ptr);
inline PRUint32 ProcessData(unsigned char *data, PRUint32 count);
public:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
png_structp mPNG;
png_infop mInfo;
PRUint8 *colorLine, *alphaLine;
PRUint8 *interlacebuf;
PRUint32 ibpr;
};
#endif // nsPNGDecoder_h__

View File

@@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsPNGDecoder.h"
// objects that just require generic constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGDecoder)
static nsModuleComponentInfo components[] =
{
{ "PNG decoder",
NS_PNGDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/png",
nsPNGDecoderConstructor, },
{ "PNG decoder",
NS_PNGDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/x-png",
nsPNGDecoderConstructor, },
};
NS_IMPL_NSGETMODULE("nsPNGDecoderModule", components)

View File

@@ -0,0 +1,42 @@
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = imgppm
LIBRARY_NAME = imgppm
IS_COMPONENT = 1
REQUIRES = xpcom layout necko gfx2 imglib2
CPPSRCS = nsPPMDecoder.cpp nsPPMFactory.cpp
EXTRA_DSO_LDOPTS = \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,51 @@
#!nmake
#
# 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 Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Stuart Parmenter <pavlov@netscape.com>
#
DEPTH=..\..\..\..
include <$(DEPTH)/config/config.mak>
MODULE = imgppm
LIBRARY_NAME = imgppm
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
MAKE_OBJ_TYPE = DLL
OBJS = \
.\$(OBJDIR)\nsPPMDecoder.obj \
.\$(OBJDIR)\nsPPMFactory.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfxwin.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,305 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*
*/
#include "nsPPMDecoder.h"
#include "nsIInputStream.h"
#include "imgIContainer.h"
#include "imgIContainerObserver.h"
#include "nspr.h"
#include "nsIComponentManager.h"
#include "nsRect.h"
NS_IMPL_ISUPPORTS2(nsPPMDecoder, imgIDecoder, nsIOutputStream)
nsPPMDecoder::nsPPMDecoder()
{
NS_INIT_ISUPPORTS();
mDataReceived = 0;
mDataWritten = 0;
mDataLeft = 0;
mPrevData = nsnull;
}
nsPPMDecoder::~nsPPMDecoder()
{
}
/** imgIDecoder methods **/
/* void init (in imgIRequest aRequest); */
NS_IMETHODIMP nsPPMDecoder::Init(imgIRequest *aRequest)
{
mRequest = aRequest;
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
aRequest->GetImage(getter_AddRefs(mImage));
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
if (!mFrame)
return NS_ERROR_FAILURE;
return NS_OK;
}
/* readonly attribute imgIRequest request; */
NS_IMETHODIMP nsPPMDecoder::GetRequest(imgIRequest * *aRequest)
{
*aRequest = mRequest;
NS_ADDREF(*aRequest);
return NS_OK;
}
/** nsIOutputStream methods **/
/* void close (); */
NS_IMETHODIMP nsPPMDecoder::Close()
{
if (mObserver) {
mObserver->OnStopFrame(nsnull, nsnull, mFrame);
mObserver->OnStopContainer(nsnull, nsnull, mImage);
mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
}
return NS_OK;
}
/* void flush (); */
NS_IMETHODIMP nsPPMDecoder::Flush()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* unsigned long write (in string buf, in unsigned long count); */
NS_IMETHODIMP nsPPMDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
static char *__itoa(int n)
{
char *s;
int i, j, sign, tmp;
/* check sign and convert to positive to stringify numbers */
if ( (sign = n) < 0)
n = -n;
i = 0;
s = (char*) malloc(sizeof(char));
/* grow string as needed to add numbers from powers of 10
* down till none left
*/
do
{
s = (char*) realloc(s, (i+1)*sizeof(char));
s[i++] = n % 10 + '0'; /* '0' or 30 is where ASCII numbers start */
s[i] = '\0';
}
while( (n /= 10) > 0);
/* tack on minus sign if we found earlier that this was negative */
if (sign < 0)
{
s = (char*) realloc(s, (i+1)*sizeof(char));
s[i++] = '-';
}
s[i] = '\0';
/* pop numbers (and sign) off of string to push back into right direction */
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
return s;
}
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsPPMDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
nsresult rv;
char *buf = (char *)PR_Malloc(count + mDataLeft);
if (!buf)
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
// read the data from the input stram...
PRUint32 readLen;
rv = inStr->Read(buf+mDataLeft, count, &readLen);
PRUint32 dataLen = readLen + mDataLeft;
if (mPrevData) {
strncpy(buf, mPrevData, mDataLeft);
PR_Free(mPrevData);
mPrevData = nsnull;
mDataLeft = 0;
}
char *data = buf;
if (NS_FAILED(rv)) return rv;
if (mDataReceived == 0) {
mObserver->OnStartDecode(nsnull, nsnull);
// Check the magic number
char type;
if ((sscanf(data, "P%c\n", &type) !=1) || (type != '6')) {
return NS_ERROR_FAILURE;
}
int i = 3;
data += i;
#if 0
// XXX
// Ignore comments
while ((input = fgetc(f)) == '#')
fgets(junk, 512, f);
ungetc(input, f);
#endif
// Read size
int w, h, mcv;
if (sscanf(data, "%d %d\n%d\n", &w, &h, &mcv) != 3) {
return NS_ERROR_FAILURE;
}
char *ws = __itoa(w), *hs = __itoa(h), *mcvs = __itoa(mcv);
int j = strlen(ws) + strlen(hs) + strlen(mcvs) + 3;
data += j;
// free(ws);
// free(hs);
// free(mcvs);
readLen -= i + j;
dataLen = readLen; // since this is the first pass, we don't have any data waiting that we need to keep track of
mImage->Init(w, h, mObserver);
if (mObserver)
mObserver->OnStartContainer(nsnull, nsnull, mImage);
mFrame->Init(0, 0, w, h, gfxIFormats::RGB);
mImage->AppendFrame(mFrame);
if (mObserver)
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
}
PRUint32 bpr;
nscoord width;
mFrame->GetImageBytesPerRow(&bpr);
mFrame->GetWidth(&width);
// XXX ceil?
PRUint32 real_bpr = width * 3;
PRUint32 i = 0;
PRUint32 rownum = mDataWritten / real_bpr; // XXX this better not have a decimal
PRUint32 wroteLen = 0;
if (readLen > real_bpr) {
do {
PRUint8 *line = (PRUint8*)data + i*real_bpr;
mFrame->SetImageData(line, real_bpr, (rownum++)*bpr);
nsRect r(0, rownum, width, 1);
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
wroteLen += real_bpr ;
i++;
} while(dataLen >= real_bpr * (i+1));
}
mDataReceived += readLen; // don't double count previous data that is in 'dataLen'
mDataWritten += wroteLen;
PRUint32 dataLeft = dataLen - wroteLen;
if (dataLeft > 0) {
if (mPrevData) {
mPrevData = (char *)PR_Realloc(mPrevData, mDataLeft + dataLeft);
strncpy(mPrevData + mDataLeft, data+wroteLen, dataLeft);
mDataLeft += dataLeft;
} else {
mDataLeft = dataLeft;
mPrevData = (char *)PR_Malloc(mDataLeft);
strncpy(mPrevData, data+wroteLen, mDataLeft);
}
}
PR_FREEIF(buf);
return NS_OK;
}
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
NS_IMETHODIMP nsPPMDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute boolean nonBlocking; */
NS_IMETHODIMP nsPPMDecoder::GetNonBlocking(PRBool *aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPPMDecoder::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIOutputStreamObserver observer; */
NS_IMETHODIMP nsPPMDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsPPMDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#ifndef nsPPMDecoder_h__
#define nsPPMDecoder_h__
#include "imgIDecoder.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgIRequest.h"
#define NS_PPMDECODER_CID \
{ /* e90bfa06-1dd1-11b2-8217-f38fe5d431a2 */ \
0xe90bfa06, \
0x1dd1, \
0x11b2, \
{0x82, 0x17, 0xf3, 0x8f, 0xe5, 0xd4, 0x31, 0xa2} \
}
class nsPPMDecoder : public imgIDecoder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
NS_DECL_NSIOUTPUTSTREAM
nsPPMDecoder();
virtual ~nsPPMDecoder();
private:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIRequest> mRequest;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
PRUint32 mDataReceived;
PRUint32 mDataWritten;
PRUint32 mDataLeft;
char *mPrevData;
};
#endif // nsPPMDecoder_h__

View File

@@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsPPMDecoder.h"
// objects that just require generic constructors
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPPMDecoder)
static nsModuleComponentInfo components[] =
{
{ "ppm decoder",
NS_PPMDECODER_CID,
"@mozilla.org/image/decoder;2?type=image/x-portable-pixmap",
nsPPMDecoderConstructor, },
};
NS_IMPL_NSGETMODULE("nsPPMDecoderModule", components)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,25 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..
DIRS = public src decoders
!include $(DEPTH)\config\rules.mak

View File

@@ -0,0 +1,111 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape are
* Copyright (C) 2001 Netscape Communications Corporation.
* All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "prlog.h"
#include "nsString.h"
#if defined(PR_LOGGING)
extern PRLogModuleInfo *gImgLog;
class LogScope {
public:
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s {ENTER}\n",
mFrom, mFunc.get()));
}
/* const char * constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, const char *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%s\") {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
/* void ptr constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, const void *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=%p) {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
/* PRInt32 constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, PRInt32 paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%d\") {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
/* PRUint32 constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
const nsLiteralCString &paramName, PRUint32 paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%d\") {ENTER}\n",
mFrom, mFunc.get(),
paramName.get(),
paramValue));
}
~LogScope() {
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s {EXIT}\n",
mFrom, mFunc.get()));
}
private:
PRLogModuleInfo *mLog;
void *mFrom;
nsCAutoString mFunc;
};
#define LOG_SCOPE(l, s) \
LogScope LOG_SCOPE_TMP_VAR ##__LINE__ (l, \
NS_STATIC_CAST(void *, this), \
NS_LITERAL_CSTRING(s))
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \
LogScope LOG_SCOPE_TMP_VAR ##__LINE__ (l, \
NS_STATIC_CAST(void *, this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
#else
#define LOG_SCOPE(l, s)
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv)
#endif

Some files were not shown because too many files have changed in this diff Show More