/** @file  psPixels.h
 *
 *  @brief Contains psPixel related functions
 *
 *  @ingroup Image
 *
 *  @author Robert DeSonia, MHPCC
 *
 *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2005-06-11 02:19:05 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 */
#ifndef PS_PIXELS_H
#define PS_PIXELS_H

#include "psImage.h"
#include "psVector.h"

/// @addtogroup Image
/// @{

typedef struct
{
    psS32 x;
    psS32 y;
}
psPixelCoord;

/** list of pixel coordinates
 *
 *  Usually an image mask is the best way to carry information about what
 *  pixels mean what. However, in the case where the number of pixels in which
 *  we are interested is limited, it is more efﬁcient to simply carry a list
 *  of pixels. An example of this is in the image combination code, where we
 *  want to perform an operation on a relatively small fraction of pixels, and
 *  it is inefﬁcient to go through an entire mask image checking each pixel.
 *
 */
typedef struct
{
    int n;
    int nalloc;
    psPixelCoord* data;
}
psPixels;


/** Allocates a new psPixels structure
 *
 *  @return psPixels*   new psPixels
 */
psPixels* psPixelsAlloc(
    int size                           ///< the size of the coordinate vectors
);

/** resizes a psPixels structure
 *
 *  @return psPixels*   resized psPixels
 */
psPixels* psPixelsRealloc(
    psPixels* pixels,                  ///< psPixels to resize, or NULL to create new psPixels
    int size                           ///< the size of the coordinate vectors
);

/** Add a pixel location to a psPixels
 *
 *  @return psPixels*       psPixels with the value appended.
 */
psPixels* p_psPixelsAppend(
    psPixels* pixels,                  ///< psPixels to append new coordinate to.  NULL creates a new one.
    int growth,                        ///< number of elements to grow the psPixels list, if necessary.  if growth < 1, 10 is used.
    psS32 x,                           ///< x coordinate to append
    psS32 y                            ///< y coordinate to append
);

/** Copies a psPixels object
 *
 *  Makes a deep copy of the data in a psPixels object.  Any data in the OUT
 *  parameter will be destroyed and OUT will be resized, if necessary.
 *
 *  @return psPixels*   a new psPixels that is a duplicate to IN
 */
psPixels* psPixelsCopy(
    psPixels* out,                     ///< psPixels struct to recycle, or NULL
    const psPixels* in                 ///< psPixels struct to copy
);

/** Generate a psImage from a psPixels
 *
 *  psPixelsToMask shall return an image of type U8 with the pixels lying
 *  within the specified region set to the maskVal. The out image shall be
 *  modified if supplied, or allocated and returned if NULL. The size of the
 *  output image shall be region->x1 - region->x0 by region->y1 - region->y0,
 *  with out->x0 = region->x0 and out->y0 = region->y0. In the event that
 *  either of pixels or region are NULL, the function shall generate an
 *  error and return NULL.
 *
 *  @return psImage*    generated mask image
 */
psImage* psPixelsToMask(
    psImage* out,                      ///< psImage to recycle, or NULL
    const psPixels* pixels,            ///< list of pixels to use
    const psRegion region,             ///< region to define the output mask image
    unsigned int maskVal               ///< the mask bit-values to act upon
);

/** Generate a psPixels from a mask psImage
 *
 *  psMaskToPixels shall return a psPixels consisting of the coordinates in
 *  the mask that match the maskVal. The out pixel list shall be modiﬁed if
 *  supplied, or allocated and returned if NULL. In hte event that mask is
 *  NULL, the function shall generate an error and return NULL.
 *
 *  @return psPixels*   generated psPixels pixel list
 */
psPixels* psPixelsFromMask(
    psPixels *out,                     ///< psPixels to recycle, or NULL
    const psImage *mask,               ///< the input mask psImage
    unsigned int maskVal               ///< the mask bit-values to act upon
);

/** Concatenates two psPixels
 *
 *  psPixelsConcatenate shall concatenate pixels onto out. In the event that
 *  out is NULL, a new psPixels shall be allocated, and the contents of
 *  pixels simply copied in. If pixels is NULL, the function shall generate
 *  an error and return NULL. The function shall take care to ensure that
 *  there are no duplicate pixels in out.
 *
 *  @return psPixels         Concatenated psPixel list
 */
psPixels* psPixelsConcatenate(
    psPixels *out,                     ///< psPixels to recycle, or NULL
    const psPixels *pixels             ///< psPixels to append to OUT
);

/** Prints a psPixels to specified destination. */
bool p_psPixelsPrint(
    FILE *fd,
    psPixels* pixels,
    const char *name
);

#endif // #ifndef PS_PIXELS_H
