ColorModel.java: New file...

2000-07-23  Rolf W. Rasmussen  <rolfwr@ii.uib.no>

	* libjava/java/awt/image/ColorModel.java: New file, replaces the
	stub libjava/java/awt/ColorModel.java which was located in the
	wrong package.
	* libjava/java/awt/image/ComponentColorModel.java: New file.
	* libjava/java/awt/image/ComponentSampleModel.java: New file.
	* libjava/java/awt/image/DataBuffer.java: New file.
	* libjava/java/awt/image/DataBufferByte.java: New file.
	* libjava/java/awt/image/DataBufferInt.java: New file.
	* libjava/java/awt/image/DataBufferUShort.java: New file.
	* libjava/java/awt/image/DirectColorModel.java: New file.
	* libjava/java/awt/image/PackedColorModel.java: New file.
	* libjava/java/awt/image/Raster.java: New file.
	* libjava/java/awt/image/SampleModel.java: New file.
	* libjava/java/awt/image/SinglePixelPackedSampleModel.java: New
	file.
	* libjava/java/awt/image/IndexColorModel.java: New file.
	* libjava/java/awt/image/ImageConsumer.java: Removed import of
	java.awt.ColorModel stub.

	* gnu/gcj/util/BitMaskExtent.java: New file, utility class.
	* gnu/gcj/util/Buffers.java: New file, utility class.

	* libjava/Makefile.am: Updated to include new files.
	* libjava/Makefile.in: Rebuilt.

From-SVN: r35245
This commit is contained in:
Rolf W. Rasmussen 2000-07-25 19:53:30 +02:00 committed by Rolf Rasmussen
parent 4c31fe99c3
commit 69b1b29156
24 changed files with 4520 additions and 74 deletions

View File

@ -1,3 +1,30 @@
2000-07-23 Rolf W. Rasmussen <rolfwr@ii.uib.no>
* libjava/java/awt/image/ColorModel.java: New file, replaces the
stub libjava/java/awt/ColorModel.java which was located in the
wrong package.
* libjava/java/awt/image/ComponentColorModel.java: New file.
* libjava/java/awt/image/ComponentSampleModel.java: New file.
* libjava/java/awt/image/DataBuffer.java: New file.
* libjava/java/awt/image/DataBufferByte.java: New file.
* libjava/java/awt/image/DataBufferInt.java: New file.
* libjava/java/awt/image/DataBufferUShort.java: New file.
* libjava/java/awt/image/DirectColorModel.java: New file.
* libjava/java/awt/image/PackedColorModel.java: New file.
* libjava/java/awt/image/Raster.java: New file.
* libjava/java/awt/image/SampleModel.java: New file.
* libjava/java/awt/image/SinglePixelPackedSampleModel.java: New
file.
* libjava/java/awt/image/IndexColorModel.java: New file.
* libjava/java/awt/image/ImageConsumer.java: Removed import of
java.awt.ColorModel stub.
* gnu/gcj/util/BitMaskExtent.java: New file, utility class.
* gnu/gcj/util/Buffers.java: New file, utility class.
* libjava/Makefile.am: Updated to include new files.
* libjava/Makefile.in: Rebuilt.
2000-07-23 Oskar Liljeblad <osk@hem.passagen.se>
* java/io/StreamTokenizer.java: Merged with classpath.

View File

@ -486,6 +486,8 @@ gnu/gcj/convert/UnicodeToBytes.java
special_java_source_files = java/lang/Class.java java/lang/Object.java
awt_java_source_files = \
gnu/gcj/awt/BitMaskExtent.java \
gnu/gcj/awt/Buffers.java \
java/awt/AWTError.java \
java/awt/AWTEvent.java \
java/awt/AWTEventMulticaster.java \
@ -495,7 +497,6 @@ java/awt/Adjustable.java \
java/awt/BorderLayout.java \
java/awt/CheckboxGroup.java \
java/awt/Color.java \
java/awt/ColorModel.java \
java/awt/Component.java \
java/awt/ComponentOrientation.java \
java/awt/Container.java \
@ -535,6 +536,9 @@ java/awt/TextComponent.java \
java/awt/Toolkit.java \
java/awt/Transparency.java \
java/awt/Window.java \
java/awt/color/ColorSpace.java \
java/awt/color/ICC_ColorSpace.java \
java/awt/color/ICC_Profile.java \
java/awt/event/AWTEventListener.java \
java/awt/event/ActionEvent.java \
java/awt/event/ActionListener.java \
@ -582,9 +586,23 @@ java/awt/geom/PathIterator.java \
java/awt/geom/Point2D.java \
java/awt/geom/Rectangle2D.java \
java/awt/geom/RectangularShape.java \
java/awt/image/ColorModel.java \
java/awt/image/ComponentColorModel.java \
java/awt/image/ComponentSampleModel.java \
java/awt/image/DataBuffer.java \
java/awt/image/DataBufferByte.java \
java/awt/image/DataBufferInt.java \
java/awt/image/DataBufferUShort.java \
java/awt/image/DirectColorModel.java \
java/awt/image/ImageConsumer.java \
java/awt/image/ImageObserver.java \
java/awt/image/ImageProducer.java \
java/awt/image/IndexColorModel.java \
java/awt/image/PackedColorModel.java \
java/awt/image/Raster.java \
java/awt/image/SampleModel.java \
java/awt/image/SinglePixelPackedSampleModel.java \
java/awt/image/WritableRaster.java \
java/awt/peer/ButtonPeer.java \
java/awt/peer/CanvasPeer.java \
java/awt/peer/CheckboxMenuItemPeer.java \

View File

@ -115,48 +115,31 @@ here = @here@
libgcj_basedir = @libgcj_basedir@
AUTOMAKE_OPTIONS = foreign no-installinfo
@TESTSUBDIR_TRUE@SUBDIRS = \
@TESTSUBDIR_TRUE@$(DIRLTDL) testsuite gcj include
@TESTSUBDIR_FALSE@SUBDIRS = \
@TESTSUBDIR_FALSE@$(DIRLTDL) gcj include
@USE_LIBDIR_TRUE@toolexeclibdir = \
@USE_LIBDIR_TRUE@$(libdir)$(MULTISUBDIR)
@USE_LIBDIR_FALSE@toolexeclibdir = \
@USE_LIBDIR_FALSE@$(toolexecdir)/lib$(MULTISUBDIR)
@USE_LIBDIR_FALSE@toolexecdir = \
@USE_LIBDIR_FALSE@$(exec_prefix)/$(target_alias)
@TESTSUBDIR_TRUE@SUBDIRS = @TESTSUBDIR_TRUE@$(DIRLTDL) testsuite gcj include
@TESTSUBDIR_FALSE@SUBDIRS = @TESTSUBDIR_FALSE@$(DIRLTDL) gcj include
@USE_LIBDIR_TRUE@toolexeclibdir = @USE_LIBDIR_TRUE@$(libdir)$(MULTISUBDIR)
@USE_LIBDIR_FALSE@toolexeclibdir = @USE_LIBDIR_FALSE@$(toolexecdir)/lib$(MULTISUBDIR)
@USE_LIBDIR_FALSE@toolexecdir = @USE_LIBDIR_FALSE@$(exec_prefix)/$(target_alias)
toolexeclib_LTLIBRARIES = libgcj.la
toolexeclib_DATA = libgcj.spec
data_DATA = libgcj.zip
@NEEDS_DATA_START_TRUE@toolexeclib_LIBRARIES = \
@NEEDS_DATA_START_TRUE@libgcjdata.a
@NEEDS_DATA_START_TRUE@libgcjdata_a_SOURCES = \
@NEEDS_DATA_START_TRUE@libgcjdata.c
@NEEDS_DATA_START_TRUE@toolexeclib_LIBRARIES = @NEEDS_DATA_START_TRUE@libgcjdata.a
@NEEDS_DATA_START_TRUE@libgcjdata_a_SOURCES = @NEEDS_DATA_START_TRUE@libgcjdata.c
@NATIVE_TRUE@bin_PROGRAMS = \
@NATIVE_TRUE@jv-convert gij
@NATIVE_TRUE@bin_PROGRAMS = @NATIVE_TRUE@jv-convert gij
bin_SCRIPTS = addr2name.awk
@CANADIAN_TRUE@@NULL_TARGET_TRUE@GCJ = \
@CANADIAN_TRUE@@NULL_TARGET_TRUE@gcj
@CANADIAN_TRUE@@NULL_TARGET_FALSE@GCJ = \
@CANADIAN_TRUE@@NULL_TARGET_FALSE@$(target_alias)-gcj
@CANADIAN_FALSE@GCJ = \
@CANADIAN_FALSE@$(expanded)/gcj$(EXEEXT) -B$(expanded)/
@CANADIAN_TRUE@@NULL_TARGET_TRUE@ZIP = \
@CANADIAN_TRUE@@NULL_TARGET_TRUE@$(MULTIBUILDTOP)../$(COMPPATH)/zip/zip$(EXEEXT)
@CANADIAN_TRUE@@NULL_TARGET_FALSE@ZIP = \
@CANADIAN_TRUE@@NULL_TARGET_FALSE@zip
@CANADIAN_FALSE@ZIP = \
@CANADIAN_FALSE@$(MULTIBUILDTOP)../$(COMPPATH)/zip/zip$(EXEEXT)
@CANADIAN_TRUE@GCJH = \
@CANADIAN_TRUE@gcjh
@CANADIAN_FALSE@GCJH = \
@CANADIAN_FALSE@$(MULTIBUILDTOP)../$(COMPPATH)/gcc/gcjh$(EXEEXT)
@CANADIAN_FALSE@expanded = \
@CANADIAN_FALSE@`cd $(MULTIBUILDTOP)../$(COMPPATH)/gcc && pwd`
@CANADIAN_TRUE@@NULL_TARGET_TRUE@GCJ = @CANADIAN_TRUE@@NULL_TARGET_TRUE@gcj
@CANADIAN_TRUE@@NULL_TARGET_FALSE@GCJ = @CANADIAN_TRUE@@NULL_TARGET_FALSE@$(target_alias)-gcj
@CANADIAN_FALSE@GCJ = @CANADIAN_FALSE@$(expanded)/gcj$(EXEEXT) -B$(expanded)/
@CANADIAN_TRUE@@NULL_TARGET_TRUE@ZIP = @CANADIAN_TRUE@@NULL_TARGET_TRUE@$(MULTIBUILDTOP)../$(COMPPATH)/zip/zip$(EXEEXT)
@CANADIAN_TRUE@@NULL_TARGET_FALSE@ZIP = @CANADIAN_TRUE@@NULL_TARGET_FALSE@zip
@CANADIAN_FALSE@ZIP = @CANADIAN_FALSE@$(MULTIBUILDTOP)../$(COMPPATH)/zip/zip$(EXEEXT)
@CANADIAN_TRUE@GCJH = @CANADIAN_TRUE@gcjh
@CANADIAN_FALSE@GCJH = @CANADIAN_FALSE@$(MULTIBUILDTOP)../$(COMPPATH)/gcc/gcjh$(EXEEXT)
@CANADIAN_FALSE@expanded = @CANADIAN_FALSE@`cd $(MULTIBUILDTOP)../$(COMPPATH)/gcc && pwd`
GCJCOMPILE = CLASSPATH=$(here) $(LIBTOOL) --mode=compile $(GCJ) -fassume-compiled -L$(here) $(JC1FLAGS) -c
GCJLINK = $(LIBTOOL) --mode=link $(GCJ) -L$(here) $(JC1FLAGS) $(LDFLAGS) -o $@
@ -170,10 +153,8 @@ WARNINGS = -W -Wall
AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fasynchronous-exceptions \
@LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ $(WARNINGS) -D_GNU_SOURCE
@USING_GCC_TRUE@AM_CFLAGS = \
@USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
@USING_GCC_FALSE@AM_CFLAGS = \
@USING_GCC_FALSE@@LIBGCJ_CFLAGS@
@USING_GCC_TRUE@AM_CFLAGS = @USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
@USING_GCC_FALSE@AM_CFLAGS = @USING_GCC_FALSE@@LIBGCJ_CFLAGS@
JCFLAGS = -g
JC1FLAGS = -g @LIBGCJ_JAVAFLAGS@
@ -225,8 +206,7 @@ extra_headers = java/lang/Object.h java/lang/Class.h
NM = nm
@NATIVE_TRUE@@MAINTAINER_MODE_TRUE@noinst_PROGRAMS = \
@NATIVE_TRUE@@MAINTAINER_MODE_TRUE@gen-from-JIS
@NATIVE_TRUE@@MAINTAINER_MODE_TRUE@noinst_PROGRAMS = @NATIVE_TRUE@@MAINTAINER_MODE_TRUE@gen-from-JIS
CONVERT_DIR = gnu/gcj/convert
@ -282,6 +262,8 @@ gnu/gcj/convert/UnicodeToBytes.java
special_java_source_files = java/lang/Class.java java/lang/Object.java
awt_java_source_files = \
gnu/gcj/awt/BitMaskExtent.java \
gnu/gcj/awt/Buffers.java \
java/awt/AWTError.java \
java/awt/AWTEvent.java \
java/awt/AWTEventMulticaster.java \
@ -291,7 +273,6 @@ java/awt/Adjustable.java \
java/awt/BorderLayout.java \
java/awt/CheckboxGroup.java \
java/awt/Color.java \
java/awt/ColorModel.java \
java/awt/Component.java \
java/awt/ComponentOrientation.java \
java/awt/Container.java \
@ -331,6 +312,9 @@ java/awt/TextComponent.java \
java/awt/Toolkit.java \
java/awt/Transparency.java \
java/awt/Window.java \
java/awt/color/ColorSpace.java \
java/awt/color/ICC_ColorSpace.java \
java/awt/color/ICC_Profile.java \
java/awt/event/AWTEventListener.java \
java/awt/event/ActionEvent.java \
java/awt/event/ActionListener.java \
@ -378,9 +362,23 @@ java/awt/geom/PathIterator.java \
java/awt/geom/Point2D.java \
java/awt/geom/Rectangle2D.java \
java/awt/geom/RectangularShape.java \
java/awt/image/ColorModel.java \
java/awt/image/ComponentColorModel.java \
java/awt/image/ComponentSampleModel.java \
java/awt/image/DataBuffer.java \
java/awt/image/DataBufferByte.java \
java/awt/image/DataBufferInt.java \
java/awt/image/DataBufferUShort.java \
java/awt/image/DirectColorModel.java \
java/awt/image/ImageConsumer.java \
java/awt/image/ImageObserver.java \
java/awt/image/ImageProducer.java \
java/awt/image/IndexColorModel.java \
java/awt/image/PackedColorModel.java \
java/awt/image/Raster.java \
java/awt/image/SampleModel.java \
java/awt/image/SinglePixelPackedSampleModel.java \
java/awt/image/WritableRaster.java \
java/awt/peer/ButtonPeer.java \
java/awt/peer/CanvasPeer.java \
java/awt/peer/CheckboxMenuItemPeer.java \
@ -991,7 +989,8 @@ DIST_SUBDIRS = @DIRLTDL@ testsuite gcj include @DIRLTDL@ gcj include
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/$(srcdir)/$(CONVERT_DIR)/make-trie.P .deps/boehm.P \
.deps/defineclass.P .deps/exception.P .deps/gij.P \
.deps/gnu/gcj/RawData.P .deps/gnu/gcj/convert/BytesToUnicode.P \
.deps/gnu/gcj/RawData.P .deps/gnu/gcj/awt/BitMaskExtent.P \
.deps/gnu/gcj/awt/Buffers.P .deps/gnu/gcj/convert/BytesToUnicode.P \
.deps/gnu/gcj/convert/Convert.P .deps/gnu/gcj/convert/Input_8859_1.P \
.deps/gnu/gcj/convert/Input_EUCJIS.P \
.deps/gnu/gcj/convert/Input_JavaSrc.P \
@ -1050,14 +1049,13 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/awt/AWTEventMulticaster.P .deps/java/awt/AWTException.P \
.deps/java/awt/ActiveEvent.P .deps/java/awt/Adjustable.P \
.deps/java/awt/BorderLayout.P .deps/java/awt/CheckboxGroup.P \
.deps/java/awt/Color.P .deps/java/awt/ColorModel.P \
.deps/java/awt/Component.P .deps/java/awt/ComponentOrientation.P \
.deps/java/awt/Container.P .deps/java/awt/Cursor.P \
.deps/java/awt/Dimension.P .deps/java/awt/Event.P \
.deps/java/awt/EventDispatchThread.P .deps/java/awt/EventQueue.P \
.deps/java/awt/Font.P .deps/java/awt/FontMetrics.P \
.deps/java/awt/Frame.P .deps/java/awt/Graphics.P \
.deps/java/awt/GraphicsConfiguration.P \
.deps/java/awt/Color.P .deps/java/awt/Component.P \
.deps/java/awt/ComponentOrientation.P .deps/java/awt/Container.P \
.deps/java/awt/Cursor.P .deps/java/awt/Dimension.P \
.deps/java/awt/Event.P .deps/java/awt/EventDispatchThread.P \
.deps/java/awt/EventQueue.P .deps/java/awt/Font.P \
.deps/java/awt/FontMetrics.P .deps/java/awt/Frame.P \
.deps/java/awt/Graphics.P .deps/java/awt/GraphicsConfiguration.P \
.deps/java/awt/IllegalComponentStateException.P .deps/java/awt/Image.P \
.deps/java/awt/Insets.P .deps/java/awt/ItemSelectable.P \
.deps/java/awt/Label.P .deps/java/awt/LayoutManager.P \
@ -1071,6 +1069,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/awt/Shape.P .deps/java/awt/TextArea.P \
.deps/java/awt/TextComponent.P .deps/java/awt/Toolkit.P \
.deps/java/awt/Transparency.P .deps/java/awt/Window.P \
.deps/java/awt/color/ColorSpace.P .deps/java/awt/color/ICC_ColorSpace.P \
.deps/java/awt/color/ICC_Profile.P \
.deps/java/awt/event/AWTEventListener.P \
.deps/java/awt/event/ActionEvent.P \
.deps/java/awt/event/ActionListener.P \
@ -1109,9 +1109,21 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/awt/geom/PathIterator.P .deps/java/awt/geom/Point2D.P \
.deps/java/awt/geom/Rectangle2D.P \
.deps/java/awt/geom/RectangularShape.P \
.deps/java/awt/image/ColorModel.P \
.deps/java/awt/image/ComponentColorModel.P \
.deps/java/awt/image/ComponentSampleModel.P \
.deps/java/awt/image/DataBuffer.P .deps/java/awt/image/DataBufferByte.P \
.deps/java/awt/image/DataBufferInt.P \
.deps/java/awt/image/DataBufferUShort.P \
.deps/java/awt/image/DirectColorModel.P \
.deps/java/awt/image/ImageConsumer.P \
.deps/java/awt/image/ImageObserver.P \
.deps/java/awt/image/ImageProducer.P .deps/java/awt/peer/ButtonPeer.P \
.deps/java/awt/image/ImageProducer.P \
.deps/java/awt/image/IndexColorModel.P \
.deps/java/awt/image/PackedColorModel.P .deps/java/awt/image/Raster.P \
.deps/java/awt/image/SampleModel.P \
.deps/java/awt/image/SinglePixelPackedSampleModel.P \
.deps/java/awt/image/WritableRaster.P .deps/java/awt/peer/ButtonPeer.P \
.deps/java/awt/peer/CanvasPeer.P \
.deps/java/awt/peer/CheckboxMenuItemPeer.P \
.deps/java/awt/peer/CheckboxPeer.P .deps/java/awt/peer/ChoicePeer.P \
@ -1751,7 +1763,7 @@ distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$/$$file $(distdir)/$$file; \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \

