You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by da...@apache.org on 2017/02/09 00:03:32 UTC

svn commit: r1782282 - /commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java

Author: damjan
Date: Thu Feb  9 00:03:32 2017
New Revision: 1782282

URL: http://svn.apache.org/viewvc?rev=1782282&view=rev
Log:
Add support for writing 4 color PCX images, and clean up and simplify
the writing code.

Patch by: me

Modified:
    commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java

Modified: commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java
URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java?rev=1782282&r1=1782281&r2=1782282&view=diff
==============================================================================
--- commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java (original)
+++ commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java Thu Feb  9 00:03:32 2017
@@ -32,8 +32,8 @@ import org.apache.commons.imaging.palett
 
 class PcxWriter {
     private int encoding;
-    private int bitDepth = -1;
-    private int planes = -1;
+    private int bitDepthWanted = -1;
+    private int planesWanted = -1;
     private PixelDensity pixelDensity;
     private final RleWriter rleWriter;
 
@@ -75,7 +75,7 @@ class PcxWriter {
                     throw new ImageWriteException(
                             "Invalid bit depth parameter: " + value);
                 }
-                bitDepth = ((Number) value).intValue();
+                bitDepthWanted = ((Number) value).intValue();
             }
         }
         
@@ -86,7 +86,7 @@ class PcxWriter {
                     throw new ImageWriteException(
                             "Invalid planes parameter: " + value);
                 }
-                planes = ((Number) value).intValue();
+                planesWanted = ((Number) value).intValue();
             }
         }
 
@@ -110,29 +110,40 @@ class PcxWriter {
             throw new ImageWriteException("Unknown parameter: " + firstKey);
         }
     }
