#vulnerable code 
                                private void interpretTile(final ImageBuilder imageBuilder, final byte[] bytes,
            final int startX, final int startY, final int xLimit, final int yLimit) throws ImageReadException, IOException {
        // changes introduced May 2012
        // The following block of code implements changes that
        // reduce image loading time by using special-case processing
        // instead of the general-purpose logic from the original
        // implementation. For a detailed discussion, see the comments for
        // a similar treatment in the DataReaderStrip class
        //

        // verify that all samples are one byte in size
        final boolean allSamplesAreOneByte = isHomogenous(8);

        if (predictor != 2 && bitsPerPixel == 24 && allSamplesAreOneByte) {
            int k = 0;
            final int i0 = startY;
            int i1 = startY + tileLength;
            if (i1 > yLimit) {
                // the tile is padded past bottom of image
                i1 = yLimit;
            }
            final int j0 = startX;
            int j1 = startX + tileWidth;
            if (j1 > xLimit) {
                // the tile is padded to beyond the tile width
                j1 = xLimit;
            }
            if (photometricInterpreter instanceof PhotometricInterpreterRgb) {
                for (int i = i0; i < i1; i++) {
                    k = (i - i0) * tileWidth * 3;
                    for (int j = j0; j < j1; j++, k += 3) {
                        final int rgb = 0xff000000
                                | (((bytes[k] << 8) | (bytes[k + 1] & 0xff)) << 8)
                                | (bytes[k + 2] & 0xff);
                        imageBuilder.setRGB(j, i, rgb);
                    }
                }
            } else {
                final int[] samples = new int[3];
                for (int i = i0; i < i1; i++) {
                    k = (i - i0) * tileWidth * 3;
                    for (int j = j0; j < j1; j++) {
                        samples[0] = bytes[k++] & 0xff;
                        samples[1] = bytes[k++] & 0xff;
                        samples[2] = bytes[k++] & 0xff;
                        photometricInterpreter.interpretPixel(imageBuilder,
                                samples, j, i);
                    }
                }
            }
            return;
        }

        // End of May 2012 changes

        final BitInputStream bis = new BitInputStream(new ByteArrayInputStream(bytes), byteOrder);

        final int pixelsPerTile = tileWidth * tileLength;

        int tileX = 0;
        int tileY = 0;

        int[] samples = new int[bitsPerSampleLength];
        resetPredictor();
        for (int i = 0; i < pixelsPerTile; i++) {

            final int x = tileX + startX;
            final int y = tileY + startY;

            getSamplesAsBytes(bis, samples);

            if ((x < xLimit) && (y < yLimit)) {
                samples = applyPredictor(samples);
                photometricInterpreter.interpretPixel(imageBuilder, samples, x,
                        y);
            }

            tileX++;

            if (tileX >= tileWidth) {
                tileX = 0;
                resetPredictor();
                tileY++;
                bis.flushCache();
                if (tileY >= tileLength) {
                    break;
                }
            }

        }
    } 
                            #location 65 
                            #vulnerability type RESOURCE_LEAK
#fixed code
                                private void interpretTile(final ImageBuilder imageBuilder, final byte[] bytes,
            final int startX, final int startY, final int xLimit, final int yLimit) throws ImageReadException, IOException {
        // changes introduced May 2012
        // The following block of code implements changes that
        // reduce image loading time by using special-case processing
        // instead of the general-purpose logic from the original
        // implementation. For a detailed discussion, see the comments for
        // a similar treatment in the DataReaderStrip class
        //

        // verify that all samples are one byte in size
        final boolean allSamplesAreOneByte = isHomogenous(8);

        if (predictor != 2 && bitsPerPixel == 24 && allSamplesAreOneByte) {
            int k = 0;
            final int i0 = startY;
            int i1 = startY + tileLength;
            if (i1 > yLimit) {
                // the tile is padded past bottom of image
                i1 = yLimit;
            }
            final int j0 = startX;
            int j1 = startX + tileWidth;
            if (j1 > xLimit) {
                // the tile is padded to beyond the tile width
                j1 = xLimit;
            }
            if (photometricInterpreter instanceof PhotometricInterpreterRgb) {
                for (int i = i0; i < i1; i++) {
                    k = (i - i0) * tileWidth * 3;
                    for (int j = j0; j < j1; j++, k += 3) {
                        final int rgb = 0xff000000
                                | (((bytes[k] << 8) | (bytes[k + 1] & 0xff)) << 8)
                                | (bytes[k + 2] & 0xff);
                        imageBuilder.setRGB(j, i, rgb);
                    }
                }
            } else {
                final int[] samples = new int[3];
                for (int i = i0; i < i1; i++) {
                    k = (i - i0) * tileWidth * 3;
                    for (int j = j0; j < j1; j++) {
                        samples[0] = bytes[k++] & 0xff;
                        samples[1] = bytes[k++] & 0xff;
                        samples[2] = bytes[k++] & 0xff;
                        photometricInterpreter.interpretPixel(imageBuilder,
                                samples, j, i);
                    }
                }
            }
            return;
        }

        // End of May 2012 changes

        try (final BitInputStream bis = new BitInputStream(new ByteArrayInputStream(bytes), byteOrder)) {

            final int pixelsPerTile = tileWidth * tileLength;

            int tileX = 0;
            int tileY = 0;

            int[] samples = new int[bitsPerSampleLength];
            resetPredictor();
            for (int i = 0; i < pixelsPerTile; i++) {

                final int x = tileX + startX;
                final int y = tileY + startY;

                getSamplesAsBytes(bis, samples);

                if ((x < xLimit) && (y < yLimit)) {
                    samples = applyPredictor(samples);
                    photometricInterpreter.interpretPixel(imageBuilder, samples, x, y);
                }

                tileX++;

                if (tileX >= tileWidth) {
                    tileX = 0;
                    resetPredictor();
                    tileY++;
                    bis.flushCache();
                    if (tileY >= tileLength) {
                        break;
                    }
                }

            }
        }
    }