View File

@ -0,0 +1,51 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.awt;
/**
* Simple transparent utility class that can be used to perform bit
* mask extent calculations.
*/
public final class BitMaskExtent
{
/** The number of the least significant bit of the bit mask extent. */
public byte leastSignificantBit;
/** The number of bits in the bit mask extent. */
public byte bitWidth;
/**
* Set the bit mask. This will calculate and set the leastSignificantBit
* and bitWidth fields.
*
* @see #leastSignificantBit
* @see #bitWidth
*/
public void setMask(long mask)
{
leastSignificantBit = 0;
bitWidth = 0;
if (mask == 0) return;
long shiftMask = mask;
for (; (shiftMask&1) == 0; shiftMask >>>=1) leastSignificantBit++;
for (; (shiftMask&1) != 0; shiftMask >>>=1) bitWidth++;
if (shiftMask != 0)
throw new IllegalArgumentException("mask must be continuous");
}
/**
* Calculate the bit mask based on the values of the
* leastSignificantBit and bitWidth fields.
*/
public long toMask()
{
return ((1<<bitWidth)-1) << leastSignificantBit;
}
}

View File

@ -0,0 +1,168 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.awt;
import java.awt.image.*;
/**
* Utility class for creating and accessing data buffers of arbitrary
* data types.
*/
public final class Buffers
{
/**
* Create a data buffer of a particular type.
*
* @param dataType the desired data type of the buffer.
* @param data an array containing data, or null
* @param size the size of the data buffer bank
*/
public static DataBuffer createBuffer(int dataType, Object data,
int size)
{
if (data == null) return createBuffer(dataType, size, 1);
return createBufferFromData(dataType, data, size);
}
/**
* Create a data buffer of a particular type.
*
* @param dataType the desired data type of the buffer.
* @param size the size of the data buffer bank
*/
public static DataBuffer createBuffer(int dataType, int size) {
return createBuffer(dataType, size, 1);
}
/**
* Create a data buffer of a particular type.
*
* @param dataType the desired data type of the buffer.
* @param size the size of the data buffer bank
* @param numBanks the number of banks the buffer should have
*/
public static DataBuffer createBuffer(int dataType, int size, int numBanks)
{
switch (dataType)
{
case DataBuffer.TYPE_BYTE:
return new DataBufferByte(size, numBanks);
case DataBuffer.TYPE_USHORT:
return new DataBufferUShort(size, numBanks);
case DataBuffer.TYPE_INT:
return new DataBufferInt(size, numBanks);
default:
throw new UnsupportedOperationException();
}
}
/**
* Create a data buffer of a particular type.
*
* @param dataType the desired data type of the buffer
* @param data an array containing the data
* @param size the size of the data buffer bank
*/
public static DataBuffer createBufferFromData(int dataType, Object data,
int size)
{
switch (dataType)
{
case DataBuffer.TYPE_BYTE:
return new DataBufferByte((byte[]) data, size);
case DataBuffer.TYPE_USHORT:
return new DataBufferUShort((short[]) data, size);
case DataBuffer.TYPE_INT:
return new DataBufferInt((int[]) data, size);
default:
throw new UnsupportedOperationException();
}
}
/**
* Return the data array of a data buffer, regardless of the data
* type.
*
* @return an array of primitive values. The actual array type
* depends on the data type of the buffer.
*/
public static Object getData(DataBuffer buffer)
{
if (buffer instanceof DataBufferByte)
return ((DataBufferByte) buffer).getData();
if (buffer instanceof DataBufferUShort)
return ((DataBufferUShort) buffer).getData();
if (buffer instanceof DataBufferInt)
return ((DataBufferInt) buffer).getData();
throw new ClassCastException("Unknown data buffer type");
}
/**
* Copy data from array contained in data buffer, much like
* System.arraycopy. Create a suitable destination array if the
* given destination array is null.
*/
public static Object getData(DataBuffer src, int srcOffset,
Object dest, int destOffset,
int length)
{
Object from;
if (src instanceof DataBufferByte)
{
from = ((DataBufferByte) src).getData();
if (dest == null) dest = new byte[length+destOffset];
}
else if (src instanceof DataBufferUShort)
{
from = ((DataBufferUShort) src).getData();
if (dest == null) dest = new short[length+destOffset];
}
else if (src instanceof DataBufferInt)
{
from = ((DataBufferInt) src).getData();
if (dest == null) dest = new int[length+destOffset];
}
else
{
throw new ClassCastException("Unknown data buffer type");
}
System.arraycopy(from, srcOffset, dest, destOffset, length);
return dest;
}
/**
* @param bits the width of a data element measured in bits
*
* @return the smallest data type that can store data elements of
* the given number of bits, without any truncation.
*/
public static int smallestAppropriateTransferType(int bits)
{
if (bits <= 8)
{
return DataBuffer.TYPE_BYTE;
}
else if (bits <= 16)
{
return DataBuffer.TYPE_USHORT;
}
else if (bits <= 32)
{
return DataBuffer.TYPE_INT;
}
else
{
return DataBuffer.TYPE_UNDEFINED;
}
}
}

View File

@ -1,20 +0,0 @@
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt;
/* Status: Just a placeholder. */
public class ColorModel implements Transparency
{
public int getTransparency()
{
// FIXME
return 0;
}
}

View File

@ -0,0 +1,111 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.color;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public abstract class ColorSpace
{
public static final int TYPE_XYZ = 0;
public static final int TYPE_Lab = 1;
public static final int TYPE_Luv = 2;
public static final int TYPE_YCbCr = 3;
public static final int TYPE_Yxy = 4;
public static final int TYPE_RGB = 5;
public static final int TYPE_GRAY = 6;
public static final int TYPE_HSV = 7;
public static final int TYPE_HLS = 8;
public static final int TYPE_CMYK = 9;
// mysterious gap in the enumeration sequenece
public static final int TYPE_CMY = 11;
public static final int TYPE_2CLR = 12;
public static final int TYPE_3CLR = 13;
public static final int TYPE_4CLR = 14;
public static final int TYPE_5CLR = 15;
public static final int TYPE_6CLR = 16;
public static final int TYPE_7CLR = 17;
public static final int TYPE_8CLR = 18;
public static final int TYPE_9CLR = 19;
public static final int TYPE_ACLR = 20;
public static final int TYPE_BCLR = 21;
public static final int TYPE_CCLR = 22;
public static final int TYPE_DCLR = 23;
public static final int TYPE_ECLR = 24;
public static final int TYPE_FCLR = 25;
public static final int CS_sRGB = 1000;
public static final int CS_CIEXYZ = 1001;
public static final int CS_PYCC = 1002;
public static final int CS_GRAY = 1003;
public static final int CS_LINEAR_RGB = 1004;
private static final int CS_BASE = CS_sRGB;
private static final int CS_END = CS_LINEAR_RGB+1;
private static final int CS_COUNT = CS_END - CS_BASE;
// Instances are lazily instantiated
private static final ColorSpace[] INSTANCES = new ColorSpace[CS_COUNT];
private int type;
private int numcomponents;
protected ColorSpace(int type, int numcomponents)
{
this.type = type;
this.numcomponents = numcomponents;
}
public static ColorSpace getInstance(int colorspace)
{
if ((colorspace >= CS_BASE) && (colorspace < CS_END))
{
int instanceIndex = colorspace - CS_BASE;
if (INSTANCES[instanceIndex] == null)
{
ICC_Profile profile = new ICC_Profile(colorspace);
INSTANCES[instanceIndex] = new ICC_ColorSpace(profile);
}
return INSTANCES[instanceIndex];
}
throw new IllegalArgumentException("unknown/unsupported colorspace");
}
public boolean isCS_sRGB()
{
return false;
}
public abstract float[] toRGB(float[] colorvalue);
public abstract float[] fromRGB(float[] rgbvalue);
public abstract float[] toCIEXYZ(float[] colorvalue);
public abstract float[] fromCIEXYZ(float[] colorvalue);
public int getType()
{
return type;
}
public int getNumComponents()
{
return numcomponents;
}
public String getName(int idx)
{
return "type " + type;
}
public String toString()
{
return getClass().getName() + "[type=" + type + "]";
}
}

View File

