Checkpoint commit to getting the png recolor code into nenya. This still needs testing and such.
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@934 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
//
|
||||
// Nenya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/nenya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.media.image {
|
||||
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.Map;
|
||||
import com.threerings.util.Maps;
|
||||
import com.threerings.util.RandomUtil;
|
||||
import com.threerings.util.StringUtil;
|
||||
|
||||
public class ClassRecord
|
||||
{
|
||||
private const log :Log = Log.getLog(ClassRecord);
|
||||
|
||||
/** An integer identifier for this class. */
|
||||
public var classId :int;
|
||||
|
||||
/** The name of the color class. */
|
||||
public var name :String;
|
||||
|
||||
/** The source color to use when recoloring colors in this class. */
|
||||
public var source :uint;
|
||||
|
||||
/** Data identifying the range of colors around the source color
|
||||
* that will be recolored when recoloring using this class. */
|
||||
public var range :Array;
|
||||
|
||||
/** The default starting legality value for this color class. See
|
||||
* {@link ColorRecord#starter}. */
|
||||
public var starter :Boolean;
|
||||
|
||||
/** The default colorId to use for recoloration in this class, or
|
||||
* 0 if there is no default defined. */
|
||||
public var defaultId :int;
|
||||
|
||||
/** A table of target colors included in this class. */
|
||||
public var colors :Map = Maps.newMapOf(int);
|
||||
|
||||
/** Used when parsing the color definitions. */
|
||||
public function addColor (record :ColorRecord) :void
|
||||
{
|
||||
// validate the color id
|
||||
if (record.colorId > 127) {
|
||||
log.warning("Refusing to add color record; colorId > 127",
|
||||
"class", this, "record", record);
|
||||
} else if (colors.containsKey(record.colorId)) {
|
||||
log.warning("Refusing to add duplicate colorId",
|
||||
"class", this, "record", record, "existing", colors.get(record.colorId));
|
||||
} else {
|
||||
record.cclass = this;
|
||||
colors.put(record.colorId, record);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a color identified in string form into the id that should be used to look up
|
||||
* its information. Throws an exception if no color could be found that associates with
|
||||
* that name.
|
||||
*/
|
||||
public function getColorId (name :String) :int
|
||||
{
|
||||
// Check if the string is itself a number
|
||||
var id :int = name as int;
|
||||
if (colors.containsKey(id)) {
|
||||
return id;
|
||||
}
|
||||
|
||||
// Look for name matches among all colors
|
||||
for each (var color :ColorRecord in colors) {
|
||||
if (StringUtil.compareIgnoreCase(color.name, name) == 0) {
|
||||
return color.colorId;
|
||||
}
|
||||
}
|
||||
|
||||
// That input wasn't a color
|
||||
throw new Error("No color named '" + name + "'", 0);
|
||||
}
|
||||
|
||||
/** Returns a random starting id from the entries in this class. */
|
||||
public function randomStartingColor () :ColorRecord
|
||||
{
|
||||
// figure out our starter ids if we haven't already
|
||||
if (_starters == null) {
|
||||
_starters = [];
|
||||
for each (var color :ColorRecord in colors) {
|
||||
if (color.starter) {
|
||||
_starters.push(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if (_starters.length < 1) {
|
||||
log.warning("Requested random starting color from colorless component class",
|
||||
"class", this);
|
||||
return null;
|
||||
}
|
||||
|
||||
// return a random entry from the array
|
||||
return RandomUtil.pickRandom(_starters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default ColorRecord defined for this color class, or
|
||||
* null if none.
|
||||
*/
|
||||
public function getDefault () :ColorRecord
|
||||
{
|
||||
return colors.get(defaultId);
|
||||
}
|
||||
|
||||
public function toString () :String
|
||||
{
|
||||
return "[id=" + classId + ", name=" + name + ", source=#" +
|
||||
StringUtil.toHex(source & 0xFFFFFF, 6) +
|
||||
", range=" + StringUtil.toString(range) +
|
||||
", starter=" + starter + ", colors=" +
|
||||
StringUtil.toString(colors.values()) + "]";
|
||||
}
|
||||
|
||||
public static function fromXml (xml :XML) :ClassRecord
|
||||
{
|
||||
var rec :ClassRecord = new ClassRecord();
|
||||
for each (var colorXml :XML in xml.color) {
|
||||
rec.colors.put(colorXml.@colorId, ColorRecord.fromXml(colorXml));
|
||||
}
|
||||
|
||||
rec.name = xml.@name;
|
||||
var srcStr :String = xml.@source;
|
||||
rec.source = parseInt(srcStr.substring(1, srcStr.length - 1), 16);
|
||||
rec.range = toNumArray(xml.@range);
|
||||
rec.defaultId = xml.@defaultId;
|
||||
|
||||
return rec;
|
||||
}
|
||||
|
||||
protected static function toNumArray (str :String) :Array
|
||||
{
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return str.split(",").map(function(element :*, index :int, arr :Array) :int {
|
||||
return Number(element);
|
||||
});
|
||||
}
|
||||
|
||||
protected var _starters :Array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
//
|
||||
// Nenya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/nenya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.media.image {
|
||||
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.Map;
|
||||
import com.threerings.util.Maps;
|
||||
|
||||
public class ColorPository
|
||||
{
|
||||
private const log :Log = Log.getLog(ColorPository);
|
||||
|
||||
public function getClasses () :Array
|
||||
{
|
||||
return _classes.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the records for the colors in the
|
||||
* specified class.
|
||||
*/
|
||||
public function getColors (className :String) :Array
|
||||
{
|
||||
// make sure the class exists
|
||||
var record :ClassRecord = getClassRecordByName(className);
|
||||
if (record == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// create the array
|
||||
return record.colors.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the ids of the colors in the specified
|
||||
* class.
|
||||
*/
|
||||
public function getColorIds (className :String) :Array
|
||||
{
|
||||
// make sure the class exists
|
||||
var record :ClassRecord = getClassRecordByName(className);
|
||||
if (record == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return record.colors.values().map(
|
||||
function(element :ColorRecord, index :int, arr :Array) :int {
|
||||
return element.colorId;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified color is legal for use at character creation time. false is
|
||||
* always returned for non-existent colors or classes.
|
||||
*/
|
||||
public function isLegalStartColor (classId :int, colorId :int) :Boolean
|
||||
{
|
||||
var color :ColorRecord = getColorRecord(classId, colorId);
|
||||
return (color == null) ? false : color.starter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random starting color from the specified color class.
|
||||
*/
|
||||
public function getRandomStartingColor (className :String) :ColorRecord
|
||||
{
|
||||
// make sure the class exists
|
||||
var record :ClassRecord = getClassRecordByName(className);
|
||||
return (record == null) ? null : record.randomStartingColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a colorization by id.
|
||||
*/
|
||||
public function getColorization (classId :int, colorId :int) :Colorization
|
||||
{
|
||||
var color :ColorRecord = getColorRecord(classId, colorId);
|
||||
return (color == null) ? null : color.getColorization();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a colorization by color print.
|
||||
*/
|
||||
public function getColorizationByPrint (colorPrint :int) :Colorization
|
||||
{
|
||||
return getColorization(colorPrint >> 8, colorPrint & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a colorization by class and color names.
|
||||
*/
|
||||
public function getColorizationByName (className :String, colorName :String) :Colorization
|
||||
{
|
||||
var crec :ClassRecord = getClassRecordByName(className);
|
||||
if (crec != null) {
|
||||
var colorId :int = crec.getColorId(colorName);
|
||||
|
||||
var color :ColorRecord = crec.colors.get(colorId);
|
||||
if (color != null) {
|
||||
return color.getColorization();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads up a colorization class by name and logs a warning if it doesn't exist.
|
||||
*/
|
||||
public function getClassRecordByName (className :String) :ClassRecord
|
||||
{
|
||||
for each (var crec :ClassRecord in _classes) {
|
||||
if (crec.name == className) {
|
||||
return crec;
|
||||
}
|
||||
}
|
||||
log.warning("No such color class", "class", className, new Error());
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the requested color class record.
|
||||
*/
|
||||
public function getClassRecord (classId :int) :ClassRecord
|
||||
{
|
||||
return _classes.get(classId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the requested color record.
|
||||
*/
|
||||
public function getColorRecord (classId :int, colorId :int) :ColorRecord
|
||||
{
|
||||
var record :ClassRecord = getClassRecord(classId);
|
||||
if (record == null) {
|
||||
// if they request color class zero, we assume they're just
|
||||
// decoding a blank colorprint, otherwise we complain
|
||||
if (classId != 0) {
|
||||
log.warning("Requested unknown color class",
|
||||
"classId", classId, "colorId", colorId, new Error());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return record.colors.get(colorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the requested color record by class & color names.
|
||||
*/
|
||||
public function getColorRecordByName (className :String, colorName :String) :ColorRecord
|
||||
{
|
||||
var record :ClassRecord = getClassRecordByName(className);
|
||||
if (record == null) {
|
||||
log.warning("Requested unknown color class",
|
||||
"className", className, "colorName", colorName, new Error());
|
||||
return null;
|
||||
}
|
||||
|
||||
var colorId :int = record.getColorId(colorName);
|
||||
|
||||
return record.colors.get(colorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads up a serialized color pository from the supplied resource
|
||||
* manager.
|
||||
*/
|
||||
public static function fromXml (xml :XML) :ColorPository
|
||||
{
|
||||
var pos :ColorPository = new ColorPository();
|
||||
for each (var classXml :XML in xml.elements("class")) {
|
||||
pos._classes.put(classXml.@classId, ClassRecord.fromXml(classXml));
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/** Our mapping from class names to class records. */
|
||||
protected var _classes :Map = Maps.newMapOf(int);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// Nenya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/nenya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.media.image {
|
||||
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.StringUtil;
|
||||
|
||||
public class ColorRecord
|
||||
{
|
||||
private const log :Log = Log.getLog(ColorRecord);
|
||||
|
||||
/** The colorization class to which we belong. */
|
||||
public var cclass :ClassRecord;
|
||||
|
||||
/** A unique colorization identifier (used in fingerprints). */
|
||||
public var colorId :int;
|
||||
|
||||
/** The name of the target color. */
|
||||
public var name :String;
|
||||
|
||||
/** Data indicating the offset (in HSV color space) from the
|
||||
* source color to recolor to this color. */
|
||||
public var offsets :Array;
|
||||
|
||||
/** Tags this color as a legal starting color or not. This is a
|
||||
* shameful copout, placing application-specific functionality
|
||||
* into a general purpose library class. */
|
||||
public var starter :Boolean;
|
||||
|
||||
/**
|
||||
* Returns a value that is the composite of our class id and color
|
||||
* id which can be used to identify a colorization record. This
|
||||
* value will always be a positive integer that fits into 16 bits.
|
||||
*/
|
||||
public function getColorPrint () :int
|
||||
{
|
||||
return ((cclass.classId << 8) | colorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data in this record configured as a colorization
|
||||
* instance.
|
||||
*/
|
||||
public function getColorization () :Colorization
|
||||
{
|
||||
return new Colorization(getColorPrint(), cclass.source,
|
||||
cclass.range, offsets);
|
||||
}
|
||||
|
||||
public function toString () :String
|
||||
{
|
||||
return "[id=" + colorId + ", name=" + name +
|
||||
", offsets=" + StringUtil.toString(offsets) +
|
||||
", starter=" + starter + "]";
|
||||
}
|
||||
|
||||
|
||||
public static function fromXml (xml :XML) :ColorRecord
|
||||
{
|
||||
var rec :ColorRecord = new ColorRecord();
|
||||
rec.colorId = xml.@colorId;
|
||||
rec.name = xml.@name;
|
||||
rec.offsets = toNumArray(xml.@offsets);
|
||||
rec.starter = xml.@starter;
|
||||
|
||||
return rec;
|
||||
}
|
||||
|
||||
protected static function toNumArray (str :String) :Array
|
||||
{
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return str.split(",").map(function(element :*, index :int, arr :Array) :int {
|
||||
return Number(element);
|
||||
});
|
||||
}
|
||||
|
||||
/** Our data represented as a colorization. */
|
||||
protected var _zation :Colorization;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
//
|
||||
// aspirin library - Taking some of the pain out of Actionscript development.
|
||||
// Copyright (C) 2007-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/nenya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.media.image {
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
import com.threerings.display.ColorUtil;
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.StringUtil;
|
||||
|
||||
import com.threerings.util.F;
|
||||
public class PngRecolorUtil
|
||||
{
|
||||
private static const log :Log = Log.getLog(PngRecolorUtil);
|
||||
|
||||
protected static function isPng (bytes :ByteArray) :Boolean
|
||||
{
|
||||
if (bytes.length < PNG_HEADER.length) {
|
||||
return false;
|
||||
}
|
||||
for (var ii :int = 0; ii < PNG_HEADER.length; ii++) {
|
||||
if (PNG_HEADER[ii] != bytes[ii]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the required chunks in the bytes that represent a PNG image. All of the chunks that
|
||||
* are succesfully found are pushed into the returned array in the order in which they were
|
||||
* found in the image.
|
||||
*/
|
||||
protected static function findChunks (pngBytes :ByteArray, chunkTypes :Array) :Array
|
||||
{
|
||||
var chunks :Array = [];
|
||||
if (chunkTypes.length < 1) {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
for (var ii :int = PNG_HEADER.length; ii < pngBytes.length;) {
|
||||
pngBytes.position = ii;
|
||||
var chunk :PngChunk =
|
||||
new PngChunk(ii + 8, pngBytes.readInt(), pngBytes.readUTFBytes(4));
|
||||
|
||||
var idx :int = chunkTypes.indexOf(chunk.type);
|
||||
if (idx >= 0) {
|
||||
chunks.push(chunk);
|
||||
if (chunkTypes.length == 1) {
|
||||
return chunks;
|
||||
} else {
|
||||
chunkTypes.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 4 bytes each for length, chunk type and CRC
|
||||
ii += 12 + chunk.length;
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
public static function recolorPNG (pngBytes :ByteArray,
|
||||
colors :Array/* of Colorization */) :void
|
||||
{
|
||||
if (colors.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// first, lets make sure we really have a PNG
|
||||
if (!isPng(pngBytes)) {
|
||||
log.warning("recolorPNG received invalid pngBytes", new Error());
|
||||
return;
|
||||
}
|
||||
|
||||
var chunks :Array = findChunks(pngBytes, [HEADER_CHUNK, PALETTE_CHUNK]);
|
||||
if (chunks.length != 2 || (chunks[0] as PngChunk).type != HEADER_CHUNK) {
|
||||
log.warning("recolorPNG received an unexected PNG format", "requiredChunksFound",
|
||||
chunks.length, new Error());
|
||||
return;
|
||||
}
|
||||
var header :PngChunk = chunks[0] as PngChunk;
|
||||
var palette :PngChunk = chunks[1] as PngChunk;
|
||||
// Check to make sure the header declares this to be an indexed-color PNG
|
||||
var colorType :int = pngBytes[header.idx + COLOR_TYPE_IDX];
|
||||
if (colorType != INDEXED_COLOR_TYPE) {
|
||||
log.warning(
|
||||
"Color Type in PNG header is not indexed-color", "type", colorType, new Error());
|
||||
return;
|
||||
}
|
||||
|
||||
initializeCRCTable();
|
||||
// CRC starts with chunk type
|
||||
var crc :uint = 0xFFFFFFFF;
|
||||
for (var ii :int = 0; ii < 4; ii++) {
|
||||
crc = crcCalc(crc, PALETTE_CHUNK.charCodeAt(ii));
|
||||
}
|
||||
pngBytes.position = palette.idx;
|
||||
for (ii = palette.idx; ii < palette.idx + palette.length; ii += 3) {
|
||||
var red :uint = pngBytes.readUnsignedByte();
|
||||
var green :uint = pngBytes.readUnsignedByte();
|
||||
var blue :uint = pngBytes.readUnsignedByte();
|
||||
|
||||
var hsb :Array = ColorUtil.RGBtoHSB(red, green, blue);
|
||||
for each (var color :Colorization in colors) {
|
||||
var newRgb :uint = color.recolorColor(hsb);
|
||||
pngBytes[ii] = ColorUtil.getRed(newRgb);
|
||||
pngBytes[ii + 1] = ColorUtil.getGreen(newRgb);
|
||||
pngBytes[ii + 2] = ColorUtil.getBlue(newRgb);
|
||||
}
|
||||
|
||||
crc = F.foldl([red, green, blue], crc, crcCalc);
|
||||
}
|
||||
crc = uint(crc ^ uint(0xFFFFFFFF));
|
||||
// write out the CRC for the modified color table
|
||||
pngBytes.position = palette.idx + palette.length;
|
||||
pngBytes.writeUnsignedInt(crc);
|
||||
}
|
||||
|
||||
protected static function initializeCRCTable () :void
|
||||
{
|
||||
if (_crcTable != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
_crcTable = [];
|
||||
for (var n :uint = 0; n < 256; n++)
|
||||
{
|
||||
var c :uint = n;
|
||||
for (var k :uint = 0; k < 8; k++)
|
||||
{
|
||||
if (c & 1) {
|
||||
c = uint(uint(0xedb88320) ^ uint(c >>> 1));
|
||||
} else {
|
||||
c = uint(c >>> 1);
|
||||
}
|
||||
}
|
||||
_crcTable[n] = c;
|
||||
}
|
||||
}
|
||||
|
||||
protected static function crcCalc (crc :uint, byte :uint) :uint
|
||||
{
|
||||
return uint(_crcTable[(crc ^ byte) & uint(0xFF)] ^ uint(crc >>> 8));
|
||||
}
|
||||
|
||||
/** The amount to pad error messages by. */
|
||||
private static const ERROR_PADDING :int = 5;
|
||||
|
||||
/** Various Png-recolor related constants. */
|
||||
protected static const PNG_HEADER :Array =
|
||||
[ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ];
|
||||
protected static const PALETTE_CHUNK :String = "PLTE";
|
||||
protected static const HEADER_CHUNK :String = "IHDR";
|
||||
protected static const COLOR_TYPE_IDX :int = 9;
|
||||
protected static const INDEXED_COLOR_TYPE :int = 3;
|
||||
|
||||
protected static const JAVA_SHORT_MAX :int = 0x7FFF;
|
||||
|
||||
protected static var _crcTable :Array;
|
||||
}
|
||||
}
|
||||
|
||||
import com.threerings.util.StringUtil;
|
||||
|
||||
/** Used for recoloring pngs. */
|
||||
class PngChunk
|
||||
{
|
||||
/** The index of the beginning of the data section of the chunk. */
|
||||
public var idx :int;
|
||||
|
||||
/** The length of the data section of the chunk. */
|
||||
public var length :int;
|
||||
|
||||
/** The type of this chunk. */
|
||||
public var type :String;
|
||||
|
||||
public function PngChunk (idx :int, length :int, type :String)
|
||||
{
|
||||
this.idx = idx;
|
||||
this.length = length;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public function toString () :String
|
||||
{
|
||||
return StringUtil.simpleToString(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user