/* TranslationEditorDialog::onPalTargetLeftUp
 * Called when the left mouse button is released in the target
 * palette range canvas
 *******************************************************************/
void TranslationEditorDialog::onPalTargetLeftUp(wxMouseEvent& e)
{
	// Get current translation range
	TransRange* tr = translation.getRange(list_translations->GetSelection());

	// Update its target range if it's a palette translation
	if (tr && tr->getType() == TRANS_PALETTE)
	{
		TransRangePalette* tpr = (TransRangePalette*)tr;
		if (cb_target_reverse->GetValue())
		{
			tpr->setDEnd(pal_canvas_target->getSelectionStart());
			tpr->setDStart(pal_canvas_target->getSelectionEnd());
		}
		else
		{
			tpr->setDStart(pal_canvas_target->getSelectionStart());
			tpr->setDEnd(pal_canvas_target->getSelectionEnd());
		}
	}

	// Update UI
	updateListItem(list_translations->GetSelection());
	updatePreviews();
}
/* TranslationEditorDialog::onRBPaletteSelected
 * Called when the 'palette range' translation type radio button is
 * selected
 *******************************************************************/
void TranslationEditorDialog::onRBPaletteSelected(wxCommandEvent& e)
{
	// Swap to target palette panel
	showPaletteTarget();

	// If a range is selected
	int index = list_translations->GetSelection();
	if (index >= 0)
	{
		// Remove it
		translation.removeRange(index);

		// Recreate it
		translation.addRange(TRANS_PALETTE, index);
		TransRangePalette* tr = (TransRangePalette*)translation.getRange(index);
		// Origin range
		tr->setOStart(pal_canvas_original->getSelectionStart());
		tr->setOEnd(pal_canvas_original->getSelectionEnd());
		// Target range
		if (cb_target_reverse->GetValue())
		{
			tr->setDEnd(pal_canvas_target->getSelectionStart());
			tr->setDStart(pal_canvas_target->getSelectionEnd());
		}
		else
		{
			tr->setDStart(pal_canvas_target->getSelectionStart());
			tr->setDEnd(pal_canvas_target->getSelectionEnd());
		}

		// Update UI
		updateListItem(index);
		openRange(index);
		updatePreviews();
	}
}
/* TranslationEditorDialog::openRange
 * Opens the translation range [index] from the current translation
 *******************************************************************/
void TranslationEditorDialog::openRange(int index)
{
	// Check index
	if (index < 0 || index >= (int)translation.nRanges())
		return;

	// Get translation range to open
	TransRange* tr = translation.getRange(index);

	// Set origin selection
	pal_canvas_original->setSelection(tr->oStart(), tr->oEnd());
	pal_canvas_original->Refresh();

	// Check translation range type
	if (tr->getType() == TRANS_PALETTE)
	{
		// Palette range
		TransRangePalette* tpr = (TransRangePalette*)tr;

		// Select palette type radiobox
		rb_type_palette->SetValue(true);
		showPaletteTarget();

		// Set target range selection
		if (tpr->dStart() <= tpr->dEnd())
		{
			pal_canvas_target->setSelection(tpr->dStart(), tpr->dEnd());
			cb_target_reverse->SetValue(false);
		}
		else
		{
			pal_canvas_target->setSelection(tpr->dEnd(), tpr->dStart());
			cb_target_reverse->SetValue(true);
		}
		pal_canvas_target->Refresh();
	}
	else if (tr->getType() == TRANS_COLOUR)
	{
		// Colour gradient
		TransRangeColour* tcr = (TransRangeColour*)tr;

		// Select colour type radiobox
		rb_type_colour->SetValue(true);
		showGradientTarget();

		// Set beginning colour
		gb_gradient->setStartCol(tcr->dStart());
		cp_range_begin->SetColour(WXCOL(tcr->dStart()));

		// Set ending colour
		gb_gradient->setEndCol(tcr->dEnd());
		cp_range_end->SetColour(WXCOL(tcr->dEnd()));

		// Update UI
		gb_gradient->Refresh();
	}
	else if (tr->getType() == TRANS_DESAT)
	{
		// Desaturated colour gradient
		TransRangeDesat* tdr = (TransRangeDesat*)tr;

		// Select desaturated colour type radiobox
		rb_type_desaturate->SetValue(true);
		showGradientTarget();

		// Set beginning colour
		rgba_t col;
		col.r = MathStuff::clamp(tdr->dSr() * 128, 0, 255);
		col.g = MathStuff::clamp(tdr->dSg() * 128, 0, 255);
		col.b = MathStuff::clamp(tdr->dSb() * 128, 0, 255);
		cp_range_begin->SetColour(WXCOL(col));
		gb_gradient->setStartCol(col);

		// Set ending colour
		col.r = MathStuff::clamp(tdr->dEr() * 128, 0, 255);
		col.g = MathStuff::clamp(tdr->dEg() * 128, 0, 255);
		col.b = MathStuff::clamp(tdr->dEb() * 128, 0, 255);
		cp_range_end->SetColour(WXCOL(col));
		gb_gradient->setEndCol(col);

		// Update UI
		gb_gradient->Refresh();
	}
}
Beispiel #4
0
/* SImage::applyTranslation
 * Applies a palette translation to the image
 *******************************************************************/
