/*************************************************************************** * GFitsImageSByte.cpp - Signed Byte FITS image class * * ----------------------------------------------------------------------- * * copyright (C) 2010-2013 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ***************************************************************************/ /** * @file GFitsImageSByte.cpp * @brief Signed Byte FITS image class implementation * @author Juergen Knoedlseder */ /* __ Includes ___________________________________________________________ */ #ifdef HAVE_CONFIG_H #include #endif #include "GException.hpp" #include "GFitsCfitsio.hpp" #include "GFitsImageSByte.hpp" /* __ Method name definitions ____________________________________________ */ /* __ Macros _____________________________________________________________ */ #define G_BITPIX 10 //!< BITPIX code for TSBYTE /* __ Coding definitions _________________________________________________ */ /* __ Debug definitions __________________________________________________ */ /*========================================================================== = = = Constructors/destructors = = = ==========================================================================*/ /***********************************************************************//** * @brief Void constructor ***************************************************************************/ GFitsImageSByte::GFitsImageSByte(void) : GFitsImage() { // Initialise class members for clean destruction init_members(); // Return return; } /***********************************************************************//** * @brief 1D image constructor * * @param[in] nx Number of pixels. * @param[in] pixels Optional pointer to image pixel array * * Construct 1D instance by specifying the number of pixels in the image. ***************************************************************************/ GFitsImageSByte::GFitsImageSByte(const int& nx, const char* pixels) : GFitsImage(G_BITPIX, nx) { // Initialise class members for clean destruction init_members(); // Construct data construct_data(pixels); // Return return; } /***********************************************************************//** * @brief 2D image constructor * * @param[in] nx Number of pixels in first dimension. * @param[in] ny Number of pixels in second dimension. * @param[in] pixels Optional pointer to image pixel array * * Construct 2D image by specifying the number of pixels in each dimension. ***************************************************************************/ GFitsImageSByte::GFitsImageSByte(const int& nx, const int& ny, const char* pixels) : GFitsImage(G_BITPIX, nx, ny) { // Initialise class members for clean destruction init_members(); // Construct data construct_data(pixels); // Return return; } /***********************************************************************//** * @brief 3D image constructor * * @param[in] nx Number of pixels in first dimension. * @param[in] ny Number of pixels in second dimension. * @param[in] nz Number of pixels in third dimension. * @param[in] pixels Optional pointer to image pixel array * * Construct 3D image by specifying the number of pixels in each dimension. ***************************************************************************/ GFitsImageSByte::GFitsImageSByte(const int& nx, const int& ny, const int& nz, const char* pixels) : GFitsImage(G_BITPIX, nx, ny, nz) { // Initialise class members for clean destruction init_members(); // Construct data construct_data(pixels); // Return return; } /***********************************************************************//** * @brief 4D image constructor * * @param[in] nx Number of pixels in first dimension. * @param[in] ny Number of pixels in second dimension. * @param[in] nz Number of pixels in third dimension. * @param[in] nt Number of pixels in forth dimension. * @param[in] pixels Optional pointer to image pixel array * * Construct 4D image by specifying the number of pixels in each dimension. ***************************************************************************/ GFitsImageSByte::GFitsImageSByte(const int& nx, const int& ny, const int& nz, const int& nt, const char* pixels) : GFitsImage(G_BITPIX, nx, ny, nz, nt) { // Initialise class members for clean destruction init_members(); // Construct data construct_data(pixels); // Return return; } /***********************************************************************//** * @brief Pixel array constructor * * @param[in] naxis Image dimension (0,1,2,3,4). * @param[in] naxes Number of pixels in each dimension. * @param[in] pixels Optional pointer to image pixel array * * Construct instance of GFitsImageSByte by specifying the image dimension and * the number of pixels in each dimension. Note that this constructor does * not allocate any memory for the actual image. ***************************************************************************/ GFitsImageSByte::GFitsImageSByte(const int& naxis, const int* naxes, const char* pixels) : GFitsImage(G_BITPIX, naxis, naxes) { // Initialise class members for clean destruction init_members(); // Construct data construct_data(pixels); // Return return; } /***********************************************************************//** * @brief Copy constructor * * @param[in] image FITS image. ***************************************************************************/ GFitsImageSByte::GFitsImageSByte(const GFitsImageSByte& image) : GFitsImage(image) { // Initialise class members for clean destruction init_members(); // Copy members copy_members(image); // Return return; } /***********************************************************************//** * @brief Destructor ***************************************************************************/ GFitsImageSByte::~GFitsImageSByte(void) { // Free members free_members(); // Return return; } /*========================================================================== = = = Operators = = = ==========================================================================*/ /***********************************************************************//** * @brief Assignment operator * * @param[in] image FITS image. ***************************************************************************/ GFitsImageSByte& GFitsImageSByte::operator=(const GFitsImageSByte& image) { // Execute only if object is not identical if (this != &image) { // Copy base class members this->GFitsImage::operator=(image); // Free members free_members(); // Initialise private members for clean destruction init_members(); // Copy members copy_members(image); } // endif: object was not identical // Return this object return *this; } /***********************************************************************//** * @brief Image pixel access operator * * @param[in] ix Pixel index (starting from 0). * * Provides access to an image pixel. No range checking is performed. * Use the at(ix) method if range checking is required. ***************************************************************************/ char& GFitsImageSByte::operator()(const int& ix) { // Load data load_data(); // Return image pixel return m_pixels[ix]; } /***********************************************************************//** * @brief 2D image pixel access operator * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * * Provides access to a pixel of a 2D image. No range checking or image * dimension verification is performed. Use the at(ix,iy) method if range * checking and image dimension verification is required. ***************************************************************************/ char& GFitsImageSByte::operator()(const int& ix, const int& iy) { // Load data load_data(); // Calculate pixel offset int offset = ix + iy * m_naxes[0]; // Return image pixel return m_pixels[offset]; } /***********************************************************************//** * @brief 3D image pixel access operator * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * * Provides access to a pixel of a 3D image. No range checking or image * dimension verification is performed. Use the at(ix,iy) method if range * checking and image dimension verification is required. ***************************************************************************/ char& GFitsImageSByte::operator()(const int& ix, const int& iy, const int& iz) { // Load data load_data(); // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]); // Return image pixel return m_pixels[offset]; } /***********************************************************************//** * @brief 4D image pixel access operator * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * @param[in] it Pixel index in forth dimension (starting from 0). * * Provides access to a pixel of a 4D image. No range checking or image * dimension verification is performed. Use the at(ix,iy) method if range * checking and image dimension verification is required. ***************************************************************************/ char& GFitsImageSByte::operator()(const int& ix, const int& iy, const int& iz, const int& it) { // Load data load_data(); // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2])); // Return image pixel return m_pixels[offset]; } /***********************************************************************//** * @brief Image pixel access operator (const variant) * * @param[in] ix Pixel index (starting from 0). * * Provides access to an image pixel. No range checking is performed. * Use the at(ix) method if range checking is required. ***************************************************************************/ const char& GFitsImageSByte::operator()(const int& ix) const { // Load data load_data(); // Return image pixel return m_pixels[ix]; } /***********************************************************************//** * @brief 2D image pixel access operator (const variant) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * * Provides access to a pixel of a 2D image. No range checking or image * dimension verification is performed. Use the at(ix,iy) method if range * checking and image dimension verification is required. ***************************************************************************/ const char& GFitsImageSByte::operator()(const int& ix, const int& iy) const { // Load data load_data(); // Calculate pixel offset int offset = ix + iy * m_naxes[0]; // Return image pixel return m_pixels[offset]; } /***********************************************************************//** * @brief 3D image pixel access operator (const variant) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * * Provides access to a pixel of a 3D image. No range checking or image * dimension verification is performed. Use the at(ix,iy) method if range * checking and image dimension verification is required. ***************************************************************************/ const char& GFitsImageSByte::operator()(const int& ix, const int& iy, const int& iz) const { // Load data load_data(); // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]); // Return image pixel return m_pixels[offset]; } /***********************************************************************//** * @brief 4D image pixel access operator (const variant) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * @param[in] it Pixel index in forth dimension (starting from 0). * * Provides access to a pixel of a 4D image. No range checking or image * dimension verification is performed. Use the at(ix,iy) method if range * checking and image dimension verification is required. ***************************************************************************/ const char& GFitsImageSByte::operator()(const int& ix, const int& iy, const int& iz, const int& it) const { // Load data load_data(); // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2])); // Return image pixel return m_pixels[offset]; } /*========================================================================== = = = Public methods = = = ==========================================================================*/ /***********************************************************************//** * @brief Clear instance * * This method properly resets the object to an initial state. ***************************************************************************/ void GFitsImageSByte::clear(void) { // Free class members (base and derived classes, derived class first) free_members(); this->GFitsImage::free_members(); this->GFitsHDU::free_members(); // Initialise members this->GFitsHDU::init_members(); this->GFitsImage::init_members(); init_members(); // Return return; } /***********************************************************************//** * @brief Clone FITS image * * Cloning provides a copy of the FITS file. Cloning is used to allocate * derived classes into a base class pointer. ***************************************************************************/ GFitsImageSByte* GFitsImageSByte::clone(void) const { // Clone this image return new GFitsImageSByte(*this); } /***********************************************************************//** * @brief Image pixel access operator * * @param[in] ix Pixel index (starting from 0). * * Provides access to a pixel of an image including range checking. Note that * this method does not necessarily restrict do 1D images but generally * applies to all image dimensions. ***************************************************************************/ char& GFitsImageSByte::at(const int& ix) { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix)]); } /***********************************************************************//** * @brief 2D image pixel access operator * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * * Provides access to a pixel of an image including range checking. ***************************************************************************/ char& GFitsImageSByte::at(const int& ix, const int& iy) { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix,iy)]); } /***********************************************************************//** * @brief 3D image pixel access operator * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * * Provides access to a pixel of an image including range checking. ***************************************************************************/ char& GFitsImageSByte::at(const int& ix, const int& iy, const int& iz) { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix,iy,iz)]); } /***********************************************************************//** * @brief 4D image pixel access operator * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * @param[in] it Pixel index in forth dimension (starting from 0). * * Provides access to a pixel of an image including range checking. ***************************************************************************/ char& GFitsImageSByte::at(const int& ix, const int& iy, const int& iz, const int& it) { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix,iy,iz,it)]); } /***********************************************************************//** * @brief Image pixel access operator (const variant) * * @param[in] ix Pixel index (starting from 0). * * Provides access to a pixel of an image including range checking. ***************************************************************************/ const char& GFitsImageSByte::at(const int& ix) const { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix)]); } /***********************************************************************//** * @brief 2D image pixel access operator (const variant) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * * Provides access to a pixel of an image including range checking. ***************************************************************************/ const char& GFitsImageSByte::at(const int& ix, const int& iy) const { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix,iy)]); } /***********************************************************************//** * @brief 3D image pixel access operator (const variant) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * * Provides access to a pixel of an image including range checking. ***************************************************************************/ const char& GFitsImageSByte::at(const int& ix, const int& iy, const int& iz) const { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix,iy,iz)]); } /***********************************************************************//** * @brief 4D image pixel access operator (const variant) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * @param[in] it Pixel index in forth dimension (starting from 0). * * Provides access to a pixel of an image including range checking. ***************************************************************************/ const char& GFitsImageSByte::at(const int& ix, const int& iy, const int& iz, const int& it) const { // Load data load_data(); // Return image pixel return (m_pixels[offset(ix,iy,iz,it)]); } /***********************************************************************//** * @brief Return value of image pixel * * @param[in] ix Pixel index (starting from 0). * * Returns the value of an image pixel as double precision floating point * value. This method performs range checking. ***************************************************************************/ double GFitsImageSByte::pixel(const int& ix) const { // Return pixel value return (double(this->at(ix))); } /***********************************************************************//** * @brief Return value of image pixel (2D version) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * * Returns the value of an image pixel as double precision floating point * value. This method performs range checking. ***************************************************************************/ double GFitsImageSByte::pixel(const int& ix, const int& iy) const { // Return pixel value return (double(this->at(ix,iy))); } /***********************************************************************//** * @brief Return value of image pixel (3D version) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * * Returns the value of an image pixel as double precision floating point * value. This method performs range checking. ***************************************************************************/ double GFitsImageSByte::pixel(const int& ix, const int& iy, const int& iz) const { // Return pixel value return (double(this->at(ix,iy,iz))); } /***********************************************************************//** * @brief Return value of image pixel (4D version) * * @param[in] ix Pixel index in first dimension (starting from 0). * @param[in] iy Pixel index in second dimension (starting from 0). * @param[in] iz Pixel index in third dimension (starting from 0). * @param[in] it Pixel index in forth dimension (starting from 0). * * Returns the value of an image pixel as double precision floating point * value. This method performs range checking. ***************************************************************************/ double GFitsImageSByte::pixel(const int& ix, const int& iy, const int& iz, const int& it) const { // Return pixel value return (double(this->at(ix,iy,iz,it))); } /***********************************************************************//** * @brief Return pointer to image pixel ***************************************************************************/ void* GFitsImageSByte::pixels(void) { // Load data load_data(); // Return return m_pixels; } /***********************************************************************//** * @brief Return image type ***************************************************************************/ int GFitsImageSByte::type(void) const { // Return type return __TSBYTE; } /*========================================================================== = = = Private methods = = = ==========================================================================*/ /***********************************************************************//** * @brief Initialise class members ***************************************************************************/ void GFitsImageSByte::init_members(void) { // Initialise members m_bitpix = G_BITPIX; m_pixels = NULL; m_nulval = NULL; // Return return; } /***********************************************************************//** * @brief Copy class members * * @param image FITS image to copy * * Copy class members. If the pixel array is linked the pointer to the array * is copied. Otherwise a copy of the image pixels will be created. ***************************************************************************/ void GFitsImageSByte::copy_members(const GFitsImageSByte& image) { // Fetch column data if not yet fetched. The casting circumvents the // const correctness bool not_loaded = (image.m_pixels == NULL); if (not_loaded) { const_cast(&image)->fetch_data(); } // Copy pixels if (m_num_pixels > 0 && image.m_pixels != NULL) { m_pixels = new char[m_num_pixels]; for (int i = 0; i < m_num_pixels; ++i) { m_pixels[i] = image.m_pixels[i]; } } // Copy NULL value alloc_nulval(image.m_nulval); // Small memory option: release column if it was fetch above #if defined(G_SMALL_MEMORY) if (not_loaded) { const_cast(&image)->release_data(); } #endif // Return return; } /***********************************************************************//** * @brief Delete class members ***************************************************************************/ void GFitsImageSByte::free_members(void) { // Free memory if (m_pixels != NULL) delete [] m_pixels; if (m_nulval != NULL) delete m_nulval; // Mark memory as free m_pixels = NULL; m_nulval = NULL; // Return return; } /***********************************************************************//** * @brief Allocate data ***************************************************************************/ void GFitsImageSByte::alloc_data(void) { // Release any existing data release_data(); // Allocate new data if (m_num_pixels > 0) { m_pixels = new char[m_num_pixels]; } // Return return; } /***********************************************************************//** * @brief Initialise data ***************************************************************************/ void GFitsImageSByte::init_data(void) { // Initialise data if they exist if (m_pixels != NULL) { for (int i = 0; i < m_num_pixels; ++i) { m_pixels[i] = 0; } } // Return return; } /***********************************************************************//** * @brief Release data ***************************************************************************/ void GFitsImageSByte::release_data(void) { // Free any existing memory if (m_pixels != NULL) delete [] m_pixels; // Mark pointer as free m_pixels = NULL; // Return return; } /***********************************************************************//** * @brief Construct data from array * * @param[in] pixels Optional pointer to pixel array. * * Initialise pixel data from an optional pixel array. If the pointer is * NULL the image is simply initialised. This method supports all * constructors. ***************************************************************************/ void GFitsImageSByte::construct_data(const char* pixels) { // If there are pixels then allocate array if (m_num_pixels > 0) { // Allocate data alloc_data(); // If no pixel array has been specified then simply initialise data if (pixels == NULL) { init_data(); } // ... otherwise copy pixels else { for (int i = 0; i < m_num_pixels; ++i) { m_pixels[i] = pixels[i]; } } } // endif: there are pixels in image // Return return; } /***********************************************************************//** * @brief Load data * * Load the image data if no pixels have been allocated. ***************************************************************************/ void GFitsImageSByte::load_data(void) const { // If image pixels are not available then fetch them now. if (m_pixels == NULL) { const_cast(this)->fetch_data(); } // Return return; } /***********************************************************************//** * @brief Allocates nul value * * @param[in] value Nul value. ***************************************************************************/ void GFitsImageSByte::alloc_nulval(const void* value) { // Free any existing memory if (m_nulval != NULL) delete m_nulval; // Mark pointer as free m_nulval = NULL; // If we have valid value, allocate and set nul value if (value != NULL) { m_nulval = new char; *m_nulval = *((char*)value); } // Return return; }