[ 
https://issues.apache.org/jira/browse/BATIK-963?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Luis Bernardo resolved BATIK-963.
---------------------------------

    Resolution: Fixed

> 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]

Reply via email to