/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * 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 Lesser General Public License for more details. * * Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved. */ package org.pentaho.reporting.libraries.pixie.wmf.bitmap; import java.io.IOException; import java.io.InputStream; public class RGBCompression extends BitmapCompression { public RGBCompression() { } public int[] decompress( final InputStream in, final GDIPalette palette ) throws IOException { final int[] target = new int[ getWidth() * getHeight() ]; switch( getBpp() ) { case 1: fillMono( target, in, palette ); break; case 4: fill4Bit( target, in, palette ); break; case 8: fill8Bit( target, in, palette ); break; case 16: fill16Bit( target, in, palette ); break; case 24: fill24Bit( target, in, palette ); break; case 32: fill32Bit( target, in, palette ); break; } return target; } /** * Cut or padd the string to the given size * * @param size the wanted length * @param padChar char to use for padding (must be of length()==1!) * @return the string with correct lenght, padded with pad if necessary */ public static String forceToSizeLeft( final String str, final int size, final char padChar ) { if ( str != null && str.length() == size ) { return str; } final StringBuffer tmp; if ( str == null ) { tmp = new StringBuffer( size ); } else { tmp = new StringBuffer( str ); } if ( tmp.length() > size ) { tmp.setLength( size ); return tmp.toString(); // do cutting } else { final StringBuffer t2 = new StringBuffer( size ); final int arsize = size - tmp.length(); final char[] ar = new char[ arsize ]; for ( int i = 0; i < arsize; i++ ) { ar[ i ] = padChar; } t2.append( ar ); t2.append( tmp ); return t2.toString(); } } public void fillMono( final int[] target, final InputStream in, final GDIPalette pal ) throws IOException { final int noOfBytes = (int) Math.ceil( target.length / 8 ); if ( isTopDown() == false ) { for ( int i = noOfBytes - 1; i >= 0; i-- ) { final int iByte = readInt( in ); if ( iByte == -1 ) { return; } final int[] data = expandMonocrome( iByte, pal ); final int left = ( target.length - i * 8 ); final int size = Math.min( 8, left ); for ( int ij = size - 1; ij >= 0; ij-- ) { target[ 7 - ij + i * 8 ] = data[ ij ]; } } } else { for ( int i = 0; i < noOfBytes; i++ ) { final int iByte = readInt( in ); if ( iByte == -1 ) { return; } final int[] data = expandMonocrome( iByte, pal ); System.arraycopy( data, 0, target, i * 8, 8 ); } } } public void fill4Bit( final int[] target, final InputStream in, final GDIPalette pal ) throws IOException { final int noOfBytes = (int) Math.ceil( target.length / 2 ); if ( isTopDown() == false ) { for ( int i = noOfBytes - 1; i >= 0; i-- ) { final int iByte = in.read(); if ( iByte == -1 ) { return; } final int[] data = expand4BitTuple( iByte, pal ); target[ i * 2 ] = data[ 1 ]; target[ i * 2 + 1 ] = data[ 0 ]; } } else { for ( int i = 0; i < noOfBytes; i++ ) { final int iByte = in.read(); if ( iByte == -1 ) { return; } final int[] data = expand4BitTuple( iByte, pal ); target[ i * 2 ] = data[ 0 ]; target[ i * 2 + 1 ] = data[ 1 ]; } } } public void fill8Bit( final int[] target, final InputStream in, final GDIPalette pal ) throws IOException { final int noOfBytes = target.length; if ( isTopDown() == false ) { for ( int i = noOfBytes - 1; i >= 0; i-- ) { final int iByte = in.read(); if ( iByte == -1 ) { return; } target[ i ] = pal.lookupColor( iByte ); } } else { for ( int i = 0; i < noOfBytes; i++ ) { final int iByte = in.read(); if ( iByte == -1 ) { return; } target[ i ] = pal.lookupColor( iByte ); } } } public void fill16Bit( final int[] target, final InputStream in, final GDIPalette pal ) throws IOException { final int noOfBytes = target.length * 2; if ( isTopDown() == false ) { for ( int i = noOfBytes - 1; i >= 0; i-- ) { final int iByte = in.read(); if ( iByte == -1 ) { return; } final int iByte2 = in.read(); if ( iByte2 == -1 ) { return; } target[ i ] = pal.lookupColor( ( iByte2 << 8 ) + iByte ); } } else { for ( int i = 0; i < noOfBytes; i++ ) { final int iByte = in.read(); if ( iByte == -1 ) { return; } final int iByte2 = in.read(); if ( iByte2 == -1 ) { return; } target[ i ] = pal.lookupColor( ( iByte2 << 8 ) + iByte ); } } } public void fill24Bit( final int[] target, final InputStream in, final GDIPalette pal ) throws IOException { final int noOfBytes = target.length * 4; if ( isTopDown() == false ) { for ( int i = noOfBytes - 1; i >= 0; i-- ) { target[ i ] = pal.lookupColor( readInt( in ) ); } } else { for ( int i = 0; i < noOfBytes; i++ ) { target[ i ] = pal.lookupColor( readInt( in ) ); } } } public void fill32Bit( final int[] target, final InputStream in, final GDIPalette pal ) throws IOException { final int noOfBytes = target.length * 4; if ( isTopDown() == false ) { for ( int i = noOfBytes - 1; i >= 0; i-- ) { target[ i ] = pal.lookupColor( readInt( in ) ); } } else { for ( int i = 0; i < noOfBytes; i++ ) { target[ i ] = pal.lookupColor( readInt( in ) ); } } } protected int readInt( final InputStream in ) throws IOException { final int iByte = in.read(); if ( iByte == -1 ) { return -1; } final int iByte2 = in.read(); if ( iByte2 == -1 ) { return -1; } final int iByte3 = in.read(); if ( iByte3 == -1 ) { return -1; } final int iByte4 = in.read(); if ( iByte4 == -1 ) { return -1; } return ( ( iByte4 << 24 ) + ( iByte3 << 16 ) + ( iByte2 << 8 ) + ( iByte ) ); } }