[
https://issues.apache.org/jira/browse/BATIK-963?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13878355#comment-13878355
]
Viliam Durina commented on BATIK-963:
-------------------------------------
Thanks. The project, where I found this bug, never got into production, but I
was sad this was not applied...
> ArrayIndexOutOfBounds in AbstractWMFPainter with 1-bit color images
> -------------------------------------------------------------------
>
> Key: BATIK-963
> URL: https://issues.apache.org/jira/browse/BATIK-963
> Project: Batik
> Issue Type: Bug
> Components: Utilities
> Affects Versions: 1.8
> Environment: Operating System: All
> Platform: All
> Reporter: a6537691
> Assignee: Batik Developer's Mailing list
> Attachments: bug_50056_patch.diff, failingfile.wmf, obrazok2_orig.wmf
>
>
> I use WMFTranscoder to convert WMF files to SVG. I found a image, that fails
> with following exception:
> java.lang.ArrayIndexOutOfBoundsException: 108248
> at
> org.apache.batik.transcoder.wmf.tosvg.AbstractWMFPainter.getImage(AbstractWMFPainter.java:194)
> at
> org.apache.batik.transcoder.wmf.tosvg.AbstractWMFPainter.getImage(AbstractWMFPainter.java:74)
> at
> org.apache.batik.transcoder.wmf.tosvg.WMFPainter.paint(WMFPainter.java:859)
> at
> org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder.transcode(WMFTranscoder.java:187)
> ...
> The length of the array that caused the exception was 108248, so 1 byte after
> the end was attempted to read.
> The problem was on line 194 in AbstractWMFPainter, where next byte for the
> next iteration, which could be after the end, if there is no padding.
> Here is fixed code for the getImage(byte[]) method:
> /** Return the image associated with a bitmap in a Metafile.
> * 24 bits and 8 bits bitmaps are handled.
> * @param bit the bitmap byte array
> * @return the Image associated with the bitmap (null if the dimensions
> detected in the
> * header are not consistent with the assumed dimensions)
> */
> protected BufferedImage getImage(byte[] bit) {
> // get the header of the bitmap, first the width and height
> int _width = (((int)bit[7] & 0x00ff) << 24) | (((int)bit[6] & 0x00ff)
> << 16)
> | (((int)bit[5] & 0x00ff) << 8) | (int)bit[4] & 0x00ff;
> int _height = (((int)bit[11] & 0x00ff) << 24) | (((int)bit[10] &
> 0x00ff) << 16)
> | (((int)bit[9] & 0x00ff) << 8) | (int)bit[8] & 0x00ff;
> // OK, we can safely create the data array now
> int[] bitI = new int[_width * _height];
> BufferedImage img = new BufferedImage(_width, _height,
> BufferedImage.TYPE_INT_RGB);
> WritableRaster raster = img.getRaster();
> // retrieve useful informations in bitmap header
> // size of header
> int _headerSize = (((int)bit[3] & 0x00ff) << 24) | (((int)bit[2] &
> 0x00ff)<<16)
> | (((int)bit[1] & 0x00ff) << 8) | (int)bit[0] &
> 0x00ff;
> // number of planes
> int _planes = (((int)bit[13] & 0x00ff) << 8) | (int)bit[12] & 0x00ff;
> // number of bits per pixel
> int _nbit = (((int)bit[15] & 0x00ff) << 8) | (int)bit[14] & 0x00ff;
> // compression factor : unused
> // size of the image
> int _size = (((int)bit[23] & 0x00ff) << 24) | (((int)bit[22] &
> 0x00ff) << 16)
> | (((int)bit[21] & 0x00ff) << 8) | (int)bit[20] &
> 0x00ff;
> // infer the size of image if it is not given in the file
> if (_size == 0) _size = ((((_width * _nbit) + 31) & ~31 ) >> 3) *
> _height;
> // number of used colors
> int _clrused = (((int)bit[35] & 0x00ff) << 24) |
> (((int)bit[34]&0x00ff) << 16)
> | (((int)bit[33] & 0x00ff) << 8) |
> (int)bit[32]&0x00ff;
> // 24 bit image
> if (_nbit == 24) {
> // read the scan lines
> int pad = (_size / _height) - _width * 3;
> int offset = _headerSize; // begin to read data after header
> // populate the int array
> for (int j = 0; j < _height; j++) {
> for (int i = 0; i < _width; i++) {
> bitI[_width * (_height - j - 1) + i] =
> (255 & 0x00ff) << 24 | (((int)bit[offset+2] & 0x00ff)
> << 16)
> | (((int)bit[offset+1] & 0x00ff) << 8) |
> (int)bit[offset] & 0x00ff;
> offset += 3;
> }
> offset += pad;
> }
> // 8 bit image
> } else if (_nbit == 8) {
> // Determine the number of colors
> int nbColors = 0;
> if (_clrused > 0) nbColors = _clrused;
> else nbColors = (1 & 0x00ff) << 8;
> // Read the palette colors.
> int offset = _headerSize;
> int[] palette = new int[nbColors];
> for (int i = 0; i < nbColors; i++) {
> palette[i] = (255 & 0x00ff) << 24 | (((int)bit[offset+2] &
> 0x00ff) << 16)
> | (((int)bit[offset+1] & 0x00ff) << 8)
> | (int)bit[offset] & 0x00ff;
> offset += 4;
> }
> // populate the int array
> /* need to recalculate size because the offset used for palette
> must be substracted
> * to overall size, else we will go after the end of the byte
> array...
> */
> _size = bit.length - offset;
> int pad = (_size / _height) - _width;
> for (int j = 0; j < _height; j++) {
> for (int i = 0; i < _width; i++) {
> bitI[_width*(_height-j-1)+i] = palette [((int)bit[offset]
> & 0x00ff)];
> offset++;
> }
> offset += pad;
> }
> // black and white image
> } else if (_nbit == 1) {
> // 2 colors only (black and white image)
> int nbColors = 2;
> // Read the palette colors.
> int offset = _headerSize;
> int[] palette = new int[nbColors];
> for (int i = 0; i < nbColors; i++) {
> palette[i] = (255 & 0x00ff) << 24 | (((int)bit[offset+2] &
> 0x00ff) << 16)
> | (((int)bit[offset+1] & 0x00ff) << 8)
> | (int)bit[offset] & 0x00ff;
> offset += 4;
> }
> // populate the int array : each pixel corresponds to a bit in
> the byte array
> int pos = 7;
> byte currentByte = bit[offset];
> // padded to long words
> int pad = (_size / _height) - _width/8;
> for (int j = 0; j < _height; j++) {
> for (int i = 0; i < _width; i++) {
> if ((currentByte & (1 << pos)) != 0)
> bitI[_width*(_height-j-1)+i] = palette[1];
> else bitI[_width*(_height-j-1)+i] = palette[0];
> pos--;
> if (pos == -1) {
> pos = 7;
> offset++;
> if (offset < bit.length)
> currentByte = bit[offset];
> }
> }
> offset +=pad;
> pos = 7;
> if (offset < bit.length) currentByte = bit[offset];
> }
> }
> raster.setDataElements(0, 0, _width, _height, bitI);
> return img;
> }
--
This message was sent by Atlassian JIRA
(v6.1.5#6160)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]