159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage jme3tools.converters;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Image;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Image.Format;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.plugins.AWTLoader;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.awt.Transparency;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.awt.color.ColorSpace;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.awt.image.*;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.ByteBuffer;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.ByteOrder;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.EnumMap;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class ImageToAwt {
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final EnumMap<Format, DecodeParams> params
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            = new EnumMap<Format, DecodeParams>(Format.class);
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static class DecodeParams {
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int bpp, am, rm, gm, bm, as, rs, gs, bs, im, is;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        public DecodeParams(int bpp, int am, int rm, int gm, int bm, int as, int rs, int gs, int bs, int im, int is) {
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.bpp = bpp;
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.am = am;
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.rm = rm;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.gm = gm;
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.bm = bm;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.as = as;
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.rs = rs;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.gs = gs;
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.bs = bs;
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.im = im;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.is = is;
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        public DecodeParams(int bpp, int rm, int rs, int im, int is, boolean alpha){
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.bpp = bpp;
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (alpha){
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.am = rm;
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.as = rs;
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.rm = 0;
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.rs = 0;
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.rm = rm;
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.rs = rs;
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.am = 0;
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                this.as = 0;
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.gm = 0;
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.bm = 0;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.gs = 0;
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.bs = 0;
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.im = im;
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.is = is;
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        public DecodeParams(int bpp, int rm, int rs, int im, int is){
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this(bpp, rm, rs, im, is, false);
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    static {
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int mx___ = 0xff000000;
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m_x__ = 0x00ff0000;
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m__x_ = 0x0000ff00;
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m___x = 0x000000ff;
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int sx___ = 24;
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s_x__ = 16;
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s__x_ = 8;
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s___x = 0;
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int mxxxx = 0xffffffff;
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int sxxxx = 0;
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m4x___ = 0xf000;
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m4_x__ = 0x0f00;
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m4__x_ = 0x00f0;
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m4___x = 0x000f;
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s4x___ = 12;
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s4_x__ = 8;
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s4__x_ = 4;
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s4___x = 0;
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m5___  = 0xf800;
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m_5__  = 0x07c0;
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m__5_  = 0x003e;
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m___1  = 0x0001;
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s5___  = 11;
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s_5__  = 6;
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s__5_  = 1;
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s___1  = 0;
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m5__   = 0xf800;
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m_6_   = 0x07e0;
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m__5   = 0x001f;
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s5__   = 11;
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s_6_   = 5;
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s__5   = 0;
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int mxx__  = 0xffff0000;
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int sxx__  = 32;
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int m__xx  = 0x0000ffff;
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final int s__xx  = 0;
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // note: compressed, depth, or floating point formats not included here..
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.ABGR8,    new DecodeParams(4, mx___, m___x, m__x_, m_x__,
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                        sx___, s___x, s__x_, s_x__,
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                        mxxxx, sxxxx));
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.ARGB4444, new DecodeParams(2, m4x___, m4_x__, m4__x_, m4___x,
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                        s4x___, s4_x__, s4__x_, s4___x,
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                        mxxxx, sxxxx));
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Alpha16,  new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, true));
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Alpha8,   new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, true));
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.BGR8,     new DecodeParams(3, 0,     m___x, m__x_, m_x__,
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                        0,     s___x, s__x_, s_x__,
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                        mxxxx, sxxxx));
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Luminance16, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, false));
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Luminance8,  new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, false));
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Luminance16Alpha16, new DecodeParams(4, m__xx, mxx__, 0, 0,
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                  s__xx, sxx__, 0, 0,
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                  mxxxx, sxxxx));
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Luminance16F, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, false));
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Luminance16FAlpha16F, new DecodeParams(4, m__xx, mxx__, 0, 0,
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                    s__xx, sxx__, 0, 0,
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                    mxxxx, sxxxx));
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Luminance32F, new DecodeParams(4, mxxxx, sxxxx, mxxxx, sxxxx, false));
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.Luminance8,   new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, false));
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.RGB5A1,       new DecodeParams(2, m___1, m5___, m_5__, m__5_,
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            s___1, s5___, s_5__, s__5_,
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            mxxxx, sxxxx));
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.RGB565,       new DecodeParams(2, 0,     m5__ , m_6_ , m__5,
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            0,     s5__ , s_6_ , s__5,
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            mxxxx, sxxxx));
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.RGB8,         new DecodeParams(3, 0,     m_x__, m__x_, m___x,
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            0,     s_x__, s__x_, s___x,
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            mxxxx, sxxxx));
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        params.put(Format.RGBA8,        new DecodeParams(4, m___x, mx___, m_x__, m__x_,
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            s___x, sx___, s_x__, s__x_,
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                            mxxxx, sxxxx));
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static int Ix(int x, int y, int w){
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return y * w + x;
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static int readPixel(ByteBuffer buf, int idx, int bpp){
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.position(idx);
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int original = buf.get() & 0xff;
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while ((--bpp) > 0){
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            original = (original << 8) | (buf.get() & 0xff);
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return original;
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static void writePixel(ByteBuffer buf, int idx, int pixel, int bpp){
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.position(idx);
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while ((--bpp) >= 0){
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            pixel = pixel >> 8;
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            byte bt = (byte) ((pixel >> (bpp * 8)) & 0xff);
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            buf.put( (byte) (pixel & 0xff) );
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.put(bt);
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Convert an AWT image to jME image.
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void convert(BufferedImage image, Format format, ByteBuffer buf){
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        DecodeParams p = params.get(format);
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (p == null)
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException("Image format " + format + " is not supported");
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int width = image.getWidth();
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int height = image.getHeight();
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean alpha = true;
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean luminance = false;
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int reductionA = 8 - Integer.bitCount(p.am);
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int reductionR = 8 - Integer.bitCount(p.rm);
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int reductionG = 8 - Integer.bitCount(p.gm);
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int reductionB = 8 - Integer.bitCount(p.bm);
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int initialPos = buf.position();
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int y = 0; y < height; y++){
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (int x = 0; x < width; x++){
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Get ARGB
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int argb = image.getRGB(x, y);
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Extract color components
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int a = (argb & 0xff000000) >> 24;
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int r = (argb & 0x00ff0000) >> 16;
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int g = (argb & 0x0000ff00) >> 8;
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int b = (argb & 0x000000ff);
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Remove anything after 8 bits
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                a = a & 0xff;
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                r = r & 0xff;
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                g = g & 0xff;
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                b = b & 0xff;
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Set full alpha if target image has no alpha
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (!alpha)
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    a = 0xff;
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Convert color to luminance if target
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // image is in luminance format
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (luminance){
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // convert RGB to luminance
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Do bit reduction, assumes proper rounding has already been
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // done.
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                a = a >> reductionA;
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                r = r >> reductionR;
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                g = g >> reductionG;
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                b = b >> reductionB;
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Put components into appropriate positions
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                a = (a << p.as) & p.am;
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                r = (r << p.rs) & p.rm;
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                g = (g << p.gs) & p.gm;
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                b = (b << p.bs) & p.bm;
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int outputPixel = ((a | r | g | b) << p.is) & p.im;
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int i = initialPos + (Ix(x,y,width) * p.bpp);
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                writePixel(buf, i, outputPixel, p.bpp);
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final double LOG2 = Math.log(2);
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void createData(Image image, boolean mipmaps){
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int bpp = image.getFormat().getBitsPerPixel();
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int w = image.getWidth();
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int h = image.getHeight();
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!mipmaps){
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            image.setData(BufferUtils.createByteBuffer(w*h*bpp/8));
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expectedMipmaps = 1 + (int) Math.ceil(Math.log(Math.max(h, w)) / LOG2);
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int[] mipMapSizes = new int[expectedMipmaps];
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int total = 0;
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < mipMapSizes.length; i++){
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int size = (w * h * bpp) / 8;
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            total += size;
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            mipMapSizes[i] = size;
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            w /= 2;
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            h /= 2;
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        image.setMipMapSizes(mipMapSizes);
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        image.setData(BufferUtils.createByteBuffer(total));
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Convert the image from the given format to the output format.
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * It is assumed that both images have buffers with the appropriate
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of elements and that both have the same dimensions.
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param input
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param output
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void convert(Image input, Image output){
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        DecodeParams inParams  = params.get(input.getFormat());
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        DecodeParams outParams = params.get(output.getFormat());
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (inParams == null || outParams == null)
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException();
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int width  = input.getWidth();
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int height = input.getHeight();
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (width != output.getWidth() || height != output.getHeight())
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException();
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer inData = input.getData(0);
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean inAlpha = false;
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean inLum = false;
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean inRGB = false;
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (inParams.am != 0) {
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inAlpha = true;
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (inParams.rm != 0 && inParams.gm == 0 && inParams.bm == 0) {
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inLum = true;
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (inParams.rm != 0 && inParams.gm != 0 && inParams.bm != 0) {
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inRGB = true;
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionA = 8 - Integer.bitCount(inParams.am);
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionR = 8 - Integer.bitCount(inParams.rm);
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionG = 8 - Integer.bitCount(inParams.gm);
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionB = 8 - Integer.bitCount(inParams.bm);
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int inputPixel;
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int y = 0; y < height; y++){
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (int x = 0; x < width; x++){
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int i = Ix(x, y, width) * inParams.bpp;
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                inputPixel = (readPixel(inData, i, inParams.bpp) & inParams.im) >> inParams.is;
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int a = (inputPixel & inParams.am) >> inParams.as;
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int r = (inputPixel & inParams.rm) >> inParams.rs;
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int g = (inputPixel & inParams.gm) >> inParams.gs;
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int b = (inputPixel & inParams.bm) >> inParams.bs;
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                r = r & 0xff;
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                g = g & 0xff;
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                b = b & 0xff;
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                a = a & 0xff;
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                a = a << expansionA;
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                r = r << expansionR;
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                g = g << expansionG;
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                b = b << expansionB;
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (inLum)
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    b = g = r;
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (!inAlpha)
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    a = 0xff;
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                int argb = (a << 24) | (r << 16) | (g << 8) | b;
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                out.setRGB(x, y, argb);
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static BufferedImage convert(Image image, boolean do16bit, boolean fullalpha, int mipLevel){
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Format format = image.getFormat();
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        DecodeParams p = params.get(image.getFormat());
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (p == null)
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException();
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int width = image.getWidth();
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int height = image.getHeight();
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int level = mipLevel;
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while (--level >= 0){
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            width  /= 2;
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            height /= 2;
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer buf = image.getData(0);
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.order(ByteOrder.LITTLE_ENDIAN);
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        BufferedImage out;
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean alpha = false;
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean luminance = false;
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean rgb = false;
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (p.am != 0)
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            alpha = true;
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (p.rm != 0 && p.gm == 0 && p.bm == 0)
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            luminance = true;
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        else if (p.rm != 0 && p.gm != 0 && p.bm != 0)
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            rgb = true;
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // alpha OR luminance but not both
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if ( (alpha && !rgb && !luminance) || (luminance && !alpha && !rgb) ){
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            out = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if ( (rgb && alpha) || (luminance && alpha) ){
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (do16bit){
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (fullalpha){
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    ColorModel model = AWTLoader.AWT_RGBA4444;
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    WritableRaster raster = model.createCompatibleWritableRaster(width, width);
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    out = new BufferedImage(model, raster, false, null);
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }else{
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // RGB5_A1
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    int[] nBits = {5, 5, 5, 1};
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    int[] bOffs = {0, 1, 2, 3};
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false,
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                    Transparency.BITMASK,
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                    DataBuffer.TYPE_BYTE);
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                           width, height,
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                           width*2, 2,
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                                           bOffs, null);
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    out = new BufferedImage(colorModel, raster, false, null);
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                out = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else{
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (do16bit){
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                out = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_565_RGB);
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                out = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionA = 8 - Integer.bitCount(p.am);
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionR = 8 - Integer.bitCount(p.rm);
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionG = 8 - Integer.bitCount(p.gm);
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int expansionB = 8 - Integer.bitCount(p.bm);
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (expansionR < 0){
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            expansionR = 0;
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int mipPos = 0;
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < mipLevel; i++){
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            mipPos += image.getMipMapSizes()[i];
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int inputPixel;
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int y = 0; y < height; y++){
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (int x = 0; x < width; x++){
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int i = mipPos + (Ix(x,y,width) * p.bpp);
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                inputPixel = (readPixel(buf,i,p.bpp) & p.im) >> p.is;
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int a = (inputPixel & p.am) >> p.as;
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int r = (inputPixel & p.rm) >> p.rs;
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int g = (inputPixel & p.gm) >> p.gs;
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int b = (inputPixel & p.bm) >> p.bs;
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                r = r & 0xff;
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                g = g & 0xff;
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                b = b & 0xff;
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                a = a & 0xff;
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                a = a << expansionA;
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                r = r << expansionR;
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                g = g << expansionG;
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                b = b << expansionB;
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (luminance)
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    b = g = r;
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (!alpha)
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    a = 0xff;
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int argb = (a << 24) | (r << 16) | (g << 8) | b;
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                out.setRGB(x, y, argb);
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return out;
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
480