You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.1 KiB

#ifndef GFXRASTER_INCLUDED // -*- C++ -*-
#define GFXRASTER_INCLUDED
#if !defined(__GNUC__)
# pragma once
#endif
/************************************************************************
Raster image support.
$Id: raster.h 427 2004-09-27 04:45:31Z garland $
************************************************************************/
#include "gfx.h"
#include "vec2.h"
namespace gfx
{
typedef TVec2<short> PixelAddress;
template<class T>
class Raster
{
private:
T *data;
int W, H, nchan;
public:
Raster(int w, int h, int c)
{
W=w; H=h; nchan=c;
data = new T[length()];
}
virtual ~Raster() { delete[] data; }
int width() const { return W; }
int height() const { return H; }
int channels() const { return nchan; }
int length() const { return W*H*nchan; }
T& operator[](int i) { return data[i]; }
T operator[](int i) const { return data[i]; }
virtual T *pixel(int i, int j) { return data + (j*W+i)*nchan; }
virtual const T *pixel(int i, int j) const { return data + (j*W+i)*nchan; }
T *pixel(const PixelAddress &a) { return pixel(a[0], a[1]); }
const T *pixel(const PixelAddress &a) const { return pixel(a[0], a[1]); }
T *head() { return data; }
const T *head() const { return data; }
void reverse(int start=0, int end=-1);
void hflip();
void vflip();
bool is_valid_address(const PixelAddress& a) const
{
return is_valid_address(a[0], a[1]);
}
virtual bool is_valid_address(int x, int y) const
{
return ( (x >= 0) && (x < W) && (y >= 0) && (y < H) );
}
};
class FloatRaster;
class ByteRaster : public Raster<unsigned char>
{
public:
ByteRaster(int w, int h, int c) : Raster<unsigned char>(w,h,c) {}
ByteRaster(const ByteRaster& img);
ByteRaster(const FloatRaster& img);
};
class FloatRaster : public Raster<float>
{
public:
FloatRaster(int w, int h, int c) : Raster<float>(w,h,c) {}
FloatRaster(const FloatRaster &img);
FloatRaster(const ByteRaster &img);
};
////////////////////////////////////////////////////////////////////////
//
// Templated raster methods
//
template<class T>
inline void Raster<T>::reverse(int start, int end)
{
if(end<0 || end>=length()) end = length() - channels();
int i=start, j=end;
while(i<j)
{
for(int k=0; k<channels(); k++)
{
T tmp = (*this)[i+k];
(*this)[i+k] = (*this)[j+k];
(*this)[j+k] = tmp;
}
i += channels();
j -= channels();
}
}
template<class T>
inline void Raster<T>::hflip()
{
int i = 0;
int j = channels()*(width()-1);
while( i<length() )
{
reverse(i, i+j);
i += j + channels();
}
}
template<class T>
inline void Raster<T>::vflip()
{
reverse();
hflip();
}
////////////////////////////////////////////////////////////////////////
//
// Supported external image file formats.
//
enum { IMG_PNM=0, IMG_PNG=1, IMG_TIFF=2, IMG_JPEG=3, IMG_LIMIT=4 };
extern const char *image_type_name(int type);
extern const char *image_type_ext(int type);
extern int infer_image_type(const char *filename);
// Image I/O based on filename extensions
extern bool write_image(const char *filename, const ByteRaster&, int type=-1);
extern ByteRaster *read_image(const char *filename, int type=-1);
// PNM support provided by libgfx (always available)
extern bool will_write_raw_pnm;
extern bool write_pnm_image(const char *filename, const ByteRaster&);
extern ByteRaster *read_pnm_image(const char *filename);
// TIFF support provided through libtiff (if available).
extern bool write_tiff_image(const char *filename, const ByteRaster&);
extern ByteRaster *read_tiff_image(const char *filename);
// PNG support provided through libpng (if available).
extern bool write_png_image(const char *filename, const ByteRaster&);
extern ByteRaster *read_png_image(const char *filename);
// JPEG support provided through libjpeg (if available)
extern int jpeg_output_quality;
extern bool write_jpeg_image(const char *filename, const ByteRaster&);
extern ByteRaster *read_jpeg_image(const char *filename);
} // namespace gfx
// GFXRASTER_INCLUDED
#endif