Compare commits

..

1 Commits

Author SHA1 Message Date
(no author)
973a54719f This commit was manufactured by cvs2svn to create tag 'Last140MergeSource'.
git-svn-id: svn://10.0.0.236/tags/Last140MergeSource@10343 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-18 02:28:51 +00:00
199 changed files with 11679 additions and 105422 deletions

View File

@@ -1,6 +1,5 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
png.h
pngconf.h
jsjava.h
nsILiveconnect.h

View File

@@ -0,0 +1,89 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../..
include $(DEPTH)/config/config.mk
ifdef NSJVM
DIRS = classes
endif
MODULE = java
LIBRARY_NAME = jsj
REQUIRES = java js applet nspr img util layer xpcom
CSRCS = jsj.c \
jsj_JSObject.c \
jsj_JavaArray.c \
jsj_JavaClass.c \
jsj_JavaMember.c \
jsj_JavaObject.c \
jsj_JavaPackage.c \
jsj_array.c \
jsj_class.c \
jsj_convert.c \
jsj_field.c \
jsj_hash.c \
jsj_method.c \
jsj_utils.c \
nsCLiveconnect.c \
nsCLiveconnectFactory.c
LLIBS=$(LIBNSPR) $(DIST)/lib/js$(MOZ_BITS)$(VERSION_NUMBER).lib \
$(DIST)/lib/xpcom32.lib
ifdef NSJVM
JNI_GEN = netscape.javascript.JSObject netscape.javascript.JSException
endif
EXPORTS = jsjava.h \
$(JNI_GEN_DIR)/netscape_javascript_JSObject.h \
$(JNI_GEN_DIR)/netscape_javascript_JSException.h \
nsILiveconnect.h \
$(NULL)
include $(DEPTH)/config/rules.mk
######################################################################
# Generate jsj_nodl.c (so that you can check it in)
# These make rules only works on IRIX...sigh
ifeq ($(OS_ARCH),IRIX)
jsj_nodl.c: $(OBJDIR)/stubs.o Makefile $(DEPTH)/config/nodl.pl
rm -f $@
$(PERL) $(DEPTH)/config/nodl.pl "jsj_nodl_tab" \
`nm -Bn $(OBJDIR)/stubs.o | egrep Java_.*_stub | awk '{print $$3;}'` > $@
endif
ifdef JAVA_OR_OJI
$(OBJDIR)/stubs.o: \
$(JNI_GEN_DIR)/netscape_javascript_JSObject.c \
$(JNI_GEN_DIR)/netscape_javascript_JSException.c \
$(NULL)
else
$(OBJDIR)/stubs.o:
endif

View File

@@ -0,0 +1,90 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
ifdef NSJVM
DIRS = classes
endif
MODULE = java
LIBRARY_NAME = jsj
REQUIRES = java js applet nspr img util layer xpcom caps oji plugin
CSRCS = jsj.c \
jsj_JSObject.c \
jsj_JavaArray.c \
jsj_JavaClass.c \
jsj_JavaMember.c \
jsj_JavaObject.c \
jsj_JavaPackage.c \
jsj_array.c \
jsj_class.c \
jsj_convert.c \
jsj_field.c \
jsj_hash.c \
jsj_method.c \
jsj_utils.c
nsCLiveconnect.c \
nsCLiveconnectFactory.c
ifdef NSJVM
JNI_GEN = netscape.javascript.JSObject netscape.javascript.JSException
endif
EXPORTS = $(srcdir)/jsjava.h \
$(srcdir)/$(JNI_GEN_DIR)/netscape_javascript_JSObject.h \
$(srcdir)/$(JNI_GEN_DIR)/netscape_javascript_JSException.h \
$(NULL)
include $(topsrcdir)/config/rules.mk
######################################################################
# Generate jsj_nodl.c (so that you can check it in)
# These make rules only works on IRIX...sigh
ifeq ($(OS_ARCH),IRIX)
jsj_nodl.c: $(OBJDIR)/stubs.o Makefile $(topsrcdir)/config/nodl.pl
rm -f $@
$(PERL) $(topsrcdir)/config/nodl.pl "jsj_nodl_tab" \
`nm -Bn $(OBJDIR)/stubs.o | egrep Java_.*_stub | awk '{print $$3;}'` > $@
endif
ifdef JAVA_OR_OJI
$(OBJDIR)/stubs.o: \
$(JRI_GEN_DIR)/netscape_javascript_JSObject.c \
$(JRI_GEN_DIR)/netscape_javascript_JSException.c \
$(NULL)
else
$(OBJDIR)/stubs.o:
endif

View File

@@ -0,0 +1,14 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class netscape_javascript_JSException */
#ifndef _Included_netscape_javascript_JSException
#define _Included_netscape_javascript_JSException
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,102 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class netscape_javascript_JSObject */
#ifndef _Included_netscape_javascript_JSObject
#define _Included_netscape_javascript_JSObject
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: netscape_javascript_JSObject
* Method: initClass
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_initClass
(JNIEnv *, jclass);
/*
* Class: netscape_javascript_JSObject
* Method: getMember
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getMember
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: getSlot
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getSlot
(JNIEnv *, jobject, jint);
/*
* Class: netscape_javascript_JSObject
* Method: setMember
* Signature: (Ljava/lang/String;Ljava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setMember
(JNIEnv *, jobject, jstring, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: setSlot
* Signature: (ILjava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setSlot
(JNIEnv *, jobject, jint, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: removeMember
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_removeMember
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: call
* Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_call
(JNIEnv *, jobject, jstring, jobjectArray);
/*
* Class: netscape_javascript_JSObject
* Method: eval
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_eval
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: toString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_netscape_javascript_JSObject_toString
(JNIEnv *, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: getWindow
* Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getWindow
(JNIEnv *, jclass, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: finalize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,65 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../../..
MODULE = java
#
# the idea is that the install phase for those modules will
# make their own signed jar files
# there are some exceptions here that we deal with
# stuff in modules and in ns/js/jsj
#
JMODS = netscape/javascript netscape/javascript/adapters
#
# JDIRS is dependant on JAVA_DESTPATH in config/rules.m[a]k.
# Be sure to touch that directory if you add a new directory to
# JDIRS, or else it will not build. FIXME
#
JDIRS = $(JMODS)
JAR_JSJ = jsj10.jar
JAR_JSJ_CLASSES = $(JMODS)
#
# jars to build at install time
#
JARS = $(JAR_JSJ)
include $(DEPTH)/config/rules.mk
JAVA_SOURCEPATH = $(DEPTH)/js/src/liveconnect/classes
doc::
$(JAVADOC) -d $(DIST)/doc netscape.javascript
natives_list:: FORCE
rm -rf $@
find . -name "*.class" -print | sed 's@\./\(.*\)\.class$$@\1@' | \
sed 's@/@.@g' | xargs $(JVH) -natives | sort > $@
check_natives:: natives_list
rm -f found_natives
nm -B ../$(OBJDIR)/*.o \
| egrep "Java.*_stub" | awk '{ print $$3; }' | sort > found_natives
diff found_natives natives_list
FORCE:

View File

@@ -0,0 +1,70 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = java
#
# the idea is that the install phase for those modules will
# make their own signed jar files
# there are some exceptions here that we deal with
# stuff in modules and in ns/js/jsj
#
JMODS = netscape/javascript netscape/javascript/adapters
#
# JDIRS is dependant on JAVA_DESTPATH in config/rules.m[a]k.
# Be sure to touch that directory if you add a new directory to
# JDIRS, or else it will not build. FIXME
#
JDIRS = $(JMODS)
JAR_JSJ = jsj10.jar
JAR_JSJ_CLASSES = $(JMODS)
#
# jars to build at install time
#
JARS = $(JAR_JSJ)
include $(topsrcdir)/config/rules.mk
JAVA_SOURCEPATH = $(topsrcdir)/js/src/liveconnect/classes
doc::
$(JAVADOC) -d $(DIST)/doc netscape.javascript
natives_list:: FORCE
rm -rf $@
find . -name "*.class" -print | sed 's@\./\(.*\)\.class$$@\1@' | \
sed 's@/@.@g' | xargs $(JVH) -natives | sort > $@
check_natives:: natives_list
rm -f found_natives
nm -B ../$(OBJDIR)/*.o \
| egrep "Java.*_stub" | awk '{ print $$3; }' | sort > found_natives
diff found_natives natives_list
FORCE:

View File

@@ -0,0 +1,78 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
IGNORE_MANIFEST=1
#
#//------------------------------------------------------------------------
#//
#// Makefile to build the JavaScript-Java tree
#//
#//------------------------------------------------------------------------
DEPTH = ..\..\..\..
JAVA_SOURCEPATH=$(DEPTH)\js\src\liveconnect\classes
#//------------------------------------------------------------------------
#//
#// Define the files necessary to build the target (ie. OBJS)
#//
#//------------------------------------------------------------------------
include <$(DEPTH)\config\config.mak>
JMOZ = \
netscape/javascript \
$(NULL)
all::
MODULE=java
JMODS=netscape/javascript
!ifdef JAVA_OR_NSJVM
JDIRS=$(JMODS)
JAR_JSJ_CLASSES=$(JMODS)
JAR_NAME = jsj10.jar
!endif
include <$(DEPTH)\config\rules.mak>
!ifdef JAVA_OR_NSJVM
install::
cd $(JAVA_DESTPATH)
@echo +++ building/updating $(JAR_NAME)
-for %i in ($(JAR_JSJ_CLASSES:/=\)) do @$(ZIP_PROG) $(ZIP_FLAGS) $(JAR_NAME) %i\*.class
cd $(MAKEDIR)
!ifdef REGENERATE
install::
cd $(JAVA_DESTPATH)
@echo +++ updating $(DEPTH)\nav-java\stubs\classes\$(JAR_NAME) for checkin
-for %i in ($(JAR_JSJ_CLASSES:/=\)) do @$(ZIP_PROG) $(ZIP_FLAGS) ..\..\nav-java\stubs\classes\$(JAR_NAME) %i\*.class
cd $(MAKEDIR)
!endif
!endif
javadoc:
-mkdir $(XPDIST)\javadoc 2> NUL
echo $(JAVADOC) -sourcepath . -d $(XPDIST)\javadoc $(JDIRS:/=.)
$(JAVADOC) -sourcepath . -d $(XPDIST)\javadoc $(JDIRS:/=.)

View File

@@ -0,0 +1,56 @@
/* Insert copyright and license here 19** */
package netscape.javascript;
/**
* JSException is an exception which is thrown when JavaScript code
* returns an error.
*/
public
class JSException extends Exception {
String filename;
int lineno;
String source;
int tokenIndex;
/**
* Constructs a JSException without a detail message.
* A detail message is a String that describes this particular exception.
*/
public JSException() {
super();
filename = "unknown";
lineno = 0;
source = "";
tokenIndex = 0;
}
/**
* Constructs a JSException with a detail message.
* A detail message is a String that describes this particular exception.
* @param s the detail message
*/
public JSException(String s) {
super(s);
filename = "unknown";
lineno = 0;
source = "";
tokenIndex = 0;
}
/**
* Constructs a JSException with a detail message and all the
* other info that usually comes with a JavaScript error.
* @param s the detail message
*/
public JSException(String s, String filename, int lineno,
String source, int tokenIndex) {
super(s);
this.filename = filename;
this.lineno = lineno;
this.source = source;
this.tokenIndex = tokenIndex;
}
}

View File

@@ -0,0 +1,150 @@
/* -*- Mode: C; tab-width: 4; -*- */
/* Insert copyright and license here 19** */
/* more doc todo:
* threads
* gc
*
*
*/
package netscape.javascript;
import java.applet.Applet;
/**
* JSObject allows Java to manipulate objects that are
* defined in JavaScript.
* Values passed from Java to JavaScript are converted as
* follows:<ul>
* <li>JSObject is converted to the original JavaScript object
* <li>Any other Java object is converted to a JavaScript wrapper,
* which can be used to access methods and fields of the java object.
* Converting this wrapper to a string will call the toString method
* on the original object, converting to a number will call the
* floatValue method if possible and fail otherwise. Converting
* to a boolean will try to call the booleanValue method in the
* same way.
* <li>Java arrays are wrapped with a JavaScript object that understands
* array.length and array[index]
* <li>A Java boolean is converted to a JavaScript boolean
* <li>Java byte, char, short, int, long, float, and double are converted
* to JavaScript numbers
* </ul>
* Values passed from JavaScript to Java are converted as follows:<ul>
* <li>objects which are wrappers around java objects are unwrapped
* <li>other objects are wrapped with a JSObject
* <li>strings, numbers and booleans are converted to String, Float,
* and Boolean objects respectively
* </ul>
* This means that all JavaScript values show up as some kind
* of java.lang.Object in Java. In order to make much use of them,
* you will have to cast them to the appropriate subclass of Object,
* e.g. <code>(String) window.getMember("name");</code> or
* <code>(JSObject) window.getMember("document");</code>.
*/
public final class JSObject {
/* the internal object data */
private int internal;
/**
* initialize
*/
private static native void initClass();
static {
// On MRJ, this property won't exist, because the library is preloaded.
String liveConnectLibrary = System.getProperty("netscape.jsj.dll", null);
if (liveConnectLibrary != null) {
System.loadLibrary(liveConnectLibrary);
initClass();
}
}
/**
* it is illegal to construct a JSObject manually
*/
private JSObject(int jsobj_addr) {
internal = jsobj_addr;
}
/**
* Retrieves a named member of a JavaScript object.
* Equivalent to "this.<i>name</i>" in JavaScript.
*/
public native Object getMember(String name);
/**
* Retrieves an indexed member of a JavaScript object.
* Equivalent to "this[<i>index</i>]" in JavaScript.
*/
// public Object getMember(int index) { return getSlot(index); }
public native Object getSlot(int index);
/**
* Sets a named member of a JavaScript object.
* Equivalent to "this.<i>name</i> = <i>value</i>" in JavaScript.
*/
public native void setMember(String name, Object value);
/**
* Sets an indexed member of a JavaScript object.
* Equivalent to "this[<i>index</i>] = <i>value</i>" in JavaScript.
*/
// public void setMember(int index, Object value) {
// setSlot(index, value);
// }
public native void setSlot(int index, Object value);
/**
* Removes a named member of a JavaScript object.
*/
public native void removeMember(String name);
/**
* Calls a JavaScript method.
* Equivalent to "this.<i>methodName</i>(<i>args</i>[0], <i>args</i>[1], ...)" in JavaScript.
*/
public native Object call(String methodName, Object args[]);
/**
* Evaluates a JavaScript expression. The expression is a string
* of JavaScript source code which will be evaluated in the context
* given by "this".
*/
public native Object eval(String s);
/**
* Converts a JSObject to a String.
*/
public native String toString();
// should use some sort of identifier rather than String
// is "property" the right word?
// native String[] listProperties();
/**
* get a JSObject for the window containing the given applet
*/
public static native JSObject getWindow(Applet applet);
/**
* Finalization decrements the reference count on the corresponding
* JavaScript object.
*/
protected native void finalize();
/**
* Override java.lang.Object.equals() because identity is not preserved
* with instances of JSObject.
*/
public boolean equals(Object obj) {
JSObject jsobj;
if (!(obj instanceof JSObject))
return false;
jsobj = (JSObject)obj;
return (internal == jsobj.internal);
}
}

View File

@@ -0,0 +1,37 @@
/* -*- Mode: Java; 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* ** */
/**
* The JSProxy interface allows applets and plugins to
* share javascript contexts.
*/
package netscape.javascript;
import java.applet.Applet;
public interface JSProxy {
Object getMember(JSObject jso, String name);
Object getSlot(JSObject jso, int index);
void setMember(JSObject jso, String name, Object value);
void setSlot(JSObject jso, int index, Object value);
void removeMember(JSObject jso, String name);
Object call(JSObject jso, String methodName, Object args[]);
Object eval(JSObject jso, String s);
String toString(JSObject jso);
JSObject getWindow(Applet applet);
}

View File

@@ -0,0 +1,31 @@
package netscape.javascript;
/**
* Runs a JavaScript object with a run() method in a separate thread.
*/
public class JSRunnable implements Runnable {
private JSObject runnable;
public JSRunnable(JSObject runnable) {
this.runnable = runnable;
synchronized(this) {
new Thread(this).start();
try {
this.wait();
} catch (InterruptedException ie) {
}
}
}
public void run() {
try {
runnable.call("run", null);
synchronized(this) {
notifyAll();
}
} catch (Throwable t) {
System.err.println(t);
t.printStackTrace(System.err);
}
}
}

View File

@@ -0,0 +1,38 @@
/* -*- Mode: Java; 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* ** */
package netscape.javascript;
import java.io.*;
public class JSUtil {
/* Return the stack trace of an exception or error as a String */
public static String getStackTrace(Throwable t) {
ByteArrayOutputStream captureStream;
PrintStream p;
captureStream = new ByteArrayOutputStream();
p = new PrintStream(captureStream);
t.printStackTrace(p);
p.flush();
return captureStream.toString();
}
}

View File

@@ -0,0 +1,876 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the top-level initialization code and the implementation of the
* public API.
*
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
#include "jsjava.h" /* LiveConnect external API */
/*
* At certain times during initialization, there may be no JavaScript context
* available to direct error reports to, in which case the error messages
* are sent to this function. The caller is responsible for free'ing
* the js_error_msg argument.
*/
static void
report_java_initialization_error(JNIEnv *jEnv, const char *js_error_msg)
{
const char *error_msg, *java_error_msg;
java_error_msg = NULL;
#if 0 /* This can never work here, because jsj_GetJavaErrorMessage relies on
jlThrowable_toString which is set up by the initialization that calls
this function. */
if (jEnv) {
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
(*jEnv)->ExceptionClear(jEnv);
}
#endif
if (java_error_msg) {
error_msg = PR_smprintf("initialization error: %s (%s)\n",
js_error_msg, java_error_msg);
free((void*)java_error_msg);
} else {
error_msg = PR_smprintf("initialization error: %s\n",
js_error_msg);
}
jsj_LogError(error_msg);
}
/*
* Opaque JVM handles to Java classes and methods required for Java reflection.
* These are computed and cached during initialization.
*/
jclass jlObject; /* java.lang.Object */
jclass jlrMethod; /* java.lang.reflect.Method */
jclass jlrField; /* java.lang.reflect.Field */
jclass jlVoid; /* java.lang.Void */
jclass jlrConstructor; /* java.lang.reflect.Constructor */
jclass jlThrowable; /* java.lang.Throwable */
jclass jlSystem; /* java.lang.System */
jclass jlClass; /* java.lang.Class */
jclass jlBoolean; /* java.lang.Boolean */
jclass jlDouble; /* java.lang.Double */
jclass jlString; /* java.lang.String */
jclass njJSObject; /* netscape.javascript.JSObject */
jclass njJSException; /* netscape.javascript.JSException */
jclass njJSUtil; /* netscape.javascript.JSUtil */
jmethodID jlClass_getMethods; /* java.lang.Class.getMethods() */
jmethodID jlClass_getConstructors; /* java.lang.Class.getConstructors() */
jmethodID jlClass_getFields; /* java.lang.Class.getFields() */
jmethodID jlClass_getName; /* java.lang.Class.getName() */
jmethodID jlClass_getComponentType; /* java.lang.Class.getComponentType() */
jmethodID jlClass_getModifiers; /* java.lang.Class.getModifiers() */
jmethodID jlClass_isArray; /* java.lang.Class.isArray() */
jmethodID jlrMethod_getName; /* java.lang.reflect.Method.getName() */
jmethodID jlrMethod_getParameterTypes; /* java.lang.reflect.Method.getParameterTypes() */
jmethodID jlrMethod_getReturnType; /* java.lang.reflect.Method.getReturnType() */
jmethodID jlrMethod_getModifiers; /* java.lang.reflect.Method.getModifiers() */
jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */
jmethodID jlrConstructor_getModifiers; /* java.lang.reflect.Constructor.getModifiers() */
jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */
jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */
jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */
jmethodID jlDouble_Double; /* java.lang.Double constructor */
jmethodID jlDouble_doubleValue; /* java.lang.Double.doubleValue() */
jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */
jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */
jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() */
jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
jmethodID njJSException_JSException; /* netscape.javascript.JSexception constructor */
jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
jfieldID njJSException_lineno; /* netscape.javascript.JSException.lineno */
jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
jfieldID njJSException_source; /* netscape.javascript.JSException.source */
jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
/* Obtain a reference to a Java class */
#define LOAD_CLASS(qualified_name, class) \
{ \
jclass _##class = (*jEnv)->FindClass(jEnv, #qualified_name); \
if (_##class == 0) { \
(*jEnv)->ExceptionClear(jEnv); \
report_java_initialization_error(jEnv, \
"Can't load class " #qualified_name); \
return JS_FALSE; \
} \
class = (*jEnv)->NewGlobalRef(jEnv, _##class); \
}
/* Obtain a methodID reference to a Java method or constructor */
#define _LOAD_METHOD(qualified_class, method, mvar, signature, class, is_static)\
if (is_static) { \
class##_##mvar = \
(*jEnv)->GetStaticMethodID(jEnv, class, #method, signature); \
} else { \
class##_##mvar = \
(*jEnv)->GetMethodID(jEnv, class, #method, signature); \
} \
if (class##_##mvar == 0) { \
report_java_initialization_error(jEnv, \
"Can't get mid for " #qualified_class "." #method "()"); \
return JS_FALSE; \
}
/* Obtain a methodID reference to a Java instance method */
#define LOAD_METHOD(qualified_class, method, signature, class) \
_LOAD_METHOD(qualified_class, method, method, signature, class, JS_FALSE)
/* Obtain a methodID reference to a Java static method */
#define LOAD_STATIC_METHOD(qualified_class, method, signature, class) \
_LOAD_METHOD(qualified_class, method, method, signature, class, JS_TRUE)
/* Obtain a methodID reference to a Java constructor */
#define LOAD_CONSTRUCTOR(qualified_class, method, signature, class) \
_LOAD_METHOD(qualified_class,<init>, method, signature, class, JS_FALSE)
/* Obtain a fieldID reference to a Java instance or static field */
#define _LOAD_FIELDID(qualified_class, field, signature, class, is_static) \
if (is_static) { \
class##_##field = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
} else { \
class##_##field = (*jEnv)->GetFieldID(jEnv, class, #field, signature);\
} \
if (class##_##field == 0) { \
report_java_initialization_error(jEnv, \
"Can't get fid for " #qualified_class "." #field); \
return JS_FALSE; \
}
/* Obtain a fieldID reference to a Java instance field */
#define LOAD_FIELDID(qualified_class, field, signature, class) \
_LOAD_FIELDID(qualified_class, field, signature, class, JS_FALSE)
/* Obtain the value of a static field in a Java class */
#define LOAD_FIELD_VAL(qualified_class, field, signature, class, type) \
{ \
jfieldID field_id; \
field_id = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
if (field_id == 0) { \
report_java_initialization_error(jEnv, \
"Can't get fid for " #qualified_class "." #field); \
return JS_FALSE; \
} \
class##_##field = \
(*jEnv)->GetStatic##type##Field(jEnv, class, field_id); \
if (class##_##field == 0) { \
report_java_initialization_error(jEnv, \
"Can't read static field " #qualified_class "." #field); \
return JS_FALSE; \
} \
}
/* Obtain the value of a static field in a Java class, which is known to
contain an object value. */
#define LOAD_FIELD_OBJ(qualified_class, field, signature, class) \
LOAD_FIELD_VAL(qualified_class, field, signature, class, Object); \
class##_##field = (*jEnv)->NewGlobalRef(jEnv, class##_##field);
/*
* Load the Java classes, and the method and field descriptors required for Java reflection.
* Returns JS_TRUE on success, JS_FALSE on failure.
*/
static JSBool
init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
{
/* Load Java system classes and method, including java.lang.reflect classes */
LOAD_CLASS(java/lang/Object, jlObject);
LOAD_CLASS(java/lang/Class, jlClass);
LOAD_CLASS(java/lang/reflect/Method, jlrMethod);
LOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
LOAD_CLASS(java/lang/reflect/Field, jlrField);
LOAD_CLASS(java/lang/Throwable, jlThrowable);
LOAD_CLASS(java/lang/System, jlSystem);
LOAD_CLASS(java/lang/Boolean, jlBoolean);
LOAD_CLASS(java/lang/Double, jlDouble);
LOAD_CLASS(java/lang/String, jlString);
LOAD_CLASS(java/lang/Void, jlVoid);
LOAD_METHOD(java.lang.Class, getMethods, "()[Ljava/lang/reflect/Method;",jlClass);
LOAD_METHOD(java.lang.Class, getConstructors, "()[Ljava/lang/reflect/Constructor;",jlClass);
LOAD_METHOD(java.lang.Class, getFields, "()[Ljava/lang/reflect/Field;", jlClass);
LOAD_METHOD(java.lang.Class, getName, "()Ljava/lang/String;", jlClass);
LOAD_METHOD(java.lang.Class, isArray, "()Z", jlClass);
LOAD_METHOD(java.lang.Class, getComponentType, "()Ljava/lang/Class;", jlClass);
LOAD_METHOD(java.lang.Class, getModifiers, "()I", jlClass);
LOAD_METHOD(java.lang.reflect.Method, getName, "()Ljava/lang/String;", jlrMethod);
LOAD_METHOD(java.lang.reflect.Method, getParameterTypes, "()[Ljava/lang/Class;", jlrMethod);
LOAD_METHOD(java.lang.reflect.Method, getReturnType, "()Ljava/lang/Class;", jlrMethod);
LOAD_METHOD(java.lang.reflect.Method, getModifiers, "()I", jlrMethod);
LOAD_METHOD(java.lang.reflect.Constructor, getParameterTypes, "()[Ljava/lang/Class;", jlrConstructor);
LOAD_METHOD(java.lang.reflect.Constructor, getModifiers, "()I", jlrConstructor);
LOAD_METHOD(java.lang.reflect.Field, getName, "()Ljava/lang/String;", jlrField);
LOAD_METHOD(java.lang.reflect.Field, getType, "()Ljava/lang/Class;", jlrField);
LOAD_METHOD(java.lang.reflect.Field, getModifiers, "()I", jlrField);
LOAD_METHOD(java.lang.Throwable, toString, "()Ljava/lang/String;", jlThrowable);
LOAD_METHOD(java.lang.Throwable, getMessage, "()Ljava/lang/String;", jlThrowable);
LOAD_METHOD(java.lang.Double, doubleValue, "()D", jlDouble);
LOAD_METHOD(java.lang.Boolean, booleanValue, "()Z", jlBoolean);
LOAD_STATIC_METHOD(java.lang.System, identityHashCode, "(Ljava/lang/Object;)I", jlSystem);
LOAD_CONSTRUCTOR(java.lang.Boolean, Boolean, "(Z)V", jlBoolean);
LOAD_CONSTRUCTOR(java.lang.Double, Double, "(D)V", jlDouble);
LOAD_FIELD_OBJ(java.lang.Void, TYPE, "Ljava/lang/Class;", jlVoid);
return JS_TRUE;
}
#if XP_MAC
/**
* Workaround for the fact that MRJ loads a different instance of the shared library.
*/
#include "netscape_javascript_JSObject.h"
static JSObject_RegisterNativeMethods(JNIEnv* jEnv)
{
// Manually load the required native methods.
static JNINativeMethod nativeMethods[] = {
"initClass", "()V", (void*)&Java_netscape_javascript_JSObject_initClass,
"getMember", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getMember,
"getSlot", "(I)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getSlot,
"setMember", "(Ljava/lang/String;Ljava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setMember,
"setSlot", "(ILjava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setSlot,
"removeMember", "(Ljava/lang/String;)V", (void*)&Java_netscape_javascript_JSObject_removeMember,
"call", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_call,
"eval", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_eval,
"toString", "()Ljava/lang/String;", (void*)&Java_netscape_javascript_JSObject_toString,
"getWindow", "(Ljava/applet/Applet;)Lnetscape/javascript/JSObject;", (void*)&Java_netscape_javascript_JSObject_getWindow,
"finalize", "()V", (void*)&Java_netscape_javascript_JSObject_finalize,
/* "equals", "(Ljava/lang/Object;)Z", (void*)&Java_netscape_javascript_JSObject_equals */
};
(*jEnv)->RegisterNatives(jEnv, njJSObject, nativeMethods, sizeof(nativeMethods) / sizeof(JNINativeMethod));
if ((*jEnv)->ExceptionOccurred(jEnv)) {
report_java_initialization_error(jEnv, "Couldn't initialize JSObject native methods.");
(*jEnv)->ExceptionClear(jEnv);
}
/* call the initClass method, since we nailed the static initializer for testing. */
Java_netscape_javascript_JSObject_initClass(jEnv, njJSObject);
}
#endif
/* Load Netscape-specific Java extension classes, methods, and fields */
static JSBool
init_netscape_java_classes(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
{
LOAD_CLASS(netscape/javascript/JSObject, njJSObject);
LOAD_CLASS(netscape/javascript/JSException, njJSException);
LOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
#if XP_MAC
JSObject_RegisterNativeMethods(jEnv);
#endif
LOAD_CONSTRUCTOR(netscape.javascript.JSObject,
JSObject, "(I)V", njJSObject);
LOAD_CONSTRUCTOR(netscape.javascript.JSException,
JSException, "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V",
njJSException);
LOAD_FIELDID(netscape.javascript.JSObject,
internal, "I", njJSObject);
LOAD_FIELDID(netscape.javascript.JSException,
lineno, "I", njJSException);
LOAD_FIELDID(netscape.javascript.JSException,
tokenIndex, "I", njJSException);
LOAD_FIELDID(netscape.javascript.JSException,
source, "Ljava/lang/String;", njJSException);
LOAD_FIELDID(netscape.javascript.JSException,
filename, "Ljava/lang/String;", njJSException);
LOAD_STATIC_METHOD(netscape.javascript.JSUtil,
getStackTrace, "(Ljava/lang/Throwable;)Ljava/lang/String;",
njJSUtil);
return JS_TRUE;
}
JSJavaVM *jsjava_vm_list = NULL;
/*
* Called once per Java VM, this function initializes the classes, fields, and
* methods required for Java reflection. If java_vm is NULL, a new Java VM is
* created, using the provided classpath in addition to any default classpath.
* The classpath argument is ignored, however, if java_vm_arg is non-NULL.
*/
JSJavaVM *
JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
{
SystemJavaVM* java_vm;
JSJavaVM *jsjava_vm;
JNIEnv *jEnv;
PR_ASSERT(JSJ_callbacks);
PR_ASSERT(JSJ_callbacks->attach_current_thread);
PR_ASSERT(JSJ_callbacks->detach_current_thread);
PR_ASSERT(JSJ_callbacks->get_java_vm);
jsjava_vm = (JSJavaVM*)malloc(sizeof(JSJavaVM));
if (!jsjava_vm)
return NULL;
memset(jsjava_vm, 0, sizeof(JSJavaVM));
java_vm = java_vm_arg;
/* If a Java VM was passed in, try to attach to it on the current thread. */
if (java_vm) {
jEnv = JSJ_callbacks->attach_current_thread(java_vm);
if (jEnv == NULL) {
jsj_LogError("Failed to attach to Java VM thread\n");
free(jsjava_vm);
return NULL;
}
}
else {
PRBool ok;
PR_ASSERT(JSJ_callbacks->create_java_vm);
PR_ASSERT(JSJ_callbacks->destroy_java_vm);
ok = JSJ_callbacks->create_java_vm(&java_vm, &jEnv, initargs);
if (!ok || java_vm == NULL) {
jsj_LogError("Failed to create Java VM\n");
free(jsjava_vm);
return NULL;
}
/* Remember that we created the VM so that we know to destroy it later */
jsjava_vm->jsj_created_java_vm = JS_TRUE;
}
jsjava_vm->java_vm = java_vm;
jsjava_vm->main_thread_env = jEnv;
/* Load the Java classes, and the method and field descriptors required for
Java reflection. */
if (!init_java_VM_reflection(jsjava_vm, jEnv)) {
JSJ_DisconnectFromJavaVM(jsjava_vm);
return NULL;
}
/*
* JVM initialization for netscape.javascript.JSObject is performed
* independently of the other classes that are initialized in
* init_java_VM_reflection, because we allow it to fail. In the case
* of failure, LiveConnect is still operative, but only when calling
* from JS to Java and not vice-versa.
*/
init_netscape_java_classes(jsjava_vm, jEnv);
/* Put this VM on the list of all created VMs */
jsjava_vm->next = jsjava_vm_list;
jsjava_vm_list = jsjava_vm;
return jsjava_vm;
}
JSJCallbacks *JSJ_callbacks = NULL;
/* Called once to set up callbacks for all instances of LiveConnect */
void
JSJ_Init(JSJCallbacks *callbacks)
{
PR_ASSERT(callbacks);
JSJ_callbacks = callbacks;
}
/*
* Initialize the provided JSContext by setting up the JS classes necessary for
* reflection and by defining JavaPackage objects for the default Java packages
* as properties of global_obj. Additional packages may be pre-defined by
* setting the predefined_packages argument. (Pre-defining a Java package at
* initialization time is not necessary, but it will make package lookup faster
* and, more importantly, will avoid unnecessary network accesses if classes
* are being loaded over the network.)
*/
JSBool
JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
JavaPackageDef *predefined_packages)
{
/* Initialize the JavaScript classes used for reflection */
if (!jsj_init_JavaObject(cx, global_obj))
return JS_FALSE;
/* if (!jsj_init_JavaMember(cx, global_obj))
return JS_FALSE; */
if (!jsj_init_JavaPackage(cx, global_obj, predefined_packages))
return JS_FALSE;
if (!jsj_init_JavaClass(cx, global_obj))
return JS_FALSE;
if (!jsj_init_JavaArray(cx, global_obj))
return JS_FALSE;
if (!jsj_init_JavaMember(cx, global_obj))
return JS_FALSE;
return JS_TRUE;
}
/* Eliminate a reference to a Java class */
#define UNLOAD_CLASS(qualified_name, class) \
if (class) { \
(*jEnv)->DeleteGlobalRef(jEnv, class); \
class = NULL; \
}
/*
* This routine severs the connection to a Java VM, freeing all related resources.
* It shouldn't be called until the global scope has been cleared in all related
* JSContexts (so that all LiveConnect objects are finalized) and a JavaScript
* GC is performed. Otherwise, accessed to free'ed memory could result.
*/
void
JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
{
JNIEnv *jEnv;
SystemJavaVM *java_vm;
JSJavaVM *j, **jp;
java_vm = jsjava_vm->java_vm;
jEnv = jsjava_vm->main_thread_env;
/* Drop all references to Java objects and classes */
jsj_DiscardJavaObjReflections(jEnv);
jsj_DiscardJavaClassReflections(jEnv);
if (jsjava_vm->jsj_created_java_vm) {
(void)JSJ_callbacks->destroy_java_vm(java_vm, jEnv);
} else {
UNLOAD_CLASS(java/lang/Object, jlObject);
UNLOAD_CLASS(java/lang/Class, jlClass);
UNLOAD_CLASS(java/lang/reflect/Method, jlrMethod);
UNLOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
UNLOAD_CLASS(java/lang/reflect/Field, jlrField);
UNLOAD_CLASS(java/lang/Throwable, jlThrowable);
UNLOAD_CLASS(java/lang/System, jlSystem);
UNLOAD_CLASS(java/lang/Boolean, jlBoolean);
UNLOAD_CLASS(java/lang/Double, jlDouble);
UNLOAD_CLASS(java/lang/String, jlString);
UNLOAD_CLASS(java/lang/Void, jlVoid);
UNLOAD_CLASS(netscape/javascript/JSObject, njJSObject);
UNLOAD_CLASS(netscape/javascript/JSException, njJSException);
UNLOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
}
/* Remove this VM from the list of all JSJavaVM objects. */
for (jp = &jsjava_vm_list; (j = *jp) != NULL; jp = &j->next) {
if (j == jsjava_vm) {
*jp = jsjava_vm->next;
break;
}
}
PR_ASSERT(j);
free(jsjava_vm);
}
static JSJavaThreadState *thread_list = NULL;
static JSJavaThreadState *
new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jEnv)
{
JSJavaThreadState *jsj_env;
jsj_env = (JSJavaThreadState *)malloc(sizeof(JSJavaThreadState));
if (!jsj_env)
return NULL;
memset(jsj_env, 0, sizeof(JSJavaThreadState));
jsj_env->jEnv = jEnv;
jsj_env->jsjava_vm = jsjava_vm;
if (thread_name)
jsj_env->name = strdup(thread_name);
/* THREADSAFETY - need to protect against races */
jsj_env->next = thread_list;
thread_list = jsj_env;
return jsj_env;
}
static JSJavaThreadState *
find_jsjava_thread(JNIEnv *jEnv)
{
JSJavaThreadState *e, **p, *jsj_env;
jsj_env = NULL;
/* THREADSAFETY - need to protect against races in manipulating the thread list */
/* Search for the thread state among the list of all created
LiveConnect threads */
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
if (e->jEnv == jEnv) {
jsj_env = e;
*p = jsj_env->next;
break;
}
}
/* Move a found thread to head of list for faster search next time. */
if (jsj_env)
thread_list = jsj_env;
return jsj_env;
}
PR_IMPLEMENT(JSJavaThreadState *)
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *name, JNIEnv **java_envp)
{
JNIEnv *jEnv;
SystemJavaVM *java_vm;
JSJavaThreadState *jsj_env;
/* Try to attach a Java thread to the current native thread */
java_vm = jsjava_vm->java_vm;
jEnv = JSJ_callbacks->attach_current_thread(java_vm);
if (jEnv == NULL)
return NULL;
/* If we found an existing thread state, just return it. */
jsj_env = find_jsjava_thread(jEnv);
if (jsj_env)
return jsj_env;
/* Create a new wrapper around the thread/VM state */
jsj_env = new_jsjava_thread_state(jsjava_vm, name, jEnv);
if (java_envp)
*java_envp = jEnv;
return jsj_env;
}
static JSJavaVM *
map_java_vm_to_jsjava_vm(SystemJavaVM *java_vm)
{
JSJavaVM *v;
for (v = jsjava_vm_list; v; v = v->next) {
if (v->java_vm == java_vm)
return v;
}
return NULL;
}
/*
* Unfortunately, there's no standard means to associate any private data with
* a JNI thread environment, so we need to use the Java environment pointer as
* the key in a lookup table that maps it to a JSJavaThreadState structure,
* where we store all our per-thread private data. If no existing thread state
* is found, a new one is created.
*
* If an error occurs, returns NULL and sets the errp argument to an error
* message, which the caller is responsible for free'ing.
*/
JSJavaThreadState *
jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp)
{
JSJavaThreadState *jsj_env;
SystemJavaVM *java_vm;
JSJavaVM *jsjava_vm;
/* If we found an existing thread state, just return it. */
jsj_env = find_jsjava_thread(jEnv);
if (jsj_env)
return jsj_env;
/* No one set up a LiveConnect thread state for a given Java thread.
Invoke the callback to create one on-the-fly. */
/* First, figure out which Java VM is calling us */
java_vm = JSJ_callbacks->get_java_vm(jEnv);
if (jsjava_vm == NULL)
return NULL;
/* Get our private JavaVM data */
jsjava_vm = map_java_vm_to_jsjava_vm(java_vm);
if (!jsjava_vm) {
*errp = PR_smprintf("Total weirdness: No JSJavaVM wrapper ever created "
"for JavaVM 0x%08x", java_vm);
return NULL;
}
jsj_env = new_jsjava_thread_state(jsjava_vm, NULL, jEnv);
if (!jsj_env)
return NULL;
return jsj_env;
}
/*
* This function is used to specify a particular JSContext as *the* JavaScript
* execution environment to be used when LiveConnect is accessed from the given
* Java thread, i.e. by using one of the methods of netscape.javascript.JSObject.
* (There can only be one such JS context for a given Java thread. To
* multiplex JSContexts among a single thread, this function must be called
* before Java is invoked on that thread.) The return value is the previous
* context associated with the given Java thread.
*/
PR_IMPLEMENT(JSContext *)
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env)
{
JSContext *old_context;
old_context = jsj_env->cx;
jsj_env->cx = cx;
return old_context;
}
PR_IMPLEMENT(JSBool)
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
{
SystemJavaVM *java_vm;
JNIEnv* jEnv;
JSJavaThreadState *e, **p;
/* Disassociate the current native thread from its corresponding Java thread */
java_vm = jsj_env->jsjava_vm->java_vm;
jEnv = jsj_env->jEnv;
if (!JSJ_callbacks->detach_current_thread(java_vm, jEnv))
return JS_FALSE;
/* Destroy the LiveConnect execution environment passed in */
jsj_ClearPendingJSErrors(jsj_env);
/* THREADSAFETY - need to protect against races */
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
if (e == jsj_env) {
*p = jsj_env->next;
break;
}
}
free(jsj_env);
return JS_TRUE;
}
JSBool
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp)
{
JNIEnv *jEnv;
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp);
}
/*===========================================================================*/
#ifndef MOZILLA_CLIENT
/* The convenience functions below present a complete, but simplified
LiveConnect API which is designed to handle the special case of a single
Java-VM, single-threaded operation, and use of only one JSContext. */
/* We can get away with global variables in our single-threaded,
single-JSContext case. */
static JSJavaVM * the_jsj_vm = NULL;
static JSContext * the_cx = NULL;
static JSJavaThreadState * the_jsj_thread = NULL;
static JSObject * the_global_js_obj = NULL;
/* Trivial implementation of callback function */
static JSJavaThreadState *
default_map_js_context_to_jsj_thread(JSContext *cx, char **errp)
{
return the_jsj_thread;
}
/* Trivial implementation of callback function */
static JSContext *
default_map_jsj_thread_to_js_context(JSJavaThreadState *jsj_env, JNIEnv *jEnv, char **errp)
{
return the_cx;
}
/* Trivial implementation of callback function */
static JSObject *
default_map_java_object_to_js_object(JNIEnv *jEnv, jobject hint, char **errp)
{
return the_global_js_obj;
}
static PRBool PR_CALLBACK
default_create_java_vm(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs)
{
jint err;
const char* user_classpath = (const char*)initargs;
/* No Java VM supplied, so create our own */
JDK1_1InitArgs vm_args;
/* Magic constant indicates JRE version 1.1 */
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Prepend the classpath argument to the default JVM classpath */
if (user_classpath) {
#ifdef XP_UNIX
const char *full_classpath = PR_smprintf("%s:%s", user_classpath, vm_args.classpath);
#else
const char *full_classpath = PR_smprintf("%s;%s", user_classpath, vm_args.classpath);
#endif
if (!full_classpath) {
return PR_FALSE;
}
vm_args.classpath = (char*)full_classpath;
}
err = JNI_CreateJavaVM((JavaVM**)jvm, initialEnv, &vm_args);
return err == 0;
}
static PRBool PR_CALLBACK
default_destroy_java_vm(SystemJavaVM* jvm, JNIEnv* initialEnv)
{
JavaVM* java_vm = (JavaVM*)jvm;
jint err = (*java_vm)->DestroyJavaVM(java_vm);
return err == 0;
}
static JNIEnv* PR_CALLBACK
default_attach_current_thread(SystemJavaVM* jvm)
{
JavaVM* java_vm = (JavaVM*)jvm;
JNIEnv* env = NULL;
jint err = (*java_vm)->AttachCurrentThread(java_vm, &env, NULL);
return env;
}
static PRBool PR_CALLBACK
default_detach_current_thread(SystemJavaVM* jvm, JNIEnv* env)
{
JavaVM* java_vm = (JavaVM*)jvm;
/* assert that env is the JNIEnv of the current thread */
jint err = (*java_vm)->DetachCurrentThread(java_vm);
return err == 0;
}
static SystemJavaVM* PR_CALLBACK
default_get_java_vm(JNIEnv* env)
{
JavaVM* java_vm = NULL;
jint err = (*env)->GetJavaVM(env, &java_vm);
return (SystemJavaVM*)java_vm;
}
/* Trivial implementations of callback functions */
JSJCallbacks jsj_default_callbacks = {
default_map_jsj_thread_to_js_context,
default_map_js_context_to_jsj_thread,
default_map_java_object_to_js_object,
NULL,
NULL,
NULL,
NULL,
default_create_java_vm,
default_destroy_java_vm,
default_attach_current_thread,
default_detach_current_thread,
default_get_java_vm
};
/*
* Initialize the provided JSContext by setting up the JS classes necessary for
* reflection and by defining JavaPackage objects for the default Java packages
* as properties of global_obj. If java_vm is NULL, a new Java VM is
* created, using the provided classpath in addition to any default classpath.
* The classpath argument is ignored, however, if java_vm is non-NULL.
*/
JSBool
JSJ_SimpleInit(JSContext *cx, JSObject *global_obj, SystemJavaVM *java_vm, const char *classpath)
{
JNIEnv *jEnv;
PR_ASSERT(!the_jsj_vm);
the_jsj_vm = JSJ_ConnectToJavaVM(java_vm, (void*)classpath);
if (!the_jsj_vm)
return JS_FALSE;
JSJ_Init(&jsj_default_callbacks);
if (!JSJ_InitJSContext(cx, global_obj, NULL))
goto error;
the_cx = cx;
the_global_js_obj = global_obj;
the_jsj_thread = JSJ_AttachCurrentThreadToJava(the_jsj_vm, "main thread", &jEnv);
if (!the_jsj_thread)
goto error;
JSJ_SetDefaultJSContextForJavaThread(cx, the_jsj_thread);
return JS_TRUE;
error:
JSJ_SimpleShutdown();
return JS_FALSE;
}
/*
* Free up all LiveConnect resources. Destroy the Java VM if it was
* created by LiveConnect.
*/
PR_IMPLEMENT(void)
JSJ_SimpleShutdown()
{
PR_ASSERT(the_jsj_vm);
JSJ_DisconnectFromJavaVM(the_jsj_vm);
the_jsj_vm = NULL;
the_cx = NULL;
the_global_js_obj = NULL;
the_jsj_thread = NULL;
}
#endif /* MOZILLA_CLIENT */

View File

@@ -0,0 +1,76 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// Version stamp for this .DLL
#include <windows.h>
#include <ver.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4 // major, minor, release (alpha 1), build #
PRODUCTVERSION 4
FILEFLAGSMASK 0
FILEFLAGS 0 // final version
FILEOS VOS_DOS_WINDOWS16
FILETYPE VFT_DLL
FILESUBTYPE 0 // not used
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
VALUE "CompanyName", "Netscape Communications Corporation\0"
VALUE "FileDescription", "Netscape 16-bit JavaScript-Java Module\0"
VALUE "FileVersion", "4.0\0"
VALUE "InternalName", "JSJ1640\0"
VALUE "LegalCopyright", "Copyright Netscape Communications. 1994-96\0"
VALUE "LegalTrademarks", "Netscape, Mozilla\0"
VALUE "OriginalFilename","JSJ1640.DLL\0"
VALUE "ProductName", "NETSCAPE\0"
VALUE "ProductVersion", "4.0\0"
END
END
END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,403 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the definition of the JavaScript JavaArray class.
* Instances of JavaArray are used to reflect Java arrays.
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
/* Shorthands for ASCII (7-bit) decimal and hex conversion. */
#define JS7_ISDEC(c) (((c) >= '0') && ((c) <= '9'))
#define JS7_UNDEC(c) ((c) - '0')
/*
* Convert any jsval v to an integer jsval if ToString(v)
* contains a base-10 integer that fits into 31 bits.
* Otherwise return v.
*/
static jsval
try_convert_to_jsint(JSContext *cx, jsval idval)
{
const jschar *cp;
JSString *jsstr;
jsstr = JS_ValueToString(cx, idval);
if (!jsstr)
return idval;
cp = JS_GetStringChars(jsstr);
if (JS7_ISDEC(*cp)) {
jsuint index = JS7_UNDEC(*cp++);
jsuint oldIndex = 0;
jsuint c = 0;
if (index != 0) {
while (JS7_ISDEC(*cp)) {
oldIndex = index;
c = JS7_UNDEC(*cp);
index = 10*index + c;
cp++;
}
}
if (*cp == 0 &&
(oldIndex < (JSVAL_INT_MAX / 10) ||
(oldIndex == (JSVAL_INT_MAX / 10) && c < (JSVAL_INT_MAX % 10)))) {
return INT_TO_JSVAL(index);
}
}
return idval;
}
static JSBool
access_java_array_element(JSContext *cx,
JNIEnv *jEnv,
JSObject *obj,
jsid id,
jsval *vp,
JSBool do_assignment)
{
jsval idval;
jarray java_array;
JavaClassDescriptor *class_descriptor;
JavaObjectWrapper *java_wrapper;
jsize array_length, index;
JavaSignature *array_component_signature;
/* printf("In JavaArray_getProperty\n"); */
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper) {
const char *property_name;
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
if (!strcmp(property_name, "constructor")) {
*vp = JSVAL_VOID;
return JS_TRUE;
}
}
JS_ReportError(cx, "illegal operation on JavaArray prototype object");
return JS_FALSE;
}
class_descriptor = java_wrapper->class_descriptor;
java_array = java_wrapper->java_obj;
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_ARRAY);
JS_IdToValue(cx, id, &idval);
if (!JSVAL_IS_INT(idval))
idval = try_convert_to_jsint(cx, idval);
if (!JSVAL_IS_INT(idval)) {
/*
* Usually, properties of JavaArray objects are indexed by integers, but
* Java arrays also inherit all the methods of java.lang.Object, so a
* string-valued property is also possible.
*/
if (JSVAL_IS_STRING(idval)) {
const char *member_name;
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
if (do_assignment) {
JSVersion version = JS_GetVersion(cx);
if (!JSVERSION_IS_ECMA(version)) {
JS_ReportError(cx, "Attempt to write to invalid Java array "
"element \"%s\"", member_name);
return JS_FALSE;
} else {
*vp = JSVAL_VOID;
return JS_TRUE;
}
} else {
if (!strcmp(member_name, "length")) {
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
if (array_length < 0)
return JS_FALSE;
if (vp)
*vp = INT_TO_JSVAL(array_length);
return JS_TRUE;
}
/* Check to see if we're reflecting a Java array method */
return JavaObject_getPropertyById(cx, obj, id, vp);
}
}
JS_ReportError(cx, "invalid Java array index expression");
return JS_FALSE;
}
index = JSVAL_TO_INT(idval);
#if 0
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
if (array_length < 0)
return JS_FALSE;
/* Just let Java throw an exception instead of checking array bounds here */
if (index < 0 || index >= array_length) {
JS_ReportError(cx, "Java array index %d out of range", index);
return JS_FALSE;
}
#endif
array_component_signature = class_descriptor->array_component_signature;
if (!vp)
return JS_TRUE;
if (do_assignment) {
return jsj_SetJavaArrayElement(cx, jEnv, java_array, index,
array_component_signature, *vp);
} else {
return jsj_GetJavaArrayElement(cx, jEnv, java_array, index,
array_component_signature, vp);
}
}
PR_STATIC_CALLBACK(JSBool)
JavaArray_getPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
return access_java_array_element(cx, jEnv, obj, id, vp, JS_FALSE);
}
PR_STATIC_CALLBACK(JSBool)
JavaArray_setPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
return access_java_array_element(cx, jEnv, obj, id, vp, JS_TRUE);
}
static JSBool
JavaArray_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
)
{
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
return access_java_array_element(cx, jEnv, obj, id, NULL, JS_FALSE);
}
static JSBool
JavaArray_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp)
{
JS_ReportError(cx, "Cannot define a new property in a JavaArray");
return JS_FALSE;
}
static JSBool
JavaArray_getAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
return JS_FALSE;
}
static JSBool
JavaArray_setAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
PR_ASSERT(0);
return JS_FALSE;
}
/* Silently ignore all setAttribute attempts */
return JS_TRUE;
}
static JSBool
JavaArray_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
JSVersion version = JS_GetVersion(cx);
*vp = JSVAL_FALSE;
if (!JSVERSION_IS_ECMA(version)) {
JS_ReportError(cx, "Properties of JavaArray objects may not be deleted");
return JS_FALSE;
} else {
/* Attempts to delete permanent properties are silently ignored
by ECMAScript. */
return JS_TRUE;
}
}
static JSBool
JavaArray_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
/* printf("In JavaArray_defaultValue()\n"); */
return JavaObject_convert(cx, obj, JSTYPE_STRING, vp);
}
static JSBool
JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
JavaObjectWrapper *java_wrapper;
JNIEnv *jEnv;
jsize array_length, index;
java_wrapper = JS_GetPrivate(cx, obj);
/* Check for prototype object */
if (!java_wrapper) {
*statep = JSVAL_NULL;
if (idp)
*idp = INT_TO_JSVAL(0);
return JS_TRUE;
}
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_wrapper->java_obj);
if (array_length < 0)
return JS_FALSE;
switch(enum_op) {
case JSENUMERATE_INIT:
*statep = INT_TO_JSVAL(0);
if (idp)
*idp = INT_TO_JSVAL(array_length);
return JS_TRUE;
case JSENUMERATE_NEXT:
index = JSVAL_TO_INT(*statep);
if (index < array_length) {
JS_ValueToId(cx, INT_TO_JSVAL(index), idp);
index++;
*statep = INT_TO_JSVAL(index);
return JS_TRUE;
}
/* Fall through ... */
case JSENUMERATE_DESTROY:
*statep = JSVAL_NULL;
return JS_TRUE;
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
JavaArray_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
switch (mode) {
case JSACC_WATCH:
JS_ReportError(cx, "Cannot place watchpoints on JavaArray object properties");
return JS_FALSE;
case JSACC_IMPORT:
JS_ReportError(cx, "Cannot export a JavaArray object's properties");
return JS_FALSE;
default:
return JS_TRUE;
}
}
JSObjectOps JavaArray_ops = {
/* Mandatory non-null function pointer members. */
NULL, /* newObjectMap */
NULL, /* destroyObjectMap */
JavaArray_lookupProperty,
JavaArray_defineProperty,
JavaArray_getPropertyById, /* getProperty */
JavaArray_setPropertyById, /* setProperty */
JavaArray_getAttributes,
JavaArray_setAttributes,
JavaArray_deleteProperty,
JavaArray_defaultValue,
JavaArray_newEnumerate,
JavaArray_checkAccess,
/* Optionally non-null members start here. */
NULL, /* thisObject */
NULL, /* dropProperty */
NULL, /* call */
NULL, /* construct */
NULL, /* xdrObject */
NULL /* hasInstance */
};
static JSObjectOps *
JavaArray_getObjectOps(JSContext *cx, JSClass *clazz)
{
return &JavaArray_ops;
}
JSClass JavaArray_class = {
"JavaArray", JSCLASS_HAS_PRIVATE,
NULL, NULL, NULL, NULL,
NULL, NULL, JavaObject_convert, JavaObject_finalize,
JavaArray_getObjectOps,
};
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
/* Initialize the JS JavaArray class */
JSBool
jsj_init_JavaArray(JSContext *cx, JSObject *global_obj)
{
JavaArray_ops.newObjectMap = js_ObjectOps.newObjectMap;
JavaArray_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
if (!JS_InitClass(cx, global_obj,
0, &JavaArray_class, 0, 0,
0, 0, 0, 0))
return JS_FALSE;
return JS_TRUE;
}

View File

@@ -0,0 +1,586 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the native code implementation of JS's JavaClass class.
*
* A JavaClass is JavaScript's representation of a Java class.
* Its parent JS object is always a JavaPackage object. A JavaClass is not an
* exact reflection of Java's corresponding java.lang.Class object. Rather,
* the properties of a JavaClass are the static methods and properties of the
* corresponding Java class.
*
* Note that there is no runtime equivalent to the JavaClass class in Java.
* (Although there are instances of java.lang.String and there are static
* methods of java.lang.String that can be invoked, there's no such thing as
* a first-class object that can be referenced simply as "java.lang.String".)
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
static JSBool
JavaClass_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
char *name;
JSString *str;
JavaClassDescriptor *class_descriptor;
class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor)
return JS_FALSE;
switch(type) {
case JSTYPE_STRING:
/* Convert '/' to '.' so that it looks like Java language syntax. */
if (!class_descriptor->name)
break;
name = PR_smprintf("[JavaClass %s]", class_descriptor->name);
if (!name) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
str = JS_NewString(cx, name, strlen(name));
if (!str) {
free(name);
/* It's not necessary to call JS_ReportOutOfMemory(), as
JS_NewString() will do so on failure. */
return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str);
return JS_TRUE;
default:
break;
}
return JS_TRUE;
}
static JSBool
lookup_static_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
JavaClassDescriptor **class_descriptorp,
jsid id, JavaMemberDescriptor **memberp)
{
jsval idval;
JavaMemberDescriptor *member_descriptor;
const char *member_name;
JavaClassDescriptor *class_descriptor;
class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor) {
*class_descriptorp = NULL;
*memberp = NULL;
return JS_TRUE;
}
if (class_descriptorp)
*class_descriptorp = class_descriptor;
member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (!member_descriptor) {
JS_IdToValue(cx, id, &idval);
if (!JSVAL_IS_STRING(idval)) {
JS_ReportError(cx, "invalid JavaClass property expression. "
"(methods and fields of a JavaClass object can only be identified by their name)");
return JS_FALSE;
}
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
/* Why do we have to do this ? */
if (!strcmp(member_name, "prototype")) {
*memberp = NULL;
return JS_TRUE;
}
JS_ReportError(cx, "Java class %s has no public static field or method named \"%s\"",
class_descriptor->name, member_name);
return JS_FALSE;
}
if (memberp)
*memberp = member_descriptor;
return JS_TRUE;
}
PR_STATIC_CALLBACK(JSBool)
JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jsval idval;
jclass java_class;
const char *member_name;
JavaClassDescriptor *class_descriptor;
JavaMemberDescriptor *member_descriptor;
JNIEnv *jEnv;
/* printf("In JavaClass_getProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
return JS_FALSE;
if (!member_descriptor) {
*vp = JSVAL_VOID;
return JS_TRUE;
}
java_class = class_descriptor->java_class;
if (member_descriptor->field) {
if (!member_descriptor->methods) {
return jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, vp);
} else {
PR_ASSERT(0);
}
} else {
JSFunction *function;
/* TODO - eliminate JSFUN_BOUND_METHOD */
JS_IdToValue(cx, id, &idval);
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
function = JS_NewFunction(cx, jsj_JavaStaticMethodWrapper, 0,
JSFUN_BOUND_METHOD, obj, member_name);
if (!function)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(JS_GetFunctionObject(function));
}
return JS_TRUE;
}
PR_STATIC_CALLBACK(JSBool)
JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jclass java_class;
const char *member_name;
JavaClassDescriptor *class_descriptor;
JavaMemberDescriptor *member_descriptor;
jsval idval;
JNIEnv *jEnv;
/* printf("In JavaClass_setProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
return JS_FALSE;
/* Check for the case where there is a method with the given name, but no field
with that name */
if (!member_descriptor->field)
goto no_such_field;
/* Silently fail if field value is final (immutable), as required by ECMA spec */
if (member_descriptor->field->modifiers & ACC_FINAL)
return JS_TRUE;
java_class = class_descriptor->java_class;
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, *vp);
no_such_field:
JS_IdToValue(cx, id, &idval);
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
JS_ReportError(cx, "No static field named \"%s\" in Java class %s",
member_name, class_descriptor->name);
return JS_FALSE;
}
/*
* Free the private native data associated with the JavaPackage object.
*/
PR_STATIC_CALLBACK(void)
JavaClass_finalize(JSContext *cx, JSObject *obj)
{
JNIEnv *jEnv;
JavaClassDescriptor *class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor)
return;
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return;
/* printf("Finalizing %s\n", class_descriptor->name); */
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
}
static JSBool
JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
)
{
JNIEnv *jEnv;
JSErrorReporter old_reporter;
/* printf("In JavaClass_lookupProperty()\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
old_reporter = JS_SetErrorReporter(cx, NULL);
if (lookup_static_member_by_id(cx, jEnv, obj, NULL, id, NULL)) {
*objp = obj;
*propp = (JSProperty*)1;
} else {
*objp = NULL;
*propp = NULL;
}
JS_SetErrorReporter(cx, old_reporter);
return JS_TRUE;
}
static JSBool
JavaClass_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp)
{
JS_ReportError(cx, "Cannot define a new property in a JavaClass");
return JS_FALSE;
}
static JSBool
JavaClass_getAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
return JS_FALSE;
}
static JSBool
JavaClass_setAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
PR_ASSERT(0);
return JS_FALSE;
}
/* Silently ignore all setAttribute attempts */
return JS_TRUE;
}
static JSBool
JavaClass_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
JSVersion version = JS_GetVersion(cx);
*vp = JSVAL_FALSE;
if (!JSVERSION_IS_ECMA(version)) {
JS_ReportError(cx, "Properties of JavaClass objects may not be deleted");
return JS_FALSE;
} else {
/* Attempts to delete permanent properties are silently ignored
by ECMAScript. */
return JS_TRUE;
}
}
static JSBool
JavaClass_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
/* printf("In JavaClass_defaultValue()\n"); */
return JavaClass_convert(cx, obj, JSTYPE_STRING, vp);
}
static JSBool
JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
JavaMemberDescriptor *member_descriptor;
JavaClassDescriptor *class_descriptor;
JNIEnv *jEnv;
class_descriptor = JS_GetPrivate(cx, obj);
/* Check for prototype JavaClass object */
if (!class_descriptor) {
*statep = JSVAL_NULL;
if (idp)
*idp = INT_TO_JSVAL(0);
return JS_TRUE;
}
switch(enum_op) {
case JSENUMERATE_INIT:
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor);
*statep = PRIVATE_TO_JSVAL(member_descriptor);
if (idp)
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
return JS_TRUE;
case JSENUMERATE_NEXT:
member_descriptor = JSVAL_TO_PRIVATE(*statep);
if (member_descriptor) {
*idp = member_descriptor->id;
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
return JS_TRUE;
}
/* Fall through ... */
case JSENUMERATE_DESTROY:
*statep = JSVAL_NULL;
return JS_TRUE;
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
JavaClass_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
switch (mode) {
case JSACC_WATCH:
JS_ReportError(cx, "Cannot place watchpoints on JavaClass object properties");
return JS_FALSE;
case JSACC_IMPORT:
JS_ReportError(cx, "Cannot export a JavaClass object's properties");
return JS_FALSE;
default:
return JS_TRUE;
}
}
/*
* Implement the JavaScript instanceof operator for JavaClass objects by using
* the equivalent Java instanceof operation.
*/
static JSBool
JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval,
JSBool *has_instancep)
{
JavaClassDescriptor *class_descriptor;
JavaObjectWrapper *java_wrapper;
JSClass *js_class;
JSBool has_instance;
JSObject *candidate_obj;
jclass java_class;
jobject java_obj;
JNIEnv *jEnv;
has_instance = JS_FALSE;
class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor) {
JS_ReportError(cx, "illegal operation on JavaClass prototype object");
return JS_FALSE;
}
/*
* Make sure that the thing to the left of the instanceof operator is a
* Java object.
*/
if (!JSVAL_IS_OBJECT(candidate_jsval))
goto done;
candidate_obj = JSVAL_TO_OBJECT(candidate_jsval);
js_class = JS_GetClass(candidate_obj);
if ((js_class != &JavaObject_class) && (js_class != &JavaArray_class))
goto done;
java_class = class_descriptor->java_class;
java_wrapper = JS_GetPrivate(cx, candidate_obj);
if (!java_wrapper) {
JS_ReportError(cx, "illegal operation on prototype object");
return JS_FALSE;
}
java_obj = java_wrapper->java_obj;
/* Get JNI pointer */
jsj_MapJSContextToJSJThread(cx, &jEnv);
has_instance = (*jEnv)->IsInstanceOf(jEnv, java_obj, java_class);
done:
*has_instancep = has_instance;
return JS_TRUE;
}
JSObjectOps JavaClass_ops = {
/* Mandatory non-null function pointer members. */
NULL, /* newObjectMap */
NULL, /* destroyObjectMap */
JavaClass_lookupProperty,
JavaClass_defineProperty,
JavaClass_getPropertyById, /* getProperty */
JavaClass_setPropertyById, /* setProperty */
JavaClass_getAttributes,
JavaClass_setAttributes,
JavaClass_deleteProperty,
JavaClass_defaultValue,
JavaClass_newEnumerate,
JavaClass_checkAccess,
/* Optionally non-null members start here. */
NULL, /* thisObject */
NULL, /* dropProperty */
jsj_JavaConstructorWrapper, /* call */
jsj_JavaConstructorWrapper, /* construct */
NULL, /* xdrObject */
JavaClass_hasInstance, /* hasInstance */
};
static JSObjectOps *
JavaClass_getObjectOps(JSContext *cx, JSClass *clazz)
{
return &JavaClass_ops;
}
JSClass JavaClass_class = {
"JavaClass", JSCLASS_HAS_PRIVATE,
NULL, NULL, NULL, NULL,
NULL, NULL, JavaClass_convert, JavaClass_finalize,
JavaClass_getObjectOps,
};
static JSObject *
jsj_new_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj,
JavaClassDescriptor *class_descriptor)
{
JSObject *JavaClass_obj;
JavaClass_obj = JS_NewObject(cx, &JavaClass_class, 0, parent_obj);
if (!JavaClass_obj)
return NULL;
JS_SetPrivate(cx, JavaClass_obj, (void *)class_descriptor);
#ifdef DEBUG
/* printf("JavaClass \'%s\' created\n", class_descriptor->name); */
#endif
return JavaClass_obj;
}
JSObject *
jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj,
const char *simple_class_name,
jclass java_class)
{
JavaClassDescriptor *class_descriptor;
JSObject *JavaClass_obj;
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
if (!class_descriptor)
return NULL;
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, parent_obj, class_descriptor);
if (!JavaClass_obj)
return NULL;
if (!JS_DefineProperty(cx, parent_obj, simple_class_name,
OBJECT_TO_JSVAL(JavaClass_obj), 0, 0,
JSPROP_PERMANENT|JSPROP_READONLY|JSPROP_ENUMERATE))
return NULL;
return JavaClass_obj;
}
/*
* The getClass() native JS method is defined as a property of the global
* object. Given a JavaObject it returns the corresponding JavaClass. This
* is useful for accessing static methods and fields.
*
* js> getClass(new java.lang.String("foo"))
* [JavaClass java.lang.String]
*/
static JSBool
getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSObject *obj_arg, *JavaClass_obj;
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (argc != 1 ||
!JSVAL_IS_OBJECT(argv[0]) ||
!(obj_arg = JSVAL_TO_OBJECT(argv[0])) ||
(!JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) &&
!JS_InstanceOf(cx, obj_arg, &JavaArray_class, 0))) {
JS_ReportError(cx, "getClass expects a Java object argument");
return JS_FALSE;
}
java_wrapper = JS_GetPrivate(cx, obj_arg);
if (!java_wrapper) {
JS_ReportError(cx, "getClass called on prototype object");
return JS_FALSE;
}
class_descriptor = java_wrapper->class_descriptor;
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor);
if (!JavaClass_obj)
return JS_FALSE;
*rval = OBJECT_TO_JSVAL(JavaClass_obj);
return JS_TRUE;
}
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
JSBool
jsj_init_JavaClass(JSContext *cx, JSObject *global_obj)
{
JavaClass_ops.newObjectMap = js_ObjectOps.newObjectMap;
JavaClass_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
/* Define JavaClass class */
if (!JS_InitClass(cx, global_obj, 0, &JavaClass_class, 0, 0, 0, 0, 0, 0))
return JS_FALSE;
if (!JS_DefineFunction(cx, global_obj, "getClass", getClass, 0,
JSPROP_READONLY))
return JS_FALSE;
return jsj_InitJavaClassReflectionsTable();
}

View File

@@ -0,0 +1,134 @@
/* -*- Mode: C; tab-width: 8 -*-
* Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the native code implementation of JS's JavaMember class.
* JavaMember's are a strange beast required only to handle the special case
* of a public field and a public method that appear in the same class and
* have the same name. When such a field/method is used in Java, the compiler
* can statically determine from context whether the field or the method is
* being referenced, but that is not possible with JavaScript. For example:
*
* ambiguousVal = javaObj.fieldOrMethod; // ambiguousVal is a JavaMember object
* a = ambiguousVal(); // ambiguousVal used as a method value
* b = ambiguousVal + 4; // ambiguousVal used as a field value
*
* A JavaMember instance carries both the captured value of the Java field and
* the method value until the context that the value is to be used in is known,
* at which point conversion forces the use of one or the other.
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
/* Private, native portion of a JavaMember */
typedef struct JavaMethodOrFieldValue {
jsval method_val;
jsval field_val;
} JavaMethodOrFieldValue;
JSObject *
jsj_CreateJavaMember(JSContext *cx, jsval method_val, jsval field_val)
{
JavaMethodOrFieldValue *member_val;
JSObject *JavaMember_obj;
member_val = (JavaMethodOrFieldValue *)JS_malloc(cx, sizeof(*member_val));
if (!member_val)
return NULL;
JavaMember_obj = JS_NewObject(cx, &JavaMember_class, 0, 0);
if (!JavaMember_obj) {
JS_free(cx, member_val);
return NULL;
}
JS_SetPrivate(cx, JavaMember_obj, (void *)member_val);
member_val->method_val = method_val;
JS_AddRoot(cx, &member_val->method_val);
member_val->field_val = field_val;
if (JSVAL_IS_GCTHING(field_val))
JS_AddRoot(cx, &member_val->field_val);
return JavaMember_obj;
}
static void
JavaMember_finalize(JSContext *cx, JSObject *obj)
{
JavaMethodOrFieldValue *member_val;
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return;
member_val = JS_GetPrivate(cx, obj);
if (!member_val)
return;
JS_RemoveRoot(cx, &member_val->method_val);
if (JSVAL_IS_GCTHING(member_val->method_val))
JS_RemoveRoot(cx, &member_val->method_val);
JS_free(cx, member_val);
}
static JSBool
JavaMember_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
JavaMethodOrFieldValue *member_val;
member_val = JS_GetPrivate(cx, obj);
if (!member_val) {
if (type == JSTYPE_OBJECT) {
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
}
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
return JS_FALSE;
}
switch (type) {
case JSTYPE_VOID:
case JSTYPE_STRING:
case JSTYPE_NUMBER:
case JSTYPE_BOOLEAN:
case JSTYPE_OBJECT:
*vp = member_val->field_val;
return JS_TRUE;
case JSTYPE_FUNCTION:
*vp = member_val->method_val;
return JS_TRUE;
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
JSClass JavaMember_class = {
"JavaMember", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub,
JavaMember_convert, JavaMember_finalize
};
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
JSBool
jsj_init_JavaMember(JSContext *cx, JSObject *global_obj)
{
if (!JS_InitClass(cx, global_obj,
0, &JavaMember_class, 0, 0,
0, 0,
0, 0))
return JS_FALSE;
return JS_TRUE;
}

View File

@@ -0,0 +1,686 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the native code implementation of JS's JavaObject class.
*
* An instance of JavaObject is the JavaScript reflection of a Java object.
*
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
#include "jsj_hash.h" /* Hash table with Java object as key */
/*
* This is a hash table that maps from Java objects to JS objects.
* It is used to ensure that the same JS object is obtained when a Java
* object is reflected more than once, so that JS object equality tests
* work in the expected manner, i.e. the "==" and "===" operators.
*
* The table entry keys are Java objects (of type jobject) and the entry values
* are JSObject pointers. Because the jobject type is an opaque handle and
* not necessarily a pointer, the hashing and key comparison functions must
* invoke the appropriate JVM functions.
*
* When the corresponding JS object instance is finalized, the entry is
* removed from the table, and a Java GC root for the Java object is removed.
*/
static JSJHashTable *java_obj_reflections = NULL;
#ifdef JS_THREADSAFE
static PRMonitor *java_obj_reflections_monitor = NULL;
#endif
static JSBool
init_java_obj_reflections_table()
{
java_obj_reflections =
JSJ_NewHashTable(512, jsj_HashJavaObject, jsj_JavaObjectComparator,
NULL, NULL, NULL);
if (!java_obj_reflections)
return JS_FALSE;
#ifdef JS_THREADSAFE
java_obj_reflections_monitor = PR_NewNamedMonitor("java_obj_reflections");
if (!java_obj_reflections_monitor) {
PR_HashTableDestroy(java_obj_reflections);
return JS_FALSE;
}
#endif
return JS_TRUE;
}
JSObject *
jsj_WrapJavaObject(JSContext *cx,
JNIEnv *jEnv,
jobject java_obj,
jclass java_class)
{
JSJHashNumber hash_code;
JSClass *js_class;
JSObject *js_wrapper_obj;
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
JSJHashEntry *he, **hep;
js_wrapper_obj = NULL;
hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);
#ifdef JS_THREADSAFE
PR_EnterMonitor(java_obj_reflections_monitor);
#endif
hep = JSJ_HashTableRawLookup(java_obj_reflections,
hash_code, java_obj, (void*)jEnv);
he = *hep;
if (he) {
js_wrapper_obj = (JSObject *)he->value;
if (js_wrapper_obj)
goto done;
}
/* No existing reflection found. Construct a new one */
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
if (!class_descriptor)
goto done;
if (class_descriptor->type == JAVA_SIGNATURE_ARRAY) {
js_class = &JavaArray_class;
} else {
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS);
js_class = &JavaObject_class;
}
/* Create new JS object to reflect Java object */
js_wrapper_obj = JS_NewObject(cx, js_class, NULL, NULL);
if (!js_wrapper_obj)
goto done;
/* Create private, native portion of JavaObject */
java_wrapper =
(JavaObjectWrapper *)JS_malloc(cx, sizeof(JavaObjectWrapper));
if (!java_wrapper) {
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
goto done;
}
JS_SetPrivate(cx, js_wrapper_obj, java_wrapper);
java_wrapper->class_descriptor = class_descriptor;
java_obj = (*jEnv)->NewGlobalRef(jEnv, java_obj);
java_wrapper->java_obj = java_obj;
if (!java_obj)
goto out_of_memory;
/* Add the JavaObject to the hash table */
he = JSJ_HashTableRawAdd(java_obj_reflections, hep, hash_code,
java_obj, js_wrapper_obj, (void*)jEnv);
if (!he) {
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
goto out_of_memory;
}
done:
#ifdef JS_THREADSAFE
PR_ExitMonitor(java_obj_reflections_monitor);
#endif
return js_wrapper_obj;
out_of_memory:
/* No need to free js_wrapper_obj, as it will be finalized by GC. */
JS_ReportOutOfMemory(cx);
js_wrapper_obj = NULL;
goto done;
}
static void
remove_java_obj_reflection_from_hashtable(jobject java_obj, JNIEnv *jEnv)
{
JSJHashNumber hash_code;
JSJHashEntry *he, **hep;
hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);
#ifdef JS_THREADSAFE
PR_EnterMonitor(java_obj_reflections_monitor);
#endif
hep = JSJ_HashTableRawLookup(java_obj_reflections, hash_code,
java_obj, (void*)jEnv);
he = *hep;
PR_ASSERT(he);
if (he)
JSJ_HashTableRawRemove(java_obj_reflections, hep, he, (void*)jEnv);
#ifdef JS_THREADSAFE
PR_ExitMonitor(java_obj_reflections_monitor);
#endif
}
void
JavaObject_finalize(JSContext *cx, JSObject *obj)
{
JavaObjectWrapper *java_wrapper;
jobject java_obj;
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return;
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper)
return;
java_obj = java_wrapper->java_obj;
if (java_obj) {
remove_java_obj_reflection_from_hashtable(java_obj, jEnv);
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
}
jsj_ReleaseJavaClassDescriptor(cx, jEnv, java_wrapper->class_descriptor);
JS_free(cx, java_wrapper);
}
/* Trivial helper for jsj_DiscardJavaObjReflections(), below */
static PRIntn
enumerate_remove_java_obj(JSJHashEntry *he, PRIntn i, void *arg)
{
JNIEnv *jEnv = (JNIEnv*)arg;
jobject java_obj;
JavaObjectWrapper *java_wrapper;
JSObject *java_wrapper_obj;
java_wrapper_obj = (JSObject *)he->value;
java_wrapper = JS_GetPrivate(NULL, java_wrapper_obj);
java_obj = java_wrapper->java_obj;
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
java_wrapper->java_obj = NULL;
return HT_ENUMERATE_REMOVE;
}
/* This shutdown routine discards all JNI references to Java objects
that have been reflected into JS, even if there are still references
to them from JS. */
void
jsj_DiscardJavaObjReflections(JNIEnv *jEnv)
{
if (java_obj_reflections) {
JSJ_HashTableEnumerateEntries(java_obj_reflections,
enumerate_remove_java_obj,
(void*)jEnv);
JSJ_HashTableDestroy(java_obj_reflections);
java_obj_reflections = NULL;
}
}
PR_CALLBACK JSBool
JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
jobject java_obj;
JNIEnv *jEnv;
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper) {
if (type == JSTYPE_OBJECT) {
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
}
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
return JS_FALSE;
}
java_obj = java_wrapper->java_obj;
class_descriptor = java_wrapper->class_descriptor;
switch (type) {
case JSTYPE_OBJECT:
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
case JSTYPE_FUNCTION:
JS_ReportError(cx, "can't convert Java object to function");
return JS_FALSE;
case JSTYPE_VOID:
case JSTYPE_STRING:
/* Either extract a C-string from the java.lang.String object
or call the Java toString() method */
return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, java_obj, vp);
case JSTYPE_NUMBER:
/* Call Java doubleValue() method, if applicable */
return jsj_ConvertJavaObjectToJSNumber(cx, jEnv, class_descriptor, java_obj, vp);
case JSTYPE_BOOLEAN:
/* Call booleanValue() method, if applicable */
return jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp);
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
lookup_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
JavaObjectWrapper **java_wrapperp,
jsid id,
JavaMemberDescriptor **member_descriptorp)
{
jsval idval;
JavaObjectWrapper *java_wrapper;
JavaMemberDescriptor *member_descriptor;
const char *member_name, *property_name;
JavaClassDescriptor *class_descriptor;
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper) {
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
if (!strcmp(property_name, "constructor")) {
*java_wrapperp = NULL;
*member_descriptorp = NULL;
return JS_TRUE;
}
}
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
return JS_FALSE;
}
class_descriptor = java_wrapper->class_descriptor;
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS ||
class_descriptor->type == JAVA_SIGNATURE_ARRAY);
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (!member_descriptor) {
JS_IdToValue(cx, id, &idval);
if (!JSVAL_IS_STRING(idval)) {
JS_ReportError(cx, "invalid JavaObject property expression. "
"(methods and field properties of a JavaObject object can only be strings)");
return JS_FALSE;
}
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
JS_ReportError(cx, "Java class %s has no public instance field or "
"method named \"%s\"",
class_descriptor->name, member_name);
return JS_FALSE;
}
/* Success. Handle the multiple return values */
if (java_wrapperp)
*java_wrapperp = java_wrapper;
if (member_descriptorp)
*member_descriptorp = member_descriptor;
return JS_TRUE;
}
PR_CALLBACK JSBool
JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jobject java_obj;
JavaMemberDescriptor *member_descriptor;
JavaObjectWrapper *java_wrapper;
JNIEnv *jEnv;
JSObject *funobj;
jsval field_val, method_val;
JSBool success;
/* printf("In JavaObject_getProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor))
return JS_FALSE;
/* Handle access to "constructor" property of prototype object with
silent failure. */
if (!member_descriptor) {
*vp = JSVAL_VOID;
return JS_TRUE;
}
java_obj = java_wrapper->java_obj;
field_val = method_val = JSVAL_VOID;
/* If a field member, get the value of the field */
if (member_descriptor->field) {
success = jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, &field_val);
if (!success)
return JS_FALSE;
}
/* If a method member, build a wrapper around the Java method */
if (member_descriptor->methods) {
/* Create a function object with this JavaObject as its parent, so that
JSFUN_BOUND_METHOD binds it as the default 'this' for the function. */
funobj = JS_CloneFunctionObject(cx, member_descriptor->invoke_func_obj, obj);
if (!funobj)
return JS_FALSE;
method_val = OBJECT_TO_JSVAL(funobj);
}
#if TEST_JAVAMEMBER
/* Always create a JavaMember object, even though it's inefficient */
obj = jsj_CreateJavaMember(cx, method_val, field_val);
if (!obj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(obj);
#else /* !TEST_JAVAMEMBER */
if (member_descriptor->field) {
if (!member_descriptor->methods) {
/* Return value of Java field */
*vp = field_val;
} else {
/* Handle special case of access to a property that could refer
to either a Java field or a method that share the same name.
In Java, such ambiguity is not possible because the compiler
can statically determine which is being accessed. */
obj = jsj_CreateJavaMember(cx, method_val, field_val);
if (!obj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(obj);
}
} else {
/* Return wrapper around Java method */
*vp = method_val;
}
#endif /* !TEST_JAVAMEMBER */
return JS_TRUE;
}
PR_STATIC_CALLBACK(JSBool)
JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jobject java_obj;
const char *member_name;
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
JavaMemberDescriptor *member_descriptor;
jsval idval;
JNIEnv *jEnv;
/* printf("In JavaObject_setProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor))
return JS_FALSE;
/* Check for the case where there is a method with the give name, but no field
with that name */
if (!member_descriptor->field)
goto no_such_field;
/* Silently fail if field value is final (immutable), as required by ECMA spec */
if (member_descriptor->field->modifiers & ACC_FINAL)
return JS_TRUE;
java_obj = java_wrapper->java_obj;
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, *vp);
no_such_field:
JS_IdToValue(cx, id, &idval);
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
class_descriptor = java_wrapper->class_descriptor;
JS_ReportError(cx, "No instance field named \"%s\" in Java class %s",
member_name, class_descriptor->name);
return JS_FALSE;
}
static JSBool
JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
)
{
JNIEnv *jEnv;
JSErrorReporter old_reporter;
/* printf("In JavaObject_lookupProperty()\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
old_reporter = JS_SetErrorReporter(cx, NULL);
if (lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL)) {
*objp = obj;
*propp = (JSProperty*)1;
} else {
*objp = NULL;
*propp = NULL;
}
JS_SetErrorReporter(cx, old_reporter);
return JS_TRUE;
}
static JSBool
JavaObject_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp)
{
JS_ReportError(cx, "Cannot define a new property in a JavaObject");
return JS_FALSE;
}
static JSBool
JavaObject_getAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
return JS_FALSE;
}
static JSBool
JavaObject_setAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
PR_ASSERT(0);
return JS_FALSE;
}
/* Silently ignore all setAttribute attempts */
return JS_TRUE;
}
static JSBool
JavaObject_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
JSVersion version = JS_GetVersion(cx);
*vp = JSVAL_FALSE;
if (!JSVERSION_IS_ECMA(version)) {
JS_ReportError(cx, "Properties of JavaObject objects may not be deleted");
return JS_FALSE;
} else {
/* Attempts to delete permanent properties are silently ignored
by ECMAScript. */
return JS_TRUE;
}
}
static JSBool
JavaObject_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
/* printf("In JavaObject_defaultValue()\n"); */
return JavaObject_convert(cx, obj, type, vp);
}
static JSBool
JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
JavaObjectWrapper *java_wrapper;
JavaMemberDescriptor *member_descriptor;
JavaClassDescriptor *class_descriptor;
JNIEnv *jEnv;
java_wrapper = JS_GetPrivate(cx, obj);
/* Check for prototype object */
if (!java_wrapper) {
*statep = JSVAL_NULL;
if (idp)
*idp = INT_TO_JSVAL(0);
return JS_TRUE;
}
class_descriptor = java_wrapper->class_descriptor;
switch(enum_op) {
case JSENUMERATE_INIT:
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
*statep = PRIVATE_TO_JSVAL(member_descriptor);
if (idp)
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
return JS_TRUE;
case JSENUMERATE_NEXT:
member_descriptor = JSVAL_TO_PRIVATE(*statep);
if (member_descriptor) {
*idp = member_descriptor->id;
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
return JS_TRUE;
}
/* Fall through ... */
case JSENUMERATE_DESTROY:
*statep = JSVAL_NULL;
return JS_TRUE;
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
JavaObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
switch (mode) {
case JSACC_WATCH:
JS_ReportError(cx, "Cannot place watchpoints on JavaObject object properties");
return JS_FALSE;
case JSACC_IMPORT:
JS_ReportError(cx, "Cannot export a JavaObject object's properties");
return JS_FALSE;
default:
return JS_TRUE;
}
}
JSObjectOps JavaObject_ops = {
/* Mandatory non-null function pointer members. */
NULL, /* newObjectMap */
NULL, /* destroyObjectMap */
JavaObject_lookupProperty,
JavaObject_defineProperty,
JavaObject_getPropertyById, /* getProperty */
JavaObject_setPropertyById, /* setProperty */
JavaObject_getAttributes,
JavaObject_setAttributes,
JavaObject_deleteProperty,
JavaObject_defaultValue,
JavaObject_newEnumerate,
JavaObject_checkAccess,
/* Optionally non-null members start here. */
NULL, /* thisObject */
NULL, /* dropProperty */
NULL, /* call */
NULL, /* construct */
NULL, /* xdrObject */
NULL, /* hasInstance */
};
static JSObjectOps *
JavaObject_getObjectOps(JSContext *cx, JSClass *clazz)
{
return &JavaObject_ops;
}
JSClass JavaObject_class = {
"JavaObject", JSCLASS_HAS_PRIVATE,
NULL, NULL, NULL, NULL,
NULL, NULL, JavaObject_convert, JavaObject_finalize,
JavaObject_getObjectOps,
};
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
JSBool
jsj_init_JavaObject(JSContext *cx, JSObject *global_obj)
{
JavaObject_ops.newObjectMap = js_ObjectOps.newObjectMap;
JavaObject_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
if (!JS_InitClass(cx, global_obj,
0, &JavaObject_class, 0, 0,
0, 0,
0, 0))
return JS_FALSE;
return init_java_obj_reflections_table();
}

View File

@@ -0,0 +1,500 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the native code implementation of the JavaPackage class.
*
* A JavaPackage is JavaScript's representation of a Java package. The
* JavaPackage object contains only a string, which is the path to the package,
* e.g. "java/lang". The JS properties of a JavaPackage are either nested packages
* or a JavaClass object, which represents the path to a Java class.
*
* Note that there is no equivalent to a JavaPackage object in Java. Example:
* Although there are instances of java.lang.String and there are static methods
* of java.lang.String that can be invoked, there's no such thing as a java.lang
* object in Java that exists at run time.
*
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
#include "jsjava.h"
JSClass JavaPackage_class; /* Forward declaration */
/*
* The native part of a JavaPackage object. It gets stored in the object's
* private slot.
*/
typedef struct {
const char * path; /* e.g. "java/lang" or NULL if top level package */
int flags; /* e.g. PKG_SYSTEM, PKG_CLASS */
} JavaPackage_Private;
static JSObject *
define_JavaPackage(JSContext *cx, JSObject *parent_obj,
const char *obj_name, const char *path, int flags)
{
JSObject *package_obj;
JavaPackage_Private *package;
package_obj = JS_DefineObject(cx, parent_obj, obj_name, &JavaPackage_class, 0,
JSPROP_PERMANENT | JSPROP_READONLY);
if (!package_obj)
return NULL;
/* Attach private, native data to the JS object */
package = (JavaPackage_Private *)JS_malloc(cx, sizeof(JavaPackage_Private));
JS_SetPrivate(cx, package_obj, (void *)package);
if (path)
package->path = JS_strdup(cx, path);
else
package->path = "";
package->flags = flags;
/* Check for OOM */
if (!package->path) {
JS_DeleteProperty(cx, parent_obj, obj_name);
JS_free(cx, package);
return NULL;
}
return package_obj;
}
/* JavaPackage uses standard JS getProperty */
/*
* Don't allow user-defined properties to be set on Java package objects, e.g.
* it is illegal to write "java.lang.myProperty = 4". We probably could relax
* this restriction, but it's potentially confusing and not clearly useful.
*/
static JSBool
JavaPackage_setProperty(JSContext *cx, JSObject *obj, jsval slot, jsval *vp)
{
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
if (!package) {
JS_ReportError(cx, "illegal attempt to add property to "
"JavaPackage prototype object");
return JS_FALSE;
}
JS_ReportError(cx, "You may not add properties to a JavaPackage object");
return JS_FALSE;
}
static JSBool quiet_resolve_failure;
/*
* Resolve a component name to be either the name of a class or a package.
*/
static JSBool
JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
{
JavaPackage_Private *package;
JSBool ok = JS_TRUE;
jclass jclazz;
char *subPath, *newPath;
const char *path;
JNIEnv *jEnv;
package = (JavaPackage_Private *)JS_GetPrivate(cx, obj);
if (!package)
return JS_TRUE;
if (!JSVAL_IS_STRING(id))
return JS_TRUE;
subPath = JS_GetStringBytes(JSVAL_TO_STRING(id));
/*
* There will be an attempt to invoke the toString() method when producing
* the string representation of a JavaPackage. When this occurs, avoid
* creating a bogus toString package. (This means that no one can ever
* create a package with the simple name "toString", but we'll live with
* that limitation.)
*/
if (!strcmp(subPath, "toString"))
return JS_FALSE;
path = package->path;
newPath = PR_smprintf("%s%s%s", path, (path[0] ? "/" : ""), subPath);
if (!newPath) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
/*
Unfortunately, Java provides no way to find out whether a particular
name is a package or not. The only way to tell is to try to load the
name as a class file and, if that fails, assume it's a package. This
makes things work as expected for the most part, but it has three
noticeable problems that keep coming up:
- You can refer to a package like java.lang.i.buried.paul without
generating a complaint. Of course, you'll never be able to refer to
any classes through it.
- An annoying consequence of the above is that misspelling a class name
results in a cryptic error about packages.
- In a browser context, i.e. where applets are involved, figuring out
whether something is a class may require looking for it over the net
using the current classloader. This means that the first time you
refer to java.lang.System in a js context, there will be an attempt
to search for [[DOCBASE]]/java.class on the server.
A solution is to explicitly tell jsjava the names of all the (local)
packages on the CLASSPATH. (Not implemented yet.)
*/
jclazz = (*jEnv)->FindClass(jEnv, newPath);
if (jclazz) {
JSObject *newClass;
newClass = jsj_define_JavaClass(cx, jEnv, obj, subPath, jclazz);
if (!newClass) {
ok = JS_FALSE;
goto out;
}
} else {
/* We assume that any failed attempt to load a class is because it
doesn't exist. If we wanted to do a better job, we would check
the exception type and make sure that it's NoClassDefFoundError */
(*jEnv)->ExceptionClear(jEnv);
/* beard: this has to be done here, so built-in classes will be defined. */
/* Painful hack for pre_define_java_packages() */
if (quiet_resolve_failure) {
ok = JS_FALSE;
goto out;
}
/*
* If there's no class of the given name, then we must be referring to
* a package. However, don't allow bogus sub-packages of pre-defined
* system packages to be created.
*/
if (JS_InstanceOf(cx, obj, &JavaPackage_class, NULL)) {
JavaPackage_Private *package;
package = JS_GetPrivate(cx, obj);
if (package->flags & PKG_SYSTEM) {
char *msg, *cp;
msg = PR_smprintf("No Java system package with name \"%s\" was identified "
"and no Java class with that name exists either",
newPath);
/* Check for OOM */
if (msg) {
/* Convert package of form "java/lang" to "java.lang" */
for (cp = msg; *cp != '\0'; cp++)
if (*cp == '/')
*cp = '.';
JS_ReportError(cx, msg);
free((char*)msg);
}
ok = JS_FALSE;
goto out;
}
}
if (!define_JavaPackage(cx, obj, subPath, newPath, 0)) {
ok = JS_FALSE;
goto out;
}
#ifdef DEBUG
/* printf("JavaPackage \'%s\' created\n", newPath); */
#endif
}
out:
free(newPath);
return ok;
}
static JSBool
JavaPackage_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
JSString *str;
char *name, *cp;
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
if (!package) {
fprintf(stderr, "JavaPackage_resolve: no private data!\n");
return JS_FALSE;
}
switch (type) {
/* Pretty-printing of JavaPackage */
case JSTYPE_VOID: /* Default value */
case JSTYPE_NUMBER:
case JSTYPE_STRING:
/* Convert '/' to '.' so that it looks like Java language syntax. */
if (!package->path)
break;
name = PR_smprintf("[JavaPackage %s]", package->path);
if (!name) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
for (cp = name; *cp != '\0'; cp++)
if (*cp == '/')
*cp = '.';
str = JS_NewString(cx, name, strlen(name));
if (!str) {
free(name);
/* It's not necessary to call JS_ReportOutOfMemory(), as
JS_NewString() will do so on failure. */
return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str);
break;
case JSTYPE_OBJECT:
*vp = OBJECT_TO_JSVAL(obj);
break;
default:
break;
}
return JS_TRUE;
}
/*
* Free the private native data associated with the JavaPackage object.
*/
static void
JavaPackage_finalize(JSContext *cx, JSObject *obj)
{
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
if (!package)
return;
if (package->path)
JS_free(cx, (char *)package->path);
JS_free(cx, package);
}
/*
* The definition of the JavaPackage class
*/
JSClass JavaPackage_class = {
"JavaPackage", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JavaPackage_setProperty,
JS_EnumerateStub, JavaPackage_resolve,
JavaPackage_convert, JavaPackage_finalize
};
JavaPackageDef
standard_java_packages[] = {
{"java", NULL, PKG_USER},
{"java.applet", NULL, PKG_USER},
{"java.awt", NULL, PKG_USER},
{"java.awt.datatransfer",
NULL, PKG_SYSTEM},
{"java.awt.event", NULL, PKG_SYSTEM},
{"java.awt.image", NULL, PKG_SYSTEM},
{"java.awt.peer", NULL, PKG_SYSTEM},
{"java.beans", NULL, PKG_USER},
{"java.io", NULL, PKG_SYSTEM},
{"java.lang", NULL, PKG_USER},
{"java.lang.reflect", NULL, PKG_SYSTEM},
{"java.math", NULL, PKG_SYSTEM},
{"java.net", NULL, PKG_USER},
{"java.rmi", NULL, PKG_USER},
{"java.rmi.dgc", NULL, PKG_USER},
{"java.rmi.user", NULL, PKG_USER},
{"java.rmi.registry", NULL, PKG_USER},
{"java.rmi.server", NULL, PKG_USER},
{"java.security", NULL, PKG_USER},
{"java.security.acl", NULL, PKG_SYSTEM},
{"java.security.interfaces",
NULL, PKG_SYSTEM},
{"java.sql", NULL, PKG_USER},
{"java.text", NULL, PKG_USER},
{"java.text.resources", NULL, PKG_SYSTEM},
{"java.util", NULL, PKG_USER},
{"java.util.zip", NULL, PKG_SYSTEM},
{"netscape", NULL, PKG_USER},
{"netscape.applet", NULL, PKG_SYSTEM},
{"netscape.application",NULL, PKG_SYSTEM},
{"netscape.debug", NULL, PKG_SYSTEM},
{"netscape.javascript", NULL, PKG_SYSTEM},
{"netscape.ldap", NULL, PKG_SYSTEM},
{"netscape.misc", NULL, PKG_SYSTEM},
{"netscape.net", NULL, PKG_SYSTEM},
{"netscape.plugin", NULL, PKG_SYSTEM},
{"netscape.util", NULL, PKG_SYSTEM},
{"netscape.secfile", NULL, PKG_SYSTEM},
{"netscape.security", NULL, PKG_SYSTEM},
{"netscape.WAI", NULL, PKG_SYSTEM},
{"sun", NULL, PKG_USER},
{"Packages", "", PKG_USER},
{NULL, NULL, 0}
};
/*
* Pre-define a hierarchy of JavaPackage objects.
* Pre-defining a Java package at initialization time is not necessary, but
* it will make package lookup faster and, more importantly, will avoid
* unnecessary network accesses if classes are being loaded over the network.
*/
static JSBool
pre_define_java_packages(JSContext *cx, JSObject *global_obj,
JavaPackageDef *predefined_packages)
{
JSBool package_exists;
JSObject *parent_obj;
JavaPackageDef *package_def;
char *simple_name, *cp, *package_name, *path;
int flags;
if (!predefined_packages)
return JS_TRUE;
/* Iterate over all pre-defined Java packages */
for (package_def = predefined_packages; package_def->name; package_def++) {
package_name = path = NULL;
parent_obj = global_obj;
package_name = strdup(package_def->name);
if (!package_name)
goto out_of_memory;
/* Walk the chain of JavaPackage objects to get to the parent of the
rightmost sub-package in the fully-qualified package name. */
for (simple_name = strtok(package_name, "."); 1; simple_name = strtok(NULL, ".")) {
jsval v;
if (!simple_name) {
JS_ReportError(cx, "Package %s defined twice ?", package_name);
goto error;
}
/* Check to see if the sub-package already exists */
quiet_resolve_failure = JS_TRUE;
package_exists = JS_LookupProperty(cx, parent_obj, simple_name, &v) && JSVAL_IS_OBJECT(v);
quiet_resolve_failure = JS_FALSE;
if (package_exists) {
parent_obj = JSVAL_TO_OBJECT(v);
continue;
} else {
/* New package objects should only be created at the terminal
sub-package in a fully-qualified package-name */
if (strtok(NULL, ".")) {
JS_ReportError(cx, "Illegal predefined package definition for %s",
package_def->name);
goto error;
}
if (package_def->path) {
path = strdup(package_def->path);
if (!path)
goto out_of_memory;
} else {
/*
* The default path is specified, so create it from the
* fully-qualified package name.
*/
path = strdup(package_def->name);
if (!path)
goto out_of_memory;
/* Transform package name, e.g. "java.lang" ==> "java/lang" */
for (cp = path; *cp != '\0'; cp++) {
if (*cp == '.')
*cp = '/';
}
}
flags = package_def->flags;
parent_obj = define_JavaPackage(cx, parent_obj, simple_name, path, flags);
if (!parent_obj)
goto error;
free(path);
break;
}
}
free(package_name);
}
return JS_TRUE;
out_of_memory:
JS_ReportOutOfMemory(cx);
error:
JS_FREE_IF(cx, package_name);
JS_FREE_IF(cx, path);
return JS_FALSE;
}
static JSBool
JavaPackage_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
if (!JS_InstanceOf(cx, obj, &JavaPackage_class, argv))
return JS_FALSE;
return JavaPackage_convert(cx, obj, JSTYPE_STRING, rval);
}
static JSFunctionSpec JavaPackage_methods[] = {
{"toString", JavaPackage_toString, 0},
{0}
};
/*
* One-time initialization for the JavaPackage class. (This is not
* run once per thread, rather it's run once for a given JSContext.)
*/
JSBool
jsj_init_JavaPackage(JSContext *cx, JSObject *global_obj,
JavaPackageDef *additional_predefined_packages) {
/* Define JavaPackage class */
if (!JS_InitClass(cx, global_obj, 0, &JavaPackage_class,
0, 0, 0, JavaPackage_methods, 0, 0))
return JS_FALSE;
/* Add top-level packages, e.g. : java, netscape, sun */
if (!pre_define_java_packages(cx, global_obj, standard_java_packages))
return JS_FALSE;
if (!pre_define_java_packages(cx, global_obj, additional_predefined_packages))
return JS_FALSE;
return JS_TRUE;
}

View File

@@ -0,0 +1,180 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the code for reading and writing elements of a Java array.
*/
#include "jsj_private.h" /* LiveConnect internals */
/*
* Read the Java value at a given index into a Java array and convert it
* to a JS value. The array_component_signature describes the type of
* the resulting Java value, which can be a primitive type or an object type.
* More specifically it can be an array type in the case of multidimensional
* arrays.
*/
JSBool
jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index,
JavaSignature *array_component_signature,
jsval *vp)
{
jvalue java_value;
JavaSignatureChar component_type;
#define GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \
(*jEnv)->Get##Type##ArrayRegion(jEnv, java_array, index, 1, \
&java_value.member); \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_ReportJavaError(cx, jEnv, "Error reading element of " \
"Java primitive array"); \
return JS_FALSE; \
}
component_type = array_component_signature->type;
switch(component_type) {
case JAVA_SIGNATURE_BYTE:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s);
break;
case JAVA_SIGNATURE_INT:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
java_value.l = (*jEnv)->GetObjectArrayElement(jEnv, java_array, index);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_ReportJavaError(cx, jEnv, "Error reading Java object array");
return JS_FALSE;
}
break;
#undef GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return jsj_ConvertJavaValueToJSValue(cx, jEnv, array_component_signature, &java_value, vp);
}
JSBool
jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index,
JavaSignature *array_component_signature,
jsval js_val)
{
int dummy_cost;
jvalue java_value;
JavaSignatureChar component_type;
JSBool is_local_ref;
if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, array_component_signature,
&dummy_cost, &java_value, &is_local_ref))
return JS_FALSE;
#define SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \
(*jEnv)->Set##Type##ArrayRegion(jEnv, java_array, index, 1, \
&java_value.member); \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_ReportJavaError(cx, jEnv, "Error assigning to element of " \
"Java primitive array"); \
return JS_FALSE; \
}
component_type = array_component_signature->type;
switch(component_type) {
case JAVA_SIGNATURE_BYTE:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s);
break;
case JAVA_SIGNATURE_INT:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
(*jEnv)->SetObjectArrayElement(jEnv, java_array, index, java_value.l);
if (is_local_ref) \
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_ReportJavaError(cx, jEnv, "Error assigning to Java object array");
return JS_FALSE;
}
break;
#undef SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return JS_TRUE;
}

View File

@@ -0,0 +1,605 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the code that constructs and manipulates JavaClassDescriptor
* structs, which are the native wrappers for Java classes.
* JavaClassDescriptors are used to describe the signatures of methods and
* fields. There is a JavaClassDescriptor associated with the reflection of
* each Java Object.
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
#include "jsj_hash.h" /* Hash tables */
/* A one-to-one mapping between all referenced java.lang.Class objects and
their corresponding JavaClassDescriptor objects */
static JSJHashTable *java_class_reflections;
/*
* Given a JVM handle to a java.lang.Class object, malloc a C-string
* containing the UTF8 encoding of the fully qualified name of the class.
* It's the caller's responsibility to free the returned string.
*
* If an error occurs, NULL is returned and the error reporter called.
*/
const char *
jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
jstring java_class_name_jstr;
const char *java_class_name;
/* Get java.lang.String object containing class name */
java_class_name_jstr =
(*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getName);
if (!java_class_name_jstr)
goto error;
/* Convert to UTF8 encoding and copy */
java_class_name = jsj_DupJavaStringUTF(cx, jEnv, java_class_name_jstr);
if (!java_class_name)
return NULL;
return java_class_name;
error:
jsj_UnexpectedJavaError(cx, jEnv, "Can't get Java class name using"
"java.lang.Class.getName()");
return NULL;
}
/*
* Convert in-place a string of the form "java.lang.String" into "java/lang/String".
* Though the former style is conventionally used by Java programmers, the latter is
* what the JNI functions require.
*/
void
jsj_MakeJNIClassname(char * class_name)
{
char * c;
for (c = class_name; *c; c++)
if (*c == '.')
*c = '/';
}
/*
* Classify an instance of java.lang.Class as either one of the primitive
* types, e.g. int, char, etc., as an array type or as a non-array object type
* (subclass of java.lang.Object) by returning the appropriate enum member.
*
*/
static JavaSignatureChar
get_signature_type(JSContext *cx, JavaClassDescriptor *class_descriptor)
{
JavaSignatureChar type;
const char *java_class_name;
/* Get UTF8 encoding of class name */
java_class_name = class_descriptor->name;
PR_ASSERT(java_class_name);
if (!java_class_name)
return JAVA_SIGNATURE_UNKNOWN;
if (!strcmp(java_class_name, "byte"))
type = JAVA_SIGNATURE_BYTE;
else if (!strcmp(java_class_name, "char"))
type = JAVA_SIGNATURE_CHAR;
else if (!strcmp(java_class_name, "float"))
type = JAVA_SIGNATURE_FLOAT;
else if (!strcmp(java_class_name, "double"))
type = JAVA_SIGNATURE_DOUBLE;
else if (!strcmp(java_class_name, "int"))
type = JAVA_SIGNATURE_INT;
else if (!strcmp(java_class_name, "long"))
type = JAVA_SIGNATURE_LONG;
else if (!strcmp(java_class_name, "short"))
type = JAVA_SIGNATURE_SHORT;
else if (!strcmp(java_class_name, "boolean"))
type = JAVA_SIGNATURE_BOOLEAN;
else if (!strcmp(java_class_name, "void"))
type = JAVA_SIGNATURE_VOID;
else
/* Well, I guess it's a Java class, then. */
type = JAVA_SIGNATURE_CLASS;
return type;
}
static JSBool
is_java_array_class(JNIEnv *jEnv, jclass java_class)
{
return (*jEnv)->CallBooleanMethod(jEnv, java_class, jlClass_isArray);
}
/*
* Return the class of a Java array's component type. This is not the same
* as the array's element type. For example, the component type of an array
* of type SomeType[][][] is SomeType[][], but its element type is SomeType.
*
* If an error occurs, NULL is returned and an error reported.
*/
static jclass
get_java_array_component_class(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
jclass result;
result = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getComponentType);
if (!result) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't get Java array component class using "
"java.lang.Class.getComponentType()");
return NULL;
}
return result;
}
/*
* Given a Java class, fill in the signature structure that describes the class.
* If an error occurs, JS_FALSE is returned and the error reporter called.
*/
static JSBool
compute_java_class_signature(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature)
{
jclass java_class = signature->java_class;
if (is_java_array_class(jEnv, java_class)) {
jclass component_class;
signature->type = JAVA_SIGNATURE_ARRAY;
component_class = get_java_array_component_class(cx, jEnv, java_class);
if (!component_class)
return JS_FALSE;
signature->array_component_signature =
jsj_GetJavaClassDescriptor(cx, jEnv, component_class);
if (!signature->array_component_signature)
return JS_FALSE;
} else {
signature->type = get_signature_type(cx, signature);
}
return JS_TRUE;
}
/*
* Convert a JavaSignature object into a string format as used by
* the JNI functions, e.g. java.lang.Object ==> "Ljava/lang/Object;"
* The caller is responsible for freeing the resulting string.
*
* If an error is encountered, NULL is returned and an error reported.
*/
const char *
jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature)
{
char *sig;
if (signature->type == JAVA_SIGNATURE_CLASS) {
/* A non-array object class */
sig = PR_smprintf("L%s;", signature->name);
if (sig)
jsj_MakeJNIClassname(sig);
} else if (signature->type == JAVA_SIGNATURE_ARRAY) {
/* An array class */
const char *component_signature_string;
component_signature_string =
jsj_ConvertJavaSignatureToString(cx, signature->array_component_signature);
if (!component_signature_string)
return NULL;
sig = PR_smprintf("[%s", component_signature_string);
JS_free(cx, (char*)component_signature_string);
} else {
/* A primitive class */
sig = PR_smprintf("%c", (char)signature->type);
}
if (!sig) {
JS_ReportOutOfMemory(cx);
return NULL;
}
return sig;
}
/*
* Convert a JavaSignature object into a human-readable string format as seen
* in Java source files, e.g. "byte", or "int[][]" or "java.lang.String".
* The caller is responsible for freeing the resulting string.
*
* If an error is encountered, NULL is returned and an error reported.
*/
const char *
jsj_ConvertJavaSignatureToHRString(JSContext *cx,
JavaSignature *signature)
{
char *sig;
JavaSignature *acs;
if (signature->type == JAVA_SIGNATURE_ARRAY) {
/* An array class */
const char *component_signature_string;
acs = signature->array_component_signature;
component_signature_string =
jsj_ConvertJavaSignatureToHRString(cx, acs);
if (!component_signature_string)
return NULL;
sig = PR_smprintf("%s[]", component_signature_string);
JS_free(cx, (char*)component_signature_string);
} else {
/* A primitive class or a non-array object class */
sig = JS_strdup(cx, signature->name);
}
if (!sig) {
JS_ReportOutOfMemory(cx);
return NULL;
}
return sig;
}
static void
destroy_java_member_descriptor(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor)
{
JavaMethodSpec *method, *next_method;
if (member_descriptor->field)
jsj_DestroyFieldSpec(cx, jEnv, member_descriptor->field);
method = member_descriptor->methods;
while (method) {
next_method = method->next;
jsj_DestroyMethodSpec(cx, jEnv, method);
method = next_method;
}
if (member_descriptor->invoke_func_obj)
JS_RemoveRoot(cx, &member_descriptor->invoke_func_obj);
}
static void
destroy_class_member_descriptors(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor)
{
JavaMemberDescriptor *next_member;
while (member_descriptor) {
next_member = member_descriptor->next;
destroy_java_member_descriptor(cx, jEnv, member_descriptor);
member_descriptor = next_member;
}
}
static void
destroy_class_descriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
{
JS_FREE_IF(cx, (char *)class_descriptor->name);
if (class_descriptor->java_class) {
JSJ_HashTableRemove(java_class_reflections,
class_descriptor->java_class, (void*)jEnv);
(*jEnv)->DeleteGlobalRef(jEnv, class_descriptor->java_class);
}
if (class_descriptor->array_component_signature)
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor->array_component_signature);
destroy_class_member_descriptors(cx, jEnv, class_descriptor->instance_members);
destroy_class_member_descriptors(cx, jEnv, class_descriptor->static_members);
destroy_class_member_descriptors(cx, jEnv, class_descriptor->constructors);
JS_free(cx, class_descriptor);
}
static JavaClassDescriptor *
new_class_descriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
JavaClassDescriptor *class_descriptor;
class_descriptor = (JavaClassDescriptor *)JS_malloc(cx, sizeof(JavaClassDescriptor));
if (!class_descriptor)
return NULL;
memset(class_descriptor, 0, sizeof(JavaClassDescriptor));
class_descriptor->name = jsj_GetJavaClassName(cx, jEnv, java_class);
if (!class_descriptor->name)
goto error;
java_class = (*jEnv)->NewGlobalRef(jEnv, java_class);
if (!java_class) {
jsj_UnexpectedJavaError(cx, jEnv, "Unable to reference Java class");
goto error;
}
class_descriptor->java_class = java_class;
if (!compute_java_class_signature(cx, jEnv, class_descriptor))
goto error;
class_descriptor->modifiers =
(*jEnv)->CallIntMethod(jEnv, java_class, jlClass_getModifiers);
class_descriptor->ref_count = 1;
if (!JSJ_HashTableAdd(java_class_reflections, java_class, class_descriptor,
(void*)jEnv))
goto error;
return class_descriptor;
error:
destroy_class_descriptor(cx, jEnv, class_descriptor);
return NULL;
}
/* Trivial helper for jsj_DiscardJavaClassReflections(), below */
static PRIntn
enumerate_remove_java_class(JSJHashEntry *he, PRIntn i, void *arg)
{
JNIEnv *jEnv = (JNIEnv*)arg;
jclass java_class;
JavaClassDescriptor *class_descriptor;
class_descriptor = (JavaClassDescriptor*)he->value;
java_class = class_descriptor->java_class;
(*jEnv)->DeleteGlobalRef(jEnv, java_class);
class_descriptor->java_class = NULL;
return HT_ENUMERATE_REMOVE;
}
/* This shutdown routine discards all JNI references to Java objects
that have been reflected into JS, even if there are still references
to them from JS. */
void
jsj_DiscardJavaClassReflections(JNIEnv *jEnv)
{
if (java_class_reflections) {
JSJ_HashTableEnumerateEntries(java_class_reflections,
enumerate_remove_java_class,
(void*)jEnv);
JSJ_HashTableDestroy(java_class_reflections);
java_class_reflections = NULL;
}
}
extern JavaClassDescriptor *
jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
JavaClassDescriptor *class_descriptor;
class_descriptor = JSJ_HashTableLookup(java_class_reflections,
(const void *)java_class,
(void*)jEnv);
if (!class_descriptor)
return new_class_descriptor(cx, jEnv, java_class);
PR_ASSERT(class_descriptor->ref_count > 0);
class_descriptor->ref_count++;
return class_descriptor;
}
void
jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
{
if (!--class_descriptor->ref_count)
destroy_class_descriptor(cx, jEnv, class_descriptor);
}
static JSBool
reflect_java_methods_and_fields(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
JSBool reflect_statics_only)
{
JavaMemberDescriptor *member_descriptor;
if (reflect_statics_only)
class_descriptor->static_members_reflected = JS_TRUE;
else
class_descriptor->instance_members_reflected = JS_TRUE;
if (!jsj_ReflectJavaMethods(cx, jEnv, class_descriptor, reflect_statics_only))
return JS_FALSE;
if (!jsj_ReflectJavaFields(cx, jEnv, class_descriptor, reflect_statics_only))
return JS_FALSE;
if (reflect_statics_only) {
member_descriptor = class_descriptor->static_members;
while (member_descriptor) {
class_descriptor->num_static_members++;
member_descriptor = member_descriptor->next;
}
} else {
member_descriptor = class_descriptor->instance_members;
while (member_descriptor) {
class_descriptor->num_instance_members++;
member_descriptor = member_descriptor->next;
}
}
return JS_TRUE;
}
JavaMemberDescriptor *
jsj_GetClassStaticMembers(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor)
{
if (!class_descriptor->static_members_reflected)
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
return class_descriptor->static_members;
}
JavaMemberDescriptor *
jsj_GetClassInstanceMembers(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor)
{
if (!class_descriptor->instance_members_reflected)
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_FALSE);
return class_descriptor->instance_members;
}
JavaMemberDescriptor *
jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id)
{
JavaMemberDescriptor *member_descriptor;
member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor);
while (member_descriptor) {
if (id == member_descriptor->id)
return member_descriptor;
member_descriptor = member_descriptor->next;
}
return NULL;
}
JavaMemberDescriptor *
jsj_GetJavaStaticMemberDescriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name_jstr)
{
JavaMemberDescriptor *member_descriptor;
jsid id;
if (!JavaStringToId(cx, jEnv, member_name_jstr, &id))
return NULL;
member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (member_descriptor)
return member_descriptor;
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
if (!member_descriptor)
return NULL;
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr);
if (!member_descriptor->name) {
JS_free(cx, member_descriptor);
return NULL;
}
member_descriptor->id = id;
member_descriptor->next = class_descriptor->static_members;
class_descriptor->static_members = member_descriptor;
return member_descriptor;
}
JavaMemberDescriptor *
jsj_GetJavaClassConstructors(JSContext *cx,
JavaClassDescriptor *class_descriptor)
{
JavaMemberDescriptor *member_descriptor;
if (class_descriptor->constructors)
return class_descriptor->constructors;
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
if (!member_descriptor)
return NULL;
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
member_descriptor->name = JS_strdup(cx, "<init>");
if (!member_descriptor->name) {
JS_free(cx, member_descriptor);
return NULL;
}
class_descriptor->constructors = member_descriptor;
return member_descriptor;
}
JavaMemberDescriptor *
jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor)
{
if (!class_descriptor->static_members_reflected)
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
return class_descriptor->constructors;
}
JavaMemberDescriptor *
jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id)
{
JavaMemberDescriptor *member_descriptor;
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
while (member_descriptor) {
if (id == member_descriptor->id)
return member_descriptor;
member_descriptor = member_descriptor->next;
}
return NULL;
}
JavaMemberDescriptor *
jsj_GetJavaMemberDescriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name_jstr)
{
JavaMemberDescriptor *member_descriptor;
jsid id;
if (!JavaStringToId(cx, jEnv, member_name_jstr, &id))
return NULL;
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (member_descriptor)
return member_descriptor;
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
if (!member_descriptor)
return NULL;
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr);
if (!member_descriptor->name) {
JS_free(cx, member_descriptor);
return NULL;
}
member_descriptor->id = id;
member_descriptor->next = class_descriptor->instance_members;
class_descriptor->instance_members = member_descriptor;
return member_descriptor;
}
JSBool
jsj_InitJavaClassReflectionsTable()
{
java_class_reflections =
JSJ_NewHashTable(64, jsj_HashJavaObject, jsj_JavaObjectComparator,
NULL, NULL, NULL);
if (!java_class_reflections)
return JS_FALSE;
return JS_TRUE;
}

View File

@@ -0,0 +1,806 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* Below is the code that converts between Java and JavaScript values of all
* types.
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
/* Floating-point double utilities, stolen from jsnum.h */
#ifdef IS_LITTLE_ENDIAN
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1])
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0])
#else
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0])
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1])
#endif
#define JSDOUBLE_HI32_SIGNBIT 0x80000000
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
#define JSDOUBLE_HI32_MANTMASK 0x000fffff
#define JSDOUBLE_IS_NaN(x) \
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \
(JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
#define JSDOUBLE_IS_INFINITE(x) \
((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \
!JSDOUBLE_LO32(x))
static JSBool
convert_js_obj_to_JSObject_wrapper(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj,
JavaSignature *signature,
int *cost, jobject *java_value)
{
if (!njJSObject) {
if (java_value)
JS_ReportError(cx, "Couldn't convert JavaScript object to an "
"instance of netscape.javascript.JSObject "
"because that class could not be loaded.");
return JS_FALSE;
}
if (!(*jEnv)->IsAssignableFrom(jEnv, njJSObject, signature->java_class))
return JS_FALSE;
if (!java_value)
return JS_TRUE;
*java_value = jsj_WrapJSObject(cx, jEnv, js_obj);
return (*java_value != NULL);
}
jstring
jsj_ConvertJSStringToJavaString(JSContext *cx, JNIEnv *jEnv, JSString *js_str)
{
jstring result;
result = (*jEnv)->NewString(jEnv, JS_GetStringChars(js_str),
JS_GetStringLength(js_str));
if (!result) {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't construct instance "
"of java.lang.String");
}
return result;
}
/*
* Convert a JS value to an instance of java.lang.Object or one of its subclasses,
* performing any necessary type coercion. If non-trivial coercion is required,
* the cost value is incremented. If the java_value pass-by-reference argument
* is non-NULL, the resulting Java value is stored there.
*
* Returns JS_TRUE if the conversion is possible, JS_FALSE otherwise
*/
JSBool
jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
int *cost, jobject *java_value, JSBool *is_local_refp)
{
JSString *jsstr;
jclass target_java_class;
PR_ASSERT(signature->type == JAVA_SIGNATURE_CLASS ||
signature->type == JAVA_SIGNATURE_ARRAY);
/* Initialize to default case, in which no new Java object is
synthesized to perform the conversion and, therefore, no JNI local
references are being held. */
*is_local_refp = JS_FALSE;
/* Get the Java type of the target value */
target_java_class = signature->java_class;
if (JSVAL_IS_OBJECT(v)) {
JSObject *js_obj = JSVAL_TO_OBJECT(v);
/* JS null is always assignable to a Java object */
if (!js_obj) {
if (java_value)
*java_value = NULL;
return JS_TRUE;
}
if (JS_InstanceOf(cx, js_obj, &JavaObject_class, 0) ||
JS_InstanceOf(cx, js_obj, &JavaArray_class, 0)) {
/* The source value is a Java object wrapped inside a JavaScript
object. Unwrap the JS object and return the original Java
object if it's class makes it assignment-compatible with the
target class using Java's assignability rules. */
JavaObjectWrapper *java_wrapper = JS_GetPrivate(cx, js_obj);
jobject java_obj = java_wrapper->java_obj;
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, target_java_class)) {
if (java_value)
*java_value = java_obj;
return JS_TRUE;
}
#ifdef LIVECONNECT_IMPROVEMENTS
/* Don't allow wrapped Java objects to be converted to strings */
goto conversion_error;
#else
/* Fall through, to attempt conversion to a Java string */
#endif
} else if (JS_InstanceOf(cx, js_obj, &JavaClass_class, 0)) {
/* We're dealing with the reflection of a Java class */
JavaClassDescriptor *java_class_descriptor = JS_GetPrivate(cx, js_obj);
/* Check if target type is java.lang.Class class */
if ((*jEnv)->IsAssignableFrom(jEnv, jlClass, target_java_class)) {
if (java_value)
*java_value = java_class_descriptor->java_class;
return JS_TRUE;
}
/* Check if target type is netscape.javascript.JSObject wrapper class */
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) {
if (*java_value)
*is_local_refp = JS_TRUE;
return JS_TRUE;
}
/* Fall through, to attempt conversion to a Java string */
} else if (JS_InstanceOf(cx, js_obj, &JavaMember_class, 0)) {
if (!JS_ConvertValue(cx, v, JSTYPE_OBJECT, &v))
return JS_FALSE;
return jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
java_value, is_local_refp);
} else {
/* Otherwise, see if the target type is the netscape.javascript.JSObject
wrapper class or one of its subclasses, in which case a
reference is passed to the original JS object by wrapping it
inside an instance of netscape.javascript.JSObject */
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) {
return JS_TRUE;
}
/* Fall through, to attempt conversion to a Java string */
}
} else if (JSVAL_IS_NUMBER(v)) {
/* JS numbers, integral or not, can be converted to instances of java.lang.Double */
if ((*jEnv)->IsAssignableFrom(jEnv, jlDouble, target_java_class)) {
if (java_value) {
jsdouble d;
if (!JS_ValueToNumber(cx, v, &d))
goto conversion_error;
*java_value = (*jEnv)->NewObject(jEnv, jlDouble, jlDouble_Double, d);
if (*java_value) {
*is_local_refp = JS_TRUE;
} else {
jsj_UnexpectedJavaError(cx, jEnv,
"Couldn't construct instance of java.lang.Double");
return JS_FALSE;
}
}
#ifdef LIVECONNECT_IMPROVEMENTS
(*cost)++;
#endif
return JS_TRUE;
}
/* Fall through, to attempt conversion to a java.lang.String ... */
} else if (JSVAL_IS_BOOLEAN(v)) {
/* JS boolean values can be converted to instances of java.lang.Boolean */
if ((*jEnv)->IsAssignableFrom(jEnv, jlBoolean, target_java_class)) {
if (java_value) {
JSBool b;
if (!JS_ValueToBoolean(cx, v, &b))
goto conversion_error;
*java_value =
(*jEnv)->NewObject(jEnv, jlBoolean, jlBoolean_Boolean, b);
if (*java_value) {
*is_local_refp = JS_TRUE;
} else {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't construct instance "
"of java.lang.Boolean");
return JS_FALSE;
}
}
#ifdef LIVECONNECT_IMPROVEMENTS
(*cost)++;
#endif
return JS_TRUE;
}
/* Fall through, to attempt conversion to a java.lang.String ... */
}
/* If no other conversion is possible, see if the target type is java.lang.String */
if ((*jEnv)->IsAssignableFrom(jEnv, jlString, target_java_class)) {
#ifdef LIVECONNECT_IMPROVEMENTS
JSBool is_string = JSVAL_IS_STRING(v);
#endif
/* Convert to JS string, if necessary, and then to a Java Unicode string */
jsstr = JS_ValueToString(cx, v);
if (jsstr) {
if (java_value) {
*java_value = jsj_ConvertJSStringToJavaString(cx, jEnv, jsstr);
if (*java_value) {
*is_local_refp = JS_TRUE;
} else {
return JS_FALSE;
}
}
#ifdef LIVECONNECT_IMPROVEMENTS
if (!is_string)
(*cost)++;
#endif
return JS_TRUE;
}
}
conversion_error:
return JS_FALSE;
}
/* Valid ranges for Java numeric types */
#define jbyte_MAX_VALUE 127.0
#define jbyte_MIN_VALUE -128.0
#define jchar_MAX_VALUE 65535.0
#define jchar_MIN_VALUE 0.0
#define jshort_MAX_VALUE 32767.0
#define jshort_MIN_VALUE -32768.0
#define jint_MAX_VALUE 2147483647.0
#define jint_MIN_VALUE -2147483648.0
#define jlong_MAX_VALUE 9223372036854775807.0
#define jlong_MIN_VALUE -9223372036854775808.0
/* Utility macro for jsj_ConvertJSValueToJavaValue(), below */
#define JSVAL_TO_INTEGRAL_JVALUE(type_name, member_name, member_type, jsval, java_value) \
if (!JSVAL_IS_NUMBER(v)) { \
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v)) \
goto conversion_error; \
(*cost)++; \
} \
{ \
member_type member_name; \
\
if (JSVAL_IS_INT(v)) { \
jsint ival = JSVAL_TO_INT(v); \
member_name = (member_type) ival; \
\
/* Check to see if the jsval's magnitude is too large to be \
representable in the target java type */ \
if (member_name != ival) \
goto numeric_conversion_error; \
} else { \
jdouble dval = *JSVAL_TO_DOUBLE(v); \
\
/* NaN becomes zero when converted to integral value */ \
if (JSDOUBLE_IS_NaN(dval)) \
member_name = 0; \
\
/* Unrepresentably large numbers, including infinities, */ \
/* cause an error. */ \
else if ((dval > member_type ## _MAX_VALUE) || \
(dval < member_type ## _MIN_VALUE)) { \
goto numeric_conversion_error; \
} else \
member_name = (member_type) dval; \
\
/* Don't allow a non-integral number to be converted \
to an integral type */ \
/* Actually, we have to allow this for LC1 compatibility */ \
/* if ((jdouble)member_name != dval) \
(*cost)++; */ \
} \
if (java_value) \
java_value->member_name = member_name; \
}
#if XP_MAC
/* on MRJ jlong is typedef'd to wide, which is a struct. */
#include <Math64.h>
static jsint jlong_to_jsint(jlong lvalue)
{
SInt64 val = WideToSInt64(lvalue);
return S32Set(val);
}
static jlong jsint_to_jlong(jsint ivalue)
{
SInt64 val = S64Set(ivalue);
wide wval =SInt64ToWide(val);
return *(jlong*)&wval;
}
static jdouble jlong_to_jdouble(jlong lvalue)
{
SInt64 val = WideToSInt64(lvalue);
return SInt64ToLongDouble(val);
}
static jlong jdouble_to_jlong(jdouble dvalue)
{
SInt64 val = LongDoubleToSInt64(dvalue);
wide wval = SInt64ToWide(val);
return *(jlong*)&wval;
}
/* Mac utility macro for jsj_ConvertJSValueToJavaValue(), below */
#define JSVAL_TO_JLONG_JVALUE(member_name, member_type, jsvalue, java_value) \
if (!JSVAL_IS_NUMBER(jsvalue)) { \
if (!JS_ConvertValue(cx, jsvalue, JSTYPE_NUMBER, &jsvalue)) \
goto conversion_error; \
(*cost)++; \
} \
{ \
member_type member_name; \
\
if (JSVAL_IS_INT(jsvalue)) { \
jsint ival = JSVAL_TO_INT(jsvalue); \
member_name = jsint_to_jlong(ival); \
\
} else { \
jdouble dval = *JSVAL_TO_DOUBLE(jsvalue); \
\
/* NaN becomes zero when converted to integral value */ \
if (JSDOUBLE_IS_NaN(dval)) \
member_name = jsint_to_jlong(0); \
\
/* Unrepresentably large numbers, including infinities, */ \
/* cause an error. */ \
else if ((dval > member_type ## _MAX_VALUE) || \
(dval < member_type ## _MIN_VALUE)) { \
goto numeric_conversion_error; \
} else \
member_name = jdouble_to_jlong(dval); \
\
/* Don't allow a non-integral number to be converted \
to an integral type */ \
/* Actually, we have to allow this for LC1 compatibility */ \
/*if (jlong_to_jdouble(member_name) != dval) \
(*cost)++;*/ \
} \
if (java_value) \
java_value->member_name = member_name; \
}
#else
#define jlong_to_jdouble(lvalue) ((jdouble) lvalue)
#endif
/*
* Convert a JS value to a Java value of the given type signature. The cost
* variable is incremented if coercion is required, e.g. the source value is
* a string, but the target type is a boolean.
*
* Returns JS_FALSE if no conversion is possible, either because the jsval has
* a type that is wholly incompatible with the Java value, or because a scalar
* jsval can't be represented in a variable of the target type without loss of
* precision, e.g. the source value is "4.2" but the destination type is byte.
* If conversion is not possible and java_value is non-NULL, the JS error
* reporter is called with an appropriate message.
*/
JSBool
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v,
JavaSignature *signature,
int *cost, jvalue *java_value, JSBool *is_local_refp)
{
JavaSignatureChar type;
JSBool success = JS_FALSE;
/* Initialize to default case, in which no new Java object is
synthesized to perform the conversion and, therefore, no JNI local
references are being held. */
*is_local_refp = JS_FALSE;
type = signature->type;
switch (type) {
case JAVA_SIGNATURE_BOOLEAN:
if (!JSVAL_IS_BOOLEAN(v)) {
if (!JS_ConvertValue(cx, v, JSTYPE_BOOLEAN, &v))
goto conversion_error;
(*cost)++;
}
if (java_value)
java_value->z = (jboolean)(JSVAL_TO_BOOLEAN(v) == JS_TRUE);
break;
case JAVA_SIGNATURE_SHORT:
JSVAL_TO_INTEGRAL_JVALUE(short, s, jshort, v, java_value);
break;
case JAVA_SIGNATURE_BYTE:
JSVAL_TO_INTEGRAL_JVALUE(byte, b, jbyte, v, java_value);
break;
case JAVA_SIGNATURE_CHAR:
/* A one-character string can be converted into a character */
if (JSVAL_IS_STRING(v) && (JS_GetStringLength(JSVAL_TO_STRING(v)) == 1)) {
v = INT_TO_JSVAL(*JS_GetStringChars(JSVAL_TO_STRING(v)));
}
JSVAL_TO_INTEGRAL_JVALUE(char, c, jchar, v, java_value);
break;
case JAVA_SIGNATURE_INT:
JSVAL_TO_INTEGRAL_JVALUE(int, i, jint, v, java_value);
break;
case JAVA_SIGNATURE_LONG:
#if XP_MAC
JSVAL_TO_JLONG_JVALUE(j, jlong, v, java_value);
#else
JSVAL_TO_INTEGRAL_JVALUE(long, j, jlong, v, java_value);
#endif
break;
case JAVA_SIGNATURE_FLOAT:
if (!JSVAL_IS_NUMBER(v)) {
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
goto conversion_error;
(*cost)++;
}
if (java_value) {
if (JSVAL_IS_INT(v))
java_value->f = (jfloat) JSVAL_TO_INT(v);
else
java_value->f = (jfloat) *JSVAL_TO_DOUBLE(v);
}
break;
case JAVA_SIGNATURE_DOUBLE:
if (!JSVAL_IS_NUMBER(v)) {
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
goto conversion_error;
(*cost)++;
}
if (java_value) {
if (JSVAL_IS_INT(v))
java_value->d = (jdouble) JSVAL_TO_INT(v);
else
java_value->d = (jdouble) *JSVAL_TO_DOUBLE(v);
}
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
if (!jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
&java_value->l, is_local_refp))
goto conversion_error;
break;
default:
PR_ASSERT(0);
return JS_FALSE;
}
/* Success */
return JS_TRUE;
numeric_conversion_error:
success = JS_TRUE;
/* Fall through ... */
conversion_error:
if (java_value) {
const char *jsval_string;
JSString *jsstr;
jsval_string = NULL;
jsstr = JS_ValueToString(cx, v);
if (jsstr)
jsval_string = JS_GetStringBytes(jsstr);
if (!jsval_string)
jsval_string = "";
JS_ReportError(cx, "Unable to convert JavaScript value %s to "
"Java value of type %s",
jsval_string, signature->name);
return JS_FALSE;
}
return success;
}
/*
* A utility routine to create a JavaScript Unicode string from a
* java.lang.String (Unicode) string.
*/
JSString *
jsj_ConvertJavaStringToJSString(JSContext *cx, JNIEnv *jEnv, jstring java_str)
{
JSString *js_str;
jboolean is_copy;
const jchar *ucs2_str;
jchar *copy_ucs2_str;
jsize ucs2_str_len, num_bytes;
ucs2_str_len = (*jEnv)->GetStringLength(jEnv, java_str);
ucs2_str = (*jEnv)->GetStringChars(jEnv, java_str, &is_copy);
if (!ucs2_str) {
jsj_UnexpectedJavaError(cx, jEnv,
"Unable to extract native Unicode from Java string");
return NULL;
}
js_str = NULL;
/* The string data passed into JS_NewUCString() is
not copied, so make a copy of the Unicode character vector. */
num_bytes = ucs2_str_len * sizeof(jchar);
copy_ucs2_str = (jchar*)JS_malloc(cx, num_bytes);
if (!copy_ucs2_str)
goto done;
memcpy(copy_ucs2_str, ucs2_str, num_bytes);
js_str = JS_NewUCString(cx, (jschar*)copy_ucs2_str, ucs2_str_len);
done:
(*jEnv)->ReleaseStringChars(jEnv, java_str, ucs2_str);
return js_str;
}
/*
* Attempt to obtain a JS string representation of a Java object.
* The java_obj argument must be of type java.lang.Object or a subclass.
* If java_obj is a Java string, it's value is simply extracted and
* copied into a JS string. Otherwise, the toString() method is called
* on java_obj.
*/
JSBool
jsj_ConvertJavaObjectToJSString(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp)
{
JSString *js_str;
jstring java_str;
jmethodID toString;
/* Create a Java string, unless java_obj is already a java.lang.String */
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, jlString)) {
java_str = java_obj;
} else {
jclass java_class;
java_class = class_descriptor->java_class;
toString = (*jEnv)->GetMethodID(jEnv, java_class, "toString",
"()Ljava/lang/String;");
if (!toString) {
/* All Java objects have a toString method */
jsj_UnexpectedJavaError(cx, jEnv, "No toString() method for class %s!",
class_descriptor->name);
return JS_FALSE;
}
java_str = (*jEnv)->CallObjectMethod(jEnv, java_obj, toString);
if (!java_str) {
jsj_ReportJavaError(cx, jEnv, "toString() method failed");
return JS_FALSE;
}
}
/* Extract Unicode from java.lang.String instance and convert to JS string */
js_str = jsj_ConvertJavaStringToJSString(cx, jEnv, java_str);
if (!js_str)
return JS_FALSE;
*vp = STRING_TO_JSVAL(js_str);
return JS_TRUE;
}
/*
* Convert a Java object to a number by attempting to call the
* doubleValue() method on a Java object to get a double result.
* This usually only works on instances of java.lang.Double, but the code
* is generalized to work with any Java object that supports this method.
*
* Returns JS_TRUE if the call was successful.
* Returns JS_FALSE if conversion is not possible or an error occurs.
*/
JSBool
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp)
{
jdouble d;
jmethodID doubleValue;
jclass java_class;
java_class = class_descriptor->java_class;
doubleValue = (*jEnv)->GetMethodID(jEnv, java_class, "doubleValue", "()D");
if (!doubleValue) {
/* There is no doubleValue() method for the object. Try toString()
instead and the JS engine will attempt to convert the result to
a number. */
(*jEnv)->ExceptionClear(jEnv);
return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor,
java_obj, vp);
}
d = (*jEnv)->CallDoubleMethod(jEnv, java_obj, doubleValue);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv, "doubleValue() method failed");
return JS_FALSE;
}
return JS_NewDoubleValue(cx, d, vp);
}
/*
* Convert a Java object to a boolean by attempting to call the
* booleanValue() method on a Java object to get a boolean result.
* This usually only works on instances of java.lang.Boolean, but the code
* is generalized to work with any Java object that supports this method.
*
* Returns JS_TRUE if the call was successful.
* Returns JS_FALSE if conversion is not possible or an error occurs.
*/
extern JSBool
jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp)
{
jboolean b;
jmethodID booleanValue;
jclass java_class;
/* Null converts to false. */
if (!java_obj) {
*vp = JSVAL_FALSE;
return JS_TRUE;
}
java_class = class_descriptor->java_class;
booleanValue = (*jEnv)->GetMethodID(jEnv, java_obj, "booleanValue", "()Z");
/* Non-null Java object does not have a booleanValue() method, so
it converts to true. */
if (!booleanValue) {
(*jEnv)->ExceptionClear(jEnv);
*vp = JSVAL_TRUE;
return JS_TRUE;
}
b = (*jEnv)->CallBooleanMethod(jEnv, java_obj, booleanValue);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv, "booleanValue() method failed");
return JS_FALSE;
}
*vp = BOOLEAN_TO_JSVAL(b);
return JS_TRUE;
}
/*
* Reflect a Java object into a JS value. The source object, java_obj, must
* be of type java.lang.Object or a subclass and may, therefore, be an array.
*/
JSBool
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp)
{
jclass java_class;
JSObject *js_obj;
/* A null in Java-land is also null in JS */
if (!java_obj) {
*vp = JSVAL_NULL;
return JS_TRUE;
}
java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);
/*
* If it's an instance of netscape.javascript.JSObject, i.e. a wrapper
* around a JS object that has been passed into the Java world, unwrap
* it to obtain the original JS object.
*/
if (njJSObject && (*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
#ifdef PRESERVE_JSOBJECT_IDENTITY
js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_obj, njJSObject_internal));
#else
js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_obj);
#endif
PR_ASSERT(js_obj);
if (!js_obj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(js_obj);
return JS_TRUE;
}
/*
* Instances of java.lang.String are wrapped so we can call methods on
* them, but they convert to a JS string if used in a string context.
*/
/* TODO - let's get rid of this annoying "feature" */
/* otherwise, wrap it inside a JavaObject */
js_obj = jsj_WrapJavaObject(cx, jEnv, java_obj, java_class);
if (!js_obj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(js_obj);
return JS_TRUE;
}
/*
* Convert a Java value (primitive or object) to a JS value.
*
* This is usually an infallible operation, but JS_FALSE is returned
* on an out-of-memory condition and the error reporter is called.
*/
JSBool
jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv,
JavaSignature *signature,
jvalue *java_value,
jsval *vp)
{
int32 ival32;
switch (signature->type) {
case JAVA_SIGNATURE_VOID:
*vp = JSVAL_VOID;
return JS_TRUE;
case JAVA_SIGNATURE_BYTE:
*vp = INT_TO_JSVAL((jsint)java_value->b);
return JS_TRUE;
case JAVA_SIGNATURE_CHAR:
*vp = INT_TO_JSVAL((jsint)java_value->c);
return JS_TRUE;
case JAVA_SIGNATURE_SHORT:
*vp = INT_TO_JSVAL((jsint)java_value->s);
return JS_TRUE;
case JAVA_SIGNATURE_INT:
ival32 = java_value->i;
if (INT_FITS_IN_JSVAL(ival32)) {
*vp = INT_TO_JSVAL((jsint) ival32);
return JS_TRUE;
} else {
return JS_NewDoubleValue(cx, ival32, vp);
}
case JAVA_SIGNATURE_BOOLEAN:
*vp = BOOLEAN_TO_JSVAL((JSBool) java_value->z);
return JS_TRUE;
case JAVA_SIGNATURE_LONG:
return JS_NewDoubleValue(cx, jlong_to_jdouble(java_value->j), vp);
case JAVA_SIGNATURE_FLOAT:
return JS_NewDoubleValue(cx, java_value->f, vp);
case JAVA_SIGNATURE_DOUBLE:
return JS_NewDoubleValue(cx, java_value->d, vp);
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value->l, vp);
default:
PR_ASSERT(0);
return JS_FALSE;
}
}

View File

@@ -0,0 +1,383 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the code used to reflect Java fields as properties of
* JavaObject objects and the code to access those fields.
*
*/
#include <stdlib.h>
#include "jsj_private.h" /* LiveConnect internals */
/*
* Add a single field, described by java_field, to the JavaMemberDescriptor
* named by field_name within the given JavaClassDescriptor.
*
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
*/
static JSBool
add_java_field_to_class_descriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring field_name_jstr,
jobject java_field, /* a java.lang.reflect.Field */
jint modifiers)
{
jclass fieldType;
jfieldID fieldID;
jclass java_class;
JSBool is_static_field;
JavaMemberDescriptor *member_descriptor = NULL;
const char *sig_cstr = NULL;
const char *field_name = NULL;
JavaSignature *signature = NULL;
JavaFieldSpec *field_spec = NULL;
is_static_field = modifiers & ACC_STATIC;
if (is_static_field) {
member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
} else {
member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
}
if (!member_descriptor)
goto error;
field_spec = (JavaFieldSpec*)JS_malloc(cx, sizeof(JavaFieldSpec));
if (!field_spec)
goto error;
field_spec->modifiers = modifiers;
/* Get the Java class corresponding to the type of the field */
fieldType = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getType);
if (!fieldType) {
jsj_UnexpectedJavaError(cx, jEnv,
"Unable to determine type of field using"
" java.lang.reflect.Field.getType()");
goto error;
}
signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType);
if (!signature)
goto error;
field_spec->signature = signature;
field_name = jsj_DupJavaStringUTF(cx, jEnv, field_name_jstr);
if (!field_name)
goto error;
field_spec->name = field_name;
/* Compute the JNI-style (string-based) signature of the field type */
sig_cstr = jsj_ConvertJavaSignatureToString(cx, signature);
if (!sig_cstr)
goto error;
/* Compute the JNI fieldID and cache it for quick field access */
java_class = class_descriptor->java_class;
if (is_static_field)
fieldID = (*jEnv)->GetStaticFieldID(jEnv, java_class, field_name, sig_cstr);
else
fieldID = (*jEnv)->GetFieldID(jEnv, java_class, field_name, sig_cstr);
if (!fieldID) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't get Java field ID for class %s, field %s (sig=%s)",
class_descriptor->name, field_name, sig_cstr);
goto error;
}
field_spec->fieldID = fieldID;
JS_free(cx, (char*)sig_cstr);
member_descriptor->field = field_spec;
/* Success */
return JS_TRUE;
error:
if (field_spec) {
JS_FREE_IF(cx, (char*)field_spec->name);
JS_free(cx, field_spec);
}
JS_FREE_IF(cx, (char*)sig_cstr);
if (signature)
jsj_ReleaseJavaClassDescriptor(cx, jEnv, signature);
return JS_FALSE;
}
/*
* Free up a JavaFieldSpec and all its resources.
*/
void
jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field)
{
JS_FREE_IF(cx, (char*)field->name);
jsj_ReleaseJavaClassDescriptor(cx, jEnv, field->signature);
JS_free(cx, field);
}
/*
* Add a JavaMemberDescriptor to the collection of members in class_descriptor
* for every public field of the identified Java class. (A separate collection
* is kept in class_descriptor for static and instance members.)
* If reflect_only_static_fields is set, instance fields are not reflected. If
* it isn't set, only instance fields are reflected and static fields are not
* reflected.
*
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
*/
JSBool
jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor,
JSBool reflect_only_static_fields)
{
int i;
JSBool ok;
jint modifiers;
jobject java_field;
jstring field_name_jstr;
jarray joFieldArray;
jsize num_fields;
jclass java_class;
/* Get a java array of java.lang.reflect.Field objects, by calling
java.lang.Class.getFields(). */
java_class = class_descriptor->java_class;
joFieldArray = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getFields);
if (!joFieldArray) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't determine Java object's fields "
"using java.lang.Class.getFields()");
return JS_FALSE;
}
/* Iterate over the class fields */
num_fields = (*jEnv)->GetArrayLength(jEnv, joFieldArray);
for (i = 0; i < num_fields; i++) {
/* Get the i'th reflected field */
java_field = (*jEnv)->GetObjectArrayElement(jEnv, joFieldArray, i);
if (!java_field) {
jsj_UnexpectedJavaError(cx, jEnv, "Can't access a Field[] array");
return JS_FALSE;
}
/* Get the field modifiers, e.g. static, public, private, etc. */
modifiers = (*jEnv)->CallIntMethod(jEnv, java_field, jlrField_getModifiers);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't access a Field's modifiers using"
"java.lang.reflect.Field.getModifiers()");
return JS_FALSE;
}
/* Don't allow access to private or protected Java fields. */
if (!(modifiers & ACC_PUBLIC))
continue;
/* Reflect all instance fields or all static fields, but not both */
if (reflect_only_static_fields != ((modifiers & ACC_STATIC) != 0))
continue;
/* Determine the unqualified name of the field */
field_name_jstr = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getName);
if (!field_name_jstr) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't obtain a Field's name"
"java.lang.reflect.Field.getName()");
return JS_FALSE;
}
/* Add a JavaFieldSpec object to the JavaClassDescriptor */
ok = add_java_field_to_class_descriptor(cx, jEnv, class_descriptor, field_name_jstr,
java_field, modifiers);
if (!ok)
return JS_FALSE;
}
/* Success */
return JS_TRUE;
}
/*
* Read the value of a Java field and return it as a JavaScript value.
* If the field is static, then java_obj is a Java class, otherwise
* it's a Java instance object.
*
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
*/
JSBool
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jobject java_obj, jsval *vp)
{
JSBool is_static_field;
jvalue java_value;
JavaSignature *signature;
JavaSignatureChar field_type;
jfieldID fieldID = field_spec->fieldID;
is_static_field = field_spec->modifiers & ACC_STATIC;
#define GET_JAVA_FIELD(Type,member) \
PR_BEGIN_MACRO \
if (is_static_field) \
java_value.member = \
(*jEnv)->GetStatic##Type##Field(jEnv, java_obj, fieldID); \
else \
java_value.member = \
(*jEnv)->Get##Type##Field(jEnv, java_obj, fieldID); \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_UnexpectedJavaError(cx, jEnv, "Error reading Java field"); \
return JS_FALSE; \
} \
PR_END_MACRO
signature = field_spec->signature;
field_type = signature->type;
switch(field_type) {
case JAVA_SIGNATURE_BYTE:
GET_JAVA_FIELD(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
GET_JAVA_FIELD(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
GET_JAVA_FIELD(Short,s);
break;
case JAVA_SIGNATURE_INT:
GET_JAVA_FIELD(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
GET_JAVA_FIELD(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
GET_JAVA_FIELD(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
GET_JAVA_FIELD(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
GET_JAVA_FIELD(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
GET_JAVA_FIELD(Object,l);
break;
#undef GET_JAVA_FIELD
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return jsj_ConvertJavaValueToJSValue(cx, jEnv, signature, &java_value, vp);
}
JSBool
jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jclass java_obj, jsval js_val)
{
JSBool is_static_field, is_local_ref;
int dummy_cost;
jvalue java_value;
JavaSignature *signature;
JavaSignatureChar field_type;
jfieldID fieldID = field_spec->fieldID;
is_static_field = field_spec->modifiers & ACC_STATIC;
#define SET_JAVA_FIELD(Type,member) \
PR_BEGIN_MACRO \
if (is_static_field) { \
(*jEnv)->SetStatic##Type##Field(jEnv, java_obj, fieldID, \
java_value.member); \
} else { \
(*jEnv)->Set##Type##Field(jEnv, java_obj, fieldID,java_value.member);\
} \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_UnexpectedJavaError(cx, jEnv, "Error assigning to Java field"); \
return JS_FALSE; \
} \
PR_END_MACRO
signature = field_spec->signature;
if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, signature, &dummy_cost,
&java_value, &is_local_ref))
return JS_FALSE;
field_type = signature->type;
switch(field_type) {
case JAVA_SIGNATURE_BYTE:
SET_JAVA_FIELD(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
SET_JAVA_FIELD(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
SET_JAVA_FIELD(Short,s);
break;
case JAVA_SIGNATURE_INT:
SET_JAVA_FIELD(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
SET_JAVA_FIELD(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
SET_JAVA_FIELD(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
SET_JAVA_FIELD(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
SET_JAVA_FIELD(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
SET_JAVA_FIELD(Object,l);
if (is_local_ref)
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
break;
#undef SET_JAVA_FIELD
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return JS_TRUE;
}

View File

@@ -0,0 +1,487 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This is a copy of the NSPR hash-table library, but it has been slightly
* modified to allow an additional argument to be passed into the hash
* key-comparision function. This is used to maintain thread-safety by
* passing in a JNIEnv pointer to the key-comparison function rather
* than storing it in a global. All types,function names, etc. have
* been renamed from their original NSPR names to protect the innocent.
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_hash.h"
#include "prtypes.h"
#ifdef NSPR20
# include "prlog.h"
# include "prbit.h"
#else
# include "prassert.h"
#endif
/* Compute the number of buckets in ht */
#define NBUCKETS(ht) (1 << (JSJ_HASH_BITS - (ht)->shift))
/* The smallest table has 16 buckets */
#define MINBUCKETSLOG2 4
#define MINBUCKETS (1 << MINBUCKETSLOG2)
/* Compute the maximum entries given n buckets that we will tolerate, ~90% */
#define OVERLOADED(n) ((n) - ((n) >> 3))
/* Compute the number of entries below which we shrink the table by half */
#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0)
/*
** Stubs for default hash allocator ops.
*/
static void *
DefaultAllocTable(void *pool, size_t size)
{
#if defined(XP_MAC)
#pragma unused (pool)
#endif
return malloc(size);
}
static void
DefaultFreeTable(void *pool, void *item)
{
#if defined(XP_MAC)
#pragma unused (pool)
#endif
free(item);
}
static JSJHashEntry *
DefaultAllocEntry(void *pool, const void *key)
{
#if defined(XP_MAC)
#pragma unused (pool,key)
#endif
return malloc(sizeof(JSJHashEntry));
}
static void
DefaultFreeEntry(void *pool, JSJHashEntry *he, PRUintn flag)
{
#if defined(XP_MAC)
#pragma unused (pool)
#endif
if (flag == HT_FREE_ENTRY)
free(he);
}
static JSJHashAllocOps defaultHashAllocOps = {
DefaultAllocTable, DefaultFreeTable,
DefaultAllocEntry, DefaultFreeEntry
};
PR_IMPLEMENT(JSJHashTable *)
JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash,
JSJHashComparator keyCompare, JSJHashComparator valueCompare,
JSJHashAllocOps *allocOps, void *allocPriv)
{
JSJHashTable *ht;
PRUint32 nb;
if (n <= MINBUCKETS) {
n = MINBUCKETSLOG2;
} else {
n = PR_CeilingLog2(n);
if ((PRInt32)n < 0)
return 0;
}
if (!allocOps) allocOps = &defaultHashAllocOps;
ht = (*allocOps->allocTable)(allocPriv, sizeof *ht);
if (!ht)
return 0;
memset(ht, 0, sizeof *ht);
ht->shift = JSJ_HASH_BITS - n;
n = 1 << n;
#if defined(XP_PC) && !defined(_WIN32)
if (n > 16000) {
(*allocOps->freeTable)(allocPriv, ht);
return 0;
}
#endif /* WIN16 */
nb = n * sizeof(JSJHashEntry *);
ht->buckets = (*allocOps->allocTable)(allocPriv, nb);
if (!ht->buckets) {
(*allocOps->freeTable)(allocPriv, ht);
return 0;
}
memset(ht->buckets, 0, nb);
ht->keyHash = keyHash;
ht->keyCompare = keyCompare;
ht->valueCompare = valueCompare;
ht->allocOps = allocOps;
ht->allocPriv = allocPriv;
return ht;
}
PR_IMPLEMENT(void)
JSJ_HashTableDestroy(JSJHashTable *ht)
{
PRUint32 i, n;
JSJHashEntry *he, *next;
JSJHashAllocOps *allocOps = ht->allocOps;
void *allocPriv = ht->allocPriv;
n = NBUCKETS(ht);
for (i = 0; i < n; i++) {
for (he = ht->buckets[i]; he; he = next) {
next = he->next;
(*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY);
}
}
#ifdef DEBUG
memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]);
#endif
(*allocOps->freeTable)(allocPriv, ht->buckets);
#ifdef DEBUG
memset(ht, 0xDB, sizeof *ht);
#endif
(*allocOps->freeTable)(allocPriv, ht);
}
/*
** Multiplicative hash, from Knuth 6.4.
*/
#define GOLDEN_RATIO 0x9E3779B9U
PR_IMPLEMENT(JSJHashEntry **)
JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg)
{
JSJHashEntry *he, **hep, **hep0;
JSJHashNumber h;
#ifdef HASHMETER
ht->nlookups++;
#endif
h = keyHash * GOLDEN_RATIO;
h >>= ht->shift;
hep = hep0 = &ht->buckets[h];
while ((he = *hep) != 0) {
if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key, arg)) {
/* Move to front of chain if not already there */
if (hep != hep0) {
*hep = he->next;
he->next = *hep0;
*hep0 = he;
}
return hep0;
}
hep = &he->next;
#ifdef HASHMETER
ht->nsteps++;
#endif
}
return hep;
}
PR_IMPLEMENT(JSJHashEntry *)
JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep,
JSJHashNumber keyHash, const void *key, void *value,
void *arg)
{
PRUint32 i, n;
JSJHashEntry *he, *next, **oldbuckets;
PRUint32 nb;
/* Grow the table if it is overloaded */
n = NBUCKETS(ht);
if (ht->nentries >= OVERLOADED(n)) {
#ifdef HASHMETER
ht->ngrows++;
#endif
ht->shift--;
oldbuckets = ht->buckets;
#if defined(XP_PC) && !defined(_WIN32)
if (2 * n > 16000)
return 0;
#endif /* WIN16 */
nb = 2 * n * sizeof(JSJHashEntry *);
ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb);
if (!ht->buckets) {
ht->buckets = oldbuckets;
return 0;
}
memset(ht->buckets, 0, nb);
for (i = 0; i < n; i++) {
for (he = oldbuckets[i]; he; he = next) {
next = he->next;
hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg);
PR_ASSERT(*hep == 0);
he->next = 0;
*hep = he;
}
}
#ifdef DEBUG
memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
#endif
(*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
}
/* Make a new key value entry */
he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
if (!he)
return 0;
he->keyHash = keyHash;
he->key = key;
he->value = value;
he->next = *hep;
*hep = he;
ht->nentries++;
return he;
}
PR_IMPLEMENT(JSJHashEntry *)
JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg)
{
JSJHashNumber keyHash;
JSJHashEntry *he, **hep;
keyHash = (*ht->keyHash)(key, arg);
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
if ((he = *hep) != 0) {
/* Hit; see if values match */
if ((*ht->valueCompare)(he->value, value, arg)) {
/* key,value pair is already present in table */
return he;
}
if (he->value)
(*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
he->value = value;
return he;
}
return JSJ_HashTableRawAdd(ht, hep, keyHash, key, value, arg);
}
PR_IMPLEMENT(void)
JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg)
{
PRUint32 i, n;
JSJHashEntry *next, **oldbuckets;
PRUint32 nb;
*hep = he->next;
(*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
/* Shrink table if it's underloaded */
n = NBUCKETS(ht);
if (--ht->nentries < UNDERLOADED(n)) {
#ifdef HASHMETER
ht->nshrinks++;
#endif
ht->shift++;
oldbuckets = ht->buckets;
nb = n * sizeof(JSJHashEntry*) / 2;
ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb);
if (!ht->buckets) {
ht->buckets = oldbuckets;
return;
}
memset(ht->buckets, 0, nb);
for (i = 0; i < n; i++) {
for (he = oldbuckets[i]; he; he = next) {
next = he->next;
hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg);
PR_ASSERT(*hep == 0);
he->next = 0;
*hep = he;
}
}
#ifdef DEBUG
memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
#endif
(*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
}
}
PR_IMPLEMENT(PRBool)
JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg)
{
JSJHashNumber keyHash;
JSJHashEntry *he, **hep;
keyHash = (*ht->keyHash)(key, arg);
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
if ((he = *hep) == 0)
return PR_FALSE;
/* Hit; remove element */
JSJ_HashTableRawRemove(ht, hep, he, arg);
return PR_TRUE;
}
PR_IMPLEMENT(void *)
JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg)
{
JSJHashNumber keyHash;
JSJHashEntry *he, **hep;
keyHash = (*ht->keyHash)(key, arg);
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
if ((he = *hep) != 0) {
return he->value;
}
return 0;
}
/*
** Iterate over the entries in the hash table calling func for each
** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP).
** Return a count of the number of elements scanned.
*/
PR_IMPLEMENT(int)
JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg)
{
JSJHashEntry *he, **hep;
PRUint32 i, nbuckets;
int rv, n = 0;
JSJHashEntry *todo = 0;
nbuckets = NBUCKETS(ht);
for (i = 0; i < nbuckets; i++) {
hep = &ht->buckets[i];
while ((he = *hep) != 0) {
rv = (*f)(he, n, arg);
n++;
if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) {
*hep = he->next;
if (rv & HT_ENUMERATE_REMOVE) {
he->next = todo;
todo = he;
}
} else {
hep = &he->next;
}
if (rv & HT_ENUMERATE_STOP) {
goto out;
}
}
}
out:
hep = &todo;
while ((he = *hep) != 0) {
JSJ_HashTableRawRemove(ht, hep, he, arg);
}
return n;
}
#ifdef HASHMETER
#include <math.h>
#include <stdio.h>
PR_IMPLEMENT(void)
JSJ_HashTableDumpMeter(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
{
double mean, variance;
PRUint32 nchains, nbuckets;
PRUint32 i, n, maxChain, maxChainLen;
JSJHashEntry *he;
variance = 0;
nchains = 0;
maxChainLen = 0;
nbuckets = NBUCKETS(ht);
for (i = 0; i < nbuckets; i++) {
he = ht->buckets[i];
if (!he)
continue;
nchains++;
for (n = 0; he; he = he->next)
n++;
variance += n * n;
if (n > maxChainLen) {
maxChainLen = n;
maxChain = i;
}
}
mean = (double)ht->nentries / nchains;
variance = fabs(variance / nchains - mean * mean);
fprintf(fp, "\nHash table statistics:\n");
fprintf(fp, " number of lookups: %u\n", ht->nlookups);
fprintf(fp, " number of entries: %u\n", ht->nentries);
fprintf(fp, " number of grows: %u\n", ht->ngrows);
fprintf(fp, " number of shrinks: %u\n", ht->nshrinks);
fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps
/ ht->nlookups);
fprintf(fp, "mean hash chain length: %g\n", mean);
fprintf(fp, " standard deviation: %g\n", sqrt(variance));
fprintf(fp, " max hash chain length: %u\n", maxChainLen);
fprintf(fp, " max hash chain: [%u]\n", maxChain);
for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++)
if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT)
break;
}
#endif /* HASHMETER */
PR_IMPLEMENT(int)
JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
{
int count;
count = JSJ_HashTableEnumerateEntries(ht, dump, fp);
#ifdef HASHMETER
JSJ_HashTableDumpMeter(ht, dump, fp);
#endif
return count;
}
PR_IMPLEMENT(JSJHashNumber)
JSJ_HashString(const void *key)
{
JSJHashNumber h;
const unsigned char *s;
h = 0;
for (s = key; *s; s++)
h = (h >> 28) ^ (h << 4) ^ *s;
return h;
}
PR_IMPLEMENT(int)
JSJ_CompareStrings(const void *v1, const void *v2)
{
return strcmp(v1, v2) == 0;
}
PR_IMPLEMENT(int)
JSJ_CompareValues(const void *v1, const void *v2)
{
return v1 == v2;
}

View File

@@ -0,0 +1,141 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This is a copy of the NSPR hash-table library, but it has been slightly
* modified to allow an additional argument to be passed into the hash
* key-comparision function. This is used to maintain thread-safety by
* passing in a JNIEnv pointer to the key-comparison function rather
* than storing it in a global. All types,function names, etc. have
* been renamed from their original NSPR names to protect the innocent.
*/
#ifndef jsj_hash_h___
#define jsj_hash_h___
/*
* API to portable hash table code.
*/
#include <stddef.h>
#include <stdio.h>
#include "prtypes.h"
PR_BEGIN_EXTERN_C
typedef struct JSJHashEntry JSJHashEntry;
typedef struct JSJHashTable JSJHashTable;
typedef PRUint32 JSJHashNumber;
#define JSJ_HASH_BITS 32
typedef JSJHashNumber (*JSJHashFunction)(const void *key, void *arg);
typedef PRIntn (*JSJHashComparator)(const void *v1, const void *v2, void *arg);
typedef PRIntn (*JSJHashEnumerator)(JSJHashEntry *he, PRIntn i, void *arg);
/* Flag bits in JSJHashEnumerator's return value */
#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */
#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */
#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */
#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */
typedef struct JSJHashAllocOps {
void * (*allocTable)(void *pool, size_t size);
void (*freeTable)(void *pool, void *item);
JSJHashEntry * (*allocEntry)(void *pool, const void *key);
void (*freeEntry)(void *pool, JSJHashEntry *he, PRUintn flag);
} JSJHashAllocOps;
#define HT_FREE_VALUE 0 /* just free the entry's value */
#define HT_FREE_ENTRY 1 /* free value and entire entry */
struct JSJHashEntry {
JSJHashEntry *next; /* hash chain linkage */
JSJHashNumber keyHash; /* key hash function result */
const void *key; /* ptr to opaque key */
void *value; /* ptr to opaque value */
};
struct JSJHashTable {
JSJHashEntry **buckets; /* vector of hash buckets */
PRUint32 nentries; /* number of entries in table */
PRUint32 shift; /* multiplicative hash shift */
JSJHashFunction keyHash; /* key hash function */
JSJHashComparator keyCompare; /* key comparison function */
JSJHashComparator valueCompare; /* value comparison function */
JSJHashAllocOps *allocOps; /* allocation operations */
void *allocPriv; /* allocation private data */
#ifdef HASHMETER
PRUint32 nlookups; /* total number of lookups */
PRUint32 nsteps; /* number of hash chains traversed */
PRUint32 ngrows; /* number of table expansions */
PRUint32 nshrinks; /* number of table contractions */
#endif
};
/*
* Create a new hash table.
* If allocOps is null, use default allocator ops built on top of malloc().
*/
PR_EXTERN(JSJHashTable *)
JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash,
JSJHashComparator keyCompare, JSJHashComparator valueCompare,
JSJHashAllocOps *allocOps, void *allocPriv);
PR_EXTERN(void)
JSJ_HashTableDestroy(JSJHashTable *ht);
/* Low level access methods */
PR_EXTERN(JSJHashEntry **)
JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg);
PR_EXTERN(JSJHashEntry *)
JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep, JSJHashNumber keyHash,
const void *key, void *value, void *arg);
PR_EXTERN(void)
JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg);
/* Higher level access methods */
PR_EXTERN(JSJHashEntry *)
JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg);
PR_EXTERN(PRBool)
JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg);
PR_EXTERN(PRIntn)
JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg);
PR_EXTERN(void *)
JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg);
PR_EXTERN(PRIntn)
JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp);
/* General-purpose C string hash function. */
PR_EXTERN(JSJHashNumber)
JSJ_HashString(const void *key);
/* Compare strings using strcmp(), return true if equal. */
PR_EXTERN(int)
JSJ_CompareStrings(const void *v1, const void *v2);
/* Stub function just returns v1 == v2 */
PR_EXTERN(PRIntn)
JSJ_CompareValues(const void *v1, const void *v2);
PR_END_EXTERN_C
#endif /* jsj_hash_h___ */

File diff suppressed because it is too large Load Diff

View File

View File

@@ -0,0 +1,552 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* Declarations of private (internal) functions/data/types for
* JavaScript <==> Java communication.
*
*/
#ifndef _JSJAVA_PVT_H
#define _JSJAVA_PVT_H
#include "prtypes.h"
/* NSPR1 compatibility definitions */
#ifdef NSPR20
# include "prprf.h"
# include "prlog.h"
# include "plhash.h" /* NSPR hash-tables */
#else
# include "prprintf.h"
# include "prassert.h"
# include "prhash.h" /* NSPR hash-tables */
# define PRHashNumber prhashcode
#endif
#ifdef XP_MAC
# include "prosdep.h"
#endif
#include "jsj_hash.h" /* Hash tables */
#include "jni.h" /* Java Native Interface */
#include "jsapi.h" /* JavaScript engine API */
#include "jsjava.h" /* LiveConnect public API */
/*************************** Type Declarations ******************************/
/* Forward type declarations */
typedef struct JavaMemberDescriptor JavaMemberDescriptor;
typedef struct JavaMethodSpec JavaMethodSpec;
typedef struct JavaClassDescriptor JavaClassDescriptor;
typedef struct JavaClassDescriptor JavaSignature;
typedef struct CapturedJSError CapturedJSError;
typedef struct JavaMemberVal JavaMemberVal;
/*
* This enum uses the same character encoding used by the JDK to encode
* Java type signatures, but the enum is easier to debug/compile with.
*/
typedef enum {
JAVA_SIGNATURE_ARRAY = '[',
JAVA_SIGNATURE_BYTE = 'B',
JAVA_SIGNATURE_CHAR = 'C',
JAVA_SIGNATURE_CLASS = 'L',
JAVA_SIGNATURE_FLOAT = 'F',
JAVA_SIGNATURE_DOUBLE = 'D',
JAVA_SIGNATURE_INT = 'I',
JAVA_SIGNATURE_LONG = 'J',
JAVA_SIGNATURE_SHORT = 'S',
JAVA_SIGNATURE_VOID = 'V',
JAVA_SIGNATURE_BOOLEAN = 'Z',
JAVA_SIGNATURE_UNKNOWN = 0
} JavaSignatureChar;
/* The signature of a Java method consists of the signatures of all its
arguments and its return type signature. */
typedef struct JavaMethodSignature {
jsize num_args; /* Length of arg_signatures array */
JavaSignature ** arg_signatures; /* Array of argument signatures */
JavaSignature * return_val_signature; /* Return type signature */
} JavaMethodSignature;
/* A descriptor for the reflection of a single Java field */
typedef struct JavaFieldSpec {
jfieldID fieldID; /* JVM opaque access handle for field */
JavaSignature * signature; /* Java type of field */
int modifiers; /* Bitfield indicating field qualifiers */
const char * name; /* UTF8; TODO - Should support Unicode field names */
} JavaFieldSpec;
/* A descriptor for the reflection of a single Java method.
Each overloaded method has a separate corresponding JavaMethodSpec. */
struct JavaMethodSpec {
jmethodID methodID; /* JVM opaque access handle for method */
JavaMethodSignature signature;
const char * name; /* UTF8; TODO - Should support Unicode method names */
JavaMethodSpec * next; /* next method in chain of overloaded methods */
};
/*
* A descriptor for the reflection of a single member of a Java object.
* This can represent one or more Java methods and/or a single field.
* (When there is more than one method attached to a single JavaMemberDescriptor
* they are overloaded methods sharing the same simple name.) This same
* descriptor type is used for both static or instance members.
*/
struct JavaMemberDescriptor {
const char * name; /* simple name of field and/or method */
jsid id; /* hashed name for quick JS property lookup */
JavaFieldSpec * field; /* field with the given name, if any */
JavaMethodSpec * methods; /* Overloaded methods which share the same name, if any */
JavaMemberDescriptor * next; /* next descriptor in same defining class */
JSObject * invoke_func_obj; /* If non-null, JSFunction obj to invoke method */
};
/* This is the native portion of a reflected Java class */
struct JavaClassDescriptor {
const char * name; /* Name of class, e.g. "java/lang/Byte" */
JavaSignatureChar type; /* class category: primitive type, object, array */
jclass java_class; /* Opaque JVM handle to corresponding java.lang.Class */
int num_instance_members;
int num_static_members;
JSBool instance_members_reflected;
JavaMemberDescriptor * instance_members;
JSBool static_members_reflected;
JavaMemberDescriptor * static_members;
JavaMemberDescriptor * constructors;
int modifiers; /* Class declaration qualifiers,
e.g. abstract, private */
int ref_count; /* # of references to this struct */
JavaSignature * array_component_signature; /* Only non-NULL for array classes */
};
/* This is the native portion of a reflected Java method or field */
struct JavaMemberVal {
jsval field_val; /* Captured value of Java field */
jsval invoke_method_func_val; /* JSFunction wrapper around Java method invoker */
JavaMemberDescriptor * descriptor;
JavaMemberVal * next;
};
/* This is the native portion of a reflected Java object */
typedef struct JavaObjectWrapper {
jobject java_obj; /* Opaque JVM ref to Java object */
JavaClassDescriptor * class_descriptor; /* Java class info */
} JavaObjectWrapper;
/* These are definitions of the Java class/method/field modifier bits.
These really shouldn't be hard-coded here. Rather,
they should be read from java.lang.reflect.Modifier */
#define ACC_PUBLIC 0x0001 /* visible to everyone */
#define ACC_STATIC 0x0008 /* instance variable is static */
#define ACC_FINAL 0x0010 /* no further subclassing,overriding */
#define ACC_INTERFACE 0x0200 /* class is an interface */
#define ACC_ABSTRACT 0x0400 /* no definition provided */
/* A JSJavaVM structure must be created for each Java VM that is accessed
via LiveConnect */
struct JSJavaVM {
/* TODO - all LiveConnect global variables should be migrated into this
structure in order to allow more than one LiveConnect-enabled
Java VM to exist within the same process. */
SystemJavaVM * java_vm;
JNIEnv * main_thread_env; /* Main-thread Java environment */
JSBool jsj_created_java_vm;
int num_attached_threads;
JSJavaVM * next; /* next VM among all created VMs */
};
/* Per-thread state that encapsulates the connection to the Java VM */
struct JSJavaThreadState {
const char * name; /* Thread name, for debugging */
JSJavaVM * jsjava_vm; /* All per-JVM state */
JNIEnv * jEnv; /* Per-thread opaque handle to Java VM */
CapturedJSError * pending_js_errors; /* JS errors to be thrown as Java exceptions */
JSContext * cx; /* current JS context for thread */
JSJavaThreadState * next; /* next thread state among all created threads */
};
struct JavaToJSSavedState {
JSErrorReporter error_reporter;
JSJavaThreadState* java_jsj_env;
};
typedef struct JavaToJSSavedState JavaToJSSavedState;
/******************************** Globals ***********************************/
extern JSJCallbacks *JSJ_callbacks;
/* JavaScript classes that reflect Java objects */
extern JSClass JavaObject_class;
extern JSClass JavaArray_class;
extern JSClass JavaClass_class;
extern JSClass JavaMember_class;
/*
* Opaque JVM handles to Java classes, methods and objects required for
* Java reflection. These are computed and cached during initialization.
* TODO: These should be moved inside the JSJavaVM struct
*/
extern jclass jlObject; /* java.lang.Object */
extern jclass jlrConstructor; /* java.lang.reflect.Constructor */
extern jclass jlThrowable; /* java.lang.Throwable */
extern jclass jlSystem; /* java.lang.System */
extern jclass jlClass; /* java.lang.Class */
extern jclass jlBoolean; /* java.lang.Boolean */
extern jclass jlDouble; /* java.lang.Double */
extern jclass jlString; /* java.lang.String */
extern jclass njJSObject; /* netscape.javascript.JSObject */
extern jclass njJSException; /* netscape.javascript.JSException */
extern jclass njJSUtil; /* netscape.javascript.JSUtil */
extern jmethodID jlClass_getMethods; /* java.lang.Class.getMethods() */
extern jmethodID jlClass_getConstructors; /* java.lang.Class.getConstructors() */
extern jmethodID jlClass_getFields; /* java.lang.Class.getFields() */
extern jmethodID jlClass_getName; /* java.lang.Class.getName() */
extern jmethodID jlClass_getComponentType; /* java.lang.Class.getComponentType() */
extern jmethodID jlClass_getModifiers; /* java.lang.Class.getModifiers() */
extern jmethodID jlClass_isArray; /* java.lang.Class.isArray() */
extern jmethodID jlrMethod_getName; /* java.lang.reflect.Method.getName() */
extern jmethodID jlrMethod_getParameterTypes; /* java.lang.reflect.Method.getParameterTypes() */
extern jmethodID jlrMethod_getReturnType; /* java.lang.reflect.Method.getReturnType() */
extern jmethodID jlrMethod_getModifiers; /* java.lang.reflect.Method.getModifiers() */
extern jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */
extern jmethodID jlrConstructor_getModifiers; /* java.lang.reflect.Constructor.getModifiers() */
extern jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */
extern jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
extern jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
extern jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */
extern jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */
extern jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */
extern jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */
extern jmethodID jlDouble_Double; /* java.lang.Double constructor */
extern jmethodID jlDouble_doubleValue; /* java.lang.Double.doubleValue() */
extern jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() */
extern jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
extern jmethodID njJSException_JSException; /* netscape.javascipt.JSexception constructor */
extern jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
extern jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
extern jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
extern jfieldID njJSException_lineno; /* netscape.javascript.JSException.lineno */
extern jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
extern jfieldID njJSException_source; /* netscape.javascript.JSException.source */
extern jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
/**************** Java <==> JS conversions and Java types *******************/
extern JSBool
jsj_ComputeJavaClassSignature(JSContext *cx,
JavaSignature *signature,
jclass java_class);
extern const char *
jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature);
extern const char *
jsj_ConvertJavaSignatureToHRString(JSContext *cx,
JavaSignature *signature);
extern JavaMethodSignature *
jsj_InitJavaMethodSignature(JSContext *cx, JNIEnv *jEnv, jobject method,
JavaMethodSignature *method_signature);
extern const char *
jsj_ConvertJavaMethodSignatureToString(JSContext *cx,
JavaMethodSignature *method_signature);
extern const char *
jsj_ConvertJavaMethodSignatureToHRString(JSContext *cx,
const char *method_name,
JavaMethodSignature *method_signature);
extern void
jsj_PurgeJavaMethodSignature(JSContext *cx, JNIEnv *jEnv, JavaMethodSignature *signature);
extern JSBool
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
int *cost, jvalue *java_value, JSBool *is_local_refp);
extern JSBool
jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
int *cost, jobject *java_value, JSBool *is_local_refp);
extern jstring
jsj_ConvertJSStringToJavaString(JSContext *cx, JNIEnv *jEnv, JSString *js_str);
extern JSBool
jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature,
jvalue *java_value, jsval *vp);
extern JSBool
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp);
extern JSString *
jsj_ConvertJavaStringToJSString(JSContext *cx, JNIEnv *jEnv, jstring java_str);
extern JSBool
jsj_ConvertJavaObjectToJSString(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp);
extern JSBool
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp);
extern JSBool
jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp);
extern JSJavaThreadState *
jsj_enter_js(JNIEnv *jEnv, jobject java_wrapper_obj,
JSContext **cxp, JSObject **js_objp, JavaToJSSavedState* saved_state);
extern JSBool
jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JavaToJSSavedState* original_state);
extern JavaClassDescriptor *
jsj_get_jlObject_descriptor(JSContext *cx, JNIEnv *jEnv);
extern JSBool
jsj_remove_js_obj_reflection_from_hashtable(JSContext *cx, JSObject *js_obj);
extern JSBool
jsj_init_js_obj_reflections_table();
/************************ Java package reflection **************************/
extern JSBool
jsj_init_JavaPackage(JSContext *, JSObject *,
JavaPackageDef *predefined_packages);
/************************* Java class reflection ***************************/
extern JSBool
jsj_init_JavaClass(JSContext *cx, JSObject *global_obj);
extern void
jsj_DiscardJavaClassReflections(JNIEnv *jEnv);
extern const char *
jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class);
extern JavaClassDescriptor *
jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class);
extern void
jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor);
extern JSObject *
jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
const char *unqualified_class_name,
jclass jclazz);
extern JavaMemberDescriptor *
jsj_GetJavaMemberDescriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name);
extern JavaMemberDescriptor *
jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id);
extern JavaMemberDescriptor *
jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id);
extern JavaMemberDescriptor *
jsj_GetJavaStaticMemberDescriptor(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name);
extern JavaMemberDescriptor *
jsj_GetJavaClassConstructors(JSContext *cx,
JavaClassDescriptor *class_descriptor);
extern JavaMemberDescriptor *
jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor);
extern JavaMemberDescriptor *
jsj_GetClassInstanceMembers(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor);
extern JavaMemberDescriptor *
jsj_GetClassStaticMembers(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor);
extern JSBool
jsj_InitJavaClassReflectionsTable();
/************************* Java field reflection ***************************/
extern JSBool
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jobject java_obj, jsval *vp);
extern JSBool
jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jobject java_obj, jsval js_val);
extern JSBool
jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
JSBool reflect_only_static_fields);
extern void
jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field);
/************************* Java method reflection ***************************/
extern JSBool
jsj_JavaInstanceMethodWrapper(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp);
extern JSBool
jsj_JavaStaticMethodWrapper(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp);
extern JSBool
jsj_JavaConstructorWrapper(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp);
extern JSBool
jsj_ReflectJavaMethods(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
JSBool reflect_only_static_methods);
extern void
jsj_DestroyMethodSpec(JSContext *cx, JNIEnv *jEnv, JavaMethodSpec *method_spec);
/************************* Java member reflection ***************************/
extern JSBool
jsj_init_JavaMember(JSContext *, JSObject *);
extern JSBool
jsj_ReflectJavaMethodsAndFields(JSContext *cx, JavaClassDescriptor *class_descriptor,
JSBool reflect_only_statics);
extern JSObject *
jsj_CreateJavaMember(JSContext *cx, jsval method_val, jsval field_val);
/************************* Java object reflection **************************/
extern JSBool
jsj_init_JavaObject(JSContext *, JSObject *);
extern JSObject *
jsj_WrapJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_obj, jclass java_class);
extern void
jsj_DiscardJavaObjReflections(JNIEnv *jEnv);
extern JSBool
JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
extern void
JavaObject_finalize(JSContext *cx, JSObject *obj);
extern JSBool
JavaObject_resolve(JSContext *cx, JSObject *obj, jsval id);
extern JSBool
JavaObject_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSBool
JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
/************************* Java array reflection ***************************/
extern JSBool
jsj_init_JavaArray(JSContext *cx, JSObject *global_obj);
extern JSBool
jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array,
jsize index, JavaSignature *array_component_signature,
jsval *vp);
extern JSBool
jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array,
jsize index, JavaSignature *array_component_signature,
jsval js_val);
/********************* JavaScript object reflection ************************/
extern jobject
jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj);
extern JSObject *
jsj_UnwrapJSObjectWrapper(JNIEnv *jEnv, jobject java_wrapper_obj);
extern void
jsj_ClearPendingJSErrors(JSJavaThreadState *jsj_env);
extern JSBool
jsj_ReportUncaughtJSException(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception);
/**************************** Utilities ************************************/
extern void
jsj_ReportJavaError(JSContext *cx, JNIEnv *env, const char *format, ...);
extern void
jsj_UnexpectedJavaError(JSContext *cx, JNIEnv *env, const char *format, ...);
extern const char *
jsj_GetJavaErrorMessage(JNIEnv *env);
extern void
jsj_LogError(const char *error_msg);
PR_CALLBACK JSJHashNumber
jsj_HashJavaObject(const void *key, void* env);
PR_CALLBACK intN
jsj_JavaObjectComparator(const void *v1, const void *v2, void *arg);
extern JSJavaThreadState *
jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp);
extern void
jsj_MakeJNIClassname(char *jClassName);
extern const char *
jsj_ClassNameOfJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_object);
extern jsize
jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array);
extern JSBool
JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp);
extern const char *
jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr);
JSJavaThreadState *
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp);
JSJavaThreadState *
jsj_SetJavaJSJEnv(JSJavaThreadState* java_jsj_env);
#ifdef DEBUG
#define DEBUG_LOG(args) printf args
#endif
#define JS_FREE_IF(cx, x) \
PR_BEGIN_MACRO \
if (x) \
JS_free(cx, x); \
PR_END_MACRO
#endif /* _JSJAVA_PVT_H */

View File

@@ -0,0 +1,361 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains low-level utility code.
*
*/
#include <stdlib.h>
#include <string.h>
#include "jsj_private.h" /* LiveConnect internals */
#include "jsjava.h" /* External LiveConnect API */
/*
* This is a hash-table utility routine that computes the hash code of a Java
* object by calling java.lang.System.identityHashCode()
*/
PR_CALLBACK JSJHashNumber
jsj_HashJavaObject(const void *key, void* env)
{
PRHashNumber hash_code;
jobject java_obj;
JNIEnv *jEnv;
java_obj = (jobject)key;
jEnv = (JNIEnv*) env;
hash_code = (*jEnv)->CallStaticIntMethod(jEnv, jlSystem,
jlSystem_identityHashCode, java_obj);
PR_ASSERT(!(*jEnv)->ExceptionOccurred(jEnv));
return hash_code;
}
/*
* This is a hash-table utility routine for comparing two Java objects.
* It's not possible to use the == operator to directly compare two jobject's,
* since they're opaque references and aren't guaranteed to be simple pointers
* or handles (though they may be in some JVM implementations). Instead,
* use the JNI routine for comparing the two objects.
*/
PR_CALLBACK intN
jsj_JavaObjectComparator(const void *v1, const void *v2, void *arg)
{
jobject java_obj1, java_obj2;
JNIEnv *jEnv;
jEnv = (JNIEnv*)arg;
java_obj1 = (jobject)v1;
java_obj2 = (jobject)v2;
if (java_obj1 == java_obj2)
return 1;
return (*jEnv)->IsSameObject(jEnv, java_obj1, java_obj2);
}
/*
* Return a UTF8, null-terminated encoding of a Java string. The string must
* be free'ed by the caller.
*
* If an error occurs, returns NULL and calls the JS error reporter.
*/
const char *
jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr)
{
const char *str, *retval;
str = (*jEnv)->GetStringUTFChars(jEnv, jstr, 0);
if (!str) {
jsj_UnexpectedJavaError(cx, jEnv, "Can't get UTF8 characters from "
"Java string");
return NULL;
}
retval = JS_strdup(cx, str);
(*jEnv)->ReleaseStringUTFChars(jEnv, jstr, str);
return retval;
}
JSBool
JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp)
{
const jschar *ucs2;
JSString *jsstr;
jsize ucs2_len;
jsval val;
ucs2 = (*jEnv)->GetStringChars(jEnv, jstr, 0);
if (!ucs2) {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain Unicode characters"
"from Java string");
return JS_FALSE;
}
ucs2_len = (*jEnv)->GetStringLength(jEnv, jstr);
jsstr = JS_InternUCStringN(cx, ucs2, ucs2_len);
(*jEnv)->ReleaseStringChars(jEnv, jstr, ucs2);
if (!jsstr)
return JS_FALSE;
val = STRING_TO_JSVAL(jsstr);
JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp);
return JS_TRUE;
}
/* Not used ?
const char *
jsj_ClassNameOfJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_object)
{
jobject java_class;
java_class = (*jEnv)->GetObjectClass(jEnv, java_object);
if (!java_class) {
PR_ASSERT(0);
return NULL;
}
return jsj_GetJavaClassName(cx, jEnv, java_class);
}
*/
/*
* Return, as a C string, the error message associated with a Java exception
* that occurred as a result of a JNI call, preceded by the class name of
* the exception. As a special case, if the class of the exception is
* netscape.javascript.JSException, the exception class name is omitted.
*
* NULL is returned if no Java exception is pending. The caller is
* responsible for free'ing the returned string. On exit, the Java exception
* is *not* cleared.
*/
const char *
jsj_GetJavaErrorMessage(JNIEnv *jEnv)
{
const char *java_error_msg;
char *error_msg = NULL;
jthrowable exception;
jstring java_exception_jstring;
exception = (*jEnv)->ExceptionOccurred(jEnv);
if (exception && jlThrowable_toString) {
java_exception_jstring =
(*jEnv)->CallObjectMethod(jEnv, exception, jlThrowable_toString);
java_error_msg = (*jEnv)->GetStringUTFChars(jEnv, java_exception_jstring, NULL);
error_msg = strdup((char*)java_error_msg);
(*jEnv)->ReleaseStringUTFChars(jEnv, java_exception_jstring, java_error_msg);
#ifdef DEBUG
/* (*jEnv)->ExceptionDescribe(jEnv); */
#endif
}
return error_msg;
}
/*
* Return, as a C string, the JVM stack trace associated with a Java
* exception, as would be printed by java.lang.Throwable.printStackTrace().
* The caller is responsible for free'ing the returned string.
*
* Returns NULL if an error occurs.
*/
static const char *
get_java_stack_trace(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception)
{
const char *backtrace;
jstring backtrace_jstr;
backtrace = NULL;
if (java_exception && njJSUtil_getStackTrace) {
backtrace_jstr = (*jEnv)->CallStaticObjectMethod(jEnv, njJSUtil,
njJSUtil_getStackTrace,
java_exception);
if (!backtrace_jstr) {
jsj_UnexpectedJavaError(cx, jEnv, "Unable to get exception stack trace");
return NULL;
}
backtrace = jsj_DupJavaStringUTF(cx, jEnv, backtrace_jstr);
}
return backtrace;
}
/* Full Java backtrace when Java exceptions reported to JavaScript */
#define REPORT_JAVA_EXCEPTION_STACK_TRACE
/*
* This is a wrapper around JS_ReportError(), useful when an error condition
* is the result of a JVM failure or exception condition. It appends the
* message associated with the pending Java exception to the passed in
* printf-style format string and arguments.
*/
static void
vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
{
char *error_msg, *js_error_msg;
const char *java_stack_trace;
const char *java_error_msg;
jthrowable java_exception;
java_error_msg = NULL;
java_exception = (*jEnv)->ExceptionOccurred(jEnv);
if (java_exception && njJSException &&
(*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
(*jEnv)->ExceptionClear(jEnv);
jsj_ReportUncaughtJSException(cx, jEnv, java_exception);
return;
}
js_error_msg = PR_vsmprintf(format, ap);
if (!js_error_msg) {
PR_ASSERT(0); /* Out-of-memory */
return;
}
#ifdef REPORT_JAVA_EXCEPTION_STACK_TRACE
java_stack_trace = get_java_stack_trace(cx, jEnv, java_exception);
if (java_stack_trace) {
error_msg = PR_smprintf("%s\n%s", js_error_msg, java_stack_trace);
free((char*)java_stack_trace);
if (!error_msg) {
PR_ASSERT(0); /* Out-of-memory */
return;
}
} else
#endif
{
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
if (java_error_msg) {
error_msg = PR_smprintf("%s (%s)\n", js_error_msg, java_error_msg);
free((char*)java_error_msg);
free(js_error_msg);
} else {
error_msg = js_error_msg;
}
}
JS_ReportError(cx, error_msg);
/* Important: the Java exception must not be cleared until the reporter
has been called, because the capture_js_error_reports_for_java(),
called from JS_ReportError(), needs to read the exception from the JVM */
(*jEnv)->ExceptionClear(jEnv);
free(error_msg);
}
void
jsj_ReportJavaError(JSContext *cx, JNIEnv *env, const char *format, ...)
{
va_list ap;
va_start(ap, format);
vreport_java_error(cx, env, format, ap);
va_end(ap);
}
/*
* Same as jsj_ReportJavaError, except "internal error: " is prepended
* to message.
*/
void
jsj_UnexpectedJavaError(JSContext *cx, JNIEnv *env, const char *format, ...)
{
va_list ap;
const char *format2;
va_start(ap, format);
format2 = PR_smprintf("internal error: %s", format);
if (format2) {
vreport_java_error(cx, env, format2, ap);
free((void*)format2);
}
va_end(ap);
}
/*
* Most LiveConnect errors are signaled by calling JS_ReportError(),
* but in some circumstances, the target JSContext for such errors
* is not determinable, e.g. during initialization. In such cases
* any error messages are routed to this function.
*/
void
jsj_LogError(const char *error_msg)
{
if (JSJ_callbacks && JSJ_callbacks->error_print)
JSJ_callbacks->error_print(error_msg);
else
fputs(error_msg, stderr);
}
jsize
jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array)
{
jsize array_length = (*jEnv)->GetArrayLength(jEnv, java_array);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain array length");
return -1;
}
return array_length;
}
static JSJavaThreadState *the_java_jsj_env = NULL;
JSJavaThreadState *
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp)
{
JSJavaThreadState *jsj_env;
char *err_msg;
*envp = NULL;
err_msg = NULL;
jsj_env = the_java_jsj_env;
if (jsj_env == NULL)
jsj_env = JSJ_callbacks->map_js_context_to_jsj_thread(cx, &err_msg);
if (!jsj_env) {
if (err_msg) {
JS_ReportError(cx, err_msg);
free(err_msg);
}
return NULL;
}
if (envp)
*envp = jsj_env->jEnv;
return jsj_env;
}
/**
* Since only one Java thread is allowed to enter JavaScript, this function is
* used to enforce the use of that thread's state. The static global the_java_jsj_env
* overrides using JSJ_callbacks->map_js_context_to_jsj_thread, which maps
* native threads to JSJavaThreadStates. This isn't appropriate when Java calls
* JavaScript, as there can be a many to one mapping from Java threads to native
* threads.
*/
JSJavaThreadState *
jsj_SetJavaJSJEnv(JSJavaThreadState* java_jsj_env)
{
JSJavaThreadState *old_jsj_env = the_java_jsj_env;
the_java_jsj_env = java_jsj_env;
return old_jsj_env;
}

View File

@@ -0,0 +1,264 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* Publicly exported functions for JavaScript <==> Java communication.
*
*/
#ifndef _JSJAVA_H
#define _JSJAVA_H
#ifndef prtypes_h___
#include "prtypes.h"
#endif
PR_BEGIN_EXTERN_C
#include "jni.h" /* Java Native Interface */
#include "jsapi.h" /* JavaScript engine API */
/*
* A JSJavaVM structure is a wrapper around a JavaVM which incorporates
* additional LiveConnect state.
*/
typedef struct JSJavaVM JSJavaVM;
/* LiveConnect and Java state, one per thread */
typedef struct JSJavaThreadState JSJavaThreadState;
/*
* An opaque type that represents the connection to the Java VM. In stand-alone
* Java environments, this may be a JNI JavaVM object; in the browser environment
* it is a reference to a JVM plugin. A set of callbacks in the JSJCallbacks
* struct allow it to be manipulated.
*/
typedef struct SystemJavaVM SystemJavaVM;
/*
* This callback table provides hooks to external functions that implement
* functionality specific to the embedding. For example, these callbacks are
* necessary in multi-threaded environments or to implement a security
* policy.
*/
typedef struct JSJCallbacks {
/* This callback is invoked when there is no JavaScript execution
environment (JSContext) associated with the current Java thread and
a call is made from Java into JavaScript. (A JSContext is associated
with a Java thread by calling the JSJ_SetJSContextForJavaThread()
function.) This callback is only invoked when Java spontaneously calls
into JavaScript, i.e. it is not called when JS calls into Java which
calls back into JS.
This callback can be used to create a JSContext lazily, or obtain
one from a pool of available JSContexts. The implementation of this
callback can call JSJ_SetJSContextForJavaThread() to avoid any further
callbacks of this type for this Java thread. */
JSContext * (*map_jsj_thread_to_js_context)(JSJavaThreadState *jsj_env,
JNIEnv *jEnv,
char **errp);
/* This callback is invoked whenever a call is made into Java from
JavaScript. It's responsible for mapping from a JavaScript execution
environment (JSContext) to a Java thread. (A JavaContext can only
be associated with one Java thread at a time.) */
JSJavaThreadState * (*map_js_context_to_jsj_thread)(JSContext *cx,
char **errp);
/* This callback implements netscape.javascript.JSObject.getWindow(),
a method named for its behavior in the browser environment, where it
returns the JS "Window" object corresponding to the HTML window that an
applet is embedded within. More generally, it's a way for Java to get
hold of a JS object that has not been explicitly passed to it. */
JSObject * (*map_java_object_to_js_object)(JNIEnv *jEnv, void *pJavaObject,
char **errp);
/* An interim callback function until the LiveConnect security story is
straightened out. This function pointer can be set to NULL. */
JSPrincipals * (*get_JSPrincipals_from_java_caller)(JNIEnv *jEnv, JSContext *pJSContext);
/* The following two callbacks sandwich any JS evaluation performed
from Java. They may be used to implement concurrency constraints, e.g.
by suspending the current thread until some condition is met. In the
browser embedding, these are used to maintain the run-to-completion
semantics of JavaScript. It is acceptable for either function pointer
to be NULL. */
JSBool (*enter_js_from_java)(JNIEnv *jEnv, char **errp);
void (*exit_js)(JNIEnv *jEnv);
/* Most LiveConnect errors are signaled by calling JS_ReportError(), but in
some circumstances, the target JSContext for such errors is not
determinable, e.g. during initialization. In such cases any error
messages are routed to this function. If the function pointer is set to
NULL, error messages are sent to stderr. */
void (*error_print)(const char *error_msg);
/* This enables liveconnect to ask the VM for a java wrapper so that VM gets a chance to
store a mapping between a jsobject and java wrapper. So the unwrapping can be done on the
VM side before calling nsILiveconnect apis. This saves on a round trip request. */
jobject (*get_java_wrapper)(JNIEnv *jEnv, jint jsobject);
/* The following set of methods abstract over the JavaVM object. */
PRBool (*create_java_vm)(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs);
PRBool (*destroy_java_vm)(SystemJavaVM* jvm, JNIEnv* initialEnv);
JNIEnv* (*attach_current_thread)(SystemJavaVM* jvm);
PRBool (*detach_current_thread)(SystemJavaVM* jvm, JNIEnv* env);
SystemJavaVM* (*get_java_vm)(JNIEnv* env);
/* Reserved for future use */
void * reserved[10];
} JSJCallbacks;
/*===========================================================================*/
/* A flag that denotes that a Java package has no sub-packages other than those
explicitly pre-defined at the time of initialization. An access
to a simple name within such a package, therefore, must either correspond to
one of these explicitly pre-defined sub-packages or to a class within this
package. It is reasonable for LiveConnect to signal an error if a simple
name does not comply with these criteria. */
#define PKG_SYSTEM 1
/* A flag that denotes that a Java package which might contain sub-packages
that are not pre-defined at initialization time, because the sub-packages
may not be the same in all installations. Therefore, an access to a simple
name within such a a package which does not correspond to either a
pre-defined sub-package or to a class, must be assummed to refer to an
unknown sub-package. This behavior may cause bogus JavaPackage objects to be
created if a package name is misspelled, e.g. sun.oi.net. */
#define PKG_USER 2
/* A Java package defined at initialization time. */
typedef struct JavaPackageDef {
const char * name; /* e.g. "java.lang" */
const char * path; /* e.g. "java/lang", or NULL for default */
int flags; /* PKG_USER, PKG_SYSTEM, etc. */
} JavaPackageDef;
/*===========================================================================*/
/* The following two convenience functions present a complete, but simplified
LiveConnect API which is designed to handle the special case of a single
Java-VM, with single-threaded operation, and the use of only one JSContext.
The full API is in the section below. */
/* Initialize the provided JSContext by setting up the JS classes necessary for
reflection and by defining JavaPackage objects for the default Java packages
as properties of global_obj. If java_vm is NULL, a new Java VM is
created, using the provided classpath in addition to any default classpath.
The classpath argument is ignored, however, if java_vm is non-NULL. */
PR_IMPLEMENT(JSBool)
JSJ_SimpleInit(JSContext *cx, JSObject *global_obj,
SystemJavaVM *java_vm, const char *classpath);
/* Free up all resources. Destroy the Java VM if it was created by LiveConnect */
PR_IMPLEMENT(void)
JSJ_SimpleShutdown();
/*===========================================================================*/
/* The "full" LiveConnect API, required when more than one thread, Java VM, or
JSContext is involved. Initialization pseudocode might go roughly like
this:
JSJ_Init() // Setup callbacks
for each JavaVM {
JSJ_ConnectToJavaVM(...)
}
for each JSContext {
JSJ_InitJSContext(...)
}
for each JS evaluation {
run JavaScript code in the JSContext;
}
*/
/* Called once for all instances of LiveConnect to set up callbacks */
PR_IMPLEMENT(void)
JSJ_Init(JSJCallbacks *callbacks);
/* Called once per Java VM, this function initializes the classes, fields, and
methods required for Java reflection. If java_vm is NULL, a new Java VM is
created according to the create_java_vm callback in the JSJCallbacks,
using the provided classpath in addition to any default initargs.
The initargs argument is ignored, however, if java_vm is non-NULL. */
PR_IMPLEMENT(JSJavaVM *)
JSJ_ConnectToJavaVM(SystemJavaVM *java_vm, void* initargs);
/* Initialize the provided JSContext by setting up the JS classes necessary for
reflection and by defining JavaPackage objects for the default Java packages
as properties of global_obj. Additional packages may be pre-defined by
setting the predefined_packages argument. (Pre-defining a Java package at
initialization time is not necessary, but it will make package lookup faster
and, more importantly, will avoid unnecessary network accesses if classes
are being loaded over the network.) */
PR_IMPLEMENT(JSBool)
JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
JavaPackageDef *predefined_packages);
/* This function returns a structure that encapsulates the Java and JavaScript
execution environment for the current native thread. It is intended to
be called from the embedder's implementation of JSJCallback's
map_js_context_to_jsj_thread() function. The thread_name argument is only
used for debugging purposes and can be set to NULL. The Java JNI
environment associated with this thread is returned through the java_envp
argument if java_envp is non-NULL. */
PR_IMPLEMENT(JSJavaThreadState *)
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *thread_name,
JNIEnv **java_envp);
/* Destructor routine for per-thread JSJavaThreadState structure */
PR_IMPLEMENT(JSBool)
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env);
/* This function is used to specify a particular JSContext as *the* JavaScript
execution environment to be used when LiveConnect is accessed from the given
Java thread, i.e. when one of the methods of netscape.javascript.JSObject
has been called. There can only be one such JS context for any given Java
thread at a time. (To multiplex JSContexts among a single thread, this
function could be called before Java is invoked on that thread.) The return
value is the previous JSContext associated with the given Java thread.
If this function has not been called for a thread and a crossing is made
into JavaScript from Java, the map_jsj_thread_to_js_context() callback will
be invoked to determine the JSContext for the thread. The purpose of the
function is to improve performance by avoiding the expense of the callback.
*/
PR_IMPLEMENT(JSContext *)
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env);
/* This routine severs the connection to a Java VM, freeing all related resources.
It shouldn't be called until the global scope has been cleared in all related
JSContexts (so that all LiveConnect objects are finalized) and a JavaScript
GC is performed. Otherwise, accessed to free'ed memory could result. */
PR_IMPLEMENT(void)
JSJ_DisconnectFromJavaVM(JSJavaVM *);
/*
* Reflect a Java object into a JS value. The source object, java_obj, must
* be of type java.lang.Object or a subclass and may, therefore, be an array.
*/
PR_IMPLEMENT(JSBool)
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp);
PR_END_EXTERN_C
#endif /* _JSJAVA_H */

View File

@@ -0,0 +1,182 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
IGNORE_MANIFEST=1
#//------------------------------------------------------------------------
#//
#// Makefile to build the Java reflections of JavaScript objects
#//
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
#//
#// Specify the depth of the current directory relative to the
#// root of NS
#//
#//------------------------------------------------------------------------
DEPTH= ..\..\..
include <$(DEPTH)/config/config.mak>
!ifdef NSJVM
DIRS = classes
!endif
#//------------------------------------------------------------------------
#//
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
#//
#//------------------------------------------------------------------------
DLLNAME=jsj$(MOZ_BITS)$(VERSION_NUMBER)
PDBFILE=$(DLLNAME).pdb
MAPFILE = $(DLLNAME).map
RESFILE = jsj1640.res
DLL=.\$(OBJDIR)\$(DLLNAME).dll
MAKE_OBJ_TYPE = DLL
!if "$(MOZ_BITS)" == "16"
DEFFILE = $(DLLNAME).def
!endif
LLIBS=$(LIBNSPR) $(DIST)\lib\js$(MOZ_BITS)$(VERSION_NUMBER).lib \
$(DIST)\lib\xpcom32.lib
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
!endif
#//------------------------------------------------------------------------
#//
#// Define the files necessary to build the target (ie. OBJS)
#//
#//------------------------------------------------------------------------
OBJS= \
.\$(OBJDIR)\jsj.obj \
.\$(OBJDIR)\jsj_JSObject.obj \
.\$(OBJDIR)\jsj_JavaArray.obj \
.\$(OBJDIR)\jsj_JavaClass.obj \
.\$(OBJDIR)\jsj_JavaMember.obj \
.\$(OBJDIR)\jsj_JavaObject.obj \
.\$(OBJDIR)\jsj_JavaPackage.obj \
.\$(OBJDIR)\jsj_array.obj \
.\$(OBJDIR)\jsj_class.obj \
.\$(OBJDIR)\jsj_convert.obj \
.\$(OBJDIR)\jsj_field.obj \
.\$(OBJDIR)\jsj_hash.obj \
.\$(OBJDIR)\jsj_method.obj \
.\$(OBJDIR)\jsj_utils.obj \
.\$(OBJDIR)\nsCLiveconnect.obj \
.\$(OBJDIR)\nsCLiveconnectFactory.obj \
!if "$(MOZ_BITS)" == "16"
.\$(OBJDIR)\jsj_nodl.obj \
!endif
$(NULL)
#//------------------------------------------------------------------------
#//
#// install headers
#//
#//------------------------------------------------------------------------
INSTALL_DIR=$(PUBLIC)\js
INSTALL_FILE_LIST= \
jsjava.h nsILiveconnect.h
#//------------------------------------------------------------------------
#//
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
#// (these must be defined before the common makefiles are included)
#//
#//------------------------------------------------------------------------
!ifdef NSJVM
JNI_GEN= \
netscape.javascript.JSObject \
netscape.javascript.JSException \
$(NULL)
!endif
MODULE = java
EXPORTS = \
$(JNI_GEN_DIR)\netscape_javascript_JSObject.h \
$(JNI_GEN_DIR)\netscape_javascript_JSException.h \
$(NULL)
#//------------------------------------------------------------------------
#//
#// Define any local options for the make tools
#// (ie. LCFLAGS, LLFLAGS, LLIBS, LINCS)
#//
#//------------------------------------------------------------------------
LINCS=$(LINCS) -I$(JNI_GEN_DIR) \
-I$(PUBLIC)\js \
-I$(PUBLIC)\java \
-I$(PUBLIC)\xpcom \
$(NULL)
#!ifdef SERVER_BUILD
#LLIBS=$(DIST)/lib/httpdlw.lib $(DIST)/lib/libsjboot.lib
#!endif
#//------------------------------------------------------------------------
#//
#// Include the common makefile rules
#//
#//------------------------------------------------------------------------
include <$(DEPTH)/config/rules.mak>
export:: INSTALL_FILES
libs:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
####
# this bit of extreme scariness came from the js/src makefile
# reproduced here since that's where jsjava.c lives now...
!if ("$(MOZ_BITS)" == "16")
#//
#// Win16 Hoovers SO BAD!!!
#//
!if !defined(MOZ_DEBUG)
#//
#// We must turn off codeview debug info so jni.c can build.
#// Otherwise the linker gives errors about data in the $SYMBOLS
#// segment being beyond a segment boundary.
#//
$(OBJDIR)\jsjava.obj: jsjava.c
@$(CC) @<<$(CFGFILE)
-c
-Od
$(CFLAGS)
$(LCFLAGS)
$(LINCS)
$(LINCS_1)
$(INCS)
-Fd$(PDBFILE)
-Fo.\$(OBJDIR)\
$(*B).c
<<KEEP
!endif
!endif

View File

@@ -0,0 +1,111 @@
/* -*- Mode: C; tab-width: 8 -*-
* Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved.
*/
#include <jni.h>
/* Header for class netscape_javascript_JSObject */
#ifndef _Included_netscape_javascript_JSObject
#define _Included_netscape_javascript_JSObject
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: netscape_javascript_JSObject
* Method: initClass
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_initClass
(JNIEnv *, jclass);
/*
* Class: netscape_javascript_JSObject
* Method: getMember
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getMember
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: getSlot
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getSlot
(JNIEnv *, jobject, jint);
/*
* Class: netscape_javascript_JSObject
* Method: setMember
* Signature: (Ljava/lang/String;Ljava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setMember
(JNIEnv *, jobject, jstring, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: setSlot
* Signature: (ILjava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setSlot
(JNIEnv *, jobject, jint, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: removeMember
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_removeMember
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: call
* Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_call
(JNIEnv *, jobject, jstring, jobjectArray);
/*
* Class: netscape_javascript_JSObject
* Method: eval
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_eval
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: toString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_netscape_javascript_JSObject_toString
(JNIEnv *, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: getWindow
* Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getWindow
(JNIEnv *, jclass, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: finalize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize
(JNIEnv *, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: equals
* Signature: (Ljava/lang/Object;)Z
*/
JNIEXPORT jboolean JNICALL Java_netscape_javascript_JSObject_equals
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,567 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the implementation providing nsIFactory XP-COM interface.
*
*/
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
#include "prprf.h"
#include "prlog.h"
PR_BEGIN_EXTERN_C
#ifdef XP_MAC
#include "prosdep.h"
#endif
#include "jsj_private.h"
#include "jsjava.h"
#include "jscntxt.h" /* For js_ReportErrorAgain().
TODO - get rid of private header */
#include "netscape_javascript_JSObject.h" /* javah-generated headers */
/* A captured JavaScript error, created when JS_ReportError() is called while
running JavaScript code that is itself called from Java. */
struct CapturedJSError {
char * message;
JSErrorReport report; /* Line # of error, etc. */
jthrowable java_exception; /* Java exception, error, or null */
CapturedJSError * next; /* Next oldest captured JS error */
};
PR_END_EXTERN_C
#include "nsCLiveconnect.h"
static NS_DEFINE_IID(kILiveconnectIID, NS_ILIVECONNECT_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
////////////////////////////////////////////////////////////////////////////
// from nsISupports and AggregatedQueryInterface:
// Thes macro expands to the aggregated query interface scheme.
NS_IMPL_AGGREGATED(nsCLiveconnect);
NS_METHOD
nsCLiveconnect::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = GetInner();
AddRef();
return NS_OK;
}
if (aIID.Equals(kILiveconnectIID)) {
*aInstancePtr = this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
////////////////////////////////////////////////////////////////////////////
// from nsILiveconnect:
/**
* get member of a Native JSObject for a given name.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
* @param name - Name of a member.
* @param pjobj - return parameter as a java object representing
* the member. If it is a basic data type it is converted to
* a corresponding java type. If it is a NJSObject, then it is
* wrapped up as java wrapper netscape.javascript.JSObject.
*/
NS_METHOD
nsCLiveconnect::GetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject *pjobj)
{
JSContext *cx = NULL;
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
nsresult err = NS_OK;
jobject member = NULL;
jsval js_val = NULL;
int dummy_cost = 0;
JSBool dummy_bool = PR_FALSE;
JavaToJSSavedState saved_state = {NULL,NULL};
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NS_ERROR_FAILURE;
if (!name) {
JS_ReportError(cx, "illegal null member name");
member = NULL;
goto done;
}
if (!JS_GetProperty(cx, js_obj, name, &js_val))
goto done;
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
&dummy_cost, &member, &dummy_bool);
done:
if (!jsj_exit_js(cx, jsj_env, &saved_state))
return NS_ERROR_FAILURE;
*pjobj = member;
return NS_OK;
}
/**
* get member of a Native JSObject for a given index.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
* @param index - Index of a member.
* @param pjobj - return parameter as a java object representing
* the member.
*/
NS_METHOD
nsCLiveconnect::GetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject *pjobj)
{
JSContext *cx = NULL;
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
nsresult err = NS_OK;
jobject member = NULL;
jsval js_val = NULL;
int dummy_cost = 0;
JSBool dummy_bool = PR_FALSE;
JavaToJSSavedState saved_state = {NULL,NULL};
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NS_ERROR_FAILURE;
// =-= sudu: check to see if slot can be passed in as is.
// Should it be converted to a jsint?
if (!JS_GetElement(cx, js_obj, slot, &js_val))
goto done;
if (!jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
&dummy_cost, &member, &dummy_bool))
goto done;
done:
if (!jsj_exit_js(cx, jsj_env, &saved_state))
return NS_ERROR_FAILURE;
*pjobj = member;
return NS_OK;
}
/**
* set member of a Native JSObject for a given name.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
* @param name - Name of a member.
* @param jobj - Value to set. If this is a basic data type, it is converted
* using standard JNI calls but if it is a wrapper to a JSObject
* then a internal mapping is consulted to convert to a NJSObject.
*/
NS_METHOD
nsCLiveconnect::SetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject java_obj)
{
JSContext *cx = NULL;
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
nsresult err = NS_OK;
jobject member = NULL;
jsval js_val = NULL;
JavaToJSSavedState saved_state = {NULL,NULL};
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NS_ERROR_FAILURE;
if (!name) {
JS_ReportError(cx, "illegal null member name");
goto done;
}
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
goto done;
JS_SetProperty(cx, js_obj, name, &js_val);
done:
jsj_exit_js(cx, jsj_env, &saved_state);
return NS_OK;
}
/**
* set member of a Native JSObject for a given index.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
* @param index - Index of a member.
* @param jobj - Value to set. If this is a basic data type, it is converted
* using standard JNI calls but if it is a wrapper to a JSObject
* then a internal mapping is consulted to convert to a NJSObject.
*/
NS_METHOD
nsCLiveconnect::SetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject java_obj)
{
JSContext *cx = NULL;
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
nsresult err = NS_OK;
jsval js_val = NULL;
JavaToJSSavedState saved_state = {NULL,NULL};
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NS_ERROR_FAILURE;
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
goto done;
JS_SetElement(cx, js_obj, slot, &js_val);
done:
jsj_exit_js(cx, jsj_env, &saved_state);
return NS_OK;
}
/**
* remove member of a Native JSObject for a given name.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
* @param name - Name of a member.
*/
NS_METHOD
nsCLiveconnect::RemoveMember(JNIEnv *jEnv, jsobject obj, const char *name)
{
JSContext *cx = NULL;
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
nsresult err = NS_OK;
jsval js_val = NULL;
JavaToJSSavedState saved_state = {NULL,NULL};
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NS_ERROR_FAILURE;
if (!name) {
JS_ReportError(cx, "illegal null member name");
goto done;
}
JS_DeleteProperty2(cx, js_obj, name, &js_val);
done:
jsj_exit_js(cx, jsj_env, &saved_state);
return NS_OK;
}
/**
* call a method of Native JSObject.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
* @param name - Name of a method.
* @param jobjArr - Array of jobjects representing parameters of method being caled.
* @param pjobj - return value.
*/
NS_METHOD
nsCLiveconnect::Call(JNIEnv *jEnv, jsobject obj, const char *name, jobjectArray java_args, jobject *pjobj)
{
int i = 0;
int argc = 0;
int arg_num = 0;
jsval *argv = 0;
JSContext *cx = NULL;
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
nsresult err = NS_OK;
jobject member = NULL;
jsval js_val = NULL;
jsval function_val = NULL;
int dummy_cost = 0;
JSBool dummy_bool = PR_FALSE;
JavaToJSSavedState saved_state = {NULL,NULL};
jobject result = NULL;
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NS_ERROR_FAILURE;
result = NULL;
if (!name) {
JS_ReportError(cx, "illegal null JavaScript function name");
goto done;
}
/* FIXME: What about security stuff ? Don't principals need to be set here ? */
/* Allocate space for JS arguments */
if (java_args) {
argc = jEnv->GetArrayLength(java_args);
argv = (jsval*)JS_malloc(cx, argc * sizeof(jsval));
} else {
argc = 0;
argv = 0;
}
/* Convert arguments from Java to JS values */
for (arg_num = 0; arg_num < argc; arg_num++) {
jobject arg = jEnv->GetObjectArrayElement(java_args, arg_num);
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, arg, &argv[arg_num]))
goto cleanup_argv;
JS_AddRoot(cx, &argv[arg_num]);
}
if (!JS_GetProperty(cx, js_obj, name, &function_val))
goto cleanup_argv;
if (!JS_CallFunctionValue(cx, js_obj, function_val, argc, argv, &js_val))
goto cleanup_argv;
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
&dummy_cost, &result, &dummy_bool);
cleanup_argv:
if (argv) {
for (i = 0; i < arg_num; i++)
JS_RemoveRoot(cx, &argv[i]);
JS_free(cx, argv);
}
done:
if (!jsj_exit_js(cx, jsj_env, &saved_state))
return NS_ERROR_FAILURE;
*pjobj = result;
return NS_OK;
}
/**
* Evaluate a script with a Native JS Object representing scope.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
* @param pNSIPrincipaArray - Array of principals to be used to compare privileges.
* @param numPrincipals - Number of principals being passed.
* @param script - Script to be executed.
* @param pjobj - return value.
*/
NS_METHOD
nsCLiveconnect::Eval(JNIEnv *jEnv, jsobject obj, const char *script, jobject *pjobj)
{
JSContext *cx = NULL;
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
nsresult err = NS_OK;
jobject member = NULL;
jsval js_val = NULL;
jsval function_val = NULL;
int dummy_cost = 0;
JSBool dummy_bool = PR_FALSE;
JavaToJSSavedState saved_state = {NULL,NULL};
jobject result = NULL;
const char *codebase = NULL;
JSPrincipals *principals = NULL;
JSBool eval_succeeded = PR_FALSE;
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NULL;
result = NULL;
if (!script) {
JS_ReportError(cx, "illegal null string eval argument");
goto done;
}
/* Set up security stuff */
principals = NULL;
if (JSJ_callbacks->get_JSPrincipals_from_java_caller)
principals = JSJ_callbacks->get_JSPrincipals_from_java_caller(jEnv, cx);
codebase = principals ? principals->codebase : NULL;
/* Have the JS engine evaluate the unicode string */
eval_succeeded = JS_EvaluateScriptForPrincipals(cx, js_obj, principals,
script, strlen(script),
codebase, 0, &js_val);
if (!eval_succeeded)
goto done;
/* Convert result to a subclass of java.lang.Object */
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
&dummy_cost, &result, &dummy_bool);
done:
if (!jsj_exit_js(cx, jsj_env, &saved_state))
return NULL;
*pjobj = result;
return NS_OK;
}
/**
* Get the window object for a plugin instance.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param pJavaObject - Either a jobject or a pointer to a plugin instance
* representing the java object.
* @param pjobj - return value. This is a native js object
* representing the window object of a frame
* in which a applet/bean resides.
*/
NS_METHOD
nsCLiveconnect::GetWindow(JNIEnv *jEnv, void *pJavaObject, jsobject *pobj)
{
char *err_msg = NULL;
JSContext *cx = NULL;
JSObject *js_obj = NULL;
jsval js_val = NULL;
int dummy_cost = 0;
JSBool dummy_bool = PR_FALSE;
JavaToJSSavedState saved_state = {NULL,NULL};
jobject java_obj = NULL;
JSJavaThreadState *jsj_env = NULL;
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env)
return NULL;
err_msg = NULL;
java_obj = NULL;
js_obj = JSJ_callbacks->map_java_object_to_js_object(jEnv, pJavaObject, &err_msg);
if (!js_obj) {
if (err_msg) {
JS_ReportError(cx, err_msg);
free(err_msg);
}
goto done;
}
#if 0
js_val = OBJECT_TO_JSVAL(js_obj);
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
&dummy_cost, &java_obj, &dummy_bool);
#endif
done:
if (!jsj_exit_js(cx, jsj_env, &saved_state))
return NULL;
//*pjobj = java_obj;
*pobj = (jint)js_obj;
return NS_OK;
}
/**
* Get the window object for a plugin instance.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
*/
NS_METHOD
nsCLiveconnect::FinalizeJSObject(JNIEnv *jEnv, jsobject obj)
{
JSContext *cx = NULL;
JavaToJSSavedState saved_state = {NULL,NULL};
JSJavaThreadState *jsj_env = NULL;
JSObject *js_obj = (JSObject *)obj;
if(jEnv == NULL)
{
return NS_ERROR_FAILURE;
}
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
if (!jsj_env) /* Note: memory leak if we exit here */
return NS_ERROR_FAILURE;
#ifdef PRESERVE_JSOBJECT_IDENTITY
jsj_remove_js_obj_reflection_from_hashtable(cx, js_obj);
#endif /* PRESERVE_JSOBJECT_IDENTITY */
jsj_exit_js(cx, jsj_env, &saved_state);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////
// from nsCLiveconnect:
nsCLiveconnect::nsCLiveconnect(nsISupports *aOuter)
{
NS_INIT_AGGREGATED(aOuter);
jsj_init_js_obj_reflections_table();
}
nsCLiveconnect::~nsCLiveconnect()
{
}

View File

@@ -0,0 +1,166 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains class definition implementing the public interface.
*
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the class definition to implement nsILiveconnect XP-COM interface.
*
*/
#ifndef nsCLiveconnect_h___
#define nsCLiveconnect_h___
#include "nsILiveconnect.h"
#include "nsAgg.h"
/**
* nsCLiveconnect implements nsILiveconnect interface for navigator.
* This is used by a JVM to implement netscape.javascript.JSObject functionality.
*/
class nsCLiveconnect :public nsILiveconnect {
public:
////////////////////////////////////////////////////////////////////////////
// from nsISupports and AggregatedQueryInterface:
NS_DECL_AGGREGATED
////////////////////////////////////////////////////////////////////////////
// from nsILiveconnect:
/**
* get member of a Native JSObject for a given name.
*
* @param obj - A Native JS Object.
* @param name - Name of a member.
* @param pjobj - return parameter as a java object representing
* the member. If it is a basic data type it is converted to
* a corresponding java type. If it is a NJSObject, then it is
* wrapped up as java wrapper netscape.javascript.JSObject.
*/
NS_IMETHOD
GetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject *pjobj);
/**
* get member of a Native JSObject for a given index.
*
* @param obj - A Native JS Object.
* @param index - Index of a member.
* @param pjobj - return parameter as a java object representing
* the member.
*/
NS_IMETHOD
GetSlot(JNIEnv *jEnv, jsobject obj, int index, jobject *pjobj);
/**
* set member of a Native JSObject for a given name.
*
* @param obj - A Native JS Object.
* @param name - Name of a member.
* @param jobj - Value to set. If this is a basic data type, it is converted
* using standard JNI calls but if it is a wrapper to a JSObject
* then a internal mapping is consulted to convert to a NJSObject.
*/
NS_IMETHOD
SetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject jobj);
/**
* set member of a Native JSObject for a given index.
*
* @param obj - A Native JS Object.
* @param index - Index of a member.
* @param jobj - Value to set. If this is a basic data type, it is converted
* using standard JNI calls but if it is a wrapper to a JSObject
* then a internal mapping is consulted to convert to a NJSObject.
*/
NS_IMETHOD
SetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject jobj);
/**
* remove member of a Native JSObject for a given name.
*
* @param obj - A Native JS Object.
* @param name - Name of a member.
*/
NS_IMETHOD
RemoveMember(JNIEnv *jEnv, jsobject obj, const char *name);
/**
* call a method of Native JSObject.
*
* @param obj - A Native JS Object.
* @param name - Name of a method.
* @param jobjArr - Array of jobjects representing parameters of method being caled.
* @param pjobj - return value.
*/
NS_IMETHOD
Call(JNIEnv *jEnv, jsobject obj, const char *name, jobjectArray jobjArr, jobject *pjobj);
/**
* Evaluate a script with a Native JS Object representing scope.
*
* @param obj - A Native JS Object.
* @param pNSIPrincipaArray - Array of principals to be used to compare privileges.
* @param numPrincipals - Number of principals being passed.
* @param script - Script to be executed.
* @param pjobj - return value.
*/
NS_IMETHOD
//Eval(JNIEnv *jEnv, jsobject obj, nsIPrincipal **pNSIPrincipaArray, PRInt32 numPrincipals, const char *script, jobject *pjobj);
Eval(JNIEnv *jEnv, jsobject obj, const char *script, jobject *pjobj);
/**
* Get the window object for a plugin instance.
*
* @param pJavaObject - Either a jobject or a pointer to a plugin instance
* representing the java object.
* @param pjobj - return value. This is a native js object
* representing the window object of a frame
* in which a applet/bean resides.
*/
NS_IMETHOD
GetWindow(JNIEnv *jEnv, void *pJavaObject, jsobject *pobj);
/**
* Get the window object for a plugin instance.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
*/
NS_IMETHOD
FinalizeJSObject(JNIEnv *jEnv, jsobject obj);
////////////////////////////////////////////////////////////////////////////
// from nsCLiveconnect:
nsCLiveconnect(nsISupports *aOuter);
virtual ~nsCLiveconnect(void);
protected:
};
#endif // nsCLiveconnect_h___

View File

@@ -0,0 +1,168 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the implementation providing nsILiveconnect XP-COM interface.
*
*/
#include "prtypes.h"
#include "nspr.h"
#include "prmem.h"
#include "prmon.h"
#include "prlog.h"
#include "nsCLiveconnect.h"
#include "nsCLiveconnectFactory.h"
#include "nsRepository.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kCLiveconnectCID, NS_CLIVECONNECT_CID);
static NS_DEFINE_IID(kILiveconnectIID, NS_ILIVECONNECT_IID);
nsIFactory *nsCLiveconnectFactory::m_pNSIFactory = NULL;
nsCLiveconnect *nsCLiveconnectFactory::m_pNSCLiveconnect = NULL;
/*+++++++++++++++++++++++++++++++++++++++++++++++++
* NSGetFactory:
* Provides entry point to liveconnect dll.
+++++++++++++++++++++++++++++++++++++++++++++++++*/
extern "C" NS_EXPORT nsresult
NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
{
if (!aClass.Equals(kCLiveconnectCID)) {
return NS_ERROR_FACTORY_NOT_LOADED; // XXX right error?
}
nsCLiveconnectFactory* pCLiveConnectFactory = new nsCLiveconnectFactory();
if (pCLiveConnectFactory == NULL)
return NS_ERROR_OUT_OF_MEMORY;
pCLiveConnectFactory->AddRef();
*aFactory = pCLiveConnectFactory;
return NS_OK;
}
extern "C" NS_EXPORT PRBool
NSCanUnload(void)
{
return PR_FALSE;
}
////////////////////////////////////////////////////////////////////////////
// from nsISupports
NS_METHOD
nsCLiveconnectFactory::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
PR_ASSERT(NULL != aInstancePtr);
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIFactoryIID) ||
aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsCLiveconnectFactory)
NS_IMPL_RELEASE(nsCLiveconnectFactory)
////////////////////////////////////////////////////////////////////////////
// from nsIFactory:
NS_METHOD
nsCLiveconnectFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
nsCLiveconnect *pNSCLiveconnect = NULL;
*aResult = NULL;
if (aOuter && !aIID.Equals(kISupportsIID))
return NS_NOINTERFACE; // XXX right error?
if (m_pNSCLiveconnect == NULL)
{
m_pNSCLiveconnect = new nsCLiveconnect(aOuter);
}
if (m_pNSCLiveconnect == NULL)
{
return NS_ERROR_FAILURE;
}
if (m_pNSCLiveconnect->QueryInterface(aIID,
(void**)aResult) != NS_OK) {
// then we're trying get a interface other than nsISupports and
// nsICapsManager
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_METHOD
nsCLiveconnectFactory::LockFactory(PRBool aLock)
{
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////
// from nsCLiveconnectFactory:
nsCLiveconnectFactory::nsCLiveconnectFactory(void)
{
if( m_pNSIFactory != NULL)
{
return;
}
NS_INIT_REFCNT();
nsresult err = NS_OK;
NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
err = this->QueryInterface(kIFactoryIID, (void**)&m_pNSIFactory);
if ( (err == NS_OK) && (m_pNSIFactory != NULL) )
{
NS_DEFINE_CID(kCLiveconnectCID, NS_CLIVECONNECT_CID);
nsRepository::RegisterFactory(kCLiveconnectCID, m_pNSIFactory,
PR_FALSE);
}
}
nsCLiveconnectFactory::~nsCLiveconnectFactory()
{
if(mRefCnt == 0)
{
NS_DEFINE_CID(kCLiveconnectCID, NS_CLIVECONNECT_CID);
nsRepository::UnregisterFactory(kCLiveconnectCID, (nsIFactory *)m_pNSIFactory);
}
}

View File

@@ -0,0 +1,59 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the class definition to implement nsIFactory XP-COM interface.
*
*/
#ifndef nsCLiveconnectFactory_h___
#define nsCLiveconnectFactory_h___
#include "nsISupports.h"
#include "nsIFactory.h"
class nsCLiveconnectFactory : public nsIFactory {
public:
////////////////////////////////////////////////////////////////////////////
// from nsISupports and AggregatedQueryInterface:
NS_DECL_ISUPPORTS
////////////////////////////////////////////////////////////////////////////
// from nsIFactory:
NS_IMETHOD
CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult);
NS_IMETHOD
LockFactory(PRBool aLock);
////////////////////////////////////////////////////////////////////////////
// from nsCLiveconnectFactory:
nsCLiveconnectFactory(void);
virtual ~nsCLiveconnectFactory(void);
protected:
static nsIFactory *m_pNSIFactory;
static nsCLiveconnect *m_pNSCLiveconnect;
};
#endif // nsCLiveconnectFactory_h___

View File

@@ -0,0 +1,157 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the public XP-COM based interface for java to javascript communication.
*
*/
#ifndef nsILiveconnect_h___
#define nsILiveconnect_h___
#include "nsISupports.h"
#include "nsIFactory.h"
#include "jni.h"
typedef jint jsobject;
class nsILiveconnect : public nsISupports {
public:
/**
* get member of a Native JSObject for a given name.
*
* @param obj - A Native JS Object.
* @param name - Name of a member.
* @param pjobj - return parameter as a java object representing
* the member. If it is a basic data type it is converted to
* a corresponding java type. If it is a NJSObject, then it is
* wrapped up as java wrapper netscape.javascript.JSObject.
*/
NS_IMETHOD
GetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject *pjobj) = 0;
/**
* get member of a Native JSObject for a given index.
*
* @param obj - A Native JS Object.
* @param index - Index of a member.
* @param pjobj - return parameter as a java object representing
* the member.
*/
NS_IMETHOD
GetSlot(JNIEnv *jEnv, jsobject obj, int index, jobject *pjobj) = 0;
/**
* set member of a Native JSObject for a given name.
*
* @param obj - A Native JS Object.
* @param name - Name of a member.
* @param jobj - Value to set. If this is a basic data type, it is converted
* using standard JNI calls but if it is a wrapper to a JSObject
* then a internal mapping is consulted to convert to a NJSObject.
*/
NS_IMETHOD
SetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject jobj) = 0;
/**
* set member of a Native JSObject for a given index.
*
* @param obj - A Native JS Object.
* @param index - Index of a member.
* @param jobj - Value to set. If this is a basic data type, it is converted
* using standard JNI calls but if it is a wrapper to a JSObject
* then a internal mapping is consulted to convert to a NJSObject.
*/
NS_IMETHOD
SetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject jobj) = 0;
/**
* remove member of a Native JSObject for a given name.
*
* @param obj - A Native JS Object.
* @param name - Name of a member.
*/
NS_IMETHOD
RemoveMember(JNIEnv *jEnv, jsobject obj, const char *name) = 0;
/**
* call a method of Native JSObject.
*
* @param obj - A Native JS Object.
* @param name - Name of a method.
* @param jobjArr - Array of jobjects representing parameters of method being caled.
* @param pjobj - return value.
*/
NS_IMETHOD
Call(JNIEnv *jEnv, jsobject obj, const char *name, jobjectArray jobjArr, jobject *pjobj) = 0;
/**
* Evaluate a script with a Native JS Object representing scope.
*
* @param obj - A Native JS Object.
* @param pNSIPrincipaArray - Array of principals to be used to compare privileges.
* @param numPrincipals - Number of principals being passed.
* @param script - Script to be executed.
* @param pjobj - return value.
*/
NS_IMETHOD
//Eval(jsobject obj, nsIPrincipal **pNSIPrincipaArray, PRInt32 numPrincipals, const char *script, jobject *pjobj) = 0;
Eval(JNIEnv *jEnv, jsobject obj, const char *script, jobject *pjobj) = 0;
/**
* Get the window object for a plugin instance.
*
* @param pJavaObject - Either a jobject or a pointer to a plugin instance
* representing the java object.
* @param pjobj - return value. This is a native js object
* representing the window object of a frame
* in which a applet/bean resides.
*/
NS_IMETHOD
GetWindow(JNIEnv *jEnv, void *pJavaObject, jsobject *pobj) = 0;
/**
* Get the window object for a plugin instance.
*
* @param jEnv - JNIEnv on which the call is being made.
* @param obj - A Native JS Object.
*/
NS_IMETHOD
FinalizeJSObject(JNIEnv *jEnv, jsobject obj) = 0;
};
#define NS_ILIVECONNECT_IID \
{ /* 68190910-3318-11d2-97f0-00805f8a28d0 */ \
0x68190910, \
0x3318, \
0x11d2, \
{0x97, 0xf0, 0x00, 0x80, 0x5f, 0x8a, 0x28, 0xd0} \
};
#define NS_CLIVECONNECT_CID \
{ /* b8f0cef0-3931-11d2-97f0-00805f8a28d0 */ \
0xb8f0cef0, \
0x3931, \
0x11d2, \
{0x97, 0xf0, 0x00, 0x80, 0x5f, 0x8a, 0x28, 0xd0} \
};
#endif // nsILiveconnect_h___

View File

@@ -1,40 +0,0 @@
#
# 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 = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = $(PNGDIR) $(MNGDIR) public public_com src gifcom pngcom mngcom jpgcom
ifndef MOZ_NATIVE_PNG
PNGDIR = png
endif
ifndef MOZ_NATIVE_MNG
MNGDIR = mng
endif
include $(topsrcdir)/config/rules.mk

View File

@@ -1,36 +0,0 @@
Imglib Decoders as Components:
Basic description:
I have 4 new subdirectories to make below mozilla/modules/libimg.
Some of the files in mozilla/modules/libimg/src and libimg/public
have been moved to one of the new directories or 'retired'.
I have new exports in libimg/public and libimg/public_com.
I have a few new files that should go into the new directories.
------------------------------
The old structure:
libimg/
/src
/public
/png
------------------------------
The new structure:
libimg/
/src
new:
old
/public
/public_com
/gifcom
/jpgcom
/pngcom
------------------------------
******************************************************

View File

@@ -1,51 +0,0 @@
#
# 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 = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = nsgif
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
REQUIRES = xpcom string img layout locale util unicharutil
CPPSRCS = \
gif.cpp \
nsGIFModule.cpp \
nsGIFDecoder.cpp \
$(NULL)
LOCAL_INCLUDES = -I$(srcdir)
EXTRA_LIBS = $(NSPR_LIBS)
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
ifndef MOZ_JAVA
LOCAL_JMC_SUBDIR = .
endif
include $(topsrcdir)/config/rules.mk

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +0,0 @@
/* -*- 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):
*/
/* gif.h */
extern PRBool il_gif_init(il_container *ic);
extern int il_gif_write(il_container *, const PRUint8 *, int32);
extern void il_gif_complete(il_container *ic);
extern PRUint8 il_gif_write_ready(il_container *ic);
extern void il_gif_abort(il_container *ic);
extern void gif_delay_time_callback(void *closure);

View File

@@ -1,98 +0,0 @@
#!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):
#
#------------------------------------------------------------------------
#
# Makefile to build the IMGLIB LIB
#
#------------------------------------------------------------------------
!ifdef MOZ_JAVA
LOCAL_JMC_SUBDIR = .
!endif
LIBRARY_NAME = nsgif
#
# Make sure we have MOZILLA_CLIENT defined so we get the
# proper JS includes
#
LCFLAGS = $(LCFLAGS) -DMOZILLA_CLIENT
!ifdef BUILD_DEBUG_GC
LCFLAGS = $(LCFLAGS) -DDEBUG_GC
!endif
LCFLAGS = $(LCFLAGS) /TP
LLIBS= $(LIBNSPR) \
$(DIST)\lib\util.lib \
$(DIST)\lib\xpcom.lib \
!ifdef NU_CACHE
$(DIST)\lib\cache.lib \
!endif
$(NULL)
LIBRARY= .\$(OBJDIR)\$(LIBNAME).lib
LIBRARY_SUFFIX = $(MOZ_BITS)$(VERSION_NUMBER)
MAKE_OBJ_TYPE=DLL
#//------------------------------------------------------------------------
#//
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
#//
#//------------------------------------------------------------------------
DLLNAME=nsgif
DLL1NAME=nsgif
PDBFILE=$(DLLNAME).pdb
MAPFILE=$(DLLNAME).map
DEFFILE=nsgif.def
#//------------------------------------------------------------------------
#//
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
#// (these must be defined before the common makefiles are included)
#//
#//------------------------------------------------------------------------
DLL=.\$(OBJDIR)\$(DLLNAME).dll
MAPFILE= $(DLLNAME).map
MODULE=img
DEPTH=..\..\..
LINCS=-I$(DEPTH)/dist/public/xpcom -I. -I$(DEPTH)/dist/public/raptor
CPPSRCS= nsGIFModule.cpp nsGIFDecoder.cpp gif.cpp
CPP_OBJS= .\$(OBJDIR)\nsGIFModule.obj .\$(OBJDIR)\nsGIFDecoder.obj \
.\$(OBJDIR)\gif.obj
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib

View File

@@ -1,128 +0,0 @@
/* -*- 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.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):
*/
/*
* nsGIFDecoder.cpp --- interface to gif decoder
*/
#include "nsGIFDecoder.h"
#include "nsCOMPtr.h"
//////////////////////////////////////////////////////////////////////
// GIF Decoder Implementation
NS_IMPL_ISUPPORTS1(GIFDecoder, nsIImgDecoder);
GIFDecoder::GIFDecoder(il_container* aContainer)
{
NS_INIT_REFCNT();
ilContainer = aContainer;
}
GIFDecoder::~GIFDecoder(void)
{
}
NS_METHOD
GIFDecoder::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
nsresult rv;
if (aOuter) return NS_ERROR_NO_AGGREGATION;
il_container *ic = new il_container();
if (!ic) return NS_ERROR_OUT_OF_MEMORY;
GIFDecoder *decoder = new GIFDecoder(ic);
if (!decoder) {
delete ic;
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(decoder);
rv = decoder->QueryInterface(aIID, aResult);
NS_RELEASE(decoder);
/* why are we creating and destroying this object for no reason? */
delete ic; /* is a place holder */
return rv;
}
NS_IMETHODIMP
GIFDecoder::ImgDInit()
{
PRBool ret=PR_FALSE;
if(ilContainer != NULL) {
ret=il_gif_init(ilContainer);
}
if(ret)
return NS_OK;
else
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GIFDecoder::ImgDWriteReady(PRUint32 *max_read)
{
if(ilContainer != NULL) {
*max_read = il_gif_write_ready(ilContainer);
}
return NS_OK;
}
NS_IMETHODIMP
GIFDecoder::ImgDWrite(const unsigned char *buf, int32 len)
{
int ret = 0;
if( ilContainer != NULL ) {
ret = il_gif_write(ilContainer, buf,len);
if(ret != 0)
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
GIFDecoder::ImgDComplete()
{
if( ilContainer != NULL ) {
il_gif_complete(ilContainer);
}
return NS_OK;
}
NS_IMETHODIMP
GIFDecoder::ImgDAbort()
{
if( ilContainer != NULL ) {
il_gif_abort(ilContainer);
}
return NS_OK;
}

View File

@@ -1,66 +0,0 @@
/* -*- Mode: C; tab-width: 2; 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.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):
*/
/* -*- Mode: C; tab-width: 4 -*-
* nsGIFDecoder.cpp --- interface to gif decoder
*/
#ifndef _nsGIFDec_h
#define _nsGIFDec_h
#include "nsISupports.h"
#include "nsIImgDecoder.h"
#include "gif.h"
#define NS_GIFDECODER_CID \
{ 0x0d471b70, 0xbaf5, 0x11d2, \
{ 0x80, 0x2c, 0x00, 0x60, 0x08, 0x8f, 0x91, 0xa3 } }
//////////////////////////////////////////////////////////////////////
// GIF Decoder Definition
class GIFDecoder : public nsIImgDecoder
{
public:
GIFDecoder(il_container* aContainer);
virtual ~GIFDecoder();
NS_DECL_ISUPPORTS
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
/* stream */
NS_IMETHOD ImgDInit();
NS_IMETHOD ImgDWriteReady(PRUint32 *max_read);
NS_IMETHOD ImgDWrite(const unsigned char *buf, int32 len);
NS_IMETHOD ImgDComplete();
NS_IMETHOD ImgDAbort();
NS_IMETHOD_(il_container *) SetContainer(il_container *ic){ilContainer = ic; return ic;}
NS_IMETHOD_(il_container *) GetContainer() {return ilContainer;}
private:
il_container* ilContainer;
};
#endif

View File

@@ -1,40 +0,0 @@
/* -*- 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):
*/
#include "nsGIFDecoder.h"
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
static NS_DEFINE_CID(kGIFDecoderCID, NS_GIFDECODER_CID);
static nsModuleComponentInfo components[] =
{
{ "GIF Decoder",
NS_GIFDECODER_CID,
"@mozilla.org/image/decoder;1?type=image/gif",
GIFDecoder::Create }
};
NS_IMPL_NSGETMODULE(nsGIFModule, components)

View File

@@ -1,14 +0,0 @@
;
; temp def file for nsgif dll
;
LIBRARY nsgif.dll
DESCRIPTION 'test dll'
EXPORTS
ImgDInit @1002 PRIVATE
ImgDWrite @1003 PRIVATE
ImgDWriteReady @1004 PRIVATE
ImgDComplete @1005 PRIVATE
ImgDAbort @1006 PRIVATE

View File

@@ -1,21 +0,0 @@
?il_gif_write@@YAHPAUil_container_struct@@PBEJ@Z ; 43937
?il_BACat@@YAPADPAPADIPBDI@Z ; 42718
?gif_delay_time_callback@@YAXPAX@Z ; 41012
?ImgDWrite@GIFDecoder@@UAGIPBEJ@Z ; 2925
?il_gif_write_ready@@YAEPAUil_container_struct@@@Z ; 2820
?ImgDWriteReady@GIFDecoder@@UAGIPAI@Z ; 2820
?AddRef@GIFDecoder@@UAGKXZ ; 2814
?Release@GIFDecoder@@UAGKXZ ; 2776
?il_gif_abort@@YAXPAUil_container_struct@@@Z ; 1486
?SetContainer@GIFDecoder@@UAGPAUil_container_struct@@PAU2@@Z ; 1474
?QueryInterface@GIFDecoder@@UAGIABUnsID@@PAPAX@Z ; 1407
??0GIFDecoder@@QAE@PAUil_container_struct@@@Z ; 1407
?ImgDComplete@GIFDecoder@@UAGIXZ ; 1407
?ImgDInit@GIFDecoder@@UAGIXZ ; 1407
?il_gif_init@@YAHPAUil_container_struct@@@Z ; 1407
?Create@GIFDecoder@@SGIPAVnsISupports@@ABUnsID@@PAPAX@Z ; 1407
?il_gif_complete@@YAXPAUil_container_struct@@@Z ; 1407
??1GIFDecoder@@UAE@XZ ; 1369
??_GGIFDecoder@@UAEPAXI@Z ; 1369
?ImgDAbort@GIFDecoder@@UAGIXZ ; 136
_NSGetModule ; 1

View File

@@ -1,61 +0,0 @@
#
# 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 = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = nsjpg
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
REQUIRES = xpcom string img util layout locale jpeg unicharutil
CPPSRCS = \
jpeg.cpp \
nsJPGDecoder.cpp \
nsJPGModule.cpp \
$(NULL)
LOCAL_INCLUDES = -I$(srcdir)
EXTRA_DSO_LDOPTS = $(JPEG_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
EXTRA_LIBS = $(NSPR_LIBS)
ifndef MOZ_JAVA
LOCAL_JMC_SUBDIR = .
endif
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH)$(OS_RELEASE),SunOS5)
ifeq ($(shell uname -r),5.3)
# In this special case (jpeg.cpp), the compiler has to know
# the OS version to a finer granularity than normal.
DEFINES += -DOSMINOR=3
endif
endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +0,0 @@
/* -*- 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):
*/
/* jpeg.h */
extern int il_jpeg_init(il_container *ic);
extern int il_jpeg_write(il_container *, const PRUint8 *, int32);
extern void il_jpeg_complete(il_container *ic);
//extern unsigned int il_jpeg_write_ready(il_container *ic);
extern void il_jpeg_abort(il_container *ic);

View File

@@ -1,102 +0,0 @@
#!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):
#
#------------------------------------------------------------------------
#
# Makefile to build the IMGLIB LIB
#
#------------------------------------------------------------------------
!ifdef MOZ_JAVA
LOCAL_JMC_SUBDIR = .
!endif
LIBRARY_NAME = nsjpg
#
# Make sure we have MOZILLA_CLIENT defined so we get the
# proper JS includes
#
LCFLAGS = $(LCFLAGS) -DMOZILLA_CLIENT
!ifdef BUILD_DEBUG_GC
LCFLAGS = $(LCFLAGS) -DDEBUG_GC
!endif
LCFLAGS = $(LCFLAGS) /TP
LLIBS= $(LIBNSPR) \
$(DIST)\lib\util.lib \
$(DIST)\lib\jpeg3250.lib \
$(DIST)\lib\xpcom.lib \
!ifdef NU_CACHE
$(DIST)\lib\cache.lib \
!endif
$(NULL)
LIBRARY= .\$(OBJDIR)\$(LIBNAME).lib
LIBRARY_SUFFIX = $(MOZ_BITS)$(VERSION_NUMBER)
MAKE_OBJ_TYPE=DLL
#//------------------------------------------------------------------------
#//
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
#//
#//------------------------------------------------------------------------
DLLNAME=nsjpg
DLL1NAME=nsjpg
PDBFILE=$(DLLNAME).pdb
MAPFILE=$(DLLNAME).map
DEFFILE=nsjpg.def
#//------------------------------------------------------------------------
#//
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
#// (these must be defined before the common makefiles are included)
#//
#//------------------------------------------------------------------------
DLL=.\$(OBJDIR)\$(DLLNAME).dll
MAPFILE= $(DLLNAME).map
MODULE=img
DEPTH=..\..\..
LINCS=-I$(DEPTH)/dist/public/xpcom -I. -I$(DEPTH)/dist/public/raptor -I$(DEPTH)/dist/public/jpeg
CPPSRCS= nsJPGDecoder.cpp nsJPGModule.cpp jpeg.cpp
CPP_OBJS= \
.\$(OBJDIR)\nsJPGDecoder.obj \
.\$(OBJDIR)\nsJPGModule.obj \
.\$(OBJDIR)\jpeg.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib

View File

@@ -1,131 +0,0 @@
/* -*- 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.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):
*/
/* -*- Mode: C; tab-width: 4 -*-
* nsJPGDecoder.cpp --- interface to JPG decoder
*/
#include "nsCOMPtr.h"
#include "nsJPGDecoder.h"
#include "jpeg.h"
//////////////////////////////////////////////////////////////////////
// JPG Decoder Implementation
NS_IMPL_ISUPPORTS1(JPGDecoder, nsIImgDecoder);
JPGDecoder::JPGDecoder(il_container* aContainer)
{
NS_INIT_REFCNT();
ilContainer = aContainer;
}
JPGDecoder::~JPGDecoder(void)
{
}
NS_METHOD
JPGDecoder::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
nsresult rv;
if (aOuter) return NS_ERROR_NO_AGGREGATION;
il_container *ic = new il_container();
if (!ic) return NS_ERROR_OUT_OF_MEMORY;
JPGDecoder *decoder = new JPGDecoder(ic);
if (!decoder) {
delete ic;
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(decoder);
rv = decoder->QueryInterface(aIID, aResult);
NS_RELEASE(decoder);
/* why are we creating and destroying this object for no reason? */
delete ic; /* is a place holder */
return rv;
}
/*------------------------------------------------------*/
/* api functions
*/
/*------------------------------------------------------*/
NS_IMETHODIMP
JPGDecoder::ImgDInit()
{
int ret;
if( ilContainer != NULL ) {
ret = il_jpeg_init(ilContainer);
if(ret != 1)
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
JPGDecoder::ImgDWriteReady(PRUint32 *max_read)
{
/* dummy return needed */
*max_read = 2048;
return NS_OK;
}
NS_IMETHODIMP
JPGDecoder::ImgDWrite(const unsigned char *buf, int32 len)
{
int ret;
if( ilContainer != NULL ) {
ret = il_jpeg_write(ilContainer, buf,len);
if(ret != 0)
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
JPGDecoder::ImgDComplete()
{
if( ilContainer != NULL ) {
il_jpeg_complete(ilContainer);
}
return NS_OK;
}
NS_IMETHODIMP
JPGDecoder::ImgDAbort()
{
if( ilContainer != NULL ) {
il_jpeg_abort(ilContainer);
}
return NS_OK;
}

View File

@@ -1,58 +0,0 @@
/* -*- 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.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):
*/
#ifndef nsJPGDecoder_h___
#define nsJPGDecoder_h___
#include "nsIImgDecoder.h"
/* 1b0e6b90-d68a-11d2-802e-0060088f91a3 */
#define NS_JPGDECODER_CID \
{ 0x1b0e6b90, 0xd68a, 0x11d2, \
{ 0x80, 0x2c, 0x00, 0x60, 0x08, 0x8f, 0x91, 0xa3 } }
class JPGDecoder : public nsIImgDecoder
{
public:
JPGDecoder(il_container* aContainer);
virtual ~JPGDecoder();
NS_DECL_ISUPPORTS
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
/* stream */
NS_IMETHOD ImgDInit();
NS_IMETHOD ImgDWriteReady(PRUint32 *max_read);
NS_IMETHOD ImgDWrite(const unsigned char *buf, int32 len);
NS_IMETHOD ImgDComplete();
NS_IMETHOD ImgDAbort();
NS_IMETHOD_(il_container *) SetContainer(il_container *ic){ilContainer = ic; return ic;}
NS_IMETHOD_(il_container *) GetContainer() {return ilContainer;}
private:
il_container* ilContainer;
};
#endif /* nsJPGDecoder_h___ */

View File

@@ -1,40 +0,0 @@
/* -*- 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):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsJPGDecoder.h"
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
static NS_DEFINE_CID(kJPGDecoderCID, NS_JPGDECODER_CID);
static nsModuleComponentInfo components[] =
{
{ "JPEG Decoder",
NS_JPGDECODER_CID,
"@mozilla.org/image/decoder;1?type=image/jpeg",
JPGDecoder::Create }
};
NS_IMPL_NSGETMODULE(nsJPGModule, components)

View File

@@ -1,49 +0,0 @@
/* -*- 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):
*/
#ifndef nsJPGModule_h___
#define nsJPGModule_h___
#include "nsIModule.h"
class nsJPGModule : public nsIModule
{
public:
NS_DECL_ISUPPORTS
// Construction, Init and desstruction
nsJPGModule();
virtual ~nsJPGModule();
// nsIModule Interfaces
NS_DECL_NSIMODULE
// Facility for counting object instances
int IncrementObjCount() { if (mObjCount == -1) mObjCount = 0; return ++mObjCount; }
int DecrementObjCount() { if (mObjCount == -1) mObjCount = 0; return --mObjCount; }
int GetObjCount() { return mObjCount; }
private:
int mObjCount;
nsISupports* mClassObject;
};
#endif /* nsJPGModule_h___ */

View File

@@ -1,14 +0,0 @@
;
; temp def file for nsjpg dll
;
LIBRARY nsjpg.dll
DESCRIPTION 'test dll'
EXPORTS
ImgDInit @1002 PRIVATE
ImgDWrite @1003 PRIVATE
ImgDWriteReady @1004 PRIVATE
ImgDComplete @1005 PRIVATE
ImgDAbort @1006 PRIVATE

View File

@@ -1,24 +0,0 @@
?fill_input_buffer@@YAEPAUjpeg_decompress_struct@@@Z ; 53
?ImgDWrite@JPGDecoder@@UAGIPBEJ@Z ; 45
?il_jpeg_write@@YAHPAUil_container_struct@@PBEJ@Z ; 45
?ImgDWriteReady@JPGDecoder@@UAGIPAI@Z ; 44
?output_jpeg_scanlines@@YAHPAUil_container_struct@@H@Z ; 4
?init_source@@YAXPAUjpeg_decompress_struct@@@Z ; 2
?AddRef@JPGDecoder@@UAGKXZ ; 2
?Release@JPGDecoder@@UAGKXZ ; 2
?skip_input_data@@YAXPAUjpeg_decompress_struct@@J@Z ; 2
?SetContainer@JPGDecoder@@UAGPAUil_container_struct@@PAU2@@Z ; 2
?il_jpeg_abort@@YAXPAUil_container_struct@@@Z ; 2
_NSGetModule ; 1
?il_jpeg_COM_handler@@YAEPAUjpeg_decompress_struct@@@Z ; 1
?il_jpeg_init@@YAHPAUil_container_struct@@@Z ; 1
?setup_jpeg_src@@YAHPAUjpeg_decompress_struct@@PAUjpeg_struct@@@Z ; 1
?ImgDInit@JPGDecoder@@UAGIXZ ; 1
?QueryInterface@JPGDecoder@@UAGIABUnsID@@PAPAX@Z ; 1
??_GJPGDecoder@@UAEPAXI@Z ; 1
??0JPGDecoder@@QAE@PAUil_container_struct@@@Z ; 1
?Create@JPGDecoder@@SGIPAVnsISupports@@ABUnsID@@PAPAX@Z ; 1
??1JPGDecoder@@UAE@XZ ; 1
?ImgDAbort@JPGDecoder@@UAGIXZ ; 1
?ImgDComplete@JPGDecoder@@UAGIXZ ; 1
?il_jpeg_complete@@YAXPAUil_container_struct@@@Z ; 1

View File

@@ -1,29 +0,0 @@
#
# 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 public_com png pngcom jpgcom gifcom \
!if !defined(MOZ_DISABLE_MNG)
mng mngcom \
!endif
$(NULL)
!include $(DEPTH)\config\rules.mak

View File

@@ -1,760 +0,0 @@
-----------------------------------------------------------
1.0.1 (May 2nd 2001)
--------------------
in short:
Maintenance release.
Fixed several memory-leaks with the help of Gregg Kelly, added/fixed some CMS
handling, exported JPEG functions from standard DLL, and some other minor fixes.
The CMS fix now makes libmng automagically work in MNG_FULL_CMS mode as a
sRGB compliant system. YOU WILL NEED TO CHANGE THIS IF YOU ARE NOT ON AN sRGB
COMPLIANT SYSTEM AND WANT TO USE CMS!!!!
(look in libmng.h for the proper function-calls)
-------------------
bugfixes:
core:
- added MEND processing callback
- fixed first FRAM_MODE=4 timing problem
- added handle status-copy function (use with care)
- exported JPEG functions from standard DLL
- added BGRA8 canvas with premultiplied alpha (contrib by Gregg Kelly)
- fixed problem with display_reset/display_resume (Thanks Gregg!)
- fixed several memory-leaks (Thanks Gregg!)
- fixed reset_rundata to drop all objects (Thanks again, Gregg!)
- fixed problem with cms profile being created multiple times when both
iCCP & cHRM/gAMA are present (And again... Gregg)
- moved mng_clear_cms to libmng_cms
- added "default" sRGB generation (Thanks Marti!)
samples:
contrib:
doc:
makefiles:
autoconf:
-----------------------------------------------------------
1.0.0 (Feb 6th 2001)
--------------------
in short:
First public release. Finally(!)
This is the 0.9.5 CVS version, which will never be released, because I feel it
is now ready for a public release. So apart from the version-numbers here and
there, all other changes are listed under 0.9.5.
This library will work with every MNG/JNG known and available to me. Note that
there are still parts that need to be coded, and that MNG support is around
90-95% (JNG at 100%). It is however compliant with the latest and greatest
MNG 1.0 specification.
I hope to dedicate a bit more time this year to finish up full support and fill
in the remaining blanks. But this is coming out of my spare time. And extra
help is always appreciated.
Please enjoy!
Gerard
-----------------------------------------------------------
0.9.5 (no release)
------------------
in short:
intermediate CVS
-------------------
bugfixes:
B129681 - fixed compiler warnings SGI/Irix (thanks Dimitri)
core:
- fixed compiler-warnings Mozilla (thanks Tim)
- fixed timing-problem with switching framing_modes
- fixed some small compiler warnings (thanks Nikki)
samples:
contrib:
- fixed library-paths for MSVC DLL project (thanks Chad)
doc:
makefiles:
- added makefile for DJGPP (thanks Silvio)
autoconf:
-----------------------------------------------------------
0.9.4 (Jan 19th 2001)
----------------------
in short:
Now that the MNG spec is at 1.0, this should be the last beta. There's a few
small changes to make it inline with the spec, and a couple of bug-fixes.
This is a serious release-candidate for libmng-1.0!!
Please... test test test test!!
-------------------
bugfixes:
B123314 - fixed number of TERM related problems
B123322 - fixed unwanted repetition in mng_readdisplay()
B123443 - fixed by Ralph
B124910 - fixed definition for WIN32_LEAN_AND_MEAN (thanks Chad)
B125750 - fixed by Ralph
B125756 - fixed mixup of data- & function-pointers (thanks Dimitri)
B127517 - changed inclusion of the lcms header file for non-windows platforms
core:
- version numbers
- fixed possible loop in display_resume() (Thanks Vova!)
- fixed unwanted repetition in mng_readdisplay()
- changed inclusion of the lcms header file for non-windows platforms
- changed IHDR filter_method check for PNGs
- moved restore of object 0 to libmng_display
- added restore of object 0 to TERM processing (B123314)
- fixed TERM delay processing (B123314)
- fixed TERM end processing when count = 0 (B123314)
- changed callback convention for MSVC (Thanks Chad)
- fixed mixup of data- & function-pointers (thanks Dimitri)
- added support for "nEED MNG-1.0"
- added errorcode for MAGN methods
- added errorchecking for MAGN methods
- removed "old" MAGN methods 3 & 4
- added "new" MAGN methods 3, 4 & 5
- removed test filter-methods 1 & 65
- set default level-set for filtertype=64 to all zeroes
samples:
contrib:
- added GTK mng-view example by Vova Babin
- added MSVC MNGview sample by Nikolaus Brennig
- updated Jason Summer's mngplg to version 0.9.2
(that's mngplg-0.9.2 based on libmng-0.9.3 !!!)
- rearranged contrib directory slightly
- added MSVC project to build libmng.dll by Chad Austin
doc:
- added README.dll
- added README.config
makefiles:
- added a makefile for MS Visual C++ (Thanks to Atsushi Matsuda)
autoconf:
- fixed configure.in for lcms (FreeBSD port by Mikhail Teterin)
- by default configure includes CMS support if lcms is present
-----------------------------------------------------------
0.9.3 (October 29th 2000)
-------------------------
in short:
Another beta release. The number of changes in the MNG specification have
resulted in a lot of new code and some changed code. At the same time I saw
no need to withhold some new functionality as it was pretty clear there was
going to be another beta-round. If things go well, I'm going to try to release
libmng 1.0.0 very shortly after this one.
Many thanks to a lot of people for helping out, sending contributions, making
suggestions and testing this little baby. This would get nowhere without YOU!!!
- fixed bug 111300/117103
- added workaround for faulty PhotoShop iCCP chunk
- added MAGN/JDAA chunks
- added support for new filter_types
- added PNG/MNG spec version indicators
- added BCB mngview contribution by Andy Protano
- added BCB mngdump; a GUI-based MNG dumping utility (Andy Protano)
- implemented support for nEED "draft nn"
- implemented app-defined support for bKGD for PNG images
- removed trace-options from default SO/DLL builds (!!!)
- raised initial maximum canvas size to 10000x10000 (!!!)
(an App that wants to protect from overly large images should call
mng_set_maxcanvassize() with appropriate values)
- fixed other assorted stuff
-------------------
bugfixes:
B111300 - fixup for improved portability
B117103 - fixed compilation errors on *nix with lcms (thanks Ralph!)
core:
- fixed compiler-warnings from Mozilla
- added check for simplicity-bits in MHDR
- added workaround for faulty PhotoShop iCCP chunk
- fixed app-supplied background restore
- fixed TERM processing delay of 0 msecs
- fixed write-code for zTXt & iTXt
- fixed read-code for iTXt
- added MAGN chunk
- fixed sRGB precedence for gamma_only corection
- added support for new filter_types
- fixed problem with no refresh after TERM
- fixed DEFI behavior
- fixed inclusion parameters to make the external libs work together
- added export of zlib functions from windows dll
- fixed timing & refresh behavior for single PNG/JNG
- removed trace-options from default SO/DLL builds (!!!)
- fixed MAGN rounding errors (thanks Matthias!)
- fixed small timing problem when FRAM delay = 0
- fixed simplicity-check in compliance with draft 81/0.98a
- fixed alpha-blending for all alpha-canvasstyles
- added support for alpha-depth prediction
- fixed processing of unknown critical chunks
- removed test-MaGN
- added PNG/MNG spec version indicators
- implemented support for nEED
- added support for JDAA
- added functions to retrieve PNG/JNG specific header-info
- added optional support for bKGD for PNG images
- raised initial maximum canvas size to 10000x10000
- added support for delta-JNG
- added callback to process non-critical unknown chunks
- fixed support for delta-images during read() / display()
- added closestream() processing for mng_cleanup()
- fixed delta-processing behavior
- added storage for pixel-/alpha-sampledepth for delta's
- implemented delayed delta-processing
- fixed putchunk_plte() to set bEmpty parameter (thanks Ben!)
- added errorcode for delayed delta-processing
- added get/set for bKGD preference setting
- added get function for interlace/progressive display
- fixed bug in empty PLTE handling
- fixed seperate read() & display() processing
- fixed tRNS processing for gray-image < 8-bits
samples:
- added BCB mngview contribution by Andy Protano
contrib:
- added BCB mngdump; a GUI-based MNG dumping utility (Andy Protano)
doc:
- updated RPM spec-file by MATSUURA Takanori
- updated README.contrib
makefiles:
- fixed some stuff in automake/autoconf/libtool
- fixed auto* for bug B117103
-----------------------------------------------------------
0.9.2 (August 7th 2000)
-----------------------
in short:
Third beta release! Last one???
!!IMPORTANT!! All file-names are now prefixed with "libmng_" !!IMPORTANT!!
Many thanks to Albert Chin-A-Young for his contribution of the
autoconf/automake/libtool stuff and to Ralph Giles for helping me
put it in the right places.
There's a special README.autoconf so please read it!
- fixed bug 110320/110546/110547/111096
- added several status retrieval functions
- fixed other small bugs in display processing
- fixed number of small problems and documentation typos
- added autoconf/automake/libtool
- added latest MNG plugin (0.9.0) by Jason Summers
-------------------
bugfixes:
B110320 - fixed GCC warning about mix-sized pointer math
B110546 - fixed for improperly returning UNEXPECTEDEOF
B110547 - fixed bug in interlace code
B111096 - fixed large-buffer read-suspension
core:
- version numbers
- fixed small bugs in display processing
- removed Nextbackxxx fields (no longer used)
- fixed problem with trace-functions improperly wrapped
- put specific code in add_chunk() inside MNG_SUPPORT_WRITE wrapper
- fixed documentation typos
- fixed wrapping of suspension parameters
- added status_xxxx functions
- added trace-codes/-strings for status_xxxxx functions
- changed file-prefixes
- added function to set simplicity field
- added trace-code/-string for updatemngsimplicity
- fixed putchunk_unknown() function
samples:
contrib:
- added latest MNG plugin (0.9.0) by Jason Summers
doc:
- version numbers
- added autoconf readme
- version numbers in RPM stuff
makefiles:
- fixed for new file-prefix
- added autoconf/automake/libtool
-----------------------------------------------------------
0.9.1 (July 26th 2000)
----------------------
in short:
Second beta release.
Given the enormous amount of bug-reports (not ;-), this will most likely
be one of the last betas. If things remain upright, the first public release
(1.0.0) is fairly eminent in the weeks to come...
- added SDL mng player by Ralph Giles to contributions
- fixed timing and added internal buffering for I/O-suspension scenarios
- added get routines for internal display-state variables (frame/layer/playtime)
- changed read-processing for improved I/O-suspension (internal buffering)
- fixed several problems with create- & write-support
- added a load of documentation
- lots of small stuff
-------------------
bugfixes:
core:
- fixed mandatory BACK color to be opaque
- changed mng_display_resume to allow to be called after a suspension
return with MNG_NEEDMOREDATA
- changed comments to indicate modified behavior for timer & suspension breaks
- added variables for go_xxxx processing
- implemented support for freeze/reset/resume & go_xxxx
- added trace-codes/-strings for special display processing
- added variables for improved timing support
- added support for improved timing
- added get routines for internal display variables
- added get/set routines for suspensionmode variable
- added trace-code/-string for get/set suspensionmode
- added trace-codes/-strings for get/set display variables
- added support for improved I/O-suspension
- changed read-processing for improved I/O-suspension
- added trace-code/-string for read_databuffer (I/O-suspension)
- added suspendbuffer constants
- changed EOF processing behavior
- fixed TERM delay processing
- changed pre-draft48 frame_mode=3 to frame_mode=1
- added callbacks for SAVE/SEEK processing
- added trace-codes/-strings for SAVE/SEEK callbacks
- added variable for NEEDSECTIONWAIT breaks
- added trace-codes/-strings for get/set sectionbreaks
- added NEEDSECTIONWAIT error-code/-string
- added macro + routine to set returncode without calling error callback
- added trace-code/-string for special error routine
- changed default readbuffer size from 1024 to 4200
- added variable for freeze & reset processing
- fixed storage of images during mng_read()
- fixed support for mng_display() after mng_read()
- added error cleanup processing
- fixed support for mng_display_reset()
- fixed suspension-buffering for 32K+ chunks
- added function to set frame-/layer-count & playtime
- added trace-code/-string for updatemngheader
- added error-code/-string for updatemngheader if not a MNG
- fixed creation-code
- fixed writing of signature
- fixed several chunk-writing routines
samples:
- fixed the libmng.pas module in line with libmng.h
contrib:
- added the SDL based mngplay viewer by Ralph Giles
doc:
- extended the RPM contribution by MATSUURA Takanori
- added libmng.txt, a full description of the library and its usage
- added man-pages for mng(5), jng(5) and libmng(3)
makefiles:
-----------------------------------------------------------
0.9.0 (June 30th 2000)
----------------------
in short:
This is the first beta!!! Yippee!!!
Thanks to all the people who helped to guide me in the right direction.
You know who you are!
A special thanks to the guys with early implementations, who stood by and
put up with my whims :-)
changes over 0.5.3:
- updated mngplg to 0.4.1 (the latest & greatest)
- changed refresh parameters to 'x,y,width,height'
-----------------------------------------------------------
0.5.3 (never released)
----------------------
in short:
This is a working version only; the next release will be 0.9.0 (first Beta!)
There are a few incompatible changes with previous versions. The userdata
variable has been changed from mng_uint32 to mng_ptr to accomodate 64-bit
systems. For the same reason memory allocation size parameters have been
changed to a mng_size_t type which is a typedef of size_t.
Thanks to Aleks Jakulin for helping to iron out some 64-bit platform issues!
- implemented the update-region parameters of the refresh callback
- added support for most common delta-image options
- added an animation-speed modifier
- added an image-level parameter for the processtext callback
- updated mngplg to 0.4.0 (supports JNG, full CMS, and other enhancements!)
- fixed a lot of small things
- added support for PPLT chunk
- fixed to support 64-bit platforms
-------------------
bugfixes:
core:
- added processing of color-info on delta-image
- fixed handling of empty SAVE chunk
- fixed display of stored JNG images
- fixed problem with BASI-IEND as object 0
- changed the version parameters (obviously)
- added update-region parms for refresh calback
- added Needrefresh parameter
- added initialization of update-region for refresh
- added initialization of Needrefresh parameter
- changed progressive-display processing
- added tracecodes for tracing JPEG progression
- added tracing of JPEG calls
- added Deltaimmediate parm for faster delta-processing
- added extra checks for delta-images
- many changes to support delta-images
- optimized some store_xxx routines
- fixed some small things (as precaution)
- fixed possible trouble if IEND display-processing got broken up
- fixed nasty bug with embedded PNG after delta-image
- added processing of PLTE & tRNS for delta-images
- added processing of PLTE/tRNS & color-info for delta-images in the
ani_objects chain
- fixed problem with color-correction for stored images
- added get/set for speedtype to facilitate testing
- added trace-codes & -strings for get/set speedtype
- added speed-modifier to timing routine
- added get-routine of imagelevel for processtext callback
- added trace-code & -string for get imagelevel
- added administration of imagelevel parameter
- added support for PPLT chunk
- added trace-codes & -strings for PPLT chunk processing
- fixed problem with incorrect gamma-correction
- fixed inclusion of IJG read/write code
- fixed problem with 16-bit GA format
- fixed problem with cheap transparency for 4-bit gray
- fixed display_xxxx routines for interlaced images
- added precaution against faulty iCCP chunks from PS
- changed userdata variable to mng_ptr
- added typedef for mng_size_t
- changed size parameter for memory allocation to mng_size_t
- fixed compiler-warning for non-initialized iB variable
- changed definition for 32-bit ints (64-bit platforms)
- changed definition for mng_handle (64-bit platforms)
- swapped refresh parameters
- fixed initialization routine for new mng_handle type
- added inclusion of stdlib.h for abs()
- fixed some 64-bit warnings
- fixed incompatible return-types
samples:
contrib:
- updated mngplg to 0.3.0 (supports JNG & full color-correction!)
- updated mngplg to 0.4.0 (Jason is picking up the pace ;-)
doc:
- added rpm directory with rpm spec-file (contributed by MATSUURA Takanori)
makefiles:
- changed makefile.linux to reflect versionnr for shared-lib
- changed makefile.linux to depend on mng_conf.h & mng_types.h
-----------------------------------------------------------
0.5.2 (June 10th 2000)
----------------------
in short:
This is the third release for developers
Another milestone since JNG is now fully supported
The next release will most likely be numbered 0.9.0 as the first Beta!!
Fixed bug 106017 & 106019
Added many constants regarding chunk-property values
Implemented full JNG support
Added all the error- & trace-strings
Added get/set routines for default ZLIB/IJG parameters
Added a generic makefile for Unix platforms (contributed by Tim Rowley)
Added canvasstyle for separate RGB + A canvas (eg. mozilla-style)
Separated configuration-options into a separate file: "mng_conf.h"
Fixed stuff for generic Unix compilation (contributed by Tim Rowley)
Upgraded to lcms1.0.6 (now supports 16-bit endian-peculiarities)
Added a makefile for Linux ELF & fixed some code-issues to go along with gcc
Added support for suspended input-buffer processing
Implemented the display-routines for RGBA/ARGB/BGRA/ABGR canvasstyles
Implemented the application background-restore functionality
Fixed & tested the mngtree Unix-sample (runs on Linux-RH6.2 with libmng.so)
Upgraded mngplg to v0.2.2 (based on the latest code including JNG)
Fixed a lot of other assorted stuff
-------------------
bugfixes:
B003(106017) - fixed problem with <mem.h> being proprietary to BCB
B004(106019) - fixed problem when MNG_SUPPORT_WRITE not defined
core:
- bumped version-numbers up to 0.5.2 (yeah, really)
- fixed support for IJGSRC6B
- cleaned up some code regarding mixed support-options
- complemented constants for chunk-property values
- fixed MNG_UINT_pHYg value
- implemented JNG support
- fixed problem with DEFI clipping
- added error telltale strings & support
- added trace telltale strings & support
- added support for global color-chunks inside TERM/LOOP
- added support for global PLTE,tRNS,bKGD inside TERM/LOOP
- added default IJG compression parameters and such
- moved init of default zlib parms to "mng_hlapi.c"
- added init of default IJG parms
- added support for get/set of zlib/IJG default parms
- added tracestrings for global animation color-chunks
- added tracestrings for get/set of default ZLIB/IJG parms
- added tracestrings for global PLTE,tRNS,bKGD
- added framenr/layernr/playtime to object header
- added initialization of framenr/layernr/playtime
- changed ani_create calls not returning object pointer
- create ani objects always (not just inside TERM/LOOP)
- fixed inconsistancy with freeing global iCCP profile
- fixed minor bugs 16-bit pixel-handling
- added object promotion routine (PROM handling)
- added trace-codes & -strings for image-object promotion
- added trace-codes & -strings for delta-image processing
- added error-codes & -strings for delta-image processing
- added support for delta-image processing
- added ani-object routines for delta-image processing
- added delta-image fields
- added compression/filter/interlace fields to object-buffer for
delta-image processing
- added delta-image row-processing routines
- fixed up punctuation in several files (contributed by Tim Rowley)
- removed useless definition in "mng_chunks.h" (contributed by Tim Rowley)
- fixed pointer confusion in "mng_display.c" (contributed by Tim Rowley)
- fixed inclusion for memcpy (contributed by Tim Rowley)
- added mng_int32p (contributed by Tim Rowley)
- added internal delta-image processing callbacks
- separated configuration-options into "mng_conf.h"
- changed to most likely configuration
- added RGB8_A8 canvasstyle
- added getalphaline callback for RGB8_A8 canvasstyle
- fixed some makeup for Linux gcc compile
- implemented app bkgd restore routines
- implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines
- added support for RGB8_A8 canvasstyle
- added support for suspended input-buffer processing
- added mng_read_resume HLAPI function to support read-suspension
- fixed timer-handling to run with Mozilla (Tim Rowley)
- fixed alpha-handling for alpha canvasstyles
- fixed some compilation-warnings (contrib Jason Morris)
samples:
- fixed mngview(delphi) to work with the new core
- synchronized libmng.pas(delphi) with the new libmng.h header
- removed the error- & trace-strings from libmng.pas(delphi)
- fixed mngtree(Unix) to compile on Linux (runs with libmng.so)
- added makefile.linux for mngtree(Unix) (tested on RedHat6.2)
contrib:
- updated mngplg to 0.2.2 (based on latest code; supports JNG!)
doc:
- this file obviously
- added Tim Rowley as contributing author
- changed the examples.readme doc
- updated the design-schematics in line with the current code
makefiles:
- changed the directory to "makefiles" to avoid name-conflicts
- added generic Unix makefile (thanks to Tim Rowley)
- added Linux ELF makefile (tested on RedHat6.2)
-----------------------------------------------------------
0.5.1 May 16th 2000
-------------------
in short:
This is the second release for developers
It's a bit of a milestone since all the chunk functionality is in place and
functioning (read, examine, create & write)
This version is incompatible with 0.5.0 since some of the callback prototypes
have changed (should be the last time that happens!)
There are a few more samples and even a real contribution!
Fixed bug 105795 & 105797
Fixed a mis-alignment in animation-timing
Added chunk-access functions
Finished all chunk-storage routine-bits
Finished all chunk-write routines
Changed the callback prototypes to allow error-reporting back to the library
Fixed some routines to allow for callback error-reporting
Added version-control functions & constants
Added two functions to set display- & sRGB-profile from memory
Moved CRC table to dynamic structure (for improved thread-safety)
Added SAVE & SEEK save&restore functionality
Finished the application-based CMS-callbacks
Fixed a few BCB specifics
Changed the Win32 DLL and samples to use __stdcall
Did some more assorted little changes
Added 2 BCB samples
Added 1 Unix sample
Added the MNG plugin by Jason Summers in the contrib section
Changed some documents to reflect these changes
-------------------
bugfixes:
B001(105795) - fixed wrong lcms call & memory-leak for gammatables
B002(105797) - fixed problem with missing sRGB profile
core:
- changed chunk iteration function
- added chunk access functions
- added version control constants & functions
- changed strict-ANSI stuff
- added set_outputprofile2 & set_srgbprofile2
- added empty-chunk put-routines
- added version_dll & VERSION_DLL (for consistency)
- added version control explanatory text & samples
- added iteratechunk callback definition
- improved definitions for DLL support
- added 8-bit palette definition
- added general array definitions
- added MNG_NULL definition
- changed most callback prototypes to allow the app
to report errors during callback processing
- added CRC table to main structure (for thread-safety)
- added iPLTEentries for checking hIST-length
- changed palette definition to exported palette-type
- removed frozen indicator
- added create/write indicators
- added eMNGma hack (will be removed in 1.0.0 !!!)
- added TERM animation object pointer (easier reference)
- added saved-data structure for SAVE/SEEK processing
- added some errorcodes
- added application errorcodes (used with callbacks)
- moved chunk-access errorcodes to severity 5
- added chunk-access function trace-codes
- changed trace to macro for callback error-reporting
- added save_state & restore_state trace-codes
- put in some extra comments
- fixed layout for sBIT, PPLT
- changed write callback definition
- fixed layout for PPLT again (missed deltatype ?!?)
- cleaned up left-over teststuff in the BACK chunk routine
- changed CRC initialization to use dynamic structure
(wasn't thread-safe the old way !)
- filled in many missing sequence&length checks
- filled in many missing chunk-store snippets
- added checks for running animations
- filled remaining write routines
- fixed read_pplt with regard to deltatype
- added callback error-reporting support
- added pre-draft48 support (short MHDR, frame_mode, LOOP)
- fixed chunk-storage bit in several routines
- supplemented the SAVE & SEEK display processing
- added init of iPLTEcount
- changed calling-convention definition
- changed status-handling of display-routines
- added versioning-control routines
- filled the write routine
- fixed frame_delay misalignment
- added sanity check for frozen status
- changed display_mend to reset state to initial or SAVE
- added save_state and restore_state for SAVE/SEEK/TERM
processing
- added process_save & process_seek routines
- changed and filled iterate-chunk function
- added getchunk functions
- added putchunk functions
- added empty-chunk put-routines
- filled application-based color-management routines
- added creatememprofile
- filled the deflatedata routine
- added cleanup of saved-data (SAVE/SEEK processing)
- moved the actual write_graphic functionality from mng_hlapi.c
to it's appropriate function in the mng_write.c module
- moved standard header includes into mng_types.h
(stdlib/mem for mem-mngmt & math for fp gamma-calc)
- added getimgdata & putimgdata functions
samples:
- fixed mngview(delphi) to work with the new core
- synchronized libmng.pas(delphi) with the new libmng.h header
- added mngtree(bcb) sample
- added bogus(bcb) sample
- added mngtree(unix) sample
contrib:
- added mngplg 0.1.0 / a MNG plugin for Win32 by Jason Summers
doc:
- added this changes.readme file
- changed the samples.readme doc accordingly
- changed the contrib.readme doc accordingly
-----------------------------------------------------------
0.5.0 May 1st 2000
------------------
in short:
This is the first developers release.
It's roughly about 60% done.

View File

@@ -1,56 +0,0 @@
/* ************************************************************************** */
/* * * */
/* * COPYRIGHT NOTICE: * */
/* * * */
/* * Copyright (c) 2000 Gerard Juyn (gerard@libmng.com) * */
/* * [You may insert additional notices after this sentence if you modify * */
/* * this source] * */
/* * * */
/* * For the purposes of this copyright and license, "Contributing Authors" * */
/* * is defined as the following set of individuals: * */
/* * * */
/* * Gerard Juyn * */
/* * * */
/* * The MNG Library is supplied "AS IS". The Contributing Authors * */
/* * disclaim all warranties, expressed or implied, including, without * */
/* * limitation, the warranties of merchantability and of fitness for any * */
/* * purpose. The Contributing Authors assume no liability for direct, * */
/* * indirect, incidental, special, exemplary, or consequential damages, * */
/* * which may result from the use of the MNG Library, even if advised of * */
/* * the possibility of such damage. * */
/* * * */
/* * Permission is hereby granted to use, copy, modify, and distribute this * */
/* * source code, or portions hereof, for any purpose, without fee, subject * */
/* * to the following restrictions: * */
/* * * */
/* * 1. The origin of this source code must not be misrepresented; * */
/* * you must not claim that you wrote the original software. * */
/* * * */
/* * 2. Altered versions must be plainly marked as such and must not be * */
/* * misrepresented as being the original source. * */
/* * * */
/* * 3. This Copyright notice may not be removed or altered from any source * */
/* * or altered source distribution. * */
/* * * */
/* * The Contributing Authors specifically permit, without fee, and * */
/* * encourage the use of this source code as a component to supporting * */
/* * the MNG and JNG file format in commercial products. If you use this * */
/* * source code in a product, acknowledgment would be highly appreciated. * */
/* * * */
/* ************************************************************************** */
/* * * */
/* * Parts of this software have been adapted from the libpng package. * */
/* * Although this library supports all features from the PNG specification * */
/* * (as MNG descends from it) it does not require the libpng package. * */
/* * It does require the zlib library and optionally the IJG jpeg library, * */
/* * and/or the "little-cms" library by Marti Maria (depending on the * */
/* * inclusion of support for JNG and Full-Color-Management respectively. * */
/* * * */
/* * This library's function is primarily to read and display MNG * */
/* * animations. It is not meant as a full-featured image-editing * */
/* * component! It does however offer creation and editing functionality * */
/* * at the chunk level. * */
/* * (future modifications may include some more support for creation * */
/* * and or editing) * */
/* * * */
/* ************************************************************************** */

View File

@@ -1,7 +0,0 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
libmng.h
libmng_conf.h
libmng_types.h

View File

@@ -1,69 +0,0 @@
#
# 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 = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = mng
LIBRARY_NAME = mozmng
EXPORT_LIBRARY = 1
REQUIRES = jpeg
CSRCS = \
libmng_callback_xs.c \
libmng_chunk_io.c \
libmng_chunk_prc.c \
libmng_chunk_xs.c \
libmng_cms.c \
libmng_display.c \
libmng_dither.c \
libmng_error.c \
libmng_filter.c \
libmng_hlapi.c \
libmng_jpeg.c \
libmng_object_prc.c \
libmng_pixels.c \
libmng_prop_xs.c \
libmng_read.c \
libmng_trace.c \
libmng_write.c \
libmng_zlib.c \
$(NULL)
EXPORTS = libmng.h libmng_conf.h libmng_types.h
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
LOCAL_INCLUDES = -I$(srcdir)
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
EXTRA_DSO_LDOPTS = $(JPEG_LIBS) $(ZLIB_LIBS)
else
FORCE_STATIC_LIB = 1
endif
include $(topsrcdir)/config/rules.mk

View File

@@ -1,38 +0,0 @@
libmng 1.0.1
------------
First maintenance release!
There's been some changes in the CMS profile handling, that should make it
easier for sRGB-compliant systems. Non-sRGB compliant systems will still need
some extra work if they want to use MNG_FULL_CMS with lcms. But this has always
been so, so it's not an extra step anyway.
(Many thanks to Marti, Ivan & Warwick for their help & comments!)
Gregg Kelly has been helpful in locating a couple of memory-leaks, and make
the library even better.
The default Windows DLL that's part of the Windows zip-files now also exports
the JPEG library function calls (ijgsrc6b). Note that there's a new Delphi
component (TNGImage) that makes it a snap to work with PNG/JNG & MNG images
within Delphi.
Please enjoy!
Gerard
For more information please visit:
The official libmng web-site:
http://www.libmng.com
Libmng's community on SourceForge:
https://sourceforge.net/project/?group_id=5635
The official MNG homepage:
http://www.libpng.org/pub/mng
The official PNG homepage:
http://www.libpng.org/pub/png

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,295 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_chunk_io.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Chunk I/O routines (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the chunk input/output routines * */
/* * * */
/* * changes : 0.5.1 - 05/04/2000 - G.Juyn * */
/* * - changed CRC initializtion to use dynamic structure * */
/* * (wasn't thread-safe the old way !) * */
/* * 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed write routines definition * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/26/2000 - G.Juyn * */
/* * - added MAGN chunk * */
/* * 0.9.3 - 10/16/2000 - G.Juyn * */
/* * - added support for JDAA * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_chunk_io_h_
#define _libmng_chunk_io_h_
/* ************************************************************************** */
mng_uint32 crc (mng_datap pData,
mng_uint8p buf,
mng_int32 len);
/* ************************************************************************** */
#ifdef MNG_INCLUDE_READ_PROCS
#define READ_CHUNK(n) mng_retcode n (mng_datap pData, \
mng_chunkp pHeader, \
mng_uint32 iRawlen, \
mng_uint8p pRawdata, \
mng_chunkp* ppChunk)
READ_CHUNK (read_ihdr) ;
READ_CHUNK (read_plte) ;
READ_CHUNK (read_idat) ;
READ_CHUNK (read_iend) ;
READ_CHUNK (read_trns) ;
READ_CHUNK (read_gama) ;
READ_CHUNK (read_chrm) ;
READ_CHUNK (read_srgb) ;
READ_CHUNK (read_iccp) ;
READ_CHUNK (read_text) ;
READ_CHUNK (read_ztxt) ;
READ_CHUNK (read_itxt) ;
READ_CHUNK (read_bkgd) ;
READ_CHUNK (read_phys) ;
READ_CHUNK (read_sbit) ;
READ_CHUNK (read_splt) ;
READ_CHUNK (read_hist) ;
READ_CHUNK (read_time) ;
READ_CHUNK (read_mhdr) ;
READ_CHUNK (read_mend) ;
READ_CHUNK (read_loop) ;
READ_CHUNK (read_endl) ;
READ_CHUNK (read_defi) ;
READ_CHUNK (read_basi) ;
READ_CHUNK (read_clon) ;
READ_CHUNK (read_past) ;
READ_CHUNK (read_disc) ;
READ_CHUNK (read_back) ;
READ_CHUNK (read_fram) ;
READ_CHUNK (read_move) ;
READ_CHUNK (read_clip) ;
READ_CHUNK (read_show) ;
READ_CHUNK (read_term) ;
READ_CHUNK (read_save) ;
READ_CHUNK (read_seek) ;
READ_CHUNK (read_expi) ;
READ_CHUNK (read_fpri) ;
READ_CHUNK (read_phyg) ;
READ_CHUNK (read_jhdr) ;
READ_CHUNK (read_jdaa) ;
READ_CHUNK (read_jdat) ;
READ_CHUNK (read_jsep) ;
READ_CHUNK (read_dhdr) ;
READ_CHUNK (read_prom) ;
READ_CHUNK (read_ipng) ;
READ_CHUNK (read_pplt) ;
READ_CHUNK (read_ijng) ;
READ_CHUNK (read_drop) ;
READ_CHUNK (read_dbyk) ;
READ_CHUNK (read_ordr) ;
READ_CHUNK (read_magn) ;
READ_CHUNK (read_need) ;
READ_CHUNK (read_unknown) ;
/* ************************************************************************** */
#else /* MNG_INCLUDE_READ_PROCS */
#define read_ihdr 0
#define read_plte 0
#define read_idat 0
#define read_iend 0
#define read_trns 0
#define read_gama 0
#define read_chrm 0
#define read_srgb 0
#define read_iccp 0
#define read_text 0
#define read_ztxt 0
#define read_itxt 0
#define read_bkgd 0
#define read_phys 0
#define read_sbit 0
#define read_splt 0
#define read_hist 0
#define read_time 0
#define read_mhdr 0
#define read_mend 0
#define read_loop 0
#define read_endl 0
#define read_defi 0
#define read_basi 0
#define read_clon 0
#define read_past 0
#define read_disc 0
#define read_back 0
#define read_fram 0
#define read_move 0
#define read_clip 0
#define read_show 0
#define read_term 0
#define read_save 0
#define read_seek 0
#define read_expi 0
#define read_fpri 0
#define read_phyg 0
#define read_jhdr 0
#define read_jdaa 0
#define read_jdat 0
#define read_jsep 0
#define read_dhdr 0
#define read_prom 0
#define read_ipng 0
#define read_pplt 0
#define read_ijng 0
#define read_drop 0
#define read_dbyk 0
#define read_ordr 0
#define read_magn 0
#define read_need 0
#define read_unknown 0
#endif /* MNG_INCLUDE_READ_PROCS */
/* ************************************************************************** */
#ifdef MNG_INCLUDE_WRITE_PROCS
#define WRITE_CHUNK(n) mng_retcode n (mng_datap pData, \
mng_chunkp pChunk)
WRITE_CHUNK (write_ihdr) ;
WRITE_CHUNK (write_plte) ;
WRITE_CHUNK (write_idat) ;
WRITE_CHUNK (write_iend) ;
WRITE_CHUNK (write_trns) ;
WRITE_CHUNK (write_gama) ;
WRITE_CHUNK (write_chrm) ;
WRITE_CHUNK (write_srgb) ;
WRITE_CHUNK (write_iccp) ;
WRITE_CHUNK (write_text) ;
WRITE_CHUNK (write_ztxt) ;
WRITE_CHUNK (write_itxt) ;
WRITE_CHUNK (write_bkgd) ;
WRITE_CHUNK (write_phys) ;
WRITE_CHUNK (write_sbit) ;
WRITE_CHUNK (write_splt) ;
WRITE_CHUNK (write_hist) ;
WRITE_CHUNK (write_time) ;
WRITE_CHUNK (write_mhdr) ;
WRITE_CHUNK (write_mend) ;
WRITE_CHUNK (write_loop) ;
WRITE_CHUNK (write_endl) ;
WRITE_CHUNK (write_defi) ;
WRITE_CHUNK (write_basi) ;
WRITE_CHUNK (write_clon) ;
WRITE_CHUNK (write_past) ;
WRITE_CHUNK (write_disc) ;
WRITE_CHUNK (write_back) ;
WRITE_CHUNK (write_fram) ;
WRITE_CHUNK (write_move) ;
WRITE_CHUNK (write_clip) ;
WRITE_CHUNK (write_show) ;
WRITE_CHUNK (write_term) ;
WRITE_CHUNK (write_save) ;
WRITE_CHUNK (write_seek) ;
WRITE_CHUNK (write_expi) ;
WRITE_CHUNK (write_fpri) ;
WRITE_CHUNK (write_phyg) ;
WRITE_CHUNK (write_jhdr) ;
WRITE_CHUNK (write_jdaa) ;
WRITE_CHUNK (write_jdat) ;
WRITE_CHUNK (write_jsep) ;
WRITE_CHUNK (write_dhdr) ;
WRITE_CHUNK (write_prom) ;
WRITE_CHUNK (write_ipng) ;
WRITE_CHUNK (write_pplt) ;
WRITE_CHUNK (write_ijng) ;
WRITE_CHUNK (write_drop) ;
WRITE_CHUNK (write_dbyk) ;
WRITE_CHUNK (write_ordr) ;
WRITE_CHUNK (write_magn) ;
WRITE_CHUNK (write_need) ;
WRITE_CHUNK (write_unknown) ;
/* ************************************************************************** */
#else /* MNG_INCLUDE_WRITE_PROCS */
#define write_ihdr 0
#define write_plte 0
#define write_idat 0
#define write_iend 0
#define write_trns 0
#define write_gama 0
#define write_chrm 0
#define write_srgb 0
#define write_iccp 0
#define write_text 0
#define write_ztxt 0
#define write_itxt 0
#define write_bkgd 0
#define write_phys 0
#define write_sbit 0
#define write_splt 0
#define write_hist 0
#define write_time 0
#define write_mhdr 0
#define write_mend 0
#define write_loop 0
#define write_endl 0
#define write_defi 0
#define write_basi 0
#define write_clon 0
#define write_past 0
#define write_disc 0
#define write_back 0
#define write_fram 0
#define write_move 0
#define write_clip 0
#define write_show 0
#define write_term 0
#define write_save 0
#define write_seek 0
#define write_expi 0
#define write_fpri 0
#define write_phyg 0
#define write_jhdr 0
#define write_jdaa 0
#define write_jdat 0
#define write_jsep 0
#define write_dhdr 0
#define write_prom 0
#define write_ipng 0
#define write_pplt 0
#define write_ijng 0
#define write_drop 0
#define write_dbyk 0
#define write_ordr 0
#define write_magn 0
#define write_need 0
#define write_unknown 0
#endif /* MNG_INCLUDE_WRITE_PROCS */
/* ************************************************************************** */
#endif /* _libmng_chunk_io_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

File diff suppressed because it is too large Load Diff

View File

@@ -1,168 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_chunk_prc.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Chunk initialization & cleanup (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : definition of the chunk initialization & cleanup routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/26/2000 - G.Juyn * */
/* * - added MAGN chunk * */
/* * 0.9.3 - 10/16/2000 - G.Juyn * */
/* * - added support for JDAA * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_chunk_prc_h_
#define _libmng_chunk_prc_h_
/* ************************************************************************** */
void add_chunk (mng_datap pData,
mng_chunkp pChunk);
/* ************************************************************************** */
#define INIT_CHUNK_HDR(n) mng_retcode n (mng_datap pData, \
mng_chunkp pHeader, \
mng_chunkp* ppChunk)
INIT_CHUNK_HDR (init_ihdr) ;
INIT_CHUNK_HDR (init_plte) ;
INIT_CHUNK_HDR (init_idat) ;
INIT_CHUNK_HDR (init_iend) ;
INIT_CHUNK_HDR (init_trns) ;
INIT_CHUNK_HDR (init_gama) ;
INIT_CHUNK_HDR (init_chrm) ;
INIT_CHUNK_HDR (init_srgb) ;
INIT_CHUNK_HDR (init_iccp) ;
INIT_CHUNK_HDR (init_text) ;
INIT_CHUNK_HDR (init_ztxt) ;
INIT_CHUNK_HDR (init_itxt) ;
INIT_CHUNK_HDR (init_bkgd) ;
INIT_CHUNK_HDR (init_phys) ;
INIT_CHUNK_HDR (init_sbit) ;
INIT_CHUNK_HDR (init_splt) ;
INIT_CHUNK_HDR (init_hist) ;
INIT_CHUNK_HDR (init_time) ;
INIT_CHUNK_HDR (init_mhdr) ;
INIT_CHUNK_HDR (init_mend) ;
INIT_CHUNK_HDR (init_loop) ;
INIT_CHUNK_HDR (init_endl) ;
INIT_CHUNK_HDR (init_defi) ;
INIT_CHUNK_HDR (init_basi) ;
INIT_CHUNK_HDR (init_clon) ;
INIT_CHUNK_HDR (init_past) ;
INIT_CHUNK_HDR (init_disc) ;
INIT_CHUNK_HDR (init_back) ;
INIT_CHUNK_HDR (init_fram) ;
INIT_CHUNK_HDR (init_move) ;
INIT_CHUNK_HDR (init_clip) ;
INIT_CHUNK_HDR (init_show) ;
INIT_CHUNK_HDR (init_term) ;
INIT_CHUNK_HDR (init_save) ;
INIT_CHUNK_HDR (init_seek) ;
INIT_CHUNK_HDR (init_expi) ;
INIT_CHUNK_HDR (init_fpri) ;
INIT_CHUNK_HDR (init_need) ;
INIT_CHUNK_HDR (init_phyg) ;
INIT_CHUNK_HDR (init_jhdr) ;
INIT_CHUNK_HDR (init_jdaa) ;
INIT_CHUNK_HDR (init_jdat) ;
INIT_CHUNK_HDR (init_jsep) ;
INIT_CHUNK_HDR (init_dhdr) ;
INIT_CHUNK_HDR (init_prom) ;
INIT_CHUNK_HDR (init_ipng) ;
INIT_CHUNK_HDR (init_pplt) ;
INIT_CHUNK_HDR (init_ijng) ;
INIT_CHUNK_HDR (init_drop) ;
INIT_CHUNK_HDR (init_dbyk) ;
INIT_CHUNK_HDR (init_ordr) ;
INIT_CHUNK_HDR (init_magn) ;
INIT_CHUNK_HDR (init_unknown) ;
/* ************************************************************************** */
#define FREE_CHUNK_HDR(n) mng_retcode n (mng_datap pData, \
mng_chunkp pHeader)
FREE_CHUNK_HDR (free_ihdr) ;
FREE_CHUNK_HDR (free_plte) ;
FREE_CHUNK_HDR (free_idat) ;
FREE_CHUNK_HDR (free_iend) ;
FREE_CHUNK_HDR (free_trns) ;
FREE_CHUNK_HDR (free_gama) ;
FREE_CHUNK_HDR (free_chrm) ;
FREE_CHUNK_HDR (free_srgb) ;
FREE_CHUNK_HDR (free_iccp) ;
FREE_CHUNK_HDR (free_text) ;
FREE_CHUNK_HDR (free_ztxt) ;
FREE_CHUNK_HDR (free_itxt) ;
FREE_CHUNK_HDR (free_bkgd) ;
FREE_CHUNK_HDR (free_phys) ;
FREE_CHUNK_HDR (free_sbit) ;
FREE_CHUNK_HDR (free_splt) ;
FREE_CHUNK_HDR (free_hist) ;
FREE_CHUNK_HDR (free_time) ;
FREE_CHUNK_HDR (free_mhdr) ;
FREE_CHUNK_HDR (free_mend) ;
FREE_CHUNK_HDR (free_loop) ;
FREE_CHUNK_HDR (free_endl) ;
FREE_CHUNK_HDR (free_defi) ;
FREE_CHUNK_HDR (free_basi) ;
FREE_CHUNK_HDR (free_clon) ;
FREE_CHUNK_HDR (free_past) ;
FREE_CHUNK_HDR (free_disc) ;
FREE_CHUNK_HDR (free_back) ;
FREE_CHUNK_HDR (free_fram) ;
FREE_CHUNK_HDR (free_move) ;
FREE_CHUNK_HDR (free_clip) ;
FREE_CHUNK_HDR (free_show) ;
FREE_CHUNK_HDR (free_term) ;
FREE_CHUNK_HDR (free_save) ;
FREE_CHUNK_HDR (free_seek) ;
FREE_CHUNK_HDR (free_expi) ;
FREE_CHUNK_HDR (free_fpri) ;
FREE_CHUNK_HDR (free_need) ;
FREE_CHUNK_HDR (free_phyg) ;
FREE_CHUNK_HDR (free_jhdr) ;
FREE_CHUNK_HDR (free_jdaa) ;
FREE_CHUNK_HDR (free_jdat) ;
FREE_CHUNK_HDR (free_jsep) ;
FREE_CHUNK_HDR (free_dhdr) ;
FREE_CHUNK_HDR (free_prom) ;
FREE_CHUNK_HDR (free_ipng) ;
FREE_CHUNK_HDR (free_pplt) ;
FREE_CHUNK_HDR (free_ijng) ;
FREE_CHUNK_HDR (free_drop) ;
FREE_CHUNK_HDR (free_dbyk) ;
FREE_CHUNK_HDR (free_ordr) ;
FREE_CHUNK_HDR (free_magn) ;
FREE_CHUNK_HDR (free_unknown) ;
/* ************************************************************************** */
#endif /* _libmng_chunk_prc_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

File diff suppressed because it is too large Load Diff

View File

@@ -1,759 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_chunks.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Chunk structures (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of known chunk structures * */
/* * * */
/* * changes : 0.5.1 - 05/04/2000 - G.Juyn * */
/* * - put in some extra comments * */
/* * 0.5.1 - 05/06/2000 - G.Juyn * */
/* * - fixed layout for sBIT, PPLT * */
/* * 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed write callback definition * */
/* * - changed strict-ANSI stuff * */
/* * 0.5.1 - 05/11/2000 - G.Juyn * */
/* * - fixed layout for PPLT again (missed deltatype ?!?) * */
/* * * */
/* * 0.5.2 - 05/31/2000 - G.Juyn * */
/* * - removed useless definition (contributed by Tim Rowley) * */
/* * 0.5.2 - 06/03/2000 - G.Juyn * */
/* * - fixed makeup for Linux gcc compile * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/26/2000 - G.Juyn * */
/* * - added MAGN chunk * */
/* * 0.9.3 - 09/10/2000 - G.Juyn * */
/* * - fixed DEFI behavior * */
/* * 0.9.3 - 10/16/2000 - G.Juyn * */
/* * - added JDAA chunk * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_chunks_h_
#define _libmng_chunks_h_
/* ************************************************************************** */
#ifdef MNG_SWAP_ENDIAN
#define PNG_SIG 0x474e5089L
#define JNG_SIG 0x474e4a8bL
#define MNG_SIG 0x474e4d8aL
#define POST_SIG 0x0a1a0a0dL
#else
#define PNG_SIG 0x89504e47L
#define JNG_SIG 0x8b4a4e47L
#define MNG_SIG 0x8a4d4e47L
#define POST_SIG 0x0d0a1a0aL
#endif
/* ************************************************************************** */
typedef mng_retcode (*mng_createchunk) (mng_datap pData,
mng_chunkp pHeader,
mng_chunkp* ppChunk);
typedef mng_retcode (*mng_cleanupchunk) (mng_datap pData,
mng_chunkp pHeader);
typedef mng_retcode (*mng_readchunk) (mng_datap pData,
mng_chunkp pHeader,
mng_uint32 iRawlen,
mng_uint8p pRawdata,
mng_chunkp* pChunk);
typedef mng_retcode (*mng_writechunk) (mng_datap pData,
mng_chunkp pChunk);
/* ************************************************************************** */
typedef struct { /* generic header */
mng_chunkid iChunkname;
mng_createchunk fCreate;
mng_cleanupchunk fCleanup;
mng_readchunk fRead;
mng_writechunk fWrite;
mng_chunkp pNext; /* for double-linked list */
mng_chunkp pPrev;
} mng_chunk_header;
typedef mng_chunk_header * mng_chunk_headerp;
/* ************************************************************************** */
typedef struct { /* IHDR */
mng_chunk_header sHeader;
mng_uint32 iWidth;
mng_uint32 iHeight;
mng_uint8 iBitdepth;
mng_uint8 iColortype;
mng_uint8 iCompression;
mng_uint8 iFilter;
mng_uint8 iInterlace;
} mng_ihdr;
typedef mng_ihdr * mng_ihdrp;
/* ************************************************************************** */
typedef struct { /* PLTE */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint32 iEntrycount;
mng_rgbpaltab aEntries;
} mng_plte;
typedef mng_plte * mng_pltep;
/* ************************************************************************** */
typedef struct { /* IDAT */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint32 iDatasize;
mng_ptr pData;
} mng_idat;
typedef mng_idat * mng_idatp;
/* ************************************************************************** */
typedef struct { /* IEND */
mng_chunk_header sHeader;
} mng_iend;
typedef mng_iend * mng_iendp;
/* ************************************************************************** */
typedef struct { /* tRNS */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_bool bGlobal;
mng_uint8 iType; /* colortype (0,2,3) */
mng_uint32 iCount;
mng_uint8arr aEntries;
mng_uint16 iGray;
mng_uint16 iRed;
mng_uint16 iGreen;
mng_uint16 iBlue;
mng_uint32 iRawlen;
mng_uint8arr aRawdata;
} mng_trns;
typedef mng_trns * mng_trnsp;
/* ************************************************************************** */
typedef struct { /* gAMA */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint32 iGamma;
} mng_gama;
typedef mng_gama * mng_gamap;
/* ************************************************************************** */
typedef struct { /* cHRM */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint32 iWhitepointx;
mng_uint32 iWhitepointy;
mng_uint32 iRedx;
mng_uint32 iRedy;
mng_uint32 iGreenx;
mng_uint32 iGreeny;
mng_uint32 iBluex;
mng_uint32 iBluey;
} mng_chrm;
typedef mng_chrm * mng_chrmp;
/* ************************************************************************** */
typedef struct { /* sRGB */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint8 iRenderingintent;
} mng_srgb;
typedef mng_srgb * mng_srgbp;
/* ************************************************************************** */
typedef struct { /* iCCP */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint32 iNamesize;
mng_pchar zName;
mng_uint8 iCompression;
mng_uint32 iProfilesize;
mng_ptr pProfile;
} mng_iccp;
typedef mng_iccp * mng_iccpp;
/* ************************************************************************** */
typedef struct { /* tEXt */
mng_chunk_header sHeader;
mng_uint32 iKeywordsize;
mng_pchar zKeyword;
mng_uint32 iTextsize;
mng_pchar zText;
} mng_text;
typedef mng_text * mng_textp;
/* ************************************************************************** */
typedef struct { /* zTXt */
mng_chunk_header sHeader;
mng_uint32 iKeywordsize;
mng_pchar zKeyword;
mng_uint8 iCompression;
mng_uint32 iTextsize;
mng_pchar zText;
} mng_ztxt;
typedef mng_ztxt * mng_ztxtp;
/* ************************************************************************** */
typedef struct { /* iTXt */
mng_chunk_header sHeader;
mng_uint32 iKeywordsize;
mng_pchar zKeyword;
mng_uint8 iCompressionflag;
mng_uint8 iCompressionmethod;
mng_uint32 iLanguagesize;
mng_pchar zLanguage;
mng_uint32 iTranslationsize;
mng_pchar zTranslation;
mng_uint32 iTextsize;
mng_pchar zText;
} mng_itxt;
typedef mng_itxt * mng_itxtp;
/* ************************************************************************** */
typedef struct { /* bKGD */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint8 iType; /* 3=indexed, 0=gray, 2=rgb */
mng_uint8 iIndex;
mng_uint16 iGray;
mng_uint16 iRed;
mng_uint16 iGreen;
mng_uint16 iBlue;
} mng_bkgd;
typedef mng_bkgd * mng_bkgdp;
/* ************************************************************************** */
typedef struct { /* pHYs */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint32 iSizex;
mng_uint32 iSizey;
mng_uint8 iUnit;
} mng_phys;
typedef mng_phys * mng_physp;
/* ************************************************************************** */
typedef struct { /* sBIT */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint8 iType; /* colortype (0,2,3,4,6,10,12,14,16) */
mng_uint8arr4 aBits;
} mng_sbit;
typedef mng_sbit * mng_sbitp;
/* ************************************************************************** */
typedef struct { /* sPLT */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint32 iNamesize;
mng_pchar zName;
mng_uint8 iSampledepth;
mng_uint32 iEntrycount;
mng_ptr pEntries;
} mng_splt;
typedef mng_splt * mng_spltp;
/* ************************************************************************** */
typedef struct { /* hIST */
mng_chunk_header sHeader;
mng_uint32 iEntrycount;
mng_uint16arr aEntries;
} mng_hist;
typedef mng_hist * mng_histp;
/* ************************************************************************** */
typedef struct { /* tIME */
mng_chunk_header sHeader;
mng_uint16 iYear;
mng_uint8 iMonth;
mng_uint8 iDay;
mng_uint8 iHour;
mng_uint8 iMinute;
mng_uint8 iSecond;
} mng_time;
typedef mng_time * mng_timep;
/* ************************************************************************** */
typedef struct { /* MHDR */
mng_chunk_header sHeader;
mng_uint32 iWidth;
mng_uint32 iHeight;
mng_uint32 iTicks;
mng_uint32 iLayercount;
mng_uint32 iFramecount;
mng_uint32 iPlaytime;
mng_uint32 iSimplicity;
} mng_mhdr;
typedef mng_mhdr * mng_mhdrp;
/* ************************************************************************** */
typedef struct { /* MEND */
mng_chunk_header sHeader;
} mng_mend;
typedef mng_mend * mng_mendp;
/* ************************************************************************** */
typedef struct { /* LOOP */
mng_chunk_header sHeader;
mng_uint8 iLevel;
mng_uint32 iRepeat;
mng_uint8 iTermination;
mng_uint32 iItermin;
mng_uint32 iItermax;
mng_uint32 iCount;
mng_uint32p pSignals;
} mng_loop;
typedef mng_loop * mng_loopp;
/* ************************************************************************** */
typedef struct { /* ENDL */
mng_chunk_header sHeader;
mng_uint8 iLevel;
} mng_endl;
typedef mng_endl * mng_endlp;
/* ************************************************************************** */
typedef struct { /* DEFI */
mng_chunk_header sHeader;
mng_uint16 iObjectid;
mng_bool bHasdonotshow;
mng_uint8 iDonotshow;
mng_bool bHasconcrete;
mng_uint8 iConcrete;
mng_bool bHasloca;
mng_int32 iXlocation;
mng_int32 iYlocation;
mng_bool bHasclip;
mng_int32 iLeftcb;
mng_int32 iRightcb;
mng_int32 iTopcb;
mng_int32 iBottomcb;
} mng_defi;
typedef mng_defi * mng_defip;
/* ************************************************************************** */
typedef struct { /* BASI */
mng_chunk_header sHeader;
mng_uint32 iWidth;
mng_uint32 iHeight;
mng_uint8 iBitdepth;
mng_uint8 iColortype;
mng_uint8 iCompression;
mng_uint8 iFilter;
mng_uint8 iInterlace;
mng_uint16 iRed;
mng_uint16 iGreen;
mng_uint16 iBlue;
mng_uint16 iAlpha;
mng_uint8 iViewable;
} mng_basi;
typedef mng_basi * mng_basip;
/* ************************************************************************** */
typedef struct { /* CLON */
mng_chunk_header sHeader;
mng_uint16 iSourceid;
mng_uint16 iCloneid;
mng_uint8 iClonetype;
mng_uint8 iDonotshow;
mng_uint8 iConcrete;
mng_bool bHasloca;
mng_uint8 iLocationtype;
mng_int32 iLocationx;
mng_int32 iLocationy;
} mng_clon;
typedef mng_clon * mng_clonp;
/* ************************************************************************** */
typedef struct { /* PAST source */
mng_uint16 iSourceid;
mng_uint8 iComposition;
mng_uint8 iOrientation;
mng_uint8 iOffsettype;
mng_int32 iOffsetx;
mng_int32 iOffsety;
mng_uint8 iBoundarytype;
mng_int32 iBoundaryl;
mng_int32 iBoundaryr;
mng_int32 iBoundaryt;
mng_int32 iBoundaryb;
} mng_past_source;
typedef mng_past_source * mng_past_sourcep;
typedef struct { /* PAST */
mng_chunk_header sHeader;
mng_uint16 iDestid;
mng_uint8 iTargettype;
mng_int32 iTargetx;
mng_int32 iTargety;
mng_uint32 iCount;
mng_past_sourcep pSources;
} mng_past;
typedef mng_past * mng_pastp;
/* ************************************************************************** */
typedef struct { /* DISC */
mng_chunk_header sHeader;
mng_uint32 iCount;
mng_uint16p pObjectids;
} mng_disc;
typedef mng_disc * mng_discp;
/* ************************************************************************** */
typedef struct { /* BACK */
mng_chunk_header sHeader;
mng_uint16 iRed;
mng_uint16 iGreen;
mng_uint16 iBlue;
mng_uint8 iMandatory;
mng_uint16 iImageid;
mng_uint8 iTile;
} mng_back;
typedef mng_back * mng_backp;
/* ************************************************************************** */
typedef struct { /* FRAM */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint8 iMode;
mng_uint32 iNamesize;
mng_pchar zName;
mng_uint8 iChangedelay;
mng_uint8 iChangetimeout;
mng_uint8 iChangeclipping;
mng_uint8 iChangesyncid;
mng_uint32 iDelay;
mng_uint32 iTimeout;
mng_uint8 iBoundarytype;
mng_int32 iBoundaryl;
mng_int32 iBoundaryr;
mng_int32 iBoundaryt;
mng_int32 iBoundaryb;
mng_uint32 iCount;
mng_uint32p pSyncids;
} mng_fram;
typedef mng_fram * mng_framp;
/* ************************************************************************** */
typedef struct { /* MOVE */
mng_chunk_header sHeader;
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint8 iMovetype;
mng_int32 iMovex;
mng_int32 iMovey;
} mng_move;
typedef mng_move * mng_movep;
/* ************************************************************************** */
typedef struct { /* CLIP */
mng_chunk_header sHeader;
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint8 iCliptype;
mng_int32 iClipl;
mng_int32 iClipr;
mng_int32 iClipt;
mng_int32 iClipb;
} mng_clip;
typedef mng_clip * mng_clipp;
/* ************************************************************************** */
typedef struct { /* SHOW */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint8 iMode;
} mng_show;
typedef mng_show * mng_showp;
/* ************************************************************************** */
typedef struct { /* TERM */
mng_chunk_header sHeader;
mng_uint8 iTermaction;
mng_uint8 iIteraction;
mng_uint32 iDelay;
mng_uint32 iItermax;
} mng_term;
typedef mng_term * mng_termp;
/* ************************************************************************** */
typedef struct { /* SAVE entry */
mng_uint8 iEntrytype;
mng_uint32arr2 iOffset; /* 0=MSI, 1=LSI */
mng_uint32arr2 iStarttime; /* 0=MSI, 1=LSI */
mng_uint32 iLayernr;
mng_uint32 iFramenr;
mng_uint32 iNamesize;
mng_pchar zName;
} mng_save_entry;
typedef mng_save_entry * mng_save_entryp;
typedef struct { /* SAVE */
mng_chunk_header sHeader;
mng_bool bEmpty;
mng_uint8 iOffsettype;
mng_uint32 iCount;
mng_save_entryp pEntries;
} mng_save;
typedef mng_save * mng_savep;
/* ************************************************************************** */
typedef struct { /* SEEK */
mng_chunk_header sHeader;
mng_uint32 iNamesize;
mng_pchar zName;
} mng_seek;
typedef mng_seek * mng_seekp;
/* ************************************************************************** */
typedef struct { /* eXPI */
mng_chunk_header sHeader;
mng_uint16 iSnapshotid;
mng_uint32 iNamesize;
mng_pchar zName;
} mng_expi;
typedef mng_expi * mng_expip;
/* ************************************************************************** */
typedef struct { /* fPRI */
mng_chunk_header sHeader;
mng_uint8 iDeltatype;
mng_uint8 iPriority;
} mng_fpri;
typedef mng_fpri * mng_fprip;
/* ************************************************************************** */
typedef struct { /* nEED */
mng_chunk_header sHeader;
mng_uint32 iKeywordssize;
mng_pchar zKeywords;
} mng_need;
typedef mng_need * mng_needp;
/* ************************************************************************** */
typedef mng_phys mng_phyg; /* pHYg */
typedef mng_phyg * mng_phygp;
/* ************************************************************************** */
#ifdef MNG_INCLUDE_JNG
typedef struct { /* JHDR */
mng_chunk_header sHeader;
mng_uint32 iWidth;
mng_uint32 iHeight;
mng_uint8 iColortype;
mng_uint8 iImagesampledepth;
mng_uint8 iImagecompression;
mng_uint8 iImageinterlace;
mng_uint8 iAlphasampledepth;
mng_uint8 iAlphacompression;
mng_uint8 iAlphafilter;
mng_uint8 iAlphainterlace;
} mng_jhdr;
typedef mng_jhdr * mng_jhdrp;
/* ************************************************************************** */
typedef mng_idat mng_jdaa; /* JDAA */
typedef mng_jdaa * mng_jdaap;
/* ************************************************************************** */
typedef mng_idat mng_jdat; /* JDAT */
typedef mng_jdat * mng_jdatp;
/* ************************************************************************** */
typedef struct { /* JSEP */
mng_chunk_header sHeader;
} mng_jsep;
typedef mng_jsep * mng_jsepp;
#endif /* MNG_INCLUDE_JNG */
/* ************************************************************************** */
typedef struct { /* DHDR */
mng_chunk_header sHeader;
mng_uint16 iObjectid;
mng_uint8 iImagetype;
mng_uint8 iDeltatype;
mng_uint32 iBlockwidth;
mng_uint32 iBlockheight;
mng_uint32 iBlockx;
mng_uint32 iBlocky;
} mng_dhdr;
typedef mng_dhdr * mng_dhdrp;
/* ************************************************************************** */
typedef struct { /* PROM */
mng_chunk_header sHeader;
mng_uint8 iColortype;
mng_uint8 iSampledepth;
mng_uint8 iFilltype;
} mng_prom;
typedef mng_prom * mng_promp;
/* ************************************************************************** */
typedef struct { /* IPNG */
mng_chunk_header sHeader;
} mng_ipng;
typedef mng_ipng *mng_ipngp;
/* ************************************************************************** */
typedef struct { /* PPLT entry */
mng_uint8 iRed;
mng_uint8 iGreen;
mng_uint8 iBlue;
mng_uint8 iAlpha;
mng_bool bUsed;
} mng_pplt_entry;
typedef mng_pplt_entry * mng_pplt_entryp;
typedef struct { /* PPLT */
mng_chunk_header sHeader;
mng_uint8 iDeltatype;
mng_uint32 iCount;
mng_pplt_entry aEntries [256];
} mng_pplt;
typedef mng_pplt * mng_ppltp;
/* ************************************************************************** */
typedef struct { /* IJNG */
mng_chunk_header sHeader;
} mng_ijng;
typedef mng_ijng *mng_ijngp;
/* ************************************************************************** */
typedef struct { /* DROP */
mng_chunk_header sHeader;
mng_uint32 iCount;
mng_chunkidp pChunknames;
} mng_drop;
typedef mng_drop * mng_dropp;
/* ************************************************************************** */
typedef struct { /* DBYK */
mng_chunk_header sHeader;
mng_chunkid iChunkname;
mng_uint8 iPolarity;
mng_uint32 iKeywordssize;
mng_pchar zKeywords;
} mng_dbyk;
typedef mng_dbyk * mng_dbykp;
/* ************************************************************************** */
typedef struct { /* ORDR entry */
mng_chunkid iChunkname;
mng_uint8 iOrdertype;
} mng_ordr_entry;
typedef mng_ordr_entry * mng_ordr_entryp;
typedef struct mng_ordr_struct { /* ORDR */
mng_chunk_header sHeader;
mng_uint32 iCount;
mng_ordr_entryp pEntries;
} mng_ordr;
typedef mng_ordr * mng_ordrp;
/* ************************************************************************** */
typedef struct { /* MAGN */
mng_chunk_header sHeader;
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint16 iMethodX;
mng_uint16 iMX;
mng_uint16 iMY;
mng_uint16 iML;
mng_uint16 iMR;
mng_uint16 iMT;
mng_uint16 iMB;
mng_uint16 iMethodY;
} mng_magn;
typedef mng_magn * mng_magnp;
/* ************************************************************************** */
typedef struct { /* unknown chunk */
mng_chunk_header sHeader;
mng_uint32 iDatasize;
mng_ptr pData;
} mng_unknown_chunk;
typedef mng_unknown_chunk * mng_unknown_chunkp;
/* ************************************************************************** */
#endif /* _libmng_chunks_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,928 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_cms.c copyright (c) 2000 G.Juyn * */
/* * version : 1.0.1 * */
/* * * */
/* * purpose : color management routines (implementation) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : implementation of the color management routines * */
/* * * */
/* * changes : 0.5.1 - 05/01/2000 - G.Juyn * */
/* * - B001(105795) - fixed a typo and misconception about * */
/* * freeing allocated gamma-table. (reported by Marti Maria) * */
/* * 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * 0.5.1 - 05/09/2000 - G.Juyn * */
/* * - filled application-based color-management routines * */
/* * 0.5.1 - 05/11/2000 - G.Juyn * */
/* * - added creatememprofile * */
/* * - added callback error-reporting support * */
/* * 0.5.1 - 05/12/2000 - G.Juyn * */
/* * - changed trace to macro for callback error-reporting * */
/* * * */
/* * 0.5.2 - 06/10/2000 - G.Juyn * */
/* * - fixed some compilation-warnings (contrib Jason Morris) * */
/* * * */
/* * 0.5.3 - 06/21/2000 - G.Juyn * */
/* * - fixed problem with color-correction for stored images * */
/* * 0.5.3 - 06/23/2000 - G.Juyn * */
/* * - fixed problem with incorrect gamma-correction * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/31/2000 - G.Juyn * */
/* * - fixed sRGB precedence for gamma_only corection * */
/* * * */
/* * 0.9.4 - 12/16/2000 - G.Juyn * */
/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
/* * * */
/* * 1.0.1 - 03/31/2001 - G.Juyn * */
/* * - ignore gamma=0 (see png-list for more info) * */
/* * 1.0.1 - 04/25/2001 - G.Juyn (reported by Gregg Kelly) * */
/* * - fixed problem with cms profile being created multiple * */
/* * times when both iCCP & cHRM/gAMA are present * */
/* * 1.0.1 - 04/25/2001 - G.Juyn * */
/* * - moved mng_clear_cms to libmng_cms * */
/* * 1.0.1 - 05/02/2001 - G.Juyn * */
/* * - added "default" sRGB generation (Thanks Marti!) * */
/* * * */
/* ************************************************************************** */
#include "libmng.h"
#include "libmng_data.h"
#include "libmng_error.h"
#include "libmng_trace.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "libmng_objects.h"
#include "libmng_cms.h"
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
/* ************************************************************************** */
#ifdef MNG_INCLUDE_DISPLAY_PROCS
/* ************************************************************************** */
/* * * */
/* * Little CMS helper routines * */
/* * * */
/* ************************************************************************** */
#ifdef MNG_INCLUDE_LCMS
#define MNG_CMS_FLAGS 0
/* ************************************************************************** */
void mnglcms_initlibrary ()
{
cmsErrorAction (LCMS_ERROR_IGNORE); /* LCMS should ignore errors! */
}
/* ************************************************************************** */
mng_cmsprof mnglcms_createfileprofile (mng_pchar zFilename)
{
return cmsOpenProfileFromFile (zFilename, "r");
}
/* ************************************************************************** */
mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
mng_ptr pProfile)
{
return cmsOpenProfileFromMem (pProfile, iProfilesize);
}
/* ************************************************************************** */
mng_cmsprof mnglcms_createsrgbprofile (void)
{
cmsCIExyY D65;
cmsCIExyYTRIPLE Rec709Primaries = {
{0.6400, 0.3300, 1.0},
{0.3000, 0.6000, 1.0},
{0.1500, 0.0600, 1.0}
};
LPGAMMATABLE Gamma24[3];
mng_cmsprof hsRGB;
cmsWhitePointFromTemp(6504, &D65);
Gamma24[0] = Gamma24[1] = Gamma24[2] = cmsBuildGamma(256, 2.4);
hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma24);
cmsFreeGamma(Gamma24[0]);
return hsRGB;
}
/* ************************************************************************** */
void mnglcms_freeprofile (mng_cmsprof hProf)
{
cmsCloseProfile (hProf);
return;
}
/* ************************************************************************** */
void mnglcms_freetransform (mng_cmstrans hTrans)
{
/* B001 start */
cmsDeleteTransform (hTrans);
/* B001 end */
return;
}
/* ************************************************************************** */
mng_retcode mng_clear_cms (mng_datap pData)
{
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_START)
#endif
if (pData->hTrans) /* transformation still active ? */
mnglcms_freetransform (pData->hTrans);
pData->hTrans = 0;
if (pData->hProf1) /* file profile still active ? */
mnglcms_freeprofile (pData->hProf1);
pData->hProf1 = 0;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
#endif /* MNG_INCLUDE_LCMS */
/* ************************************************************************** */
/* * * */
/* * Color-management initialization & correction routines * */
/* * * */
/* ************************************************************************** */
#ifdef MNG_INCLUDE_LCMS
mng_retcode init_full_cms (mng_datap pData)
{
mng_cmsprof hProf;
mng_cmstrans hTrans;
mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
mng_imagedatap pBuf;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_START)
#endif
if (!pImage) /* no current object? then use object 0 */
pImage = (mng_imagep)pData->pObjzero;
pBuf = pImage->pImgbuf; /* address the buffer */
if ((pBuf->bHasICCP) || (pData->bHasglobalICCP))
{
if (!pData->hProf2) /* output profile not defined ? */
{ /* then assume sRGB !! */
pData->hProf2 = mnglcms_createsrgbprofile ();
if (!pData->hProf2) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
}
if (pBuf->bHasICCP) /* generate a profile handle */
hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
else
hProf = cmsOpenProfileFromMem (pData->pGlobalProfile, pData->iGlobalProfilesize);
pData->hProf1 = hProf; /* save for future use */
if (!hProf) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
if (pData->bIsRGBA16) /* 16-bit intermediates ? */
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
pData->hProf2, TYPE_RGBA_16_SE,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
else
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
pData->hProf2, TYPE_RGBA_8,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
pData->hTrans = hTrans; /* save for future use */
if (!hTrans) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_full_cms;
return MNG_NOERROR; /* and done */
}
else
if ((pBuf->bHasSRGB) || (pData->bHasglobalSRGB))
{
mng_uint8 iIntent;
if (pData->bIssRGB) /* sRGB system ? */
return MNG_NOERROR; /* no conversion required */
if (!pData->hProf3) /* sRGB profile not defined ? */
{ /* then create it implicitly !! */
pData->hProf3 = mnglcms_createsrgbprofile ();
if (!pData->hProf3) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
}
hProf = pData->hProf3; /* convert from sRGB profile */
if (pBuf->bHasSRGB) /* determine rendering intent */
iIntent = pBuf->iRenderingintent;
else
iIntent = pData->iGlobalRendintent;
if (pData->bIsRGBA16) /* 16-bit intermediates ? */
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
pData->hProf2, TYPE_RGBA_16_SE,
iIntent, MNG_CMS_FLAGS);
else
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
pData->hProf2, TYPE_RGBA_8,
iIntent, MNG_CMS_FLAGS);
pData->hTrans = hTrans; /* save for future use */
if (!hTrans) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_full_cms;
return MNG_NOERROR; /* and done */
}
else
if ( ((pBuf->bHasCHRM) || (pData->bHasglobalCHRM)) &&
( ((pBuf->bHasGAMA) && (pBuf->iGamma > 0)) ||
((pData->bHasglobalGAMA) && (pData->iGlobalGamma > 0)) ))
{
mng_CIExyY sWhitepoint;
mng_CIExyYTRIPLE sPrimaries;
mng_gammatabp pGammatable[3];
mng_float dGamma;
if (!pData->hProf2) /* output profile not defined ? */
{ /* then assume sRGB !! */
pData->hProf2 = mnglcms_createsrgbprofile ();
if (!pData->hProf2) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
}
if (pBuf->bHasCHRM) /* local cHRM ? */
{
sWhitepoint.x = (mng_float)pBuf->iWhitepointx / 100000;
sWhitepoint.y = (mng_float)pBuf->iWhitepointy / 100000;
sPrimaries.Red.x = (mng_float)pBuf->iPrimaryredx / 100000;
sPrimaries.Red.y = (mng_float)pBuf->iPrimaryredy / 100000;
sPrimaries.Green.x = (mng_float)pBuf->iPrimarygreenx / 100000;
sPrimaries.Green.y = (mng_float)pBuf->iPrimarygreeny / 100000;
sPrimaries.Blue.x = (mng_float)pBuf->iPrimarybluex / 100000;
sPrimaries.Blue.y = (mng_float)pBuf->iPrimarybluey / 100000;
}
else
{
sWhitepoint.x = (mng_float)pData->iGlobalWhitepointx / 100000;
sWhitepoint.y = (mng_float)pData->iGlobalWhitepointy / 100000;
sPrimaries.Red.x = (mng_float)pData->iGlobalPrimaryredx / 100000;
sPrimaries.Red.y = (mng_float)pData->iGlobalPrimaryredy / 100000;
sPrimaries.Green.x = (mng_float)pData->iGlobalPrimarygreenx / 100000;
sPrimaries.Green.y = (mng_float)pData->iGlobalPrimarygreeny / 100000;
sPrimaries.Blue.x = (mng_float)pData->iGlobalPrimarybluex / 100000;
sPrimaries.Blue.y = (mng_float)pData->iGlobalPrimarybluey / 100000;
}
sWhitepoint.Y = /* Y component is always 1.0 */
sPrimaries.Red.Y =
sPrimaries.Green.Y =
sPrimaries.Blue.Y = 1.0;
if (pBuf->bHasGAMA) /* get the gamma value */
dGamma = (mng_float)pBuf->iGamma / 100000;
else
dGamma = (mng_float)pData->iGlobalGamma / 100000;
/* dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma); ??? */
dGamma = pData->dViewgamma / dGamma;
pGammatable [0] = /* and build the lookup tables */
pGammatable [1] =
pGammatable [2] = cmsBuildGamma (256, dGamma);
/* B001 start */
if (!pGammatable [0]) /* enough memory ? */
/* B001 end */
MNG_ERRORL (pData, MNG_LCMS_NOMEM)
/* create the profile */
hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
/* B001 start */
cmsFreeGamma (pGammatable [0]); /* free the temporary gamma tables ? */
/* yes! but just the one! */
/* B001 end */
pData->hProf1 = hProf; /* save for future use */
if (!hProf) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
if (pData->bIsRGBA16) /* 16-bit intermediates ? */
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
pData->hProf2, TYPE_RGBA_16_SE,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
else
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
pData->hProf2, TYPE_RGBA_8,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
pData->hTrans = hTrans; /* save for future use */
if (!hTrans) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_full_cms;
return MNG_NOERROR; /* and done */
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_END)
#endif
return init_gamma_only (pData); /* if we get here, we'll only do gamma */
}
#endif /* MNG_INCLUDE_LCMS */
/* ************************************************************************** */
#ifdef MNG_INCLUDE_LCMS
mng_retcode init_full_cms_object (mng_datap pData)
{
mng_cmsprof hProf;
mng_cmstrans hTrans;
mng_imagedatap pBuf;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS_OBJ, MNG_LC_START)
#endif
/* address the object-buffer */
pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
if (pBuf->bHasICCP)
{
if (!pData->hProf2) /* output profile not defined ? */
{ /* then assume sRGB !! */
pData->hProf2 = mnglcms_createsrgbprofile ();
if (!pData->hProf2) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
}
/* generate a profile handle */
hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
pData->hProf1 = hProf; /* save for future use */
if (!hProf) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
if (pData->bIsRGBA16) /* 16-bit intermediates ? */
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
pData->hProf2, TYPE_RGBA_16_SE,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
else
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
pData->hProf2, TYPE_RGBA_8,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
pData->hTrans = hTrans; /* save for future use */
if (!hTrans) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_full_cms;
return MNG_NOERROR; /* and done */
}
else
if (pBuf->bHasSRGB)
{
if (pData->bIssRGB) /* sRGB system ? */
return MNG_NOERROR; /* no conversion required */
if (!pData->hProf3) /* sRGB profile not defined ? */
{ /* then create it implicitly !! */
pData->hProf3 = mnglcms_createsrgbprofile ();
if (!pData->hProf3) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
}
hProf = pData->hProf3; /* convert from sRGB profile */
if (pData->bIsRGBA16) /* 16-bit intermediates ? */
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
pData->hProf2, TYPE_RGBA_16_SE,
pBuf->iRenderingintent, MNG_CMS_FLAGS);
else
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
pData->hProf2, TYPE_RGBA_8,
pBuf->iRenderingintent, MNG_CMS_FLAGS);
pData->hTrans = hTrans; /* save for future use */
if (!hTrans) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_full_cms;
return MNG_NOERROR; /* and done */
}
else
if ((pBuf->bHasCHRM) && (pBuf->bHasGAMA) && (pBuf->iGamma > 0))
{
mng_CIExyY sWhitepoint;
mng_CIExyYTRIPLE sPrimaries;
mng_gammatabp pGammatable[3];
mng_float dGamma;
if (!pData->hProf2) /* output profile not defined ? */
{ /* then assume sRGB !! */
pData->hProf2 = mnglcms_createsrgbprofile ();
if (!pData->hProf2) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
}
sWhitepoint.x = (mng_float)pBuf->iWhitepointx / 100000;
sWhitepoint.y = (mng_float)pBuf->iWhitepointy / 100000;
sPrimaries.Red.x = (mng_float)pBuf->iPrimaryredx / 100000;
sPrimaries.Red.y = (mng_float)pBuf->iPrimaryredy / 100000;
sPrimaries.Green.x = (mng_float)pBuf->iPrimarygreenx / 100000;
sPrimaries.Green.y = (mng_float)pBuf->iPrimarygreeny / 100000;
sPrimaries.Blue.x = (mng_float)pBuf->iPrimarybluex / 100000;
sPrimaries.Blue.y = (mng_float)pBuf->iPrimarybluey / 100000;
sWhitepoint.Y = /* Y component is always 1.0 */
sPrimaries.Red.Y =
sPrimaries.Green.Y =
sPrimaries.Blue.Y = 1.0;
dGamma = (mng_float)pBuf->iGamma / 100000;
/* dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma); ??? */
dGamma = pData->dViewgamma / dGamma;
pGammatable [0] = /* and build the lookup tables */
pGammatable [1] =
pGammatable [2] = cmsBuildGamma (256, dGamma);
/* B001 start */
if (!pGammatable [0]) /* enough memory ? */
/* B001 end */
MNG_ERRORL (pData, MNG_LCMS_NOMEM)
/* create the profile */
hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
/* B001 start */
cmsFreeGamma (pGammatable [0]); /* free the temporary gamma tables ? */
/* yes! but just the one! */
/* B001 end */
pData->hProf1 = hProf; /* save for future use */
if (!hProf) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
if (pData->bIsRGBA16) /* 16-bit intermediates ? */
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
pData->hProf2, TYPE_RGBA_16_SE,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
else
hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
pData->hProf2, TYPE_RGBA_8,
INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
pData->hTrans = hTrans; /* save for future use */
if (!hTrans) /* handle error ? */
MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_full_cms;
return MNG_NOERROR; /* and done */
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS_OBJ, MNG_LC_END)
#endif
/* if we get here, we'll only do gamma */
return init_gamma_only_object (pData);
}
#endif /* MNG_INCLUDE_LCMS */
/* ************************************************************************** */
#ifdef MNG_INCLUDE_LCMS
mng_retcode correct_full_cms (mng_datap pData)
{
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_START)
#endif
cmsDoTransform (pData->hTrans, pData->pRGBArow, pData->pRGBArow, pData->iRowsamples);
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_END)
#endif
return MNG_NOERROR;
}
#endif /* MNG_INCLUDE_LCMS */
/* ************************************************************************** */
#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
mng_retcode init_gamma_only (mng_datap pData)
{
mng_float dGamma;
mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
mng_imagedatap pBuf;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_START)
#endif
if (!pImage) /* no current object? then use object 0 */
pImage = (mng_imagep)pData->pObjzero;
pBuf = pImage->pImgbuf; /* address the buffer */
if (pBuf->bHasSRGB) /* get the gamma value */
dGamma = 0.45455;
else
if (pBuf->bHasGAMA)
dGamma = (mng_float)pBuf->iGamma / 100000;
else
if (pData->bHasglobalSRGB)
dGamma = 0.45455;
else
if (pData->bHasglobalGAMA)
dGamma = (mng_float)pData->iGlobalGamma / 100000;
else
dGamma = pData->dDfltimggamma;
if (dGamma > 0) /* ignore gamma=0 */
{
dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma);
if (dGamma != pData->dLastgamma) /* lookup table needs to be computed ? */
{
mng_int32 iX;
pData->aGammatab [0] = 0;
for (iX = 1; iX <= 255; iX++)
pData->aGammatab [iX] = (mng_uint8)(pow (iX / 255.0, dGamma) * 255 + 0.5);
pData->dLastgamma = dGamma; /* keep for next time */
}
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_gamma_only;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_END)
#endif
return MNG_NOERROR;
}
#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS */
/* ************************************************************************** */
#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
mng_retcode init_gamma_only_object (mng_datap pData)
{
mng_float dGamma;
mng_imagedatap pBuf;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY_OBJ, MNG_LC_START)
#endif
/* address the object-buffer */
pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
if (pBuf->bHasSRGB) /* get the gamma value */
dGamma = 0.45455;
else
if (pBuf->bHasGAMA)
dGamma = (mng_float)pBuf->iGamma / 100000;
else
dGamma = pData->dDfltimggamma;
if (dGamma) /* lets not divide by zero, shall we... */
dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma);
if (dGamma != pData->dLastgamma) /* lookup table needs to be computed ? */
{
mng_int32 iX;
pData->aGammatab [0] = 0;
for (iX = 1; iX <= 255; iX++)
pData->aGammatab [iX] = (mng_uint8)(pow (iX / 255.0, dGamma) * 255 + 0.5);
pData->dLastgamma = dGamma; /* keep for next time */
}
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_gamma_only;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY_OBJ, MNG_LC_END)
#endif
return MNG_NOERROR;
}
#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS */
/* ************************************************************************** */
#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
mng_retcode correct_gamma_only (mng_datap pData)
{
mng_uint8p pWork;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_START)
#endif
pWork = pData->pRGBArow; /* address intermediate row */
if (pData->bIsRGBA16) /* 16-bit intermediate row ? */
{
/* TODO: 16-bit precision gamma processing */
/* we'll just do the high-order byte for now */
/* convert all samples in the row */
for (iX = 0; iX < pData->iRowsamples; iX++)
{ /* using the precalculated gamma lookup table */
*pWork = pData->aGammatab [*pWork];
*(pWork+2) = pData->aGammatab [*(pWork+2)];
*(pWork+4) = pData->aGammatab [*(pWork+4)];
pWork += 8;
}
}
else
{ /* convert all samples in the row */
for (iX = 0; iX < pData->iRowsamples; iX++)
{ /* using the precalculated gamma lookup table */
*pWork = pData->aGammatab [*pWork];
*(pWork+1) = pData->aGammatab [*(pWork+1)];
*(pWork+2) = pData->aGammatab [*(pWork+2)];
pWork += 4;
}
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_END)
#endif
return MNG_NOERROR;
}
#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS */
/* ************************************************************************** */
#ifdef MNG_APP_CMS
mng_retcode init_app_cms (mng_datap pData)
{
mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_START)
#endif
if ( (pData->fProcessiccp) &&
((pBuf->bHasICCP) || (pData->bHasglobalICCP)) )
{
mng_uint32 iProfilesize;
mng_ptr pProfile;
if (pBuf->bHasICCP) /* get the right profile */
{
iProfilesize = pBuf->iProfilesize;
pProfile = pBuf->pProfile;
}
else
{
iProfilesize = pData->iGlobalProfilesize;
pProfile = pData->pGlobalProfile;
}
/* inform the app */
if (!pData->fProcessiccp ((mng_handle)pData, iProfilesize, pProfile))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
if ( (pData->fProcesssrgb) &&
((pBuf->bHasSRGB) || (pData->bHasglobalSRGB)) )
{
mng_uint8 iIntent;
if (pBuf->bHasSRGB) /* determine rendering intent */
iIntent = pBuf->iRenderingintent;
else
iIntent = pData->iGlobalRendintent;
/* inform the app */
if (!pData->fProcesssrgb ((mng_handle)pData, iIntent))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
if ( (pData->fProcesschroma) &&
( ((pBuf->bHasCHRM) || (pData->bHasglobalCHRM)) ) )
{
mng_uint32 iWhitepointx, iWhitepointy;
mng_uint32 iPrimaryredx, iPrimaryredy;
mng_uint32 iPrimarygreenx, iPrimarygreeny;
mng_uint32 iPrimarybluex, iPrimarybluey;
if (pBuf->bHasCHRM) /* local cHRM ? */
{
iWhitepointx = pBuf->iWhitepointx;
iWhitepointy = pBuf->iWhitepointy;
iPrimaryredx = pBuf->iPrimaryredx;
iPrimaryredy = pBuf->iPrimaryredy;
iPrimarygreenx = pBuf->iPrimarygreenx;
iPrimarygreeny = pBuf->iPrimarygreeny;
iPrimarybluex = pBuf->iPrimarybluex;
iPrimarybluey = pBuf->iPrimarybluey;
}
else
{
iWhitepointx = pData->iGlobalWhitepointx;
iWhitepointy = pData->iGlobalWhitepointy;
iPrimaryredx = pData->iGlobalPrimaryredx;
iPrimaryredy = pData->iGlobalPrimaryredy;
iPrimarygreenx = pData->iGlobalPrimarygreenx;
iPrimarygreeny = pData->iGlobalPrimarygreeny;
iPrimarybluex = pData->iGlobalPrimarybluex;
iPrimarybluey = pData->iGlobalPrimarybluey;
}
/* inform the app */
if (!pData->fProcesschroma ((mng_handle)pData, iWhitepointx, iWhitepointy,
iPrimaryredx, iPrimaryredy,
iPrimarygreenx, iPrimarygreeny,
iPrimarybluex, iPrimarybluey))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
if ( (pData->fProcessgamma) &&
((pBuf->bHasGAMA) || (pData->bHasglobalGAMA)) )
{
mng_uint32 iGamma;
if (pBuf->bHasGAMA) /* get the gamma value */
iGamma = pBuf->iGamma;
else
iGamma = pData->iGlobalGamma;
/* inform the app */
if (!pData->fProcessgamma ((mng_handle)pData, iGamma))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_END)
#endif
return MNG_NOERROR;
}
#endif /* MNG_APP_CMS */
/* ************************************************************************** */
#ifdef MNG_APP_CMS
mng_retcode init_app_cms_object (mng_datap pData)
{
mng_imagedatap pBuf = ((mng_imagep)pData->pCurrentobj)->pImgbuf;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_APP_CMS_OBJ, MNG_LC_START)
#endif
if ((pData->fProcessiccp) && (pBuf->bHasICCP))
{ /* inform the app */
if (!pData->fProcessiccp ((mng_handle)pData, pBuf->iProfilesize, pBuf->pProfile))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
if ((pData->fProcesssrgb) && (pBuf->bHasSRGB))
{ /* inform the app */
if (!pData->fProcesssrgb ((mng_handle)pData, pBuf->iRenderingintent))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
if ((pData->fProcesschroma) && (pBuf->bHasCHRM))
{ /* inform the app */
if (!pData->fProcesschroma ((mng_handle)pData, pBuf->iWhitepointx, pBuf->iWhitepointy,
pBuf->iPrimaryredx, pBuf->iPrimaryredy,
pBuf->iPrimarygreenx, pBuf->iPrimarygreeny,
pBuf->iPrimarybluex, pBuf->iPrimarybluey))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
if ((pData->fProcessgamma) && (pBuf->bHasGAMA))
{ /* inform the app */
if (!pData->fProcessgamma ((mng_handle)pData, pBuf->iGamma))
MNG_ERROR (pData, MNG_APPCMSERROR)
/* load color-correction routine */
pData->fCorrectrow = (mng_fptr)correct_app_cms;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_APP_CMS_OBJ, MNG_LC_END)
#endif
return MNG_NOERROR;
}
#endif /* MNG_APP_CMS */
/* ************************************************************************** */
#ifdef MNG_APP_CMS
mng_retcode correct_app_cms (mng_datap pData)
{
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_START)
#endif
if (pData->fProcessarow) /* let the app do something with our row */
if (!pData->fProcessarow ((mng_handle)pData, pData->iRowsamples,
pData->bIsRGBA16, pData->pRGBArow))
MNG_ERROR (pData, MNG_APPCMSERROR)
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_END)
#endif
return MNG_NOERROR;
}
#endif /* MNG_APP_CMS */
/* ************************************************************************** */
#endif /* MNG_INCLUDE_DISPLAY_PROCS */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,80 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_cms.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.1 * */
/* * * */
/* * purpose : color management routines (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of color management routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * 0.5.1 - 05/11/2000 - G.Juyn * */
/* * - added creatememprofile * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 1.0.1 - 04/25/2001 - G.Juyn * */
/* * - moved mng_clear_cms to libmng_cms * */
/* * 1.0.1 - 05/02/2001 - G.Juyn * */
/* * - added "default" sRGB generation (Thanks Marti!) * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_cms_h_
#define _libmng_cms_h_
/* ************************************************************************** */
#ifdef MNG_INCLUDE_LCMS
void mnglcms_initlibrary (void);
mng_cmsprof mnglcms_createfileprofile (mng_pchar zFilename);
mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
mng_ptr pProfile );
mng_cmsprof mnglcms_createsrgbprofile (void);
void mnglcms_freeprofile (mng_cmsprof hProf );
void mnglcms_freetransform (mng_cmstrans hTrans );
mng_retcode mng_clear_cms (mng_datap pData );
#endif
/* ************************************************************************** */
#ifdef MNG_FULL_CMS
mng_retcode init_full_cms (mng_datap pData);
mng_retcode init_full_cms_object (mng_datap pData);
mng_retcode correct_full_cms (mng_datap pData);
#endif
#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY)
mng_retcode init_gamma_only (mng_datap pData);
mng_retcode init_gamma_only_object (mng_datap pData);
mng_retcode correct_gamma_only (mng_datap pData);
#endif
#ifdef MNG_APP_CMS
mng_retcode init_app_cms (mng_datap pData);
mng_retcode init_app_cms_object (mng_datap pData);
mng_retcode correct_app_cms (mng_datap pData);
#endif
/* ************************************************************************** */
#endif /* _libmng_cms_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,209 +0,0 @@
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_conf.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : main configuration file * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : The configuration file. Change this to include/exclude * */
/* * the options you want or do not want in libmng. * */
/* * * */
/* * changes : 0.5.2 - 06/02/2000 - G.Juyn * */
/* * - separated configuration-options into this file * */
/* * - changed to most likely configuration (?) * */
/* * 0.5.2 - 06/03/2000 - G.Juyn * */
/* * - changed options to create a standard so-library * */
/* * with everything enabled * */
/* * 0.5.2 - 06/04/2000 - G.Juyn * */
/* * - changed options to create a standard win32-dll * */
/* * with everything enabled * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/12/2000 - G.Juyn * */
/* * - added workaround for faulty PhotoShop iCCP chunk * */
/* * 0.9.3 - 09/16/2000 - G.Juyn * */
/* * - removed trace-options from default SO/DLL builds * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_conf_h_
#define _libmng_conf_h_
/* ************************************************************************** */
/* * * */
/* * User-selectable compile-time options * */
/* * * */
/* ************************************************************************** */
/* enable exactly one(1) of the MNG-(sub)set selectors */
/* use this to select which (sub)set of the MNG specification you wish
to support */
/* generally you'll want full support as the library provides it automatically
for you! if you're really strung on memory-requirements you can opt
to enable less support (but it's just NOT a good idea!) */
/* NOTE that this isn't actually implemented yet */
#if !defined(MNG_SUPPORT_FULL) && !defined(MNG_SUPPORT_LC) && !defined(MNG_SUPPORT_VLC)
#define MNG_SUPPORT_FULL
/* #define MNG_SUPPORT_LC */
/* #define MNG_SUPPORT_VLC */
#endif
/* ************************************************************************** */
/* enable JPEG support if required */
/* use this to enable the JNG support routines */
/* this requires an external jpeg package;
currently only IJG's jpgsrc6b is supported! */
/* NOTE that the IJG code can be either 8- or 12-bit (eg. not both);
so choose the one you've defined in jconfig.h; if you don't know what
the heck I'm talking about, just leave it at 8-bit support (thank you!) */
#ifdef MNG_SUPPORT_FULL /* full support includes JNG */
#define MNG_SUPPORT_IJG6B
#endif
#ifndef MNG_SUPPORT_IJG6B
#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
#define MNG_SUPPORT_IJG6B
#endif
#endif
#if defined(MNG_SUPPORT_IJG6B) && !defined(MNG_SUPPORT_JPEG8) && !defined(MNG_SUPPORT_JPEG12)
#define MNG_SUPPORT_JPEG8
/* #define MNG_SUPPORT_JPEG12 */
#endif
/* ************************************************************************** */
/* enable required high-level functions */
/* use this to select the high-level functions you require */
/* if you only need to display a MNG, disable write support! */
/* if you only need to examine a MNG, disable write & display support! */
/* if you only need to copy a MNG, disable display support! */
/* if you only need to create a MNG, disable read & display support! */
/* NOTE that turning all options off will be very unuseful! */
#if !defined(MNG_SUPPORT_READ) && !defined(MNG_SUPPORT_WRITE) && !defined(MNG_SUPPORT_DISPLAY)
#define MNG_SUPPORT_READ
#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
#define MNG_SUPPORT_WRITE
#endif
#define MNG_SUPPORT_DISPLAY
#endif
/* ************************************************************************** */
/* enable chunk access functions */
/* use this to select whether you need access to the individual chunks */
/* useful if you want to examine a read MNG (you'll also need MNG_STORE_CHUNKS !)*/
/* required if you need to create & write a new MNG! */
#ifndef MNG_ACCESS_CHUNKS
#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
#define MNG_ACCESS_CHUNKS
#endif
#endif
/* ************************************************************************** */
/* enable exactly one of the color-management-functionality selectors */
/* use this to select the level of automatic color support */
/* MNG_FULL_CMS requires the lcms (little cms) external package ! */
/* if you want your own app (or the OS) to handle color-management
select MNG_APP_CMS */
#if !defined(MNG_FULL_CMS) && !defined(MNG_GAMMA_ONLY) && !defined(MNG_NO_CMS) && !defined(MNG_APP_CMS)
#if defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
#define MNG_FULL_CMS
#else
#define MNG_GAMMA_ONLY
#endif
/* #define MNG_NO_CMS */
/* #define MNG_APP_CMS */
#endif
/* ************************************************************************** */
/* enable automatic dithering */
/* use this if you need dithering support to convert high-resolution
images to a low-resolution output-device */
/* NOTE that this is not supported yet */
/* #define MNG_AUTO_DITHER */
/* ************************************************************************** */
/* enable whether chunks should be stored for reference later */
/* use this if you need to examine the chunks of a MNG you have read,
or (re-)write a MNG you have read */
/* turn this off if you want to reduce memory-consumption */
#ifndef MNG_STORE_CHUNKS
#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
#define MNG_STORE_CHUNKS
#endif
#endif
/* ************************************************************************** */
/* enable internal memory management (if your compiler supports it) */
/* use this if your compiler supports the 'standard' memory functions
(calloc & free), and you want the library to use these functions and not
bother your app with memory-callbacks */
/* #define MNG_INTERNAL_MEMMNGMT */
/* ************************************************************************** */
/* enable internal tracing-functionality (manual debugging purposes) */
/* use this if you have trouble location bugs or problems */
/* NOTE that you'll need to specify the trace callback function! */
/* #define MNG_SUPPORT_TRACE */
/* ************************************************************************** */
/* enable extended error- and trace-telltaling */
/* use this if you need explanatory messages with errors and/or tracing */
#if !defined(MNG_ERROR_TELLTALE) && !defined(MNG_TRACE_TELLTALE)
#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
#define MNG_ERROR_TELLTALE
#define MNG_TRACE_TELLTALE
#endif
#endif
/* ************************************************************************** */
/* enable big-endian support */
/* enable this if you're on an architecture that supports big-endian reads
and writes that aren't word-aligned */
/* according to reliable sources this only works for PowerPC (bigendian mode)
and 680x0 */
/* #define MNG_BIGENDIAN_SUPPORTED */
/* ************************************************************************** */
/* * * */
/* * End of user-selectable compile-time options * */
/* * * */
/* ************************************************************************** */
#endif /* _libmng_conf_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,759 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_data.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.1 * */
/* * * */
/* * purpose : main data structure definition * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the library main data structure * */
/* * * */
/* * changes : 0.5.1 - 05/04/2000 - G.Juyn * */
/* * - added CRC table to main structure (for thread-safety) * */
/* * 0.5.1 - 05/06/2000 - G.Juyn * */
/* * - added iPLTEentries for checking hIST-length * */
/* * 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed palette definition to exported palette-type * */
/* * - removed frozen indicator * */
/* * - added create/write indicators * */
/* * - changed strict-ANSI stuff * */
/* * 0.5.1 - 05/13/2000 - G.Juyn * */
/* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
/* * - added TERM animation object pointer (easier reference) * */
/* * - added saved-data structure for SAVE/SEEK processing * */
/* * * */
/* * 0.5.2 - 05/18/2000 - G.Juyn * */
/* * - added fields for JNG support (IJG-based) * */
/* * 0.5.2 - 05/24/2000 - G.Juyn * */
/* * - changed global tRNS definition * */
/* * 0.5.2 - 05/30/2000 - G.Juyn * */
/* * - added delta-image fields * */
/* * 0.5.2 - 06/01/2000 - G.Juyn * */
/* * - added internal delta-image processing callbacks * */
/* * 0.5.2 - 06/02/2000 - G.Juyn * */
/* * - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED * */
/* * (contributed by Tim Rowley) * */
/* * - added getalphaline callback for RGB8_A8 canvasstyle * */
/* * 0.5.2 - 06/06/2000 - G.Juyn * */
/* * - added parameter for delayed buffer-processing * */
/* * * */
/* * 0.5.3 - 06/16/2000 - G.Juyn * */
/* * - added update-region parms for refresh calback * */
/* * - added Needrefresh parameter * */
/* * 0.5.3 - 06/17/2000 - G.Juyn * */
/* * - added Deltaimmediate parm for faster delta-processing * */
/* * 0.5.3 - 06/21/2000 - G.Juyn * */
/* * - added Speed parameter to facilitate testing * */
/* * - added Imagelevel parameter for processtext callback * */
/* * 0.5.3 - 06/26/2000 - G.Juyn * */
/* * - changed userdata variable to mng_ptr * */
/* * * */
/* * 0.9.1 - 07/07/2000 - G.Juyn * */
/* * - added variables for go_xxxx processing * */
/* * 0.9.1 - 07/08/2000 - G.Juyn * */
/* * - added variables for improved timing support * */
/* * 0.9.1 - 07/15/2000 - G.Juyn * */
/* * - added callbacks for SAVE/SEEK processing * */
/* * - added variable for NEEDSECTIONWAIT breaks * */
/* * - added variable for freeze & reset processing * */
/* * 0.9.1 - 07/17/2000 - G.Juyn * */
/* * - fixed suspension-buffering for 32K+ chunks * */
/* * * */
/* * 0.9.2 - 07/29/2000 - G.Juyn * */
/* * - removed Nextbackxxx fields (no longer used) * */
/* * 0.9.2 - 07/31/2000 - G.Juyn * */
/* * - fixed wrapping of suspension parameters * */
/* * 0.9.2 - 08/04/2000 - G.Juyn * */
/* * - B111096 - fixed large-buffer read-suspension * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/26/2000 - G.Juyn * */
/* * - added MAGN chunk * */
/* * 0.9.3 - 09/07/2000 - G.Juyn * */
/* * - added support for new filter_types * */
/* * 0.9.3 - 09/10/2000 - G.Juyn * */
/* * - fixed DEFI behavior * */
/* * 0.9.3 - 10/10/2000 - G.Juyn * */
/* * - added support for alpha-depth prediction * */
/* * 0.9.3 - 10/11/2000 - G.Juyn * */
/* * - added support for nEED * */
/* * 0.9.3 - 10/16/2000 - G.Juyn * */
/* * - added optional support for bKGD for PNG images * */
/* * - added support for JDAA * */
/* * 0.9.3 - 10/17/2000 - G.Juyn * */
/* * - added callback to process non-critical unknown chunks * */
/* * - fixed support for bKGD * */
/* * 0.9.3 - 10/19/2000 - G.Juyn * */
/* * - implemented delayed delta-processing * */
/* * 0.9.4 - 12/16/2000 - G.Juyn * */
/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
/* * * */
/* * 1.0.1 - 02/08/2001 - G.Juyn * */
/* * - added MEND processing callback * */
/* * 1.0.1 - 02/13/2001 - G.Juyn * */
/* * - fixed first FRAM_MODE=4 timing problem * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_data_h_
#define _libmng_data_h_
/* ************************************************************************** */
#define MNG_MAGIC 0x52530a0aL
/* ************************************************************************** */
/* * * */
/* * Internal structures * */
/* * * */
/* ************************************************************************** */
typedef mng_palette8 mng_rgbpaltab;
/* ************************************************************************** */
/* * * */
/* * The saved_data structure * */
/* * * */
/* * This contains the saved data after a SAVE chunk has been processed. * */
/* * The data is saved from the main data structure during SAVE processing, * */
/* * and restored to the main data structure during SEEK processing. * */
/* * * */
/* ************************************************************************** */
typedef struct mng_savedata_struct {
#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
mng_bool bHasglobalPLTE; /* global PLTE chunk processed */
mng_bool bHasglobalTRNS; /* global tRNS chunk processed */
mng_bool bHasglobalGAMA; /* global gAMA chunk processed */
mng_bool bHasglobalCHRM; /* global cHRM chunk processed */
mng_bool bHasglobalSRGB; /* global sRGB chunk processed */
mng_bool bHasglobalICCP; /* global iCCP chunk processed */
mng_bool bHasglobalBKGD; /* global bKGD chunk processed */
#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
#ifdef MNG_SUPPORT_DISPLAY
mng_uint16 iBACKred; /* BACK fields */
mng_uint16 iBACKgreen;
mng_uint16 iBACKblue;
mng_uint8 iBACKmandatory;
mng_uint16 iBACKimageid;
mng_uint8 iBACKtile;
mng_uint8 iFRAMmode; /* FRAM fields (global) */
mng_uint32 iFRAMdelay;
mng_uint32 iFRAMtimeout;
mng_bool bFRAMclipping;
mng_int32 iFRAMclipl;
mng_int32 iFRAMclipr;
mng_int32 iFRAMclipt;
mng_int32 iFRAMclipb;
mng_uint32 iGlobalPLTEcount; /* global PLTE fields */
mng_rgbpaltab aGlobalPLTEentries;
mng_uint32 iGlobalTRNSrawlen; /* global tRNS fields */
mng_uint8arr aGlobalTRNSrawdata;
mng_uint32 iGlobalGamma; /* global gAMA fields */
mng_uint32 iGlobalWhitepointx; /* global cHRM fields */
mng_uint32 iGlobalWhitepointy;
mng_uint32 iGlobalPrimaryredx;
mng_uint32 iGlobalPrimaryredy;
mng_uint32 iGlobalPrimarygreenx;
mng_uint32 iGlobalPrimarygreeny;
mng_uint32 iGlobalPrimarybluex;
mng_uint32 iGlobalPrimarybluey;
mng_uint8 iGlobalRendintent; /* global sRGB fields */
mng_uint32 iGlobalProfilesize; /* global iCCP fields */
mng_ptr pGlobalProfile;
mng_uint16 iGlobalBKGDred; /* global bKGD fields */
mng_uint16 iGlobalBKGDgreen;
mng_uint16 iGlobalBKGDblue;
#endif /* MNG_SUPPORT_DISPLAY */
} mng_savedata;
typedef mng_savedata * mng_savedatap;
/* ************************************************************************** */
/* * * */
/* * The main libmng data structure * */
/* * * */
/* * The handle used in all functions points to this structure which * */
/* * contains all volatile data necessary to process the network graphic. * */
/* * * */
/* ************************************************************************** */
typedef struct mng_data_struct {
mng_uint32 iMagic; /* magic number to validate
a given handle */
mng_ptr pUserdata; /* application workdata */
mng_imgtype eSigtype; /* image information */
mng_imgtype eImagetype; /* initially zeroed */
mng_uint32 iWidth; /* filled after header is processed */
mng_uint32 iHeight;
mng_uint32 iTicks; /* these only after MHDR */
mng_uint32 iLayercount;
mng_uint32 iFramecount;
mng_uint32 iPlaytime;
mng_uint32 iSimplicity;
mng_uint8 iAlphadepth; /* indicates expected alpha-depth */
mng_uint32 iImagelevel; /* level an image inside a stream */
mng_uint32 iCanvasstyle; /* layout of the drawing-canvas */
mng_uint32 iBkgdstyle; /* layout of the background-canvas */
mng_int8 iMagnify; /* magnification factor (not used yet) */
mng_uint32 iOffsetx; /* x-offset for extremely large image */
mng_uint32 iOffsety; /* y-offset for extremely large image */
mng_uint32 iCanvaswidth; /* real canvas size */
mng_uint32 iCanvasheight; /* must be set by processheader callback */
mng_uint16 iBGred; /* default background color */
mng_uint16 iBGgreen; /* initially "black" */
mng_uint16 iBGblue;
mng_bool bUseBKGD; /* preferred use of bKGD for PNG */
mng_bool bIssRGB; /* indicates sRGB system */
#ifdef MNG_FULL_CMS /* little CMS variables */
mng_cmsprof hProf1; /* image input profile */
mng_cmsprof hProf2; /* default output profile */
mng_cmsprof hProf3; /* default sRGB profile */
mng_cmstrans hTrans; /* current transformation handle */
#endif
mng_float dViewgamma; /* gamma calculation variables */
mng_float dDisplaygamma; /* initially set for sRGB conditions */
mng_float dDfltimggamma;
mng_bool bStorechunks; /* switch for storing chunkdata */
mng_bool bSectionbreaks; /* indicate NEEDSECTIONWAIT breaks */
mng_speedtype iSpeed; /* speed-modifier for animations */
mng_uint32 iMaxwidth; /* maximum canvas size */
mng_uint32 iMaxheight; /* initially set to 1024 x 1024 */
mng_int32 iErrorcode; /* error reporting fields */
mng_int8 iSeverity;
mng_int32 iErrorx1;
mng_int32 iErrorx2;
mng_pchar zErrortext;
mng_memalloc fMemalloc; /* callback pointers */
mng_memfree fMemfree; /* initially nulled */
mng_openstream fOpenstream;
mng_closestream fClosestream;
mng_readdata fReaddata;
mng_writedata fWritedata;
mng_errorproc fErrorproc;
mng_traceproc fTraceproc;
mng_processheader fProcessheader;
mng_processtext fProcesstext;
mng_processsave fProcesssave;
mng_processseek fProcessseek;
mng_processneed fProcessneed;
mng_processmend fProcessmend;
mng_processunknown fProcessunknown;
mng_getcanvasline fGetcanvasline;
mng_getbkgdline fGetbkgdline;
mng_getalphaline fGetalphaline;
mng_refresh fRefresh;
mng_gettickcount fGettickcount;
mng_settimer fSettimer;
mng_processgamma fProcessgamma;
mng_processchroma fProcesschroma;
mng_processsrgb fProcesssrgb;
mng_processiccp fProcessiccp;
mng_processarow fProcessarow;
#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
mng_bool bPreDraft48; /* flags ancient style draft */
mng_chunkid iChunkname; /* read/write-state variables */
mng_uint32 iChunkseq;
mng_chunkp pFirstchunk; /* double-linked list of */
mng_chunkp pLastchunk; /* stored chunk-structures */
mng_bool bHasheader; /* first header chunk processed */
mng_bool bHasMHDR; /* inside a MHDR-MEND sequence */
mng_bool bHasIHDR; /* inside a IHDR-IEND sequence */
mng_bool bHasBASI; /* inside a BASI-IEND sequence */
mng_bool bHasDHDR; /* inside a DHDR-IEND sequence */
#ifdef MNG_INCLUDE_JNG
mng_bool bHasJHDR; /* inside a JHDR-IEND sequence */
mng_bool bHasJSEP; /* passed the JSEP separator */
mng_bool bHasJDAA; /* at least 1 JDAA processed */
mng_bool bHasJDAT; /* at least 1 JDAT processed */
#endif
mng_bool bHasPLTE; /* PLTE chunk processed */
mng_bool bHasTRNS; /* tRNS chunk processed */
mng_bool bHasGAMA; /* gAMA chunk processed */
mng_bool bHasCHRM; /* cHRM chunk processed */
mng_bool bHasSRGB; /* sRGB chunk processed */
mng_bool bHasICCP; /* iCCP chunk processed */
mng_bool bHasBKGD; /* bKGD chunk processed */
mng_bool bHasIDAT; /* at least 1 IDAT processed */
mng_bool bHasSAVE; /* SAVE chunk processed */
mng_bool bHasBACK; /* BACK chunk processed */
mng_bool bHasFRAM; /* FRAM chunk processed */
mng_bool bHasTERM; /* TERM chunk processed */
mng_bool bHasLOOP; /* at least 1 LOOP open */
mng_bool bHasglobalPLTE; /* global PLTE chunk processed */
mng_bool bHasglobalTRNS; /* global tRNS chunk processed */
mng_bool bHasglobalGAMA; /* global gAMA chunk processed */
mng_bool bHasglobalCHRM; /* global cHRM chunk processed */
mng_bool bHasglobalSRGB; /* global sRGB chunk processed */
mng_bool bHasglobalICCP; /* global iCCP chunk processed */
mng_bool bHasglobalBKGD; /* global bKGD chunk processed */
mng_uint32 iDatawidth; /* IHDR/BASI/DHDR fields */
mng_uint32 iDataheight; /* valid if inside IHDR-IEND, */
mng_uint8 iBitdepth; /* BASI-IEND or DHDR-IEND */
mng_uint8 iColortype;
mng_uint8 iCompression;
mng_uint8 iFilter;
mng_uint8 iInterlace;
mng_uint32 iPLTEcount; /* PLTE fields */
mng_bool bEMNGMAhack; /* TODO: to be removed in 1.0.0 !!! */
#ifdef MNG_INCLUDE_JNG
mng_uint8 iJHDRcolortype; /* JHDR fields */
mng_uint8 iJHDRimgbitdepth; /* valid if inside JHDR-IEND */
mng_uint8 iJHDRimgcompression;
mng_uint8 iJHDRimginterlace;
mng_uint8 iJHDRalphabitdepth;
mng_uint8 iJHDRalphacompression;
mng_uint8 iJHDRalphafilter;
mng_uint8 iJHDRalphainterlace;
#endif
#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
#ifdef MNG_SUPPORT_READ
mng_bool bReading; /* read processing variables */
mng_bool bHavesig;
mng_bool bEOF;
mng_uint32 iReadbufsize;
mng_uint8p pReadbuf;
mng_uint32 iLargebufsize; /* temp for very large chunks */
mng_uint8p pLargebuf;
mng_uint32 iSuspendtime; /* tickcount at last suspension */
mng_bool bSuspended; /* input-reading has been suspended;
we're expecting a call to
mng_read_resume! */
mng_uint8 iSuspendpoint; /* indicates at which point the flow
was broken to suspend input-reading */
mng_bool bSuspensionmode; /* I/O-suspension variables */
mng_uint32 iSuspendbufsize;
mng_uint8p pSuspendbuf;
mng_uint8p pSuspendbufnext;
mng_uint32 iSuspendbufleft;
mng_uint32 iChunklen; /* chunk length */
mng_uint8p pReadbufnext; /* 32K+ suspension-processing */
#endif /* MNG_SUPPORT_READ */
#ifdef MNG_SUPPORT_WRITE
mng_bool bCreating; /* create/write processing variables */
mng_bool bWriting;
mng_chunkid iFirstchunkadded;
mng_uint32 iWritebufsize;
mng_uint8p pWritebuf;
#endif
#ifdef MNG_SUPPORT_DISPLAY
mng_bool bDisplaying; /* display-state variables */
mng_bool bFramedone;
mng_uint32 iFrameseq;
mng_uint32 iLayerseq;
mng_uint32 iFrametime; /* millisecs */
mng_uint32 iRequestframe; /* go_xxxx variables */
mng_uint32 iRequestlayer;
mng_uint32 iRequesttime;
mng_bool bSearching;
mng_bool bRestorebkgd; /* flags restore required before IDAT/JDAT */
mng_uint32 iRuntime; /* millisecs since start */
mng_uint32 iSynctime; /* tickcount at last framesync */
mng_uint32 iStarttime; /* tickcount at start */
mng_uint32 iEndtime; /* tickcount at end */
mng_bool bRunning; /* animation is active */
mng_bool bTimerset; /* the timer has been set;
we're expecting a call to
mng_display_resume! */
mng_uint8 iBreakpoint; /* indicates at which point the
flow was broken to run the timer */
mng_bool bSectionwait; /* indicates a section break */
mng_bool bFreezing; /* indicates app requested a freeze */
mng_bool bResetting; /* indicates app requested a reset */
mng_bool bNeedrefresh; /* indicates screen-refresh is needed */
mng_objectp pCurrentobj; /* current "object" */
mng_objectp pCurraniobj; /* current animation object
"to be"/"being" processed */
mng_objectp pTermaniobj; /* TERM animation object */
mng_uint32 iIterations; /* TERM/MEND iteration count */
mng_objectp pObjzero; /* "on-the-fly" image (object = 0) */
mng_objectp pLastclone; /* last clone */
mng_objectp pStoreobj; /* current store object for row routines */
mng_objectp pStorebuf; /* current store object-buffer for row routines */
mng_objectp pRetrieveobj; /* current retrieve object for row routines */
mng_savedatap pSavedata; /* pointer to saved data (after SAVE) */
mng_uint32 iUpdateleft; /* update region for refresh */
mng_uint32 iUpdateright;
mng_uint32 iUpdatetop;
mng_uint32 iUpdatebottom;
mng_int8 iPass; /* current interlacing pass;
negative value means no interlace */
mng_int32 iRow; /* current row counter */
mng_int32 iRowinc; /* row increment for this pass */
mng_int32 iCol; /* current starting column */
mng_int32 iColinc; /* column increment for this pass */
mng_int32 iRowsamples; /* nr. of samples in current workrow */
mng_int32 iSamplemul; /* needed to calculate rowsize */
mng_int32 iSampleofs; /* from rowsamples */
mng_int32 iSamplediv;
mng_int32 iRowsize; /* size of actual data in work row */
mng_int32 iRowmax; /* maximum size of data in work row */
mng_int32 iFilterofs; /* offset to filter-byte in work row */
mng_int32 iPixelofs; /* offset to pixel-bytes in work row */
mng_uint32 iLevel0; /* leveling variables */
mng_uint32 iLevel1;
mng_uint32 iLevel2;
mng_uint32 iLevel3;
mng_uint8p pWorkrow; /* working row of pixel-data */
mng_uint8p pPrevrow; /* previous row of pixel-data */
mng_uint8p pRGBArow; /* intermediate row of RGBA8 or RGBA16 data */
mng_bool bIsRGBA16; /* indicates intermediate row is RGBA16 */
mng_bool bIsOpaque; /* indicates intermediate row is fully opaque */
mng_int32 iFilterbpp; /* bpp index for filtering routines */
mng_int32 iSourcel; /* variables for showing objects */
mng_int32 iSourcer;
mng_int32 iSourcet;
mng_int32 iSourceb;
mng_int32 iDestl;
mng_int32 iDestr;
mng_int32 iDestt;
mng_int32 iDestb;
mng_objectp pFirstimgobj; /* double-linked list of */
mng_objectp pLastimgobj; /* image-object structures */
mng_objectp pFirstaniobj; /* double-linked list of */
mng_objectp pLastaniobj; /* animation-object structures */
#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
mng_uint8 aGammatab[256]; /* precomputed gamma lookup table */
mng_float dLastgamma; /* last gamma used to compute table */
#endif
mng_fptr fDisplayrow; /* internal callback to display an
uncompressed/unfiltered/
color-corrected row */
mng_fptr fRestbkgdrow; /* internal callback for restore-
background processing of a row */
mng_fptr fCorrectrow; /* internal callback to color-correct an
uncompressed/unfiltered row */
mng_fptr fRetrieverow; /* internal callback to retrieve an
uncompressed/unfiltered row of data */
mng_fptr fStorerow; /* internal callback to store an
uncompressed/unfiltered row of data */
mng_fptr fProcessrow; /* internal callback to process an
uncompressed row of data */
mng_fptr fDifferrow; /* internal callback to perform
added filter leveling and
differing on an unfiltered row */
mng_fptr fScalerow; /* internal callback to scale a
delta-row to the bitdepth of its target */
mng_fptr fDeltarow; /* internal callback to execute a
delta-row onto a target */
mng_fptr fInitrowproc; /* internal callback to initialize
the row processing */
mng_uint16 iDEFIobjectid; /* DEFI fields */
mng_bool bDEFIhasdonotshow;
mng_uint8 iDEFIdonotshow;
mng_bool bDEFIhasconcrete;
mng_uint8 iDEFIconcrete;
mng_bool bDEFIhasloca;
mng_int32 iDEFIlocax;
mng_int32 iDEFIlocay;
mng_bool bDEFIhasclip;
mng_int32 iDEFIclipl;
mng_int32 iDEFIclipr;
mng_int32 iDEFIclipt;
mng_int32 iDEFIclipb;
mng_uint16 iBACKred; /* BACK fields */
mng_uint16 iBACKgreen;
mng_uint16 iBACKblue;
mng_uint8 iBACKmandatory;
mng_uint16 iBACKimageid;
mng_uint8 iBACKtile;
mng_uint8 iFRAMmode; /* FRAM fields (global) */
mng_uint32 iFRAMdelay;
mng_uint32 iFRAMtimeout;
mng_bool bFRAMclipping;
mng_int32 iFRAMclipl;
mng_int32 iFRAMclipr;
mng_int32 iFRAMclipt;
mng_int32 iFRAMclipb;
mng_uint8 iFramemode; /* current subframe variables */
mng_uint32 iFramedelay;
mng_uint32 iFrametimeout;
mng_bool bFrameclipping;
mng_int32 iFrameclipl;
mng_int32 iFrameclipr;
mng_int32 iFrameclipt;
mng_int32 iFrameclipb;
mng_uint32 iNextdelay; /* delay for *after* next image */
mng_uint8 iSHOWmode; /* SAVE fields */
mng_uint16 iSHOWfromid;
mng_uint16 iSHOWtoid;
mng_uint16 iSHOWnextid;
mng_int16 iSHOWskip;
mng_uint32 iGlobalPLTEcount; /* global PLTE fields */
mng_rgbpaltab aGlobalPLTEentries;
mng_uint32 iGlobalTRNSrawlen; /* global tRNS fields */
mng_uint8arr aGlobalTRNSrawdata;
mng_uint32 iGlobalGamma; /* global gAMA fields */
mng_uint32 iGlobalWhitepointx; /* global cHRM fields */
mng_uint32 iGlobalWhitepointy;
mng_uint32 iGlobalPrimaryredx;
mng_uint32 iGlobalPrimaryredy;
mng_uint32 iGlobalPrimarygreenx;
mng_uint32 iGlobalPrimarygreeny;
mng_uint32 iGlobalPrimarybluex;
mng_uint32 iGlobalPrimarybluey;
mng_uint8 iGlobalRendintent; /* global sRGB fields */
mng_uint32 iGlobalProfilesize; /* global iCCP fields */
mng_ptr pGlobalProfile;
mng_uint16 iGlobalBKGDred; /* global bKGD fields */
mng_uint16 iGlobalBKGDgreen;
mng_uint16 iGlobalBKGDblue;
mng_ptr pDeltaImage; /* delta-image fields */
mng_uint8 iDeltaImagetype;
mng_uint8 iDeltatype;
mng_uint32 iDeltaBlockwidth;
mng_uint32 iDeltaBlockheight;
mng_uint32 iDeltaBlockx;
mng_uint32 iDeltaBlocky;
mng_bool bDeltaimmediate;
mng_fptr fDeltagetrow; /* internal delta-proc callbacks */
mng_fptr fDeltaaddrow;
mng_fptr fDeltareplacerow;
mng_fptr fDeltaputrow;
mng_uint16 iMAGNfromid;
mng_uint16 iMAGNtoid;
#endif /* MNG_SUPPORT_DISPLAY */
#ifdef MNG_INCLUDE_ZLIB
z_stream sZlib; /* zlib (de)compression variables */
mng_int32 iZlevel; /* zlib compression parameters */
mng_int32 iZmethod;
mng_int32 iZwindowbits;
mng_int32 iZmemlevel;
mng_int32 iZstrategy;
mng_uint32 iMaxIDAT; /* maximum size of IDAT data */
mng_bool bInflating; /* indicates "inflate" in progress */
mng_bool bDeflating; /* indicates "deflate" in progress */
#endif /* MNG_INCLUDE_ZLIB */
#ifdef MNG_INCLUDE_JNG
mngjpeg_dctmethod eJPEGdctmethod; /* IJG compression variables */
mng_int32 iJPEGquality;
mng_int32 iJPEGsmoothing;
mng_bool bJPEGcompressprogr;
mng_bool bJPEGcompressopt;
mng_uint32 iMaxJDAT; /* maximum size of JDAT/JDAA data */
mngjpeg_compp pJPEGcinfo; /* compression structure */
mngjpeg_errorp pJPEGcerr; /* error-manager compress */
mngjpeg_decompp pJPEGdinfo; /* decompression structure (JDAT) */
mngjpeg_errorp pJPEGderr; /* error-manager decompress (JDAT) */
mngjpeg_sourcep pJPEGdsrc; /* source-manager decompress (JDAT) */
mngjpeg_decompp pJPEGdinfo2; /* decompression structure (JDAA) */
mngjpeg_errorp pJPEGderr2; /* error-manager decompress (JDAA) */
mngjpeg_sourcep pJPEGdsrc2; /* source-manager decompress (JDAA) */
mng_uint8p pJPEGbuf; /* buffer for JPEG (de)compression (JDAT) */
mng_uint32 iJPEGbufmax; /* allocated space for buffer (JDAT) */
mng_uint8p pJPEGcurrent; /* current pointer into buffer (JDAT) */
mng_uint32 iJPEGbufremain; /* remaining bytes in buffer (JDAT) */
mng_uint32 iJPEGtoskip; /* bytes to skip on next input-block (JDAT) */
mng_uint8p pJPEGbuf2; /* buffer for JPEG (de)compression (JDAA) */
mng_uint32 iJPEGbufmax2; /* allocated space for buffer (JDAA) */
mng_uint8p pJPEGcurrent2; /* current pointer into buffer (JDAA) */
mng_uint32 iJPEGbufremain2; /* remaining bytes in buffer (JDAA) */
mng_uint32 iJPEGtoskip2; /* bytes to skip on next input-block (JDAA) */
mng_uint8p pJPEGrow; /* buffer for a JPEG row of samples (JDAT) */
mng_uint32 iJPEGrowlen;
mng_uint8p pJPEGrow2; /* buffer for a JPEG row of samples (JDAA) */
mng_uint32 iJPEGrowlen2;
mng_bool bJPEGcompress; /* indicates "compress" initialized */
mng_bool bJPEGdecompress; /* indicates "decompress" initialized (JDAT) */
mng_bool bJPEGhasheader; /* indicates "readheader" succeeded (JDAT) */
mng_bool bJPEGdecostarted; /* indicates "decompress" started (JDAT) */
mng_bool bJPEGscanstarted; /* indicates "first scan" started (JDAT) */
mng_bool bJPEGprogressive; /* indicates a progressive image (JDAT) */
mng_bool bJPEGdecompress2; /* indicates "decompress" initialized (JDAA) */
mng_bool bJPEGhasheader2; /* indicates "readheader" succeeded (JDAA) */
mng_bool bJPEGdecostarted2; /* indicates "decompress" started (JDAA) */
mng_bool bJPEGscanstarted2; /* indicates "first scan" started (JDAA) */
mng_bool bJPEGprogressive2; /* indicates a progressive image (JDAA) */
mng_fptr fStorerow2; /* internal callback to store an
uncompressed/unfiltered row of JPEG-data (JDAT) */
mng_fptr fStorerow3; /* internal callback to store an
uncompressed/unfiltered row of JPEG-data (JDAA) */
mng_uint32 iJPEGrow; /* row-number for current JPEG row */
mng_uint32 iJPEGalpharow; /* nr. of rows filled with alpha */
mng_uint32 iJPEGrgbrow; /* nr. of rows filled with 'color'-info */
mng_uint32 iJPEGdisprow; /* nr. of rows already displayed "on-the-fly" */
#if defined(MNG_USE_SETJMP) && defined (MNG_INCLUDE_IJG6B)
jmp_buf sErrorbuf; /* setjmp/longjmp buffer (error-recovery) */
#endif
#endif /* MNG_INCLUDE_JNG */
mng_uint32 aCRCtable [256]; /* CRC prefab table */
mng_bool bCRCcomputed; /* "has been build" indicator */
} mng_data;
typedef mng_data * mng_datap;
/* ************************************************************************** */
/* * * */
/* * Internal Callback-Function prototypes * */
/* * * */
/* ************************************************************************** */
typedef mng_retcode(*mng_displayrow) (mng_datap pData);
typedef mng_retcode(*mng_restbkgdrow) (mng_datap pData);
typedef mng_retcode(*mng_correctrow) (mng_datap pData);
typedef mng_retcode(*mng_retrieverow) (mng_datap pData);
typedef mng_retcode(*mng_storerow) (mng_datap pData);
typedef mng_retcode(*mng_processrow) (mng_datap pData);
typedef mng_retcode(*mng_initrowproc) (mng_datap pData);
typedef mng_retcode(*mng_differrow) (mng_datap pData);
typedef mng_retcode(*mng_scalerow) (mng_datap pData);
typedef mng_retcode(*mng_deltarow) (mng_datap pData);
typedef mng_retcode(*mng_magnify_x) (mng_datap pData,
mng_uint16 iMX,
mng_uint16 iML,
mng_uint16 iMR,
mng_uint32 iWidth,
mng_uint8p iSrcline,
mng_uint8p iDstline);
typedef mng_retcode(*mng_magnify_y) (mng_datap pData,
mng_int32 iM,
mng_int32 iS,
mng_uint32 iWidth,
mng_uint8p iSrcline1,
mng_uint8p iSrcline2,
mng_uint8p iDstline);
/* ************************************************************************** */
/* * * */
/* * Routines for swapping byte-order from and to graphic files * */
/* * (This code is adapted from the libpng package) * */
/* * * */
/* ************************************************************************** */
#ifndef MNG_BIGENDIAN_SUPPORTED
mng_uint32 mng_get_uint32 (mng_uint8p pBuf);
mng_int32 mng_get_int32 (mng_uint8p pBuf);
mng_uint16 mng_get_uint16 (mng_uint8p pBuf);
void mng_put_uint32 (mng_uint8p pBuf,
mng_uint32 i);
void mng_put_int32 (mng_uint8p pBuf,
mng_int32 i);
void mng_put_uint16 (mng_uint8p pBuf,
mng_uint16 i);
#else /* MNG_BIGENDIAN_SUPPORTED */
#define mng_get_uint32(P) *(mng_uint32p)(P)
#define mng_get_int32(P) *(mng_int32p)(P)
#define mng_get_uint16(P) *(mng_uint16p)(P)
#define mng_put_uint32(P,I) *(mng_uint32p)(P) = (I)
#define mng_put_int32(P,I) *(mng_int32p)(P) = (I)
#define mng_put_uint16(P,I) *(mng_uint16p)(P) = (I)
#endif /* MNG_BIGENDIAN_SUPPORTED */
/* ************************************************************************** */
/* * * */
/* * Some handy(?) macro definitions * */
/* * * */
/* ************************************************************************** */
#define MAX_COORD(a, b) (((a) > (b)) ? (a) : (b))
#define MIN_COORD(a, b) (((a) < (b)) ? (a) : (b))
/* ************************************************************************** */
#endif /* _libmng_data_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_display.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Display management (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the display managament routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.5.2 - 05/20/2000 - G.Juyn * */
/* * - added JNG support stuff * */
/* * * */
/* * 0.5.3 - 06/16/2000 - G.Juyn * */
/* * - changed progressive-display processing * */
/* * 0.5.3 - 06/22/2000 - G.Juyn * */
/* * - added support for delta-image processing * */
/* * - added support for PPLT chunk processing * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * 0.9.3 - 08/07/2000 - G.Juyn * */
/* * - B111300 - fixup for improved portability * */
/* * 0.9.3 - 08/26/2000 - G.Juyn * */
/* * - added MAGN chunk * */
/* * 0.9.3 - 10/16/2000 - G.Juyn * */
/* * - added JDAA chunk * */
/* * * */
/* * 0.9.4 - 11/24/2000 - G.Juyn * */
/* * - moved restore of object 0 to libmng_display * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_display_h_
#define _libmng_display_h_
/* ************************************************************************** */
mng_retcode display_progressive_refresh (mng_datap pData,
mng_uint32 iInterval);
/* ************************************************************************** */
mng_retcode mng_reset_objzero (mng_datap pData);
mng_retcode display_image (mng_datap pData,
mng_imagep pImage,
mng_bool bLayeradvanced);
mng_retcode execute_delta_image (mng_datap pData,
mng_imagep pTarget,
mng_imagep pDelta);
/* ************************************************************************** */
mng_retcode process_display (mng_datap pData);
/* ************************************************************************** */
mng_retcode process_display_ihdr (mng_datap pData);
mng_retcode process_display_idat (mng_datap pData,
mng_uint32 iRawlen,
mng_uint8p pRawdata);
mng_retcode process_display_iend (mng_datap pData);
mng_retcode process_display_mend (mng_datap pData);
mng_retcode process_display_defi (mng_datap pData);
mng_retcode process_display_basi (mng_datap pData,
mng_uint16 iRed,
mng_uint16 iGreen,
mng_uint16 iBlue,
mng_bool bHasalpha,
mng_uint16 iAlpha,
mng_uint8 iViewable);
mng_retcode process_display_clon (mng_datap pData,
mng_uint16 iSourceid,
mng_uint16 iCloneid,
mng_uint8 iClonetype,
mng_bool bHasdonotshow,
mng_uint8 iDonotshow,
mng_uint8 iConcrete,
mng_bool bHasloca,
mng_uint8 iLocationtype,
mng_int32 iLocationx,
mng_int32 iLocationy);
mng_retcode process_display_clon2 (mng_datap pData);
mng_retcode process_display_disc (mng_datap pData,
mng_uint32 iCount,
mng_uint16p pIds);
mng_retcode process_display_fram (mng_datap pData,
mng_uint8 iFramemode,
mng_uint8 iChangedelay,
mng_uint32 iDelay,
mng_uint8 iChangetimeout,
mng_uint32 iTimeout,
mng_uint8 iChangeclipping,
mng_uint8 iCliptype,
mng_int32 iClipl,
mng_int32 iClipr,
mng_int32 iClipt,
mng_int32 iClipb);
mng_retcode process_display_fram2 (mng_datap pData);
mng_retcode process_display_move (mng_datap pData,
mng_uint16 iFromid,
mng_uint16 iToid,
mng_uint8 iMovetype,
mng_int32 iMovex,
mng_int32 iMovey);
mng_retcode process_display_clip (mng_datap pData,
mng_uint16 iFromid,
mng_uint16 iToid,
mng_uint8 iCliptype,
mng_int32 iClipl,
mng_int32 iClipr,
mng_int32 iClipt,
mng_int32 iClipb);
mng_retcode process_display_show (mng_datap pData);
mng_retcode process_display_save (mng_datap pData);
mng_retcode process_display_seek (mng_datap pData);
mng_retcode process_display_jhdr (mng_datap pData);
mng_retcode process_display_jdaa (mng_datap pData,
mng_uint32 iRawlen,
mng_uint8p pRawdata);
mng_retcode process_display_jdat (mng_datap pData,
mng_uint32 iRawlen,
mng_uint8p pRawdata);
mng_retcode process_display_dhdr (mng_datap pData,
mng_uint16 iObjectid,
mng_uint8 iImagetype,
mng_uint8 iDeltatype,
mng_uint32 iBlockwidth,
mng_uint32 iBlockheight,
mng_uint32 iBlockx,
mng_uint32 iBlocky);
mng_retcode process_display_prom (mng_datap pData,
mng_uint8 iBitdepth,
mng_uint8 iColortype,
mng_uint8 iFilltype);
mng_retcode process_display_ipng (mng_datap pData);
mng_retcode process_display_ijng (mng_datap pData);
mng_retcode process_display_pplt (mng_datap pData,
mng_uint8 iType,
mng_uint32 iCount,
mng_palette8ep paIndexentries,
mng_uint8p paAlphaentries,
mng_uint8p paUsedentries);
mng_retcode process_display_magn (mng_datap pData,
mng_uint16 iFirstid,
mng_uint16 iLastid,
mng_uint16 iMethodX,
mng_uint16 iMX,
mng_uint16 iMY,
mng_uint16 iML,
mng_uint16 iMR,
mng_uint16 iMT,
mng_uint16 iMB,
mng_uint16 iMethodY);
mng_retcode process_display_magn2 (mng_datap pData);
/* ************************************************************************** */
#endif /* _libmng_display_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,54 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_dither.c copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Dithering routines (implementation) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : implementation of the dithering routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* ************************************************************************** */
#include "libmng.h"
#include "libmng_data.h"
#include "libmng_error.h"
#include "libmng_trace.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "libmng_dither.h"
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
/* ************************************************************************** */
mng_retcode dither_a_row (mng_datap pData,
mng_uint8p pRow)
{
return MNG_NOERROR;
}
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,44 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_dither.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Dithering routines (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the dithering routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_dither_h_
#define _libmng_dither_h_
/* ************************************************************************** */
mng_retcode dither_a_row (mng_datap pData,
mng_uint8p pRow);
/* ************************************************************************** */
#endif /* _libmng_dither_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,267 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_error.c copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Error routines (implementation) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : implementation of the general error handling routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.5.2 - 05/23/2000 - G.Juyn * */
/* * - added error telltaling * */
/* * 0.5.2 - 05/30/2000 - G.Juyn * */
/* * - added errorstrings for delta-image processing * */
/* * 0.5.2 - 05/31/2000 - G.Juyn * */
/* * - fixed up punctuation (contributed by Tim Rowley) * */
/* * 0.5.2 - 06/06/2000 - G.Juyn * */
/* * - added errorstring for delayed buffer-processing * */
/* * * */
/* * 0.9.1 - 07/06/2000 - G.Juyn * */
/* * - added MNG_NEEDTIMERWAIT errorstring * */
/* * 0.9.1 - 07/15/2000 - G.Juyn * */
/* * - added NEEDSECTIONWAIT errorstring * */
/* * - added macro + routine to set returncode without * */
/* * calling error callback * */
/* * 0.9.1 - 07/19/2000 - G.Juyn * */
/* * - added errorstring for updatemngheader if not a MNG * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/09/2000 - G.Juyn * */
/* * - added check for simplicity-bits in MHDR * */
/* * 0.9.3 - 10/11/2000 - G.Juyn * */
/* * - fixed processing of unknown critical chunks * */
/* * - added support for nEED * */
/* * 0.9.3 - 10/20/2000 - G.Juyn * */
/* * - added errorcode for delayed delta-processing * */
/* * * */
/* * 0.9.4 - 1/18/2001 - G.Juyn * */
/* * - added errorcode for MAGN methods * */
/* * * */
/* ************************************************************************** */
#include "libmng.h"
#include "libmng_data.h"
#include "libmng_error.h"
#include "libmng_trace.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
/* ************************************************************************** */
#ifdef MNG_INCLUDE_ERROR_STRINGS
mng_error_entry error_table [] =
{
{MNG_NOERROR, "No error"},
{MNG_OUTOFMEMORY, "Out of memory"},
{MNG_INVALIDHANDLE, "The handle is invalid"},
{MNG_NOCALLBACK, "A required callback is not defined"},
{MNG_UNEXPECTEDEOF, "Encountered unexpected end-of-file"},
{MNG_ZLIBERROR, "zlib encountered an error"},
{MNG_JPEGERROR, "ijgsrc6b encountered an error"},
{MNG_LCMSERROR, "lcms encountered an error"},
{MNG_NOOUTPUTPROFILE, "No output-profile defined for CMS"},
{MNG_NOSRGBPROFILE, "No sRGB-profile defined for CMS"},
{MNG_BUFOVERFLOW, "Internal buffer-overflow"},
{MNG_FUNCTIONINVALID, "Function is invalid at this point"},
{MNG_OUTPUTERROR, "Writing was unsuccessful; disk full?"},
{MNG_JPEGBUFTOOSMALL, "Internal buffer for JPEG processing too small"},
{MNG_NEEDMOREDATA, "Reading suspended; waiting for I/O to catch up"},
{MNG_NEEDTIMERWAIT, "Timer suspension; normal animation delay"},
{MNG_NEEDSECTIONWAIT, "SEEK suspension; application decides"},
{MNG_APPIOERROR, "Application signalled I/O error"},
{MNG_APPTIMERERROR, "Application signalled timing error"},
{MNG_APPCMSERROR, "Application signalled CMS error"},
{MNG_APPMISCERROR, "Application signalled an error"},
{MNG_APPTRACEABORT, "Application signalled error during trace-callback"},
{MNG_INTERNALERROR, "Internal error in libmng"},
{MNG_INVALIDSIG, "The signature is invalid"},
{MNG_INVALIDCRC, "The CRC for this chunk is invalid"},
{MNG_INVALIDLENGTH, "Chunk-length is invalid"},
{MNG_SEQUENCEERROR, "Chunk out of sequence"},
{MNG_CHUNKNOTALLOWED, "Chunk not allowed at this point"},
{MNG_MULTIPLEERROR, "Chunk cannot occur multiple times"},
{MNG_PLTEMISSING, "Missing PLTE chunk"},
{MNG_IDATMISSING, "Missing IDAT chunk(s)"},
{MNG_CANNOTBEEMPTY, "Chunk cannot be empty"},
{MNG_GLOBALLENGTHERR, "Global data length invalid"},
{MNG_INVALIDBITDEPTH, "The bit_depth is invalid"},
{MNG_INVALIDCOLORTYPE, "The color_type is invalid"},
{MNG_INVALIDCOMPRESS, "The compression_method is invalid"},
{MNG_INVALIDFILTER, "The filter_method or filter_type is invalid"},
{MNG_INVALIDINTERLACE, "The interlace_method is invalid"},
{MNG_NOTENOUGHIDAT, "There is not enough data in the IDAT chunk(s)"},
{MNG_PLTEINDEXERROR, "Palette-index out of bounds"},
{MNG_NULLNOTFOUND, "NULL separator not found"},
{MNG_KEYWORDNULL, "Keyword cannot be zero-length"},
{MNG_OBJECTUNKNOWN, "Object does not exist"},
{MNG_OBJECTEXISTS, "Object already exists"},
{MNG_TOOMUCHIDAT, "Too much data in IDAT chunk(s)"},
{MNG_INVSAMPLEDEPTH, "The sample_depth is invalid"},
{MNG_INVOFFSETSIZE, "The offset_type is invalid"},
{MNG_INVENTRYTYPE, "The entry_type is invalid"},
{MNG_ENDWITHNULL, "Chunk must not end with NULL byte"},
{MNG_INVIMAGETYPE, "The image_type is invalid"},
{MNG_INVDELTATYPE, "The delta_type is invalid"},
{MNG_INVALIDINDEX, "Index-value out of bounds"},
{MNG_TOOMUCHJDAT, "Too much data in JDAT chunk(s)"},
{MNG_JPEGPARMSERR, "JHDR parameters & JFIF-data do not match"},
{MNG_INVFILLMETHOD, "The fill_method is invalid"},
{MNG_OBJNOTCONCRETE, "Target object for DHDR must be concrete"},
{MNG_TARGETNOALPHA, "Target object must have alpha-channel"},
{MNG_MNGTOOCOMPLEX, "MHDR simplicity indicates unsupported feature(s)"},
{MNG_UNKNOWNCRITICAL, "Unknown critical chunk encountered"},
{MNG_UNSUPPORTEDNEED, "Requested nEED resources are not supported"},
{MNG_INVALIDDELTA, "The delta operation is invalid (mismatched color_types?)"},
{MNG_INVALIDMETHOD, "Method is invalid"},
{MNG_INVALIDCNVSTYLE, "Canvas_style is invalid"},
{MNG_WRONGCHUNK, "Attempt to access the wrong chunk"},
{MNG_INVALIDENTRYIX, "Attempt to access an non-existing entry"},
{MNG_NOHEADER, "No valid header-chunk"},
{MNG_NOCORRCHUNK, "Parent chunk not found"},
{MNG_NOMHDR, "No MNG header (MHDR) found"},
{MNG_IMAGETOOLARGE, "Image is larger than defined maximum"},
{MNG_NOTANANIMATION, "Image is not an animation"},
{MNG_FRAMENRTOOHIGH, "Framenr out of bounds"},
{MNG_LAYERNRTOOHIGH, "Layernr out of bounds"},
{MNG_PLAYTIMETOOHIGH, "Playtime out of bounds"},
{MNG_FNNOTIMPLEMENTED, "Function not yet implemented"},
{MNG_IMAGEFROZEN, "Image is frozen"},
{MNG_LCMS_NOHANDLE, "Handle could not be initialized"},
{MNG_LCMS_NOMEM, "No memory for gamma-table(s)"},
{MNG_LCMS_NOTRANS, "Transformation could not be initialized"},
};
#endif /* MNG_INCLUDE_ERROR_STRINGS */
/* ************************************************************************** */
mng_bool mng_store_error (mng_datap pData,
mng_retcode iError,
mng_retcode iExtra1,
mng_retcode iExtra2)
{
#ifdef MNG_SUPPORT_TRACE
MNG_TRACEB (pData, MNG_FN_STORE_ERROR, MNG_LC_START)
#endif
if (pData != 0)
{
pData->iErrorcode = iError; /* save also for getlasterror */
pData->iErrorx1 = iExtra1;
pData->iErrorx2 = iExtra2;
#ifdef MNG_INCLUDE_ERROR_STRINGS
{ /* binary search variables */
mng_int32 iTop, iLower, iUpper, iMiddle;
mng_error_entryp pEntry; /* pointer to found entry */
/* determine max index of table */
iTop = (sizeof (error_table) / sizeof (error_table [0])) - 1;
iLower = 0; /* initialize binary search */
iMiddle = iTop >> 1; /* start in the middle */
iUpper = iTop;
pEntry = 0; /* no goods yet! */
do /* the binary search itself */
{
if (error_table [iMiddle].iError < iError)
iLower = iMiddle + 1;
else if (error_table [iMiddle].iError > iError)
iUpper = iMiddle - 1;
else
{
pEntry = &error_table [iMiddle];
break;
}
iMiddle = (iLower + iUpper) >> 1;
}
while (iLower <= iUpper);
if (pEntry) /* found it ? */
pData->zErrortext = pEntry->zErrortext;
else
pData->zErrortext = "Unknown error";
}
#else
pData->zErrortext = 0;
#endif /* mng_error_telltale */
if (iError == 0) /* no error is not severe ! */
{
pData->iSeverity = 0;
}
else
{
switch (iError&0x3C00) /* determine the severity */
{
case 0x0800 : { pData->iSeverity = 5; break; }
case 0x1000 : { pData->iSeverity = 2; break; }
case 0x2000 : { pData->iSeverity = 1; break; }
default : { pData->iSeverity = 9; }
}
}
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACEB (pData, MNG_FN_STORE_ERROR, MNG_LC_END)
#endif
return MNG_TRUE;
}
/* ************************************************************************** */
mng_bool mng_process_error (mng_datap pData,
mng_retcode iError,
mng_retcode iExtra1,
mng_retcode iExtra2)
{
#ifdef MNG_SUPPORT_TRACE
MNG_TRACEB (pData, MNG_FN_PROCESS_ERROR, MNG_LC_START)
#endif
mng_store_error (pData, iError, iExtra1, iExtra2);
if (pData != 0)
{
if (pData->fErrorproc) /* callback defined ? */
return pData->fErrorproc (((mng_handle)pData), iError, pData->iSeverity,
pData->iChunkname, pData->iChunkseq,
pData->iErrorx1, pData->iErrorx2, pData->zErrortext);
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACEB (pData, MNG_FN_PROCESS_ERROR, MNG_LC_END)
#endif
return MNG_FALSE; /* automatic failure */
}
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,109 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_error.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Error functions (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the generic error-codes and functions * */
/* * * */
/* * changes : 0.5.1 - 05/06/2000 - G.Juyn * */
/* * - added some errorcodes * */
/* * 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - added some errorcodes * */
/* * - changed strict-ANSI stuff * */
/* * 0.5.1 - 05/11/2000 - G.Juyn * */
/* * - added application errorcodes (used with callbacks) * */
/* * - moved chunk-access errorcodes to severity 5 * */
/* * * */
/* * 0.5.2 - 05/20/2000 - G.Juyn * */
/* * - added JNG errorcodes * */
/* * 0.5.2 - 05/23/2000 - G.Juyn * */
/* * - added error tell-tale definition * */
/* * 0.5.2 - 05/30/2000 - G.Juyn * */
/* * - added errorcodes for delta-image processing * */
/* * 0.5.2 - 06/06/2000 - G.Juyn * */
/* * - added errorcode for delayed buffer-processing * */
/* * - moved errorcodes to "libmng.h" * */
/* * * */
/* * 0.9.1 - 07/15/2000 - G.Juyn * */
/* * - added macro + routine to set returncode without * */
/* * calling error callback * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_error_h_
#define _libmng_error_h_
/* ************************************************************************** */
/* * * */
/* * Default error routines * */
/* * * */
/* ************************************************************************** */
mng_bool mng_store_error (mng_datap pData,
mng_retcode iError,
mng_retcode iExtra1,
mng_retcode iExtra2);
mng_bool mng_process_error (mng_datap pData,
mng_retcode iError,
mng_retcode iExtra1,
mng_retcode iExtra2);
/* ************************************************************************** */
/* * * */
/* * Error handling macros * */
/* * * */
/* ************************************************************************** */
#define MNG_ERROR(D,C) { mng_process_error (D, C, 0, 0); return C; }
#define MNG_ERRORZ(D,Z) { mng_process_error (D, MNG_ZLIBERROR, Z, 0); return MNG_ZLIBERROR; }
#define MNG_ERRORJ(D,J) { mng_process_error (D, MNG_JPEGERROR, J, 0); return MNG_JPEGERROR; }
#define MNG_ERRORL(D,L) { mng_process_error (D, MNG_LCMSERROR, L, 0); return MNG_LCMSERROR; }
#define MNG_RETURN(D,C) { mng_store_error (D, C, 0, 0); return C; }
#define MNG_WARNING(D,C) { if (!mng_process_error (D, C, 0, 0)) return C; }
#define MNG_VALIDHANDLE(H) { if ((H == 0) || (((mng_datap)H)->iMagic != MNG_MAGIC)) \
return MNG_INVALIDHANDLE; }
#define MNG_VALIDHANDLEX(H) { if ((H == 0) || (((mng_datap)H)->iMagic != MNG_MAGIC)) \
return 0; }
#define MNG_VALIDCB(D,C) { if (!((mng_datap)D)->C) \
MNG_ERROR (((mng_datap)D), MNG_NOCALLBACK) }
/* ************************************************************************** */
/* * * */
/* * Error string-table entry * */
/* * * */
/* ************************************************************************** */
typedef struct {
mng_retcode iError;
mng_pchar zErrortext;
} mng_error_entry;
typedef mng_error_entry * mng_error_entryp;
/* ************************************************************************** */
#endif /* _libmng_error_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,890 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_filter.c copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Filtering routines (implementation) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : implementation of the filtering routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * 0.5.1 - 05/12/2000 - G.Juyn * */
/* * - changed trace to macro for callback error-reporting * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 09/07/2000 - G.Juyn * */
/* * - added support for new filter_types * */
/* * * */
/* ************************************************************************** */
#include "libmng.h"
#include "libmng_data.h"
#include "libmng_error.h"
#include "libmng_trace.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "libmng_filter.h"
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
/* ************************************************************************** */
#ifdef MNG_INCLUDE_FILTERS
/* ************************************************************************** */
mng_retcode filter_a_row (mng_datap pData)
{
mng_retcode iRetcode;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_START)
#endif
switch (*(pData->pWorkrow + pData->iFilterofs))
{
case 1 : {
iRetcode = filter_sub (pData);
break;
}
case 2 : {
iRetcode = filter_up (pData);
break;
}
case 3 : {
iRetcode = filter_average (pData);
break;
}
case 4 : {
iRetcode = filter_paeth (pData);
break;
}
default : iRetcode = MNG_INVALIDFILTER;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_END)
#endif
return iRetcode;
}
/* ************************************************************************** */
mng_retcode filter_sub (mng_datap pData)
{
mng_uint32 iBpp;
mng_uint8p pRawx;
mng_uint8p pRawx_prev;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_START)
#endif
iBpp = pData->iFilterbpp;
pRawx = pData->pWorkrow + pData->iPixelofs + iBpp;
pRawx_prev = pData->pWorkrow + pData->iPixelofs;
for (iX = iBpp; iX < pData->iRowsize; iX++)
{
*pRawx = (mng_uint8)(*pRawx + *pRawx_prev);
pRawx++;
pRawx_prev++;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode filter_up (mng_datap pData)
{
mng_uint8p pRawx;
mng_uint8p pPriorx;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_START)
#endif
pRawx = pData->pWorkrow + pData->iPixelofs;
pPriorx = pData->pPrevrow + pData->iPixelofs;
for (iX = 0; iX < pData->iRowsize; iX++)
{
*pRawx = (mng_uint8)(*pRawx + *pPriorx);
pRawx++;
pPriorx++;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode filter_average (mng_datap pData)
{
mng_int32 iBpp;
mng_uint8p pRawx;
mng_uint8p pRawx_prev;
mng_uint8p pPriorx;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_START)
#endif
iBpp = pData->iFilterbpp;
pRawx = pData->pWorkrow + pData->iPixelofs;
pPriorx = pData->pPrevrow + pData->iPixelofs;
pRawx_prev = pData->pWorkrow + pData->iPixelofs;
for (iX = 0; iX < iBpp; iX++)
{
*pRawx = (mng_uint8)(*pRawx + ((*pPriorx) >> 1));
pRawx++;
pPriorx++;
}
for (iX = iBpp; iX < pData->iRowsize; iX++)
{
*pRawx = (mng_uint8)(*pRawx + ((*pRawx_prev + *pPriorx) >> 1));
pRawx++;
pPriorx++;
pRawx_prev++;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode filter_paeth (mng_datap pData)
{
mng_int32 iBpp;
mng_uint8p pRawx;
mng_uint8p pRawx_prev;
mng_uint8p pPriorx;
mng_uint8p pPriorx_prev;
mng_int32 iX;
mng_uint32 iA, iB, iC;
mng_uint32 iP;
mng_uint32 iPa, iPb, iPc;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_START)
#endif
iBpp = pData->iFilterbpp;
pRawx = pData->pWorkrow + pData->iPixelofs;
pPriorx = pData->pPrevrow + pData->iPixelofs;
pRawx_prev = pData->pWorkrow + pData->iPixelofs;
pPriorx_prev = pData->pPrevrow + pData->iPixelofs;
for (iX = 0; iX < iBpp; iX++)
{
*pRawx = (mng_uint8)(*pRawx + *pPriorx);
pRawx++;
pPriorx++;
}
for (iX = iBpp; iX < pData->iRowsize; iX++)
{
iA = (mng_uint32)*pRawx_prev;
iB = (mng_uint32)*pPriorx;
iC = (mng_uint32)*pPriorx_prev;
iP = iA + iB - iC;
iPa = abs (iP - iA);
iPb = abs (iP - iB);
iPc = abs (iP - iC);
if ((iPa <= iPb) && (iPa <= iPc))
*pRawx = (mng_uint8)(*pRawx + iA);
else
if (iPb <= iPc)
*pRawx = (mng_uint8)(*pRawx + iB);
else
*pRawx = (mng_uint8)(*pRawx + iC);
pRawx++;
pPriorx++;
pRawx_prev++;
pPriorx_prev++;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
/* ************************************************************************** */
mng_retcode init_rowdiffering (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_START)
#endif
if (pData->iFilter & 0x40) /* has leveling parameters ? */
{
switch (pData->iColortype) /* salvage leveling parameters */
{
case 0 : { /* gray */
if (pData->iBitdepth <= 8)
pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
else
pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
break;
}
case 2 : { /* rgb */
if (pData->iBitdepth <= 8)
{
pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
}
else
{
pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
}
break;
}
case 3 : { /* indexed */
pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
break;
}
case 4 : { /* gray+alpha */
if (pData->iBitdepth <= 8)
{
pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
}
else
{
pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
}
break;
}
case 6 : { /* rgb+alpha */
if (pData->iBitdepth <= 8)
{
pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
pData->iLevel3 = (mng_uint16)*(pData->pWorkrow+3);
}
else
{
pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
pData->iLevel3 = mng_get_uint16 (pData->pWorkrow+6);
}
break;
}
}
}
/* shift the entire row back in place */
pRawi = pData->pWorkrow + pData->iFilterofs;
pRawo = pData->pWorkrow;
for (iX = 0; iX < pData->iRowsize + pData->iPixelofs - pData->iFilterofs; iX++)
*pRawo++ = *pRawi++;
pData->iFilterofs = 0; /* indicate so ! */
if (pData->iFilter & 0x01) /* no adaptive filtering ? */
pData->iPixelofs = pData->iFilterofs;
else
pData->iPixelofs = pData->iFilterofs + 1;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_g1 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_START)
#endif
if (pData->iLevel0 & 0x01) /* is it uneven level ? */
{
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
/* just invert every bit */
for (iX = 0; iX < pData->iRowsize; iX++)
*pRawo++ = (mng_uint8)(~(*pRawi++));
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_g2 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
mng_int32 iC, iS;
mng_uint8 iB, iN, iQ;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
iC = 0;
iB = 0;
iN = 0;
iS = 0;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
if (!iC)
{
iC = 4;
iB = *pRawi++;
iN = 0;
iS = 8;
}
iS -= 2;
iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
iN = (mng_uint8)((iN << 2) + iQ);
iC--;
if (!iC)
*pRawo++ = iN;
}
if (iC)
*pRawo = (mng_uint8)(iN << iS);
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_g4 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
mng_int32 iC, iS;
mng_uint8 iB, iN, iQ;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
iC = 0;
iB = 0;
iN = 0;
iS = 0;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
if (!iC)
{
iC = 2;
iB = *pRawi++;
iN = 0;
iS = 8;
}
iS -= 4;
iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
iN = (mng_uint8)((iN << 4) + iQ);
iC--;
if (!iC)
*pRawo++ = iN;
}
if (iC)
*pRawo = (mng_uint8)(iN << iS);
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_g8 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
pRawi++;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_g16 (mng_datap pData)
{
mng_uint16p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_START)
#endif
pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*pRawo++ = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
pRawi++;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_rgb8 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
*pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
(mng_uint16)*(pRawo+1)) & 0xFF);
*(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
(mng_uint16)*(pRawo+1)) & 0xFF);
pRawi += 3;
pRawo += 3;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_rgb16 (mng_datap pData)
{
mng_uint16p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_START)
#endif
pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
*pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
(mng_uint32)*(pRawo+1)) & 0xFFFF);
*(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
(mng_uint32)*(pRawo+1)) & 0xFFFF);
pRawi += 3;
pRawo += 3;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_idx1 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_START)
#endif
if (pData->iLevel0 & 0x01) /* is it uneven level ? */
{
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
/* just invert every bit */
for (iX = 0; iX < pData->iRowsize; iX++)
*pRawo++ = (mng_uint8)(~(*pRawi++));
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_idx2 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
mng_int32 iC, iS;
mng_uint8 iB, iN, iQ;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
iC = 0;
iB = 0;
iN = 0;
iS = 0;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
if (!iC)
{
iC = 4;
iB = *pRawi++;
iN = 0;
iS = 8;
}
iS -= 2;
iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
iN = (mng_uint8)((iN << 2) + iQ);
iC--;
if (!iC)
*pRawo++ = iN;
}
if (iC)
*pRawo = (mng_uint8)(iN << iS);
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_idx4 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
mng_int32 iC, iS;
mng_uint8 iB, iN, iQ;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
iC = 0;
iB = 0;
iN = 0;
iS = 0;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
if (!iC)
{
iC = 2;
iB = *pRawi++;
iN = 0;
iS = 8;
}
iS -= 4;
iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
iN = (mng_uint8)((iN << 4) + iQ);
iC--;
if (!iC)
*pRawo++ = iN;
}
if (iC)
*pRawo = (mng_uint8)(iN << iS);
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_idx8 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
pRawi++;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_ga8 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
*(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
pRawi += 2;
pRawo += 2;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_ga16 (mng_datap pData)
{
mng_uint16p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_START)
#endif
pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
*(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
pRawi += 2;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_rgba8 (mng_datap pData)
{
mng_uint8p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_START)
#endif
pRawi = pData->pWorkrow + pData->iPixelofs;
pRawo = pData->pPrevrow + pData->iPixelofs;
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
*pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
(mng_uint16)*(pRawo+1)) & 0xFF);
*(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
(mng_uint16)*(pRawo+1)) & 0xFF);
*(pRawo+3) = (mng_uint8)(((mng_uint16)*(pRawi+3) + pData->iLevel3) & 0xFF);
pRawi += 4;
pRawo += 4;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
mng_retcode differ_rgba16 (mng_datap pData)
{
mng_uint16p pRawi, pRawo;
mng_int32 iX;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_START)
#endif
pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
for (iX = 0; iX < pData->iRowsamples; iX++)
{
*(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
*pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
(mng_uint32)*(pRawo+1)) & 0xFFFF);
*(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
(mng_uint32)*(pRawo+1)) & 0xFFFF);
*(pRawo+3) = (mng_uint16)(((mng_uint32)*(pRawi+3) + (mng_uint32)pData->iLevel3) & 0xFFFF);
pRawi += 4;
pRawo += 4;
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
#endif /* MNG_INCLUDE_FILTERS */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,71 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_filter.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Filtering routines (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the filtering routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 09/07/2000 - G.Juyn * */
/* * - added support for new filter_types * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_filter_h_
#define _libmng_filter_h_
/* ************************************************************************** */
mng_retcode filter_a_row (mng_datap pData);
mng_retcode filter_sub (mng_datap pData);
mng_retcode filter_up (mng_datap pData);
mng_retcode filter_average (mng_datap pData);
mng_retcode filter_paeth (mng_datap pData);
/* ************************************************************************** */
mng_retcode init_rowdiffering (mng_datap pData);
mng_retcode differ_g1 (mng_datap pData);
mng_retcode differ_g2 (mng_datap pData);
mng_retcode differ_g4 (mng_datap pData);
mng_retcode differ_g8 (mng_datap pData);
mng_retcode differ_g16 (mng_datap pData);
mng_retcode differ_rgb8 (mng_datap pData);
mng_retcode differ_rgb16 (mng_datap pData);
mng_retcode differ_idx1 (mng_datap pData);
mng_retcode differ_idx2 (mng_datap pData);
mng_retcode differ_idx4 (mng_datap pData);
mng_retcode differ_idx8 (mng_datap pData);
mng_retcode differ_ga8 (mng_datap pData);
mng_retcode differ_ga16 (mng_datap pData);
mng_retcode differ_rgba8 (mng_datap pData);
mng_retcode differ_rgba16 (mng_datap pData);
/* ************************************************************************** */
#endif /* _libmng_filter_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,59 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_jpeg.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : JPEG library interface (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the JPEG library interface * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 10/16/2000 - G.Juyn * */
/* * - added support for JDAA * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_jpeg_h_
#define _libmng_jpeg_h_
/* ************************************************************************** */
mng_retcode mngjpeg_initialize (mng_datap pData);
mng_retcode mngjpeg_cleanup (mng_datap pData);
mng_retcode mngjpeg_decompressinit (mng_datap pData);
mng_retcode mngjpeg_decompressdata (mng_datap pData,
mng_uint32 iRawsize,
mng_uint8p pRawdata);
mng_retcode mngjpeg_decompressfree (mng_datap pData);
mng_retcode mngjpeg_decompressinit2 (mng_datap pData);
mng_retcode mngjpeg_decompressdata2 (mng_datap pData,
mng_uint32 iRawsize,
mng_uint8p pRawdata);
mng_retcode mngjpeg_decompressfree2 (mng_datap pData);
/* ************************************************************************** */
#endif /* _libmng_jpeg_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,66 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_memory.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Memory management (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of memory management functions * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.5.3 - 06/12/2000 - G.Juyn * */
/* * - swapped MNG_COPY parameter-names * */
/* * 0.5.3 - 06/27/2000 - G.Juyn * */
/* * - changed size parameter to mng_size_t * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_memory_h_
#define _libmng_memory_h_
/* ************************************************************************** */
/* * * */
/* * Generic memory manager macros * */
/* * * */
/* ************************************************************************** */
#ifdef MNG_INTERNAL_MEMMNGMT
#define MNG_ALLOC(H,P,L) { P = calloc (1, (mng_size_t)(L)); \
if (P == 0) { MNG_ERROR (H, MNG_OUTOFMEMORY) } }
#define MNG_ALLOCX(H,P,L) { P = calloc (1, (mng_size_t)(L)); }
#define MNG_FREE(H,P,L) { if (P) { free (P); P = 0; } }
#define MNG_FREEX(H,P,L) { if (P) free (P); }
#else
#define MNG_ALLOC(H,P,L) { P = H->fMemalloc ((mng_size_t)(L)); \
if (P == 0) { MNG_ERROR (H, MNG_OUTOFMEMORY) } }
#define MNG_ALLOCX(H,P,L) { P = H->fMemalloc ((mng_size_t)(L)); }
#define MNG_FREE(H,P,L) { if (P) { H->fMemfree (P, (mng_size_t)(L)); P = 0; } }
#define MNG_FREEX(H,P,L) { if (P) { H->fMemfree (P, (mng_size_t)(L)); } }
#endif /* mng_internal_memmngmt */
#define MNG_COPY(D,S,L) { memcpy (D, S, (mng_size_t)(L)); }
/* ************************************************************************** */
#endif /* _libmng_memory_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

File diff suppressed because it is too large Load Diff

View File

@@ -1,432 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_object_prc.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Object processing routines (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the internal object processing routines * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.5.2 - 05/24/2000 - G.Juyn * */
/* * - added support for global color-chunks in animation * */
/* * - added support for global PLTE,tRNS,bKGD in animation * */
/* * - added SAVE & SEEK animation objects * */
/* * 0.5.2 - 05/29/2000 - G.Juyn * */
/* * - changed ani_object create routines not to return the * */
/* * created object (wasn't necessary) * */
/* * - added compression/filter/interlace fields to * */
/* * object-buffer for delta-image processing * */
/* * * */
/* * 0.5.3 - 06/22/2000 - G.Juyn * */
/* * - added support for PPLT chunk * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/26/2000 - G.Juyn * */
/* * - added MAGN chunk * */
/* * 0.9.3 - 10/17/2000 - G.Juyn * */
/* * - added routine to discard "invalid" objects * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_object_prc_h_
#define _libmng_object_prc_h_
/* ************************************************************************** */
mng_retcode drop_invalid_objects (mng_datap pData);
/* ************************************************************************** */
mng_retcode create_imagedataobject (mng_datap pData,
mng_bool bConcrete,
mng_bool bViewable,
mng_uint32 iWidth,
mng_uint32 iHeight,
mng_uint8 iBitdepth,
mng_uint8 iColortype,
mng_uint8 iCompression,
mng_uint8 iFilter,
mng_uint8 iInterlace,
mng_imagedatap *ppObject);
mng_retcode free_imagedataobject (mng_datap pData,
mng_imagedatap pImagedata);
mng_retcode clone_imagedataobject (mng_datap pData,
mng_bool bConcrete,
mng_imagedatap pSource,
mng_imagedatap *ppClone);
/* ************************************************************************** */
mng_retcode create_imageobject (mng_datap pData,
mng_uint16 iId,
mng_bool bConcrete,
mng_bool bVisible,
mng_bool bViewable,
mng_uint32 iWidth,
mng_uint32 iHeight,
mng_uint8 iBitdepth,
mng_uint8 iColortype,
mng_uint8 iCompression,
mng_uint8 iFilter,
mng_uint8 iInterlace,
mng_int32 iPosx,
mng_int32 iPosy,
mng_bool bClipped,
mng_int32 iClipl,
mng_int32 iClipr,
mng_int32 iClipt,
mng_int32 iClipb,
mng_imagep *ppObject);
mng_retcode free_imageobject (mng_datap pData,
mng_imagep pImage);
mng_imagep find_imageobject (mng_datap pData,
mng_uint16 iId);
mng_retcode clone_imageobject (mng_datap pData,
mng_uint16 iId,
mng_bool bPartial,
mng_bool bVisible,
mng_bool bAbstract,
mng_bool bHasloca,
mng_uint8 iLocationtype,
mng_int32 iLocationx,
mng_int32 iLocationy,
mng_imagep pSource,
mng_imagep *ppClone);
mng_retcode renum_imageobject (mng_datap pData,
mng_imagep pSource,
mng_uint16 iId,
mng_bool bVisible,
mng_bool bAbstract,
mng_bool bHasloca,
mng_uint8 iLocationtype,
mng_int32 iLocationx,
mng_int32 iLocationy);
mng_retcode reset_object_details (mng_datap pData,
mng_imagep pImage,
mng_uint32 iWidth,
mng_uint32 iHeight,
mng_uint8 iBitdepth,
mng_uint8 iColortype,
mng_uint8 iCompression,
mng_uint8 iFilter,
mng_uint8 iInterlace,
mng_bool bResetall);
mng_retcode promote_imageobject (mng_datap pData,
mng_imagep pImage,
mng_uint8 iBitdepth,
mng_uint8 iColortype,
mng_uint8 iFilltype);
mng_retcode magnify_imageobject (mng_datap pData,
mng_imagep pImage);
/* ************************************************************************** */
mng_retcode create_ani_image (mng_datap pData);
mng_retcode create_ani_plte (mng_datap pData,
mng_uint32 iEntrycount,
mng_palette8ep paEntries);
mng_retcode create_ani_trns (mng_datap pData,
mng_uint32 iRawlen,
mng_uint8p pRawdata);
mng_retcode create_ani_gama (mng_datap pData,
mng_bool bEmpty,
mng_uint32 iGamma);
mng_retcode create_ani_chrm (mng_datap pData,
mng_bool bEmpty,
mng_uint32 iWhitepointx,
mng_uint32 iWhitepointy,
mng_uint32 iRedx,
mng_uint32 iRedy,
mng_uint32 iGreenx,
mng_uint32 iGreeny,
mng_uint32 iBluex,
mng_uint32 iBluey);
mng_retcode create_ani_srgb (mng_datap pData,
mng_bool bEmpty,
mng_uint8 iRenderinginent);
mng_retcode create_ani_iccp (mng_datap pData,
mng_bool bEmpty,
mng_uint32 iProfilesize,
mng_ptr pProfile);
mng_retcode create_ani_bkgd (mng_datap pData,
mng_uint16 iRed,
mng_uint16 iGreen,
mng_uint16 iBlue);
mng_retcode create_ani_loop (mng_datap pData,
mng_uint8 iLevel,
mng_uint32 iRepeatcount,
mng_uint8 iTermcond,
mng_uint32 iItermin,
mng_uint32 iItermax,
mng_uint32 iCount,
mng_uint32p pSignals);
mng_retcode create_ani_endl (mng_datap pData,
mng_uint8 iLevel);
mng_retcode create_ani_defi (mng_datap pData);
mng_retcode create_ani_basi (mng_datap pData,
mng_uint16 iRed,
mng_uint16 iGreen,
mng_uint16 iBlue,
mng_bool bHasalpha,
mng_uint16 iAlpha,
mng_uint8 iViewable);
mng_retcode create_ani_clon (mng_datap pData,
mng_uint16 iCloneid,
mng_uint16 iSourceid,
mng_uint8 iClonetype,
mng_bool bHasdonotshow,
mng_uint8 iDonotshow,
mng_uint8 iConcrete,
mng_bool bHasloca,
mng_uint8 iLocatype,
mng_int32 iLocax,
mng_int32 iLocay);
mng_retcode create_ani_back (mng_datap pData,
mng_uint16 iRed,
mng_uint16 iGreen,
mng_uint16 iBlue,
mng_uint8 iMandatory,
mng_uint16 iImageid,
mng_uint8 iTile);
mng_retcode create_ani_fram (mng_datap pData,
mng_uint8 iFramemode,
mng_uint8 iChangedelay,
mng_uint32 iDelay,
mng_uint8 iChangetimeout,
mng_uint32 iTimeout,
mng_uint8 iChangeclipping,
mng_uint8 iCliptype,
mng_int32 iClipl,
mng_int32 iClipr,
mng_int32 iClipt,
mng_int32 iClipb);
mng_retcode create_ani_move (mng_datap pData,
mng_uint16 iFirstid,
mng_uint16 iLastid,
mng_uint8 iType,
mng_int32 iLocax,
mng_int32 iLocay);
mng_retcode create_ani_clip (mng_datap pData,
mng_uint16 iFirstid,
mng_uint16 iLastid,
mng_uint8 iType,
mng_int32 iClipl,
mng_int32 iClipr,
mng_int32 iClipt,
mng_int32 iClipb);
mng_retcode create_ani_show (mng_datap pData,
mng_uint16 iFirstid,
mng_uint16 iLastid,
mng_uint8 iMode);
mng_retcode create_ani_term (mng_datap pData,
mng_uint8 iTermaction,
mng_uint8 iIteraction,
mng_uint32 iDelay,
mng_uint32 iItermax);
mng_retcode create_ani_save (mng_datap pData);
mng_retcode create_ani_seek (mng_datap pData);
mng_retcode create_ani_dhdr (mng_datap pData,
mng_uint16 iObjectid,
mng_uint8 iImagetype,
mng_uint8 iDeltatype,
mng_uint32 iBlockwidth,
mng_uint32 iBlockheight,
mng_uint32 iBlockx,
mng_uint32 iBlocky);
mng_retcode create_ani_prom (mng_datap pData,
mng_uint8 iBitdepth,
mng_uint8 iColortype,
mng_uint8 iFilltype);
mng_retcode create_ani_ipng (mng_datap pData);
mng_retcode create_ani_ijng (mng_datap pData);
mng_retcode create_ani_pplt (mng_datap pData,
mng_uint8 iType,
mng_uint32 iCount,
mng_palette8ep paIndexentries,
mng_uint8p paAlphaentries,
mng_uint8p paUsedentries);
mng_retcode create_ani_magn (mng_datap pData,
mng_uint16 iFirstid,
mng_uint16 iLastid,
mng_uint16 iMethodX,
mng_uint16 iMX,
mng_uint16 iMY,
mng_uint16 iML,
mng_uint16 iMR,
mng_uint16 iMT,
mng_uint16 iMB,
mng_uint16 iMethodY);
/* ************************************************************************** */
mng_retcode free_ani_image (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_plte (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_trns (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_gama (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_chrm (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_srgb (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_iccp (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_bkgd (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_loop (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_endl (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_defi (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_basi (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_clon (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_back (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_fram (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_move (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_clip (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_show (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_term (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_save (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_seek (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_dhdr (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_prom (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_ipng (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_ijng (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_pplt (mng_datap pData,
mng_objectp pObject);
mng_retcode free_ani_magn (mng_datap pData,
mng_objectp pObject);
/* ************************************************************************** */
mng_retcode process_ani_image (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_plte (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_trns (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_gama (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_chrm (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_srgb (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_iccp (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_bkgd (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_loop (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_endl (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_defi (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_basi (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_clon (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_back (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_fram (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_move (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_clip (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_show (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_term (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_save (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_seek (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_dhdr (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_prom (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_ipng (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_ijng (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_pplt (mng_datap pData,
mng_objectp pObject);
mng_retcode process_ani_magn (mng_datap pData,
mng_objectp pObject);
/* ************************************************************************** */
#endif /* _libmng_object_prc_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

View File

@@ -1,509 +0,0 @@
/* ************************************************************************** */
/* * For conditions of distribution and use, * */
/* * see copyright notice in libmng.h * */
/* ************************************************************************** */
/* * * */
/* * project : libmng * */
/* * file : libmng_objects.h copyright (c) 2000 G.Juyn * */
/* * version : 1.0.0 * */
/* * * */
/* * purpose : Internal object structures (definition) * */
/* * * */
/* * author : G.Juyn * */
/* * web : http://www.3-t.com * */
/* * email : mailto:info@3-t.com * */
/* * * */
/* * comment : Definition of the internal object structures * */
/* * * */
/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
/* * - changed strict-ANSI stuff * */
/* * * */
/* * 0.5.2 - 05/23/2000 - G.Juyn * */
/* * - changed inclusion to DISPLAY_PROCS * */
/* * 0.5.2 - 05/24/2000 - G.Juyn * */
/* * - added global color-chunks for animations * */
/* * - added global PLTE,tRNS,bKGD chunks for animation * */
/* * - added SAVE & SEEK animation objects * */
/* * 0.5.2 - 05/29/2000 - G.Juyn * */
/* * - added framenr/layernr/playtime to object header * */
/* * 0.5.2 - 05/30/2000 - G.Juyn * */
/* * - added ani-objects for delta-image processing * */
/* * - added compression/filter/interlace fields to * */
/* * object-buffer for delta-image processing * */
/* * * */
/* * 0.5.3 - 06/17/2000 - G.Juyn * */
/* * - changed definition of aTRNSentries * */
/* * 0.5.3 - 06/22/2000 - G.Juyn * */
/* * - added definition for PPLT animation-processing * */
/* * * */
/* * 0.9.2 - 08/05/2000 - G.Juyn * */
/* * - changed file-prefixes * */
/* * * */
/* * 0.9.3 - 08/26/2000 - G.Juyn * */
/* * - added MAGN chunk * */
/* * 0.9.3 - 09/10/2000 - G.Juyn * */
/* * - fixed DEFI behavior * */
/* * 0.9.3 - 10/16/2000 - G.Juyn * */
/* * - added support for delta-JNG * */
/* * 0.9.3 - 10/17/2000 - G.Juyn * */
/* * - added valid-flag to stored objects for read() / display()* */
/* * 0.9.3 - 10/19/2000 - G.Juyn * */
/* * - added storage for pixel-/alpha-sampledepth for delta's * */
/* * * */
/* ************************************************************************** */
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
#pragma option -A /* force ANSI-C */
#endif
#ifndef _libmng_objects_h_
#define _libmng_objects_h_
/* ************************************************************************** */
#ifdef MNG_INCLUDE_DISPLAY_PROCS
/* ************************************************************************** */
typedef mng_retcode (*mng_cleanupobject) (mng_datap pData,
mng_objectp pHeader);
typedef mng_retcode (*mng_processobject) (mng_datap pData,
mng_objectp pHeader);
/* ************************************************************************** */
typedef struct {
mng_cleanupobject fCleanup;
mng_processobject fProcess;
mng_objectp pNext; /* for double-linked list */
mng_objectp pPrev;
mng_uint32 iFramenr;
mng_uint32 iLayernr;
mng_uint32 iPlaytime;
} mng_object_header;
typedef mng_object_header * mng_object_headerp;
/* ************************************************************************** */
typedef struct { /* MNG specification "object-buffer" */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint32 iRefcount; /* reference counter */
mng_bool bFrozen; /* frozen flag */
mng_bool bConcrete; /* concrete flag */
mng_bool bViewable; /* viewable flag */
mng_uint32 iWidth; /* image specifics */
mng_uint32 iHeight;
mng_uint8 iBitdepth;
mng_uint8 iColortype;
mng_uint8 iCompression;
mng_uint8 iFilter;
mng_uint8 iInterlace;
mng_uint8 iAlphabitdepth; /* used only for JNG images */
mng_uint8 iJHDRcompression;
mng_uint8 iJHDRinterlace;
mng_uint8 iPixelsampledepth; /* used with delta-images */
mng_uint8 iAlphasampledepth;
mng_bool bHasPLTE; /* PLTE chunk present */
mng_bool bHasTRNS; /* tRNS chunk present */
mng_bool bHasGAMA; /* gAMA chunk present */
mng_bool bHasCHRM; /* cHRM chunk present */
mng_bool bHasSRGB; /* sRGB chunk present */
mng_bool bHasICCP; /* iCCP chunk present */
mng_bool bHasBKGD; /* bKGD chunk present */
mng_uint32 iPLTEcount; /* PLTE fields */
mng_rgbpaltab aPLTEentries;
mng_uint16 iTRNSgray; /* tRNS fields */
mng_uint16 iTRNSred;
mng_uint16 iTRNSgreen;
mng_uint16 iTRNSblue;
mng_uint32 iTRNScount;
mng_uint8arr aTRNSentries;
mng_uint32 iGamma; /* gAMA fields */
mng_uint32 iWhitepointx; /* cHRM fields */
mng_uint32 iWhitepointy;
mng_uint32 iPrimaryredx;
mng_uint32 iPrimaryredy;
mng_uint32 iPrimarygreenx;
mng_uint32 iPrimarygreeny;
mng_uint32 iPrimarybluex;
mng_uint32 iPrimarybluey;
mng_uint8 iRenderingintent; /* sRGB fields */
mng_uint32 iProfilesize; /* iCCP fields */
mng_ptr pProfile;
mng_uint8 iBKGDindex; /* bKGD fields */
mng_uint16 iBKGDgray;
mng_uint16 iBKGDred;
mng_uint16 iBKGDgreen;
mng_uint16 iBKGDblue;
mng_uint32 iSamplesize; /* size of a sample */
mng_uint32 iRowsize; /* size of a row of samples */
mng_uint32 iImgdatasize; /* size of the sample data buffer */
mng_uint8p pImgdata; /* actual sample data buffer */
} mng_imagedata;
typedef mng_imagedata * mng_imagedatap;
/* ************************************************************************** */
typedef struct { /* MNG specification "object" */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iId; /* object-id */
mng_bool bFrozen; /* frozen flag */
mng_bool bVisible; /* potential visibility flag */
mng_bool bViewable; /* viewable flag */
mng_bool bValid; /* marks invalid when only reading */
mng_int32 iPosx; /* location fields */
mng_int32 iPosy;
mng_bool bClipped; /* clipping fields */
mng_int32 iClipl;
mng_int32 iClipr;
mng_int32 iClipt;
mng_int32 iClipb;
mng_uint16 iMAGN_MethodX; /* magnification (MAGN) */
mng_uint16 iMAGN_MethodY;
mng_uint16 iMAGN_MX;
mng_uint16 iMAGN_MY;
mng_uint16 iMAGN_ML;
mng_uint16 iMAGN_MR;
mng_uint16 iMAGN_MT;
mng_uint16 iMAGN_MB;
mng_imagedatap pImgbuf; /* the image-data buffer */
} mng_image;
typedef mng_image * mng_imagep;
/* ************************************************************************** */
/* "on-the-fly" image (= object 0) */
typedef mng_image mng_ani_image; /* let's (ab)use the general "object" */
typedef mng_ani_image * mng_ani_imagep; /* that's actualy crucial, so don't change it! */
/* ************************************************************************** */
typedef struct { /* global PLTE object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint32 iEntrycount;
mng_rgbpaltab aEntries;
} mng_ani_plte;
typedef mng_ani_plte * mng_ani_pltep;
/* ************************************************************************** */
typedef struct { /* global tRNS object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint32 iRawlen;
mng_uint8arr aRawdata;
} mng_ani_trns;
typedef mng_ani_trns * mng_ani_trnsp;
/* ************************************************************************** */
typedef struct { /* global gAMA object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_bool bEmpty;
mng_uint32 iGamma;
} mng_ani_gama;
typedef mng_ani_gama * mng_ani_gamap;
/* ************************************************************************** */
typedef struct { /* global gCRM object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_bool bEmpty;
mng_uint32 iWhitepointx;
mng_uint32 iWhitepointy;
mng_uint32 iRedx;
mng_uint32 iRedy;
mng_uint32 iGreenx;
mng_uint32 iGreeny;
mng_uint32 iBluex;
mng_uint32 iBluey;
} mng_ani_chrm;
typedef mng_ani_chrm * mng_ani_chrmp;
/* ************************************************************************** */
typedef struct { /* global sRGB object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_bool bEmpty;
mng_uint8 iRenderingintent;
} mng_ani_srgb;
typedef mng_ani_srgb * mng_ani_srgbp;
/* ************************************************************************** */
typedef struct { /* global iCCP object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_bool bEmpty;
mng_uint32 iProfilesize;
mng_ptr pProfile;
} mng_ani_iccp;
typedef mng_ani_iccp * mng_ani_iccpp;
/* ************************************************************************** */
typedef struct { /* global bKGD object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iRed;
mng_uint16 iGreen;
mng_uint16 iBlue;
} mng_ani_bkgd;
typedef mng_ani_bkgd * mng_ani_bkgdp;
/* ************************************************************************** */
typedef struct { /* LOOP object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint8 iLevel;
mng_uint32 iRepeatcount;
mng_uint8 iTermcond;
mng_uint32 iItermin;
mng_uint32 iItermax;
mng_uint32 iCount;
mng_uint32p pSignals;
mng_uint32 iRunningcount; /* running counter */
} mng_ani_loop;
typedef mng_ani_loop * mng_ani_loopp;
/* ************************************************************************** */
typedef struct { /* ENDL object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint8 iLevel;
mng_ani_loopp pLOOP; /* matching LOOP */
} mng_ani_endl;
typedef mng_ani_endl * mng_ani_endlp;
/* ************************************************************************** */
typedef struct { /* DEFI object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iId;
mng_bool bHasdonotshow;
mng_uint8 iDonotshow;
mng_bool bHasconcrete;
mng_uint8 iConcrete;
mng_bool bHasloca;
mng_int32 iLocax;
mng_int32 iLocay;
mng_bool bHasclip;
mng_int32 iClipl;
mng_int32 iClipr;
mng_int32 iClipt;
mng_int32 iClipb;
} mng_ani_defi;
typedef mng_ani_defi * mng_ani_defip;
/* ************************************************************************** */
typedef struct { /* BASI object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iRed;
mng_uint16 iGreen;
mng_uint16 iBlue;
mng_bool bHasalpha;
mng_uint16 iAlpha;
mng_uint8 iViewable;
} mng_ani_basi;
typedef mng_ani_basi * mng_ani_basip;
/* ************************************************************************** */
typedef struct { /* CLON object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iCloneid;
mng_uint16 iSourceid;
mng_uint8 iClonetype;
mng_bool bHasdonotshow;
mng_uint8 iDonotshow;
mng_uint8 iConcrete;
mng_bool bHasloca;
mng_uint8 iLocatype;
mng_int32 iLocax;
mng_int32 iLocay;
} mng_ani_clon;
typedef mng_ani_clon * mng_ani_clonp;
/* ************************************************************************** */
typedef struct { /* BACK object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iRed;
mng_uint16 iGreen;
mng_uint16 iBlue;
mng_uint8 iMandatory;
mng_uint16 iImageid;
mng_uint8 iTile;
} mng_ani_back;
typedef mng_ani_back * mng_ani_backp;
/* ************************************************************************** */
typedef struct { /* FRAM object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint8 iFramemode;
mng_uint8 iChangedelay;
mng_uint32 iDelay;
mng_uint8 iChangetimeout;
mng_uint32 iTimeout;
mng_uint8 iChangeclipping;
mng_uint8 iCliptype;
mng_int32 iClipl;
mng_int32 iClipr;
mng_int32 iClipt;
mng_int32 iClipb;
} mng_ani_fram;
typedef mng_ani_fram * mng_ani_framp;
/* ************************************************************************** */
typedef struct { /* MOVE object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint8 iType;
mng_int32 iLocax;
mng_int32 iLocay;
} mng_ani_move;
typedef mng_ani_move * mng_ani_movep;
/* ************************************************************************** */
typedef struct { /* CLIP object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint8 iType;
mng_int32 iClipl;
mng_int32 iClipr;
mng_int32 iClipt;
mng_int32 iClipb;
} mng_ani_clip;
typedef mng_ani_clip * mng_ani_clipp;
/* ************************************************************************** */
typedef struct { /* SHOW object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint8 iMode;
} mng_ani_show;
typedef mng_ani_show * mng_ani_showp;
/* ************************************************************************** */
typedef struct { /* TERM object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint8 iTermaction;
mng_uint8 iIteraction;
mng_uint32 iDelay;
mng_uint32 iItermax;
} mng_ani_term;
typedef mng_ani_term * mng_ani_termp;
/* ************************************************************************** */
typedef struct { /* SAVE object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
} mng_ani_save;
typedef mng_ani_save * mng_ani_savep;
/* ************************************************************************** */
typedef struct { /* SEEK object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
} mng_ani_seek;
typedef mng_ani_seek * mng_ani_seekp;
/* ************************************************************************** */
typedef struct { /* DHDR object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iObjectid;
mng_uint8 iImagetype;
mng_uint8 iDeltatype;
mng_uint32 iBlockwidth;
mng_uint32 iBlockheight;
mng_uint32 iBlockx;
mng_uint32 iBlocky;
} mng_ani_dhdr;
typedef mng_ani_dhdr * mng_ani_dhdrp;
/* ************************************************************************** */
typedef struct { /* PROM object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint8 iBitdepth;
mng_uint8 iColortype;
mng_uint8 iFilltype;
} mng_ani_prom;
typedef mng_ani_prom * mng_ani_promp;
/* ************************************************************************** */
typedef struct { /* IPNG object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
} mng_ani_ipng;
typedef mng_ani_ipng * mng_ani_ipngp;
/* ************************************************************************** */
typedef struct { /* IJNG object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
} mng_ani_ijng;
typedef mng_ani_ijng * mng_ani_ijngp;
/* ************************************************************************** */
typedef struct { /* PPLT object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint8 iType;
mng_uint32 iCount;
mng_rgbpaltab aIndexentries;
mng_uint8arr aAlphaentries;
mng_uint8arr aUsedentries;
} mng_ani_pplt;
typedef mng_ani_pplt * mng_ani_ppltp;
/* ************************************************************************** */
typedef struct { /* MAGN object */
mng_object_header sHeader; /* default header (DO NOT REMOVE) */
mng_uint16 iFirstid;
mng_uint16 iLastid;
mng_uint16 iMethodX;
mng_uint16 iMX;
mng_uint16 iMY;
mng_uint16 iML;
mng_uint16 iMR;
mng_uint16 iMT;
mng_uint16 iMB;
mng_uint16 iMethodY;
} mng_ani_magn;
typedef mng_ani_magn * mng_ani_magnp;
/* ************************************************************************** */
#endif /* MNG_INCLUDE_DISPLAY_PROCS */
/* ************************************************************************** */
#endif /* _libmng_objects_h_ */
/* ************************************************************************** */
/* * end of file * */
/* ************************************************************************** */

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