### How to write a new library for KSquirrel (for example, it will decode abstract 'ttx' format) ?

- Create a directory with necessary sources ('generate' is distributed with ksquirrel-libs):

      # ./generate ttx -build

- Typical fmt_codec_ttx_defs.h

      #ifndef KSQUIRREL_READ_IMAGE_ttx
      #define KSQUIRREL_READ_IMAGE_ttx

      // Define constants you need here

      #endif

- Typical fmt_codec_ttx.h

      #ifndef KSQUIRREL_LIBS_CLASS_DEFINITION_ttx_H
      #define KSQUIRREL_LIBS_CLASS_DEFINITION_ttx_H

      #include "fmt_codec_base.h"

      class fmt_codec : public fmt_codec_base
      {
          public:

              fmt_codec();
              ~fmt_codec();

              virtual std::string     fmt_version();
              virtual std::string     fmt_quickinfo();
              virtual std::string     fmt_filter();
              virtual std::string     fmt_mime();
              virtual std::string     fmt_pixmap();
              virtual std::string     fmt_extension(const s32 bpp);

              virtual bool    fmt_readable() const;
              virtual s32     fmt_read_init(const std::string &file);
              virtual s32     fmt_read_next();
              virtual s32     fmt_read_next_pass();
              virtual s32     fmt_read_scanline(RGBA *scan);
              virtual void    fmt_read_close();

              virtual bool    fmt_writable() const;
              virtual void    fmt_getwriteoptions(fmt_writeoptionsabs *);
              virtual s32     fmt_write_init(const std::string &file, const fmt_image &image,
      					const fmt_writeoptions &opt);
              virtual s32     fmt_write_next();
              virtual s32     fmt_write_next_pass();
              virtual s32     fmt_write_scanline(RGBA *scan);
              virtual void    fmt_write_close();

          private:
              // define variables you need here
      };

      extern "C" fmt_codec_base* fmt_codec_create()
      {
          return (new fmt_codec);
      }

      extern "C" void fmt_codec_destroy(fmt_codec_base *p)
      {
          delete p;
      }

