function bytes = figToImStream(varargin)   
%     figToImStream Streams out a snapshot of a figure represented by 
%       a byte array encoded in the format specified. 
%
%     figToImStream
%       figToImStream alone creates a signed byte array with the png data 
%       for the current figure.  The size and position of the printed 
%       output depends on the figure's PaperPosition[mode] properties.
%
%     figToImStream('figHandle', <Figure Handle>, ...)
%       You can optionally specific the figure output to be used.
%       The Default is the current image
%
%     figToImStream('imageFormat', <imageFormat>, ...)
%       You can optionally specify an image format to convert to.
%       The valid types are:
%           png
%           jpg
%           bmp
%           gif
%       The Default is png
%
%     figToImStream('outputType', <outputType>)
%       You can optionally specify an output data type for the bytes.
%       The valid types are:
%           int8    (signed byte)   Used for the java primitive Byte
%           uint8   (unsigned byte) Used for the .NET primitive Byte
%       The default is int8
%
%      figToImStream( ... )
%        Same as above only this is a comma separated parenthesized 
%        argument list. It allows the passing of variables for any or all 
%        of the input arguments.
%
%   Examples:
%   
%   Convert the current figure to a signed png byte array:
%       surf(peaks)
%       bytes = figToImStream;
%   
%   Convert a specific figure to an unsigned bmp byte array:
%       f = figure;
%       surf(peaks)
%       bytes = figToImStream('figHandle', f, ...
%                             'imageFormat', 'bmp', ...
%                             'outputType', 'uint8');
%

% Copyright 2007-2016 The MathWorks, Inc.

    % First parsing: check data type of imageFormat and outputType
    p = inputParser;
       
    %If no figure is passed in use the current figure
    p.addOptional('figHandle',get(0,'CurrentFigure'), ...
        @(x)~isempty(x) && ishghandle(x) && strcmp(get(x,'type'),'figure'))
    
    %If no image format is passed in use PNG
    p.addOptional('imageFormat','png', ...
        @(x)validateattributes(x,{'char','string'},{'scalartext'}, ...
        'figToImStream','imageFormat'))

    %If no outputType is specified use int8
    p.addOptional('outputType','int8', ...
        @(x)validateattributes(x,{'char','string'},{'scalartext'}, ...
        'figToImStream','outputType'))
    p.parse(varargin{:});
    
    % Ensure imageFormat is a valid option
    if ~any(strcmpi(p.Results.imageFormat,{'png','gif','bmp','jpg'}))
        error(message('Compiler:figToImStream:InvalidImageFormat', ...
            char(p.Results.imageFormat)))
    end
    
    % Ensure outputType is a valid option
    if ~any(strcmpi(p.Results.outputType,{'int8', 'uint8'}))
        error(message('Compiler:figToImStream:InvalidOutputType', ...
            char(p.Results.outputType)))
    end
    
    % Check that a figure exists 
    %(if you clear all variables there is no GCF)
    if(isempty(p.Results.figHandle))
        error(message('Compiler:figToImStream:InvalidFigureHandle'));
    end
    
    %Get the MATLAB pixel representation of the figure
    pixels = hardcopyOutput(p.Results.figHandle);

    %Required java classes to convert image.
	import java.awt.image.BufferedImage;
	import java.awt.image.DataBufferInt;
	import java.awt.image.DataBuffer;
	import java.awt.image.ComponentSampleModel;
	import java.awt.image.Raster;
	import java.io.ByteArrayOutputStream;
	import javax.imageio.ImageIO;

    %This creates a model that depicts how
    %  our pixel information is stored
	[rows,cols,planes] = size(pixels);
	dataBuffer = DataBufferInt(pixels(:), rows*cols*planes);
	sampleModel = ComponentSampleModel( DataBuffer.TYPE_INT, ...
                                        cols, ...
                                        rows, ...
                                        rows, ...
                                        1,...
                        				[0,rows*cols,2*rows*cols]);
                                    
    %We then use a Raster to map the array data into 
    %  a java raster using the infromation in the model
	raster = Raster.createRaster(sampleModel,dataBuffer,[]);

    %Create a buffered image that is the size of our image
	buffImage = BufferedImage(cols,rows,BufferedImage.TYPE_INT_RGB);
    %Fill it with the data from the raster
    buffImage.setData(raster);

	stream = ByteArrayOutputStream;
    %Convert the buffered Image to a stream
	ImageIO.write(buffImage, char(p.Results.imageFormat), stream);

    %Return the stream as a byte array
    bytes = typecast(stream.toByteArray, char(p.Results.outputType));
end
