/*------------------------------------------------------------------------------
 src/lib/djImage/djImageIoPpm.h
 
 Copyright (c) 2004-2006 Darby Johnston.
 All rights reserved.
 Use is subject to license terms.
 
 Supported:
 
 * Channels: L, RGB.
 * Bit depths: U8, U16.
 * Attributes: ASCII or binary data.
 
 Unsupported:
 
 * 1-bit data (PPM P1 and P4 files).
 * Files with multiple images.
 
 To Do:

 * Speed up ASCII data I/O.

 References:
 
 * Jef Poskanzer, "PPM Format Specification",
   http://netpbm.sourceforge.net/doc/ppm.html
------------------------------------------------------------------------------*/

#ifndef DJ_IMAGE_IO_PPM_H
#define DJ_IMAGE_IO_PPM_H
#include <djFileIo.h>
#include <djImageIo.h>

namespace dj {
namespace ImageIoPpm {

// Plugin name.
//
inline const Str name() { return "PPM"; }

// File extensions.
//
static const StrList extensionList()
  { return StrList() + Str(".ppm") + Str(".pnm") + Str(".pgm"); }

// File header.
//
struct Header {
  int type;
  int width, height;
  int maxValue;
};

// Image load plugin.
//
class Load : public ImageLoad {
public:

  const Str name() const { return ImageIoPpm::name(); }
  Plugin * copy() const { return new Load(*this); }
  const StrList extensionList() const { return ImageIoPpm::extensionList(); }
  
  bool open(const Str & fileName, ImageIoInfo *);

protected:

  bool imageOpen(const Str & fileName, ImageIoInfo *);
  bool imageBegin(int frame, ImageIoInfo *);
  bool imageGet(PixelData *, int proxyScale);

private:

  FileInfo _fileInfo;
  FileIo _f;
  Header _header;
  Pixel _pixel;
};

// Image save plugin.
//
class Save : public ImageSave {
public:

  Save();
  
  const Str name() const { return ImageIoPpm::name(); }
  Plugin * copy() const { return new Save(*this); }
  const StrList extensionList() const { return ImageIoPpm::extensionList(); }
  
  enum MODE { ASCII, BINARY };
  enum ATTR { ATTR_MODE };
  const StrList attrNameList() const;
  bool attr(const Str &, const StrList &);
  const StrList attr(const Str &) const;
  
  bool open(const Str & fileName, const ImageIoInfo &);

protected:

  bool imageOpen(const Str & fileName, const Image &);
  bool imageBegin(const Image &, int frame);
  bool imageSet(const PixelData &);

private:

  PixelDataInfo _info;
  MODE _mode;
  
  FileInfo _fileInfo;
  FileIo _f;
  Header _header;
};

// Get next word from a PPM file. Words are separated by white space. Comments
// start with "#" and continue until the end of the line.
//
bool getWord(FileIo *, char *, int maxStrLen);

// String to integer.
//
int atoi(const char *, int maxStrLen);

// Labels.
//
inline const StrList modeStr()
  { return StrList() + Str("ASCII") + Str("Binary"); }
inline const StrList saveAttrStr()
  { return StrList() + Str("Mode"); }

}
}

#endif