@ -0,0 +1,53 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.color;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class ICC_ColorSpace extends ColorSpace
{
private ICC_Profile profile;
public ICC_ColorSpace(ICC_Profile profile)
{
super(CS_sRGB, profile.getNumComponents());
this.profile = profile;
}
public ICC_Profile getProfile()
{
return profile;
}
public float[] toRGB(float[] colorvalue)
{
// FIXME: Always assumes sRGB:
return colorvalue;
}
public float[] fromRGB(float[] rgbvalue)
{
// FIXME: Always assumes sRGB:
return rgbvalue;
}
public float[] toCIEXYZ(float[] colorvalue)
{
// FIXME: Not implemented
throw new UnsupportedOperationException();
}
public float[] fromCIEXYZ(float[] colorvalue)
{
// FIXME: Not implemented
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,40 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.color;
// Currently just a stub.
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class ICC_Profile
{
long profileID; // why long?
ICC_Profile(long profileID)
{
this.profileID = profileID;
}
public int getNumComponents()
{
switch (profileID)
{
case ColorSpace.CS_sRGB:
case ColorSpace.CS_LINEAR_RGB:
case ColorSpace.CS_CIEXYZ:
return 3;
case ColorSpace.CS_GRAY:
return 1;
case ColorSpace.CS_PYCC: // have no clue about this one
default:
throw new UnsupportedOperationException("profile not implemented");
}
}
}

View File

@ -0,0 +1,575 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import gnu.gcj.awt.Buffers;
/**
* A color model operates with colors in several formats:
*
* <ul>
* <li>normalized: component samples are in range [0.0, 1.0].</li>
*
* <li>color model pixel value: all the color component samples for a
* sigle pixel packed/encoded in a way natural for the color
* model.</li>
*
* <li>color model pixel int value: only makes sense if the natural
* encoding of a single pixel can fit in a single int value.</li>
*
* <li>array of transferType containing a single pixel: the pixel is
* encoded in the natural way of the color model, taking up as many
* array elements as needed.</li>
*
* <li>sRGB pixel int value: a pixel in sRGB color space, encoded in
* default 0xAARRGGBB format, assumed not alpha premultiplied.</li>
*
* <li>single [0, 255] scaled int samples from default sRGB color
* space. These are always assumed to be alpha non-premultiplied.</li>
*
* <li>arrays of unnormalized component samples of single pixel: these
* samples are scaled and multiplied according to the color model, but
* is otherwise not packed or encoded. Each element of the array is one
* seperate component sample. The color model only operate on the
* components from one pixel at a time, but using offsets, allows
* manipulation of arrays that contain the components of more than one
* pixel.</li>
*
* </ul>
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public abstract class ColorModel implements Transparency
{
protected int pixel_bits;
protected int transferType;
private int[] bits;
private ColorSpace cspace;
private int transparency;
private boolean hasAlpha;
private boolean isAlphaPremultiplied;
static int[] nArray(int value, int times)
{
int[] array = new int[times];
java.util.Arrays.fill(array, value);
return array;
}
static byte[] nArray(byte value, int times)
{
byte[] array = new byte[times];
java.util.Arrays.fill(array, value);
return array;
}
public ColorModel(int bits)
{
this(bits * 4, // total bits, sRGB, four channels
nArray(bits, 4), // bits for each channel
null, // FIXME: should be sRGB
true, // has alpha
false, // not premultiplied
TRANSLUCENT,
Buffers.smallestAppropriateTransferType(bits * 4));
}
protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
boolean hasAlpha, boolean isAlphaPremultiplied,
int transparency, int transferType)
{
this.pixel_bits = pixel_bits;
this.bits = bits;
this.cspace = cspace;
this.hasAlpha = hasAlpha;
this.isAlphaPremultiplied = isAlphaPremultiplied;
this.transparency = transparency;
this.transferType = transferType;
}
public static ColorModel getRGBdefault()
{
return new DirectColorModel(8, 0xff0000, 0xff00, 0xff, 0xff000000);
}
public final boolean hasAlpha()
{
return hasAlpha;
}
public final boolean isAlphaPremultiplied()
{
return isAlphaPremultiplied;
}
public int getPixelSize()
{
return pixel_bits;
}
public int getComponentSize(int componentIdx)
{
return bits[componentIdx];
}
public int[] getComponentSize()
{
return bits;
}
public int getTransparency()
{
return transparency;
}
public int getNumComponents()
{
return getNumColorComponents() + (hasAlpha ? 1 : 0);
}
public int getNumColorComponents()
{
return cspace.getNumComponents();
}
/**
* Converts pixel value to sRGB and extract red int sample scaled
* to range [0, 255].
*
* @param pixel pixel value that will be interpreted according to
* the color model, (assumed alpha premultiplied if color model says
* so.)
*
* @return red sample scaled to range [0, 255], from default color
* space sRGB, alpha non-premultiplied.
*/
public abstract int getRed(int pixel);
/**
* Converts pixel value to sRGB and extract green int sample
* scaled to range [0, 255].
*
* @see #getRed(int)
*/
public abstract int getGreen(int pixel);
/**
* Converts pixel value to sRGB and extract blue int sample
* scaled to range [0, 255].
*
* @see #getRed(int)
*/
public abstract int getBlue(int pixel);
/**
* Extract alpha int sample from pixel value, scaled to [0, 255].
*
* @param pixel pixel value that will be interpreted according to
* the color model.
*
* @return alpha sample, scaled to range [0, 255].
*/
public abstract int getAlpha(int pixel);
/**
* Converts a pixel int value of the color space of the color
* model to a sRGB pixel int value.
*
* This method is typically overriden in subclasses to provide a
* more efficient implementation.
*
* @param pixel pixel value that will be interpreted according to
* the color model.
*
* @return a pixel in sRGB color space, encoded in default
* 0xAARRGGBB format. */
public int getRGB(int pixel)
{
return
((getAlpha(pixel) & 0xff) << 24) |
(( getRed(pixel) & 0xff) << 16) |
((getGreen(pixel) & 0xff) << 8) |
(( getBlue(pixel) & 0xff) << 0);
}
/**
* In this color model we know that the whole pixel value will
* always be contained within the first element of the pixel
* array.
*/
final int getPixelFromArray(Object inData) {
DataBuffer data =
Buffers.createBufferFromData(transferType, inData, 1);
Object da = Buffers.getData(data);
return data.getElem(0);
}
/**
* Converts pixel in the given array to sRGB and extract blue int
* sample scaled to range [0-255].
*
* This method is typically overriden in subclasses to provide a
* more efficient implementation.
*
* @param array of transferType containing a single pixel. The
* pixel should be encoded in the natural way of the color model.
*/
public int getRed(Object inData)
{
return getRed(getPixelFromArray(inData));
}
/**
* @see #getRed(Object)
*/
public int getGreen(Object inData)
{
return getGreen(getPixelFromArray(inData));
}
/**
* @see #getRed(Object)
*/
public int getBlue(Object inData) {
return getBlue(getPixelFromArray(inData));
}
/**
* @see #getRed(Object)
*/
public int getAlpha(Object inData) {
return getBlue(getPixelFromArray(inData));
}
/**
* Converts a pixel in the given array of the color space of the
* color model to an sRGB pixel int value.
*
* <p>This method performs the inverse function of
* <code>getDataElements(int rgb, Object pixel)</code>.
* I.e. <code>(rgb == cm.getRGB(cm.getDataElements(rgb,
* null)))</code>.
*
* @param inData array of transferType containing a single pixel. The
* pixel should be encoded in the natural way of the color model.
*
* @return a pixel in sRGB color space, encoded in default
* 0xAARRGGBB format.
*
* @see #getDataElements(int, Object)
*/
public int getRGB(Object inData)
{
return
((getAlpha(inData) & 0xff) << 24) |
(( getRed(inData) & 0xff) << 16) |
((getGreen(inData) & 0xff) << 8) |
(( getBlue(inData) & 0xff) << 0);
}
/**
* Converts an sRGB pixel int value to an array containing a
* single pixel of the color space of the color model.
*
* <p>This method performs the inverse function of
* <code>getRGB(Object inData)</code>.
*
* Outline of conversion process:
*
* <ol>
*
* <li>Convert rgb to normalized [0.0, 1.0] sRGB values.</li>
*
* <li>Convert to color space components using fromRGB in
* ColorSpace.</li>
*
* <li>If color model has alpha and should be premultiplied,
* multiply color space components with alpha value</li>
*
* <li>Scale the components to the correct number of bits.</li>
*
* <li>Arrange the components in the output array</li>
*
* </ol>
*
* @param rgb The color to be converted to dataElements. A pixel
* in sRGB color space, encoded in default 0xAARRGGBB format,
* assumed not alpha premultiplied.
*
* @param pixel to avoid needless creation of arrays, an array to
* use to return the pixel can be given. If null, a suitable array
* will be created.
*
* @return An array of transferType values representing the color,
* in the color model format. The color model defines whether the
*
* @see #getRGB(Object)
*/
public Object getDataElements(int rgb, Object pixel)
{
// FIXME: implement
throw new UnsupportedOperationException();
}
/**
* Fills an array with the unnormalized component samples from a
* pixel value. I.e. decompose the pixel, but not perform any
* color conversion.
*
* This method is typically overriden in subclasses to provide a
* more efficient implementation.
*
* @param pixel pixel value encoded according to the color model.
*
* @return arrays of unnormalized component samples of single
* pixel. The scale and multiplication state of the samples are
* according to the color model. Each component sample is stored
* as a seperate element in the array.
*/
public int[] getComponents(int pixel, int[] components, int offset) {
// FIXME: implement
throw new UnsupportedOperationException();
}
/**
* Fills an array with the unnormalized component samples from an
* array of transferType containing a single pixel. I.e. decompose
* the pixel, but not perform any color conversion.
*
* This method is typically overriden in subclasses to provide a
* more efficient implementation.
*
* @param array of transferType containing a single pixel. The
* pixel should be encoded in the natural way of the color model.
*
* @return arrays of unnormalized component samples of single
* pixel. The scale and multiplication state of the samples are
* according to the color model. Each component sample is stored
* as a seperate element in the array.
*/
public int[] getComponents(Object pixel, int[] components, int offset)
{
throw new UnsupportedOperationException();
}
/**
* Convert normalized components to unnormalized components.
*/
public int[] getUnnormalizedComponents(float[] normComponents,
int normOffset,
int[] components,
int offset)
{
int numComponents = getNumComponents();
if (components == null)
{
components = new int[offset + numComponents];
}
for (int i=0; i<numComponents; i++)
{
float in = normComponents[normOffset++];
int out = (int) (in * ((2<<getComponentSize(i)) - 1));
components[offset++] = out;
}
return components;
}
/**
* Convert unnormalized components to normalized components.
*/
public float[] getNormalizedComponents(int[] components,
int offset,
float[] normComponents,
int normOffset)
{
int numComponents = getNumComponents();
if (normComponents == null)
{
normComponents = new float[normOffset + numComponents];
}
for (int i=0; i<numComponents; i++)
{
float in = components[offset++];
float out = in / ((2<<getComponentSize(i)) - 1);
normComponents[normOffset++] = out;
}
return normComponents;
}
/**
* Converts the unnormalized component samples from an array to a
* pixel value. I.e. composes the pixel from component samples, but
* does not perform any color conversion or scaling of the samples.
*
* This method performs the inverse function of
* <code>getComponents(int pixel, int[] components,
* int offset)</code>. I.e.
*
* <code>(pixel == cm.getDataElement(cm.getComponents(pixel, null,
* 0), 0))</code>.
*
* This method is typically overriden in subclasses to provide a
* more efficient implementation.
*
* @param arrays of unnormalized component samples of single
* pixel. The scale and multiplication state of the samples are
* according to the color model. Each component sample is stored
* as a seperate element in the array.
*
* @return pixel value encoded according to the color model.
*/
public int getDataElement(int[] components, int offset)
{
throw new UnsupportedOperationException();
}
public Object getDataElements(int[] components, int offset, Object obj)
{
throw new UnsupportedOperationException();
}
public boolean equals(Object obj)
{
if (!(obj instanceof ColorModel)) return false;
ColorModel o = (ColorModel) obj;
return
(pixel_bits == o.pixel_bits) &&
(transferType == o.transferType) &&
(transparency == o.transparency) &&
(hasAlpha == o.hasAlpha) &&
(isAlphaPremultiplied == isAlphaPremultiplied) &&
(bits.equals(o.bits)) &&
(cspace.equals(o.cspace));
}
public final ColorSpace getColorSpace()
{
return cspace;
}
// Typically overridden
public ColorModel coerceData(WritableRaster raster,
boolean isAlphaPremultiplied)
{
if (this.isAlphaPremultiplied == isAlphaPremultiplied)
return this;
int w = raster.getWidth();
int h = raster.getHeight();
int x = raster.getMinX();
int y = raster.getMinY();
int size = w*h;
int numColors = getNumColorComponents();
int numComponents = getNumComponents();
int alphaScale = (1<<getComponentSize(numColors)) - 1;
double[] pixels = raster.getPixels(x, y, w, h, (double[]) null);
for (int i=0; i<size; i++)
{
double alpha = pixels[i*numComponents+numColors]*alphaScale;
for (int c=0; c<numColors; c++)
{
int offset = i*numComponents+c;
if (isAlphaPremultiplied)
pixels[offset] = pixels[offset]/alpha;
else
pixels[offset] = pixels[offset]*alpha;
}
}
raster.setPixels(0, 0, w, h, pixels);
// FIXME: what can we return?
return null;
}
// Typically overridden
public boolean isCompatibleRaster(Raster raster)
{
SampleModel sampleModel = raster.getSampleModel();
return isCompatibleSampleModel(sampleModel);
}
// Typically overridden
public WritableRaster createCompatibleWritableRaster(int w, int h)
{
return new WritableRaster(createCompatibleSampleModel(w, h),
new Point(0, 0));
}
// Typically overridden
public SampleModel createCompatibleSampleModel(int w, int h)
{
throw new UnsupportedOperationException();
}
// Typically overridden
public boolean isCompatibleSampleModel(SampleModel sm)
{
return sm.getTransferType() == transferType;
}
public void finalize() {
}
/**
* Subclasses must override this method if it is possible for the
* color model to have an alpha channel.
*
* @return null, as per JDK 1.3 doc. Subclasses will only return
* null if no alpha raster exists.
*/
public WritableRaster getAlphaRaster(WritableRaster raster)
{
return null;
/* It is a mystery to me why we couldn't use the following code...
if (!hasAlpha()) return null;
SampleModel sm = raster.getSampleModel();
int[] alphaBand = { sm.getNumBands() - 1 };
SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
DataBuffer buffer = raster.getDataBuffer();
Point origin = new Point(0, 0);
return Raster.createWritableRaster(alphaModel, buffer, origin);
...here, and avoided overriding the method in subclasses,
but the Sun docs state that this method always will return
null, and that overriding is required. Oh, well.
*/
}
String stringParam()
{
return "pixel_bits=" + pixel_bits +
", cspace=" + cspace +
", transferType=" + transferType +
", transparency=" + transparency +
", hasAlpha=" + hasAlpha +
", isAlphaPremultiplied=" + isAlphaPremultiplied;
}
public String toString()
{
return getClass().getName() + "[" + stringParam() + "]";
}
}

View File

@ -0,0 +1,303 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import java.awt.color.*;
import java.awt.Point;
import gnu.gcj.awt.Buffers;
public class ComponentColorModel extends ColorModel
{
private static int sum(int[] values)
{
int sum = 0;
for (int i=0; i<values.length; i++)
sum += values[i];
return sum;
}
public ComponentColorModel(ColorSpace colorSpace, int[] bits,
boolean hasAlpha,
boolean isAlphaPremultiplied,
int transparency, int transferType)
{
super(sum(bits), bits, colorSpace, hasAlpha, isAlphaPremultiplied,
transparency, transferType);
}
public int getRed(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return (int) getRGBFloat(pixel)[0];
}
public int getGreen(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return (int) getRGBFloat(pixel)[0];
}
public int getBlue(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return (int) getRGBFloat(pixel)[0];
}
public int getAlpha(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
int shift = 8 - getComponentSize(getNumColorComponents());
if (shift >= 0) return pixel << shift;
return pixel >> (-shift);
}
public int getRGB(int pixel)
{
float[] rgb = getRGBFloat(pixel);
int ret = getRGB(rgb);
if (hasAlpha()) ret |= getAlpha(pixel) << 24;
return ret;
}
/* FIXME: Is the values returned from toRGB() in the [0.0, 1.0] or the
[0.0, 256) range?
we assume it is in the [0.0, 1.0] range along with the
other color spaces. */
/* Note, it's OK to pass a to large array to toRGB(). Extra
elements are ignored. */
private float[] getRGBFloat(int pixel)
{
float[] data = { pixel };
return cspace.toRGB(data);
}
private float[] getRGBFloat(Object inData)
{
DataBuffer buffer =
Buffers.createBufferFromData(transferType, inData,
getNumComponents());
int colors = getNumColorComponents();
float[] data = new float[colors];
// FIXME: unpremultiply data that is premultiplied
for (int i=0; i<colors; i++)
{
float maxValue = (1<<getComponentSize(i))-1;
data[i] = buffer.getElemFloat(i)/maxValue;
}
float[] rgb = cspace.toRGB(data);
return rgb;
}
public int getRed(Object inData)
{
return (int) getRGBFloat(inData)[0]*255;
}
public int getGreen(Object inData)
{
return (int) getRGBFloat(inData)[1]*255;
}
public int getBlue(Object inData)
{
return (int) getRGBFloat(inData)[2]*255;
}
public int getAlpha(Object inData)
{
DataBuffer buffer =
Buffers.createBufferFromData(transferType, inData,
getNumComponents());
int shift = 8 - getComponentSize(getNumColorComponents());
int alpha = buffer.getElem(getNumColorComponents());
if (shift >= 0) return alpha << shift;
return alpha >> (-shift);
}
private int getRGB(float[] rgb)
{
/* NOTE: We could cast to byte instead of int here. This would
avoid bits spilling over from one bit field to
another. But, if we assume that floats are in the [0.0,
1.0] range, this will never happen anyway. */
/* Remember to multiply BEFORE casting to int, otherwise, decimal
point data will be lost. */
int ret =
(((int) (rgb[0]*255F)) << 16) |
(((int) (rgb[1]*255F)) << 8) |
(((int) (rgb[2]*255F)) << 0);
return ret;
}
/**
* @param inData pixel data of transferType, as returned by the
* getDataElements method in SampleModel.
*/
public int getRGB(Object inData)
{
float[] rgb = getRGBFloat(inData);
int ret = getRGB(rgb);
if (hasAlpha()) ret |= getAlpha(inData) << 24;
return ret;
}
public Object getDataElements(int rgb, Object pixel)
{
// Convert rgb to [0.0, 1.0] sRGB values.
float[] rgbFloats = {
((rgb >> 16)&0xff)/255.0F,
((rgb >> 8)&0xff)/255.0F,
((rgb >> 0)&0xff)/255.0F
};
// Convert from rgb to color space components.
float[] data = cspace.fromRGB(rgbFloats);
DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
getNumComponents());
int numColors = getNumColorComponents();
if (hasAlpha())
{
float alpha = ((rgb >> 24)&0xff)/255.0F;
/* If color model has alpha and should be premultiplied, multiply
color space components with alpha value. */
if (isAlphaPremultiplied()) {
for (int i=0; i<numColors; i++)
data[i] *= alpha;
}
// Scale the alpha sample to the correct number of bits.
alpha *= (1<<(bits[numColors]-1));
// Arrange the alpha sample in the output array.
buffer.setElemFloat(numColors, alpha);
}
for (int i=0; i<numColors; i++)
{
// Scale the color samples to the correct number of bits.
float value = data[i]*(1<<(bits[i]-1));
// Arrange the color samples in the output array.
buffer.setElemFloat(i, value);
}
return Buffers.getData(buffer);
}
public int[] getComponents(int pixel, int[] components, int offset)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
if (components == null)
components = new int[getNumComponents() + offset];
components[offset] = pixel;
return components;
}
public int[] getComponents(Object pixel, int[] components, int offset)
{
DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
getNumComponents());
int numComponents = getNumComponents();
if (components == null)
components = new int[numComponents + offset];
for (int i=0; i<numComponents; i++)
components[offset++] = buffer.getElem(i);
return components;
}
public int getDataElement(int[] components, int offset)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return components[offset];
}
public Object getDataElements(int[] components, int offset, Object obj)
{
DataBuffer buffer = Buffers.createBuffer(transferType, obj,
getNumComponents());
int numComponents = getNumComponents();
for (int i=0; i<numComponents; i++)
buffer.setElem(i, components[offset++]);
return Buffers.getData(buffer);
}
public ColorModel coerceData(WritableRaster raster,
boolean isAlphaPremultiplied) {
if (this.isAlphaPremultiplied == isAlphaPremultiplied)
return this;
/* TODO: provide better implementation based on the
assumptions we can make due to the specific type of the
color model. */
super.coerceData(raster, isAlphaPremultiplied);
return new ComponentColorModel(cspace, bits, hasAlpha(),
isAlphaPremultiplied, // argument
transparency, transferType);
}
public boolean isCompatibleRaster(Raster raster)
{
return super.isCompatibleRaster(raster);
// FIXME: Should we test something more here? (Why override?)
}
public WritableRaster createCompatibleWritableRaster(int w, int h)
{
SampleModel sm = createCompatibleSampleModel(w, h);
Point origin = new Point(0, 0);
return Raster.createWritableRaster(sm, origin);
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
int pixelStride = getNumComponents();
/* TODO: Maybe we don't need to create a new offset array each
time, but rather use the same array every time. */
int[] bandOffsets = new int[pixelStride];
for (int i=0; i<pixelStride; i++) bandOffsets[i] = i;
return new ComponentSampleModel(transferType, w, h,
pixelStride, pixelStride*w,
bandOffsets);
}
public boolean isCompatibleSampleModel(SampleModel sm)
{
return
(sm instanceof ComponentSampleModel) &&
super.isCompatibleSampleModel(sm);
}
public WritableRaster getAlphaRaster(WritableRaster raster)
{
if (!hasAlpha()) return null;
SampleModel sm = raster.getSampleModel();
int[] alphaBand = { sm.getNumBands() - 1 };
SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
DataBuffer buffer = raster.getDataBuffer();
Point origin = new Point(0, 0);
return Raster.createWritableRaster(alphaModel, buffer, origin);
}
public boolean equals(Object obj)
{
if (!(obj instanceof ComponentColorModel)) return false;
return super.equals(obj);
}
}

