/dwt/graphics/ImageData.d
D | 3730 lines | 2714 code | 128 blank | 888 comment | 562 complexity | f5aaf21d4995d3f83418f9f1d98c727f MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *
- * Port to the D programming language:
- * Frank Benoit <benoit@tionex.de>
- * Jacob Carlborg <jacob.carlborg@gmail.com>
- *******************************************************************************/
- module dwt.graphics.ImageData;
- import dwt.dwthelper.utils;
- import dwt.dwthelper.System;
- import dwt.DWT;
- import dwt.DWTException;
- import dwt.graphics.Device;
- import dwt.graphics.GC;
- import dwt.graphics.Image;
- import dwt.graphics.ImageDataLoader;
- import dwt.graphics.PaletteData;
- import dwt.graphics.RGB;
- import dwt.internal.CloneableCompatibility;
- import dwt.dwthelper.InputStream;
- /**
- * Instances of this class are device-independent descriptions
- * of images. They are typically used as an intermediate format
- * between loading from or writing to streams and creating an
- * <code>Image</code>.
- * <p>
- * Note that the public fields <code>x</code>, <code>y</code>,
- * <code>disposalMethod</code> and <code>delayTime</code> are
- * typically only used when the image is in a set of images used
- * for animation.
- * </p>
- *
- * @see Image
- * @see ImageLoader
- * @see <a href="http://www.eclipse.org/swt/snippets/#image">ImageData snippets</a>
- * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ImageAnalyzer</a>
- * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
- */
- public final class ImageData : CloneableCompatibility {
- /**
- * The width of the image, in pixels.
- */
- public int width;
- /**
- * The height of the image, in pixels.
- */
- public int height;
- /**
- * The color depth of the image, in bits per pixel.
- * <p>
- * Note that a depth of 8 or less does not necessarily
- * mean that the image is palette indexed, or
- * conversely that a depth greater than 8 means that
- * the image is direct color. Check the associated
- * PaletteData's isDirect field for such determinations.
- */
- public int depth;
- /**
- * The scanline padding.
- * <p>
- * If one scanline of the image is not a multiple of
- * this number, it will be padded with zeros until it is.
- * </p>
- */
- public int scanlinePad;
- /**
- * The number of bytes per scanline.
- * <p>
- * This is a multiple of the scanline padding.
- * </p>
- */
- public int bytesPerLine;
- /**
- * The pixel data of the image.
- * <p>
- * Note that for 16 bit depth images the pixel data is stored
- * in least significant byte order; however, for 24bit and
- * 32bit depth images the pixel data is stored in most
- * significant byte order.
- * </p>
- */
- public byte[] data;
- /**
- * The color table for the image.
- */
- public PaletteData palette;
- /**
- * The transparent pixel.
- * <p>
- * Pixels with this value are transparent.
- * </p><p>
- * The default is -1 which means 'no transparent pixel'.
- * </p>
- */
- public int transparentPixel;
- /**
- * An icon-specific field containing the data from the icon mask.
- * <p>
- * This is a 1 bit bitmap stored with the most significant
- * bit first. The number of bytes per scanline is
- * '((width + 7) / 8 + (maskPad - 1)) / maskPad * maskPad'.
- * </p><p>
- * The default is null which means 'no transparency mask'.
- * </p>
- */
- public byte[] maskData;
- /**
- * An icon-specific field containing the scanline pad of the mask.
- * <p>
- * If one scanline of the transparency mask is not a
- * multiple of this number, it will be padded with zeros until
- * it is.
- * </p>
- */
- public int maskPad;
- /**
- * The alpha data of the image.
- * <p>
- * Every pixel can have an <em>alpha blending</em> value that
- * varies from 0, meaning fully transparent, to 255 meaning
- * fully opaque. The number of bytes per scanline is
- * 'width'.
- * </p>
- */
- public byte[] alphaData;
- /**
- * The global alpha value to be used for every pixel.
- * <p>
- * If this value is set, the <code>alphaData</code> field
- * is ignored and when the image is rendered each pixel
- * will be blended with the background an amount
- * proportional to this value.
- * </p><p>
- * The default is -1 which means 'no global alpha value'
- * </p>
- */
- public int alpha;
- /**
- * The type of file from which the image was read.
- *
- * It is expressed as one of the following values:
- * <dl>
- * <dt><code>IMAGE_BMP</code></dt>
- * <dd>Windows BMP file format, no compression</dd>
- * <dt><code>IMAGE_BMP_RLE</code></dt>
- * <dd>Windows BMP file format, RLE compression if appropriate</dd>
- * <dt><code>IMAGE_GIF</code></dt>
- * <dd>GIF file format</dd>
- * <dt><code>IMAGE_ICO</code></dt>
- * <dd>Windows ICO file format</dd>
- * <dt><code>IMAGE_JPEG</code></dt>
- * <dd>JPEG file format</dd>
- * <dt><code>IMAGE_PNG</code></dt>
- * <dd>PNG file format</dd>
- * </dl>
- */
- public int type;
- /**
- * The x coordinate of the top left corner of the image
- * within the logical screen (this field corresponds to
- * the GIF89a Image Left Position value).
- */
- public int x;
- /**
- * The y coordinate of the top left corner of the image
- * within the logical screen (this field corresponds to
- * the GIF89a Image Top Position value).
- */
- public int y;
- /**
- * A description of how to dispose of the current image
- * before displaying the next.
- *
- * It is expressed as one of the following values:
- * <dl>
- * <dt><code>DM_UNSPECIFIED</code></dt>
- * <dd>disposal method not specified</dd>
- * <dt><code>DM_FILL_NONE</code></dt>
- * <dd>do nothing - leave the image in place</dd>
- * <dt><code>DM_FILL_BACKGROUND</code></dt>
- * <dd>fill with the background color</dd>
- * <dt><code>DM_FILL_PREVIOUS</code></dt>
- * <dd>restore the previous picture</dd>
- * </dl>
- * (this field corresponds to the GIF89a Disposal Method value)
- */
- public int disposalMethod;
- /**
- * The time to delay before displaying the next image
- * in an animation (this field corresponds to the GIF89a
- * Delay Time value).
- */
- public int delayTime;
- /**
- * Arbitrary channel width data to 8-bit conversion table.
- */
- private static byte[][] _ANY_TO_EIGHT;
- static byte[][] ANY_TO_EIGHT ()
- {
- return _ANY_TO_EIGHT = _ANY_TO_EIGHT.length > 0 ? _ANY_TO_EIGHT : new byte[][](9);
- }
- static byte[] ONE_TO_ONE_MAPPING ()
- {
- if (_ONE_TO_ONE_MAPPING.length > 0)
- return _ONE_TO_ONE_MAPPING;
- for (int b = 0; b < 9; ++b) {
- byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b];
- if (b == 0) continue;
- int inc = 0;
- for (int bit = 0x10000; (bit >>= b) != 0;) inc |= bit;
- for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = cast(byte)(v >> 8);
- }
- _ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8];
- }
- private static byte[] _ONE_TO_ONE_MAPPING;
- /**
- * Scaled 8x8 Bayer dither matrix.
- */
- static const int[][] DITHER_MATRIX = [
- [ 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 ],
- [ 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 ],
- [ 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 ],
- [ 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 ],
- [ 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 ],
- [ 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 ],
- [ 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 ],
- [ 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 ]
- ];
- /**
- * Constructs a new, empty ImageData with the given width, height,
- * depth and palette. The data will be initialized to an (all zero)
- * array of the appropriate size.
- *
- * @param width the width of the image
- * @param height the height of the image
- * @param depth the depth of the image
- * @param palette the palette of the image (must not be null)
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if the width or height is zero or negative, or if the depth is not
- * one of 1, 2, 4, 8, 16, 24 or 32</li>
- * <li>ERROR_NULL_ARGUMENT - if the palette is null</li>
- * </ul>
- */
- public this(int width, int height, int depth, PaletteData palette) {
- this(width, height, depth, palette,
- 4, null, 0, null,
- null, -1, -1, DWT.IMAGE_UNDEFINED,
- 0, 0, 0, 0);
- }
- /**
- * Constructs a new, empty ImageData with the given width, height,
- * depth, palette, scanlinePad and data.
- *
- * @param width the width of the image
- * @param height the height of the image
- * @param depth the depth of the image
- * @param palette the palette of the image
- * @param scanlinePad the padding of each line, in bytes
- * @param data the data of the image
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if the width or height is zero or negative, or if the depth is not
- * one of 1, 2, 4, 8, 16, 24 or 32, or the data array is too small to contain the image data</li>
- * <li>ERROR_NULL_ARGUMENT - if the palette or data is null</li>
- * <li>ERROR_CANNOT_BE_ZERO - if the scanlinePad is zero</li>
- * </ul>
- */
- public this(int width, int height, int depth, PaletteData palette, int scanlinePad, byte[] data) {
- this(width, height, depth, palette,
- scanlinePad, checkData(data), 0, null,
- null, -1, -1, DWT.IMAGE_UNDEFINED,
- 0, 0, 0, 0);
- }
- /**
- * Constructs an <code>ImageData</code> loaded from the specified
- * input stream. Throws an error if an error occurs while loading
- * the image, or if the image has an unsupported type. Application
- * code is still responsible for closing the input stream.
- * <p>
- * This constructor is provided for convenience when loading a single
- * image only. If the stream contains multiple images, only the first
- * one will be loaded. To load multiple images, use
- * <code>ImageLoader.load()</code>.
- * </p><p>
- * This constructor may be used to load a resource as follows:
- * </p>
- * <pre>
- * static ImageData loadImageData (Class clazz, String string) {
- * InputStream stream = clazz.getResourceAsStream (string);
- * if (stream is null) return null;
- * ImageData imageData = null;
- * try {
- * imageData = new ImageData (stream);
- * } catch (DWTException ex) {
- * } finally {
- * try {
- * stream.close ();
- * } catch (IOException ex) {}
- * }
- * return imageData;
- * }
- * </pre>
- *
- * @param stream the input stream to load the image from (must not be null)
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_IO - if an IO error occurs while reading from the stream</li>
- * <li>ERROR_INVALID_IMAGE - if the image stream contains invalid data</li>
- * <li>ERROR_UNSUPPORTED_FORMAT - if the image stream contains an unrecognized format</li>
- * </ul>
- *
- * @see ImageLoader#load(InputStream)
- */
- public this(InputStream stream) {
- ImageData[] data = ImageDataLoader.load(stream);
- if (data.length < 1) DWT.error(DWT.ERROR_INVALID_IMAGE);
- ImageData i = data[0];
- setAllFields(
- i.width,
- i.height,
- i.depth,
- i.scanlinePad,
- i.bytesPerLine,
- i.data,
- i.palette,
- i.transparentPixel,
- i.maskData,
- i.maskPad,
- i.alphaData,
- i.alpha,
- i.type,
- i.x,
- i.y,
- i.disposalMethod,
- i.delayTime);
- }
- /**
- * Constructs an <code>ImageData</code> loaded from a file with the
- * specified name. Throws an error if an error occurs loading the
- * image, or if the image has an unsupported type.
- * <p>
- * This constructor is provided for convenience when loading a single
- * image only. If the file contains multiple images, only the first
- * one will be loaded. To load multiple images, use
- * <code>ImageLoader.load()</code>.
- * </p>
- *
- * @param filename the name of the file to load the image from (must not be null)
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_IO - if an IO error occurs while reading from the file</li>
- * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
- * <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
- * </ul>
- */
- public this(String filename) {
- ImageData[] data = ImageDataLoader.load(filename);
- if (data.length < 1) DWT.error(DWT.ERROR_INVALID_IMAGE);
- ImageData i = data[0];
- setAllFields(
- i.width,
- i.height,
- i.depth,
- i.scanlinePad,
- i.bytesPerLine,
- i.data,
- i.palette,
- i.transparentPixel,
- i.maskData,
- i.maskPad,
- i.alphaData,
- i.alpha,
- i.type,
- i.x,
- i.y,
- i.disposalMethod,
- i.delayTime);
- }
- /**
- * Prevents uninitialized instances from being created outside the package.
- */
- private this() {
- }
- /**
- * Constructs an image data by giving values for all non-computable fields.
- * <p>
- * This method is for internal use, and is not described further.
- * </p>
- */
- this(
- int width, int height, int depth, PaletteData palette,
- int scanlinePad, byte[] data, int maskPad, byte[] maskData,
- byte[] alphaData, int alpha, int transparentPixel, int type,
- int x, int y, int disposalMethod, int delayTime)
- {
- if (palette is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
- if (!(depth is 1 || depth is 2 || depth is 4 || depth is 8
- || depth is 16 || depth is 24 || depth is 32)) {
- DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- }
- if (width <= 0 || height <= 0) {
- DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- }
- if (scanlinePad is 0) DWT.error (DWT.ERROR_CANNOT_BE_ZERO);
- int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1))
- / scanlinePad * scanlinePad;
- /*
- * When the image is being loaded from a PNG, we need to use the theoretical minimum
- * number of bytes per line to check whether there is enough data, because the actual
- * number of bytes per line is calculated based on the given depth, which may be larger
- * than the actual depth of the PNG.
- */
- int minBytesPerLine = type is DWT.IMAGE_PNG ? ((((width + 7) / 8) + 3) / 4) * 4 : bytesPerLine;
- if (data !is null && data.length < minBytesPerLine * height) {
- DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- }
- setAllFields(
- width,
- height,
- depth,
- scanlinePad,
- bytesPerLine,
- data !is null ? data : new byte[bytesPerLine * height],
- palette,
- transparentPixel,
- maskData,
- maskPad,
- alphaData,
- alpha,
- type,
- x,
- y,
- disposalMethod,
- delayTime);
- }
- /**
- * Initializes all fields in the receiver. This method must be called
- * by all public constructors to ensure that all fields are initialized
- * for a new ImageData object. If a new field is added to the class,
- * then it must be added to this method.
- * <p>
- * This method is for internal use, and is not described further.
- * </p>
- */
- void setAllFields(int width, int height, int depth, int scanlinePad,
- int bytesPerLine, byte[] data, PaletteData palette, int transparentPixel,
- byte[] maskData, int maskPad, byte[] alphaData, int alpha,
- int type, int x, int y, int disposalMethod, int delayTime) {
- this.width = width;
- this.height = height;
- this.depth = depth;
- this.scanlinePad = scanlinePad;
- this.bytesPerLine = bytesPerLine;
- this.data = data;
- this.palette = palette;
- this.transparentPixel = transparentPixel;
- this.maskData = maskData;
- this.maskPad = maskPad;
- this.alphaData = alphaData;
- this.alpha = alpha;
- this.type = type;
- this.x = x;
- this.y = y;
- this.disposalMethod = disposalMethod;
- this.delayTime = delayTime;
- }
- /**
- * Invokes internal DWT functionality to create a new instance of
- * this class.
- * <p>
- * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
- * API for <code>ImageData</code>. It is marked public only so that it
- * can be shared within the packages provided by DWT. It is subject
- * to change without notice, and should never be called from
- * application code.
- * </p>
- * <p>
- * This method is for internal use, and is not described further.
- * </p>
- */
- public static ImageData internal_new(
- int width, int height, int depth, PaletteData palette,
- int scanlinePad, byte[] data, int maskPad, byte[] maskData,
- byte[] alphaData, int alpha, int transparentPixel, int type,
- int x, int y, int disposalMethod, int delayTime)
- {
- return new ImageData(
- width, height, depth, palette, scanlinePad, data, maskPad, maskData,
- alphaData, alpha, transparentPixel, type, x, y, disposalMethod, delayTime);
- }
- ImageData colorMaskImage(int pixel) {
- ImageData mask = new ImageData(width, height, 1, bwPalette(),
- 2, null, 0, null, null, -1, -1, DWT.IMAGE_UNDEFINED,
- 0, 0, 0, 0);
- int[] row = new int[width];
- for (int y = 0; y < height; y++) {
- getPixels(0, y, width, row, 0);
- for (int i = 0; i < width; i++) {
- if (pixel !is -1 && row[i] is pixel) {
- row[i] = 0;
- } else {
- row[i] = 1;
- }
- }
- mask.setPixels(0, y, width, row, 0);
- }
- return mask;
- }
- static byte[] checkData(byte [] data) {
- if (data is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
- return data;
- }
- /**
- * Returns a new instance of the same class as the receiver,
- * whose slots have been filled in with <em>copies</em> of
- * the values in the slots of the receiver. That is, the
- * returned object is a <em>deep copy</em> of the receiver.
- *
- * @return a copy of the receiver.
- */
- public Object clone() {
- byte[] cloneData = new byte[data.length];
- System.arraycopy(data, 0, cloneData, 0, data.length);
- byte[] cloneMaskData = null;
- if (maskData !is null) {
- cloneMaskData = new byte[maskData.length];
- System.arraycopy(maskData, 0, cloneMaskData, 0, maskData.length);
- }
- byte[] cloneAlphaData = null;
- if (alphaData !is null) {
- cloneAlphaData = new byte[alphaData.length];
- System.arraycopy(alphaData, 0, cloneAlphaData, 0, alphaData.length);
- }
- return new ImageData(
- width,
- height,
- depth,
- palette,
- scanlinePad,
- cloneData,
- maskPad,
- cloneMaskData,
- cloneAlphaData,
- alpha,
- transparentPixel,
- type,
- x,
- y,
- disposalMethod,
- delayTime);
- }
- /**
- * Returns the alpha value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's alpha data.
- * The alpha value is between 0 (transparent) and
- * 255 (opaque).
- *
- * @param x the x coordinate of the pixel to get the alpha value of
- * @param y the y coordinate of the pixel to get the alpha value of
- * @return the alpha value at the given coordinates
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if either argument is out of range</li>
- * </ul>
- */
- public int getAlpha(int x, int y) {
- if (x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- if (alphaData is null) return 255;
- return alphaData[y * width + x] & 0xFF;
- }
- /**
- * Returns <code>getWidth</code> alpha values starting at offset
- * <code>x</code> in scanline <code>y</code> in the receiver's alpha
- * data starting at <code>startIndex</code>. The alpha values
- * are unsigned, between <code>(byte)0</code> (transparent) and
- * <code>(byte)255</code> (opaque).
- *
- * @param x the x position of the pixel to begin getting alpha values
- * @param y the y position of the pixel to begin getting alpha values
- * @param getWidth the width of the data to get
- * @param alphas the buffer in which to put the alpha values
- * @param startIndex the offset into the image to begin getting alpha values
- *
- * @exception IndexOutOfBoundsException if getWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
- * </ul>
- */
- public void getAlphas(int x, int y, int getWidth, byte[] alphas, int startIndex) {
- if (alphas is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
- if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- if (getWidth is 0) return;
- if (alphaData is null) {
- int endIndex = startIndex + getWidth;
- for (int i = startIndex; i < endIndex; i++) {
- alphas[i] = cast(byte)255;
- }
- return;
- }
- // may throw an IndexOutOfBoundsException
- System.arraycopy(alphaData, y * width + x, alphas, startIndex, getWidth);
- }
- /**
- * Returns the pixel value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data.
- *
- * @param x the x position of the pixel to get
- * @param y the y position of the pixel to get
- * @return the pixel at the given coordinates
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if either argument is out of bounds</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
- public int getPixel(int x, int y) {
- if (x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- int index;
- int theByte;
- int mask;
- switch (depth) {
- case 32:
- index = (y * bytesPerLine) + (x * 4);
- return ((data[index] & 0xFF) << 24) + ((data[index+1] & 0xFF) << 16) +
- ((data[index+2] & 0xFF) << 8) + (data[index+3] & 0xFF);
- case 24:
- index = (y * bytesPerLine) + (x * 3);
- return ((data[index] & 0xFF) << 16) + ((data[index+1] & 0xFF) << 8) +
- (data[index+2] & 0xFF);
- case 16:
- index = (y * bytesPerLine) + (x * 2);
- return ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF);
- case 8:
- index = (y * bytesPerLine) + x ;
- return data[index] & 0xFF;
- case 4:
- index = (y * bytesPerLine) + (x >> 1);
- theByte = data[index] & 0xFF;
- if ((x & 0x1) is 0) {
- return theByte >> 4;
- } else {
- return theByte & 0x0F;
- }
- case 2:
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index] & 0xFF;
- int offset = 3 - (x % 4);
- mask = 3 << (offset * 2);
- return (theByte & mask) >> (offset * 2);
- case 1:
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index] & 0xFF;
- mask = 1 << (7 - (x & 0x7));
- if ((theByte & mask) is 0) {
- return 0;
- } else {
- return 1;
- }
- default:
- }
- DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH);
- return 0;
- }
- /**
- * Returns <code>getWidth</code> pixel values starting at offset
- * <code>x</code> in scanline <code>y</code> in the receiver's
- * data starting at <code>startIndex</code>.
- *
- * @param x the x position of the first pixel to get
- * @param y the y position of the first pixel to get
- * @param getWidth the width of the data to get
- * @param pixels the buffer in which to put the pixels
- * @param startIndex the offset into the byte array to begin storing pixels
- *
- * @exception IndexOutOfBoundsException if getWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4 or 8
- * (For higher depths, use the int[] version of this method.)</li>
- * </ul>
- */
- public void getPixels(int x, int y, int getWidth, byte[] pixels, int startIndex) {
- if (pixels is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
- if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- if (getWidth is 0) return;
- int index;
- int theByte;
- int mask = 0;
- int n = getWidth;
- int i = startIndex;
- int srcX = x, srcY = y;
- switch (depth) {
- case 8:
- index = (y * bytesPerLine) + x;
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = data[index];
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- return;
- case 4:
- index = (y * bytesPerLine) + (x >> 1);
- if ((x & 0x1) is 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = cast(byte)(theByte & 0x0F);
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- while (n > 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = cast(byte)(theByte >> 4);
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- pixels[i] = cast(byte)(theByte & 0x0F);
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- }
- if (n > 0) {
- theByte = data[index] & 0xFF;
- pixels[i] = cast(byte)(theByte >> 4);
- }
- return;
- case 2:
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index] & 0xFF;
- int offset;
- while (n > 0) {
- offset = 3 - (srcX % 4);
- mask = 3 << (offset * 2);
- pixels[i] = cast(byte)((theByte & mask) >> (offset * 2));
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (offset is 0) {
- index++;
- theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- case 1:
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index] & 0xFF;
- while (n > 0) {
- mask = 1 << (7 - (srcX & 0x7));
- if ((theByte & mask) is 0) {
- pixels[i] = 0;
- } else {
- pixels[i] = 1;
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (mask is 1) {
- index++;
- if (n > 0) theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- default:
- }
- DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH);
- }
- /**
- * Returns <code>getWidth</code> pixel values starting at offset
- * <code>x</code> in scanline <code>y</code> in the receiver's
- * data starting at <code>startIndex</code>.
- *
- * @param x the x position of the first pixel to get
- * @param y the y position of the first pixel to get
- * @param getWidth the width of the data to get
- * @param pixels the buffer in which to put the pixels
- * @param startIndex the offset into the buffer to begin storing pixels
- *
- * @exception IndexOutOfBoundsException if getWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
- public void getPixels(int x, int y, int getWidth, int[] pixels, int startIndex) {
- if (pixels is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
- if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- if (getWidth is 0) return;
- int index;
- int theByte;
- int mask;
- int n = getWidth;
- int i = startIndex;
- int srcX = x, srcY = y;
- switch (depth) {
- case 32:
- index = (y * bytesPerLine) + (x * 4);
- i = startIndex;
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = ((data[index] & 0xFF) << 24) | ((data[index+1] & 0xFF) << 16)
- | ((data[index+2] & 0xFF) << 8) | (data[index+3] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 4;
- }
- }
- return;
- case 24:
- index = (y * bytesPerLine) + (x * 3);
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = ((data[index] & 0xFF) << 16) | ((data[index+1] & 0xFF) << 8)
- | (data[index+2] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 3;
- }
- }
- return;
- case 16:
- index = (y * bytesPerLine) + (x * 2);
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 2;
- }
- }
- return;
- case 8:
- index = (y * bytesPerLine) + x;
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = data[index] & 0xFF;
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- return;
- case 4:
- index = (y * bytesPerLine) + (x >> 1);
- if ((x & 0x1) is 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = theByte & 0x0F;
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- while (n > 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = theByte >> 4;
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- pixels[i] = theByte & 0x0F;
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- }
- if (n > 0) {
- theByte = data[index] & 0xFF;
- pixels[i] = theByte >> 4;
- }
- return;
- case 2:
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index] & 0xFF;
- int offset;
- while (n > 0) {
- offset = 3 - (srcX % 4);
- mask = 3 << (offset * 2);
- pixels[i] = cast(byte)((theByte & mask) >> (offset * 2));
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (offset is 0) {
- index++;
- theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- case 1:
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index] & 0xFF;
- while (n > 0) {
- mask = 1 << (7 - (srcX & 0x7));
- if ((theByte & mask) is 0) {
- pixels[i] = 0;
- } else {
- pixels[i] = 1;
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (mask is 1) {
- index++;
- if (n > 0) theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- default:
- }
- DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH);
- }
- /**
- * Returns an array of <code>RGB</code>s which comprise the
- * indexed color table of the receiver, or null if the receiver
- * has a direct color model.
- *
- * @return the RGB values for the image or null if direct color
- *
- * @see PaletteData#getRGBs()
- */
- public RGB[] getRGBs() {
- return palette.getRGBs();
- }
- /**
- * Returns an <code>ImageData</code> which specifies the
- * transparency mask information for the receiver. If the
- * receiver has no transparency or is not an icon, returns
- * an opaque mask.
- *
- * @return the transparency mask
- */
- public ImageData getTransparencyMask() {
- if (getTransparencyType() is DWT.TRANSPARENCY_MASK) {
- return new ImageData(width, height, 1, bwPalette(), maskPad, maskData);
- } else {
- return colorMaskImage(transparentPixel);
- }
- }
- /**
- * Returns the image transparency type, which will be one of
- * <code>DWT.TRANSPARENCY_NONE</code>, <code>DWT.TRANSPARENCY_MASK</code>,
- * <code>DWT.TRANSPARENCY_PIXEL</code> or <code>DWT.TRANSPARENCY_ALPHA</code>.
- *
- * @return the receiver's transparency type
- */
- public int getTransparencyType() {
- if (maskData !is null) return DWT.TRANSPARENCY_MASK;
- if (transparentPixel !is -1) return DWT.TRANSPARENCY_PIXEL;
- if (alphaData !is null) return DWT.TRANSPARENCY_ALPHA;
- return DWT.TRANSPARENCY_NONE;
- }
- /**
- * Returns the byte order of the receiver.
- *
- * @return MSB_FIRST or LSB_FIRST
- */
- int getByteOrder() {
- return depth !is 16 ? MSB_FIRST : LSB_FIRST;
- }
- /**
- * Returns a copy of the receiver which has been stretched or
- * shrunk to the specified size. If either the width or height
- * is negative, the resulting image will be inverted in the
- * associated axis.
- *
- * @param width the width of the new ImageData
- * @param height the height of the new ImageData
- * @return a scaled copy of the image
- */
- public ImageData scaledTo(int width, int height) {
- /* Create a destination image with no data */
- bool flipX = (width < 0);
- if (flipX) width = - width;
- bool flipY = (height < 0);
- if (flipY) height = - height;
- ImageData dest = new ImageData(
- width, height, depth, palette,
- scanlinePad, null, 0, null,
- null, -1, transparentPixel, type,
- x, y, disposalMethod, delayTime);
- /* Scale the image contents */
- if (palette.isDirect) blit(BLIT_SRC,
- this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, 0, 0, 0,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, 0, 0, 0,
- flipX, flipY);
- else blit(BLIT_SRC,
- this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, null, null, null,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, null, null, null,
- flipX, flipY);
- /* Scale the image mask or alpha */
- if (maskData !is null) {
- dest.maskPad = this.maskPad;
- int destBpl = (dest.width + 7) / 8;
- destBpl = (destBpl + (dest.maskPad - 1)) / dest.maskPad * dest.maskPad;
- dest.maskData = new byte[destBpl * dest.height];
- int srcBpl = (this.width + 7) / 8;
- srcBpl = (srcBpl + (this.maskPad - 1)) / this.maskPad * this.maskPad;
- blit(BLIT_SRC,
- this.maskData, 1, srcBpl, MSB_FIRST, 0, 0, this.width, this.height, null, null, null,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.maskData, 1, destBpl, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null,
- flipX, flipY);
- } else if (alpha !is -1) {
- dest.alpha = this.alpha;
- } else if (alphaData !is null) {
- dest.alphaData = new byte[dest.width * dest.height];
- blit(BLIT_SRC,
- this.alphaData, 8, this.width, MSB_FIRST, 0, 0, this.width, this.height, null, null, null,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.alphaData, 8, dest.width, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null,
- flipX, flipY);
- }
- return dest;
- }
- /**
- * Sets the alpha value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's alpha data.
- * The alpha value must be between 0 (transparent)
- * and 255 (opaque).
- *
- * @param x the x coordinate of the alpha value to set
- * @param y the y coordinate of the alpha value to set
- * @param alpha the value to set the alpha to
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * </ul>
- */
- public void setAlpha(int x, int y, int alpha) {
- if (x >= width || y >= height || x < 0 || y < 0 || alpha < 0 || alpha > 255)
- DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- if (alphaData is null) alphaData = new byte[width * height];
- alphaData[y * width + x] = cast(byte)alpha;
- }
- /**
- * Sets the alpha values starting at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's alpha data to the
- * values from the array <code>alphas</code> starting at
- * <code>startIndex</code>. The alpha values must be between
- * <code>(byte)0</code> (transparent) and <code>(byte)255</code> (opaque)
- *
- * @param x the x coordinate of the pixel to being setting the alpha values
- * @param y the y coordinate of the pixel to being setting the alpha values
- * @param putWidth the width of the alpha values to set
- * @param alphas the alpha values to set
- * @param startIndex the index at which to begin setting
- *
- * @exception IndexOutOfBoundsException if putWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
- * </ul>
- */
- public void setAlphas(int x, int y, int putWidth, byte[] alphas, int startIndex) {
- if (alphas is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
- if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- if (putWidth is 0) return;
- if (alphaData is null) alphaData = new byte[width * height];
- // may throw an IndexOutOfBoundsException
- System.arraycopy(alphas, startIndex, alphaData, y * width + x, putWidth);
- }
- /**
- * Sets the pixel value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data.
- *
- * @param x the x coordinate of the pixel to set
- * @param y the y coordinate of the pixel to set
- * @param pixelValue the value to set the pixel to
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
- public void setPixel(int x, int y, int pixelValue) {
- if (x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- int index;
- byte theByte;
- int mask;
- switch (depth) {
- case 32:
- index = (y * bytesPerLine) + (x * 4);
- data[index] = cast(byte)((pixelValue >> 24) & 0xFF);
- data[index + 1] = cast(byte)((pixelValue >> 16) & 0xFF);
- data[index + 2] = cast(byte)((pixelValue >> 8) & 0xFF);
- data[index + 3] = cast(byte)(pixelValue & 0xFF);
- return;
- case 24:
- index = (y * bytesPerLine) + (x * 3);
- data[index] = cast(byte)((pixelValue >> 16) & 0xFF);
- data[index + 1] = cast(byte)((pixelValue >> 8) & 0xFF);
- data[index + 2] = cast(byte)(pixelValue & 0xFF);
- return;
- case 16:
- index = (y * bytesPerLine) + (x * 2);
- data[index + 1] = cast(byte)((pixelValue >> 8) & 0xFF);
- data[index] = cast(byte)(pixelValue & 0xFF);
- return;
- case 8:
- index = (y * bytesPerLine) + x ;
- data[index] = cast(byte)(pixelValue & 0xFF);
- return;
- case 4:
- index = (y * bytesPerLine) + (x >> 1);
- if ((x & 0x1) is 0) {
- data[index] = cast(byte)((data[index] & 0x0F) | ((pixelValue & 0x0F) << 4));
- } else {
- data[index] = cast(byte)((data[index] & 0xF0) | (pixelValue & 0x0F));
- }
- return;
- case 2:
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index];
- int offset = 3 - (x % 4);
- mask = 0xFF ^ (3 << (offset * 2));
- data[index] = cast(byte)((data[index] & mask) | (pixelValue << (offset * 2)));
- return;
- case 1:
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index];
- mask = 1 << (7 - (x & 0x7));
- if ((pixelValue & 0x1) is 1) {
- data[index] = cast(byte)(theByte | mask);
- } else {
- data[index] = cast(byte)(theByte & (mask ^ -1));
- }
- return;
- default:
- }
- DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH);
- }
- /**
- * Sets the pixel values starting at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data to the
- * values from the array <code>pixels</code> starting at
- * <code>startIndex</code>.
- *
- * @param x the x position of the pixel to set
- * @param y the y position of the pixel to set
- * @param putWidth the width of the pixels to set
- * @param pixels the pixels to set
- * @param startIndex the index at which to begin setting
- *
- * @exception IndexOutOfBoundsException if putWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8
- * (For higher depths, use the int[] version of this method.)</li>
- * </ul>
- */
- public void setPixels(int x, int y, int putWidth, byte[] pixels, int startIndex) {
- if (pixels is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
- if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
- if (putWidth is 0) return;
- int index;
- int theByte;
- int mask;
- int n = putWidth;
- int i = startIndex;
- int srcX = x, srcY = y;
- switch (depth) {
- case 8:
- index = (y * bytesPerLine) + x;
- for (int j = 0; j < putWidth; j++) {
- data[index] = cast(byte)(pixels[i] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- return;
- case 4:
- index = (y * bytesPerLine) + (x >> 1);
- bool high = (x & 0x1) is 0;
- while (n > 0) {
- theByte = pixels[i] & 0x0F;
- if (high) {
- data[index] = cast(byte)((data[index] & 0x0F) | (theByte << 4));
- } else {
- data[index] = cast(byte)((data[index] & 0xF0) | theByte);
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- high = true;
- srcX = 0;
- } else {
- if (!high) index++;
- high = !high;
- }
- }
- return;
- case 2:
- byte [] masks = [ cast(byte)0xFC, cast(byte)0xF3, cast(byte)0xCF, cast(byte)0x3F ];
- index = (y * bytesPerLine) + (x >> 2);
- int offset = 3 - (x % 4);
- while (n > 0) {
- theByte = pixels[i] & 0x3;
- data[index] = cast(byte)((data[index] & masks[offset]) | (theByte << (offset * 2)));
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- offset = 0;
- srcX = 0;
- } else {
- if (offset is 0) {
- index++;
- offset = 3;
- } else {
- offset--;
- }
- }
- }
- return;
- case 1:
- index = (y * bytesPerLine) + (x >> 3);
- while (n > 0) {
- mask = 1 << (7 - (srcX & 0x7));
- if ((pixels[i] & 0x1) is 1) {
- data[index] = cast(byte)((data[index] & 0xFF) | mask);
- } else {
- data[index] = cast(byte)((data[index] & 0xFF) & (mask ^ -1));
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- if (mask is 1) {
- index++;
- }
- }
- }
- return;
- default:
- }
- DWT.error(DWT.ERROR_UNSUPPORTED_DEPTH);
- }
- /**
- * Sets the pixel values starting at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data to the
- * values from the array <code>pixels</code> starting at
- * <code>startIndex</code>.
- *
- * @param x the x position of the pixel to set
- * @param y the y position of the pixel to set
- * @param putWidth the width of the pixels to set
- * @param pixels the pixels to set
- * @param startIndex the index at which to begin setting
- *
- * @exception IndexOutOfBoundsException if putWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
- * </ul>
- * @exception DWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 3…
Large files files are truncated, but you can click here to view the full file