Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STPic.h: interface for the CSTPic class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <assert.h></assert.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef STPIC_H
Toshihiro Shimizu 890ddd
#define STPIC_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/****** SASA Picture Class Template **********************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Currently there are two types of this object
Toshihiro Shimizu 890ddd
ST_RGBM		- CSTPic<uc_pixel>	- UCHAR r,g,b,m channels</uc_pixel>
Toshihiro Shimizu 890ddd
ST_RGBM64	- CSTPic<us_pixel>	- USHORT r,g,b,m channels</us_pixel>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
The CMAP RASTER pictures have to be converted to ST_RGBM or
Shinya Kitaoka 120a6e
ST_RGBM64, but the CMAP information can be used with the help
Shinya Kitaoka 120a6e
of m_raster.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
m_lX,m_lY - the length of the picture in X,Y direction
Toshihiro Shimizu 890ddd
m_pic - the buffer of the picture
Shinya Kitaoka 120a6e
m_ras - stores the pointer to the original RASTER picture
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
************************************************************/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz4.6/udit.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/raster.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/pixel.h"
Toshihiro Shimizu 890ddd
#include "SDef.h"
Toshihiro Shimizu 890ddd
#include "SError.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define ISINPIC(x, y) (m_pic && x >= 0 && x < m_lX && y >= 0 && y < m_lY)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef enum {
luzpaz 27707d
  ST_NIL,    // EMPTY
Shinya Kitaoka 120a6e
  ST_RGBM,   // UC_PIXEL
Shinya Kitaoka 120a6e
  ST_RGBM64  // US_PIXEL
Toshihiro Shimizu 890ddd
} ST_TYPE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Old 4.6 picture class template (sandor fxs). There is a significant
Shinya Kitaoka 120a6e
//! modification
Shinya Kitaoka 120a6e
//! to be considered starting from Toonz 6.1 - the allocated raster is now
Shinya Kitaoka 120a6e
//! managed
Shinya Kitaoka 120a6e
//! by the image cache. Basically, when constructing one such object, the image
Shinya Kitaoka 120a6e
//! is locked
Shinya Kitaoka 120a6e
//! in the Toonz cache - and you must remember to unlock and relock it along
Shinya Kitaoka 120a6e
//! inactivity periods.
Toshihiro Shimizu 890ddd
template <class p=""></class>
Shinya Kitaoka 120a6e
class CSTPic {
Shinya Kitaoka 120a6e
  std::string m_cacheId;
Shinya Kitaoka 120a6e
  TRasterImageP m_picP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  int m_lX, m_lY;
Shinya Kitaoka 120a6e
  P *m_pic;
Shinya Kitaoka 120a6e
  const RASTER *m_ras;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CSTPic(void)
Shinya Kitaoka 120a6e
      : m_cacheId(TImageCache::instance()->getUniqueId())
Shinya Kitaoka 120a6e
      , m_lX(0)
Shinya Kitaoka 120a6e
      , m_lY(0)
Shinya Kitaoka 120a6e
      , m_pic(0)
Shinya Kitaoka 120a6e
      , m_ras(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void nullPic() {
Shinya Kitaoka 120a6e
    // if ( m_pic ) { delete [] m_pic; m_pic=0; }
Shinya Kitaoka 120a6e
    unlock();
Shinya Kitaoka 120a6e
    TImageCache::instance()->remove(m_cacheId);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Retrieves the raster image from the cache to work with it.
Shinya Kitaoka 120a6e
  void lock() {
Shinya Kitaoka 120a6e
    m_picP = TImageCache::instance()->get(m_cacheId, true);
Shinya Kitaoka 120a6e
    m_pic  = (P *)m_picP->getRaster()->getRawData();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Release the raster image for inactivity periods.
Shinya Kitaoka 120a6e
  void unlock() {
Shinya Kitaoka 120a6e
    m_picP = 0;
Shinya Kitaoka 120a6e
    m_pic  = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CSTPic(const int lX, const int lY)
Shinya Kitaoka 120a6e
      :  // throw(SMemAllocError) :
Shinya Kitaoka 120a6e
      m_cacheId(TImageCache::instance()->getUniqueId())
Shinya Kitaoka 120a6e
      , m_lX(lX)
Shinya Kitaoka 120a6e
      , m_lY(lY)
Shinya Kitaoka 120a6e
      , m_pic(0)
Shinya Kitaoka 120a6e
      , m_ras(0) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      initPic();
Shinya Kitaoka 120a6e
    } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
      null();
Shinya Kitaoka 120a6e
      throw;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CSTPic(const CSTPic

&sp)

Shinya Kitaoka 120a6e
      :  // throw(SMemAllocError) :
Shinya Kitaoka 120a6e
      m_lX(sp.m_lX)
Shinya Kitaoka 120a6e
      , m_lY(sp.m_lY)
Shinya Kitaoka 120a6e
      , m_pic(0)
Shinya Kitaoka 120a6e
      , m_ras(sp.m_ras) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      initPic();
Shinya Kitaoka 120a6e
      copyPic(sp);
Shinya Kitaoka 120a6e
    } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
      null();
Shinya Kitaoka 120a6e
      throw;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~CSTPic(void) { null(); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Allocates the specified raster and surrenders it to the image cache.
Shinya Kitaoka 120a6e
  //!\b NOTE: The raster being initialized is LOCKED after this call.
Shinya Kitaoka 120a6e
  //! You must remember to UNLOCK it when no more used.
Shinya Kitaoka 120a6e
  void initPic()  // throw(SMemAllocError)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    nullPic();
Shinya Kitaoka 120a6e
    if (m_lX > 0 && m_lY > 0) {
Shinya Kitaoka 120a6e
      // m_pic=new P[m_lX*m_lY];
Shinya Kitaoka 120a6e
      TRasterGR8P ras(m_lX * m_lY * sizeof(P), 1);
Shinya Kitaoka 120a6e
      if (!ras) throw SMemAllocError("in initPic");
Shinya Kitaoka 120a6e
      TImageCache::instance()->add(m_cacheId, TRasterImageP(ras));
Shinya Kitaoka 120a6e
      lock();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      char s[200];
Rozhuk Ivan 823a31
      snprintf(s, sizeof(s), "in initPic lXY=(%d,%d)\n", m_lX, m_lY);
Shinya Kitaoka 120a6e
      throw SMemAllocError(s);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void null() {
Shinya Kitaoka 120a6e
    nullPic();
Shinya Kitaoka 120a6e
    m_lX = m_lY = 0;
Shinya Kitaoka 120a6e
    m_ras       = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Draws the border of the CSTPic
Shinya Kitaoka 120a6e
  void drawRect(const P &ip) {
Shinya Kitaoka 120a6e
    SRECT rect = {0, 0, m_lX - 1, m_lY - 1};
Shinya Kitaoka 120a6e
    drawRect(rect, ip);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //------------------- The following need to be *LOCKED* before the call
Shinya Kitaoka 120a6e
  //------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Currently there are two types of STPic
Shinya Kitaoka 120a6e
  // ST_RGBM   -	UCHAR r,g,b,m channels
Shinya Kitaoka 120a6e
  // ST_RGBM64 -	USHORT r,g,b,m channels
Shinya Kitaoka 120a6e
  ST_TYPE getType() const {
Shinya Kitaoka 120a6e
    if (!m_pic) return ST_NIL;
Shinya Kitaoka 120a6e
    if (sizeof(m_pic->r) == sizeof(UCHAR)) return ST_RGBM;
Shinya Kitaoka 120a6e
    if (sizeof(m_pic->r) == sizeof(USHORT)) return ST_RGBM64;
Shinya Kitaoka 120a6e
    return ST_NIL;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Copies the 'sp' CSTPic into 'm_pic'
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void copyPic(const CSTPic

&sp) {

Shinya Kitaoka 120a6e
    P p;
Shinya Kitaoka 120a6e
    for (int y = 0; y < m_lY && y < sp.m_lY; y++)
Shinya Kitaoka 120a6e
      for (int x = 0; x < m_lX && x < sp.m_lX; x++) {
Shinya Kitaoka 120a6e
        sp.getPixel(x, y, p);
Shinya Kitaoka 120a6e
        setRGBM(x, y, p);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Copies the 'r' rectangle of 'sp' CSTPic into the 'p' position
Shinya Kitaoka 120a6e
  // of 'm_pic'
Shinya Kitaoka 120a6e
  void copyPic(const CSTPic

&sp, const SRECT &r, const SPOINT &p) {

Shinya Kitaoka 120a6e
    P ip;
Shinya Kitaoka 120a6e
    int xs, ys, xd, yd;
Shinya Kitaoka 120a6e
    for (ys = r.y0, yd = p.y; ys <= r.y1; ys++, yd++)
Shinya Kitaoka 120a6e
      for (xs = r.x0, xd = p.x; xs <= r.x1; xs++, xd++) {
Shinya Kitaoka 120a6e
        sp.getPixel(xs, ys, ip);
Shinya Kitaoka 120a6e
        setRGBM(xd, yd, ip);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Draws a rectangle into CSTPic
Shinya Kitaoka 120a6e
  void drawRect(const SRECT &rect, const P &ip) {
Shinya Kitaoka 120a6e
    for (int x = rect.x0; x <= rect.x1; x++) {
Shinya Kitaoka 120a6e
      setRGBM(x, rect.y0, ip);
Shinya Kitaoka 120a6e
      setRGBM(x, rect.y1, ip);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int y = rect.y0; y <= rect.y1; y++) {
Shinya Kitaoka 120a6e
      setRGBM(rect.x0, y, ip);
Shinya Kitaoka 120a6e
      setRGBM(rect.x1, y, ip);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void erease() {
Shinya Kitaoka 120a6e
    P p = {0, 0, 0, 0};
Shinya Kitaoka 120a6e
    fill(p);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void fill(const P &ip) {
Shinya Kitaoka 120a6e
    for (int y = 0; y < m_lY; y++)
Shinya Kitaoka 120a6e
      for (int x = 0; x < m_lX; x++) setRGBM(x, y, ip);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Checks whether (x,y) is a proper coordinate
Shinya Kitaoka 120a6e
  inline bool isInPic(const int x, const int y) const {
Shinya Kitaoka 120a6e
    return (m_pic && x >= 0 && x < m_lX && y >= 0 && y < m_lY);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Sets the color of the CSTPic pixel
Shinya Kitaoka 120a6e
  void setRGB(const int x, const int y, const P &ip) {
Shinya Kitaoka 120a6e
    if (ISINPIC(x, y)) {
Shinya Kitaoka 120a6e
      P *p = m_pic + y * m_lX + x;
Shinya Kitaoka 120a6e
      p->r = ip.r;
Shinya Kitaoka 120a6e
      p->g = ip.g;
Shinya Kitaoka 120a6e
      p->b = ip.b;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setRGBM(const int x, const int y, const P &ip) {
Shinya Kitaoka 120a6e
    if (ISINPIC(x, y)) {
Shinya Kitaoka 120a6e
      P *p = m_pic + y * m_lX + x;
Shinya Kitaoka 120a6e
      p->r = ip.r;
Shinya Kitaoka 120a6e
      p->g = ip.g;
Shinya Kitaoka 120a6e
      p->b = ip.b;
Shinya Kitaoka 120a6e
      p->m = ip.m;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Sets the color of the CSTPic pixel
Shinya Kitaoka 120a6e
  void setRGB(const int x, const int y, const I_PIXEL &ip) {
Shinya Kitaoka 120a6e
    if (ISINPIC(x, y)) {
Shinya Kitaoka 120a6e
      P *p = m_pic + y * m_lX + x;
Shinya Kitaoka 120a6e
      if (getType() == ST_RGBM) {
Shinya Kitaoka 120a6e
        p->r = (UCHAR)I_CUT_0_255(ip.r);
Shinya Kitaoka 120a6e
        p->g = (UCHAR)I_CUT_0_255(ip.g);
Shinya Kitaoka 120a6e
        p->b = (UCHAR)I_CUT_0_255(ip.b);
Shinya Kitaoka 120a6e
      } else if (getType() == ST_RGBM64) {
Shinya Kitaoka 120a6e
        p->r = (USHORT)I_CUT_0_65535(ip.r);
Shinya Kitaoka 120a6e
        p->g = (USHORT)I_CUT_0_65535(ip.g);
Shinya Kitaoka 120a6e
        p->b = (USHORT)I_CUT_0_65535(ip.b);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setRGBM(const int x, const int y, const I_PIXEL &ip) {
Shinya Kitaoka 120a6e
    if (ISINPIC(x, y)) {
Shinya Kitaoka 120a6e
      P *p = m_pic + y * m_lX + x;
Shinya Kitaoka 120a6e
      if (getType() == ST_RGBM) {
Shinya Kitaoka 120a6e
        p->r = (UCHAR)I_CUT_0_255(ip.r);
Shinya Kitaoka 120a6e
        p->g = (UCHAR)I_CUT_0_255(ip.g);
Shinya Kitaoka 120a6e
        p->b = (UCHAR)I_CUT_0_255(ip.b);
Shinya Kitaoka 120a6e
        p->m = (UCHAR)I_CUT_0_255(ip.m);
Shinya Kitaoka 120a6e
      } else if (getType() == ST_RGBM64) {
Shinya Kitaoka 120a6e
        p->r = I_CUT_0_65535(ip.r);
Shinya Kitaoka 120a6e
        p->g = I_CUT_0_65535(ip.g);
Shinya Kitaoka 120a6e
        p->b = I_CUT_0_65535(ip.b);
Shinya Kitaoka 120a6e
        p->m = I_CUT_0_65535(ip.m);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Gets the color of the CSTPic pixel
Shinya Kitaoka 120a6e
  void getPixel(const int x, const int y, P &ip) const {
Shinya Kitaoka 120a6e
    if (ISINPIC(x, y)) {
Shinya Kitaoka 120a6e
      const P *p = m_pic + y * m_lX + x;
Shinya Kitaoka 120a6e
      ASSIGN_PIXEL(&ip, p);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ip.r = ip.g = ip.b = ip.m = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void getPixel(const int x, const int y, I_PIXEL &ip) const {
Shinya Kitaoka 120a6e
    if (ISINPIC(x, y)) {
Shinya Kitaoka 120a6e
      const P *p = m_pic + y * m_lX + x;
Shinya Kitaoka 120a6e
      ip.r       = (int)p->r;
Shinya Kitaoka 120a6e
      ip.g       = (int)p->g;
Shinya Kitaoka 120a6e
      ip.b       = (int)p->b;
Shinya Kitaoka 120a6e
      ip.m       = (int)p->m;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ip.r = ip.g = ip.b = ip.m = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Gets the color of a RASTER pixel
Shinya Kitaoka 120a6e
  // RASTER operation always gets I_PIXEL color and I_PIXEL is casted
Shinya Kitaoka 120a6e
  // to the right type
Shinya Kitaoka 120a6e
  void getRasterPixel(const RASTER *ras, const int x, const int y,
Shinya Kitaoka 120a6e
                      I_PIXEL &ip) const {
Shinya Kitaoka 120a6e
    if (x >= 0 && x < ras->lx && y >= 0 && y < ras->ly && ras->buffer) {
Shinya Kitaoka 120a6e
      LPIXEL *pL;
Shinya Kitaoka 120a6e
      LPIXEL pLL;
Shinya Kitaoka 120a6e
      SPIXEL *pS;
Shinya Kitaoka 120a6e
      UD44_CMAPINDEX32 *ci32;
Shinya Kitaoka 120a6e
      // UD44_PIXEL32* pen;
Shinya Kitaoka 120a6e
      UD44_PIXEL32 *col;
Shinya Kitaoka 120a6e
      switch (ras->type) {
Shinya Kitaoka 120a6e
      case (RAS_RGBM):
Shinya Kitaoka 120a6e
        pL   = (LPIXEL *)(ras->buffer) + y * ras->wrap + x;
Shinya Kitaoka 120a6e
        ip.r = (int)pL->r;
Shinya Kitaoka 120a6e
        ip.g = (int)pL->g;
Shinya Kitaoka 120a6e
        ip.b = (int)pL->b;
Shinya Kitaoka 120a6e
        ip.m = (int)pL->m;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      case (RAS_RGBM64):
Shinya Kitaoka 120a6e
        pS   = (SPIXEL *)(ras->buffer) + y * ras->wrap + x;
Shinya Kitaoka 120a6e
        ip.r = (int)pS->r;
Shinya Kitaoka 120a6e
        ip.g = (int)pS->g;
Shinya Kitaoka 120a6e
        ip.b = (int)pS->b;
Shinya Kitaoka 120a6e
        ip.m = (int)pS->m;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      case (RAS_CM32):
Shinya Kitaoka 120a6e
        ci32 = (UD44_CMAPINDEX32 *)(ras->buffer) + y * ras->wrap + x;
Shinya Kitaoka 120a6e
        col  = (UD44_PIXEL32 *)(ras->cmap.buffer);
Shinya Kitaoka 120a6e
        PIX_CM32_MAP_TO_RGBM(*ci32, col, pLL)
Shinya Kitaoka 120a6e
        ip.r = (int)pLL.r;
Shinya Kitaoka 120a6e
        ip.g = (int)pLL.g;
Shinya Kitaoka 120a6e
        ip.b = (int)pLL.b;
Shinya Kitaoka 120a6e
        ip.m = (int)pLL.m;
Shinya Kitaoka 120a6e
        break;
Rozhuk Ivan 823a31
      default:
Rozhuk Ivan 823a31
         break;
Rozhuk Ivan 823a31
     }
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      ip.r = ip.g = ip.b = ip.m = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void getRasterPixel(const int x, const int y, I_PIXEL &ip) const {
Shinya Kitaoka 120a6e
    if (m_ras)
Shinya Kitaoka 120a6e
      getRasterPixel(m_ras, x, y, ip);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      ip.r = ip.g = ip.b = ip.m = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Sets the color of a RASTER pixel
Shinya Kitaoka 120a6e
  // RASTER operation always gets I_PIXEL color and I_PIXEL is casted
Shinya Kitaoka 120a6e
  // to the right type
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setRasterPixel(RASTER *ras, const int x, const int y,
Shinya Kitaoka 120a6e
                      const I_PIXEL &ip) const {
Shinya Kitaoka 120a6e
    if (x >= 0 && x < ras->lx && y >= 0 && y < ras->ly && ras->buffer) {
Shinya Kitaoka 120a6e
      LPIXEL *pL;
Shinya Kitaoka 120a6e
      SPIXEL *pS;
Shinya Kitaoka 120a6e
      switch (ras->type) {
Shinya Kitaoka 120a6e
      case (RAS_RGBM):
Shinya Kitaoka 120a6e
        pL    = (LPIXEL *)(ras->buffer) + y * ras->wrap + x;
Shinya Kitaoka 120a6e
        pL->r = (UCHAR)ip.r;
Shinya Kitaoka 120a6e
        pL->g = (UCHAR)ip.g;
Shinya Kitaoka 120a6e
        pL->b = (UCHAR)ip.b;
Shinya Kitaoka 120a6e
        pL->m = (UCHAR)ip.m;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      case (RAS_RGBM64):
Shinya Kitaoka 120a6e
        pS    = (SPIXEL *)(ras->buffer) + y * ras->wrap + x;
Shinya Kitaoka 120a6e
        pS->r = (USHORT)ip.r;
Shinya Kitaoka 120a6e
        pS->g = (USHORT)ip.g;
Shinya Kitaoka 120a6e
        pS->b = (USHORT)ip.b;
Shinya Kitaoka 120a6e
        pS->m = (USHORT)ip.m;
Shinya Kitaoka 120a6e
        break;
Rozhuk Ivan 823a31
      default:
Rozhuk Ivan 823a31
         break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool copy_raster(const RASTER *ir, RASTER *out_r, const int xBeg,
Shinya Kitaoka 120a6e
                   const int yBeg, const int xEnd, const int yEnd, const int ox,
Shinya Kitaoka 120a6e
                   const int oy)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if ((ir->lx <= 0) || (ir->ly <= 0) || (out_r->lx <= 0) || (out_r->ly <= 0))
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    if (ir->buffer == NULL || out_r->buffer == NULL) return false;
Shinya Kitaoka 120a6e
    if (out_r->type == RAS_CM32) return false;
Shinya Kitaoka 120a6e
    if (ir->type == RAS_CM32 && (ir->cmap.buffer == NULL)) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int y = yBeg, yy = oy; y <= yEnd; y++, yy++)
Shinya Kitaoka 120a6e
      for (int x = xBeg, xx = ox; x <= xEnd; x++, xx++) {
Shinya Kitaoka 120a6e
        I_PIXEL ip;
Shinya Kitaoka 120a6e
        getRasterPixel(ir, x, y, ip);
Shinya Kitaoka 120a6e
        if (xx >= 0 && yy >= 0 && xx < out_r->lx && yy < out_r->ly) {
Shinya Kitaoka 120a6e
          LPIXEL *pL;
Shinya Kitaoka 120a6e
          SPIXEL *pS;
Shinya Kitaoka 120a6e
          if (out_r->type == RAS_RGBM &&
Shinya Kitaoka 120a6e
              (ir->type == RAS_RGBM || ir->type == RAS_CM32)) {
Shinya Kitaoka 120a6e
            pL    = (LPIXEL *)(out_r->buffer) + yy * out_r->wrap + xx;
Shinya Kitaoka 120a6e
            pL->r = (UCHAR)ip.r;
Shinya Kitaoka 120a6e
            pL->g = (UCHAR)ip.g;
Shinya Kitaoka 120a6e
            pL->b = (UCHAR)ip.b;
Shinya Kitaoka 120a6e
            pL->m = (UCHAR)ip.m;
Shinya Kitaoka 120a6e
          } else if (out_r->type == RAS_RGBM && ir->type == RAS_RGBM64) {
Shinya Kitaoka 120a6e
            pL    = (LPIXEL *)(out_r->buffer) + yy * out_r->wrap + xx;
Shinya Kitaoka 120a6e
            pL->r = PIX_BYTE_FROM_USHORT((USHORT)ip.r);
Shinya Kitaoka 120a6e
            pL->g = PIX_BYTE_FROM_USHORT((USHORT)ip.g);
Shinya Kitaoka 120a6e
            pL->b = PIX_BYTE_FROM_USHORT((USHORT)ip.b);
Shinya Kitaoka 120a6e
            pL->m = PIX_BYTE_FROM_USHORT((USHORT)ip.m);
Shinya Kitaoka 120a6e
          } else if (out_r->type == RAS_RGBM64 &&
Shinya Kitaoka 120a6e
                     (ir->type == RAS_RGBM || ir->type == RAS_CM32)) {
Shinya Kitaoka 120a6e
            pS    = (SPIXEL *)(out_r->buffer) + yy * out_r->wrap + xx;
Shinya Kitaoka 120a6e
            pS->r = PIX_USHORT_FROM_BYTE((UCHAR)ip.r);
Shinya Kitaoka 120a6e
            pS->g = PIX_USHORT_FROM_BYTE((UCHAR)ip.g);
Shinya Kitaoka 120a6e
            pS->b = PIX_USHORT_FROM_BYTE((UCHAR)ip.b);
Shinya Kitaoka 120a6e
            pS->m = PIX_USHORT_FROM_BYTE((UCHAR)ip.m);
Shinya Kitaoka 120a6e
          } else if (out_r->type == RAS_RGBM64 && ir->type == RAS_RGBM64) {
Shinya Kitaoka 120a6e
            pS    = (SPIXEL *)(out_r->buffer) + yy * out_r->wrap + xx;
Shinya Kitaoka 120a6e
            pS->r = (USHORT)ip.r;
Shinya Kitaoka 120a6e
            pS->g = (USHORT)ip.g;
Shinya Kitaoka 120a6e
            pS->b = (USHORT)ip.b;
Shinya Kitaoka 120a6e
            pS->m = (USHORT)ip.m;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Generates and reads the CSTPic using RASTER.
Shinya Kitaoka 120a6e
  // \b NOTE: This LOCKS the raster being read. You must remember to unlock it
Shinya Kitaoka 120a6e
  // afterwards
Shinya Kitaoka 120a6e
  // when it is needed no more.
Shinya Kitaoka 120a6e
  virtual void read(const RASTER *ras)  // throw(SMemAllocError)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      null();
Shinya Kitaoka 120a6e
      if (((ras->type == RAS_RGBM || ras->type == RAS_RGBM64) && ras->buffer &&
Shinya Kitaoka 120a6e
           ras->lx > 0 && ras->ly > 0) ||
Shinya Kitaoka 120a6e
          (ras->type == RAS_CM32 && ras->buffer && ras->cmap.buffer &&
Shinya Kitaoka 120a6e
           ras->lx > 0 && ras->ly > 0)) {
Shinya Kitaoka 120a6e
        m_lX  = ras->lx;
Shinya Kitaoka 120a6e
        m_lY  = ras->ly;
Shinya Kitaoka 120a6e
        m_ras = ras;
Shinya Kitaoka 120a6e
        initPic();
Shinya Kitaoka 120a6e
        lock();
Shinya Kitaoka 120a6e
        ST_TYPE type = getType();
Shinya Kitaoka 120a6e
        P *p         = m_pic;
Shinya Kitaoka 120a6e
        I_PIXEL ip;
Shinya Kitaoka 120a6e
        memset(&ip, 0, sizeof(I_PIXEL));
Shinya Kitaoka 120a6e
        for (int y = 0; y < m_lY; y++)
Shinya Kitaoka 120a6e
          for (int x = 0; x < m_lX; x++, p++) {
Shinya Kitaoka 120a6e
            getRasterPixel(ras, x, y, ip);
Shinya Kitaoka 120a6e
            switch (type) {
Shinya Kitaoka 120a6e
            case (ST_RGBM):
Shinya Kitaoka 120a6e
              if (ras->type == RAS_RGBM64) {
Shinya Kitaoka 120a6e
                // RGBM have to be 'scaled' from USHORT to UCHAR
Shinya Kitaoka 120a6e
                p->r = PIX_BYTE_FROM_USHORT((USHORT)ip.r);
Shinya Kitaoka 120a6e
                p->g = PIX_BYTE_FROM_USHORT((USHORT)ip.g);
Shinya Kitaoka 120a6e
                p->b = PIX_BYTE_FROM_USHORT((USHORT)ip.b);
Shinya Kitaoka 120a6e
                p->m = PIX_BYTE_FROM_USHORT((USHORT)ip.m);
Shinya Kitaoka 120a6e
              } else {
Shinya Kitaoka 120a6e
                // RGBM are UCHAR in the raster
Shinya Kitaoka 120a6e
                p->r = (UCHAR)ip.r;
Shinya Kitaoka 120a6e
                p->g = (UCHAR)ip.g;
Shinya Kitaoka 120a6e
                p->b = (UCHAR)ip.b;
Shinya Kitaoka 120a6e
                p->m = (UCHAR)ip.m;
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
              break;
Shinya Kitaoka 120a6e
            case (ST_RGBM64):
Shinya Kitaoka 120a6e
              if (ras->type == RAS_RGBM64) {
Shinya Kitaoka 120a6e
                // RGBM are USHORT in the raster
Shinya Kitaoka 120a6e
                p->r = ip.r;
Shinya Kitaoka 120a6e
                p->g = ip.g;
Shinya Kitaoka 120a6e
                p->b = ip.b;
Shinya Kitaoka 120a6e
                p->m = ip.m;
Shinya Kitaoka 120a6e
              } else {
Shinya Kitaoka 120a6e
                // RGBM have to be 'scaled' from UCHAR to USHORT
Shinya Kitaoka 120a6e
                p->r = PIX_USHORT_FROM_BYTE((UCHAR)ip.r);
Shinya Kitaoka 120a6e
                p->g = PIX_USHORT_FROM_BYTE((UCHAR)ip.g);
Shinya Kitaoka 120a6e
                p->b = PIX_USHORT_FROM_BYTE((UCHAR)ip.b);
Shinya Kitaoka 120a6e
                p->m = PIX_USHORT_FROM_BYTE((UCHAR)ip.m);
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
              break;
Rozhuk Ivan 823a31
            default:
Rozhuk Ivan 823a31
              break;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
      null();
Shinya Kitaoka 120a6e
      throw;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const CSTPic

&operator=(const CSTPic

&sp) // throw(SMemAllocError)

Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      null();
Shinya Kitaoka 120a6e
      m_lX  = sp.m_lX;
Shinya Kitaoka 120a6e
      m_lY  = sp.m_lY;
Shinya Kitaoka 120a6e
      m_ras = sp.m_ras;
Shinya Kitaoka 120a6e
      initPic();
Shinya Kitaoka 120a6e
      copyPic(sp);
Shinya Kitaoka 120a6e
    } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
      null();
Shinya Kitaoka 120a6e
      throw;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return (*this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Writes the CSTPic into the RASTER
Shinya Kitaoka 120a6e
  virtual void write(RASTER *ras) const  // throw(SWriteRasterError)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if ((ras->type == RAS_RGBM || ras->type == RAS_RGBM64) && ras->lx > 0 &&
Shinya Kitaoka 120a6e
        ras->ly > 0 && ras->buffer) {
Shinya Kitaoka 120a6e
      int x, y;
Shinya Kitaoka 120a6e
      I_PIXEL ip;
Shinya Kitaoka 120a6e
      const P *p;
Shinya Kitaoka 120a6e
      for (y = 0; y < m_lY && y < ras->ly; y++)
Shinya Kitaoka 120a6e
        for (x = 0; x < m_lX && x < ras->lx; x++) {
Shinya Kitaoka 120a6e
          p    = m_pic + y * m_lX + x;
Shinya Kitaoka 120a6e
          ip.r = (int)p->r;
Shinya Kitaoka 120a6e
          ip.g = (int)p->g;
Shinya Kitaoka 120a6e
          ip.b = (int)p->b;
Shinya Kitaoka 120a6e
          ip.m = (int)p->m;
Shinya Kitaoka 120a6e
          setRasterPixel(ras, x, y, ip);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw SWriteRasterError("(bad Raster type)");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Writes the 'r' rectangle of CSTPic into the 'p' position in RASTER
Shinya Kitaoka 120a6e
  virtual void write(RASTER *ras, const SRECT &r, const SPOINT &p) const
Shinya Kitaoka 120a6e
  // throw(SWriteRasterError)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (ras->type == RAS_RGBM || ras->type == RAS_RGBM64) {
Shinya Kitaoka 120a6e
      int xs, ys, xd, yd;
Shinya Kitaoka 120a6e
      P pp;
Shinya Kitaoka 120a6e
      I_PIXEL ip;
Shinya Kitaoka 120a6e
      for (ys = r.y0, yd = p.y; ys <= r.y1; ys++, yd++)
Shinya Kitaoka 120a6e
        for (xs = r.x0, xd = p.x; xs <= r.x1; xs++, xd++) {
Shinya Kitaoka 120a6e
          getPixel(xs, ys, pp);
Shinya Kitaoka 120a6e
          ip.r = (int)pp.r;
Shinya Kitaoka 120a6e
          ip.g = (int)pp.g;
Shinya Kitaoka 120a6e
          ip.b = (int)pp.b;
Shinya Kitaoka 120a6e
          ip.m = (int)pp.m;
Shinya Kitaoka 120a6e
          setRasterPixel(ras, xd, yd, ip);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw SWriteRasterError("(bad Raster type)");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual void writeOutBorder(const RASTER *rasin, const int border,
Shinya Kitaoka 120a6e
                              RASTER *ras, const SRECT &r,
Shinya Kitaoka 120a6e
                              const SPOINT &p) const
Shinya Kitaoka 120a6e
  // throw(SWriteRasterError)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    assert(rasin->type == RAS_CM32);
Shinya Kitaoka 120a6e
    UD44_PIXEL32 *col = (UD44_PIXEL32 *)(rasin->cmap.buffer);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (ras->type == RAS_RGBM || ras->type == RAS_RGBM64) {
Shinya Kitaoka 120a6e
      int xs, ys, xd, yd;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      I_PIXEL ip;
Shinya Kitaoka 120a6e
      for (ys = r.y0, yd = p.y; ys <= r.y1; ys++, yd++)
Shinya Kitaoka 120a6e
        for (xs = r.x0, xd = p.x; xs <= r.x1; xs++, xd++) {
Shinya Kitaoka 120a6e
          int x = xd - border;
Shinya Kitaoka 120a6e
          int y = yd - border;
Shinya Kitaoka 120a6e
          if (x >= 0 && y >= 0 && x < rasin->lx && y < rasin->ly) {
Shinya Kitaoka 120a6e
            UD44_CMAPINDEX32 pixel =
Shinya Kitaoka 120a6e
                *(((UD44_CMAPINDEX32 *)rasin->buffer) + y * rasin->wrap + x);
Shinya Kitaoka 120a6e
            // int tone = (pix&0xff);
Shinya Kitaoka 120a6e
            // int paint = ((pix>>8)&0xfff);
Shinya Kitaoka 120a6e
            if ((pixel & 0xff) == 0 || ((pixel >> 8) & 0xfff) != 0) {
Shinya Kitaoka 120a6e
              LPIXEL pLL;
Shinya Kitaoka 120a6e
              PIX_CM32_MAP_TO_RGBM(pixel, col, pLL)
Shinya Kitaoka 120a6e
              ip.r = (int)pLL.r;
Shinya Kitaoka 120a6e
              ip.g = (int)pLL.g;
Shinya Kitaoka 120a6e
              ip.b = (int)pLL.b;
Shinya Kitaoka 120a6e
              ip.m = (int)pLL.m;
Shinya Kitaoka 120a6e
              setRasterPixel(ras, xd, yd, ip);
Shinya Kitaoka 120a6e
              continue;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          P pp;
Shinya Kitaoka 120a6e
          getPixel(xs, ys, pp);
Shinya Kitaoka 120a6e
          ip.r = (int)pp.r;
Shinya Kitaoka 120a6e
          ip.g = (int)pp.g;
Shinya Kitaoka 120a6e
          ip.b = (int)pp.b;
Shinya Kitaoka 120a6e
          ip.m = (int)pp.m;
Shinya Kitaoka 120a6e
          setRasterPixel(ras, xd, yd, ip);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw SWriteRasterError("(bad Raster type)");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void convertToCurrentType(P &d, const I_PIXEL &s) const {
Shinya Kitaoka 120a6e
    if (getType() == ST_RGBM) {
Shinya Kitaoka 120a6e
      d.r = (UCHAR)s.r;
Shinya Kitaoka 120a6e
      d.g = (UCHAR)s.g;
Shinya Kitaoka 120a6e
      d.b = (UCHAR)s.b;
Shinya Kitaoka 120a6e
      d.m = (UCHAR)s.m;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (getType() == ST_RGBM64) {
Shinya Kitaoka 120a6e
      d.r = (USHORT)s.r;
Shinya Kitaoka 120a6e
      d.g = (USHORT)s.g;
Shinya Kitaoka 120a6e
      d.b = (USHORT)s.b;
Shinya Kitaoka 120a6e
      d.m = (USHORT)s.m;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isSameColor(const P *a, const P *b) const {
Shinya Kitaoka 120a6e
    if (a->r == b->r && a->g == b->g && a->b == b->b) return true;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void colorNoise(const I_PIXEL &cc1, const I_PIXEL &cc2, const double d) {
Shinya Kitaoka 120a6e
    P c1, c2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (d <= 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    convertToCurrentType(c1, cc1);
Shinya Kitaoka 120a6e
    convertToCurrentType(c2, cc2);
Shinya Kitaoka 120a6e
    int xy  = m_lX * m_lY;
Shinya Kitaoka 120a6e
    P *pPic = m_pic;
Shinya Kitaoka 120a6e
    for (int i = 0; i < xy; i++, pPic++)
Shinya Kitaoka 120a6e
      if (isSameColor(&c1, pPic)) {
Shinya Kitaoka 120a6e
        double q = (rand() % 101) / 100.0;
Shinya Kitaoka 120a6e
        q        = d * q;
Shinya Kitaoka 120a6e
        q        = q > 1.0 ? 1.0 : q;
Shinya Kitaoka 120a6e
        double r = (1.0 - q) * (double)c1.r + q * (double)c2.r;
Shinya Kitaoka 120a6e
        double g = (1.0 - q) * (double)c1.g + q * (double)c2.g;
Shinya Kitaoka 120a6e
        double b = (1.0 - q) * (double)c1.b + q * (double)c2.b;
Shinya Kitaoka 120a6e
        r        = D_CUT_0_255(r);
Shinya Kitaoka 120a6e
        g        = D_CUT_0_255(g);
Shinya Kitaoka 120a6e
        b        = D_CUT_0_255(b);
Shinya Kitaoka 120a6e
        pPic->r  = UC_ROUND(r);
Shinya Kitaoka 120a6e
        pPic->g  = UC_ROUND(g);
Shinya Kitaoka 120a6e
        pPic->b  = UC_ROUND(b);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
void hlsNoise(const double d)
Toshihiro Shimizu 890ddd
{	int xy=m_lX*m_lY;
Shinya Kitaoka 120a6e
  P* p=m_pic;
Shinya Kitaoka 120a6e
  for( int i=0; i
Shinya Kitaoka 120a6e
          if ( p->m>0 ) {
Shinya Kitaoka 120a6e
                  double h,l,s,q;
Shinya Kitaoka 120a6e
                  rgb2hls(p->r,p->g,p->b,&h,&l,&s);
Shinya Kitaoka 120a6e
                  q=1.0-d*(double)((rand()%201)-100)/100.0;
Shinya Kitaoka 120a6e
                  l*=q;
Shinya Kitaoka 120a6e
                  hls2rgb(h,l,s,&(p->r),&(p->g),&(p->b));
Shinya Kitaoka 120a6e
          }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void rgb2hls(UCHAR r, UCHAR g, UCHAR b, double *h, double *l, double *s) {
Shinya Kitaoka 120a6e
    double ma, mi, delta, sum;
Shinya Kitaoka 120a6e
    double rf, gf, bf;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rf = (double)r / 255.0;
Shinya Kitaoka 120a6e
    gf = (double)g / 255.0;
Shinya Kitaoka 120a6e
    bf = (double)b / 255.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ma    = rf > gf ? rf : gf;
Shinya Kitaoka 120a6e
    ma    = ma > bf ? ma : bf;
Shinya Kitaoka 120a6e
    mi    = rf < gf ? rf : gf;
Shinya Kitaoka 120a6e
    mi    = mi < bf ? mi : bf;
Shinya Kitaoka 120a6e
    sum   = ma + mi;
Shinya Kitaoka 120a6e
    delta = ma - mi;
Shinya Kitaoka 120a6e
    *l    = sum / 2.0;
Shinya Kitaoka 120a6e
    if (fabs(delta) < 0.000001) {
Shinya Kitaoka 120a6e
      *s = 0.0;
Shinya Kitaoka 120a6e
      *h = UNDEFINED;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      *s = *l <= 0.5 ? delta / sum : delta / (2.0 - sum);
Shinya Kitaoka 120a6e
      *h = fabs((rf - ma)) < 0.000001
Shinya Kitaoka 120a6e
               ? (gf - bf) / delta
Shinya Kitaoka 120a6e
               : (fabs((gf - ma)) < 0.000001 ? 2.0 + (bf - rf) / delta
Shinya Kitaoka 120a6e
                                             : 4.0 + (rf - gf) / delta);
Shinya Kitaoka 120a6e
      *h *= 60;
Shinya Kitaoka 120a6e
      *h = *h < 0.0 ? *h + 360.0 : *h;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double fromHue(double n1, double n2, double hue) {
Shinya Kitaoka 120a6e
    double v, h;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    h = hue > 360.0 ? hue - 360.0 : hue;
Shinya Kitaoka 120a6e
    h = h < 0.0 ? h + 360.0 : h;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (h < 60.0) {
Shinya Kitaoka 120a6e
      v = n1 + (n2 - n1) * h / 60.0;
Shinya Kitaoka 120a6e
    } else if (h < 180.0) {
Shinya Kitaoka 120a6e
      v = n2;
Shinya Kitaoka 120a6e
    } else if (h < 240.0) {
Shinya Kitaoka 120a6e
      v = n1 + (n2 - n1) * (240.0 - h) / 60.0;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      v = n1;
Shinya Kitaoka 120a6e
    return (v);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void hls2rgb(double h, double l, double s, UCHAR *r, UCHAR *g, UCHAR *b) {
Shinya Kitaoka 120a6e
    double rf, gf, bf;
Shinya Kitaoka 120a6e
    double m1, m2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m2 = l <= 0.5 ? l * (1.0 + s) : l + s - l * s;
Shinya Kitaoka 120a6e
    m1 = 2 * l - m2;
Shinya Kitaoka 120a6e
    if (fabs(s - 0.0) < 0.000001) {
Shinya Kitaoka 120a6e
      if (fabs(h - UNDEFINED) < 0.000001) {
Shinya Kitaoka 120a6e
        rf = gf = bf = l * 255.0;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        rf = gf = bf = 0.0;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      rf = fromHue(m1, m2, h + 120.0) * 255.0;
Shinya Kitaoka 120a6e
      gf = fromHue(m1, m2, h) * 255.0;
Shinya Kitaoka 120a6e
      bf = fromHue(m1, m2, h - 120.0) * 255.0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    rf = D_CUT_0_255(rf);
Shinya Kitaoka 120a6e
    gf = D_CUT_0_255(gf);
Shinya Kitaoka 120a6e
    bf = D_CUT_0_255(bf);
Shinya Kitaoka 120a6e
    *r = UC_ROUND(rf);
Shinya Kitaoka 120a6e
    *g = UC_ROUND(gf);
Shinya Kitaoka 120a6e
    *b = UC_ROUND(bf);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Shinya Kitaoka 120a6e
#endif  // !defined(AFX_STPIC_H__BABE9488_F054_11D5_B927_0040F674BE6A__INCLUDED_)