Beispiel #1
0
void InitSelectedMap()
{
	BScreen screen;
	rgb_color c, d;
	int32 i;

	for (i = 0; i < 255; i++)
	{
		d = c = screen.ColorForIndex(i);

		c.red = c.red * 2 / 3;
		c.green = c.green * 2 / 3;
		c.blue = c.blue * 2 / 3;

		gSelectedMap[i] = screen.IndexForColor(c);

		d.red = (c.red + 438) / 3;
		d.green = (c.green + 438) / 3;
		d.blue = (c.blue + 438) / 3;

		gDisabledMap[i] = screen.IndexForColor(d);
	}

	gSelectedMap[255] = 255;
	gDisabledMap[255] = 255;
} /* InitSelectedMap */
Beispiel #2
0
void
CMenuTool::SetBitmap(
	BBitmap *bitmap)
{
	D_OPERATION(("CMenuTool::SetBitmap()\n"));

	if (bitmap && (bitmap != m_bitmap))
	{
		delete m_bitmap;
		delete m_disabledBitmap;

		m_bitmap = bitmap;

		// calculate disabled bitmap
		BScreen screen;
		uint8 light = screen.IndexForColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
													  B_LIGHTEN_1_TINT));
		uint8 dark  = screen.IndexForColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
													  B_DARKEN_1_TINT));
		m_disabledBitmap = new BBitmap(bitmap);
		uint8 *start = (uint8 *)m_disabledBitmap->Bits();
		uint8 *end = start + m_disabledBitmap->BitsLength();
		for (uint8 *pos = start; pos < end; pos++)
		{
			rgb_color color = screen.ColorForIndex(*pos);
			if ((color.alpha < 255) || (color.red + color.green + color.blue >= 765))
				continue;
			if (color.red + color.green + color.blue > 384)
				*pos = light;
			else
				*pos = dark;
		}
	}

	if (ToolBar())
		ToolBar()->Invalidate();
}
Beispiel #3
0
void
Scaler::Dither(int32 fromRow, int32 toRow)
{
	BBitmap* src;
	BBitmap* dest;
	intType destW;
	intType x, y;

	uchar* srcBits;
	intType srcBPR;
	uchar* srcDataRow;
	uchar* srcData;

	uchar* destBits;
	intType destBPR;
	uchar* destDataRow;
	uchar* destData;
	const int32 kBPP = 4;
	DitheringColumnData* columnData0;
	DitheringColumnData* columnData;
	DitheringColumnData* cd;
	BScreen screen;
	intType error[3], err[3];

	src = fScaledImage;
	dest = GetDestImage();

	ASSERT(src->ColorSpace() == B_RGB32 || src->ColorSpace() == B_RGBA32);
	ASSERT(dest->ColorSpace() == B_CMAP8);
	ASSERT(src->Bounds().IntegerWidth() == dest->Bounds().IntegerWidth());
	ASSERT(src->Bounds().IntegerHeight() == dest->Bounds().IntegerHeight());

	destW = dest->Bounds().IntegerWidth();

	srcBits = (uchar*)src->Bits();
	srcBPR = src->BytesPerRow();
	destBits = (uchar*)dest->Bits();
	destBPR = dest->BytesPerRow();

	// Allocate space for sentinel at left and right bounds,
	// so that columnData[-1] and columnData[destW+1] can be safely accessed
	columnData0 = new DitheringColumnData[destW+3];
	columnData = columnData0 + 1;

	// clear error
	cd = columnData;
	for (x = destW; x >= 0; x --, cd ++) {
		cd->error[0] = cd->error[1] = cd->error[2] =0;
	}

	srcDataRow = srcBits + fromRow * srcBPR;
	destDataRow = destBits + fromRow * destBPR;
	for (y = fromRow; IsRunning() && y <= toRow; y ++, srcDataRow += srcBPR, destDataRow += destBPR) {
		// left to right
		error[0] = error[1] = error[2] = 0;
		srcData = srcDataRow;
		destData = destDataRow;
		for (x = 0; x <= destW; x ++, srcData += kBPP, destData += 1) {
			rgb_color color, actualColor;
			uint8 index;

			color.red = Limit(srcData[2] + error[0] / 16);
			color.green = Limit(srcData[1] + error[1] / 16);
			color.blue = Limit(srcData[0] + error[2] / 16);

			index = screen.IndexForColor(color);
			actualColor = screen.ColorForIndex(index);

			*destData = index;

			err[0] = color.red - actualColor.red;
			err[1] = color.green -actualColor.green;
			err[2] = color.blue -actualColor.blue;

			// distribute error
			// get error for next pixel
			cd = &columnData[x+1];
			error[0] = cd->error[0] + 7 * err[0];
			error[1] = cd->error[1] + 7 * err[1];
			error[2] = cd->error[2] + 7 * err[2];

			// set error for right pixel below current pixel
			cd->error[0] = err[0];
			cd->error[1] = err[1];
			cd->error[2] = err[2];

			// add error for pixel below current pixel
			cd --;
			cd->error[0] += 5 * err[0];
			cd->error[1] += 5 * err[1];
			cd->error[2] += 5 * err[2];

			// add error for left pixel below current pixel
			cd --;
			cd->error[0] += 3 * err[0];
			cd->error[1] += 3 * err[1];
			cd->error[2] += 3 * err[2];
		}
		// Note: Alogrithm has good results with "left to right" already
		// Optionally remove code to end of block:
		y ++;
		srcDataRow += srcBPR; destDataRow += destBPR;
		if (y > toRow) break;
		// right to left
		error[0] = error[1] = error[2] = 0;
		srcData = srcDataRow + destW * kBPP;
		destData = destDataRow + destW;
		for (x = 0; x <= destW; x ++, srcData -= kBPP, destData -= 1) {
			rgb_color color, actualColor;
			uint8 index;

			color.red = Limit(srcData[2] + error[0] / 16);
			color.green = Limit(srcData[1] + error[1] / 16);
			color.blue = Limit(srcData[0] + error[2] / 16);

			index = screen.IndexForColor(color);
			actualColor = screen.ColorForIndex(index);

			*destData = index;

			err[0] = color.red - actualColor.red;
			err[1] = color.green -actualColor.green;
			err[2] = color.blue -actualColor.blue;

			// distribute error
			// get error for next pixel
			cd = &columnData[x-1];
			error[0] = cd->error[0] + 7 * err[0];
			error[1] = cd->error[1] + 7 * err[1];
			error[2] = cd->error[2] + 7 * err[2];

			// set error for left pixel below current pixel
			cd->error[0] = err[0];
			cd->error[1] = err[1];
			cd->error[2] = err[2];

			// add error for pixel below current pixel
			cd ++;
			cd->error[0] += 5 * err[0];
			cd->error[1] += 5 * err[1];
			cd->error[2] += 5 * err[2];

			// add error for right pixel below current pixel
			cd ++;
			cd->error[0] += 3 * err[0];
			cd->error[1] += 3 * err[1];
			cd->error[2] += 3 * err[2];
		}
	}

	delete[] columnData0;
}
BBitmap *ConvertTo8bit( BBitmap *bitmap )
{
	if( bitmap->ColorSpace() == B_COLOR_8_BIT )
		return new BBitmap( bitmap );

	if( (bitmap->ColorSpace()!=B_RGB32) && (bitmap->ColorSpace()!=B_RGBA32) )
		return NULL;

	BBitmap *bitmap_8bit = new BBitmap( bitmap->Bounds(), B_COLOR_8_BIT, false );
	
	int width = (int)bitmap->Bounds().Width()+1;
	int height = (int)bitmap->Bounds().Height()+1;
	bool srchasalpha = bitmap->ColorSpace()==B_RGBA32;

	BScreen screen;
	
	int *forward = new int[3*width*3];
	memset( forward, 0, 3*width*3*sizeof(int) );
	
	bitmap_rgb *srcbits = (bitmap_rgb*)bitmap->Bits();
	int srcstride = bitmap->BytesPerRow()/sizeof(bitmap_rgb);

	uint8 *dstbits = (uint8*)bitmap_8bit->Bits();
	int dststride = bitmap_8bit->BytesPerRow()/sizeof(uint8);

	for( int iy=0; iy<height; iy++ )
	{
		for( int ix=0; ix<width; ix++ )
		{
			bitmap_rgb rgb = srcbits[ix+iy*srcstride];

			int red = clamp( rgb.red+forward[0+ix*3], 0, 255 );
			int green = clamp( rgb.green+forward[1+ix*3], 0, 255 );
			int blue = clamp( rgb.blue+forward[2+ix*3], 0, 255 );

#if 0
			uint8 close_col = screen.IndexForColor( red, green, blue );
#else
			uint8 close_col = 0;
			uint32 close_err = 0x7fffffff;
			for( int i=0; i<256; i++ )
			{
				rgb_color col = screen.ColorForIndex( i );
				uint32 err = (col.red-red)*(col.red-red)*299 +
					(col.green-green)*(col.green-green)*587 +
					(col.blue-blue)*(col.blue-blue)*114;
				if( err<close_err )
				{
					close_col = i;
					close_err = err;
				}
			}
#endif
			rgb_color close_rgb = screen.ColorForIndex( close_col );
#if 1
			if(  srchasalpha && rgb.alpha<192 )
				close_col = 255;
#endif
			dstbits[ix+iy*dststride] = close_col;
			
			int err[3] = {red-close_rgb.red,green-close_rgb.green,blue-close_rgb.blue};
			for( int i=0; i<3; i++ )
			{
#if 0
				int h = err[i]>>1;
				int e1 = (7*h)>>3;
				int e2 = h-e1;
				h = err[i]-h;
				int e3 = (5*h)>>3;
				int e4 = h-e3;
				
				if( ix<width-1 )
				{
					forward[i+(ix+1)*3]+=e1;
					forward[i+(ix+1)*3+3*width]+=e2;
				}
				forward[i+ix*3+3*width]+=e3; 
				if( ix>0 ) forward[i+(ix-1)*3+3*width]+=e4;
#else
				int e1 = (err[i]*8+21)/42;
				int e2 = (err[i]*4+21)/42;

				int e3 = (err[i]*2+21)/42;
				int e4 = (err[i]*4+21)/42;
				int e5 = (err[i]*8+21)/42;
				int e6 = (err[i]*4+21)/42;
				int e7 = (err[i]*2+21)/42;

				int e8 = (err[i]*1+21)/42;
				int e9 = (err[i]*2+21)/42;
				int e10 = (err[i]*4+21)/42;
				int e11 = (err[i]*2+21)/42;
				int e12 = (err[i]*1+21)/42;
				
				if( ix>1 )
				{
					forward[i+(ix-2)*3+3*width]+=e3;
					forward[i+(ix-2)*3+2*3*width]+=e8;
				}
				if( ix>0 )
				{
					forward[i+(ix-1)*3+3*width]+=e4;
					forward[i+(ix-1)*3+2*3*width]+=e9;
				}
				forward[i+(ix)*3+3*width]+=e5;
				forward[i+(ix)*3+2*3*width]+=e10;
				if( ix<width-1 )
				{
					forward[i+(ix+1)*3]+=e1;
					forward[i+(ix+1)*3+3*width]+=e6;
					forward[i+(ix+1)*3+2*3*width]+=e11;
				}
				if( ix<width-2 )
				{
					forward[i+(ix+1)*3]+=e2;
					forward[i+(ix+1)*3+3*width]+=e7;
					forward[i+(ix+1)*3+2*3*width]+=e12;
				}
				
#endif
			}
			
//			uint8 col = screen.IndexForColor( rgb.red, rgb.green, rgb.blue );
//			dstbits[ix+iy*dststride] = col;
		}
		
		memmove( forward, forward+3*width, 3*width*2*sizeof(int) );
		memset( forward+3*width*2, 0, width*3*sizeof(int) );
	}

	delete forward;
	return bitmap_8bit;
}