//<copyright>
//
// Copyright (c) 1995
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
//
//</copyright>


//<file>
//
//
// Name :       rimage.h
//
// Purpose :    Interface to class RasterImage
//
// Created :    04 Jan 95    Bernhard Marschall
// Modified :   04 Jan 95    Bernhard Marschall
// Modified :   03 Aug 95    Bernhard Marschall
//
//
// Description:
//
//</file>

#ifndef harmony_widgets_rimage_h
#define harmony_widgets_rimage_h

#include "libwidgets.h"
#include <stdio.h>
#include <InterViews/raster.h>

class HgRasterCallback;

typedef unsigned char Byte;


//<function>
//
// Prototype:  GraphicFormat identifyGraphicFormat(const char* buffer)
//
// Purpose:    magic number test to identify graphic formats
//
// Return Values:
// 0...Unknown
// 1...PPM
// 2...PAC
// 3...GIF
// 4...JPEG
// 5...TIFF
// 6...X Bitmap
// 7...PNG
//
//</function>

enum GraphicFormat {
  GF_Unknown = 0,
  GF_PPM,
  GF_PAC,
  GF_GIF,
  GF_JPEG,
  GF_TIFF,
  GF_Bitmap,
  GF_PNG
};

extern GraphicFormat identifyGraphicFormat(const char* buffer);



//<class>
//
// Name:       RasterImage
//
// Purpose:    abstract base class to decide and store a raster image
//
//
// Public Interface:
//
// - RasterImage(FILE*, const char* fname, Raster*&,
//               HgRasterCallback*, boolean dither);
//   Constructor. Takes pointer the file (and its name) with image
//   data, a callback class, and a flag wheter to dither the image as
//   parameter. A Raster*& has to be provided from outside. This
//   Raster is filled with the actual image data. Destruction of this
//   Raster is the responsibility of the caller.
//
// - virtual ~RasterImage();
//   Destructor.
//
// - int width() const;
// - int height() const;
//   Returns width and height of the image.
//
// - const Byte* data() const;
// - const Byte* alpha() const; 
//   Returns data and transparency arrays. (Must be read by displaying class.)
//
// - virtual void decode(int numrows);
//   Decode 'numrows' rows of the image.
//
// - virtual void finishDecode();
//   Decode remaining rows of the image.
//
// - virtual void abortDecoding();
//   Abort decoding.
//
// - virtual int not_live() const;
//   Returns if the image can be displayed "live" during decoding.
//
// Description:
//   This base class provides the functionality to store a raster image.
//   RasterImage itself displays only a fixed (black) image of a default
//   size. The actual reading of the image has to be implemented in a derived
//   class, i.e. the derived class essentially add a decoder for some image
//   format (GIF, JPEG, TIFF, ...)
//
//</class>


class RasterImage {
public:
  RasterImage(FILE*, const char* fname, Raster*& raster,
              HgRasterCallback* = 0, boolean dither = true);
  virtual ~RasterImage();

  int width() const;
  int height() const;
  const Byte* data() const;
  const Byte* alpha() const;
  const Raster* raster() const;

  virtual void decode(int /*numrows*/) {}
  virtual void finishDecode();
  virtual void abortDecoding() {}
  virtual int not_live() const { return 1; }

protected:
  void setSize(int w, int h);     // set the size of the image

  HgRasterCallback* callback_;    // callback
  FILE* file_;                    // input file
  const char* filename_;          // name of input file
  Raster*& raster_;               // raster is used to store image data  
  boolean dither_;                // dither image
  int decoded_;                   // number of already decoded rows
  int error_;                     // flag to indicate error
};


inline int RasterImage::width() const {
  if (raster_)
    return raster_->pwidth();
  else
    return 100;
}

inline int RasterImage::height() const {
  if (raster_)
    return raster_->pheight();
  else
    return 100;
}

inline const Raster* RasterImage::raster() const {
  return raster_;
}

#endif