-
+    
     public void writeImage(final BufferedImage src, final OutputStream os)
             throws ImageWriteException, IOException {
         final PaletteFactory paletteFactory = new PaletteFactory();
         final SimplePalette palette = paletteFactory.makeExactRgbPaletteSimple(src, 256);
         final BinaryOutputStream bos = new BinaryOutputStream(os,
                 ByteOrder.LITTLE_ENDIAN);
-        if (palette == null || bitDepth == 24 || bitDepth == 32) {
-            if (bitDepth == 32) {
-                write32BppPCX(src, bos);
+        final int bitDepth;
+        final int planes;
+        if (palette == null || bitDepthWanted == 24 || bitDepthWanted == 32) {
+            if (bitDepthWanted == 32) {
+                bitDepth = 32;
+                planes = 1;
             } else {
-                write24BppPCX(src, bos);
+                bitDepth = 8;
+                planes = 3;
             }
-        } else if (palette.length() > 16 || bitDepth == 8) {
-            write256ColorPCX(src, palette, bos);
-        } else if (palette.length() > 8 || bitDepth == 4) {
-            if (planes == 1) {
-                write16ColorPCXIn1Plane(src, palette, bos);
+        } else if (palette.length() > 16 || bitDepthWanted == 8) {
+            bitDepth = 8;
+            planes = 1;
+        } else if (palette.length() > 8 || bitDepthWanted == 4) {
+            if (planesWanted == 1) {
+                bitDepth = 4;
+                planes = 1;
             } else {
-                write16ColorPCXIn4Planes(src, palette, bos);
+                bitDepth = 1;
+                planes = 4;
             }
-        } else if (palette.length() > 2 || bitDepth == 3) {
-            write8ColorPcx(src, palette, bos);
+        } else if (palette.length() > 4 || bitDepthWanted == 3) {
+            bitDepth = 1;
+            planes = 3;
+        } else if (palette.length() > 2 || bitDepthWanted == 2) {
+            bitDepth = 1;
+            planes = 2;
         } else {
             boolean onlyBlackAndWhite = true;
             if (palette.length() >= 1) {
@@ -148,147 +159,20 @@ class PcxWriter {
                 }
             }
             if (onlyBlackAndWhite) {
-                writeBlackAndWhitePCX(src, bos);
+                bitDepth = 1;
+                planes = 1;
             } else {
-                write8ColorPcx(src, palette, bos);
-            }
-        }
-    }
-
-    private void write32BppPCX(final BufferedImage src, final BinaryOutputStream bos)
-            throws ImageWriteException, IOException {
-        final int bytesPerLine = src.getWidth() % 2 == 0 ? src.getWidth() : src.getWidth() + 1;
-
-        // PCX header
-        bos.write(10); // manufacturer
-        bos.write(5); // version
-        bos.write(encoding); // encoding
-        bos.write(32); // bits per pixel
-        bos.write2Bytes(0); // xMin
-        bos.write2Bytes(0); // yMin
-        bos.write2Bytes(src.getWidth() - 1); // xMax
-        bos.write2Bytes(src.getHeight() - 1); // yMax
-        bos.write2Bytes((short) Math.round(pixelDensity.horizontalDensityInches())); // hDpi
-        bos.write2Bytes((short) Math.round(pixelDensity.verticalDensityInches())); // vDpi
-        bos.write(new byte[48]); // 16 color palette
-        bos.write(0); // reserved
-        bos.write(1); // planes
-        bos.write2Bytes(bytesPerLine); // bytes per line
-        bos.write2Bytes(1); // palette info
-        bos.write2Bytes(0); // hScreenSize
-        bos.write2Bytes(0); // vScreenSize
-        bos.write(new byte[54]);
-
-        final int[] rgbs = new int[src.getWidth()];
-        final byte[] rgbBytes = new byte[4 * bytesPerLine];
-        for (int y = 0; y < src.getHeight(); y++) {
-            src.getRGB(0, y, src.getWidth(), 1, rgbs, 0, src.getWidth());
-            for (int x = 0; x < rgbs.length; x++) {
-                rgbBytes[4 * x + 0] = (byte) (rgbs[x] & 0xff);
-                rgbBytes[4 * x + 1] = (byte) ((rgbs[x] >> 8) & 0xff);
-                rgbBytes[4 * x + 2] = (byte) ((rgbs[x] >> 16) & 0xff);
-                rgbBytes[4 * x + 3] = 0;
-            }
-            rleWriter.write(bos, rgbBytes);
-        }
-        rleWriter.flush(bos);
-    }
-
-    private void write24BppPCX(final BufferedImage src, final BinaryOutputStream bos)
-            throws ImageWriteException, IOException {
-        final int bytesPerLine = src.getWidth() % 2 == 0 ? src.getWidth() : src.getWidth() + 1;
-
-        // PCX header
-        bos.write(10); // manufacturer
-        bos.write(5); // version
-        bos.write(encoding); // encoding
-        bos.write(8); // bits per pixel
-        bos.write2Bytes(0); // xMin
-        bos.write2Bytes(0); // yMin
-        bos.write2Bytes(src.getWidth() - 1); // xMax
-        bos.write2Bytes(src.getHeight() - 1); // yMax
-        bos.write2Bytes((short) Math.round(pixelDensity.horizontalDensityInches())); // hDpi
-        bos.write2Bytes((short) Math.round(pixelDensity.verticalDensityInches())); // vDpi
-        bos.write(new byte[48]); // 16 color palette
-        bos.write(0); // reserved
-        bos.write(3); // planes
-        bos.write2Bytes(bytesPerLine); // bytes per line
-        bos.write2Bytes(1); // palette info
-        bos.write2Bytes(0); // hScreenSize
-        bos.write2Bytes(0); // vScreenSize
-        bos.write(new byte[54]);
-
-        final int[] rgbs = new int[src.getWidth()];
-        final byte[] rgbBytes = new byte[3 * bytesPerLine];
-        for (int y = 0; y < src.getHeight(); y++) {
-            src.getRGB(0, y, src.getWidth(), 1, rgbs, 0, src.getWidth());
-            for (int x = 0; x < rgbs.length; x++) {
-                rgbBytes[x] = (byte) ((rgbs[x] >> 16) & 0xff);
-                rgbBytes[bytesPerLine + x] = (byte) ((rgbs[x] >> 8) & 0xff);
-                rgbBytes[2 * bytesPerLine + x] = (byte) (rgbs[x] & 0xff);
+                bitDepth = 1;
+                planes = 2;
             }
-            rleWriter.write(bos, rgbBytes);
         }
-        rleWriter.flush(bos);
-    }
-
-    private void writeBlackAndWhitePCX(final BufferedImage src,
-            final BinaryOutputStream bos)
-            throws ImageWriteException, IOException {
-        int bytesPerLine = (src.getWidth() + 7) / 8;
-        if (bytesPerLine % 2 != 0) {
-            ++bytesPerLine;
-        }
-
-        // PCX header
-        bos.write(10); // manufacturer
-        bos.write(3); // version - it seems some apps only open
-        // black and white files if the version is 3...
-        bos.write(encoding); // encoding
-        bos.write(1); // bits per pixel
-        bos.write2Bytes(0); // xMin
-        bos.write2Bytes(0); // yMin
-        bos.write2Bytes(src.getWidth() - 1); // xMax
-        bos.write2Bytes(src.getHeight() - 1); // yMax
-        bos.write2Bytes((short) Math.round(pixelDensity.horizontalDensityInches())); // hDpi
-        bos.write2Bytes((short) Math.round(pixelDensity.verticalDensityInches())); // vDpi
-        bos.write(new byte[48]); // 16 color palette
-        bos.write(0); // reserved
-        bos.write(1); // planes
-        bos.write2Bytes(bytesPerLine); // bytes per line
-        bos.write2Bytes(1); // palette info
-        bos.write2Bytes(0); // hScreenSize
-        bos.write2Bytes(0); // vScreenSize
-        bos.write(new byte[54]);
-
-        final byte[] row = new byte[bytesPerLine];
-        for (int y = 0; y < src.getHeight(); y++) {
-            Arrays.fill(row, (byte) 0);
-            for (int x = 0; x < src.getWidth(); x++) {
-                final int rgb = 0xffffff & src.getRGB(x, y);
-                int bit;
-                if (rgb == 0x000000) {
-                    bit = 0;
-                } else if (rgb == 0xffffff) {
-                    bit = 1;
-                } else {
-                    throw new ImageWriteException(
-                            "Pixel neither black nor white");
-                }
-                row[x / 8] |= (bit << (7 - (x % 8)));
-            }
-            rleWriter.write(bos, row);
-        }
-        rleWriter.flush(bos);
-    }
-
-    private void write16ColorPCXIn1Plane(final BufferedImage src, final SimplePalette palette,
-            final BinaryOutputStream bos) throws ImageWriteException, IOException {
-        int bytesPerLine = (src.getWidth() + 1) / 2;
-        if (bytesPerLine % 2 != 0) {
-            ++bytesPerLine;
+        
+        int bytesPerLine = (bitDepth * src.getWidth() + 7) / 8;
+        if ((bytesPerLine % 2) != 0) {
+            // must be even:
+            bytesPerLine++;
         }
-
+        
         final byte[] palette16 = new byte[16 * 3];
         for (int i = 0; i < 16; i++) {
             int rgb;
@@ -304,9 +188,9 @@ class PcxWriter {
 
         // PCX header
         bos.write(10); // manufacturer
-        bos.write(5); // version
+        bos.write(bitDepth == 1 && planes == 1 ? 3 : 5); // version. Some apps only open black and white PCX with version=3.
         bos.write(encoding); // encoding
-        bos.write(4); // bits per pixel
+        bos.write(bitDepth); // bits per pixel
         bos.write2Bytes(0); // xMin
         bos.write2Bytes(0); // yMin
         bos.write2Bytes(src.getWidth() - 1); // xMax
@@ -315,198 +199,127 @@ class PcxWriter {
         bos.write2Bytes((short) Math.round(pixelDensity.verticalDensityInches())); // vDpi
         bos.write(palette16); // 16 color palette
         bos.write(0); // reserved
-        bos.write(1); // planes
+        bos.write(planes); // planes
         bos.write2Bytes(bytesPerLine); // bytes per line
         bos.write2Bytes(1); // palette info
         bos.write2Bytes(0); // hScreenSize
         bos.write2Bytes(0); // vScreenSize
         bos.write(new byte[54]);
 
-        final byte[] indeces = new byte[bytesPerLine];
-        for (int y = 0; y < src.getHeight(); y++) {
-            Arrays.fill(indeces, (byte) 0);
-            for (int x = 0; x < src.getWidth(); x++) {
-                final int argb = src.getRGB(x, y);
-                final int index = palette.getPaletteIndex(0xffffff & argb);
-                indeces[x / 2] |= (index << 4 * (1 - (x % 2)));
-            }
-            rleWriter.write(bos, indeces);
-        }
-        rleWriter.flush(bos);
-    }
-
-    private void write16ColorPCXIn4Planes(final BufferedImage src, final SimplePalette palette,
-            final BinaryOutputStream bos) throws ImageWriteException, IOException {
-        int bytesPerLine = (src.getWidth() + 7) / 8;
-        if (bytesPerLine % 2 != 0) {
-            ++bytesPerLine;
+        if (bitDepth == 32) {
+            writePixels32(src, bytesPerLine, bos);
+        } else {
+            writePixels(src, bitDepth, planes, bytesPerLine, palette, bos);
         }
-
-        final byte[] palette16 = new byte[16 * 3];
-        for (int i = 0; i < 16; i++) {
-            int rgb;
-            if (i < palette.length()) {
-                rgb = palette.getEntry(i);
-            } else {
-                rgb = 0;
+        
+        if (bitDepth == 8 && planes == 1) {
+            // 256 color palette
+            bos.write(12);
+            for (int i = 0; i < 256; i++) {
+                int rgb;
+                if (i < palette.length()) {
+                    rgb = palette.getEntry(i);
+                } else {
+                    rgb = 0;
+                }
+                bos.write((rgb >> 16) & 0xff);
+                bos.write((rgb >> 8) & 0xff);
+                bos.write(rgb & 0xff);
             }
-            palette16[3 * i + 0] = (byte) (0xff & (rgb >> 16));
-            palette16[3 * i + 1] = (byte) (0xff & (rgb >> 8));
-            palette16[3 * i + 2] = (byte) (0xff & rgb);
         }
-
-        // PCX header
-        bos.write(10); // manufacturer
-        bos.write(5); // version
-        bos.write(encoding); // encoding
-        bos.write(1); // bits per pixel
-        bos.write2Bytes(0); // xMin
-        bos.write2Bytes(0); // yMin
-        bos.write2Bytes(src.getWidth() - 1); // xMax
-        bos.write2Bytes(src.getHeight() - 1); // yMax
-        bos.write2Bytes((short) Math.round(pixelDensity.horizontalDensityInches())); // hDpi
-        bos.write2Bytes((short) Math.round(pixelDensity.verticalDensityInches())); // vDpi
-        bos.write(palette16); // 16 color palette
-        bos.write(0); // reserved
-        bos.write(4); // planes
-        bos.write2Bytes(bytesPerLine); // bytes per line
-        bos.write2Bytes(1); // palette info
-        bos.write2Bytes(0); // hScreenSize
-        bos.write2Bytes(0); // vScreenSize
-        bos.write(new byte[54]);
-
+    }
+    
+    private void writePixels(final BufferedImage src, final int bitDepth, final int planes,
+            final int bytesPerLine, final SimplePalette palette, final BinaryOutputStream bos) throws IOException, ImageWriteException {
         final byte[] plane0 = new byte[bytesPerLine];
         final byte[] plane1 = new byte[bytesPerLine];
         final byte[] plane2 = new byte[bytesPerLine];
         final byte[] plane3 = new byte[bytesPerLine];
+        final byte[][] allPlanes = { plane0, plane1, plane2, plane3 };
+        
         for (int y = 0; y < src.getHeight(); y++) {
-            Arrays.fill(plane0, (byte)0);
-            Arrays.fill(plane1, (byte)0);
-            Arrays.fill(plane2, (byte)0);
-            Arrays.fill(plane3, (byte)0);
-            for (int x = 0; x < src.getWidth(); x++) {
-                final int argb = src.getRGB(x, y);
-                final int index = palette.getPaletteIndex(0xffffff & argb);
-                plane0[x >>> 3] |= (index & 1) << (7 - (x & 7));
-                plane1[x >>> 3] |= ((index & 2) >> 1) << (7 - (x & 7));
-                plane2[x >>> 3] |= ((index & 4) >> 2) << (7 - (x & 7));
-                plane3[x >>> 3] |= ((index & 8) >> 3) << (7 - (x & 7));
-            }
-            rleWriter.write(bos, plane0);
-            rleWriter.write(bos, plane1);
-            rleWriter.write(bos, plane2);
-            rleWriter.write(bos, plane3);
-        }
-        rleWriter.flush(bos);
-    }
-
-    private void write8ColorPcx(final BufferedImage src, final SimplePalette palette,
-            final BinaryOutputStream bos) throws ImageWriteException, IOException {
-        int bytesPerLine = (src.getWidth() + 7) / 8;
-        if (bytesPerLine % 2 != 0) {
-            ++bytesPerLine;
-        }
-
-        final byte[] palette16 = new byte[16 * 3];
-        for (int i = 0; i < 8; i++) {
-            int rgb;
-            if (i < palette.length()) {
-                rgb = palette.getEntry(i);
-            } else {
-                rgb = 0;
+            for (int i = 0; i < planes; i++) {
+                Arrays.fill(allPlanes[i], (byte)0);
+            }
+            
+            if (bitDepth == 1 && planes == 1) {
+                for (int x = 0; x < src.getWidth(); x++) {
+                    final int rgb = 0xffffff & src.getRGB(x, y);
+                    int bit;
+                    if (rgb == 0x000000) {
+                        bit = 0;
+                    } else {
+                        bit = 1;
+                    }
+                    plane0[x >>> 3] |= (bit << (7 - (x & 7)));
+                }
+            } else if (bitDepth == 1 && planes == 2) {
+                for (int x = 0; x < src.getWidth(); x++) {
+                    final int argb = src.getRGB(x, y);
+                    final int index = palette.getPaletteIndex(0xffffff & argb);
+                    plane0[x >>> 3] |= (index & 1) << (7 - (x & 7));
+                    plane1[x >>> 3] |= ((index & 2) >> 1) << (7 - (x & 7));
+                }
+            } else if (bitDepth == 1 && planes == 3) {
+                for (int x = 0; x < src.getWidth(); x++) {
+                    final int argb = src.getRGB(x, y);
+                    final int index = palette.getPaletteIndex(0xffffff & argb);
+                    plane0[x >>> 3] |= (index & 1) << (7 - (x & 7));
+                    plane1[x >>> 3] |= ((index & 2) >> 1) << (7 - (x & 7));
+                    plane2[x >>> 3] |= ((index & 4) >> 2) << (7 - (x & 7));
+                }
+            } else if (bitDepth == 1 && planes == 4) {
+                for (int x = 0; x < src.getWidth(); x++) {
+                    final int argb = src.getRGB(x, y);
+                    final int index = palette.getPaletteIndex(0xffffff & argb);
+                    plane0[x >>> 3] |= (index & 1) << (7 - (x & 7));
+                    plane1[x >>> 3] |= ((index & 2) >> 1) << (7 - (x & 7));
+                    plane2[x >>> 3] |= ((index & 4) >> 2) << (7 - (x & 7));
+                    plane3[x >>> 3] |= ((index & 8) >> 3) << (7 - (x & 7));
+                }
+            } else if (bitDepth == 4 && planes == 1) {
+                for (int x = 0; x < src.getWidth(); x++) {
+                    final int argb = src.getRGB(x, y);
+                    final int index = palette.getPaletteIndex(0xffffff & argb);
+                    plane0[x >>> 1] |= (index << 4 * (1 - (x & 1)));
+                }
+            } else if (bitDepth == 8 && planes == 1) {
+                for (int x = 0; x < src.getWidth(); x++) {
+                    final int argb = src.getRGB(x, y);
+                    final int index = palette.getPaletteIndex(0xffffff & argb);
+                    plane0[x] = (byte) index;
+                }
+            } else if (bitDepth == 8 && planes == 3) {
+                for (int x = 0; x < src.getWidth(); x++) {
+                    final int argb = src.getRGB(x, y);
+                    plane0[x] = (byte) (argb >>> 16);
+                    plane1[x] = (byte) (argb >>> 8);
+                    plane2[x] = (byte) argb;
+                }
+            }
+            
+            for (int i = 0; i < planes; i++) {
+                rleWriter.write(bos, allPlanes[i]);
             }
-            palette16[3 * i + 0] = (byte) (0xff & (rgb >> 16));
-            palette16[3 * i + 1] = (byte) (0xff & (rgb >> 8));
-            palette16[3 * i + 2] = (byte) (0xff & rgb);
-        }
-
-        // PCX header
-        bos.write(10); // manufacturer
-        bos.write(5); // version
-        bos.write(encoding); // encoding
-        bos.write(1); // bits per pixel
-        bos.write2Bytes(0); // xMin
-        bos.write2Bytes(0); // yMin
-        bos.write2Bytes(src.getWidth() - 1); // xMax
-        bos.write2Bytes(src.getHeight() - 1); // yMax
-        bos.write2Bytes((short) Math.round(pixelDensity.horizontalDensityInches())); // hDpi
-        bos.write2Bytes((short) Math.round(pixelDensity.verticalDensityInches())); // vDpi
-        bos.write(palette16); // 16 color palette
-        bos.write(0); // reserved
-        bos.write(3); // planes
-        bos.write2Bytes(bytesPerLine); // bytes per line
-        bos.write2Bytes(1); // palette info
-        bos.write2Bytes(0); // hScreenSize
-        bos.write2Bytes(0); // vScreenSize
-        bos.write(new byte[54]);
-
-        final byte[] plane0 = new byte[bytesPerLine];
-        final byte[] plane1 = new byte[bytesPerLine];
-        final byte[] plane2 = new byte[bytesPerLine];
-        for (int y = 0; y < src.getHeight(); y++) {
-            Arrays.fill(plane0, (byte)0);
-            Arrays.fill(plane1, (byte)0);
-            Arrays.fill(plane2, (byte)0);
-            for (int x = 0; x < src.getWidth(); x++) {
-                final int argb = src.getRGB(x, y);
-                final int index = palette.getPaletteIndex(0xffffff & argb);
-                plane0[x >>> 3] |= (index & 1) << (7 - (x & 7));
-                plane1[x >>> 3] |= ((index & 2) >> 1) << (7 - (x & 7));
-                plane2[x >>> 3] |= ((index & 4) >> 2) << (7 - (x & 7));
-            }
-            rleWriter.write(bos, plane0);
-            rleWriter.write(bos, plane1);
-            rleWriter.write(bos, plane2);
         }
         rleWriter.flush(bos);
     }
 
-    private void write256ColorPCX(final BufferedImage src, final SimplePalette palette,
-            final BinaryOutputStream bos) throws ImageWriteException, IOException {
-        final int bytesPerLine = src.getWidth() % 2 == 0 ? src.getWidth() : src.getWidth() + 1;
-
-        // PCX header
-        bos.write(10); // manufacturer
-        bos.write(5); // version
-        bos.write(encoding); // encoding
-        bos.write(8); // bits per pixel
-        bos.write2Bytes(0); // xMin
-        bos.write2Bytes(0); // yMin
-        bos.write2Bytes(src.getWidth() - 1); // xMax
-        bos.write2Bytes(src.getHeight() - 1); // yMax
-        bos.write2Bytes((short) Math.round(pixelDensity.horizontalDensityInches())); // hDpi
-        bos.write2Bytes((short) Math.round(pixelDensity.verticalDensityInches())); // vDpi
-        bos.write(new byte[48]); // 16 color palette
-        bos.write(0); // reserved
-        bos.write(1); // planes
-        bos.write2Bytes(bytesPerLine); // bytes per line
-        bos.write2Bytes(1); // palette info
-        bos.write2Bytes(0); // hScreenSize
-        bos.write2Bytes(0); // vScreenSize
-        bos.write(new byte[54]);
-
-        final byte[] indeces = new byte[bytesPerLine];
+    private void writePixels32(final BufferedImage src, final int bytesPerLine,
+            final BinaryOutputStream bos) throws IOException, ImageWriteException {
+        
+        final int[] rgbs = new int[src.getWidth()];
+        final byte[] plane = new byte[4 * bytesPerLine];
         for (int y = 0; y < src.getHeight(); y++) {
-            for (int x = 0; x < src.getWidth(); x++) {
-                final int argb = src.getRGB(x, y);
-                final int index = palette.getPaletteIndex(0xffffff & argb);
-                indeces[x] = (byte) index;
+            src.getRGB(0, y, src.getWidth(), 1, rgbs, 0, src.getWidth());
+            for (int x = 0; x < rgbs.length; x++) {
+                plane[4 * x + 0] = (byte) rgbs[x];
+                plane[4 * x + 1] = (byte) (rgbs[x] >> 8);
+                plane[4 * x + 2] = (byte) (rgbs[x] >> 16);
+                plane[4 * x + 3] = 0;
             }
-            rleWriter.write(bos, indeces);
+            rleWriter.write(bos, plane);
         }
         rleWriter.flush(bos);
-        // palette
-        bos.write(12);
-        for (int i = 0; i < 256; i++) {
-            int rgb;
-            if (i < palette.length()) {
-                rgb = palette.getEntry(i);
-            } else {
-                rgb = 0;
-            }
-            bos.write((rgb >> 16) & 0xff);
-            bos.write((rgb >> 8) & 0xff);
-            bos.write(rgb & 0xff);
-        }
     }
 }