javaandroidbufferunderflowexception

Buffer Underflow?


I have the following snippet of code. The marked line is causing a BufferUnderflowException. I read the documentation on the exception but still do not understand what exactly it menas. I use the .rewind() method which I was under the impression mitigates the issue.

Can anyone please enlighten me on the topic or cause of my error?

            Bitmap cameraBaseSized = BitmapFactory.decodeFile(cameraPath, opts);
            Bitmap canvasBlendSized = BitmapFactory.decodeFile(canvasPath, options);
            Bitmap result = cameraBaseSized.copy(Config.ARGB_8888, true);
            IntBuffer buffBase = IntBuffer.allocate(cameraBaseSized.getWidth()
                    * cameraBaseSized.getHeight());
            cameraBaseSized.copyPixelsToBuffer(buffBase);
            buffBase.rewind();
            IntBuffer buffBlend = IntBuffer.allocate(canvasBlendSized.getWidth()
                    * canvasBlendSized.getHeight());
            canvasBlendSized.copyPixelsToBuffer(buffBlend);
            buffBlend.rewind();
            IntBuffer buffOut = IntBuffer.allocate(cameraBaseSized.getWidth()
                    * cameraBaseSized.getHeight());
            buffOut.rewind();
            while (buffOut.position() < buffOut.limit()) {
                int filterInt = buffBlend.get(); //BUFFERUNDERFLOW EXCEPTION
                int srcInt = buffBase.get();
                int redValueFilter = Color.red(filterInt);
                int greenValueFilter = Color.green(filterInt);
                int blueValueFilter = Color.blue(filterInt);
                int redValueSrc = Color.red(srcInt);
                int greenValueSrc = Color.green(srcInt);
                int blueValueSrc = Color.blue(srcInt);
                int redValueFinal = multiply(redValueFilter, redValueSrc);
                int greenValueFinal = multiply(greenValueFilter, greenValueSrc);
                int blueValueFinal = multiply(blueValueFilter, blueValueSrc);
                int pixel = Color.argb(255, redValueFinal, greenValueFinal, blueValueFinal);
                buffOut.put(pixel);
            }
            buffOut.rewind();
            result.copyPixelsFromBuffer(buffOut);

And the exception snippet

11-29 14:41:57.347: E/AndroidRuntime(2166): Caused by: java.nio.BufferUnderflowException
11-29 14:41:57.347: E/AndroidRuntime(2166):     at java.nio.IntArrayBuffer.get(IntArrayBuffer.java:55)

I also would like to add this is happening only on specific devices, particularly samsung flavors.


Solution

  • Since it is happening on certain devices, it could be possible that you are not getting the pixel format you are expecting.

    Also if buffBlend is for any reason shorter than buffOut (which could potentially be caused by the bitmaps being different formats), you will get this exception when you try and get() past the end of it.

    EDIT:

    You could change int filterInt = buffBlend.get(); to

    int filterInt = 0;
    if (buffBlend.position() < buffBlend.limit())
        filterInt = buffBlend.get();
    

    If you do that for both of your buffers, that should protect you against the exception, and blend with black when one image is bigger than the other.