Toshihiro Shimizu 890ddd
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
#if _MSC_VER > 1000
Toshihiro Shimizu 890ddd
#pragma once
Toshihiro Shimizu 890ddd
#endif // _MSC_VER > 1000
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
Toshihiro Shimizu 890ddd
The CMAP RASTER pictures have to be converted to ST_RGBM or 
Toshihiro Shimizu 890ddd
ST_RGBM64, but the CMAP information can be used with the help 
Toshihiro Shimizu 890ddd
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
Toshihiro Shimizu 890ddd
m_ras - stores the pointer to the original RASTER picture 
Toshihiro Shimizu 890ddd
   
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 {
Toshihiro Shimizu 890ddd
	ST_NIL,   // EMTY
Toshihiro Shimizu 890ddd
	ST_RGBM,  // UC_PIXEL
Toshihiro Shimizu 890ddd
	ST_RGBM64 // US_PIXEL
Toshihiro Shimizu 890ddd
} ST_TYPE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Old 4.6 picture class template (sandor fxs). There is a significant modification
Toshihiro Shimizu 890ddd
//! to be considered starting from Toonz 6.1 - the allocated raster is now managed
Toshihiro Shimizu 890ddd
//! by the image cache. Basically, when constructing one such object, the image is locked
Toshihiro Shimizu 890ddd
//! in the Toonz cache - and you must remember to unlock and relock it along inactivity periods.
Toshihiro Shimizu 890ddd
template <class p=""></class>
Toshihiro Shimizu 890ddd
class CSTPic
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 3bfa54
	std::string m_cacheId;
Toshihiro Shimizu 890ddd
	TRasterImageP m_picP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	int m_lX, m_lY;
Toshihiro Shimizu 890ddd
	P *m_pic;
Toshihiro Shimizu 890ddd
	const RASTER *m_ras;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CSTPic(void) : m_cacheId(TImageCache::instance()->getUniqueId()),
Toshihiro Shimizu 890ddd
				   m_lX(0), m_lY(0), m_pic(0), m_ras(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void nullPic()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		//if ( m_pic ) { delete [] m_pic; m_pic=0; }
Toshihiro Shimizu 890ddd
		unlock();
Toshihiro Shimizu 890ddd
		TImageCache::instance()->remove(m_cacheId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//!Retrieves the raster image from the cache to work with it.
Toshihiro Shimizu 890ddd
	void lock()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_picP = TImageCache::instance()->get(m_cacheId, true);
Toshihiro Shimizu 890ddd
		m_pic = (P *)m_picP->getRaster()->getRawData();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//!Release the raster image for inactivity periods.
Toshihiro Shimizu 890ddd
	void unlock()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_picP = 0;
Toshihiro Shimizu 890ddd
		m_pic = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CSTPic(const int lX, const int lY) : //throw(SMemAllocError) :
Toshihiro Shimizu 890ddd
										 m_cacheId(TImageCache::instance()->getUniqueId()),
Toshihiro Shimizu 890ddd
										 m_lX(lX), m_lY(lY),
Toshihiro Shimizu 890ddd
										 m_pic(0), m_ras(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			initPic();
Toshihiro Shimizu 890ddd
		} catch (SMemAllocError) {
Toshihiro Shimizu 890ddd
			null();
Toshihiro Shimizu 890ddd
			throw;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CSTPic(const CSTPic

&sp) : //throw(SMemAllocError) :

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

&sp)

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

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

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

&operator=(const CSTPic

&sp) // throw(SMemAllocError)

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