-
Enhancement
-
Resolution: Fixed
-
P3
-
1.3.0
-
None
-
beta
-
generic
-
solaris_7
In BytePackedRaster.setDataElements(int x, int y, Raster inRaster), there
is a division into two cases, one where the bit offsets of the source and
destination Rasters have equivalent alignment, and one where they do not.
The latter case is implemented by falling back to the superclass implementation.
The diffs required to implement the latter case are provided below for potentia
inclusion in Kestrel.
------- BytePackedRaster.java -------
534a535,539
> byte[] inData = inByteRaster.data;
> byte[] outData = this.data;
> int copybits = w * numberOfBits;
> int inscan = inByteRaster.scanlineStride;
>
537,540d541
< byte[] inData = inByteRaster.data;
< byte[] outData = this.data;
< int inscan = inByteRaster.scanlineStride;
< int copybits = w * numberOfBits;
602,604c603,672
< }
< // REMIND: we could do an else{} here and copy unaligned
< // contiguous data by shifting and merging pairs of bytes...
---
> } else {
> // Unaligned case
> for (int j = 0; j < h; j++) {
> int save_inbit = inbit;
> int save_outbit = outbit;
>
> int inbyte, outbyte;
> int mask;
>
> int bits = outbit & 7;
> if (bits > 0) {
> inbyte = inbit >> 8;
> outbyte = outbit >> 8;
> mask = 0xff >> bits;
> if (copybits < bits) {
> mask &= mask << (8 - copybits);
> bits = copybits;
> }
>
> int element = outData[outbyte];
> element &= ~mask;
> element |= (inData[inbyte] & mask);
> outData[outbyte] = (byte) element;
>
> inbit += bits;
> outbit += bits;
> copybits -= bits;
> }
>
> if (copybits == 0) {
> continue;
> }
>
> int shift0 = inbit & 7;
> int shift1 = 7 - shift0;
> int mask1 = 0xff >> shift1;
>
> inbyte = inbit >> 3;
> outbyte = outbit >> 3;
>
> int inData0 = inData[inbyte];
> while (copybits >= 8) {
> int inData1 = inData[inbyte + 1];
> int val = (inData0 << shift0) |
> ((inData1 >> shift1) & mask1);
> outData[outbyte] = (byte)val;
> inData0 = inData1;
>
> ++inbyte;
> ++outbyte;
> inbit += 8;
> outbit += 8;
> copybits -= 8;
> }
>
> if (copybits > 0) {
> inbyte = inbit >> 3;
> outbyte = outbit >> 3;
> mask = (0xff00 >> copybits) & 0xff;
>
> int element = outData[outbyte];
> element &= ~mask;
> element |= (inData[inbyte] & mask);
> outData[outbyte] = (byte)element;
> }
>
> inbit = save_inbit + 8*inscan;
> outbit = save_outbit + 8*outscan;
> }
> }
607d674
< super.setDataElements(x, y, inRaster);
--------------------------
daniel.rice@Eng 1999-10-25
I just noticed a slight problem with the above, the 'continue' statement
is not quite right, you need to add the scanline offsets. Really you just
need to guard the "inData0 = inData[inbyte]" statement with "if (copybits > 0)"
to avoid overrunning the input buffer.
brian.burkhalter@Eng 2000-10-20
See modification of the above suggestion in "Suggested Fix".
Also see test attachment.
is a division into two cases, one where the bit offsets of the source and
destination Rasters have equivalent alignment, and one where they do not.
The latter case is implemented by falling back to the superclass implementation.
The diffs required to implement the latter case are provided below for potentia
inclusion in Kestrel.
------- BytePackedRaster.java -------
534a535,539
> byte[] inData = inByteRaster.data;
> byte[] outData = this.data;
> int copybits = w * numberOfBits;
> int inscan = inByteRaster.scanlineStride;
>
537,540d541
< byte[] inData = inByteRaster.data;
< byte[] outData = this.data;
< int inscan = inByteRaster.scanlineStride;
< int copybits = w * numberOfBits;
602,604c603,672
< }
< // REMIND: we could do an else{} here and copy unaligned
< // contiguous data by shifting and merging pairs of bytes...
---
> } else {
> // Unaligned case
> for (int j = 0; j < h; j++) {
> int save_inbit = inbit;
> int save_outbit = outbit;
>
> int inbyte, outbyte;
> int mask;
>
> int bits = outbit & 7;
> if (bits > 0) {
> inbyte = inbit >> 8;
> outbyte = outbit >> 8;
> mask = 0xff >> bits;
> if (copybits < bits) {
> mask &= mask << (8 - copybits);
> bits = copybits;
> }
>
> int element = outData[outbyte];
> element &= ~mask;
> element |= (inData[inbyte] & mask);
> outData[outbyte] = (byte) element;
>
> inbit += bits;
> outbit += bits;
> copybits -= bits;
> }
>
> if (copybits == 0) {
> continue;
> }
>
> int shift0 = inbit & 7;
> int shift1 = 7 - shift0;
> int mask1 = 0xff >> shift1;
>
> inbyte = inbit >> 3;
> outbyte = outbit >> 3;
>
> int inData0 = inData[inbyte];
> while (copybits >= 8) {
> int inData1 = inData[inbyte + 1];
> int val = (inData0 << shift0) |
> ((inData1 >> shift1) & mask1);
> outData[outbyte] = (byte)val;
> inData0 = inData1;
>
> ++inbyte;
> ++outbyte;
> inbit += 8;
> outbit += 8;
> copybits -= 8;
> }
>
> if (copybits > 0) {
> inbyte = inbit >> 3;
> outbyte = outbit >> 3;
> mask = (0xff00 >> copybits) & 0xff;
>
> int element = outData[outbyte];
> element &= ~mask;
> element |= (inData[inbyte] & mask);
> outData[outbyte] = (byte)element;
> }
>
> inbit = save_inbit + 8*inscan;
> outbit = save_outbit + 8*outscan;
> }
> }
607d674
< super.setDataElements(x, y, inRaster);
--------------------------
daniel.rice@Eng 1999-10-25
I just noticed a slight problem with the above, the 'continue' statement
is not quite right, you need to add the scanline offsets. Really you just
need to guard the "inData0 = inData[inbyte]" statement with "if (copybits > 0)"
to avoid overrunning the input buffer.
brian.burkhalter@Eng 2000-10-20
See modification of the above suggestion in "Suggested Fix".
Also see test attachment.