Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename channel_type="" pixel,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void computeBBox(TRasterPT<pixel> ras, TRect &bbox)</pixel>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bbox = ras->getBounds();
Toshihiro Shimizu 890ddd
	int lx = ras->getLx();
Toshihiro Shimizu 890ddd
	int ly = ras->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// se c'e' un pixel opaco in alto a sin e in basso a destra allora bbox = bounds
Toshihiro Shimizu 890ddd
	if (ras->pixels(0)[0].m != 0 &&
Toshihiro Shimizu 890ddd
		ras->pixels(ly - 1)[lx - 1].m != 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int y;
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
	for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
		CHANNEL_TYPE *pix = &(ras->pixels(y)->m);
Toshihiro Shimizu 890ddd
		CHANNEL_TYPE *endPix = pix + 4 * lx;
Toshihiro Shimizu 890ddd
		while (pix < endPix && *pix == 0)
Toshihiro Shimizu 890ddd
			pix += 4;
Toshihiro Shimizu 890ddd
		if (pix < endPix)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (y == ly) {
Toshihiro Shimizu 890ddd
		// tutta trasparente
Toshihiro Shimizu 890ddd
		bbox = TRect();
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	bbox.y0 = y;
Toshihiro Shimizu 890ddd
	for (y = ly - 1; y > bbox.y0; y--) {
Toshihiro Shimizu 890ddd
		CHANNEL_TYPE *pix = &(ras->pixels(y)->m);
Toshihiro Shimizu 890ddd
		CHANNEL_TYPE *endPix = pix + 4 * lx;
Toshihiro Shimizu 890ddd
		while (pix < endPix && *pix == 0)
Toshihiro Shimizu 890ddd
			pix += 4;
Toshihiro Shimizu 890ddd
		if (pix < endPix)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	bbox.y1 = y;
Toshihiro Shimizu 890ddd
	assert(bbox.y0 <= bbox.y1);
Toshihiro Shimizu 890ddd
	bbox.x0 = lx;
Toshihiro Shimizu 890ddd
	bbox.x1 = -1;
Toshihiro Shimizu 890ddd
	for (y = bbox.y0; y <= bbox.y1; y++) {
Toshihiro Shimizu 890ddd
		CHANNEL_TYPE *row = &(ras->pixels(y)->m);
Toshihiro Shimizu 890ddd
		int x = 0;
Toshihiro Shimizu 890ddd
		for (x = 0; x < bbox.x0 && row[x * 4] == 0; x++) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		bbox.x0 = x;
Toshihiro Shimizu 890ddd
		for (x = lx - 1; x > bbox.x1 && row[x * 4] == 0; x--) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		bbox.x1 = x;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(bbox.x0 <= bbox.x1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ras->unlock();
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UCHAR *row_m = &(ras->pixels()->m);
Toshihiro Shimizu 890ddd
  // se c'e' un pixel opaco in alto a sin e in basso a destra allora bbox = bounds
Toshihiro Shimizu 890ddd
  if(row_m[0] && row_m[(ly-1)*wrap4 + (lx-1)*4])
Toshihiro Shimizu 890ddd
	  return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  int y;
Toshihiro Shimizu 890ddd
  UCHAR *m, *max_m, *min_m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  for(y=0;y
Toshihiro Shimizu 890ddd
	  {   
Toshihiro Shimizu 890ddd
     max_m = row_m + lx * 4;
Toshihiro Shimizu 890ddd
		 for(m = row_m; m
Toshihiro Shimizu 890ddd
		 if(m
Toshihiro Shimizu 890ddd
		 row_m += wrap4;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
  if(y>=ly)
Toshihiro Shimizu 890ddd
	  {
Toshihiro Shimizu 890ddd
		 // tutta trasparente
Toshihiro Shimizu 890ddd
		 return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bbox.y0 = bbox.y1 = y;
Toshihiro Shimizu 890ddd
  bbox.x0 = (m - row_m)/4;
Toshihiro Shimizu 890ddd
  assert(0<=bbox.x0 && bbox.x0
Toshihiro Shimizu 890ddd
  assert(ras->pixels(bbox.y0)[bbox.x0].m>0);
Toshihiro Shimizu 890ddd
  assert(bbox.x0 == 0 || ras->pixels(bbox.y0)[bbox.x0-1].m==0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  min_m = m;
Toshihiro Shimizu 890ddd
  for(m = max_m - 4;m>min_m && *m==0;m-=4) {}
Toshihiro Shimizu 890ddd
  bbox.x1 = (m - row_m)/4;
Toshihiro Shimizu 890ddd
  assert(0<=bbox.x1 && bbox.x1
Toshihiro Shimizu 890ddd
  assert(ras->pixels(bbox.y0)[bbox.x1].m>0);
Toshihiro Shimizu 890ddd
  assert(bbox.x1 == lx-1 || ras->pixels(bbox.y0)[bbox.x1+1].m==0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	row_m += wrap4;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  for(y++;y
Toshihiro Shimizu 890ddd
	  {   
Toshihiro Shimizu 890ddd
     max_m = row_m + lx * 4;
Toshihiro Shimizu 890ddd
		 for(m = row_m; m
Toshihiro Shimizu 890ddd
		 if(m
Toshihiro Shimizu 890ddd
		   {
Toshihiro Shimizu 890ddd
			  int x = (m - row_m)/4;
Toshihiro Shimizu 890ddd
				if(x
Toshihiro Shimizu 890ddd
				  {
Toshihiro Shimizu 890ddd
					 bbox.x0 = x;
Toshihiro Shimizu 890ddd
           assert(0<=bbox.x0 && bbox.x0
Toshihiro Shimizu 890ddd
           assert(ras->pixels(y)[bbox.x0].m>0);
Toshihiro Shimizu 890ddd
           assert(bbox.x0 == 0 || ras->pixels(y)[bbox.x0-1].m==0);
Toshihiro Shimizu 890ddd
          }
Toshihiro Shimizu 890ddd
        min_m = row_m + bbox.x1*4;
Toshihiro Shimizu 890ddd
			  for(m = max_m - 4;m>min_m && *m==0;m-=4) {}
Toshihiro Shimizu 890ddd
				if(m>min_m) 
Toshihiro Shimizu 890ddd
				  {
Toshihiro Shimizu 890ddd
					 x = (m - row_m)/4;
Toshihiro Shimizu 890ddd
					 assert(x>bbox.x1);
Toshihiro Shimizu 890ddd
					 bbox.x1 = x;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				bbox.y1 = y;
Toshihiro Shimizu 890ddd
			 }
Toshihiro Shimizu 890ddd
		 row_m += wrap4;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline bool isTransparent(TPixelCM32 *pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (!pix->isPureInk() &&
Toshihiro Shimizu 890ddd
			//  (pix->getPaint()==BackgroundStyle
Toshihiro Shimizu 890ddd
			(pix->getPaint() == 0 && pix->isPurePaint()));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void computeBBoxCM32(TRasterCM32P ras, TRect &bbox)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bbox = ras->getBounds();
Toshihiro Shimizu 890ddd
	int lx = ras->getLx();
Toshihiro Shimizu 890ddd
	int ly = ras->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// se c'e' un pixel opaco in alto a sin e in basso a destra allora bbox = bounds
Toshihiro Shimizu 890ddd
	if (!isTransparent(&(ras->pixels(0)[0])) &&
Toshihiro Shimizu 890ddd
		!isTransparent(&(ras->pixels(ly - 1)[lx - 1])))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int y;
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
	for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
		TPixelCM32 *pix = ras->pixels(y);
Toshihiro Shimizu 890ddd
		TPixelCM32 *endPix = pix + lx;
Toshihiro Shimizu 890ddd
		while (pix < endPix && isTransparent(pix))
Toshihiro Shimizu 890ddd
			++pix;
Toshihiro Shimizu 890ddd
		if (pix < endPix)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (y == ly) {
Toshihiro Shimizu 890ddd
		// tutta trasparente
Toshihiro Shimizu 890ddd
		bbox = TRect();
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	bbox.y0 = y;
Toshihiro Shimizu 890ddd
	for (y = ly - 1; y > bbox.y0; y--) {
Toshihiro Shimizu 890ddd
		TPixelCM32 *pix = ras->pixels(y);
Toshihiro Shimizu 890ddd
		TPixelCM32 *endPix = pix + lx;
Toshihiro Shimizu 890ddd
		while (pix < endPix && isTransparent(pix))
Toshihiro Shimizu 890ddd
			++pix;
Toshihiro Shimizu 890ddd
		if (pix < endPix)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	bbox.y1 = y;
Toshihiro Shimizu 890ddd
	assert(bbox.y0 <= bbox.y1);
Toshihiro Shimizu 890ddd
	bbox.x0 = lx;
Toshihiro Shimizu 890ddd
	bbox.x1 = -1;
Toshihiro Shimizu 890ddd
	for (y = bbox.y0; y <= bbox.y1; y++) {
Toshihiro Shimizu 890ddd
		TPixelCM32 *row = ras->pixels(y);
Toshihiro Shimizu 890ddd
		int x = 0;
Toshihiro Shimizu 890ddd
		for (x = 0; x < bbox.x0 && isTransparent(&row[x]); x++) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		bbox.x0 = x;
Toshihiro Shimizu 890ddd
		for (x = lx - 1; x > bbox.x1 && isTransparent(&row[x]); x--) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		bbox.x1 = x;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(bbox.x0 <= bbox.x1);
Toshihiro Shimizu 890ddd
	ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRop::computeBBox(TRasterP ras, TRect &bbox)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P ras32 = ras;
Toshihiro Shimizu 890ddd
	if (ras32) {
Toshihiro Shimizu 890ddd
		::computeBBox<tpixel32, uchar="">(ras32, bbox);</tpixel32,>
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster64P ras64 = ras;
Toshihiro Shimizu 890ddd
	if (ras64) {
Toshihiro Shimizu 890ddd
		::computeBBox<tpixel64, ushort="">(ras64, bbox);</tpixel64,>
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterCM32P rasCM32 = ras;
Toshihiro Shimizu 890ddd
	if (rasCM32) {
Toshihiro Shimizu 890ddd
		computeBBoxCM32(rasCM32, bbox);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterGR8P ras8 = ras;
Toshihiro Shimizu 890ddd
	if (ras8) {
Toshihiro Shimizu 890ddd
		bbox = ras->getBounds();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(0);
Toshihiro Shimizu 890ddd
}