155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/*
255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * you may not use this file except in compliance with the License.
655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * You may obtain a copy of the License at
755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * See the License for the specific language governing permissions and
1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * limitations under the License.
1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */
1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
1755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpackage com.android.ddmlib;
1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
194eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohetimport java.nio.ByteBuffer;
204eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
2155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/**
2255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Data representing an image taken from a device frame buffer.
2355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */
2455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpublic final class RawImage {
254eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int version;
2655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public int bpp;
2755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public int size;
2855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public int width;
2955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public int height;
304eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int red_offset;
314eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int red_length;
324eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int blue_offset;
334eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int blue_length;
344eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int green_offset;
354eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int green_length;
364eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int alpha_offset;
374eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int alpha_length;
3855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
3955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public byte[] data;
404eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
414eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    /**
424eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * Reads the header of a RawImage from a {@link ByteBuffer}.
434eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * <p/>The way the data is sent over adb is defined in system/core/adb/framebuffer_service.c
444eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * @param version the version of the protocol.
454eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * @param buf the buffer to read from.
464eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * @return true if success
474eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     */
484eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public boolean readHeader(int version, ByteBuffer buf) {
494eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        this.version = version;
504eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
514eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        if (version == 16) {
524eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            // compatibility mode with original protocol
534eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.bpp = 16;
544eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
554eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            // read actual values.
564eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.size = buf.getInt();
574eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.width = buf.getInt();
584eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.height = buf.getInt();
594eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
604eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            // create default values for the rest. Format is 565
614eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.red_offset = 11;
624eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.red_length = 5;
634eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.green_offset = 5;
644eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.green_length = 6;
654eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.blue_offset = 0;
664eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.blue_length = 5;
674eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.alpha_offset = 0;
684eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.alpha_length = 0;
694eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        } else if (version == 1) {
704eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.bpp = buf.getInt();
714eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.size = buf.getInt();
724eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.width = buf.getInt();
734eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.height = buf.getInt();
744eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.red_offset = buf.getInt();
754eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.red_length = buf.getInt();
764eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.blue_offset = buf.getInt();
774eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.blue_length = buf.getInt();
784eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.green_offset = buf.getInt();
794eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.green_length = buf.getInt();
804eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.alpha_offset = buf.getInt();
814eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            this.alpha_length = buf.getInt();
824eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        } else {
834eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            // unsupported protocol!
844eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            return false;
854eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        }
864eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
874eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        return true;
884eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    }
894eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
904eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    /**
914eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * Returns the mask value for the red color.
924eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
934eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     */
944eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int getRedMask() {
954eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        return getMask(red_length, red_offset);
964eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    }
974eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
984eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    /**
994eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * Returns the mask value for the green color.
1004eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
1014eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     */
1024eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int getGreenMask() {
1034eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        return getMask(green_length, green_offset);
1044eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    }
1054eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
1064eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    /**
1074eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * Returns the mask value for the blue color.
1084eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
1094eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     */
1104eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public int getBlueMask() {
1114eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        return getMask(blue_length, blue_offset);
1124eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    }
1134eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
1144eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    /**
1154eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * Returns the size of the header for a specific version of the framebuffer adb protocol.
1164eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * @param version the version of the protocol
1174eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * @return the number of int that makes up the header.
1184eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     */
1194eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    public static int getHeaderSize(int version) {
1204eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        switch (version) {
1214eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            case 16: // compatibility mode
1224eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet                return 3; // size, width, height
1234eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            case 1:
1244eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet                return 12; // bpp, size, width, height, 4*(length, offset)
1254eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        }
1264eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
1274eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        return 0;
1284eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    }
1294eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
1304eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    /**
1310f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     * Returns a rotated version of the image
1320f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     * The image is rotated counter-clockwise.
1330f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     */
1340f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    public RawImage getRotated() {
1350f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        RawImage rotated = new RawImage();
1360f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.version = this.version;
1370f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.bpp = this.bpp;
1380f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.size = this.size;
1390f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.red_offset = this.red_offset;
1400f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.red_length = this.red_length;
1410f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.blue_offset = this.blue_offset;
1420f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.blue_length = this.blue_length;
1430f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.green_offset = this.green_offset;
1440f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.green_length = this.green_length;
1450f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.alpha_offset = this.alpha_offset;
1460f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.alpha_length = this.alpha_length;
1470f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1480f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.width = this.height;
1490f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.height = this.width;
1500f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1510f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        int count = this.data.length;
1520f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        rotated.data = new byte[count];
1530f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1540f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        int byteCount = this.bpp >> 3; // bpp is in bits, we want bytes to match our array
1550f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        final int w = this.width;
1560f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        final int h = this.height;
1570f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        for (int y = 0 ; y < h ; y++) {
1580f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            for (int x = 0 ; x < w ; x++) {
1590f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet                System.arraycopy(
1600f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet                        this.data, (y * w + x) * byteCount,
1610f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet                        rotated.data, ((w-x-1) * h + y) * byteCount,
1620f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet                        byteCount);
1630f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            }
1640f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        }
1650f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1660f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        return rotated;
1670f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    }
1680f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1690f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    /**
1700f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     * Returns an ARGB integer value for the pixel at <var>index</var> in {@link #data}.
1710f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     */
1720f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    public int getARGB(int index) {
1730f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        int value;
1740f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        if (bpp == 16) {
1750f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            value = data[index] & 0x00FF;
1760f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            value |= (data[index+1] << 8) & 0x0FF00;
1770f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        } else if (bpp == 32) {
1780f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            value = data[index] & 0x00FF;
1790f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            value |= (data[index+1] & 0x00FF) << 8;
1800f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            value |= (data[index+2] & 0x00FF) << 16;
1810f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            value |= (data[index+3] & 0x00FF) << 24;
1820f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        } else {
1830f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet            throw new UnsupportedOperationException("RawImage.getARGB(int) only works in 16 and 32 bit mode.");
1840f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        }
1850f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1860f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        int r = ((value >>> red_offset) & getMask(red_length)) << (8 - red_length);
1870f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        int g = ((value >>> green_offset) & getMask(green_length)) << (8 - green_length);
1880f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        int b = ((value >>> blue_offset) & getMask(blue_length)) << (8 - blue_length);
189e313f07f211def20a0392fd731271171aa96f059Xavier Ducrohet        int a;
190e313f07f211def20a0392fd731271171aa96f059Xavier Ducrohet        if (alpha_length == 0) {
191e313f07f211def20a0392fd731271171aa96f059Xavier Ducrohet            a = 0xFF; // force alpha to opaque if there's no alpha value in the framebuffer.
192e313f07f211def20a0392fd731271171aa96f059Xavier Ducrohet        } else {
193e313f07f211def20a0392fd731271171aa96f059Xavier Ducrohet            a = ((value >>> alpha_offset) & getMask(alpha_length)) << (8 - alpha_length);
194e313f07f211def20a0392fd731271171aa96f059Xavier Ducrohet        }
1950f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1960f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        return a << 24 | r << 16 | g << 8 | b;
1970f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    }
1980f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
1990f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    /**
2004eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * creates a mask value based on a length and offset.
2014eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
2024eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet     */
2034eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    private int getMask(int length, int offset) {
2040f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet        int res = getMask(length) << offset;
2054eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
2064eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        // if the bpp is 32 bits then we need to invert it because the buffer is in little endian
2074eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        if (bpp == 32) {
2084eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet            return Integer.reverseBytes(res);
2094eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        }
2104eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet
2114eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet        return res;
2124eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1Xavier Ducrohet    }
2130f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet
2140f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    /**
2150f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     * Creates a mask value based on a length.
2160f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     * @param length
2170f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     * @return
2180f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet     */
219b6f7188561f88511ed7a8685a0e9f67d5bae8558Kenny Root    private static int getMask(int length) {
220b6f7188561f88511ed7a8685a0e9f67d5bae8558Kenny Root        return (1 << length) - 1;
2210f30c14088ef1ee37e19f36ccbee67f44ea79bacXavier Ducrohet    }
22255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project}
223