X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Ftterminal%2FSixel.java;h=f19087770f82e37d1a7474b0d2db42ac2098d0c7;hb=4b7ac2598c005c634966d9c415425bc6c7bc144b;hp=8d8429b8dd2c63cacacc689c50611c6f6db19d04;hpb=5fc7bf09f3c9987287f34f9035b522b0e5e9de13;p=fanfix.git diff --git a/src/jexer/tterminal/Sixel.java b/src/jexer/tterminal/Sixel.java index 8d8429b..f190877 100644 --- a/src/jexer/tterminal/Sixel.java +++ b/src/jexer/tterminal/Sixel.java @@ -49,10 +49,8 @@ public class Sixel { private enum ScanState { GROUND, QUOTE, - COLOR_ENTRY, - COLOR_PARAM, - COLOR_PIXELS, - SIXEL_REPEAT, + COLOR, + REPEAT, } // ------------------------------------------------------------------------ @@ -62,7 +60,7 @@ public class Sixel { /** * If true, enable debug messages. */ - private static boolean DEBUG = true; + private static boolean DEBUG = false; /** * Number of pixels to increment when we need more horizontal room. @@ -80,9 +78,14 @@ public class Sixel { private ScanState scanState = ScanState.GROUND; /** - * Parameter characters being collected. + * Parameters being collected. */ - private ArrayList colorParams; + private int [] params = new int[5]; + + /** + * Current parameter being collected. + */ + private int paramsI = 0; /** * The sixel palette colors specified. @@ -119,6 +122,11 @@ public class Sixel { */ private int x = 0; + /** + * The maximum y drawn to. This will set the final image height. + */ + private int y = 0; + /** * The current drawing color. */ @@ -135,7 +143,6 @@ public class Sixel { */ public Sixel(final String buffer) { this.buffer = buffer; - colorParams = new ArrayList(); palette = new HashMap(); image = new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < buffer.length(); i++) { @@ -154,7 +161,7 @@ public class Sixel { */ public BufferedImage getImage() { if ((width > 0) && (height > 0)) { - return image.getSubimage(0, 0, width, height); + return image.getSubimage(0, 0, width, y + 1); } return null; } @@ -169,6 +176,11 @@ public class Sixel { BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); + if (DEBUG) { + System.err.println("resizeImage(); old " + image.getWidth() + "x" + + image.getHeight() + " new " + newWidth + "x" + newHeight); + } + Graphics2D gr = newImage.createGraphics(); gr.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); gr.dispose(); @@ -179,32 +191,14 @@ public class Sixel { * Clear the parameters and flags. */ private void toGround() { - colorParams.clear(); + paramsI = 0; + for (int i = 0; i < params.length; i++) { + params[i] = 0; + } scanState = ScanState.GROUND; repeatCount = -1; } - /** - * Save a byte into the color parameters buffer. - * - * @param ch byte to save - */ - private void param(final byte ch) { - if (colorParams.size() == 0) { - colorParams.add(Integer.valueOf(0)); - } - Integer n = colorParams.get(colorParams.size() - 1); - if ((ch >= '0') && (ch <= '9')) { - n *= 10; - n += (ch - '0'); - colorParams.set(colorParams.size() - 1, n); - } - - if ((ch == ';') && (colorParams.size() < 16)) { - colorParams.add(Integer.valueOf(0)); - } - } - /** * Get a color parameter value, with a default. * @@ -213,10 +207,10 @@ public class Sixel { * @return parameter value */ private int getColorParam(final int position, final int defaultValue) { - if (colorParams.size() < position + 1) { + if (position > paramsI) { return defaultValue; } - return colorParams.get(position).intValue(); + return params[position]; } /** @@ -249,6 +243,12 @@ public class Sixel { */ private void addSixel(final char ch) { int n = ((int) ch - 63); + + if (DEBUG && (color == null)) { + System.err.println("color is null?!"); + System.err.println(buffer); + } + int rgb = color.getRGB(); int rep = (repeatCount == -1 ? 1 : repeatCount); @@ -257,6 +257,8 @@ public class Sixel { Integer.toHexString(n) + " color " + color); } + assert (n >= 0); + if (x + rep > image.getWidth()) { // Resize the image, give us another max(rep, WIDTH_INCREASE) // pixels of horizontal length. @@ -273,30 +275,39 @@ public class Sixel { return; } + int dy = 0; for (int i = 0; i < rep; i++) { - if ((n & 0x01) == 0x01) { - image.setRGB(x, height, rgb); + if ((n & 0x01) != 0) { + dy = 0; + image.setRGB(x, height + dy, rgb); } - if ((n & 0x02) == 0x02) { - image.setRGB(x, height + 1, rgb); + if ((n & 0x02) != 0) { + dy = 1; + image.setRGB(x, height + dy, rgb); } - if ((n & 0x04) == 0x04) { - image.setRGB(x, height + 2, rgb); + if ((n & 0x04) != 0) { + dy = 2; + image.setRGB(x, height + dy, rgb); } - if ((n & 0x08) == 0x08) { - image.setRGB(x, height + 3, rgb); + if ((n & 0x08) != 0) { + dy = 3; + image.setRGB(x, height + dy, rgb); } - if ((n & 0x10) == 0x10) { - image.setRGB(x, height + 4, rgb); + if ((n & 0x10) != 0) { + dy = 4; + image.setRGB(x, height + dy, rgb); } - if ((n & 0x20) == 0x20) { - image.setRGB(x, height + 5, rgb); + if ((n & 0x20) != 0) { + dy = 5; + image.setRGB(x, height + dy, rgb); } - x++; - if (x > width) { - width++; - assert (x == width); + if (height + dy > y) { + y = height + dy; } + x++; + } + if (x > width) { + width = x; } } @@ -306,14 +317,19 @@ public class Sixel { private void setPalette() { int idx = getColorParam(0, 0); - if (colorParams.size() == 1) { + if (paramsI == 0) { Color newColor = palette.get(idx); if (newColor != null) { color = newColor; + } else { + if (DEBUG) { + System.err.println("COLOR " + idx + " NOT FOUND"); + } + color = Color.BLACK; } if (DEBUG) { - System.err.println("set color: " + color); + System.err.println("set color " + idx + " " + color); } return; } @@ -329,6 +345,11 @@ public class Sixel { if (DEBUG) { System.err.println("Palette color " + idx + " --> " + newColor); } + } else { + if (DEBUG) { + System.err.println("UNKNOWN COLOR TYPE " + type + ": " + type + + " " + idx + " R " + red + " G " + green + " B " + blue); + } } } @@ -342,164 +363,100 @@ public class Sixel { // DEBUG // System.err.printf("Sixel.consume() %c STATE = %s\n", ch, scanState); - switch (scanState) { - - case GROUND: - switch (ch) { - case '#': - scanState = ScanState.COLOR_ENTRY; - return; - case '\"': - scanState = ScanState.QUOTE; - return; - default: - break; - } - - if (ch == '!') { - // Repeat count - scanState = ScanState.SIXEL_REPEAT; - } - if (ch == '-') { - if (height + 6 < image.getHeight()) { - // Resize the image, give us another HEIGHT_INCREASE - // pixels of vertical length. - resizeImage(image.getWidth(), - image.getHeight() + HEIGHT_INCREASE); - } - height += 6; - x = 0; - } - - if (ch == '$') { - x = 0; - } - return; - - case QUOTE: - switch (ch) { - case '#': - scanState = ScanState.COLOR_ENTRY; - return; - default: - break; + // Between decimal 63 (inclusive) and 127 (exclusive) --> pixels + if ((ch >= 63) && (ch < 127)) { + if (scanState == ScanState.COLOR) { + setPalette(); } - - // Ignore everything else in the quote header. + addSixel(ch); + toGround(); return; + } - case COLOR_ENTRY: - // Between decimal 63 (inclusive) and 189 (exclusive) --> pixels - if ((ch >= 63) && (ch < 189)) { - addSixel(ch); - return; - } - - // 30-39, 3B --> param, then switch to COLOR_PARAM - if ((ch >= '0') && (ch <= '9')) { - param((byte) ch); - scanState = ScanState.COLOR_PARAM; - } - if (ch == ';') { - param((byte) ch); - scanState = ScanState.COLOR_PARAM; - } - - if (ch == '#') { - // Next color is here, parse what we had before. + if (ch == '#') { + // Next color is here, parse what we had before. + if (scanState == ScanState.COLOR) { setPalette(); toGround(); } + scanState = ScanState.COLOR; + return; + } - if (ch == '!') { - setPalette(); - toGround(); - - // Repeat count - scanState = ScanState.SIXEL_REPEAT; - } - if (ch == '-') { + if (ch == '!') { + // Repeat count + if (scanState == ScanState.COLOR) { setPalette(); toGround(); - - if (height + 6 < image.getHeight()) { - // Resize the image, give us another HEIGHT_INCREASE - // pixels of vertical length. - resizeImage(image.getWidth(), - image.getHeight() + HEIGHT_INCREASE); - } - height += 6; - x = 0; } + scanState = ScanState.REPEAT; + repeatCount = 0; + return; + } - if (ch == '$') { + if (ch == '-') { + if (scanState == ScanState.COLOR) { setPalette(); toGround(); - - x = 0; } - return; - case COLOR_PARAM: - - // Between decimal 63 (inclusive) and 189 (exclusive) --> pixels - if ((ch >= 63) && (ch < 189)) { - addSixel(ch); - return; - } + height += 6; + x = 0; - // 30-39, 3B --> param, then switch to COLOR_PARAM - if ((ch >= '0') && (ch <= '9')) { - param((byte) ch); - } - if (ch == ';') { - param((byte) ch); + if (height + 6 > image.getHeight()) { + // Resize the image, give us another HEIGHT_INCREASE + // pixels of vertical length. + resizeImage(image.getWidth(), + image.getHeight() + HEIGHT_INCREASE); } + return; + } - if (ch == '#') { - // Next color is here, parse what we had before. + if (ch == '$') { + if (scanState == ScanState.COLOR) { setPalette(); toGround(); - scanState = ScanState.COLOR_ENTRY; } + x = 0; + return; + } - if (ch == '!') { - setPalette(); - toGround(); - - // Repeat count - scanState = ScanState.SIXEL_REPEAT; - } - if (ch == '-') { + if (ch == '"') { + if (scanState == ScanState.COLOR) { setPalette(); toGround(); - - if (height + 6 < image.getHeight()) { - // Resize the image, give us another HEIGHT_INCREASE - // pixels of vertical length. - resizeImage(image.getWidth(), - image.getHeight() + HEIGHT_INCREASE); - } - height += 6; - x = 0; } + scanState = ScanState.QUOTE; + return; + } - if (ch == '$') { - setPalette(); - toGround(); + switch (scanState) { - x = 0; + case GROUND: + // Unknown character. + if (DEBUG) { + System.err.println("UNKNOWN CHAR: " + ch); } return; - case SIXEL_REPEAT: + case QUOTE: + // Ignore everything else in the quote header. + return; - // Between decimal 63 (inclusive) and 189 (exclusive) --> pixels - if ((ch >= 63) && (ch < 189)) { - addSixel(ch); - toGround(); + case COLOR: + // 30-39, 3B --> param + if ((ch >= '0') && (ch <= '9')) { + params[paramsI] *= 10; + params[paramsI] += (ch - '0'); + } + if (ch == ';') { + if (paramsI < params.length - 1) { + paramsI++; + } } + return; + case REPEAT: if ((ch >= '0') && (ch <= '9')) { if (repeatCount == -1) { repeatCount = (int) (ch - '0'); @@ -508,14 +465,8 @@ public class Sixel { repeatCount += (int) (ch - '0'); } } - - if (ch == '#') { - // Next color. - toGround(); - scanState = ScanState.COLOR_ENTRY; - } - return; + } }