View File

@ -0,0 +1,435 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import gnu.gcj.awt.Buffers;
/* FIXME: This class does not yet support data type TYPE_SHORT */
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class ComponentSampleModel extends SampleModel
{
protected int[] bandOffsets;
protected int[] bankIndices;
// FIXME: Should we really shadow the numBands in the superclass?
//protected int numBands;
/** Used when creating data buffers. */
protected int numBanks;
protected int scanlineStride;
protected int pixelStride;
private boolean tightPixelPacking = false;
public ComponentSampleModel(int dataType,
int w, int h,
int pixelStride,
int scanlineStride,
int[] bandOffsets)
{
this(dataType, w, h, pixelStride, scanlineStride,
new int[bandOffsets.length], bandOffsets);
}
public ComponentSampleModel(int dataType,
int w, int h,
int pixelStride,
int scanlineStride,
int[] bankIndices,
int[] bandOffsets)
{
super(dataType, w, h, bandOffsets.length);
if ((pixelStride<0) || (scanlineStride<0) ||
(bandOffsets.length<1) ||
(bandOffsets.length != bankIndices.length))
throw new IllegalArgumentException();
this.bandOffsets = bandOffsets;
this.bankIndices = bankIndices;
for (int b=0; b<bankIndices.length; b++)
this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
this.scanlineStride = scanlineStride;
this.pixelStride = pixelStride;
// See if we can use some speedups
/* FIXME: May these checks should be reserved for the
PixelInterleavedSampleModel? */
if (pixelStride == numBands)
{
tightPixelPacking = true;
for (int b=0; b<numBands; b++) {
if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
{
tightPixelPacking = false;
break;
}
}
}
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
return new ComponentSampleModel(dataType, w, h, pixelStride,
scanlineStride, bankIndices,
bandOffsets);
}
public SampleModel createSubsetSampleModel(int[] bands)
{
int numBands = bands.length;
int[] bankIndices = new int[numBands];
int[] bandOffsets = new int[numBands];
for (int b=0; b<numBands; b++)
{
bankIndices[b] = this.bankIndices[bands[b]];
bandOffsets[b] = this.bandOffsets[bands[b]];
}
return new ComponentSampleModel(dataType, width, height, pixelStride,
scanlineStride, bankIndices,
bandOffsets);
}
public DataBuffer createDataBuffer()
{
// Maybe this value should be precalculated in the constructor?
int highestOffset = 0;
for (int b=0; b<numBands; b++)
{
highestOffset = Math.max(highestOffset, bandOffsets[b]);
}
int size = pixelStride*(width-1) + scanlineStride*(height-1) +
highestOffset + 1;
return Buffers.createBuffer(getDataType(), size, numBanks);
}
public int getOffset(int x, int y)
{
return getOffset(x, y, 0);
}
public int getOffset(int x, int y, int b)
{
return bandOffsets[b] + pixelStride*x + scanlineStride*y;
}
public final int[] getSampleSize()
{
int size = DataBuffer.getDataTypeSize(getDataType());
int[] sizes = new int[numBands];
java.util.Arrays.fill(sizes, size);
return sizes;
}
public final int getSampleSize(int band)
{
return DataBuffer.getDataTypeSize(getDataType());
}
public final int[] getBankIndices()
{
return bankIndices;
}
public final int[] getBandOffsets()
{
return bandOffsets;
}
public final int getScanlineStride()
{
return scanlineStride;
}
public final int getPixelStride()
{
return pixelStride;
}
public final int getNumDataElements()
{
return numBands;
}
public Object getDataElements(int x, int y, Object obj, DataBuffer data)
{
int xyOffset = pixelStride*x + scanlineStride*y;
int[] totalBandDataOffsets = new int[numBands];
/* Notice that band and bank offsets are different. Band offsets
are managed by the sample model, and bank offsets are managed
by the data buffer. Both must be accounted for. */
/* FIXME: For single pixels, it is probably easier to simple
call getElem instead of calculating the bank offset ourself.
On the other hand, then we need to push the value through
the int type returned by the getElem method. */
int[] bankOffsets = data.getOffsets();
for (int b=0; b<numBands; b++)
{
totalBandDataOffsets[b] =
bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
}
try
{
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
DataBufferByte inByte = (DataBufferByte) data;
byte[] outByte = (byte[]) obj;
if (outByte == null) outByte = new byte[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outByte[b] = inByte.getData(bankIndices[b])[dOffset];
}
return outByte;
case DataBuffer.TYPE_USHORT:
DataBufferUShort inUShort = (DataBufferUShort) data;
short[] outUShort = (short[]) obj;
if (outUShort == null) outUShort = new short[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
}
return outUShort;
case DataBuffer.TYPE_INT:
DataBufferInt inInt = (DataBufferInt) data;
int[] outInt = (int[]) obj;
if (outInt == null) outInt = new int[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outInt[b] = inInt.getData(bankIndices[b])[dOffset];
}
return outInt;
// FIXME: Fill in the other possible types.
default:
throw new IllegalStateException("unknown transfer type " +
getTransferType());
}
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
String msg = "While reading data elements, " +
"x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
", data.getSize()=" + data.getSize() + ": " + aioobe;
throw new ArrayIndexOutOfBoundsException(msg);
}
}
public Object getDataElements(int x, int y, int w, int h, Object obj,
DataBuffer data)
{
if (!tightPixelPacking)
{
return super.getDataElements(x, y, w, h, obj, data);
}
// using get speedup
// We can copy whole rows
int rowSize = w*numBands;
int dataSize = rowSize*h;
DataBuffer transferBuffer =
Buffers.createBuffer(getTransferType(), obj, dataSize);
obj = Buffers.getData(transferBuffer);
int inOffset =
pixelStride*x +
scanlineStride*y +
data.getOffset(); // Assumes only one band is used
/* We don't add band offsets since we assume that bands have
offsets 0, 1, 2, ... */
// See if we can copy everything in one go
if (scanlineStride == rowSize)
{
// Collapse scan lines:
rowSize *= h;
// We ignore scanlineStride since it won't be of any use
h = 1;
}
int outOffset = 0;
Object inArray = Buffers.getData(data);
for (int yd = 0; yd<h; yd++)
{
System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
inOffset += scanlineStride;
outOffset += rowSize;
}
return obj;
}
public void setDataElements(int x, int y, int w, int h,
Object obj, DataBuffer data)
{
if (!tightPixelPacking)
{
super.setDataElements(x, y, w, h, obj, data);
return;
}
// using set speedup, we can copy whole rows
int rowSize = w*numBands;
int dataSize = rowSize*h;
DataBuffer transferBuffer =
Buffers.createBufferFromData(getTransferType(), obj, dataSize);
int[] bankOffsets = data.getOffsets();
int outOffset =
pixelStride*x +
scanlineStride*y +
bankOffsets[0]; // same assuptions as in get...
// See if we can copy everything in one go
if (scanlineStride == rowSize)
{
// Collapse scan lines:
scanlineStride = rowSize *= h;
h = 1;
}
int inOffset = 0;
Object outArray = Buffers.getData(data);
for (int yd = 0; yd<h; yd++)
{
System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
outOffset += scanlineStride;
inOffset += rowSize;
}
}
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
if (iArray == null) iArray = new int[numBands];
for (int b=0; b<numBands; b++)
{
iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
}
return iArray;
}
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
if (iArray == null) iArray = new int[numBands*w*h];
int outOffset = 0;
for (y=0; y<h; y++)
{
int lineOffset = offset;
for (x=0; x<w; x++)
{
for (int b=0; b<numBands; b++)
{
iArray[outOffset++] =
data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
}
lineOffset += pixelStride;
}
offset += scanlineStride;
}
return iArray;
}
public int getSample(int x, int y, int b, DataBuffer data)
{
return data.getElem(bankIndices[b], getOffset(x, y, b));
}
public void setDataElements(int x, int y, Object obj, DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
int[] totalBandDataOffsets = new int[numBands];
int[] bankOffsets = data.getOffsets();
for (int b=0; b<numBands; b++)
totalBandDataOffsets[b] =
bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
{
DataBufferByte out = (DataBufferByte) data;
byte[] in = (byte[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
case DataBuffer.TYPE_USHORT:
{
DataBufferUShort out = (DataBufferUShort) data;
short[] in = (short[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
case DataBuffer.TYPE_INT:
{
DataBufferInt out = (DataBufferInt) data;
int[] in = (int[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
default:
throw new UnsupportedOperationException("transfer type not " +
"implemented");
}
}
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
for (int b=0; b<numBands; b++)
data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
}
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
data.setElem(bankIndices[b], getOffset(x, y, b), s);
}
}

View File

@ -0,0 +1,177 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
/**
* Class that manages arrays of data elements. A data buffer consists
* of one or more banks. A bank is a continuous region of data
* elements.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public abstract class DataBuffer
{
public static final int TYPE_BYTE = 0;
public static final int TYPE_USHORT = 1;
public static final int TYPE_SHORT = 2;
public static final int TYPE_INT = 3;
public static final int TYPE_FLOAT = 4;
public static final int TYPE_DOUBLE = 5;
public static final int TYPE_UNDEFINED = 32;
/** The type of the data elements stored in the data buffer. */
protected int dataType;
/** The number of banks in this buffer. */
protected int banks = 1;
/** Offset into the default (0'th) bank). */
protected int offset; // FIXME: Is offsets[0] always mirrored in offset?
/** The size of the banks. */
protected int size;
/** Offset into each bank. */
protected int[] offsets;
protected DataBuffer(int dataType, int size)
{
this.dataType = dataType;
this.size = size;
}
protected DataBuffer(int dataType, int size, int numBanks) {
this(dataType, size);
banks = numBanks;
offsets = new int[numBanks];
}
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
this(dataType, size, numBanks);
java.util.Arrays.fill(offsets, offset);
this.offset = offset;
}
protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
this(dataType, size);
if (numBanks != offsets.length)
throw new ArrayIndexOutOfBoundsException();
banks = numBanks;
this.offsets = offsets;
offset = offsets[0];
}
public static int getDataTypeSize(int dataType) {
// Maybe this should be a lookup table instead.
switch (dataType)
{
case TYPE_BYTE:
return 8;
case TYPE_USHORT:
case TYPE_SHORT:
return 16;
case TYPE_INT:
case TYPE_FLOAT:
return 32;
case TYPE_DOUBLE:
return 64;
default:
throw new IllegalArgumentException();
}
}
public int getDataType()
{
return dataType;
}
public int getSize()
{
return size;
}
public int getOffset()
{
return offset;
}
public int[] getOffsets()
{
if (offsets == null)
{
// is this necessary?
offsets = new int[1];
offsets[0] = offset;
}
return offsets;
}
public int getNumBanks()
{
return banks;
}
public int getElem(int i)
{
return getElem(0, i);
}
public abstract int getElem(int bank, int i);
public void setElem(int i, int val)
{
setElem(0, i, val);
}
public abstract void setElem(int bank, int i, int val);
public float getElemFloat(int i)
{
return getElem(i);
}
public float getElemFloat(int bank, int i)
{
return getElem(bank, i);
}
public void setElemFloat(int i, float val)
{
setElem(i, (int) val);
}
public void setElemFloat(int bank, int i, float val)
{
setElem(bank, i, (int) val);
}
public double getElemDouble(int i)
{
return getElem(i);
}
public double getElemDouble(int bank, int i)
{
return getElem(bank, i);
}
public void setElemDouble(int i, double val)
{
setElem(i, (int) val);
}
public void setElemDouble(int bank, int i, double val)
{
setElem(bank, i, (int) val);
}
}

View File

@ -0,0 +1,103 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
/* This is one of several classes that are nearly identical. Maybe we
should have a central template and generate all these files. This
is one of the cases where templates or macros would have been
useful to have in Java.
This file has been created using search-replace. My only fear is
that these classes will grow out-of-sync as of a result of changes
that are not propagated to the other files. As always, mirroring
code is a maintenance nightmare. */
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class DataBufferByte extends DataBuffer
{
private byte[] data;
private byte[][] bankData;
public DataBufferByte(int size)
{
super(TYPE_BYTE, size);
data = new byte[size];
}
public DataBufferByte(int size, int numBanks)
{
super(TYPE_BYTE, size, numBanks);
bankData = new byte[numBanks][size];
data = bankData[0];
}
public DataBufferByte(byte[] dataArray, int size)
{
super(TYPE_BYTE, size);
data = dataArray;
}
public DataBufferByte(byte[] dataArray, int size, int offset)
{
super(TYPE_BYTE, size, 1, offset);
data = dataArray;
}
public DataBufferByte(byte[][] dataArray, int size)
{
super(TYPE_BYTE, size, dataArray.length);
bankData = dataArray;
data = bankData[0];
}
public DataBufferByte(byte[][] dataArray, int size, int[] offsets)
{
super(TYPE_BYTE, size, dataArray.length, offsets);
bankData = dataArray;
data = bankData[0];
}
public byte[] getData()
{
return data;
}
public byte[] getData(int bank)
{
return bankData[bank];
}
public byte[][] getBankData()
{
return bankData;
}
public int getElem(int i)
{
return data[i+offset] & 0xff; // get unsigned byte as int
}
public int getElem(int bank, int i)
{
// get unsigned byte as int
return bankData[bank][i+offsets[bank]] & 0xff;
}
public void setElem(int i, int val)
{
data[i+offset] = (byte) val;
}
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (byte) val;
}
}

View File

@ -0,0 +1,103 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
/* This is one of several classes that are nearly identical. Maybe we
should have a central template and generate all these files. This
is one of the cases where templates or macros would have been
useful to have in Java.
This file has been created using search-replace. My only fear is
that these classes will grow out-of-sync as of a result of changes
that are not propagated to the other files. As always, mirroring
code is a maintenance nightmare. */
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class DataBufferInt extends DataBuffer
{
private int[] data;
private int[][] bankData;
public DataBufferInt(int size)
{
super(TYPE_INT, size);
data = new int[size];
}
public DataBufferInt(int size, int numBanks)
{
super(TYPE_INT, size, numBanks);
bankData = new int[numBanks][size];
data = bankData[0];
}
public DataBufferInt(int[] dataArray, int size)
{
super(TYPE_INT, size);
data = dataArray;
}
public DataBufferInt(int[] dataArray, int size, int offset)
{
super(TYPE_INT, size, 1, offset);
data = dataArray;
}
public DataBufferInt(int[][] dataArray, int size)
{
super(TYPE_INT, size, dataArray.length);
bankData = dataArray;
data = bankData[0];
}
public DataBufferInt(int[][] dataArray, int size, int[] offsets)
{
super(TYPE_INT, size, dataArray.length, offsets);
bankData = dataArray;
data = bankData[0];
}
public int[] getData()
{
return data;
}
public int[] getData(int bank)
{
return bankData[bank];
}
public int[][] getBankData()
{
return bankData;
}
public int getElem(int i)
{
return data[i+offset];
}
public int getElem(int bank, int i)
{
// get unsigned int as int
return bankData[bank][i+offsets[bank]];
}
public void setElem(int i, int val)
{
data[i+offset] = (int) val;
}
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (int) val;
}
}

