public void uploadSubTexture(int target, Image src, int index, int targetX, int targetY, int areaX, int areaY, int areaWidth, int areaHeight, boolean linearizeSrgb) {
        if (target != GL.GL_TEXTURE_2D || src.getDepth() > 1) {
            throw new UnsupportedOperationException("Updating non-2D texture is not supported");
        }

        if (src.getMipMapSizes() != null) {
            throw new UnsupportedOperationException("Updating mip-mapped images is not supported");
        }

        if (src.getMultiSamples() > 1) {
            throw new UnsupportedOperationException("Updating multisampled images is not supported");
        }

        Image.Format jmeFormat = src.getFormat();

        if (jmeFormat.isCompressed()) {
            throw new UnsupportedOperationException("Updating compressed images is not supported");
        } else if (jmeFormat.isDepthFormat()) {
            throw new UnsupportedOperationException("Updating depth images is not supported");
        }

        boolean getSrgbFormat = src.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
        GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);

        ByteBuffer data = src.getData(index);

        if (data == null) {
            throw new IndexOutOfBoundsException("The image index " + index + " is not valid for the given image");
        }

        int Bpp = src.getFormat().getBitsPerPixel() / 8;

        int srcWidth = src.getWidth();
        int cpos = data.position();
        int skip = areaX;
        skip += areaY * srcWidth;
        skip *= Bpp;

        data.position(skip);

        boolean needsStride = srcWidth != areaWidth;

        if (needsStride && (!supportUnpackRowLength)) { // doesn't support stride, copy row by row (slower).
            for (int i = 0; i < areaHeight; i++) {
                data.position(skip + (srcWidth * Bpp * i));
                gl.glTexSubImage2D(target, 0, targetX, targetY + i, areaWidth, 1, oglFormat.format, oglFormat.dataType, data);
            }
        } else {
            if (needsStride)
                gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, srcWidth);
            gl.glTexSubImage2D(target, 0, targetX, targetY, areaWidth, areaHeight, oglFormat.format, oglFormat.dataType, data);
            if (needsStride)
                gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
        }
        data.position(cpos);

    }
@deprecated Use uploadSubTexture(int target,  Image src, int index,int targetX, int targetY,int srcX,int srcY,  int areaWidth,int areaHeight, boolean linearizeSrgb)
jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java