
// epimgconv: Enterprise 128 image converter utility
// Copyright (C) 2008 Istvan Varga <istvanv@users.sourceforge.net>
//
// 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 2 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// The Enterprise 128 program files generated by this utility are not covered
// by the GNU General Public License, and can be used, modified, and
// distributed without any restrictions.

#ifndef EPIMGCONV_ATTR16_HPP
#define EPIMGCONV_ATTR16_HPP

#include "epimgconv.hpp"
#include "imageconv.hpp"

namespace Ep128ImgConv {

  class ImageConv_Attr16 : public ImageConverter {
   protected:
    int           width;
    int           height;
    float         colorErrorScale;
    int           fixBiasValue;
    YUVImage      inputImage;
    YUVImage      ditherErrorImage;
    IndexedImage  convertedImage;
    IndexedImage  palette;
    IndexedImage  attr0;
    IndexedImage  attr1;
    int           conversionQuality;
    int           borderColor;
    int           ditherType;
    float         ditherDiffusion;
    double        *errorTable;          // size = 256*256
    bool          fixedColors[8];
    float         paletteY[256];
    float         paletteU[256];
    float         paletteV[256];
    // --------
    inline double calculateYUVErrorSqr(int c, double y, double u, double v)
    {
      return Ep128ImgConv::calculateYUVErrorSqr(double(paletteY[c]),
                                                double(paletteU[c]),
                                                double(paletteV[c]),
                                                y, u, v, colorErrorScale);
    }
    void initializePalettes();
    void setFixBias(int n);
    void randomizePalette(int yc, int seedValue);
    double calculateError(const size_t *colorCntTable,
                          const unsigned char *palette_,
                          int colorChanged = -1,
                          unsigned char *colorIndexCache = (unsigned char *) 0,
                          double *errorCache = (double *) 0,
                          double maxError = 1000000000.0);
    double calculateAttrCellError(int xc, int yc, int c0, int c1);
    double calculateLineError2(int yc, double maxError = 10000000.0);
    double calculateTotalError2();
    double calculateLineError16(
        int yc, int colorChanged = -1,
        unsigned char *colorIndexCache = (unsigned char *) 0,
        double *errorCache = (double *) 0, double maxError = 1000000000.0);
    double calculateTotalError16(double maxError = 1000000000.0);
    double optimizeLinePalette(int yc, int optimizeLevel = 2);
    double optimizeLineAttributes(int yc, bool usePalette,
                                  int optimizeLevel = 2);
    double optimizeImagePalette(int optimizeLevel = 2,
                                bool optimizeFixBias = false);
    void sortLinePalette(int yc);
    void setFixedPalette();
    void ditherLine(long yc, bool updateError = true);
    void preDitherImage();
    double optimizeLinePalette_fast(int yc);
    static void pixelStoreCallback(void *userData, int xc, int yc,
                                   float y, float u, float v);
    static void pixelStoreCallbackI(void *userData, int xc, int yc,
                                    float y, float u, float v);
   public:
    ImageConv_Attr16();
    virtual ~ImageConv_Attr16();
    // the return value is false if the processing has been stopped
    virtual bool processImage(ImageData& imgData, const char *infileName,
                              YUVImageConverter& imgConv,
                              const ImageConvConfig& config);
  };

}       // namespace Ep128ImgConv

#endif  // EPIMGCONV_ATTR16_HPP

