Exemplo n.º 1
0
int32_t CxImage::Histogram(int32_t* red, int32_t* green, int32_t* blue, int32_t* gray, int32_t colorspace)
{
	if (!pDib) return 0;
	RGBQUAD color;

	if (red) memset(red,0,256*sizeof(int32_t));
	if (green) memset(green,0,256*sizeof(int32_t));
	if (blue) memset(blue,0,256*sizeof(int32_t));
	if (gray) memset(gray,0,256*sizeof(int32_t));

	int32_t xmin,xmax,ymin,ymax;
	if (pSelection){
		xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
		ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
	} else {
		xmin = ymin = 0;
		xmax = head.biWidth; ymax=head.biHeight;
	}

	for(int32_t y=ymin; y<ymax; y++){
		for(int32_t x=xmin; x<xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
			if (BlindSelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
			{
				switch (colorspace){
				case 1:
					color = HSLtoRGB(BlindGetPixelColor(x,y));
					break;
				case 2:
					color = YUVtoRGB(BlindGetPixelColor(x,y));
					break;
				case 3:
					color = YIQtoRGB(BlindGetPixelColor(x,y));
					break;
				case 4:
					color = XYZtoRGB(BlindGetPixelColor(x,y));
					break;
				default:
					color = BlindGetPixelColor(x,y);
				}

				if (red) red[color.rgbRed]++;
				if (green) green[color.rgbGreen]++;
				if (blue) blue[color.rgbBlue]++;
				if (gray) gray[(uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
			}
		}
	}

	int32_t n=0;
	for (int32_t i=0; i<256; i++){
		if (red && red[i]>n) n=red[i];
		if (green && green[i]>n) n=green[i];
		if (blue && blue[i]>n) n=blue[i];
		if (gray && gray[i]>n) n=gray[i];
	}

	return n;
}
Exemplo n.º 2
0
/**
 * Adds to the selection all the pixels matching the specified color.
 */
bool CxImage::SelectionAddColor(RGBQUAD c, uint8_t level)
{
    if (pSelection==NULL) SelectionCreate();
	if (pSelection==NULL) return false;

	RECT localbox = {head.biWidth,0,0,head.biHeight};

    for (int32_t y = 0; y < head.biHeight; y++){
        for (int32_t x = 0; x < head.biWidth; x++){
            RGBQUAD color = BlindGetPixelColor(x, y);
            if (color.rgbRed   == c.rgbRed &&
				color.rgbGreen == c.rgbGreen &&
                color.rgbBlue  == c.rgbBlue)
            {
                pSelection[x + y * head.biWidth] = level;

				if (localbox.top < y) localbox.top = y;
				if (localbox.left > x) localbox.left = x;
				if (localbox.right < x) localbox.right = x;
				if (localbox.bottom > y) localbox.bottom = y;
            }
        }
    }

	if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = localbox.top + 1;
	if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
	if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = localbox.right + 1;
	if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;

	return true;
}
Exemplo n.º 3
0
/**
 * exports the image into a RGBA buffer, Useful for OpenGL applications.
 * \param hFile: file handle (CxMemFile or CxIOFile), with write access.
 * \param bFlipY: direction of Y axis. default = false.
 * \return true if everything is ok
 */
bool CxImage::Encode2RGB(CxFile *hFile, bool bFlipY)
{
	if (EncodeSafeCheck(hFile)) return false;

	for (int32_t y1 = 0; y1 < head.biHeight; y1++) {
		int32_t y = bFlipY ? head.biHeight - 1 - y1 : y1;
		for(int32_t x = 0; x < head.biWidth; x++) {
			RGBQUAD color = BlindGetPixelColor(x,y);
			hFile->PutC(color.rgbRed);
			hFile->PutC(color.rgbGreen);
			hFile->PutC(color.rgbBlue);
		}
	}
	return true;
}
Exemplo n.º 4
0
/**
 * Blends the alpha channel and the alpha palette with the pixels. The result is a 24 bit image.
 * The background color can be selected using SetTransColor().
 */
void CxImage::AlphaStrip()
{
	bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
	bool bAlphaIsValid = AlphaIsValid();
	if (!(bAlphaIsValid || bAlphaPaletteIsValid)) return;
	RGBQUAD c;
	long a, a1;
	if (head.biBitCount==24){
		for(long y=0; y<head.biHeight; y++){
			for(long x=0; x<head.biWidth; x++){
				c = BlindGetPixelColor(x,y);
				if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
				a1 = 256-a;
				c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>8);
				c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
				c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
				BlindSetPixelColor(x,y,c);
			}
		}
		AlphaDelete();
	} else {
Exemplo n.º 5
0
/**
 * HistogramStretch
 * \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels.
 * \param threshold: minimum percentage level in the histogram to recognize it as meaningful. Range: 0.0 to 1.0; default = 0; typical = 0.005 (0.5%);
 * \return true if everything is ok
 * \author [dave] and [nipper]; changes [DP]
 */
bool CxImage::HistogramStretch(long method, double threshold)
{
	
	

	if (!pDib) return false;

	double dbScaler = 50.0/head.biHeight;
	long x,y;

  if ((head.biBitCount==8) && IsGrayScale()){

	double p[256];
	memset(p,  0, 256*sizeof(double));
	for (y=0; y<head.biHeight; y++)
	{
		info.nProgress = (long)(y*dbScaler);
		if (info.nEscape) break;
		for (x=0; x<head.biWidth; x++)	{
			p[BlindGetPixelIndex(x, y)]++;
		}
	}

	double maxh = 0;
	for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
	threshold *= maxh;
	int minc = 0;
	while (minc<255 && p[minc]<=threshold) minc++;
	int maxc = 255;
	while (maxc>0 && p[maxc]<=threshold) maxc--;

	if (minc == 0 && maxc == 255) return true;
	if (minc >= maxc) return true;

	// calculate LUT
	BYTE lut[256];
	for (x = 0; x <256; x++){
		lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
	}

	for (y=0; y<head.biHeight; y++)	{
		if (info.nEscape) break;
		info.nProgress = (long)(50.0+y*dbScaler);
		for (x=0; x<head.biWidth; x++)
		{
			BlindSetPixelIndex(x, y, lut[BlindGetPixelIndex(x, y)]);
		}
	}
  } else {
	switch(method){
	case 1:
	  { // <nipper>
		double p[256];
		memset(p,  0, 256*sizeof(double));
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(y*dbScaler);
			if (info.nEscape) break;
			for (x=0; x<head.biWidth; x++)	{
				RGBQUAD color = BlindGetPixelColor(x, y);
				p[color.rgbRed]++;
				p[color.rgbBlue]++;
				p[color.rgbGreen]++;
			}
		}
		double maxh = 0;
		for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
		threshold *= maxh;
		int minc = 0;
		while (minc<255 && p[minc]<=threshold) minc++;
		int maxc = 255;
		while (maxc>0 && p[maxc]<=threshold) maxc--;

		if (minc == 0 && maxc == 255) return true;
		if (minc >= maxc) return true;

		// calculate LUT
		BYTE lut[256];
		for (x = 0; x <256; x++){
			lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
		}

		// normalize image
		for (y=0; y<head.biHeight; y++)	{
			if (info.nEscape) break;
			info.nProgress = (long)(50.0+y*dbScaler);

			for (x=0; x<head.biWidth; x++)
			{
				RGBQUAD color = BlindGetPixelColor(x, y);

				color.rgbRed = lut[color.rgbRed];
				color.rgbBlue = lut[color.rgbBlue];
				color.rgbGreen = lut[color.rgbGreen];

				BlindSetPixelColor(x, y, color);
			}
		}
	  }
		break;
	case 2:
	  { // <nipper>
		double pR[256];
		memset(pR,  0, 256*sizeof(double));
		double pG[256];
		memset(pG,  0, 256*sizeof(double));
		double pB[256];
		memset(pB,  0, 256*sizeof(double));
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(y*dbScaler);
			if (info.nEscape) break;
			for (long x=0; x<head.biWidth; x++)	{
				RGBQUAD color = BlindGetPixelColor(x, y);
				pR[color.rgbRed]++;
				pB[color.rgbBlue]++;
				pG[color.rgbGreen]++;
			}
		}

		double maxh = 0;
		for (y=0; y<255; y++) if (maxh < pR[y]) maxh = pR[y];
		double threshold2 = threshold*maxh;
		int minR = 0;
		while (minR<255 && pR[minR]<=threshold2) minR++;
		int maxR = 255;
		while (maxR>0 && pR[maxR]<=threshold2) maxR--;

		maxh = 0;
		for (y=0; y<255; y++) if (maxh < pG[y]) maxh = pG[y];
		threshold2 = threshold*maxh;
		int minG = 0;
		while (minG<255 && pG[minG]<=threshold2) minG++;
		int maxG = 255;
		while (maxG>0 && pG[maxG]<=threshold2) maxG--;

		maxh = 0;
		for (y=0; y<255; y++) if (maxh < pB[y]) maxh = pB[y];
		threshold2 = threshold*maxh;
		int minB = 0;
		while (minB<255 && pB[minB]<=threshold2) minB++;
		int maxB = 255;
		while (maxB>0 && pB[maxB]<=threshold2) maxB--;

		if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
			return true;

		// calculate LUT
		BYTE lutR[256];
		BYTE range = maxR - minR;
		if (range != 0)	{
			for (x = 0; x <256; x++){
				lutR[x] = (BYTE)max(0,min(255,(255 * (x - minR) / range)));
			}
		} else lutR[minR] = minR;

		BYTE lutG[256];
		range = maxG - minG;
		if (range != 0)	{
			for (x = 0; x <256; x++){
				lutG[x] = (BYTE)max(0,min(255,(255 * (x - minG) / range)));
			}
		} else lutG[minG] = minG;
			
		BYTE lutB[256];
		range = maxB - minB;
		if (range != 0)	{
			for (x = 0; x <256; x++){
				lutB[x] = (BYTE)max(0,min(255,(255 * (x - minB) / range)));
			}
		} else lutB[minB] = minB;

		// normalize image
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(50.0+y*dbScaler);
			if (info.nEscape) break;

			for (x=0; x<head.biWidth; x++)
			{
				RGBQUAD color = BlindGetPixelColor(x, y);

				color.rgbRed = lutR[color.rgbRed];
				color.rgbBlue = lutB[color.rgbBlue];
				color.rgbGreen = lutG[color.rgbGreen];

				BlindSetPixelColor(x, y, color);
			}
		}
	  }
		break;
	default:
	  { // <dave>
		double p[256];
		memset(p,  0, 256*sizeof(double));
		for (y=0; y<head.biHeight; y++)
		{
			info.nProgress = (long)(y*dbScaler);
			if (info.nEscape) break;
			for (x=0; x<head.biWidth; x++)	{
				RGBQUAD color = BlindGetPixelColor(x, y);
				p[RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue)]++;
			}
		}

		double maxh = 0;
		for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
		threshold *= maxh;
		int minc = 0;
		while (minc<255 && p[minc]<=threshold) minc++;
		int maxc = 255;
		while (maxc>0 && p[maxc]<=threshold) maxc--;

		if (minc == 0 && maxc == 255) return true;
		if (minc >= maxc) return true;

		// calculate LUT
		BYTE lut[256];
		for (x = 0; x <256; x++){
			lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
		}

		for(y=0; y<head.biHeight; y++){
			info.nProgress = (long)(50.0+y*dbScaler);
			if (info.nEscape) break;
			for(x=0; x<head.biWidth; x++){

				RGBQUAD color = BlindGetPixelColor( x, y );
				RGBQUAD yuvClr = RGBtoYUV(color);
				yuvClr.rgbRed = lut[yuvClr.rgbRed];
				color = YUVtoRGB(yuvClr);
				BlindSetPixelColor( x, y, color );
			}
		}
	  }
	}
  }
  return true;
}
Exemplo n.º 6
0
////////////////////////////////////////////////////////////////////////////////
// HistogramRoot function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramRoot()
{
	
	

	if (!pDib) return false;
	//q(i,j) = sqrt(|p(i,j)|);

    int x, y, i;
	RGBQUAD color;
	RGBQUAD	 yuvClr;
	double	dtmp;
	unsigned int YVal, high = 1;

     // Find Highest Luminance Value in the Image
	if( head.biClrUsed == 0 ){ // No Palette
		for(y=0; y < head.biHeight; y++){
			info.nProgress = (long)(50*y/head.biHeight);
			if (info.nEscape) break;
			for(x=0; x < head.biWidth; x++){
				color = BlindGetPixelColor( x, y );
				YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
				if (YVal > high ) high = YVal;
			}
		}
	} else { // Palette
		for(i = 0; i < (int)head.biClrUsed; i++){
			color = GetPaletteColor((BYTE)i);
			YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			if (YVal > high ) high = YVal;
		}
	}

	// Root Operator
	double k = 128.0 / ::log( 1.0 + (double)high );
	if( head.biClrUsed == 0 ){
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (long)(50+50*y/head.biHeight);
			if (info.nEscape) break;
			for( x = 0; x < head.biWidth; x++ ){

				color = BlindGetPixelColor( x, y );
				yuvClr = RGBtoYUV( color );

				dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
				if ( dtmp > 255.0 )	dtmp = 255.0;
				if ( dtmp < 0 )	dtmp = 0;
                yuvClr.rgbRed = (BYTE)dtmp;

				color = YUVtoRGB( yuvClr );
				BlindSetPixelColor( x, y, color );
			}
		}
	} else {
		for(i = 0; i < (int)head.biClrUsed; i++){

			color = GetPaletteColor( (BYTE)i );
			yuvClr = RGBtoYUV( color );

			dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
			if ( dtmp > 255.0 )	dtmp = 255.0;
			if ( dtmp < 0 ) dtmp = 0;
            yuvClr.rgbRed = (BYTE)dtmp;

			color = YUVtoRGB( yuvClr );
 			SetPaletteColor( (BYTE)i, color );
		}
	}
 
	return true;
}
Exemplo n.º 7
0
////////////////////////////////////////////////////////////////////////////////
// HistogramNormalize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramNormalize()
{
	
	

	if (!pDib) return false;

	int histogram[256];
	int threshold_intensity, intense;
	int x, y, i;
	unsigned int normalize_map[256];
	unsigned int high, low, YVal;

	RGBQUAD color;
	RGBQUAD	yuvClr;

	memset( &histogram, 0, sizeof( int ) * 256 );
	memset( &normalize_map, 0, sizeof( unsigned int ) * 256 );
 
     // form histogram
	for(y=0; y < head.biHeight; y++){
		info.nProgress = (long)(50*y/head.biHeight);
		if (info.nEscape) break;
		for(x=0; x < head.biWidth; x++){
			color = BlindGetPixelColor( x, y );
			YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			histogram[YVal]++;
		}
	}

	// find histogram boundaries by locating the 1 percent levels
	threshold_intensity = ( head.biWidth * head.biHeight) / 100;

	intense = 0;
	for( low = 0; low < 255; low++ ){
		intense += histogram[low];
		if( intense > threshold_intensity )	break;
	}

	intense = 0;
	for( high = 255; high != 0; high--){
		intense += histogram[ high ];
		if( intense > threshold_intensity ) break;
	}

	if ( low == high ){
		// Unreasonable contrast;  use zero threshold to determine boundaries.
		threshold_intensity = 0;
		intense = 0;
		for( low = 0; low < 255; low++){
			intense += histogram[low];
			if( intense > threshold_intensity )	break;
		}
		intense = 0;
		for( high = 255; high != 0; high-- ){
			intense += histogram [high ];
			if( intense > threshold_intensity )	break;
		}
	}
	if( low == high ) return false;  // zero span bound

	// Stretch the histogram to create the normalized image mapping.
	for(i = 0; i <= 255; i++){
		if ( i < (int) low ){
			normalize_map[i] = 0;
		} else {
			if(i > (int) high)
				normalize_map[i] = 255;
			else
				normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low );
		}
	}

	// Normalize
	if( head.biClrUsed == 0 ){
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (long)(50+50*y/head.biHeight);
			if (info.nEscape) break;
			for( x = 0; x < head.biWidth; x++ ){

				color = BlindGetPixelColor( x, y );
				yuvClr = RGBtoYUV( color );

                yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];

				color = YUVtoRGB( yuvClr );
				BlindSetPixelColor( x, y, color );
			}
		}
	} else {
		for(i = 0; i < (int)head.biClrUsed; i++){

			color = GetPaletteColor( (BYTE)i );
			yuvClr = RGBtoYUV( color );

            yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];

			color = YUVtoRGB( yuvClr );
 			SetPaletteColor( (BYTE)i, color );
		}
	}
	return true;
}
Exemplo n.º 8
0
////////////////////////////////////////////////////////////////////////////////
// HistogramEqualize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramEqualize()
{
	
	

	if (!pDib) return false;

    int histogram[256];
	int map[256];
	int equalize_map[256];
    int x, y, i, j;
	RGBQUAD color;
	RGBQUAD	yuvClr;
	unsigned int YVal, high, low;

	memset( &histogram, 0, sizeof(int) * 256 );
	memset( &map, 0, sizeof(int) * 256 );
	memset( &equalize_map, 0, sizeof(int) * 256 );
 
     // form histogram
	for(y=0; y < head.biHeight; y++){
		info.nProgress = (long)(50*y/head.biHeight);
		if (info.nEscape) break;
		for(x=0; x < head.biWidth; x++){
			color = BlindGetPixelColor( x, y );
			YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			histogram[YVal]++;
		}
	}

	// integrate the histogram to get the equalization map.
	j = 0;
	for(i=0; i <= 255; i++){
		j += histogram[i];
		map[i] = j; 
	}

	// equalize
	low = map[0];
	high = map[255];
	if (low == high) return false;
	for( i = 0; i <= 255; i++ ){
		equalize_map[i] = (unsigned int)((((double)( map[i] - low ) ) * 255) / ( high - low ) );
	}

	// stretch the histogram
	if(head.biClrUsed == 0){ // No Palette
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (long)(50+50*y/head.biHeight);
			if (info.nEscape) break;
			for( x = 0; x < head.biWidth; x++ ){

				color = BlindGetPixelColor( x, y );
				yuvClr = RGBtoYUV(color);

                yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];

				color = YUVtoRGB(yuvClr);
				BlindSetPixelColor( x, y, color );
			}
		}
	} else { // Palette
		for( i = 0; i < (int)head.biClrUsed; i++ ){

			color = GetPaletteColor((BYTE)i);
			yuvClr = RGBtoYUV(color);

            yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];

			color = YUVtoRGB(yuvClr);
			SetPaletteColor( (BYTE)i, color );
		}
	}
	return true;
}
Exemplo n.º 9
0
long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace)
{
	
	

	if (!pDib) return 0;
	RGBQUAD color;

	if (red) memset(red,0,256*sizeof(long));
	if (green) memset(green,0,256*sizeof(long));
	if (blue) memset(blue,0,256*sizeof(long));
	if (gray) memset(gray,0,256*sizeof(long));

	long xmin,xmax,ymin,ymax;
	if (pSelection){
		xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
		ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
	} else {
		xmin = ymin = 0;
		xmax = head.biWidth - 1; ymax=head.biHeight - 1;
	}

	for(long y=ymin; y<=ymax; y++){
		for(long x=xmin; x<=xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
			if (BlindSelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
			{
				switch (colorspace){
				case 1:
					color = HSLtoRGB(BlindGetPixelColor(x,y));
					break;
				case 2:
					color = YUVtoRGB(BlindGetPixelColor(x,y));
					break;
				case 3:
					color = YIQtoRGB(BlindGetPixelColor(x,y));
					break;
				case 4:
					color = XYZtoRGB(BlindGetPixelColor(x,y));
					break;
				default:
					color = BlindGetPixelColor(x,y);
				}

				if (red) red[color.rgbRed]++;
				if (green) green[color.rgbGreen]++;
				if (blue) blue[color.rgbBlue]++;
				if (gray) gray[(BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
			}
		}
	}

	long n=0;
	long nMed=(long)((xmax*ymax)/3);
	for (int i=0; i<256; i++){
		if (red && red[i]>n) n=red[i];
		if (green && green[i]>n) n=green[i];
		if (blue && blue[i]>n) n=blue[i];
		if (gray) {
			n+=gray[i];
			if(n>nMed)
				return i;
		}
	}

	return n;
}
Exemplo n.º 10
0
bool CxImagePCX::Encode(CxFile * hFile)
{
	if (EncodeSafeCheck(hFile)) return false;

  cx_try
  {
	PCXHEADER pcxHeader;
	memset(&pcxHeader,0,sizeof(pcxHeader));
	pcxHeader.Manufacturer = PCX_MAGIC;
	pcxHeader.Version = 5;
	pcxHeader.Encoding = 1;
	pcxHeader.Xmin = 0;
	pcxHeader.Ymin = 0;
	pcxHeader.Xmax = (WORD)head.biWidth-1;
	pcxHeader.Ymax = (WORD)head.biHeight-1;
	pcxHeader.Hres = (WORD)info.xDPI;
	pcxHeader.Vres = (WORD)info.yDPI;
	pcxHeader.Reserved = 0;
	pcxHeader.PaletteType = head.biClrUsed==0;

	switch(head.biBitCount){
	case 24:
	case 8:
		{
			pcxHeader.BitsPerPixel = 8;
			pcxHeader.ColorPlanes = head.biClrUsed==0 ? 3 : 1;
#if CXIMAGE_SUPPORT_ALPHA
			if (AlphaIsValid() && head.biClrUsed==0) pcxHeader.ColorPlanes =4;
#endif //CXIMAGE_SUPPORT_ALPHA
			pcxHeader.BytesPerLine = (WORD)head.biWidth;
			break;
		}
	default: //(4 1)
		pcxHeader.BitsPerPixel = 1;
		pcxHeader.ColorPlanes = head.biClrUsed==16 ? 4 : 1;
		pcxHeader.BytesPerLine = (WORD)((head.biWidth * pcxHeader.BitsPerPixel + 7)>>3);
	}

    if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
		pcxHeader.ColorMap[0][0] = pcxHeader.ColorMap[0][1] = pcxHeader.ColorMap[0][2] = 0;
		pcxHeader.ColorMap[1][0] = pcxHeader.ColorMap[1][1] = pcxHeader.ColorMap[1][2] = 255;
	}
	if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 4){
		RGBQUAD c;
		for (int i = 0; i < 16; i++){
			c=GetPaletteColor(i);
			pcxHeader.ColorMap[i][0] = c.rgbRed;
			pcxHeader.ColorMap[i][1] = c.rgbGreen;
			pcxHeader.ColorMap[i][2] = c.rgbBlue;
		}
	}

	pcxHeader.BytesPerLine = (pcxHeader.BytesPerLine + 1)&(~1);

	PCX_toh(&pcxHeader);
	if (hFile->Write(&pcxHeader, sizeof(pcxHeader), 1) == 0 )
	   cx_throw("cannot write PCX header");
	PCX_toh(&pcxHeader);

	CxMemFile buffer;
	buffer.Open();

	BYTE c,n;
	long x,y;
	if (head.biClrUsed==0){
		for (y = head.biHeight-1; y >=0 ; y--){
			for (int p=0; p<pcxHeader.ColorPlanes; p++){
				c=n=0;
				for (x = 0; x<head.biWidth; x++){
					if (p==0)
						PCX_PackPixels(BlindGetPixelColor(x,y).rgbRed,c,n,buffer);
					else if (p==1)
						PCX_PackPixels(BlindGetPixelColor(x,y).rgbGreen,c,n,buffer);
					else if (p==2)
						PCX_PackPixels(BlindGetPixelColor(x,y).rgbBlue,c,n,buffer);
#if CXIMAGE_SUPPORT_ALPHA
					else if (p==3)
						PCX_PackPixels(BlindAlphaGet(x,y),c,n,buffer);
#endif //CXIMAGE_SUPPORT_ALPHA
				}
				PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
			}
		}

		hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);

	} else if (head.biBitCount==8) {

		for (y = head.biHeight-1; y >=0 ; y--){
			c=n=0;
			for (x = 0; x<head.biWidth; x++){
				PCX_PackPixels(GetPixelIndex(x,y),c,n,buffer);
			}
			PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
		}

		hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);

		if (head.biBitCount == 8){
			hFile->PutC(0x0C);
			BYTE* pal = (BYTE*)malloc(768);
			RGBQUAD c;
			for (int i=0;i<256;i++){
				c=GetPaletteColor(i);
				pal[3*i+0] = c.rgbRed;
				pal[3*i+1] = c.rgbGreen;
				pal[3*i+2] = c.rgbBlue;
			}
			hFile->Write(pal,768,1);
			free(pal);
		}
	} else { //(head.biBitCount==4) || (head.biBitCount==1)

		RGBQUAD *rgb = GetPalette();
		bool binvert = false;
		if (CompareColors(&rgb[0],&rgb[1])>0) binvert=(head.biBitCount==1);
		
		BYTE* plane = (BYTE*)malloc(pcxHeader.BytesPerLine);
		BYTE* raw = (BYTE*)malloc(head.biWidth);

		for(y = head.biHeight-1; y >=0 ; y--) {

			for( x = 0; x < head.biWidth; x++)	raw[x] = (BYTE)GetPixelIndex(x,y);

			if (binvert) for( x = 0; x < head.biWidth; x++)	raw[x] = 1-raw[x];

			for( x = 0; x < pcxHeader.ColorPlanes; x++ ) {
				PCX_PixelsToPlanes(raw, head.biWidth, plane, x);
				PCX_PackPlanes(plane, pcxHeader.BytesPerLine, buffer);
			}
		}

		free(plane);
		free(raw);

		hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);

	}

  } cx_catch {
	if (strcmp(message,"")) strncpy(info.szLastError,message,255);
	return false;
  }
    return true;
}
Exemplo n.º 11
0
////////////////////////////////////////////////////////////////////////////////
// HistogramLog function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramLog()
{
	if (!pDib) return false;

	//q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|);
    int32_t x, y, i;
	RGBQUAD color;
	RGBQUAD	yuvClr;

	uint32_t YVal, high = 1;

    // Find Highest Luminance Value in the Image
	if( head.biClrUsed == 0 ){ // No Palette
		for(y=0; y < head.biHeight; y++){
			info.nProgress = (int32_t)(50*y/head.biHeight);
			if (info.nEscape) break;
			for(x=0; x < head.biWidth; x++){
				color = BlindGetPixelColor( x, y );
				YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
				if (YVal > high ) high = YVal;
			}
		}
	} else { // Palette
		for(i = 0; i < (int32_t)head.biClrUsed; i++){
			color = GetPaletteColor((uint8_t)i);
			YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
			if (YVal > high ) high = YVal;
		}
	}

	// Logarithm Operator
	double k = 255.0 / ::log( 1.0 + (double)high );
	if( head.biClrUsed == 0 ){
		for( y = 0; y < head.biHeight; y++ ){
			info.nProgress = (int32_t)(50+50*y/head.biHeight);
			if (info.nEscape) break;
			for( x = 0; x < head.biWidth; x++ ){

				color = BlindGetPixelColor( x, y );
				yuvClr = RGBtoYUV( color );
                
				yuvClr.rgbRed = (uint8_t)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );

				color = YUVtoRGB( yuvClr );
				BlindSetPixelColor( x, y, color );
			}
		}
	} else {
		for(i = 0; i < (int32_t)head.biClrUsed; i++){

			color = GetPaletteColor( (uint8_t)i );
			yuvClr = RGBtoYUV( color );

            yuvClr.rgbRed = (uint8_t)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
			
			color = YUVtoRGB( yuvClr );
 			SetPaletteColor( (uint8_t)i, color );
		}
	}
 
	return true;
}
Exemplo n.º 12
0
bool CxImage::Vibrance(long strength)
{
	long xmin,xmax,ymin,ymax;
	if (pSelection){
		xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
		ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
	} else {
		xmin = ymin = 0;
		xmax = head.biWidth - 1; ymax=head.biHeight - 1;
	}

	if (xmin==xmax || ymin==ymax)
		return false;

	int size = (xmax - xmin + 1) * (ymax - ymin + 1);
	int histDistrib[256];
	::memset(histDistrib,0,256 * sizeof(int));
	BYTE maxSat = 0;
	for(long y=ymin; y<=ymax; y++){
		info.nProgress = (long)(100*(y-ymin)/(ymax-ymin));
		if (info.nEscape) break;
		for(long x=xmin; x<=xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
			if (BlindSelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
			{
				BYTE curSat = RGBtoHSL(BlindGetPixelColor(x,y)).rgbGreen;
				histDistrib[curSat]++;
				if (curSat > maxSat)
					maxSat = curSat;
			}
		}
	}

	BYTE ceilSat = (BYTE)min((int)maxSat + strength, 250);
	BYTE cTable[256];
	float fCurCum = 0.0f;
	float fStdDev = 0.0f;
	float fCumDistrib[256];
	for (int i=0;i<256;i++)	{
		cTable[i] = (BYTE)max(0,min((int)ceilSat,i + strength) - i);
		fStdDev += pow((float)size / 2.0f - (float)histDistrib[i], 2.0f);
		fCurCum += (float)histDistrib[i] / (float)size;		
		fCumDistrib[i] = max(0.0f, fCurCum);
	}
	fStdDev = (sqrt(fStdDev) / (float)size) * 255.0f;
	for (int i=0;i<256;i++)
		cTable[i] = (BYTE)(fCumDistrib[i] * (float)cTable[i] * CxMath::NormalDistrib (127.0f, fStdDev, (float)i, false));
	for(long y=ymin; y<=ymax; y++){
		info.nProgress = (long)(100*(y-ymin)/(ymax-ymin));
		if (info.nEscape) break;
		for(long x=xmin; x<=xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
			if (BlindSelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
			{
				RGBQUAD c = RGBtoHSL(BlindGetPixelColor(x,y));
				BYTE curSat = c.rgbGreen;
				c.rgbGreen = (BYTE)min((int)ceilSat, (int)curSat + (int)cTable[curSat]);
				c = HSLtoRGB(c);
				BlindSetPixelColor(x,y,c);
			}
		}
	}
	return true;
}