List of usage examples for com.badlogic.gdx.utils IntIntMap get
public int get(int key, int defaultValue)
From source file:com.crashinvaders.texturepackergui.utils.PNG8.java
License:Open Source License
/** * Attempts to write the given Pixmap exactly as a PNG-8 image to output; this attempt will only succeed if there * are no more than 256 colors in the Pixmap (treating all partially transparent colors as fully transparent). * If the attempt fails, this falls back to calling {@link #write(OutputStream, Pixmap, boolean, boolean)}, which * can dither the image to use no more than 255 colors (plus fully transparent) based on ditherFallback and will * always analyze the Pixmap to get an accurate-enough palette, using the given threshold for analysis (which is * typically between 1 and 1000, and most often near 200-400). All other write() methods in this class will * reduce the color depth somewhat, but as long as the color count stays at 256 or less, this will keep the * non-alpha components of colors exactly. * @param output an OutputStream that will not be closed * @param pixmap a Pixmap to write to the given output stream * @param ditherFallback if the Pixmap contains too many colors, this determines whether it will dither the output * @param threshold the analysis threshold to use if there are too many colors (min 0, practical max is over 100000) * @throws IOException if OutputStream things fail for any reason *///w ww. j a v a2 s . co m public void writePrecisely(OutputStream output, Pixmap pixmap, boolean ditherFallback, int threshold) throws IOException { IntIntMap colorToIndex = new IntIntMap(256); colorToIndex.put(0, 0); int color; int hasTransparent = 0; final int w = pixmap.getWidth(), h = pixmap.getHeight(); for (int y = 0; y < h; y++) { int py = flipY ? (h - y - 1) : y; for (int px = 0; px < w; px++) { color = pixmap.getPixel(px, py); if ((color & 0xFE) != 0xFE) { if (hasTransparent == 0 && colorToIndex.size >= 256) { write(output, pixmap, true, ditherFallback, threshold); return; } hasTransparent = 1; } else if (!colorToIndex.containsKey(color)) { colorToIndex.put(color, colorToIndex.size & 255); if (colorToIndex.size == 257 && hasTransparent == 0) { colorToIndex.remove(0, 0); } if (colorToIndex.size > 256) { write(output, pixmap, true, ditherFallback, threshold); return; } } } } int[] paletteArray = new int[colorToIndex.size]; for (IntIntMap.Entry ent : colorToIndex) { paletteArray[ent.value] = ent.key; } DeflaterOutputStream deflaterOutput = new DeflaterOutputStream(buffer, deflater); DataOutputStream dataOutput = new DataOutputStream(output); dataOutput.write(SIGNATURE); buffer.writeInt(IHDR); buffer.writeInt(pixmap.getWidth()); buffer.writeInt(pixmap.getHeight()); buffer.writeByte(8); // 8 bits per component. buffer.writeByte(COLOR_INDEXED); buffer.writeByte(COMPRESSION_DEFLATE); buffer.writeByte(FILTER_NONE); buffer.writeByte(INTERLACE_NONE); buffer.endChunk(dataOutput); buffer.writeInt(PLTE); for (int i = 0; i < paletteArray.length; i++) { int p = paletteArray[i]; buffer.write(p >>> 24); buffer.write(p >>> 16); buffer.write(p >>> 8); } buffer.endChunk(dataOutput); if (hasTransparent == 1) { buffer.writeInt(TRNS); buffer.write(0); buffer.endChunk(dataOutput); } buffer.writeInt(IDAT); deflater.reset(); int lineLen = pixmap.getWidth(); byte[] lineOut, curLine, prevLine; if (lineOutBytes == null) { lineOut = (lineOutBytes = new ByteArray(lineLen)).items; curLine = (curLineBytes = new ByteArray(lineLen)).items; prevLine = (prevLineBytes = new ByteArray(lineLen)).items; } else { lineOut = lineOutBytes.ensureCapacity(lineLen); curLine = curLineBytes.ensureCapacity(lineLen); prevLine = prevLineBytes.ensureCapacity(lineLen); for (int i = 0, n = lastLineLen; i < n; i++) { prevLine[i] = 0; } } lastLineLen = lineLen; for (int y = 0; y < h; y++) { int py = flipY ? (h - y - 1) : y; for (int px = 0; px < w; px++) { color = pixmap.getPixel(px, py); curLine[px] = (byte) colorToIndex.get(color, 0); } lineOut[0] = (byte) (curLine[0] - prevLine[0]); //Paeth for (int x = 1; x < lineLen; x++) { int a = curLine[x - 1] & 0xff; int b = prevLine[x] & 0xff; int c = prevLine[x - 1] & 0xff; int p = a + b - c; int pa = p - a; if (pa < 0) pa = -pa; int pb = p - b; if (pb < 0) pb = -pb; int pc = p - c; if (pc < 0) pc = -pc; if (pa <= pb && pa <= pc) c = a; else if (pb <= pc) c = b; lineOut[x] = (byte) (curLine[x] - c); } deflaterOutput.write(PAETH); deflaterOutput.write(lineOut, 0, lineLen); byte[] temp = curLine; curLine = prevLine; prevLine = temp; } deflaterOutput.finish(); buffer.endChunk(dataOutput); buffer.writeInt(IEND); buffer.endChunk(dataOutput); output.flush(); }