📄 skinromizationtool.java
字号:
* @param prop property to compare value with * @return true if properties have the same value */ boolean isEqualValue(SkinPropertyBase prop) { if (!(prop instanceof CompositeImageSkinProperty)) { return false; } CompositeImageSkinProperty p = (CompositeImageSkinProperty)prop; if (p.value.length != value.length) { return false; } boolean equal = true; for (int i = 0; i < value.length; ++i) { if (!(p.value[i].equals(value[i]))) { equal = false; break; } } return equal; } /** * How many entries in values array is required for * storing this property value * * @return number of array entries required for storing * the value of this property */ int getValueOffsetDelta() { // for composite image, values array contain // file names of image pieces return value.length; } /** * Prints values array entries for this property's value * * @param out where to print entries */ void outputValue(BinaryOutputStreamExt out) throws java.io.IOException { // output pieces file names for (int i = 0; i < value.length; ++i) { out.writeString(value[i]); } }}/** * Represents romized image */final class RomizedImage extends RomizedByteArray { /** romized image index */ int imageIndex; /** * Constructor * * @param data romized image data * @param index romized image index */ RomizedImage(byte data[], int index) { super(data); this.imageIndex = index; }}/** * Creates RomizedImage instances */final class RomizedImageFactory { /** for converting image into raw format */ ImageToRawConverter converter; /** romized images counter */ int romizedImageCounter = 0; /** * Constructor * * @param converter converter to use for converting images * into raw format */ private RomizedImageFactory(ImageToRawConverter converter) { this.converter = converter; } /** * Creates RomizedImage from BufferedImage object * * @param image image to create romized image from * @param imageIndex romized image index * @return created RomizedImage */ RomizedImage createFromBufferedImage(BufferedImage image, int imageIndex) { int width = image.getWidth(null); int height = image.getHeight(null); boolean hasAlpha = image.getColorModel().hasAlpha(); int[] imageData = getBufferedImageData(image); byte[] rawData = converter.convertToRaw(imageData, width, height, hasAlpha); return new RomizedImage(rawData, romizedImageCounter++); } /** * Utility method. Gets BuffredImage data as in array. * * @param image BufferedImage to return data for * @return image data as byte array */ private static int[] getBufferedImageData(BufferedImage image) { int width = image.getWidth(null); int height = image.getHeight(null); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics g = bi.getGraphics(); try { g.drawImage(image, 0, 0, width, height, null); } finally { g.dispose(); } DataBuffer srcBuf = bi.getData().getDataBuffer(); int[] buf = ((DataBufferInt)srcBuf).getData(); return buf; } /** * Returns factory class instance * * @param rawFormat format of raw file * @param colorFormat format of pixel in raw file * @param endian romized image data endianess * @return RomizedImage factory */ static RomizedImageFactory getFactory(int rawFormat, int colorFormat, int endian) { ImageToRawConverter converter = new ImageToRawConverter(rawFormat, colorFormat, endian); return new RomizedImageFactory(converter); }}/** * Binary output stream capable of writing data * in big/little endian format. */final class BinaryOutputStreamExt extends BinaryOutputStream { /** * Constructor * * @param out underlying output stream for writing bytes into * @param isBigEndian true for big endian format, false for little */ BinaryOutputStreamExt(OutputStream out, boolean isBigEndian) { super(out, isBigEndian); } /** * Writes string into stream. The string data is written * in follwoing order: * - Number of bytes for string chars * - Encoding (US ASCII or UTF8) * - String chars as bytes * * The number of bytes for string chars is written as * single byte, so it can't exceed 255. * * @param value String value to write into stream */ public void writeString(String value) throws java.io.IOException { byte[] chars = value.getBytes("UTF8"); int length = chars.length; // determine what encoding to use int encoding = SkinResourcesConstants.STRING_ENCODING_USASCII; for (int i = 0; i < length; ++i) { int ch = chars[i] & 0xFF; if (ch >= 128) { encoding = SkinResourcesConstants.STRING_ENCODING_UTF8; break; } } if (encoding == SkinResourcesConstants.STRING_ENCODING_UTF8) { System.err.println("UTF8: " + value); // for '\0' at the end of the string length += 1; } // write string data length if (length > 255) { throw new IllegalArgumentException( "String data length exceeds 255 bytes"); } outputStream.writeByte(length); // write string encoding outputStream.writeByte(encoding); // write string data for (int i = 0; i < chars.length; ++i) { outputStream.writeByte(chars[i] & 0xFF); } if (encoding == SkinResourcesConstants.STRING_ENCODING_UTF8) { // '\0' at the end of the string outputStream.writeByte(0); } }}/** * Perform the romization */class SkinRomizer extends RomUtil { /** current romization job */ RomizationJob romizationJob; /** XML with skin properties as Document */ private Document domDoc = null; /** Be verbose: print some debug info while running */ private boolean debug = false; /** All skin properties */ Vector allProps = null; /** All integers sequence skin properties */ Vector intSeqProps = null; /** All string skin properties */ Vector stringProps = null; /** All integers font skin properties */ Vector fontProps = null; /** All image skin properties */ Vector imageProps = null; /** All composite image skin properties */ Vector compImageProps = null; /** All romized images */ Vector romizedImages = null; /** Romized image factory */ RomizedImageFactory romizedImageFactory; /** Binary output file stream */ BinaryOutputStreamExt outputStream = null; /** raw image file format */ int rawFormat = ImageToRawConverter.FORMAT_INVALID; /** raw image color format */ int colorFormat = ImageToRawConverter.FORMAT_INVALID; /** raw image data endianess */ int endianFormat = ImageToRawConverter.FORMAT_INVALID; /** array of strings used in XML file to specify raw image format */ static String[] imageFormatStrings = { // raw file formats "Putpixel", "ARGB", // endianess "Little", "Big", // supported pixel formats "565", "888", }; /** array of constants corresponding to strings above */ static int[] imageFormats = { // raw file formats ImageToRawConverter.RAW_FORMAT_PP, ImageToRawConverter.RAW_FORMAT_ARGB, // endianess ImageToRawConverter.INT_FORMAT_LITTLE_ENDIAN, ImageToRawConverter.INT_FORMAT_BIG_ENDIAN, // supported pixel formats ImageToRawConverter.COLOR_FORMAT_565, ImageToRawConverter.COLOR_FORMAT_888 }; /** * Constructor * * @param dbg print some debug output while running */ public SkinRomizer(boolean dbg) { debug = dbg; SkinPropertyBase.debug = dbg; } /** * Does the actual romization * * @param romizationJob romization to perform * @exception Exception if there was an error during romization */ public void romize(RomizationJob romizationJob) throws Exception { this.romizationJob = romizationJob; allProps = new Vector(); intSeqProps = new Vector(); stringProps = new Vector(); fontProps = new Vector(); imageProps = new Vector(); compImageProps = new Vector(); // load XML file as DOM tree DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); // do not validate input XML file, // we assume it has been validated before domFactory.setValidating(false); DocumentBuilder domBuilder = domFactory.newDocumentBuilder(); domDoc = domBuilder.parse(new File(romizationJob.skinXMLFileName)); // traverse DOM tree constructed from input XML and // collect all skin properties described there collectSkinProperties(domDoc.getDocumentElement()); // now, when we know format of romized images, // we can create romized images factory romizedImageFactory = RomizedImageFactory.getFactory( rawFormat, colorFormat, endianFormat); // assign offsets assignPropertiesValuesOffsets(intSeqProps, 0); assignPropertiesValuesOffsets(stringProps, 0); assignPropertiesValuesOffsets(fontProps, 0); // values for composite image properties are stored in same // array as values for image properties. first, values for // image properties are stored, followed by values for // composite image properties. int lastOffset = assignPropertiesValuesOffsets(imageProps, 0); ImageSkinProperty.totalImages = lastOffset - 1; lastOffset = assignPropertiesValuesOffsets(compImageProps, lastOffset); CompositeImageSkinProperty.totalImages = lastOffset - 1; // total unique skin images int totalImages = ImageSkinProperty.totalImages + CompositeImageSkinProperty.totalImages; // if image isn't romized, then corresponding value will be null romizedImages = new Vector(totalImages); romizedImages.setSize(totalImages); romizeImages(); // output generated skin description file OutputStream outForSkinDescr; if (!romizationJob.romizeAll) { makeDirectoryTree(romizationJob.outBinFileName); outForSkinDescr = new BufferedOutputStream(new FileOutputStream( romizationJob.outBinFileName), 8192); } else { outForSkinDescr = new ByteArrayOutputStream(8192); } outputStream = new BinaryOutputStreamExt(outForSkinDescr, endianFormat == ImageToRawConverter.INT_FORMAT_BIG_ENDIAN); writeBinHeader(); writeRomizedProperties(); // output generated C file with images OutputStream outForCFile = new FileOutputStream(romizationJob.outCFileName); writer = new PrintWriter(new OutputStreamWriter(outForCFile)); writeCHeader(); writeRomizedImagesData(); writeGetMethod(); if (romizationJob.romizeAll) { writeSkinDescription( ((ByteArrayOutputStream)outForSkinDescr).toByteArray()); } else { writeSkinDescription(null); } outputStream.close(); writer.close(); } /** * Walks the XML tree and collects all skin properties elements * * @param n current DOM node in document * @exception Exception if there was an error during romization */ private void collectSkinProperties(Node n) throws Exception { if (n.getNodeName().equals("skin") && (n instanceof Element)) { NodeList list = n.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { collectSkinProperties(list.item(i)); } } else if (n.getNodeName().equals("rawimage") && (n instanceof Element)) { collectImageFormat(n); } else if (n.getNodeName().equals("skin_properties") && (n instanceof Element)) { NodeList list = n.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { collectSkinProperty(list.item(i)); } } else { NodeList list = n.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { collectSkinProperties(list.item(i)); } } } /** * Collects raw images format specification * @param n current DOM node in document * @exception Exception if there was an error during romization */ private void collectImageFormat(Node n) { Element e = (Element)n; String rawFormatStr = e.getAttribute("Format"); rawFormat = ImageToRawConverter.FORMAT_INVALID; for (int i = 0; i < imageFormatStrings.length; ++i) { if (imageFormatStrings[i].equals(rawFormatStr)) { rawFormat = imageFormats[i]; break; } } if (rawFormat == ImageToRawConverter.FORMAT_INVALID) { throw new IllegalArgumentException("invalid raw file format " + '"' + rawFormatStr + '"'); } String colorFormatStr = e.getAttribute("Colors"); colorFormat = ImageToRawConverter.FORMAT_INVALID; for (int i = 0; i < imageFormatStrings.length; ++i) { if (imageFormatStrings[i].equals(colorFormatStr)) { colorFormat = imageFormats[i]; break; } } if (colorFormat == ImageToRawConverter.FORMAT_INVALID) { throw new IllegalArgumentException("invalid color format " + '"' + colorFormatStr + '"'); } String endianFormatStr = e.getAttribute("Endian"); endianFormat = ImageToRawConverter.FORMAT_INVALID; for (int i = 0; i < imageFormatStrings.length; ++i) { if (imageFormatStrings[i].equals(endianFormatStr)) { endianFormat = imageFormats[i]; break; } } if (endianFormat == ImageToRawConverter.FORMAT_INVALID) { throw new IllegalArgumentException("invalid color format " + '"' + endianFormatStr + '"'); } if (!ImageToRawConverter.isFormatSupported(rawFormat, colorFormat)) { throw new IllegalArgumentException( "unsupported romized image format: "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -