# E.S.O. - VLT project 
#
# "@(#) $Id: ImageData.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" 
#
# This file is processed by the ESO/VLT docDoManPages command to
# produce a man page in nroff, TeX and MIF formats. 
# See docDoManPages(1) for a description of the input format.
# 
# who             when       what
# --------------  ---------  ----------------------------------------
# Allan Brighton  20 Jul 95  Created
#                 21 Feb 96  Renamed from RTI to ImageData
#                 30 Sep 96  updated
#

NAME
ImageData - C++ Base Class for Managing Image Data

SYNOPSIS
#include "ImageData.h"

class ImageData {
...
public:
    // maximum scale factor
    enum {MAX_IMAGE_SCALE = 50};

    // types of color scaling
    enum ImageColorScaleType {
	LINEAR_SCALE,		// linear scale
	LOG_SCALE,		// logarithmic or exponential scale
	SQRT_SCALE,		// square root scale
	HISTEQ_SCALE		// histogram equalization
    };

    virtual ~ImageData();

    static ImageData* makeImage(const char* name, const ImageIO&, int verbose = 0);

    int write(const char* filename);
   
    void doTrans(double& x, double& y, int distFlag = 0, 
		 double xOffset = 0.0, double yOffset = 0.0, 
		 int width = 0, int height = 0);

    void undoTrans(double& x, double& y, int distFlag = 0, 
		   double xOffset = 0.0, double yOffset = 0.0, 
		   int width = 0, int height = 0);

    void coordsToDist(double& x, double& y, int width = 0, int height = 0);
    void distToCoords(double& x, double& y, int width = 0, int height = 0);
    int getIndex(double x, double y, int& ix, int& iy);
    void setXImageData(byte* xImage, int width, int height);
    void setScale(int xScale, int yScale);
    void shrinkToFit(int width, int height);
    void update();
    void updateOffset(double x, double y);
    virtual void getDist(int& numValues, double* xyvalues);
    int getSpectrum(double* xyvalues, int x0, int y0, int x1, int y1);
    virtual void setCutLevels(double min, double max, int scaled);
    virtual void autoSetCutLevels(double percent = 98.0);
    virtual void medianFilter(double* pattern = NULL);
    virtual void colorScale(int ncolors, unsigned long* colors);
    virtual int dataType() = 0;
    virtual ImageData* copy() = 0;
    void saveParams(ImageDataParams&);
    void restoreParams(ImageDataParams&);
    virtual char* getValue(char* buf, double x, double y) = 0;

    virtual void getValues(double x, double y, double rx, double ry, 
			   char* xStr, char* yStr, char* valueStr,
			   char* raStr, char* decStr, char* equinoxStr) = 0;

    virtual void getValues(double x, double y, double* ar, int nrows, int ncols) = 0;
    virtual void getValues(double x, double y, int w, int h, float* ar) = 0;

    virtual double getValue(double x, double y) = 0;
    virtual int getStatistics(double x, double y, int w, int h, 
			      double& meanX, double& meanY,
			      double& fwhmX, double& fwhmY,
			      double& symetryAngle, 
			      double& objectPeak, double& meanBackground);
    
    Mem& data();
    Mem& header();
    
    int getFitsHeader(ostream& os);
    
    void data(const Mem& data);
    void header(const Mem& header);
    
    WCS& wcs();

    byte* xImage();
    const ImageIO& image();
    void colorScaleType(ImageColorScaleType t);
    ImageColorScaleType colorScaleType();
    int ncolors();
    unsigned long* colors();
    unsigned long color0();
    unsigned long colorn();
    void setColors(int ncolors, unsigned long* colors);
    void expo(double e);
    double expo();
    int width();
    int height();
    int dispWidth();
    int dispHeight();
    int xScale();
    int yScale();
    int flipX();
    void flipX(int b);
    int flipY();
    void flipY(int b);
    int rotate();
    void rotate(int);
    double highCut();
    double lowCut();
    double minValue();
    double maxValue();
    void subsample(int b);
    void verbose(int b);
    void name(const char* name);
    char* name();
    void object(const char *object);
    char* object();
    int update_pending();
    void update_pending(int b);
    LookupTable lookup();
    int lookup(LookupTable);
    void clear();
};


DESCRIPTION
This class is part of the RTI or Real-Time Image library and is
independent of X and Tcl/Tk, so it could, in principle, be used by a
separate process from the one displaying the image.  Class ImageData
is used for managing the image data and the conversion of the raw
image data to X image data with transformations (scaling, flipping and
rotating). Note that the term "X image", in this case refers to a
pointer to an array of bytes and not the XImage struct itself, which
is used to actually display the image later. The base class ImageData
is the only class visible to the outside, however, there is one
subclass for each underlying raw image data type. These subclasses
implement the type specific operations on the raw image. Here is the
class hierarchy:

ImageData
	Base class, only class visible outside.

   ShortImageData   
   UShortImageData     
   ByteImageData	      
   LongImageData
   FloatImageData
	Derived classed for images with the raw data types: short,
	ushort, byte, long and float
            
   XImageData
	This class is like ByteImageData, except that the raw image is
	already in XImage format (i.e.: different Y axis direction and
	no need for color scaling or cut levels).

CREATING AN IMAGE OBJECT
The ImageData class is designed to work, in principle, independently
of the actual image format, although in the end, something resembling
FITS format is expected. An ImageData object can be created with the
"makeImage()" method.

ImageData::makeImage() takes an arbitrary image name, an ImageIO
object, and a verbose flag and returns a pointer to an object that is
a subclass of ImageData specialized in the data type for that image
(ShortImageData, FloatImageData, etc.). 

The caller creates the ImageIO object and can control how the image is
constructed. ImageIO is a reference counted class that can be
initialized with a pointer to a subclass of ImageIORep. The astrotcl
package currently defines only one subclass called FitsIO, however
other packages may add other subclasses to implement support for new
image types. You can create an ImageIO object by passing the
constructor a pointer to a FitsIO object, and then use this for the 
ImageData::makeImage() call:

    ImageIO imio(new FitsIO(width, height, type, 0.0, 1.0, header, data));
    image = ImageData::makeImage("myimage", imio, 0);

Or you can do it all in one step and let the compiler do the conversion:

    image = ImageData::makeImage("myimage", new FitsIO(...), 0);

Note that the internal image format is always FITS. Other formats may
be converted to FITS internally (see ImageIO).

WORKING WITH IMAGES
The main task of the the ImageData class is to transform raw image
data of some type to data that can be displayed in an application
window. This includes transformations, such as scaling, rotating and
flipping and color scaling, or the mapping of pixel values to a
limited number of colormap values.  Since applications don't always
display the entire image at once, methods are available to transform
only a given section of the image. Whenever a part of the raw image is
to be copied to the X image, the current transformations and color
scaling algorithm are taken into account. The transformations are
controlled by flags. These can be accessed through the inline member
functions rotate(), flipX(), flipY(), xScale() and yScale(). The color
scaling algorithms (linear, logarithmic, square root and histogram
equalization) are used to create a lookup table that is used when
transforming the image.  Basically, the lookup tables (taken from
saoimage) convert shorts to bytes. Each subclass defines the method to
convert the raw image pixel values to shorts, which are then converted
to bytes via the lookup table, according to the current color scaling
algorithm.

COORDINATES
Arguments representing coordinates and dimensions are generally
expected to be in image coordinates. Since the caller usually has
screen coordinates, these must be converted first to image coordinates
by reversing the transformations using the method "undoTrans".

METHODS
makeImage(name, imageIo, verbose)
	Return a pointer to a derived class of ImageData specialized
	in the given type of image. See also above and class ImageIO.

write(filename)
	Save the image to a file. For FITS images, if a header was
	present, it is reused, otherwise FITS keywords are inserted
	indicating the image type, width and height along with the
	date and a number of numbered "blank cards" or FITS keyword
	fields that can be modified by other applications as needed.
	The fields have names starting with BLANK followed by 2 digits
	(from BLANK00 to BLANK28). See FitsIO for more information.

doTrans(x, y, dist_flag)
undoTrans(x, y, dist_flag)
	apply (doTrans) or reverse (undoTrans) the transformations on
	given coordinates (scale, rotate, flipX and flipY). If
	dist_flag is non-zero, x and y are treated as a distance, so
	that "flipX" and "flipY" are not done. Note that both methods
	also reverse the Y axis (when dist_flag is 0), since image
	coordinates have the origin at lower left rather than upper
	left as for canvas coordinates. These methods essentially convert
	between canvas (displayed) coordinates and image coordinates.

setXImageData(xImage, width, height)
	Set the destination XImage buffer and dimensions.  This class
	copies the rawimage to xImage, doing any necessary
	transformations along the way.

setScale(xScale, yScale)
	Set the scaling factor.  The scaling factors are positive or
	negative integers (default 1). Positive integers are used to
	zoom in on the image (2 means twice the original
	size). Negative integers are used to zoom out (-2 means 1/2
	the original size). The software imposes an arbitrary limit on
	the scaling factor of +-MAX_IMAGE_SCALE.
    
shrinkToFit(width, height)
	Set the scaling factor so that the image will fit within the
	given dimensions.

update()
	Update the entire image from the raw image if necessary.  If
	nothing has changed since the image was last updated, this
	call does nothing, otherwise the entire raw image is copied to
	the X image with transformations.

updateOffset(x, y)
	Update the image area starting at the given offset and
	continuing to the end of the raw image or the end of the X
	image data, which ever comes first. The raw data starting at
	the offset (x,y) is copied to the X image starting at (0,0)
	with transformations. Note that x and y are in image
	coordinates.  This method is used when the X Image is the same
	size as the visible window and displays the part of the image
	at some x,y scroll offset.

getDist(numValues, xyvalues)
	Scan the image and generate X,Y values to show the
	distribution of pixel values in the image. "numValues" is the
	max number of X,Y pairs to put in xyvalues (if there are not
	enough values, numValues is modified to reflect the actual,
	smaller number of values). This method is used to generate a
	BLT(n) graph of the pixel value distribution in the image.

