001/* Huffman Decoder. 002 003 Copyright (c) 2004-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.actor.lib.comm; 029 030import ptolemy.data.ArrayToken; 031import ptolemy.data.BooleanToken; 032import ptolemy.data.Token; 033import ptolemy.data.type.ArrayType; 034import ptolemy.data.type.BaseType; 035import ptolemy.kernel.CompositeEntity; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.InternalErrorException; 038import ptolemy.kernel.util.NameDuplicationException; 039import ptolemy.kernel.util.Workspace; 040 041/////////////////////////////////////////////////////////////////// 042//// HuffmanCoder 043 044/** 045 Given a probability distribution and the corresponding alphabet, 046 decode the input using Huffman code and send the result to the output 047 port. Its base class HuffmanBasic generates the code book. 048 The decoder simply decode the input according to this code book. 049 050 @see HuffmanBasic 051 @see HuffmanCoder 052 @author Ye Zhou 053 @version $Id$ 054 @since Ptolemy II 4.1 055 @Pt.ProposedRating Red (zhouye) 056 @Pt.AcceptedRating Red (cxh) 057 */ 058public class HuffmanDecoder extends HuffmanBasic { 059 /** Construct an actor with the given container and name. 060 * The output and trigger ports are also constructed. 061 * @param container The container. 062 * @param name The name of this actor. 063 * @exception IllegalActionException If the entity cannot be contained 064 * by the proposed container. 065 * @exception NameDuplicationException If the container already has an 066 * actor with this name. 067 */ 068 public HuffmanDecoder(CompositeEntity container, String name) 069 throws NameDuplicationException, IllegalActionException { 070 super(container, name); 071 072 // Declare port types. 073 output.setTypeAtLeast(ArrayType.elementType(alphabet)); 074 input.setTypeEquals(BaseType.BOOLEAN); 075 } 076 077 /////////////////////////////////////////////////////////////////// 078 //// public methods //// 079 080 /** Clone the actor into the specified workspace. This calls the 081 * base class and then creates new ports and parameters. 082 * @param workspace The workspace for the new object. 083 * @return A new actor. 084 * @exception CloneNotSupportedException If a derived class contains 085 * an attribute that cannot be cloned. 086 */ 087 @Override 088 public Object clone(Workspace workspace) throws CloneNotSupportedException { 089 HuffmanDecoder newObject = (HuffmanDecoder) super.clone(workspace); 090 try { 091 newObject.output 092 .setTypeAtLeast(ArrayType.elementType(newObject.alphabet)); 093 } catch (IllegalActionException e) { 094 // Should have been caught before. 095 throw new InternalErrorException(e); 096 } 097 return newObject; 098 } 099 100 /** Generate the Huffman codebook for the given <i>pmf</i>, and 101 * encode the input into booleans and send them to the output port. 102 * @exception IllegalActionException If the input is not a decodable code. 103 */ 104 @Override 105 public void fire() throws IllegalActionException { 106 super.fire(); 107 108 ArrayToken alphabetArrayToken = (ArrayToken) alphabet.getToken(); 109 Token[] alphabetTokens = new Token[_pmf.length]; 110 111 for (int i = 0; i < _pmf.length; i++) { 112 alphabetTokens[i] = alphabetArrayToken.getElement(i); 113 } 114 115 // Get the input token. Ready for output. 116 if (!input.hasToken(0) && !_code.equals("")) { 117 throw new IllegalActionException(this, 118 "This is not a decodable code."); 119 } 120 121 BooleanToken inputToken = (BooleanToken) input.get(0); 122 123 if (inputToken.booleanValue()) { 124 _code = _code + "1"; 125 } else { 126 _code = _code + "0"; 127 } 128 129 // Find the codeword in the code book. 130 for (int i = 0; i < _pmf.length; i++) { 131 if (_code.equals(_codeBook[i])) { 132 output.send(0, alphabetTokens[i]); 133 _code = ""; 134 break; 135 } 136 } 137 } 138 139 /** Initialize the actor. set the current input string to be empty. 140 */ 141 @Override 142 public void initialize() throws IllegalActionException { 143 super.initialize(); 144 _code = ""; 145 } 146 147 /////////////////////////////////////////////////////////////////// 148 //// private variables //// 149 // The current input string, concatenated by input booleans. 150 private String _code = ""; 151}