bool SImage::applyTranslation(Translation* tr, Palette8bit* pal)
{
	// Check image is ok
	if (!data)
		return false;

	// Can't apply a translation to a non-paletted image
	if (type != PALMASK)
		return false;

	// Get palette to use
	if (has_palette || !pal)
		pal = &palette;

	// Go through pixels
	for (int p = 0; p < width*height; p++)
	{
		uint8_t i = data[p];

		// No need to process transparent pixels
		if (mask && mask[p] == 0)
			continue;

		// Go through each translation component
		for (unsigned a = 0; a < tr->nRanges(); a++)
		{
			TransRange* r = tr->getRange(a);

			// Palette range translation
			if (r->getType() == TRANS_PALETTE)
			{
				TransRangePalette* tp = (TransRangePalette*)r;

				// Check pixel is within translation range
				if (i >= tp->oStart() && i <= tp->oEnd())
				{
					// Figure out how far along the range this colour is
					double range_frac = 0;
					if (tp->oStart() != tp->oEnd())
						range_frac = double(i - tp->oStart()) / double(tp->oEnd() - tp->oStart());

					// Determine destination palette index
					uint8_t di = tp->dStart() + range_frac * (tp->dEnd() - tp->dStart());

					// Apply new colour
					data[p] = di;
				}
			}

			// Colour range
			else if (r->getType() == TRANS_COLOUR)
			{
				TransRangeColour* tc = (TransRangeColour*)r;

				// Check pixel is within translation range
				if (i >= tc->oStart() && i <= tc->oEnd())
				{
					// Figure out how far along the range this colour is
					double range_frac = 0;
					if (tc->oStart() != tc->oEnd())
						range_frac = double(i - tc->oStart()) / double(tc->oEnd() - tc->oStart());

					// Determine destination colour
					uint8_t r = tc->dStart().r + range_frac * (tc->dEnd().r - tc->dStart().r);
					uint8_t g = tc->dStart().g + range_frac * (tc->dEnd().g - tc->dStart().g);
					uint8_t b = tc->dStart().b + range_frac * (tc->dEnd().b - tc->dStart().b);

					// Find nearest colour in palette
					uint8_t di = pal->nearestColour(rgba_t(r, g, b));

					// Apply new colour
					data[p] = di;
				}
			}

			// Desaturated colour range
			else if (r->getType() == TRANS_DESAT)
			{
				TransRangeDesat* td = (TransRangeDesat*)r;

				// Check pixel is within translation range
				if (i >= td->oStart() && i <= td->oEnd())
				{
					// Get greyscale colour
					rgba_t col = pal->colour(i);
					float grey = (col.r*0.3f + col.g*0.59f + col.b*0.11f) / 255.0f;

					// Determine destination colour
					uint8_t r = MIN(255, int((td->dSr() + grey*(td->dEr() - td->dSr()))*255.0f));
					uint8_t g = MIN(255, int((td->dSg() + grey*(td->dEg() - td->dSg()))*255.0f));
					uint8_t b = MIN(255, int((td->dSb() + grey*(td->dEb() - td->dSb()))*255.0f));

					// Find nearest colour in palette
					uint8_t di = pal->nearestColour(rgba_t(r, g, b));

					// Apply new colour
					data[p] = di;
				}
			}
		}
	}

	return true;
}