⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmap.java

📁 cygwin 是一个在windows平台上运行的unix模拟环境
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* Bitmap.java
 * Component: ProperJavaRDP
 * 
 * Revision: $Revision: 1.7 $
 * Author: $Author: telliott $
 * Date: $Date: 2005/09/27 14:15:39 $
 *
 * Copyright (c) 2005 Propero Limited
 *
 * Purpose: Provide a class for storage of Bitmap images, along with
 *          static methods for decompression and conversion of bitmaps.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 * 
 * (See gpl.txt for details of the GNU General Public License.)
 * 
 */

package net.propero.rdp;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;

import org.apache.log4j.Logger;

public class Bitmap {

    public int usage;
    
	private int[] highdata = null;

	private int width = 0;

	private int height = 0;

	private int x = 0;

	private int y = 0;

	protected static Logger logger = Logger.getLogger(Rdp.class);
  
    public static int convertTo24(int colour){
        if(Options.server_bpp == 15) return convert15to24(colour);
        if(Options.server_bpp == 16) return convert16to24(colour);
        return colour;
    }
    
    
    public static int convert15to24(int colour16){
        int r24 = (colour16 >> 7) & 0xF8;
        int g24 = (colour16 >> 2) & 0xF8;
        int b24 = (colour16 << 3) & 0xFF;
        
        r24 |= r24 >> 5;
        g24 |= g24 >> 5;
        b24 |= b24 >> 5;
        
        return (r24 << 16) | (g24 << 8) | b24;
    }
    
    public static int convert16to24(int colour16){
        int r24 = (colour16 >> 8) & 0xF8;
        int g24 = (colour16 >> 3) & 0xFC;
        int b24 = (colour16 << 3) & 0xFF;
        
        r24 |= r24 >> 5;
        g24 |= g24 >> 6;
        b24 |= b24 >> 5;
        
        return (r24 << 16) | (g24 << 8) | b24;
    }
    
	private static int bmpCount = 0;

    /**
     * Read integer of a specified byte-length from byte array
     * @param data Array to read from
     * @param offset Offset in array to read from
     * @param Bpp Number of bytes to read
     * @return
     */
	static int cvalx(byte[] data, int offset, int Bpp) {
		int rv = 0;
        if(Options.server_bpp == 15){
            int lower = data[offset] & 0xFF;
            int full = (data[offset + 1] & 0xFF) << 8 | lower;     
            
            int r24 = (full >> 7) & 0xF8;   r24 |= r24 >> 5;
            int g24 = (full >> 2) & 0xF8;   g24 |= g24 >> 5;
            int b24 = (lower << 3) & 0xFF;  b24 |= b24 >> 5;
            
            return (r24 << 16) | (g24 << 8) | b24;
            
        }else if(Options.server_bpp == 16){
            int lower = data[offset] & 0xFF;
            int full = (data[offset + 1] & 0xFF) << 8 | lower;          

            int r24 = (full >> 8) & 0xF8;   r24 |= r24 >> 5;
            int g24 = (full >> 3) & 0xFC;   g24 |= g24 >> 6;
            int b24 = (lower << 3) & 0xFF;  b24 |= b24 >> 5;
            
            return (r24 << 16) | (g24 << 8) | b24;
            
        }else{
            for (int i = (Bpp - 1); i >= 0; i--) {
                rv = rv << 8;
                rv |= data[offset + i] & 0xFF;
            }
        }
        
		return rv;
	}

	/**
     * 
     * @param input
     * @param startOffset
     * @param offset
     * @param Bpp
     * @return
	 */
	static int getli(byte[] input, int startOffset, int offset, int Bpp) {
		int rv = 0;

		int rOffset = startOffset + (offset * Bpp);
		for (int i = 0; i < Bpp; i++) {
			rv = rv << 8;
			rv |= (input[rOffset + (Bpp - i - 1)]) & 0xFF;
		}
		return rv;
	}

    /**
     * 
     * @param input
     * @param startlocation
     * @param offset
     * @param value
     * @param Bpp
     */
	static void setli(byte[] input, int startlocation, int offset, int value,
			int Bpp) {
		int location = startlocation + offset * Bpp;

		input[location] = (byte) (value & 0xFF);
		if (Bpp > 1)
			input[location + 1] = (byte) ((value & 0xFF00) >> 8);
		if (Bpp > 2)
			input[location + 2] = (byte) ((value & 0xFF0000) >> 16);
	}

    /**
     * Convert byte array representing a bitmap into integer array of pixels
     * @param bitmap Byte array of bitmap data
     * @param Bpp Bytes-per-pixel for bitmap
     * @return Integer array of pixel data representing input image data
     */
	static int[] convertImage(byte[] bitmap, int Bpp) {
		int[] out = new int[bitmap.length / Bpp];

		for (int i = 0; i < out.length; i++) {
			if (Bpp == 1)
				out[i] = bitmap[i] & 0xFF;
			else if (Bpp == 2)
				out[i] = ((bitmap[i * Bpp + 1] & 0xFF) << 8)
						| (bitmap[i * Bpp] & 0xFF);
			else if (Bpp == 3)
				out[i] = ((bitmap[i * Bpp + 2] & 0xFF) << 16)
						| ((bitmap[i * Bpp + 1] & 0xFF) << 8)
						| (bitmap[i * Bpp] & 0xFF);
			out[i] = Bitmap.convertTo24(out[i]);
		}
		return out;
	}