View File

@ -0,0 +1,103 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
/* This is one of several classes that are nearly identical. Maybe we
should have a central template and generate all these files. This
is one of the cases where templates or macros would have been
useful to have in Java.
This file has been created using search-replace. My only fear is
that these classes will grow out-of-sync as of a result of changes
that are not propagated to the other files. As always, mirroring
code is a maintenance nightmare. */
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class DataBufferUShort extends DataBuffer
{
private short[] data;
private short[][] bankData;
public DataBufferUShort(int size)
{
super(TYPE_USHORT, size);
data = new short[size];
}
public DataBufferUShort(int size, int numBanks)
{
super(TYPE_USHORT, size, numBanks);
bankData = new short[numBanks][size];
data = bankData[0];
}
public DataBufferUShort(short[] dataArray, int size)
{
super(TYPE_USHORT, size);
data = dataArray;
}
public DataBufferUShort(short[] dataArray, int size, int offset)
{
super(TYPE_USHORT, size, 1, offset);
data = dataArray;
}
public DataBufferUShort(short[][] dataArray, int size)
{
super(TYPE_USHORT, size, dataArray.length);
bankData = dataArray;
data = bankData[0];
}
public DataBufferUShort(short[][] dataArray, int size, int[] offsets)
{
super(TYPE_USHORT, size, dataArray.length, offsets);
bankData = dataArray;
data = bankData[0];
}
public short[] getData()
{
return data;
}
public short[] getData(int bank)
{
return bankData[bank];
}
public short[][] getBankData()
{
return bankData;
}
public int getElem(int i)
{
return data[i+offset] & 0xffff; // get unsigned short as int
}
public int getElem(int bank, int i)
{
// get unsigned short as int
return bankData[bank][i+offsets[bank]] & 0xffff;
}
public void setElem(int i, int val)
{
data[i+offset] = (short) val;
}
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (short) val;
}
}

View File

@ -0,0 +1,338 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import gnu.gcj.awt.Buffers;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class DirectColorModel extends PackedColorModel
{
public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask)
{
this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
rmask, gmask, bmask, 0,
false, // not alpha premultiplied
Buffers.smallestAppropriateTransferType(pixelBits) // find type
);
}
public DirectColorModel(int pixelBits,
int rmask, int gmask, int bmask, int amask)
{
this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
rmask, gmask, bmask, amask,
false, // not alpha premultiplied
Buffers.smallestAppropriateTransferType(pixelBits) // find type
);
}
public DirectColorModel(ColorSpace cspace, int pixelBits,
int rmask, int gmask, int bmask, int amask,
boolean isAlphaPremultiplied,
int transferType)
{
super(cspace, pixelBits,
rmask, gmask, bmask, amask, isAlphaPremultiplied,
((amask == 0) ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
transferType);
}
public final int getRedMask()
{
return getMask(0);
}
public final int getGreenMask()
{
return getMask(1);
}
public final int getBlueMask()
{
return getMask(2);
}
public final int getAlphaMask()
{
return hasAlpha() ? getMask(3) : 0;
}
public final int getRed(int pixel)
{
return extractAndNormalizeSample(pixel, 0);
}
public final int getGreen(int pixel)
{
return extractAndNormalizeSample(pixel, 1);
}
public final int getBlue(int pixel)
{
return extractAndNormalizeSample(pixel, 2);
}
public final int getAlpha(int pixel)
{
if (!hasAlpha()) return 0;
return extractAndScaleSample(pixel, 3);
}
private final int extractAndNormalizeSample(int pixel, int component)
{
int value = extractAndScaleSample(pixel, component);
if (hasAlpha() && isAlphaPremultiplied())
value = value*255/getAlpha(pixel);
return value;
}
private final int extractAndScaleSample(int pixel, int component)
{
int field = pixel & getMask(component);
int to8BitShift =
8 - shifts[component] - getComponentSize(component);
return (to8BitShift>0) ?
(field << to8BitShift) :
(field >>> (-to8BitShift));
}
/* FIXME: The Sun docs show that this method is overridden, but I don't
see any way to improve on the superclass implementation. */
public final int getRGB(int pixel)
{
return super.getRGB(pixel);
}
public int getRed(Object inData)
{
return getRed(getPixelFromArray(inData));
}
public int getGreen(Object inData)
{
return getGreen(getPixelFromArray(inData));
}
public int getBlue(Object inData)
{
return getBlue(getPixelFromArray(inData));
}
public int getAlpha(Object inData)
{
return getAlpha(getPixelFromArray(inData));
}
public int getRGB(Object inData)
{
return getRGB(getPixelFromArray(inData));
}
/**
* Converts a normalized pixel int value in the sRGB color
* space to an array containing a single pixel of the color space
* of the color model.
*
* <p>This method performs the inverse function of
* <code>getRGB(Object inData)</code>.
*
* @param rgb pixel as a normalized sRGB, 0xAARRGGBB value.
*
* @param pixel to avoid needless creation of arrays, an array to
* use to return the pixel can be given. If null, a suitable array
* will be created.
*
* @return array of transferType containing a single pixel. The
* pixel should be encoded in the natural way of the color model.
*
* @see #getRGB(Object)
*/
public Object getDataElements(int rgb, Object pixel)
{
// FIXME: handle alpha multiply
int pixelValue = 0;
int a = 0;
if (hasAlpha()) {
a = (rgb >>> 24) & 0xff;
pixelValue = valueToField(a, 3, 8);
}
if (hasAlpha() && isAlphaPremultiplied())
{
int r, g, b;
/* if r=0xff and a=0xff, then resulting
value will be (r*a)>>>8 == 0xfe... This seems wrong.
We should divide by 255 rather than shifting >>>8 after
multiplying.
Too bad, shifting is probably less expensive.
r = ((rgb >>> 16) & 0xff)*a;
g = ((rgb >>> 8) & 0xff)*a;
b = ((rgb >>> 0) & 0xff)*a; */
/* The r, g, b values we calculate are 16 bit. This allows
us to avoid discarding the lower 8 bits obtained if
multiplying with the alpha band. */
// using 16 bit values
r = ((rgb >>> 8) & 0xff00)*a/255;
g = ((rgb >>> 0) & 0xff00)*a/255;
b = ((rgb << 8) & 0xff00)*a/255;
pixelValue |=
valueToField(r, 0, 16) | // Red
valueToField(g, 1, 16) | // Green
valueToField(b, 2, 16); // Blue
}
else
{
int r, g, b;
// using 8 bit values
r = (rgb >>> 16) & 0xff;
g = (rgb >>> 8) & 0xff;
b = (rgb >>> 0) & 0xff;
pixelValue |=
valueToField(r, 0, 8) | // Red
valueToField(g, 1, 8) | // Green
valueToField(b, 2, 8); // Blue
}
/* In this color model, the whole pixel fits in the first element
of the array. */
DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1);
buffer.setElem(0, pixelValue);
return Buffers.getData(buffer);
}
/**
* Converts a value to the correct field bits based on the
* information derived from the field masks.
*
* @param highBit the position of the most significant bit in the
* val parameter.
*/
private final int valueToField(int val, int component, int highBit)
{
int toFieldShift =
getComponentSize(component) + shifts[component] - highBit;
int ret = (toFieldShift>0) ?
(val << toFieldShift) :
(val >>> (-toFieldShift));
return ret & getMask(component);
}
/**
* Converts a 16 bit value to the correct field bits based on the
* information derived from the field masks.
*/
private final int value16ToField(int val, int component)
{
int toFieldShift = getComponentSize(component) + shifts[component] - 16;
return (toFieldShift>0) ?
(val << toFieldShift) :
(val >>> (-toFieldShift));
}
/**
* Fills an array with the unnormalized component samples from a
* pixel value. I.e. decompose the pixel, but not perform any
* color conversion.
*/
public final int[] getComponents(int pixel, int[] components, int offset)
{
int numComponents = getNumComponents();
if (components == null) components = new int[offset + numComponents];
for (int b=0; b<numComponents; b++)
components[offset++] = (pixel&getMask(b)) >>> shifts[b];
return components;
}
public final int[] getComponents(Object pixel, int[] components,
int offset)
{
return getComponents(getPixelFromArray(pixel), components, offset);
}
public final WritableRaster createCompatibleWritableRaster(int w, int h)
{
SampleModel sm = createCompatibleSampleModel(w, h);
Point origin = new Point(0, 0);
return Raster.createWritableRaster(sm, origin);
}
public int getDataElement(int[] components, int offset)
{
int numComponents = getNumComponents();
int pixelValue = 0;
for (int c=0; c<numComponents; c++)
pixelValue |= (components[offset++] << shifts[c]) & getMask(c);
return pixelValue;
}
public Object getDataElements(int[] components, int offset, Object obj)
{
/* In this color model, the whole pixel fits in the first element
of the array. */
int pixelValue = getDataElement(components, offset);
DataBuffer buffer = Buffers.createBuffer(transferType, obj, 1);
buffer.setElem(0, pixelValue);
return Buffers.getData(buffer);
}
public ColorModel coerceData(WritableRaster raster,
boolean isAlphaPremultiplied)
{
if (this.isAlphaPremultiplied == isAlphaPremultiplied)
return this;
/* TODO: provide better implementation based on the
assumptions we can make due to the specific type of the
color model. */
super.coerceData(raster, isAlphaPremultiplied);
return new ComponentColorModel(cspace, bits, hasAlpha(),
isAlphaPremultiplied, // argument
transparency, transferType);
}
public boolean isCompatibleRaster(Raster raster)
{
/* FIXME: the Sun docs say this method is overridden here,
but I don't see any way to improve upon the implementation
in ColorModel. */
return super.isCompatibleRaster(raster);
}
String stringParam()
{
return super.stringParam() +
", redMask=" + Integer.toHexString(getRedMask()) +
", greenMask=" + Integer.toHexString(getGreenMask()) +
", blueMask=" + Integer.toHexString(getBlueMask()) +
", alphaMask=" + Integer.toHexString(getAlphaMask());
}
public String toString()
{
/* FIXME: Again, docs say override, but how do we improve upon the
superclass implementation? */
return super.toString();
}
}

View File

@ -8,7 +8,6 @@ details. */
package java.awt.image;
import java.util.Hashtable;
import java.awt.ColorModel;
public interface ImageConsumer
{

View File

@ -0,0 +1,355 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import gnu.gcj.awt.Buffers;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class IndexColorModel extends ColorModel
{
private byte[] r;
private byte[] g;
private byte[] b;
private byte[] a;
private int[] argb;
private byte[] cmap;
private int start;
private int transparent;
private int size;
public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b)
{
super(bits, nArray(bits, 3),
ColorSpace.getInstance(ColorSpace.CS_sRGB),
false, // no transparency
false, // no premultiplied
Transparency.OPAQUE,
Buffers.smallestAppropriateTransferType(bits));
this.r = r;
this.g = g;
this.b = b;
this.size = size;
}
public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b,
int transparent)
{
super(bits, nArray(bits, 4),
ColorSpace.getInstance(ColorSpace.CS_sRGB),
true, // has transparency
false,
Transparency.BITMASK,
Buffers.smallestAppropriateTransferType(bits));
this.r = r;
this.g = g;
this.b = b;
this.transparent = transparent;
this.size = size;
}
public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b,
byte[] a)
{
super(bits, nArray(bits, 4),
ColorSpace.getInstance(ColorSpace.CS_sRGB),
true, // has transparency
false,
Transparency.BITMASK,
Buffers.smallestAppropriateTransferType(bits));
this.r = r;
this.g = g;
this.b = b;
this.a = a;
this.size = size;
}
public IndexColorModel(int bits, int size, byte[] cmap, int start,
boolean hasAlpha)
{
super(bits, nArray(bits, hasAlpha ? 4 : 3),
ColorSpace.getInstance(ColorSpace.CS_sRGB),
hasAlpha,
false,
hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE,
Buffers.smallestAppropriateTransferType(bits));
this.cmap = cmap;
this.start = start;
this.size = size;
}
public IndexColorModel(int bits, int size, byte[] cmap, int start,
boolean hasAlpha, int transparent,
int transferType)
{
super(bits, nArray(bits, hasAlpha ? 4 : 3),
ColorSpace.getInstance(ColorSpace.CS_sRGB),
hasAlpha,
false,
hasAlpha ?
Transparency.TRANSLUCENT :
((transparent < 0) ?
Transparency.OPAQUE :
Transparency.BITMASK),
transferType);
this.cmap = cmap;
this.start = start;
this.size = size;
}
public final int getMapSize()
{
return size;
}
public final int getTransparentPixel()
{
return transparent;
}
public final void getReds(byte r[])
{
if (this.r == null) calcRGBArrays();
System.arraycopy(this.r, 0, r, 0, getMapSize());
}
public final void getGreens(byte g[])
{
if (this.g == null) calcRGBArrays();
System.arraycopy(this.g, 0, g, 0, getMapSize());
}
public final void getBlues(byte b[])
{
if (this.b == null) calcRGBArrays();
System.arraycopy(this.b, 0, b, 0, getMapSize());
}
public final void getAlphas(byte a[])
{
if (this.a == null) calcAlphaArray();
System.arraycopy(this.a, 0, a, 0, getMapSize());
}
public final void getRGBs(int rgb[])
{
if (this.argb == null) calcARGBArray();
System.arraycopy(this.argb, 0, rgb, 0, getMapSize());
}
public int getRed(int pixel)
{
try
{
return r[pixel];
}
catch (NullPointerException npe)
{
calcRGBArrays();
return r[pixel];
}
}
public int getGreen(int pixel)
{
try
{
return g[pixel];
}
catch (NullPointerException npe)
{
calcRGBArrays();
return g[pixel];
}
}
public int getBlue(int pixel)
{
try
{
return b[pixel];
}
catch (NullPointerException npe)
{
calcRGBArrays();
return b[pixel];
}
}
public int getAlpha(int pixel)
{
try
{
return a[pixel];
}
catch (NullPointerException npe)
{
calcAlphaArray();
return a[pixel];
}
}
private void calcRGBArrays() {
int j=0;
boolean hasAlpha = hasAlpha();
r = new byte[size];
g = new byte[size];
b = new byte[size];
if (hasAlpha) a = new byte[size];
for (int i=0; i<size; i++)
{
r[i] = cmap[j++];
g[i] = cmap[j++];
b[i] = cmap[j++];
if (hasAlpha()) a[i] = cmap[j++];
}
}
private void calcAlphaArray()
{
int transparency = getTransparency();
switch (transparency)
{
case Transparency.OPAQUE:
case Transparency.BITMASK:
a = nArray((byte) 255, size);
if (transparency == Transparency.BITMASK)
a[transparent] = 0;
break;
case Transparency.TRANSLUCENT:
calcRGBArrays();
}
}
private void calcARGBArray()
{
int mapSize = getMapSize();
argb = new int[mapSize];
for (int p=0; p<mapSize; p++) argb[p] = getRGB(p);
}
public int getRed(Object inData)
{
return getRed(getPixelFromArray(inData));
}
public int getGreen(Object inData)
{
return getGreen(getPixelFromArray(inData));
}
public int getBlue(Object inData)
{
return getBlue(getPixelFromArray(inData));
}
public int getAlpha(Object inData)
{
return getAlpha(getPixelFromArray(inData));
}
public int getRGB(Object inData)
{
return getRGB(getPixelFromArray(inData));
}
public Object getDataElements(int rgb, Object pixel)
{
int av, rv, gv, bv;
// using 8 bit values
av = (rgb >>> 24) & 0xff;
rv = (rgb >>> 16) & 0xff;
gv = (rgb >>> 8) & 0xff;
bv = (rgb >>> 0) & 0xff;
int pixelValue = getPixelValue(av, rv, gv, bv);
/* In this color model, the whole pixel fits in the first element
of the array. */
DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1);
buffer.setElem(0, pixelValue);
return Buffers.getData(buffer);
}
private int getPixelValue(int av, int rv, int gv, int bv)
{
if (r == null) calcRGBArrays();
if (a == null) calcAlphaArray();
int minDAlpha = 1<<8;
int minDRGB = (1<<8)*(1<<8)*3;
int pixelValue = -1;
for (int i=0; i<size; i++)
{
int dAlpha = Math.abs(av-(a[i]&0xff));
if (dAlpha > minDAlpha) continue;
int dR = rv-(r[i]&0xff);
int dG = gv-(g[i]&0xff);
int dB = bv-(b[i]&0xff);
int dRGB = dR*dR + dG*dG + dB*dB;
if (dRGB >= minDRGB) continue;
pixelValue = i;
minDRGB = dRGB;
}
return pixelValue;
}
public int[] getComponents(int pixel, int[] components, int offset)
{
int numComponents = getNumComponents();
if (components == null) components = new int[offset + numComponents];
components[offset++] = (r[pixel]&0xff);
components[offset++] = (g[pixel]&0xff);
components[offset++] = (b[pixel]&0xff);
if (hasAlpha()) components[offset++] = (a[pixel]&0xff);
return components;
}
public final int[] getComponents(Object pixel, int[] components,
int offset)
{
return getComponents(getPixelFromArray(pixel), components, offset);
}
public int getDataElement(int[] components, int offset)
{
int r = components[offset++];
int g = components[offset++];
int b = components[offset++];
int a = hasAlpha() ? components[offset++] : 255;
return getPixelValue(a, r, g, b);
}
public Object getDataElements(int[] components, int offset, Object pixel)
{
int pixelValue = getDataElement(components, offset);
/* In this color model, the whole pixel fits in the first element
of the array. */
DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1);
buffer.setElem(0, pixelValue);
return Buffers.getData(buffer);
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
int[] bandOffsets = {0};
return new ComponentSampleModel(transferType, w, h,
1, // pixel stride
w, // scanline stride
bandOffsets);
}
}

View File

@ -0,0 +1,162 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import java.awt.Point;
import java.awt.color.ColorSpace;
import gnu.gcj.awt.BitMaskExtent;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public abstract class PackedColorModel extends ColorModel
{
private int masks[];
/* Package accessibility, the DirectColorModel needs this array */
int shifts[];
public PackedColorModel(ColorSpace cspace, int pixelBits,
int[] colorMaskArray, int alphaMask,
boolean isAlphaPremultiplied,
int transparency,
int transferType)
{
super(pixelBits, calcBitsPerComponent(colorMaskArray, alphaMask),
cspace, (alphaMask != 0), isAlphaPremultiplied, transparency,
transferType);
initMasks(colorMaskArray, alphaMask);
if ((pixelBits<1) || (pixelBits>32)) {
throw new IllegalArgumentException("pixels per bits must be " +
"in the range [1, 32]");
}
}
private static int[] calcBitsPerComponent(int[] colorMaskArray,
int alphaMask)
{
int numComponents = colorMaskArray.length;
if (alphaMask != 0) numComponents++;
int[] bitsPerComponent = new int[numComponents];
BitMaskExtent extent = new BitMaskExtent();
for (int b=0; b<colorMaskArray.length; b++)
{
extent.setMask(colorMaskArray[b]);
bitsPerComponent[b] = extent.bitWidth;
}
if (alphaMask != 0)
{
extent.setMask(alphaMask);
bitsPerComponent[numComponents-1] = extent.bitWidth;
}
return bitsPerComponent;
}
/** Initializes the masks.
*
* @return an array containing the number of bits per color
* component.
*/
private void initMasks(int[] colorMaskArray, int alphaMask)
{
int numComponents = colorMaskArray.length;
if (alphaMask == 0)
{
masks = colorMaskArray;
}
else
{
masks = new int[numComponents+1];
System.arraycopy(colorMaskArray, 0,
masks, 0,
numComponents);
masks[numComponents++] = alphaMask;
}
shifts = new int[numComponents];
// Bit field handling have been moved to a utility class
BitMaskExtent extent = new BitMaskExtent();
for (int b=0; b<numComponents; b++)
{
extent.setMask(masks[b]);
shifts[b] = extent.leastSignificantBit;
}
}
public PackedColorModel(ColorSpace cspace, int pixelBits,
int rmask, int gmask, int bmask,
int amask, boolean isAlphaPremultiplied,
int transparency,
int transferType)
{
this(cspace, pixelBits, makeColorMaskArray(rmask, gmask, bmask),
amask, isAlphaPremultiplied, transparency, transferType);
}
/* TODO: If there is a alpha mask, it is inefficient to create a
color mask array that will be discarded when the alpha mask is
appended. We should probably create a private constructor that
takes a complete array of masks (color+alpha) as an
argument. */
private static int[] makeColorMaskArray(int rmask, int gmask, int bmask)
{
int[] colorMaskArray = { rmask, gmask, bmask };
return colorMaskArray;
}
public final int getMask(int index)
{
return masks[index];
}
public final int[] getMasks()
{
return masks;
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
return new SinglePixelPackedSampleModel(transferType, w, h, masks);
}
public boolean isCompatibleSampleModel(SampleModel sm)
{
if (!super.isCompatibleSampleModel(sm)) return false;
if (!(sm instanceof SinglePixelPackedSampleModel)) return false;
SinglePixelPackedSampleModel sppsm =
(SinglePixelPackedSampleModel) sm;
return java.util.Arrays.equals(sppsm.getBitMasks(), masks);
}
public WritableRaster getAlphaRaster(WritableRaster raster) {
if (!hasAlpha()) return null;
SampleModel sm = raster.getSampleModel();
int[] alphaBand = { sm.getNumBands() - 1 };
SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
DataBuffer buffer = raster.getDataBuffer();
Point origin = new Point(0, 0);
return Raster.createWritableRaster(alphaModel, buffer, origin);
}
public boolean equals(Object obj)
{
if (!super.equals(obj)) return false;
if (!(obj instanceof PackedColorModel)) return false;
PackedColorModel other = (PackedColorModel) obj;
return java.util.Arrays.equals(masks, other.masks);
}
}