getSpectrum(xyvalues, x0, y0, x1, y1)
	Scan the raw image along the line given by x0,y0 and x1,y1 and
	generate an array of (index, pixel value) information. Return
	the number of (index,value) pairs generated for the line.
	This method is used to generate a BLT(n) graph of the pixel
	values in an arbitrary line in the image. As always, the
	arguments are expected in image coordinates.

setCutLevels(min, max)
	Manually set the cut levels. This affects color scaling (see
	colorScale()).

autoSetCutLevels(percent)
	Scan the image to find the distribution of pixel values (using
	getDist()) and set the cut levels so that the given percent of
	pixels are within the low and high cut values.

medianFilter(pattern)
	Automatically set the cut levels using a median filtering
	algorithm.  The optional "pattern" parameter may be specified
	as a pointer to an array containing a fixed pattern of pixels
	(the same size as the image),
	which is used by the algorithm.

colorScale(ncolors, colors)
	Create the color scale lookup table for the image.  "ncolors"
	is the number of available colors in the colormap.  "colors"
	is an array of pixel values for the available colors.  The
	color scaling algorithm used is set with the (inline) method
	colorScaleType(), and defaults to ImageData::LINEAR_SCALE.

dataType()
	Return the type of the raw image data as an enumeration value
	(see enum ImageDataType above).

copy()
	This virtual method returns an allocated copy of the image.
	The copy will share the same raw image pointer and color
	lookup table. Normally, a new X image pointer is assigned
	after this call, so that the same raw image can be transformed
	in different ways. This is used by the rtdimage widget to
	implement "views", such as the panning window and zoom window.

copyParamsFrom(image)
	Copy the cut levels and transformation params from the given
	image.

getValue(buf, x, y)
	Print the coordinates and raw data value at the given x,y
	image coords to the given char* buffer.  A "-" is printed if
	the x,y coords are out of range.

getValue(x, y)
	Return the raw image value at the given x,y coordinates as a
	double.  The input x,y is assumed to be in image coordinates.
	If the coordinates are out of range, 0.0 is returned.

getValues(x, y, xStr, yStr, valueStr, raStr, decStr, equinoxStr)
	Print the values at the given x,y coordinates to the given
	buffers for display. X and Y are specified in image
	coordinates and the values written to the buffers are in image
	and world coordinates, resp. If the given point is out of
	range, the buffers are set to the empty string.

getValues(x, y, ar, nrows, ncols)
	Fill the given array with the pixel values surrounding the
	given image coordinate point.  nrows and ncols give the
	dimensions of the array. Any values that are outside of the
	image are set to HUGE_VAL.  Note: it is assumed that nrows and
	ncols are odd numbers and that the array is one row and column
	larger (nrows+1 x ncols+1), so that it can hold the X and Y
	index headings.  The X heading is in the first row of the 2
	dimensional array and contains the X coordinate values. The Y
	coordinate values are in the first column.

header()
data()
	Return a reference to the class "Mem" object used to represent the
	FITS image header (or data).

header(m)
data(m)
	Set a new (FITS) image header or image data object (of class Mem). 

xImage()
	Get a pointer to the X image data.

colorScaleType()
colorScaleType(type)
	Get/set the current color scale algorithm (see enum
	ImageColorScaleType above).

ncolors()
colors()
	Get the number of colors in the colormap or the pointer to the
	color values (set with colorScale() or setColors()).

setColors(ncolors, colors)
	Set the number of colors in the colormap or the pointer to the
	color values.

color0()
colorn()
	These two methods return the color values for blank pixels
	(color0()) and saturated pixels (colorn()). These two color
	cells are normally reserved for this purpose and are not
	otherwise used in the image. color0 is normally black and
	colorn is normally white. See ImageColor.

expo(e)
expo()
	Set/get the exponent used for logarithmic or square
	root color scaling.
	
width()
height()
	Get the dimensions of the raw image.

dispWidth()
dispHeight()
	Get the dimensions of the image after transformations.

xScale()
yScale()
	Get the X and Y scale (magnification) factors (Set
	with setScale()).

flipX()
flipX(bool)
flipY()
flipY(bool)
rotate()
rotate(bool)
	Turn flipping in the X or Y direction or rotating on
	or off for the image.

highCut()
lowCut()
	Get the high or low cut value (set with setCutLevels()).

minValue()
maxValue()
	Get the minimum or maximum raw image value.

subsample(bool)
	Set the subsample flag, to true to use every nth pixel
	when shrinking an image, or false to use the maximum
	pixel.

verbose(bool)
	Sets a flag: if true, diagnostic messages are printed
	out at run time.

name(name)
name()
	Set/get the name of the image. This is some arbitrary string
	used to identify the image. The set routine makes a local copy
	of the string,

wcs()
	This method returns a reference to the WCS class object for this
	image. This object provides a number of methods for working with
	world coordinates and converting between pixel and world coordinates.

clear()
	Temporarilly clear the X image data to make the image blank
	(until the next call to "update" or "updateOffset").
    
SEE ALSO
rtdimage(n), RtdImage, ImageColor(3C++), ImageDisplay(3C++), 
WCS, BLT(n)
----------------------------------------------------------------------

