aboutsummaryrefslogtreecommitdiffstats
path: root/java/com/tigervnc/rfb
diff options
context:
space:
mode:
authorBrian P. Hinz <bphinz@users.sf.net>2018-01-01 17:24:20 -0500
committerBrian P. Hinz <bphinz@users.sf.net>2018-01-16 23:28:37 -0500
commitb40235af946e6854e7fcf1f8f7a00c165e71008e (patch)
tree8b1c795bb084e332349c02b2af13a61b9fb969fe /java/com/tigervnc/rfb
parent46fab93cbdc6f114f63279f0268ea3be94cd2922 (diff)
downloadtigervnc-b40235af946e6854e7fcf1f8f7a00c165e71008e.tar.gz
tigervnc-b40235af946e6854e7fcf1f8f7a00c165e71008e.zip
Fixes for erros in java hextile/zrle decoders
Various errors exposed when connecting to RealVNC servers on alternative platforms (ARM, SPARC). SSLEngineManager was also cleaned up but most of the changes are cosmetic.
Diffstat (limited to 'java/com/tigervnc/rfb')
-rw-r--r--java/com/tigervnc/rfb/CMsgReader.java33
-rw-r--r--java/com/tigervnc/rfb/CSecurityVncAuth.java10
-rw-r--r--java/com/tigervnc/rfb/HextileDecoder.java36
-rw-r--r--java/com/tigervnc/rfb/PixelFormat.java7
-rw-r--r--java/com/tigervnc/rfb/TightDecoder.java22
-rw-r--r--java/com/tigervnc/rfb/ZRLEDecoder.java114
6 files changed, 116 insertions, 106 deletions
diff --git a/java/com/tigervnc/rfb/CMsgReader.java b/java/com/tigervnc/rfb/CMsgReader.java
index a79cf842..e65db8c6 100644
--- a/java/com/tigervnc/rfb/CMsgReader.java
+++ b/java/com/tigervnc/rfb/CMsgReader.java
@@ -153,10 +153,10 @@ public class CMsgReader {
vlog.error("cut text too long ("+len+" bytes) - ignoring");
return;
}
- byte[] buf = new byte[len];
- is.readBytes(buf, 0, len);
+ ByteBuffer buf = ByteBuffer.allocate(len);
+ is.readBytes(buf, len);
Charset latin1 = Charset.forName("ISO-8859-1");
- CharBuffer chars = latin1.decode(ByteBuffer.wrap(buf));
+ CharBuffer chars = latin1.decode(buf.compact());
handler.serverCutText(chars.toString(), len);
}
@@ -164,22 +164,22 @@ public class CMsgReader {
{
int flags;
int len;
- byte[] data = new byte[64];
+ ByteBuffer data = ByteBuffer.allocate(64);
is.skip(3);
flags = is.readU32();
len = is.readU8();
- if (len > data.length) {
+ if (len > data.capacity()) {
System.out.println("Ignoring fence with too large payload\n");
is.skip(len);
return;
}
- is.readBytes(data, 0, len);
+ is.readBytes(data, len);
- handler.fence(flags, len, data);
+ handler.fence(flags, len, data.array());
}
protected void readEndOfContinuousUpdates()
@@ -243,6 +243,12 @@ public class CMsgReader {
int byte_ = y * maskBytesPerRow + x / 8;
int bit = 7 - x % 8;
+ // NOTE: BufferedImage needs ARGB, rather than RGBA
+ if ((mask.get(byte_) & (1 << bit)) > 0)
+ out.put(out.position(), (byte)255);
+ else
+ out.put(out.position(), (byte)0);
+
if ((data.get(byte_) & (1 << bit)) > 0) {
out.put(out.position() + 1, pr);
out.put(out.position() + 2, pg);
@@ -253,11 +259,6 @@ public class CMsgReader {
out.put(out.position() + 3, sb);
}
- if ((mask.get(byte_) & (1 << bit)) > 0)
- out.put(out.position() + 0, (byte)255);
- else
- out.put(out.position() + 0, (byte)0);
-
out.position(out.position() + 4);
}
}
@@ -281,8 +282,8 @@ public class CMsgReader {
is.readBytes(mask, mask_len);
int maskBytesPerRow = (width+7)/8;
- in = (ByteBuffer)data.duplicate().mark();
- out = (ByteBuffer)ByteBuffer.wrap(buf).mark();
+ in = ByteBuffer.wrap(data.array());
+ out = ByteBuffer.wrap(buf);
for (y = 0;y < height;y++) {
for (x = 0;x < width;x++) {
int byte_ = y * maskBytesPerRow + x / 8;
@@ -294,10 +295,10 @@ public class CMsgReader {
else
out.put((byte)0);
- handler.cp.pf().rgbFromBuffer(out, in.duplicate(), 1);
+ handler.cp.pf().rgbFromBuffer(out.duplicate(), in.duplicate(), 1);
in.position(in.position() + handler.cp.pf().bpp/8);
- out.position(out.reset().position() + 4).mark();
+ out.position(out.position() + 3);
}
}
diff --git a/java/com/tigervnc/rfb/CSecurityVncAuth.java b/java/com/tigervnc/rfb/CSecurityVncAuth.java
index 06154953..b1859f11 100644
--- a/java/com/tigervnc/rfb/CSecurityVncAuth.java
+++ b/java/com/tigervnc/rfb/CSecurityVncAuth.java
@@ -18,6 +18,8 @@
package com.tigervnc.rfb;
+import java.nio.*;
+
import com.tigervnc.rdr.*;
import com.tigervnc.vncviewer.*;
@@ -33,8 +35,8 @@ public class CSecurityVncAuth extends CSecurity {
OutStream os = cc.getOutStream();
// Read the challenge & obtain the user's password
- byte[] challenge = new byte[vncAuthChallengeSize];
- is.readBytes(challenge, 0, vncAuthChallengeSize);
+ ByteBuffer challenge = ByteBuffer.allocate(vncAuthChallengeSize);
+ is.readBytes(challenge, vncAuthChallengeSize);
StringBuffer passwd = new StringBuffer();
upg.getUserPasswd(cc.isSecure(), null, passwd);
@@ -51,10 +53,10 @@ public class CSecurityVncAuth extends CSecurity {
key[i] = i<pwdLen ? utf8str[i] : 0;
DesCipher des = new DesCipher(key);
for (int j = 0; j < vncAuthChallengeSize; j += 8)
- des.encrypt(challenge,j,challenge,j);
+ des.encrypt(challenge.array(),j,challenge.array(),j);
// Return the response to the server
- os.writeBytes(challenge, 0, vncAuthChallengeSize);
+ os.writeBytes(challenge.array(), 0, vncAuthChallengeSize);
os.flush();
return true;
}
diff --git a/java/com/tigervnc/rfb/HextileDecoder.java b/java/com/tigervnc/rfb/HextileDecoder.java
index b0744cad..4c99deeb 100644
--- a/java/com/tigervnc/rfb/HextileDecoder.java
+++ b/java/com/tigervnc/rfb/HextileDecoder.java
@@ -51,8 +51,8 @@ public class HextileDecoder extends Decoder {
t.br.x = Math.min(r.br.x, t.tl.x + 16);
- tileType = is.readU8() & 0xff;
- os.writeU32(tileType);
+ tileType = is.readU8();
+ os.writeU8(tileType);
if ((tileType & hextileRaw) != 0) {
os.copyBytes(is, t.area() * bytesPerPixel);
@@ -68,8 +68,8 @@ public class HextileDecoder extends Decoder {
if ((tileType & hextileAnySubrects) != 0) {
int nSubrects;
- nSubrects = is.readU8() & 0xff;
- os.writeU32(nSubrects);
+ nSubrects = is.readU8();
+ os.writeU8(nSubrects);
if ((tileType & hextileSubrectsColoured) != 0)
os.copyBytes(is, nSubrects * (bytesPerPixel + 2));
@@ -115,29 +115,24 @@ public class HextileDecoder extends Decoder {
}
private static ByteBuffer READ_PIXEL(InStream is, PixelFormat pf) {
- ByteBuffer b = ByteBuffer.allocate(4);
switch (pf.bpp) {
case 8:
- b.putInt(is.readOpaque8());
- return ByteBuffer.allocate(1).put(b.get(3));
+ return ByteBuffer.allocate(1).put(0, (byte)is.readOpaque8());
case 16:
- b.putInt(is.readOpaque16());
- return ByteBuffer.allocate(2).put(b.array(), 2, 2);
- case 32:
+ return ByteBuffer.allocate(2).putShort(0, (short)is.readOpaque16());
default:
- b.putInt(is.readOpaque32());
- return b;
+ return ByteBuffer.allocate(4).putInt(0, is.readOpaque32());
}
}
private void HEXTILE_DECODE(Rect r, InStream is,
- PixelFormat pf,
- ModifiablePixelBuffer pb)
+ PixelFormat pf,
+ ModifiablePixelBuffer pb)
{
Rect t = new Rect();
ByteBuffer bg = ByteBuffer.allocate(pf.bpp/8);
ByteBuffer fg = ByteBuffer.allocate(pf.bpp/8);
- ByteBuffer buf = ByteBuffer.allocate(16 * 16 * 4);
+ ByteBuffer buf = ByteBuffer.allocate(16 * 16 * pf.bpp/8);
for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) {
@@ -147,10 +142,10 @@ public class HextileDecoder extends Decoder {
t.br.x = Math.min(r.br.x, t.tl.x + 16);
- int tileType = is.readU32();
+ int tileType = is.readU8();
if ((tileType & hextileRaw) != 0) {
- is.readBytes(buf, t.area() * (pf.bpp/8));
+ is.readBytes(buf.duplicate(), t.area() * (pf.bpp/8));
pb.imageRect(pf, t, buf.array());
continue;
}
@@ -166,7 +161,7 @@ public class HextileDecoder extends Decoder {
fg = READ_PIXEL(is, pf);
if ((tileType & hextileAnySubrects) != 0) {
- int nSubrects = is.readU32();
+ int nSubrects = is.readU8();
for (int i = 0; i < nSubrects; i++) {
@@ -180,13 +175,16 @@ public class HextileDecoder extends Decoder {
int y = (xy & 15);
int w = ((wh >> 4) & 15) + 1;
int h = (wh & 15) + 1;
+ if (x + w > 16 || y + h > 16) {
+ throw new Exception("HEXTILE_DECODE: Hextile out of bounds");
+ }
ptr = buf.duplicate();
ptr.position((y * t.width() + x)*pf.bpp/8);
int rowAdd = (t.width() - w)*pf.bpp/8;
while (h-- > 0) {
len = w;
while (len-- > 0) ptr.put(fg.array());
- ptr.position(ptr.position()+Math.min(rowAdd,ptr.remaining()));
+ if (h > 0) ptr.position(ptr.position()+rowAdd);
}
}
}
diff --git a/java/com/tigervnc/rfb/PixelFormat.java b/java/com/tigervnc/rfb/PixelFormat.java
index 9a269992..593b7804 100644
--- a/java/com/tigervnc/rfb/PixelFormat.java
+++ b/java/com/tigervnc/rfb/PixelFormat.java
@@ -204,11 +204,13 @@ public class PixelFormat {
return 0;
}
+ // This method should be invoked with duplicates of dst/src Buffers
public void bufferFromRGB(ByteBuffer dst, ByteBuffer src, int pixels)
{
bufferFromRGB(dst, src, pixels, pixels, 1);
}
+ // This method should be invoked with duplicates of dst/src Buffers
public void bufferFromRGB(ByteBuffer dst, ByteBuffer src,
int w, int stride, int h)
{
@@ -269,11 +271,13 @@ public class PixelFormat {
}
}
+ // This method should be invoked with duplicates of dst/src Buffers
public void rgbFromBuffer(ByteBuffer dst, ByteBuffer src, int pixels)
{
rgbFromBuffer(dst, src, pixels, pixels, 1);
}
+ // This method should be invoked with duplicates of dst/src Buffers
public void rgbFromBuffer(ByteBuffer dst, ByteBuffer src,
int w, int stride, int h)
{
@@ -326,7 +330,7 @@ public class PixelFormat {
dst.put(b);
src.position(src.position() + bpp/8);
}
- src.reset().position(src.position() + srcPad).mark();
+ src.position(src.position() + srcPad);
}
}
}
@@ -345,6 +349,7 @@ public class PixelFormat {
}
}
+ // This method should be invoked with a duplicates of buffer
public int pixelFromBuffer(ByteBuffer buffer)
{
int p;
diff --git a/java/com/tigervnc/rfb/TightDecoder.java b/java/com/tigervnc/rfb/TightDecoder.java
index b180707d..262fcc34 100644
--- a/java/com/tigervnc/rfb/TightDecoder.java
+++ b/java/com/tigervnc/rfb/TightDecoder.java
@@ -211,7 +211,7 @@ public class TightDecoder extends Decoder {
assert(buflen >= 3);
- pf.bufferFromRGB(pix, bufptr, 1);
+ pf.bufferFromRGB(pix.duplicate(), bufptr, 1);
pb.fillRect(pf, r, pix.array());
} else {
assert(buflen >= pf.bpp/8);
@@ -296,7 +296,7 @@ public class TightDecoder extends Decoder {
// Determine if the data should be decompressed or just copied.
int rowSize, dataSize;
- byte[] netbuf;
+ ByteBuffer netbuf;
if (palSize != 0) {
if (palSize <= 2)
@@ -330,14 +330,14 @@ public class TightDecoder extends Decoder {
zis[streamId].setUnderlying(ms, len);
// Allocate netbuf and read in data
- netbuf = new byte[dataSize];
+ netbuf = ByteBuffer.allocate(dataSize);
- zis[streamId].readBytes(netbuf, 0, dataSize);
+ zis[streamId].readBytes(netbuf, dataSize);
zis[streamId].removeUnderlying();
ms = null;
- bufptr = ByteBuffer.wrap(netbuf);
+ bufptr = (ByteBuffer)netbuf.flip();
buflen = dataSize;
}
@@ -426,7 +426,7 @@ public class TightDecoder extends Decoder {
pix.put(c, (byte)(inbuf.get(y*rectWidth*3+c) + prevRow[c]));
thisRow[c] = pix.get(c);
}
- pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride), pix, 1);
+ pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride), pix, 1);
/* Remaining pixels of a row */
for (x = 1; x < rectWidth; x++) {
@@ -440,7 +440,7 @@ public class TightDecoder extends Decoder {
pix.put(c, (byte)(inbuf.get((y*rectWidth+x)*3+c) + est[c]));
thisRow[x*3+c] = pix.get(c);
}
- pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride+x), pix, 1);
+ pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride+x), pix, 1);
}
System.arraycopy(thisRow, 0, prevRow, 0, prevRow.length);
@@ -463,13 +463,13 @@ public class TightDecoder extends Decoder {
for (y = 0; y < rectHeight; y++) {
/* First pixel in a row */
- pf.rgbFromBuffer(pix, (ByteBuffer)inbuf.position(y*rectWidth), 1);
+ pf.rgbFromBuffer(pix.duplicate(), (ByteBuffer)inbuf.position(y*rectWidth), 1);
for (c = 0; c < 3; c++)
pix.put(c, (byte)(pix.get(c) + prevRow[c]));
System.arraycopy(pix.array(), 0, thisRow, 0, pix.capacity());
- pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride), pix, 1);
+ pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride), pix, 1);
/* Remaining pixels of a row */
for (x = 1; x < rectWidth; x++) {
@@ -482,13 +482,13 @@ public class TightDecoder extends Decoder {
}
}
- pf.rgbFromBuffer(pix, (ByteBuffer)inbuf.position(y*rectWidth+x), 1);
+ pf.rgbFromBuffer(pix.duplicate(), (ByteBuffer)inbuf.position(y*rectWidth+x), 1);
for (c = 0; c < 3; c++)
pix.put(c, (byte)(pix.get(c) + est[c]));
System.arraycopy(pix.array(), 0, thisRow, x*3, pix.capacity());
- pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride+x), pix, 1);
+ pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride+x), pix, 1);
}
System.arraycopy(thisRow, 0, prevRow, 0, prevRow.length);
diff --git a/java/com/tigervnc/rfb/ZRLEDecoder.java b/java/com/tigervnc/rfb/ZRLEDecoder.java
index c1f908ab..03692b96 100644
--- a/java/com/tigervnc/rfb/ZRLEDecoder.java
+++ b/java/com/tigervnc/rfb/ZRLEDecoder.java
@@ -26,24 +26,24 @@ import com.tigervnc.rdr.*;
public class ZRLEDecoder extends Decoder {
- private static int readOpaque24A(InStream is)
+ private static ByteBuffer readOpaque24A(InStream is)
{
is.check(3);
ByteBuffer r = ByteBuffer.allocate(4);
r.put(0, (byte)is.readU8());
r.put(1, (byte)is.readU8());
r.put(2, (byte)is.readU8());
- return ((ByteBuffer)r.rewind()).getInt();
+ return r;
}
- private static int readOpaque24B(InStream is)
+ private static ByteBuffer readOpaque24B(InStream is)
{
is.check(3);
ByteBuffer r = ByteBuffer.allocate(4);
- r.put(2, (byte)is.readU8());
r.put(1, (byte)is.readU8());
- r.put(0, (byte)is.readU8());
- return ((ByteBuffer)r.rewind()).getInt();
+ r.put(2, (byte)is.readU8());
+ r.put(3, (byte)is.readU8());
+ return r;
}
public ZRLEDecoder() {
@@ -67,97 +67,98 @@ public class ZRLEDecoder extends Decoder {
{
MemInStream is = new MemInStream((byte[])buffer, 0, buflen);
PixelFormat pf = cp.pf();
- ByteBuffer buf = ByteBuffer.allocate(64 * 64 * 4);
switch (pf.bpp) {
- case 8: zrleDecode8(r, is, zis, buf, pf, pb); break;
- case 16: zrleDecode16(r, is, zis, buf, pf, pb); break;
+ case 8: zrleDecode8(r, is, zis, pf, pb); break;
+ case 16: zrleDecode16(r, is, zis, pf, pb); break;
case 32:
- int maxPixel = pf.pixelFromRGB(-1, -1, -1, pf.getColorModel());
- boolean fitsInLS3Bytes = maxPixel < (1<<24);
- boolean fitsInMS3Bytes = (maxPixel & 0xff) == 0;
-
- if ((fitsInLS3Bytes && pf.isLittleEndian()) ||
- (fitsInMS3Bytes && pf.isBigEndian()))
- {
- zrleDecode24A(r, is, zis, buf, pf, pb);
- }
- else if ((fitsInLS3Bytes && pf.isBigEndian()) ||
- (fitsInMS3Bytes && pf.isLittleEndian()))
- {
- zrleDecode24B(r, is, zis, buf, pf, pb);
- }
- else
- {
- zrleDecode32(r, is, zis, buf, pf, pb);
+ {
+ if (pf.depth <= 24) {
+ int maxPixel = pf.pixelFromRGB(-1, -1, -1, pf.getColorModel());
+ boolean fitsInLS3Bytes = maxPixel < (1<<24);
+ boolean fitsInMS3Bytes = (maxPixel & 0xff) == 0;
+
+ if ((fitsInLS3Bytes && pf.isLittleEndian()) ||
+ (fitsInMS3Bytes && pf.isBigEndian()))
+ {
+ zrleDecode24A(r, is, zis, pf, pb);
+ break;
+ }
+
+ if ((fitsInLS3Bytes && pf.isBigEndian()) ||
+ (fitsInMS3Bytes && pf.isLittleEndian()))
+ {
+ zrleDecode24B(r, is, zis, pf, pb);
+ break;
+ }
}
+
+ zrleDecode32(r, is, zis, pf, pb);
break;
+ }
}
}
private static enum PIXEL_T { U8, U16, U24A, U24B, U32 };
private static ByteBuffer READ_PIXEL(InStream is, PIXEL_T type) {
- ByteBuffer b = ByteBuffer.allocate(4);
switch (type) {
case U8:
- b.putInt(is.readOpaque8());
- return (ByteBuffer)ByteBuffer.allocate(1).put(b.get(3)).rewind();
+ return ByteBuffer.allocate(1).put(0, (byte)is.readOpaque8());
case U16:
- b.putInt(is.readOpaque16());
- return (ByteBuffer)ByteBuffer.allocate(2).put(b.array(), 2, 2).rewind();
+ return ByteBuffer.allocate(2).putShort(0, (short)is.readOpaque16());
case U24A:
- return (ByteBuffer)b.putInt(readOpaque24A(is)).rewind();
+ return readOpaque24A(is);
case U24B:
- return (ByteBuffer)b.putInt(readOpaque24B(is)).rewind();
- case U32:
+ return readOpaque24B(is);
default:
- return (ByteBuffer)b.putInt(is.readOpaque32()).rewind();
+ return ByteBuffer.allocate(4).putInt(0, is.readOpaque32());
}
}
private void zrleDecode8(Rect r, InStream is,
- ZlibInStream zis, ByteBuffer buf,
+ ZlibInStream zis,
PixelFormat pf, ModifiablePixelBuffer pb)
{
- ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U8);
+ ZRLE_DECODE(r, is, zis, pf, pb, PIXEL_T.U8);
}
private void zrleDecode16(Rect r, InStream is,
- ZlibInStream zis, ByteBuffer buf,
+ ZlibInStream zis,
PixelFormat pf, ModifiablePixelBuffer pb)
{
- ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U16);
+ ZRLE_DECODE(r, is, zis, pf, pb, PIXEL_T.U16);
}
private void zrleDecode24A(Rect r, InStream is,
- ZlibInStream zis, ByteBuffer buf,
+ ZlibInStream zis,
PixelFormat pf, ModifiablePixelBuffer pb)
{
- ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U24A);
+ ZRLE_DECODE(r, is, zis, pf, pb, PIXEL_T.U24A);
}
private void zrleDecode24B(Rect r, InStream is,
- ZlibInStream zis, ByteBuffer buf,
+ ZlibInStream zis,
PixelFormat pf, ModifiablePixelBuffer pb)
{
- ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U24B);
+ ZRLE_DECODE(r, is, zis, pf, pb, PIXEL_T.U24B);
}
private void zrleDecode32(Rect r, InStream is,
- ZlibInStream zis, ByteBuffer buf,
+ ZlibInStream zis,
PixelFormat pf, ModifiablePixelBuffer pb)
{
- ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U32);
+ ZRLE_DECODE(r, is, zis, pf, pb, PIXEL_T.U32);
}
private void ZRLE_DECODE(Rect r, InStream is,
- ZlibInStream zis, ByteBuffer buf,
+ ZlibInStream zis,
PixelFormat pf, ModifiablePixelBuffer pb,
PIXEL_T pix_t)
{
int length = is.readU32();
zis.setUnderlying(is, length);
Rect t = new Rect();
+ ByteBuffer buf = ByteBuffer.allocate(64 * 64 * pf.bpp/8);
for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 64) {
@@ -175,11 +176,12 @@ public class ZRLEDecoder extends Decoder {
for (int i = 0; i < palSize; i++) {
palette.put(READ_PIXEL(zis, pix_t));
}
+ palette.flip();
if (palSize == 1) {
- ByteBuffer pix =
- ByteBuffer.allocate(pf.bpp/8).put(palette.array(), 0, pf.bpp/8);
- pb.fillRect(pf, t, pix.array());
+ byte[] pix = new byte[pf.bpp/8];
+ palette.get(pix);
+ pb.fillRect(pf, t, pix);
continue;
}
@@ -191,12 +193,12 @@ public class ZRLEDecoder extends Decoder {
case U24A:
case U24B:
ByteBuffer ptr = buf.duplicate();
- for (int iptr=0; iptr < t.area(); iptr++) {
+ for (int i=0; i < t.area(); i++) {
ptr.put(READ_PIXEL(zis, pix_t));
}
break;
default:
- zis.readBytes(buf, t.area() * (pf.bpp/8));
+ zis.readBytes(buf.duplicate(), t.area() * (pf.bpp/8));
}
} else {
@@ -241,12 +243,12 @@ public class ZRLEDecoder extends Decoder {
len += b;
} while (b == 255);
- if (end - ptr.position() < len*(pf.bpp/8)) {
+ if (end - ptr.position() < len*pf.bpp/8) {
System.err.println("ZRLE decode error\n");
throw new Exception("ZRLE decode error");
}
- while (len-- > 0) ptr.put(pix);
+ while (len-- > 0) ptr.put(pix.array());
}
} else {
@@ -265,7 +267,7 @@ public class ZRLEDecoder extends Decoder {
len += b;
} while (b == 255);
- if (end - ptr.position() < len*(pf.bpp/8)) {
+ if (end - ptr.position() < len*pf.bpp/8) {
System.err.println("ZRLE decode error\n");
throw new Exception("ZRLE decode error");
}
@@ -273,8 +275,10 @@ public class ZRLEDecoder extends Decoder {
index &= 127;
- while (len-- > 0) ptr.put(palette.array(), index*pf.bpp/8, pf.bpp/8);
+ ByteBuffer pix = ByteBuffer.allocate(pf.bpp/8);
+ pix.put(palette.array(), index*pf.bpp/8, pf.bpp/8);
+ while (len-- > 0) ptr.put(pix.array());
}
}
}