View File

@ -0,0 +1,418 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import java.awt.*;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class Raster
{
protected SampleModel sampleModel;
protected DataBuffer dataBuffer;
protected int minX;
protected int minY;
protected int width;
protected int height;
protected int sampleModelTranslateX;
protected int sampleModelTranslateY;
protected int numBands;
protected int numDataElements;
protected Raster parent;
protected Raster(SampleModel sampleModel, Point origin)
{
this(sampleModel, sampleModel.createDataBuffer(), origin);
}
protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
Point origin)
{
this(sampleModel, dataBuffer,
new Rectangle(origin.x, origin.y,
sampleModel.getWidth(), sampleModel.getHeight()),
origin, null);
}
protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
Rectangle aRegion,
Point sampleModelTranslate, Raster parent)
{
this.sampleModel = sampleModel;
this.dataBuffer = dataBuffer;
this.minX = aRegion.x;
this.minY = aRegion.y;
this.width = aRegion.width;
this.height = aRegion.height;
this.sampleModelTranslateX = sampleModelTranslate.x;
this.sampleModelTranslateY = sampleModelTranslate.y;
this.numBands = sampleModel.getNumBands();
this.numDataElements = sampleModel.getNumDataElements();
this.parent = parent;
}
public static WritableRaster createInterleavedRaster(int dataType,
int w, int h,
int bands,
Point location)
{
int[] bandOffsets = new int[bands];
// TODO: Maybe not generate this every time.
for (int b=0; b<bands; b++) bandOffsets[b] = b;
int scanlineStride = bands*w;
return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
bandOffsets, location);
}
public static WritableRaster createInterleavedRaster(int dataType,
int w, int h,
int scanlineStride,
int pixelStride,
int[] bandOffsets,
Point location)
{
SampleModel sm = new ComponentSampleModel(dataType,
w, h,
pixelStride,
scanlineStride,
bandOffsets);
return createWritableRaster(sm, location);
}
public static WritableRaster createBandedRaster(int dataType,
int w, int h, int bands,
Point location)
{
// FIXME: Implement;
throw new UnsupportedOperationException("not implemented yet");
}
public static WritableRaster createBandedRaster(int dataType,
int w, int h,
int scanlineStride,
int[] bankIndices,
int[] bandOffsets,
Point location)
{
// FIXME: Implement;
throw new UnsupportedOperationException("not implemented yet");
}
public static WritableRaster createPackedRaster(int dataType,
int w, int h,
int[] bandMasks,
Point location)
{
SampleModel sm = new SinglePixelPackedSampleModel(dataType,
w, h,
bandMasks);
return createWritableRaster(sm, location);
}
public static WritableRaster
createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
int scanlineStride, int pixelStride,
int[] bandOffsets, Point location)
{
SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
w, h,
scanlineStride,
pixelStride,
bandOffsets);
return createWritableRaster(sm, dataBuffer, location);
}
public static
WritableRaster createBandedRaster(DataBuffer dataBuffer,
int w, int h,
int scanlineStride,
int[] bankIndices,
int[] bandOffsets,
Point location)
{
// FIXME: Implement;
throw new UnsupportedOperationException("not implemented yet");
}
public static WritableRaster
createPackedRaster(DataBuffer dataBuffer,
int w, int h,
int scanlineStride,
int[] bandMasks,
Point location) {
SampleModel sm =
new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
w, h,
scanlineStride,
bandMasks);
return createWritableRaster(sm, dataBuffer, location);
}
public static Raster createRaster(SampleModel sm, DataBuffer db,
Point location)
{
return new Raster(sm, db, location);
}
public static WritableRaster createWritableRaster(SampleModel sm,
Point location)
{
return new WritableRaster(sm, location);
}
public static WritableRaster createWritableRaster(SampleModel sm,
DataBuffer db,
Point location)
{
return new WritableRaster(sm, db, location);
}
public Raster getParent()
{
return parent;
}
public final int getSampleModelTranslateX()
{
return sampleModelTranslateX;
}
public final int getSampleModelTranslateY()
{
return sampleModelTranslateY;
}
public WritableRaster createCompatibleWritableRaster()
{
return new WritableRaster(getSampleModel(), new Point(minX, minY));
}
public WritableRaster createCompatibleWritableRaster(int w, int h)
{
return createCompatibleWritableRaster(minX, minY, w, h);
}
public WritableRaster createCompatibleWritableRaster(Rectangle rect)
{
return createCompatibleWritableRaster(rect.x, rect.y,
rect.width, rect.height);
}
public WritableRaster createCompatibleWritableRaster(int x, int y,
int w, int h)
{
SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
return new WritableRaster(sm, sm.createDataBuffer(),
new Point(x, y));
}
public Raster createTranslatedChild(int childMinX, int childMinY) {
int tcx = sampleModelTranslateX - minX + childMinX;
int tcy = sampleModelTranslateY - minY + childMinY;
return new Raster(sampleModel, dataBuffer,
new Rectangle(childMinX, childMinY,
width, height),
new Point(tcx, tcy),
this);
}
public Raster createChild(int parentX, int parentY, int width,
int height, int childMinX, int childMinY,
int[] bandList)
{
/* FIXME: Throw RasterFormatException if child bounds extends
beyond the bounds of this raster. */
SampleModel sm = (bandList == null) ?
sampleModel :
sampleModel.createSubsetSampleModel(bandList);
/*
data origin
/
+-------------------------
|\. __ parent trans
| \`.
| \ `. parent origin
| \ `. /
| /\ +-------- - -
|trans\ /<\-- deltaTrans
|child +-+-\---- - -
| /|`| \__ parent [x, y]
|child | |`. \
|origin| : `.\
| | / `\
| : / +
| child [x, y]
parent_xy - parent_trans = child_xy - child_trans
child_trans = parent_trans + child_xy - parent_xy
*/
return new Raster(sm, dataBuffer,
new Rectangle(childMinX, childMinY,
width, height),
new Point(sampleModelTranslateX+childMinX-parentX,
sampleModelTranslateY+childMinY-parentY),
this);
}
public Rectangle getBounds()
{
return new Rectangle(minX, minY, width, height);
}
public final int getMinX()
{
return minX;
}
public final int getMinY()
{
return minY;
}
public final int getWidth()
{
return width;
}
public final int getHeight()
{
return height;
}
public final int getNumDataElements()
{
return numDataElements;
}
public final int getTransferType()
{
return sampleModel.getTransferType();
}
public DataBuffer getDataBuffer()
{
return dataBuffer;
}
public SampleModel getSampleModel()
{
return sampleModel;
}
public Object getDataElements(int x, int y, Object outData)
{
return sampleModel.getDataElements(x-sampleModelTranslateX,
y-sampleModelTranslateY,
outData, dataBuffer);
}
public Object getDataElements(int x, int y, int w, int h,
Object outData)
{
return sampleModel.getDataElements(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, outData, dataBuffer);
}
public int[] getPixel(int x, int y, int[] iArray)
{
return sampleModel.getPixel(x-sampleModelTranslateX,
y-sampleModelTranslateY,
iArray, dataBuffer);
}
public float[] getPixel(int x, int y, float[] fArray)
{
return sampleModel.getPixel(x-sampleModelTranslateX,
y-sampleModelTranslateY,
fArray, dataBuffer);
}
public double[] getPixel(int x, int y, double[] dArray)
{
return sampleModel.getPixel(x-sampleModelTranslateX,
y-sampleModelTranslateY,
dArray, dataBuffer);
}
public int[] getPixels(int x, int y, int w, int h, int[] iArray)
{
return sampleModel.getPixels(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, iArray, dataBuffer);
}
public float[] getPixels(int x, int y, int w, int h,
float[] fArray)
{
return sampleModel.getPixels(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, fArray, dataBuffer);
}
public double[] getPixels(int x, int y, int w, int h,
double[] dArray)
{
return sampleModel.getPixels(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, dArray, dataBuffer);
}
public int getSample(int x, int y, int b)
{
return sampleModel.getSample(x-sampleModelTranslateX,
y-sampleModelTranslateY,
b, dataBuffer);
}
public float getSampleFloat(int x, int y, int b)
{
return sampleModel.getSampleFloat(x-sampleModelTranslateX,
y-sampleModelTranslateY,
b, dataBuffer);
}
public double getSampleDouble(int x, int y, int b)
{
return sampleModel.getSampleDouble(x-sampleModelTranslateX,
y-sampleModelTranslateY,
b, dataBuffer);
}
public int[] getSamples(int x, int y, int w, int h, int b,
int[] iArray)
{
return sampleModel.getSamples(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, b, iArray, dataBuffer);
}
public float[] getSamples(int x, int y, int w, int h, int b,
float[] fArray)
{
return sampleModel.getSamples(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, b, fArray, dataBuffer);
}
public double[] getSamples(int x, int y, int w, int h, int b,
double[] dArray)
{
return sampleModel.getSamples(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, b, dArray, dataBuffer);
}
}

View File

@ -0,0 +1,436 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public abstract class SampleModel
{
/** Width of image described. */
protected int width;
/** Height of image described. */
protected int height;
/** Number of bands in the image described. */
protected int numBands;
/**
* The DataBuffer type that is used to store the data of the image
* described.
*/
protected int dataType;
public SampleModel(int dataType, int w, int h, int numBands)
{
if ((w<=0) || (h<=0)) throw new IllegalArgumentException();
// FIXME: How can an int be greater than Integer.MAX_VALUE?
// FIXME: How do we identify an unsupported data type?
this.dataType = dataType;
this.width = w;
this.height = h;
this.numBands = numBands;
}
public final int getWidth()
{
return width;
}
public final int getHeight()
{
return height;
}
public final int getNumBands()
{
return numBands;
}
public abstract int getNumDataElements();
public final int getDataType()
{
return dataType;
}
public int getTransferType()
{
// FIXME: Is this a reasonable default implementation?
return dataType;
}
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
if (iArray == null) iArray = new int[numBands];
for (int b=0; b<numBands; b++) iArray[b] = getSample(x, y, b, data);
return iArray;
}
/**
*
* This method is provided as a faster alternative to getPixel(),
* that can be used when there is no need to decode the pixel into
* seperate sample values.
*
* @param obj An array to return the pixel data in. If null, an
* array of the right type and size will be created.
*
* @return A single pixel as an array object of a primitive type,
* based on the transfer type. Eg. if transfer type is
* DataBuffer.TYPE_USHORT, then a short[] object is returned.
*/
public abstract Object getDataElements(int x, int y, Object obj,
DataBuffer data);
public Object getDataElements(int x, int y, int w, int h, Object obj,
DataBuffer data)
{
int size = w*h;
int numDataElements = getNumDataElements();
int dataSize = numDataElements*size;
if (obj == null)
{
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
obj = new byte[dataSize];
break;
case DataBuffer.TYPE_USHORT:
obj = new short[dataSize];
break;
case DataBuffer.TYPE_INT:
obj = new int[dataSize];
break;
default:
// Seems like the only sensible thing to do.
throw new ClassCastException();
}
}
Object pixelData = null;
int outOffset = 0;
for (int yy = y; yy<(y+h); yy++)
{
for (int xx = x; xx<(x+w); xx++)
{
pixelData = getDataElements(xx, yy, pixelData, data);
System.arraycopy(pixelData, 0, obj, outOffset,
numDataElements);
outOffset += numDataElements;
}
}
return obj;
}
public abstract void setDataElements(int x, int y, Object obj,
DataBuffer data);
public void setDataElements(int x, int y, int w, int h,
Object obj, DataBuffer data)
{
int size = w*h;
int numDataElements = getNumDataElements();
int dataSize = numDataElements*size;
Object pixelData;
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
pixelData = new byte[numDataElements];
break;
case DataBuffer.TYPE_USHORT:
pixelData = new short[numDataElements];
break;
case DataBuffer.TYPE_INT:
pixelData = new int[numDataElements];
break;
default:
// Seems like the only sensible thing to do.
throw new ClassCastException();
}
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(obj, inOffset, pixelData, 0,
numDataElements);
setDataElements(xx, yy, pixelData, data);
inOffset += numDataElements;
}
}
}
public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
{
if (fArray == null) fArray = new float[numBands];
for (int b=0; b<numBands; b++)
{
fArray[0] = getSampleFloat(x, y, b, data);
}
return fArray;
}
public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
if (dArray == null) dArray = new double[numBands];
for (int b=0; b<numBands; b++)
{
dArray[0] = getSampleDouble(x, y, b, data);
}
return dArray;
}
/* FIXME: Should it return a banded or pixel interleaved array of
samples? (Assume interleaved.) */
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int size = w*h;
int outOffset = 0;
int[] pixel = null;
if (iArray == null) iArray = new int[w*h*numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
getPixel(xx, yy, pixel, data);
System.arraycopy(pixel, 0, iArray, outOffset, numBands);
outOffset += numBands;
}
}
return iArray;
}
/* FIXME: Should it return a banded or pixel interleaved array of
samples? (Assume interleaved.) */
public float[] getPixels(int x, int y, int w, int h, float[] fArray,
DataBuffer data)
{
int size = w*h;
int outOffset = 0;
float[] pixel = null;
if (fArray == null) fArray = new float[w*h*numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
getPixel(xx, yy, pixel, data);
System.arraycopy(pixel, 0, fArray, outOffset, numBands);
outOffset += numBands;
}
}
return fArray;
}
/* FIXME: Should it return a banded or pixel interleaved array of
samples? (Assume interleaved.) */
public double[] getPixels(int x, int y, int w, int h, double[] dArray,
DataBuffer data)
{
int size = w*h;
int outOffset = 0;
double[] pixel = null;
if (dArray == null) dArray = new double[w*h*numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
getPixel(xx, yy, pixel, data);
System.arraycopy(pixel, 0, dArray, outOffset, numBands);
outOffset += numBands;
}
}
return dArray;
}
public abstract int getSample(int x, int y, int b, DataBuffer data);
public float getSampleFloat(int x, int y, int b, DataBuffer data)
{
return getSample(x, y, b, data);
}
public double getSampleDouble(int x, int y, int b, DataBuffer data)
{
return getSampleFloat(x, y, b, data);
}
public int[] getSamples(int x, int y, int w, int h, int b,
int[] iArray, DataBuffer data)
{
int size = w*h;
int outOffset = 0;
if (iArray == null) iArray = new int[size];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
iArray[outOffset++] = getSample(xx, yy, b, data);
}
}
return iArray;
}
public float[] getSamples(int x, int y, int w, int h, int b,
float[] fArray, DataBuffer data)
{
int size = w*h;
int outOffset = 0;
if (fArray == null) fArray = new float[size];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
fArray[outOffset++] = getSampleFloat(xx, yy, b, data);
}
}
return fArray;
}
public double[] getSamples(int x, int y, int w, int h, int b,
double[] dArray, DataBuffer data)
{
int size = w*h;
int outOffset = 0;
if (dArray == null) dArray = new double[size];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
dArray[outOffset++] = getSampleDouble(xx, yy, b, data);
}
}
return dArray;
}
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
for (int b=0; b<numBands; b++) setSample(x, y, b, iArray[b], data);
}
public void setPixel(int x, int y, float[] fArray, DataBuffer data)
{
for (int b=0; b<numBands; b++) setSample(x, y, b, fArray[b], data);
}
public void setPixel(int x, int y, double[] dArray, DataBuffer data)
{
for (int b=0; b<numBands; b++) setSample(x, y, b, dArray[b], data);
}
public void setPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int inOffset = 0;
int[] pixel = new int[numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(iArray, inOffset, pixel, 0, numBands);
setPixel(xx, yy, pixel, data);
inOffset += numBands;
}
}
}
public void setPixels(int x, int y, int w, int h, float[] fArray,
DataBuffer data)
{
int inOffset = 0;
float[] pixel = new float[numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(fArray, inOffset, pixel, 0, numBands);
setPixel(xx, yy, pixel, data);
inOffset += numBands;
}
}
}
public void setPixels(int x, int y, int w, int h, double[] dArray,
DataBuffer data)
{
int inOffset = 0;
double[] pixel = new double[numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(dArray, inOffset, pixel, 0, numBands);
setPixel(xx, yy, pixel, data);
inOffset += numBands;
}
}
}
public abstract void setSample(int x, int y, int b, int s,
DataBuffer data);
public void setSample(int x, int y, int b, float s,
DataBuffer data)
{
setSample(x, y, b, (int) s, data);
}
public void setSample(int x, int y, int b, double s,
DataBuffer data)
{
setSample(x, y, b, (float) s, data);
}
public void setSamples(int x, int y, int w, int h, int b,
int[] iArray, DataBuffer data)
{
int size = w*h;
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
for (int xx=x; xx<(x+w); xx++)
setSample(xx, yy, b, iArray[inOffset++], data);
}
public void setSamples(int x, int y, int w, int h, int b,
float[] fArray, DataBuffer data)
{
int size = w*h;
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
for (int xx=x; xx<(x+w); xx++)
setSample(xx, yy, b, fArray[inOffset++], data);
}
public void setSamples(int x, int y, int w, int h, int b,
double[] dArray, DataBuffer data) {
int size = w*h;
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
for (int xx=x; xx<(x+w); xx++)
setSample(xx, yy, b, dArray[inOffset++], data);
}
public abstract SampleModel createCompatibleSampleModel(int w, int h);
public abstract SampleModel createSubsetSampleModel(int[] bands);
public abstract DataBuffer createDataBuffer();
public abstract int[] getSampleSize();
public abstract int getSampleSize(int band);
}