- Typical fmt_codec_ttx.cpp

      #include <iostream>

      #include "fmt_types.h"
      #include "fileio.h"
      #include "fmt_codec_ttx_defs.h"
      #include "fmt_codec_ttx.h"

      #include "error.h"

      fmt_codec::fmt_codec() : fmt_codec_base()
      {}

      fmt_codec::~fmt_codec()
      {}

      Returns library's version
      std::string fmt_codec::fmt_version()
      {
          return std::string("0.0.1");
      }

      Returns common information on ttx format
      std::string fmt_codec::fmt_quickinfo()
      {
          return std::string("TTX is a very cool format!");
      }

      Filter for a file manager (with a blank after
      each extension)
      std::string fmt_codec::fmt_filter()
      {
          return std::string("*.ttx1 *.ttx2 *.ttx3 ");
      }

      The regular expression defining the file type
      (usually first 2-5 characters in a file).
      This example shows, that format TTX is defined by header
      TTX7, TTX8 or TTX9. If the file has no header
       (like .ico and .pix) this function should return empty string.
      std::string fmt_codec::fmt_mime()
      {
          return std::string("TTX[789]");
      }

      Compile this program,
      create PNG icon 16x16 and run
      #./bits icon.png > icon.bits.
      Then copy contents of icon.bits here
      std::string fmt_codec::fmt_pixmap()
      {
          return std::string("");
      }

      Open file, initialize variables, etc.
      s32 fmt_codec::fmt_read_init(const std::string &file)
      {
          frs.open(file.c_str(), ios::binary | ios::in);

          if(!frs.good())
              return SQERR_NOFILE;

          currentImage = -1;
          read_error = false;

          finfo.animated = false;

          return SQERR_OK;
      }

      This method will be called BEFORE decoding of each image in a file,
      so we should seek to correct file offset or do something important now.
      Return SQERR_NOTOK, if the next image can't be decoded (no such image),
      and any other error code on error.
      s32 fmt_codec::fmt_read_next()
      {
          currentImage++;

          if(currentImage)
      	return SQERR_NOTOK; return, if TTX can
      			     have only one image.

          fmt_image image;

          Non-interlaced image has 1 pass.
          If you need to define another value, do it here
          image.passes = 1;

      Here you should read necessary data from file,
      and initialize finfo.image[currentImage].w,h,bpp. Return error
      code you need on error.
      ...

          image.compression = "-";
          image.colorspace = "RGB";

          finfo.image.push_back(image);

          return SQERR_OK;
      }

      This method will be called BEFORE decoding of each pass
      in the interlaced image.
      s32 fmt_codec::fmt_read_next_pass()
      {
          Our TTX fromat can't be interlaced, so we
          won't do anything, just return SQERR_OK
          return SQERR_OK;
      }

      Reads scanline in 'scan'. This example just fills
      'scan' with white color (RGBA(255,255,255,255))
      s32 fmt_codec::fmt_read_scanline(RGBA *scan)
      {
          memset(scan, 255, finfo.image[currentImage].w * sizeof(RGBA));

          return SQERR_OK;
      }

      Closes everything, frees allocated memory, etc.
      void fmt_codec::fmt_read_close()
      {
          frs.close();

          // you should free information on close
          finfo.meta.clear();
          finfo.image.clear();
      }

      Returns write options for TTX format. This method won't be
      called, if fmt_writable() returns 'false'
      void fmt_codec::fmt_getwriteoptions(fmt_writeoptionsabs *opt)
      {
          Can TTX format be interlaced ? No.
          opt->interlaced = false;

          With which compression it can be compressed ?
          With no compression (like not-RLE BMP).
          opt->compression_scheme = CompressionNo;

          minimum, maximum, and default compression level.
          Ignored, if the compression is CompressionNo.
          opt->compression_min = 0;
          opt->compression_max = 0;
          opt->compression_def = 0;

          TTX can't be interlaced, passes = 1
          opt->passes = 1;

          KSquirrel shouldn't flip the image
          before writing
          opt->needflip = false;
      }

      Same to fmt_read_init()
      s32 fmt_codec::fmt_write_init(const std::string &file, const fmt_image &image,
      				const fmt_writeoptions &opt)
      {
          if(!image.w || !image.h || file.empty())
              return SQE_W_WRONGPARAMS;

          writeimage = image;
          writeopt = opt;

          fws.open(file.c_str(), ios::binary | ios::out);

          if(!fws.good())
              return SQE_W_NOFILE;

          return SQE_OK;
      }

      Same to fmt_read_next()
      s32 fmt_codec::fmt_write_next()
      {
          return SQE_OK;
      }

      Same to fmt_read_next_pass()
      s32 fmt_codec::fmt_write_next_pass()
      {
          return SQE_OK;
      }

      Write scanline. Same to fmt_read_scanline()
      s32 fmt_codec::fmt_write_scanline(RGBA *scan)
      {
          ...
          return SQE_OK;
      }

      Same to fmt_read_init()
      void fmt_codec::fmt_write_close()
      {
          fws.close();
      }

      Can this library write TTX ? No.
      bool fmt_codec::fmt_writable() const
      {
          return false;
      }

      Can this library read TTX ? Yes.
      bool fmt_codec::fmt_readable() const
      {
          return true;
      }

      Some libraries support several image types (like PNM library).
      This method should be used by writing function to determine file extension by image's bpp.
      For example, 1 bpp means .pbm, 8 bpp - pgm"
      std::string fmt_codec::fmt_extension(const s32 /*bpp*/)
      {
          return std::string("");
      }

- Compile it

      # ./compile-c++
      #

- That's all. You've just created a new decoder for KSquirrel. Copy libSQ_codec_ttx.so in /usr/lib/ksquirrel-libs.