示例#1
0
Scaler::~Scaler()
{
	if (GetDestImage() != fScaledImage) {
		delete fScaledImage;
		fScaledImage = NULL;
	}
}
示例#2
0
void
Scaler::Completed()
{
	if (GetDestImage() != fScaledImage) {
		delete fScaledImage; fScaledImage = NULL;
	}
}
示例#3
0
void
Scaler::Run(int32 i, int32 n)
{
	int32 from, to, height, imageHeight;
	imageHeight = GetDestImage()->Bounds().IntegerHeight() + 1;
	height = imageHeight / n;
	from = i * height;
	if (i+1 == n) {
		to = imageHeight - 1;
	} else {
		to = from + height - 1;
	}
	if (GetDestImage()->Bounds().Width() >= GetSrcImage()->Bounds().Width()) {
		ScaleBilinearFP(from, to);
	} else {
		DownScaleBilinear(from, to);
	}
	if (fDither) {
		Dither(from, to);
	}
}
示例#4
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;
}
示例#5
0
// Note: On my systems, the operation kInvert shows a speedup on multiple CPUs only!
void
ImageProcessor::Run(int32 i, int32 n)
{
	int32 from, to;
	int32 height = (fHeight+1) / n;
	from = i * height;
	if (i+1 == n) {
		to = fHeight;
	} else {
		to = from + height - 1;
	}

	int32 x, y, destX, destY;
	const uchar* src = (uchar*)GetSrcImage()->Bits();
	uchar* dest = (uchar*)GetDestImage()->Bits();

	switch (fOp) {
		case kRotateClockwise:
			for (y = from; y <= to; y ++) {
				for (x = 0; x <= fWidth; x ++) {
					destX = fHeight - y;
					destY = x;
					CopyPixel(dest, destX, destY, src, x, y);
				}
			}
			break;
		case kRotateCounterClockwise:
			for (y = from; y <= to; y ++) {
				for (x = 0; x <= fWidth; x ++) {
					destX = y;
					destY = fWidth - x;
					CopyPixel(dest, destX, destY, src, x, y);
				}
			}
			break;
		case kFlipTopToBottom:
			for (y = from; y <= to; y ++) {
				for (x = 0; x <= fWidth; x ++) {
					destX = x;
					destY = fHeight - y;
					CopyPixel(dest, destX, destY, src, x, y);
				}
			}
			break;
		case kFlipLeftToRight:
			for (y = from; y <= to; y ++) {
				for (x = 0; x <= fWidth; x ++) {
					destX = fWidth - x;
					destY = y;
					CopyPixel(dest, destX, destY, src, x, y);
				}
			}
			break;
		case kInvert:
			for (y = from; y <= to; y ++) {
				for (x = 0; x <= fWidth; x ++) {
					InvertPixel(x, y, dest, src);
				}
			}
			break;
	}

}