    /**
     * Constructor for Bitmap based on integer pixel values
     * @param data Array of pixel data, one integer per pixel. Should have a length of width*height.
     * @param width Width of bitmap represented by data
     * @param height Height of bitmap represented by data
     * @param x Desired x-coordinate of bitmap 
     * @param y Desired y-coordinate of bitmap
     */
	public Bitmap(int[] data, int width, int height, int x, int y) {
		this.highdata = data;
		this.width = width;
		this.height = height;
		this.x = x;
		this.y = y;
	}
    
    /**
     * Constructor for Bitmap based on 
     * @param data Array of pixel data, each pixel represented by Bpp bytes. Should have a length of width*height*Bpp.
     * @param width Width of bitmap represented by data
     * @param height Height of bitmap represented by data
     * @param x Desired x-coordinate of bitmap 
     * @param y Desired y-coordinate of bitmap
     * @param Bpp Number of bytes per pixel in image represented by data
     */
    public Bitmap(byte[] data, int width, int height, int x, int y, int Bpp) {
        this.highdata = Bitmap.convertImage(data,Bpp);
        this.width = width;
        this.height = height;
        this.x = x;
        this.y = y;
    }

    /**
     * Retrieve data representing this Bitmap, as an array of integer pixel values 
     * @return Bitmap pixel data
     */
    public int[] getBitmapData() {
		return this.highdata;
	}

    /**
     * Retrieve width of the bitmap represented by this object
     * @return Bitmap width
     */   
    public int getWidth() {
		return this.width;
	}
    
    /**
     * Retrieve height of the bitmap represented by this object
     * @return Bitmap height
     */
	public int getHeight() {
		return this.height;
	}

    /**
     * Retrieve desired x-coordinate of the bitmap represented by this object
     * @return x-coordinate of this bitmap
     */
	public int getX() {
		return this.x;
	}

    /**
     * Retrieve desired y-coordinate of the bitmap represented by this object
     * @return y-coordinate of this bitmap
     */
	public int getY() {
		return this.y;
	}
    
	/**
     * Decompress bitmap data from packet and output directly to supplied image object
     * @param width Width of bitmap to decompress
     * @param height Height of bitmap to decompress
     * @param size Size of compressed data in bytes
     * @param data Packet containing bitmap data
     * @param Bpp Bytes per-pixel for bitmap
     * @param cm Colour model of bitmap
     * @param left X offset for drawing bitmap
     * @param top Y offset for drawing bitmap
     * @param w Image to draw bitmap to
     * @return Original image object, with decompressed bitmap drawn at specified coordinates
     * @throws RdesktopException
	 */
    public static WrappedImage decompressImgDirect(int width, int height, int size, RdpPacket_Localised data, int Bpp, IndexColorModel cm, int left, int top, WrappedImage w) throws RdesktopException {

        //WrappedImage w = null;
        
        byte[] compressed_pixel = new byte[size];
        data.copyToByteArray(compressed_pixel, 0, data.getPosition(), size);
        data.incrementPosition(size);

        int previous = -1, line = 0, prevY = 0;
        int input = 0, end = size;
        int opcode = 0, count = 0, offset = 0, x = width;
        int lastopcode = -1, fom_mask = 0;
        int code = 0, color1 = 0, color2 = 0;
        byte mixmask = 0;
        int mask = 0;
        int mix = 0xffffffff;

        boolean insertmix = false, bicolor = false, isfillormix = false;
        
        while (input < end) {
            fom_mask = 0;
            code = (compressed_pixel[input++] & 0x000000ff);
            opcode = code >> 4;

            /* Handle different opcode forms */
            switch (opcode) {
            case 0xc:
            case 0xd:
            case 0xe:
                opcode -= 6;
                count = code & 0xf;
                offset = 16;
                break;

            case 0xf:
                opcode = code & 0xf;
                if (opcode < 9) {
                    count = (compressed_pixel[input++] & 0xff);
                    count |= ((compressed_pixel[input++] & 0xff) << 8);
                } else {
                    count = (opcode < 0xb) ? 8 : 1;
                }
                offset = 0;
                break;

            default:
                opcode >>= 1;
                count = code & 0x1f;
                offset = 32;
                break;
            }

            /* Handle strange cases for counts */
            if (offset != 0) {
                isfillormix = ((opcode == 2) || (opcode == 7));

                if (count == 0) {
                    if (isfillormix)
                        count = (compressed_pixel[input++] & 0x000000ff) + 1;
                    else
                        count = (compressed_pixel[input++] & 0x000000ff)
                                + offset;
                } else if (isfillormix) {
                    count <<= 3;
                }
            }

            switch (opcode) {
            case 0: /* Fill */
                if ((lastopcode == opcode)
                        && !((x == width) && (previous == -1)))
                    insertmix = true;
                break;
            case 8: /* Bicolor */
                color1 = cvalx(compressed_pixel, input, Bpp);
                    //(compressed_pixel[input++]&0x000000ff);
                input += Bpp;
            case 3: /* Color */
                color2 = cvalx(compressed_pixel, input, Bpp);
                //color2 = (compressed_pixel[input++]&0x000000ff);
                input += Bpp;
                break;
            case 6: /* SetMix/Mix */
            case 7: /* SetMix/FillOrMix */
                // mix = compressed_pixel[input++];
                mix = cvalx(compressed_pixel, input, Bpp);
                input += Bpp;
                opcode -= 5;
                break;
            case 9: /* FillOrMix_1 */
                mask = 0x03;
                opcode = 0x02;
                fom_mask = 3;
                break;
            case 0x0a: /* FillOrMix_2 */
                mask = 0x05;
                opcode = 0x02;
                fom_mask = 5;
                break;

            }

            lastopcode = opcode;
            mixmask = 0;

            /* Output body */
            while (count > 0) {
               if (x >= width) {
                   if (height <= 0) throw new RdesktopException("Decompressing bitmap failed! Height = " + height);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -