*                     no scaling.
     * @return new image object
     */
    // was synchronized, not think it is needed?
    public BufferedImage getImage(Color fill, Resources resources, boolean allowScaling) {
        if (Tagger.tagging)
            Tagger.beginImage(pObjectReference, inlineImage);
        //String debugFill = (fill == null) ? "null" : Integer.toHexString(fill.getRGB());
        //System.out.println("Stream.getImage()  for: " + pObjectReference + "  fill: " + debugFill + "\n  stream: " + this);

        if (Tagger.tagging)
            Tagger.tagImage("Filter=" + getNormalisedFilterNames());

        // parse colour space
        PColorSpace colourSpace = null;
        Object o = library.getObject(entries, "ColorSpace");
        if (resources != null) {
            colourSpace = resources.getColorSpace(o);
        }
        //colorSpace = PColorSpace.getColorSpace(library, o);
        // assume b&w image is no colour space
        if (colourSpace == null) {
            colourSpace = new DeviceGray(library, null);
            if (Tagger.tagging)
                Tagger.tagImage("ColorSpace_Implicit_DeviceGray");
        }
        if (Tagger.tagging)
            Tagger.tagImage("ColorSpace=" + colourSpace.getDescription());

        boolean imageMask = isImageMask();
        if (Tagger.tagging)
            Tagger.tagImage("ImageMask=" + imageMask);
        if (imageMask)
            allowScaling = false;

        // find out the number of bits in the image
        int bitspercomponent = library.getInt(entries, "BitsPerComponent");
        if (imageMask && bitspercomponent == 0) {
            bitspercomponent = 1;
            if (Tagger.tagging)
                Tagger.tagImage("BitsPerComponent_Implicit_1");
        }
        if (Tagger.tagging)
            Tagger.tagImage("BitsPerComponent=" + bitspercomponent);

        // get dimension of image stream
        int width = library.getInt(entries, "Width");
        int height = library.getInt(entries, "Height");

        // check for available memory, get colour space and bit count
        // to better estimate size of image in memory
        int colorSpaceCompCount = colourSpace.getNumComponents();

        // parse decode information
        Vector<Integer> decode = (Vector) library.getObject(entries, "Decode");
        if (decode == null) {
            int depth = colourSpace.getNumComponents();
            decode = new Vector<Integer>(depth);
            // add a decode param for each colour channel.
            for (int i= 0; i < depth; i++){
                decode.addElement(0);
                decode.addElement(1);
            }
            if (Tagger.tagging)
                Tagger.tagImage("Decode_Implicit_01");
        }
        if (Tagger.tagging)
            Tagger.tagImage("Decode=" + decode);

        BufferedImage smaskImage = null;
        BufferedImage maskImage = null;
        int[] maskMinRGB = null;
        int[] maskMaxRGB = null;
        int maskMinIndex = -1;
        int maskMaxIndex = -1;
        Object smaskObj = library.getObject(entries, "SMask");
        Object maskObj = library.getObject(entries, "Mask");
        if (smaskObj instanceof Stream) {
            if (Tagger.tagging)
                Tagger.tagImage("SMaskStream");
            Stream smaskStream = (Stream) smaskObj;
            if (smaskStream.isImageSubtype())
                smaskImage = smaskStream.getImage(fill, resources, false);
        }
        if (smaskImage != null) {
            if (Tagger.tagging)
                Tagger.tagImage("SMaskImage");
            allowScaling = false;
        }
        if (maskObj != null && smaskImage == null) {
            if (maskObj instanceof Stream) {
                if (Tagger.tagging)
                    Tagger.tagImage("MaskStream");
                Stream maskStream = (Stream) maskObj;
                if (maskStream.isImageSubtype()) {
                    maskImage = maskStream.getImage(fill, resources, false);
                    if (maskImage != null) {
                        if (Tagger.tagging)
                            Tagger.tagImage("MaskImage");
                    }
                }
            } else if (maskObj instanceof Vector) {
                if (Tagger.tagging)
                    Tagger.tagImage("MaskVector");
                Vector maskVector = (Vector) maskObj;
                int[] maskMinOrigCompsInt = new int[colorSpaceCompCount];
                int[] maskMaxOrigCompsInt = new int[colorSpaceCompCount];
                for (int i = 0; i < colorSpaceCompCount; i++) {
                    if ((i * 2) < maskVector.size())
                        maskMinOrigCompsInt[i] = ((Number) maskVector.get(i * 2)).intValue();
                    if ((i * 2 + 1) < maskVector.size())
                        maskMaxOrigCompsInt[i] = ((Number) maskVector.get(i * 2 + 1)).intValue();
                }
                if (colourSpace instanceof Indexed) {
                    Indexed icolourSpace = (Indexed) colourSpace;
                    Color[] colors = icolourSpace.accessColorTable();
                    if (colors != null &&
                            maskMinOrigCompsInt.length >= 1 &&
                            maskMaxOrigCompsInt.length >= 1) {
                        maskMinIndex = maskMinOrigCompsInt[0];
                        maskMaxIndex = maskMaxOrigCompsInt[0];
                        if (maskMinIndex >= 0 && maskMinIndex < colors.length &&
                                maskMaxIndex >= 0 && maskMaxIndex < colors.length) {
                            Color minColor = colors[maskMinOrigCompsInt[0]];
                            Color maxColor = colors[maskMaxOrigCompsInt[0]];
                            maskMinRGB = new int[]{minColor.getRed(), minColor.getGreen(), minColor.getBlue()};
                            maskMaxRGB = new int[]{maxColor.getRed(), maxColor.getGreen(), maxColor.getBlue()};
                        }
                    }
                } else {
                    PColorSpace.reverseInPlace(maskMinOrigCompsInt);
                    PColorSpace.reverseInPlace(maskMaxOrigCompsInt);
                    float[] maskMinOrigComps = new float[colorSpaceCompCount];
                    float[] maskMaxOrigComps = new float[colorSpaceCompCount];
                    colourSpace.normaliseComponentsToFloats(maskMinOrigCompsInt, maskMinOrigComps, (1 << bitspercomponent) - 1);
                    colourSpace.normaliseComponentsToFloats(maskMaxOrigCompsInt, maskMaxOrigComps, (1 << bitspercomponent) - 1);

                    Color minColor = colourSpace.getColor(maskMinOrigComps);
                    Color maxColor = colourSpace.getColor(maskMaxOrigComps);
                    PColorSpace.reverseInPlace(maskMinOrigComps);
                    PColorSpace.reverseInPlace(maskMaxOrigComps);
                    maskMinRGB = new int[]{minColor.getRed(), minColor.getGreen(), minColor.getBlue()};
                    maskMaxRGB = new int[]{maxColor.getRed(), maxColor.getGreen(), maxColor.getBlue()};
                }
            }
        }

        BufferedImage img = getImage(
                colourSpace, fill,
                width, height,
                colorSpaceCompCount,
                bitspercomponent,
                imageMask,
                decode,
                smaskImage,
                maskImage,
                maskMinRGB, maskMaxRGB,
                maskMinIndex, maskMaxIndex);
        if (img != null) {
            img = putIntoImageCache(img, width, height, allowScaling);
        }
//String title = "Image: " + getPObjectReference();
//CCITTFax.showRenderedImage(img, title);
        if (Tagger.tagging)
            Tagger.endImage(pObjectReference);
        return img;
    }