/*
 * Copyright (c) 2011-2026 Ross Cunniff
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/******************************************************************************
 * OADL images - LIBIMAGE
 *****************************************************************************/

#if(!#defined(_IMAGE_IMPL))
    #library "image"
#endif

namespace Image {

/* The Image class. It may be instantiated in one of several ways:
 *
 *      new Image("filename"[, flags])
 *              Load the image from the given file with optional flags from below.
 *
 *      new Image(itype, dtype, width, height[, ptype, palette])
 *              Create an empty image with the given itype (from below),
 *              dtype (from Ubyte, Ushort, Ulong, Half, Float, Double) and
 *              dimensions. The ptype and palette arguments are only used
 *              (and are required) if itype is IMG_INDEX.
 *
 *      new Image(itype, data[, ptype, palette])
 *              Create an image of the given image type from a data array.
 *              The data array must be a packed 2D (w x h) or 3D (w x h x c)
 *              numeric array. The ptype and palette arguments are only used
 *              (and are required) if itype is IMG_INDEX.
 *
 *      new Image(image, itype, dtype)
 *              Convert an image to another itype (from below) and data type.
 *              A Typecheck exception will be thrown if itype is IMG_INDEX but
 *              the image is not of imageType IMG_INDEX.
 *
 * An image may be written to disk via the write method, thus:
 *
 *      image.write("filename"[, flags[, quality]])
 *              Write the image to the given filename. The flags are optional.
 *              The quality is only used (and is required) if the flags include
 *              STORE_QUALITY. The quality is a number from 0 to QUALITY_MAX,
 *              inclusive.
 *
 * A new image of a different size may be created using the resample method:
 *
 *      newImage = image.resample(newWidth, newHeight[, resampMethod])
 *           The resampMethod is an optional parameter from IMG_SAMP_*, below.
 *           The default resampMethod is IMG_SAMP_POINT. If the image is of
 *           IMG_INDEX imageType, any resampMethod other than IMG_SAMP_POINT will
 *           throw a RangeCheck exception.
 *
 * The Image class overloads the [] and [=] operators to peek and poke pixels,
 * although one may access the data element directly if one so desires. It
 * similarly overloads the #[] and #[=] operators.
 *
 */
class Image;
    public imageType;     // From types below (protected)
    public width, height; // Dimensions of the image (protected)
    public components;    // Number of image components from 1 to 4 (protected)
    public palette;       // Palette (look-up table) for the image (protected)
    public paletteType;   // Palette type - nil or an IMG_RGB* (protected)
    public paletteDataType; // Palette data type - nil or Ubyte, Ushort, etc. (protected)
    public data;          // 3D (width x height x comps) data array (protected)
                          // Note: can be just 2D (width x height) if only 1 comp
                          // Packed numeric (Ubyte, Ushort, Ulong, Half, Float, Double)
    public dataType;      // The base type of the data array (protected)
    public resolution;    // 2-element float "pixels-per-meter" (public)
    public metadata;      // List of key-value metadata settings (public)
    public metakind;      // From META_*, below
    public create;        // The create method - see above
    public write;         // The write method - see above
    public resample;      // The resample method - see above
    // operator []        // Access the image data
    // operator [=]       // Modify the image data
    // operator #[]       // Access the image data
    // operator #[=]      // Modify the image data

// libimage supports up to 4 components (RGBA or CMYK):
const
    MAX_COMPONENTS = 4;

// Possible image load flags
const
    LOAD_INFO_ONLY = 0x00000001,        // Only load info
    LOAD_METADATA  = 0x00000002;        // Load metadata

// Possible image store flags
const
    STORE_QUALITY  = 0x00000001,        // Next argument is quality for lossy
    STORE_METADATA = 0x00000002,        // Store EXIF metadata too
    STORE_DUPLICATE_METADATA = 0x00000004; // Don't eliminate duplicates from the metadata

const
    QUALITY_MAX    = 100;               // Maximum quality

// Possible image types. Note that this is independent of data type.
const
    IMG_INDEX   = 1,    // Index into a palette
    IMG_LUM     = 2,    // Luminance
    IMG_LUMA    = 3,    // Luminance+Alpha
    IMG_RGB     = 4,    // Red, Green, Blue
    IMG_RGBA    = 5,    // Red, Green, Blue, Alpha
    IMG_CMYK    = 6,    // Cyan, Magenta, Yellow, Black
    IMG_YCBCR   = 7,    // Luma, Blue-diff, Red-diff
    IMG_LAB     = 8,    // CIE L*a*b*
    IMG_XYZ     = 9;    // CIE XYZ

// Possible metadata types
const
    META_EXIF      = 0,                 // EXIF metatdata, see exif*.oah
    META_XMP       = 1;                 // XMP metatdata, also see exif*.oah

// Possible image resampling modes
const
    IMG_SAMP_POINT = 0,    // Point sampling (default)
    IMG_SAMP_BILINEAR = 1, // Bilinear sampling
    IMG_SAMP_BICUBIC = 2;  // Bi-cubic sampling

}