View File

@ -0,0 +1,245 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import gnu.gcj.awt.BitMaskExtent;
import gnu.gcj.awt.Buffers;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class SinglePixelPackedSampleModel extends SampleModel
{
private int scanlineStride;
private int[] bitMasks;
private int[] bitOffsets;
private int[] sampleSize;;
public SinglePixelPackedSampleModel(int dataType, int w, int h,
int[] bitMasks)
{
this(dataType, w, h, w, bitMasks);
}
public SinglePixelPackedSampleModel(int dataType, int w, int h,
int scanlineStride, int[] bitMasks)
{
super(dataType, w, h, bitMasks.length);
this.scanlineStride = scanlineStride;
this.bitMasks = bitMasks;
bitOffsets = new int[numBands];
sampleSize = new int[numBands];
BitMaskExtent extent = new BitMaskExtent();
for (int b=0; b<numBands; b++)
{
extent.setMask(bitMasks[b]);
sampleSize[b] = extent.bitWidth;
bitOffsets[b] = extent.leastSignificantBit;
}
}
public int getNumDataElements()
{
return 1;
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
/* FIXME: We can avoid recalculation of bit offsets and sample
sizes here by passing these from the current instance to a
special private constructor. */
return new SinglePixelPackedSampleModel(dataType, w, h, bitMasks);
}
public DataBuffer createDataBuffer()
{
// Important: use scanlineStride here, not width!
int size = scanlineStride*height;
return Buffers.createBuffer(getDataType(), size);
}
public int[] getSampleSize()
{
return sampleSize;
}
public int getSampleSize(int band)
{
return sampleSize[band];
}
public int getOffset(int x, int y)
{
return scanlineStride*y + x;
}
public int[] getBitOffsets()
{
return bitOffsets;
}
public int[] getBitMasks()
{
return bitMasks;
}
public int getScanlineStride()
{
return scanlineStride;
}
public SampleModel createSubsetSampleModel(int[] bands)
{
// FIXME: Is this the right way to interpret bands?
int numBands = bands.length;
int[] bitMasks = new int[numBands];
for (int b=0; b<numBands; b++)
bitMasks[b] = this.bitMasks[bands[b]];
return new SinglePixelPackedSampleModel(dataType, width, height,
scanlineStride, bitMasks);
}
public Object getDataElements(int x, int y, Object obj,
DataBuffer data)
{
int offset = scanlineStride*y + x + data.getOffset();
return Buffers.getData(data, offset, obj,
0, // destination offset,
1 // length
);
}
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = scanlineStride*y + x;
if (iArray == null) iArray = new int[numBands];
int samples = data.getElem(offset);
for (int b=0; b<numBands; b++)
iArray[b] = (samples & bitMasks[b]) >>> bitOffsets[b];
return iArray;
}
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int offset = scanlineStride*y + x;
if (iArray == null) iArray = new int[numBands*w*h];
int outOffset = 0;
for (y=0; y<h; y++)
{
int lineOffset = offset;
for (x=0; x<w; x++)
{
int samples = data.getElem(lineOffset++);
for (int b=0; b<numBands; b++)
iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
}
offset += scanlineStride;
}
return iArray;
}
public int getSample(int x, int y, int b, DataBuffer data)
{
int offset = scanlineStride*y + x;
int samples = data.getElem(offset);
return (samples & bitMasks[b]) >>> bitOffsets[b];
}
public void setDataElements(int x, int y, Object obj, DataBuffer data)
{
int offset = scanlineStride*y + x + data.getOffset();
int transferType = getTransferType();
if (getTransferType() != data.getDataType())
{
throw new IllegalArgumentException("transfer type ("+
getTransferType()+"), "+
"does not match data "+
"buffer type (" +
data.getDataType() +
").");
}
try
{
switch (transferType)
{
case DataBuffer.TYPE_BYTE:
{
DataBufferByte out = (DataBufferByte) data;
byte[] in = (byte[]) obj;
out.getData()[offset] = in[0];
return;
}
case DataBuffer.TYPE_USHORT:
{
DataBufferUShort out = (DataBufferUShort) data;
short[] in = (short[]) obj;
out.getData()[offset] = in[0];
return;
}
case DataBuffer.TYPE_INT:
{
DataBufferInt out = (DataBufferInt) data;
int[] in = (int[]) obj;
out.getData()[offset] = in[0];
return;
}
// FIXME: Fill in the other possible types.
default:
throw new InternalError();
}
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
String msg = "While writing data elements" +
", x="+x+", y="+y+
", width="+width+", height="+height+
", scanlineStride="+scanlineStride+
", offset="+offset+
", data.getSize()="+data.getSize()+
", data.getOffset()="+data.getOffset()+
": " +
aioobe;
throw new ArrayIndexOutOfBoundsException(msg);
}
}
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = scanlineStride*y + x;
int samples = 0;
for (int b=0; b<numBands; b++)
samples |= (iArray[b] << bitOffsets[b]) & bitMasks[b];
data.setElem(offset, samples);
}
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
int offset = scanlineStride*y + x;
int samples = data.getElem(offset);
int bitMask = bitMasks[b];
samples &= ~bitMask;
samples |= (s << bitOffsets[b]) & bitMask;
data.setElem(offset, samples);
}
}

View File

@ -0,0 +1,234 @@
/* Copyright © 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
import java.awt.*;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class WritableRaster extends Raster
{
protected WritableRaster(SampleModel sampleModel, Point origin)
{
this(sampleModel, sampleModel.createDataBuffer(), origin);
}
protected WritableRaster(SampleModel sampleModel,
DataBuffer dataBuffer, Point origin)
{
this(sampleModel, dataBuffer,
new Rectangle(origin.x, origin.y,
sampleModel.getWidth(), sampleModel.getHeight()),
origin,
null);
}
protected WritableRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Rectangle aRegion,
Point sampleModelTranslate,
WritableRaster parent)
{
super(sampleModel, dataBuffer, aRegion, sampleModelTranslate,
parent);
}
public WritableRaster getWritableParent()
{
return (WritableRaster) getParent();
}
public WritableRaster createWritableTranslatedChild(int childMinX,
int childMinY)
{
// This mirrors the code from the super class
int tcx = sampleModelTranslateX - minX + childMinX;
int tcy = sampleModelTranslateY - minY + childMinY;
return new WritableRaster(sampleModel, dataBuffer,
new Rectangle(childMinX, childMinY,
width, height),
new Point(tcx, tcy),
this);
}
public WritableRaster createWritableChild(int parentX,
int parentY,
int w, int h,
int childMinX,
int childMinY,
int[] bandList)
{
// This mirrors the code from the super class
// FIXME: Throw RasterFormatException if child bounds extends
// beyond the bounds of this raster.
SampleModel sm = (bandList == null) ?
sampleModel :
sampleModel.createSubsetSampleModel(bandList);
return new
WritableRaster(sm, dataBuffer,
new Rectangle(childMinX, childMinY,
w, h),
new Point(sampleModelTranslateX+childMinX-parentX,
sampleModelTranslateY+childMinY-parentY),
this);
}
public void setDataElements(int x, int y, Object inData)
{
sampleModel.setDataElements(x-sampleModelTranslateX,
y-sampleModelTranslateY,
inData, dataBuffer);
}
public void setDataElements(int x, int y, Raster inRaster)
{
Object dataElements = getDataElements(0, 0,
inRaster.getWidth(),
inRaster.getHeight(),
null);
setDataElements(x, y, dataElements);
}
public void setDataElements(int x, int y, int w, int h,
Object inData)
{
sampleModel.setDataElements(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, inData, dataBuffer);
}
public void setRect(Raster srcRaster)
{
setRect(srcRaster, 0, 0);
}
public void setRect(Raster srcRaster, int dx, int dy)
{
Rectangle targetUnclipped = new Rectangle(srcRaster.getMinX()+dx,
srcRaster.getMinY()+dy,
srcRaster.getWidth(),
srcRaster.getHeight());
Rectangle target = getBounds().intersection(targetUnclipped);
if (target.isEmpty()) return;
int sx = target.x - dx;
int sy = target.y - dy;
// FIXME: Do tests on rasters and use get/set data instead.
/* The JDK documentation seems to imply this implementation.
(the trucation of higher bits), but an implementation using
get/setDataElements would be more efficient. None of the
implementations would do anything sensible when the sample
models don't match.
But this is probably not the place to consider such
optimizations.*/
int[] pixels = srcRaster.getPixels(sx, sy,
target.width, target.height,
(int[]) null);
setPixels(target.x, target.y, target.width, target.height, pixels);
}
public void setPixel(int x, int y, int[] iArray)
{
sampleModel.setPixel(x-sampleModelTranslateX,
y-sampleModelTranslateY,
iArray, dataBuffer);
}
public void setPixel(int x, int y, float[] fArray)
{
sampleModel.setPixel(x-sampleModelTranslateX,
y-sampleModelTranslateY,
fArray, dataBuffer);
}
public void setPixel(int x, int y, double[] dArray)
{
sampleModel.setPixel(x-sampleModelTranslateX,
y-sampleModelTranslateY,
dArray, dataBuffer);
}
public void setPixels(int x, int y, int w, int h, int[] iArray)
{
sampleModel.setPixels(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, iArray, dataBuffer);
}
public void setPixels(int x, int y, int w, int h, float[] fArray)
{
sampleModel.setPixels(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, fArray, dataBuffer);
}
public void setPixels(int x, int y, int w, int h, double[] dArray)
{
sampleModel.setPixels(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, dArray, dataBuffer);
}
public void setSample(int x, int y, int b, int s)
{
sampleModel.setSample(x-sampleModelTranslateX,
y-sampleModelTranslateY,
b, s, dataBuffer);
}
public void setSample(int x, int y, int b, float s)
{
sampleModel.setSample(x-sampleModelTranslateX,
y-sampleModelTranslateY,
b, s, dataBuffer);
}
public void setSample(int x, int y, int b, double s)
{
sampleModel.setSample(x-sampleModelTranslateX,
y-sampleModelTranslateY,
b, s, dataBuffer);
}
public void setSamples(int x, int y, int w, int h, int b,
int[] iArray)
{
sampleModel.setSamples(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, b, iArray, dataBuffer);
}
public void setSamples(int x, int y, int w, int h, int b,
float[] fArray)
{
sampleModel.setSamples(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, b, fArray, dataBuffer);
}
public void setSamples(int x, int y, int w, int h, int b,
double[] dArray)
{
sampleModel.setSamples(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w, h, b, dArray, dataBuffer);
}
}